From cbe6f83afa75cdb3a809e1b9b93af501fa2f92ed Mon Sep 17 00:00:00 2001 From: Jose Agustin Puente Date: Tue, 2 Jun 2026 10:08:56 +0200 Subject: [PATCH 01/20] =?UTF-8?q?fix(query+ingest):=20value-anchored=20NL?= =?UTF-8?q?=E2=86=92SQL=20grounding,=20hierarchy=20resolution,=20pipeline?= =?UTF-8?q?=20robustness?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Surface column values into the grounding/generation prompts and harden the query + ingestion pipelines so the NL→SQL agents stop guessing literals and the control flow stops reporting wrong-but-empty results as confident answers. Grounding / value anchoring: - profile: store the full distinct value set for low-cardinality columns (was top-5) - retrieval: value_fingerprint() on hits; render a "Column value catalogue" into the grounding and generation prompts; instructions to copy WHERE/CASE literals verbatim, handle tall/EAV layouts and scaled-duplicate measures - structurally detect self-referencing hierarchy columns (value containment, with a row-wise discriminator) and teach "a person's team/reports/structure" -> filter the hierarchy column Control flow / governance: - treat 0-row / degenerate aggregate results as suspicious -> clarification + confidence cap - gate auto-learning on row_count > 0 (stop poisoning the example store) - prefer a candidate that passes the firewall and returns non-empty rows over candidates[0] - exclude CTE names from AST table_refs (firewall no longer rejects valid CTE SQL) - snapshot-scope retrieval; honor and persist conversation snapshot pins - unify /stream, :explain, :validate on the rendered prompts + firewall/scope guards - thread a re-firewalled extra_filter through the semantic-metric bind() Ingestion robustness / determinism: - header-quality scoring (skip numeric spacer rows) + stable leading-blank handling - temperature=0 for the naming/describe agents (cuts re-ingest schema churn ~94%) - rewrite Parquet column names on the no-key fallback (fixes profile/sample Binder errors) - index column values into embeddings + content_tsv - warn when the cross-encoder reranker degrades to a no-op --- src/flyquery/core/agents/builder.py | 10 + .../core/agents/column_name_proposer_agent.py | 3 + src/flyquery/core/agents/describe_agent.py | 3 + .../core/agents/rename_detection_agent.py | 3 + .../core/services/examples/auto_learner.py | 8 + .../core/services/execution/ast_classifier.py | 21 +- .../core/services/execution/table_resolver.py | 36 ++- .../ingestion/readers/excel_reader.py | 111 +++++++- .../core/services/ingestion/stages/embed.py | 60 +++- .../core/services/ingestion/stages/parse.py | 11 + .../core/services/ingestion/stages/profile.py | 168 ++++++++++- .../core/services/query/query_service.py | 264 +++++++++++++++++- .../core/services/retrieval/reranker.py | 19 +- .../core/services/retrieval/search_index.py | 150 ++++++++-- .../web/controllers/query_controller.py | 171 +++++++++--- 15 files changed, 955 insertions(+), 83 deletions(-) diff --git a/src/flyquery/core/agents/builder.py b/src/flyquery/core/agents/builder.py index 3044bfb2..a15e048d 100644 --- a/src/flyquery/core/agents/builder.py +++ b/src/flyquery/core/agents/builder.py @@ -48,6 +48,7 @@ def build_agent( instructions: str, settings: FlyquerySettings, max_output_tokens: int | None = None, + temperature: float | None = None, extra_settings: dict[str, Any] | None = None, ) -> Any: """Construct a :class:`FireflyAgent` with the standard knobs. @@ -67,6 +68,13 @@ def build_agent( requiring callers to plumb the env var themselves. max_output_tokens: Optional override for this specific call. ``None`` falls back to ``settings.agent_max_output_tokens``. + temperature: Optional sampling temperature folded into + ``model_settings``. ``None`` (the default) leaves the + provider default untouched -- grounding / generation / + critic rely on that diversity (generation samples N + candidates). Naming / description stages pass ``0.0`` so + near-identical re-ingests yield identical names and avoid + schema-change churn. extra_settings: Optional extra ``model_settings`` entries. Caller-provided keys WIN on conflict so a stage can cap below the global budget (e.g. a 1-token classifier). @@ -83,6 +91,8 @@ def build_agent( resolved_max = resolve_max_output_tokens(settings, override=max_output_tokens) model_settings: dict[str, Any] = {"max_tokens": resolved_max} + if temperature is not None: + model_settings["temperature"] = temperature if extra_settings: # Caller-provided settings win on conflict -- a stage can cap # itself below the default by passing ``max_tokens=128`` in diff --git a/src/flyquery/core/agents/column_name_proposer_agent.py b/src/flyquery/core/agents/column_name_proposer_agent.py index 3eed345c..e317931d 100644 --- a/src/flyquery/core/agents/column_name_proposer_agent.py +++ b/src/flyquery/core/agents/column_name_proposer_agent.py @@ -116,6 +116,9 @@ def build_column_name_proposer_agent(settings): output_type=ProposedColumnNames, instructions=prompt.instructions, settings=settings, + # Deterministic naming: identical re-ingests must yield identical + # column names, otherwise reconcile sees phantom schema churn. + temperature=0.0, ) diff --git a/src/flyquery/core/agents/describe_agent.py b/src/flyquery/core/agents/describe_agent.py index ac6870e2..4333e382 100644 --- a/src/flyquery/core/agents/describe_agent.py +++ b/src/flyquery/core/agents/describe_agent.py @@ -140,4 +140,7 @@ def build_describe_agent(settings): output_type=DescribedObjects, instructions=prompt.instructions, settings=settings, + # Deterministic descriptions/semantic types: identical columns on + # re-ingest must produce identical metadata, no schema-change churn. + temperature=0.0, ) diff --git a/src/flyquery/core/agents/rename_detection_agent.py b/src/flyquery/core/agents/rename_detection_agent.py index 2c1c4a98..dd951a38 100644 --- a/src/flyquery/core/agents/rename_detection_agent.py +++ b/src/flyquery/core/agents/rename_detection_agent.py @@ -62,4 +62,7 @@ def build_rename_detection_agent(settings): settings=settings, # Rename detection is a short task; cap output tokens tightly max_output_tokens=2048, + # Deterministic: the same removed/candidate pair must always + # resolve the same way so re-ingests don't flip-flop renames. + temperature=0.0, ) diff --git a/src/flyquery/core/services/examples/auto_learner.py b/src/flyquery/core/services/examples/auto_learner.py index 48101da2..1219058f 100644 --- a/src/flyquery/core/services/examples/auto_learner.py +++ b/src/flyquery/core/services/examples/auto_learner.py @@ -28,6 +28,7 @@ class AutoLearner: Skips when: - ``retries > 0`` (query required critic refinement) - PII findings were detected in the result + - the query returned no rows (``row_count`` is 0, when provided) Called by QueryService (Phase D) after a successful execution. """ @@ -46,6 +47,7 @@ async def maybe_propose( retries: int, pii_findings: list[Any], query_id: uuid.UUID, + row_count: int | None = None, ) -> None: """Insert a flyquery_examples row when all criteria pass. @@ -57,11 +59,17 @@ async def maybe_propose( :param retries: number of critic refinement loops (must be 0 to propose) :param pii_findings: any PII signals detected (must be empty to propose) :param query_id: UUID of the parent query record + :param row_count: number of rows the query returned; when provided it + must be > 0 to propose (a valid-but-wrong query returning 0 rows + would otherwise poison grounding). When ``None`` the row gate is + skipped to preserve behaviour for callers that do not pass it. """ if retries > 0: return if pii_findings: return + if row_count is not None and row_count <= 0: + return await self._service.create( tenant_id, workspace_id, diff --git a/src/flyquery/core/services/execution/ast_classifier.py b/src/flyquery/core/services/execution/ast_classifier.py index a5f9cd70..dfcd0836 100644 --- a/src/flyquery/core/services/execution/ast_classifier.py +++ b/src/flyquery/core/services/execution/ast_classifier.py @@ -76,8 +76,25 @@ def classify(self, sql: str) -> AstClassification: # pyright does not unify with the public ``Expression`` base below. kind = self._kind(stmt) # pyright: ignore[reportArgumentType] - # Collect table refs — skip anonymous subquery aliases - tables = tuple(sorted({t.name for t in stmt.find_all(sqlglot.expressions.Table) if t.name})) + # Collect table refs — skip anonymous subquery aliases AND + # CTE-defined names. sqlglot represents a reference to a CTE + # (``FROM base`` where ``WITH base AS (...)``) as an ``exp.Table`` + # node, so without this filter the CTE alias leaks into + # ``table_refs``; the downstream bad-tables guard then flags it + # as a non-existent table and the (otherwise valid) query is + # rejected — see QueryService bad-tables set-difference. + cte_names = { + cte.alias_or_name for cte in stmt.find_all(sqlglot.expressions.CTE) if cte.alias_or_name + } + tables = tuple( + sorted( + { + t.name + for t in stmt.find_all(sqlglot.expressions.Table) + if t.name and t.name not in cte_names + } + ) + ) columns = tuple(sorted({c.name for c in stmt.find_all(sqlglot.expressions.Column) if c.name})) has_subquery = bool(list(stmt.find_all(sqlglot.expressions.Subquery))) diff --git a/src/flyquery/core/services/execution/table_resolver.py b/src/flyquery/core/services/execution/table_resolver.py index 3bcd6b53..0c18785e 100644 --- a/src/flyquery/core/services/execution/table_resolver.py +++ b/src/flyquery/core/services/execution/table_resolver.py @@ -32,6 +32,7 @@ from __future__ import annotations +import json import uuid import sqlalchemy as sa @@ -54,6 +55,7 @@ async def resolve( dataset_id: uuid.UUID, table_names: list[str], object_store_base: str | None = None, + pins: dict[str, str] | None = None, ) -> dict[str, str]: """Return a mapping of table name → absolute parquet path. @@ -65,6 +67,11 @@ async def resolve( :param dataset_id: dataset to scope the lookup :param table_names: unqualified table names from the AST :param object_store_base: override for ``settings.object_store_base`` + :param pins: optional ``{table_name: snapshot_id}`` — a follow-up + drill-down turn pins each table to the snapshot it resolved to + on the first turn, so a mid-conversation re-ingest does not + silently switch the answer to a newer schema. Unpinned tables + fall back to ``current_snapshot_id``. :return: ``{name: path}`` dict for all resolvable tables """ if not table_names: @@ -77,12 +84,16 @@ async def resolve( SELECT t.name, ss.parquet_object_key FROM flyquery_tables t JOIN flyquery_schema_snapshots ss - ON ss.id = t.current_snapshot_id + ON ss.table_id = t.id + AND ss.id = COALESCE( + (CAST(:pins AS jsonb) ->> t.name)::uuid, + t.current_snapshot_id + ) WHERE t.dataset_id = :ds AND t.name = ANY(:names) AND t.is_active = true """), - {"ds": dataset_id, "names": list(table_names)}, + {"ds": dataset_id, "names": list(table_names), "pins": json.dumps(pins or {})}, ) out: dict[str, str] = {} @@ -90,3 +101,24 @@ async def resolve( key: str = r["parquet_object_key"] out[r["name"]] = f"{base}/{key}" return out + + async def current_snapshots( + self, dataset_id: uuid.UUID, table_names: list[str] + ) -> dict[str, str]: + """Return ``{table_name: current_snapshot_id}`` for the given tables. + + Used to record THIS turn's snapshot pins so a later drill-down turn + can reproduce the exact schema version it answered against. + """ + if not table_names: + return {} + rows = await self._session.execute( + sa.text(""" + SELECT name, current_snapshot_id + FROM flyquery_tables + WHERE dataset_id = :ds AND name = ANY(:names) AND is_active = true + AND current_snapshot_id IS NOT NULL + """), + {"ds": dataset_id, "names": list(table_names)}, + ) + return {r["name"]: str(r["current_snapshot_id"]) for r in rows.mappings()} diff --git a/src/flyquery/core/services/ingestion/readers/excel_reader.py b/src/flyquery/core/services/ingestion/readers/excel_reader.py index 24232227..c909facd 100644 --- a/src/flyquery/core/services/ingestion/readers/excel_reader.py +++ b/src/flyquery/core/services/ingestion/readers/excel_reader.py @@ -73,6 +73,79 @@ # Heuristic constants _MIN_HEADER_NON_EMPTY = 2 # a row needs >= 2 non-empty cells to be a header _SECTION_BREAK_EMPTY_ROWS = 2 # >= 2 consecutive empty rows close a section +# When the first header candidate looks like a numeric/spacer row, look this +# many rows ahead for a clearly-better string-label row before settling. +_HEADER_LOOKAHEAD = 3 + + +def _normalise_leading_blanks(rows: list[list[Any]]) -> list[list[Any]]: + """Drop leading rows that are *entirely* empty. + + calamine's ``to_python(skip_empty_area=True)`` trims the used-range + bounding box, but the exact number of leading blank rows it keeps can + differ between near-identical re-ingests (HDR-UNSTABLE) -- which flips + every section's absolute row index and causes column-name churn. We + normalise here by consistently removing fully-empty leading rows so the + same logical sheet yields the same header index. This MUST be applied + identically in ``_enumerate_sync`` (where indices are computed) and + ``_materialise_sync`` (where they are sliced) for the indices to line up. + """ + start = 0 + n = len(rows) + while start < n and all(c in ("", None) for c in rows[start]): + start += 1 + # Avoid a needless copy when nothing was trimmed. + return rows if start == 0 else rows[start:] + + +def _looks_like_label_row(row: list[Any]) -> bool: + """True when a row's populated cells are predominantly non-empty STRINGS. + + Header rows hold labels (text); spacer/index rows hold bare numbers + (1, 2, 3, ...). We require a strict string majority so genuinely numeric, + period, or date headers are not misclassified as data. + """ + non_empty = [c for c in row if c not in ("", None)] + if not non_empty: + return False + str_cells = sum(1 for c in non_empty if isinstance(c, str) and c.strip() != "") + return str_cells * 2 > len(non_empty) + + +def _is_numeric_spacer_row(row: list[Any]) -> bool: + """True when a header candidate looks like a numeric spacer, not labels. + + A row is a spacer when every populated cell is numeric (int/float, or a + numeric-looking string) and none is a real text label. This includes the + classic contiguous ``1..k`` column-numbering run Excel exports sometimes + inject above the real header band. A row with any genuine string label is + never a spacer. + """ + non_empty = [c for c in row if c not in ("", None)] + if len(non_empty) < _MIN_HEADER_NON_EMPTY: + return False + + def _as_number(cell: Any) -> float | None: + if isinstance(cell, bool): + return None + if isinstance(cell, (int, float)): + return float(cell) + if isinstance(cell, str): + try: + return float(cell.strip()) + except ValueError: + return None + return None + + numbers = [_as_number(c) for c in non_empty] + if any(num is None for num in numbers): + # Some populated cell is a non-numeric string -> not a spacer. + return False + + # Every populated cell is numeric and none is a text label. This covers + # both the all-numeric case and, as a strict subset, the contiguous + # ``1..k`` column-numbering run -- both are spacers, never label rows. + return True class ExcelReader: @@ -146,9 +219,34 @@ def _extract_sections(rows: list[list[Any]]) -> list[dict[str, Any]]: i += 1 continue - # Multi-cell row = section header + # Multi-cell row = section header candidate. + # + # A naive reader takes the FIRST >=2-non-empty row as the header. + # But dashboard exports sometimes inject a numeric spacer / column- + # numbering row (e.g. ``1 2 3 4``) just above the real label band + # (HDR-MULTIROW). If we treat that spacer as the header, the real + # labels become data and columns get opaque positional names. So + # when this candidate looks like a numeric/contiguous spacer, peek + # a small window ahead and prefer the first following row that is + # clearly a string-label row. We only skip the candidate when such + # a better row exists -- genuinely numeric / period / date headers + # (no string-label row just below) are left untouched, as are + # single-row sheets. header_idx = i - j = i + 1 + if _is_numeric_spacer_row(row) and not _looks_like_label_row(row): + look_end = min(i + 1 + _HEADER_LOOKAHEAD, n) + for la in range(i + 1, look_end): + la_ne = [c for c in rows[la] if c not in ("", None)] + if len(la_ne) == 0: + # A blank row before any label row means the spacer is + # really the last populated row -- stop looking ahead. + break + if len(la_ne) >= _MIN_HEADER_NON_EMPTY and _looks_like_label_row(rows[la]): + # Found a better string-label header just below; treat + # the skipped numeric/title rows as pre-header. + header_idx = la + break + j = header_idx + 1 consecutive_empty = 0 data_end = j # exclusive while j < n: @@ -208,7 +306,10 @@ def _enumerate_sync(source_path: str, rules: TableExtractionRules) -> list[Propo if allow is not None and sheet_name not in allow: continue sheet = wb.get_sheet_by_name(sheet_name) - rows = sheet.to_python(skip_empty_area=True) + # Normalise leading fully-empty rows so section indices are stable + # across re-ingests (HDR-UNSTABLE). The SAME normalisation runs in + # ``_materialise_sync`` so the stored indices slice the same rows. + rows = _normalise_leading_blanks(sheet.to_python(skip_empty_area=True)) if not rows: continue @@ -295,7 +396,9 @@ def _materialise_sync( ) wb = CalamineWorkbook.from_path(source_path) sheet = wb.get_sheet_by_name(sheet_name) - rows = sheet.to_python(skip_empty_area=True) + # Apply the SAME leading-blank normalisation used at enumerate time so + # the stored section indices slice the intended rows (HDR-UNSTABLE). + rows = _normalise_leading_blanks(sheet.to_python(skip_empty_area=True)) if sec_start is not None and sec_end is not None: # Section-encoded path -- slice precisely. diff --git a/src/flyquery/core/services/ingestion/stages/embed.py b/src/flyquery/core/services/ingestion/stages/embed.py index cd6e65d7..d3d92119 100644 --- a/src/flyquery/core/services/ingestion/stages/embed.py +++ b/src/flyquery/core/services/ingestion/stages/embed.py @@ -94,8 +94,14 @@ async def run_embed( async with session_factory() as s: result = await s.execute( sa.text( + # profile_json/sample_values_json are pulled in so the embed + # text (and thus content_tsv) covers the column's actual + # VALUES, making value-bearing columns retrievable by + # BM25/vector -- e.g. a question for "Total Revenue" finds + # the column whose distinct values include it. """ - SELECT id, qualified_name, data_type, description, synonyms_json + SELECT id, qualified_name, data_type, description, synonyms_json, + profile_json, sample_values_json FROM flyquery_schema_objects WHERE snapshot_id = :sid AND tenant_id = :tenant ORDER BY kind, qualified_name @@ -152,9 +158,61 @@ def _build_embed_text(row: dict) -> str: flat = list(synonyms.values()) if flat: parts.append("Synonyms: " + ", ".join(str(s) for s in flat)) + values = _render_values(row) + if values: + parts.append(values) return "\n".join(p for p in parts if p) +def _render_values(row: dict, *, max_chars: int = 300) -> str: + """Compact rendering of a column's actual VALUES for the embed corpus. + + Indexing the values (not just name + description) is what lets a + question like "Total Revenue" retrieve the column whose distinct set + contains that literal. + + PII safety: prefer the PII-gated ``sample_values_json`` -- the pii_tag + stage wipes it to ``[]`` when a redact/reject policy fires, so an empty + list here means "do not surface raw samples". When no gated samples are + present we fall back to ``profile_json.top_values``, the stored distinct + set for low-cardinality columns (aggregate / low-cardinality, so lower + PII risk). The result is capped to ``max_chars`` either way. + """ + seen: set[str] = set() + uniq: list[str] = [] + + # Preferred source: PII-gated samples (empty list = intentionally wiped). + samples = row.get("sample_values_json") + if isinstance(samples, list) and samples: + for v in samples: + if v is None: + continue + s = str(v) + if s not in seen: + seen.add(s) + uniq.append(s) + else: + # Fallback: stored distinct set (aggregate, low-cardinality). + prof = row.get("profile_json") + top_values = (prof or {}).get("top_values") if isinstance(prof, dict) else None + for tv in top_values or []: + v = tv.get("value") if isinstance(tv, dict) else tv + if v is None: + continue + s = str(v) + if s not in seen: + seen.add(s) + uniq.append(s) + + if not uniq: + return "" + body = " | ".join(uniq) + if len(body) > max_chars: + # Trim on a value boundary so we never emit a half-truncated literal. + body = body[:max_chars].rsplit("|", 1)[0].strip() + " …" + return f"Values: {body}" + + async def _update_object( *, object_id: uuid.UUID, diff --git a/src/flyquery/core/services/ingestion/stages/parse.py b/src/flyquery/core/services/ingestion/stages/parse.py index d54a8c2c..fea6ebaf 100644 --- a/src/flyquery/core/services/ingestion/stages/parse.py +++ b/src/flyquery/core/services/ingestion/stages/parse.py @@ -182,6 +182,17 @@ async def _propose_meaningful_column_names( "stage=parse rename_skipped reason=no_api_key fallback_prefix=%s", section_prefix, ) + if fallback == current_names: + return mat_result + # Rewrite the physical Parquet so its column names match the + # section-prefixed fallback we record in the MaterialiseResult -- + # otherwise the persisted schema_objects names diverge from the + # Parquet header and downstream DuckDB stages hit Binder Errors. + await _rename_parquet_columns( + parquet_path=parquet_path, + current_columns=current_names, + proposed_columns=fallback, + ) return _rebuild_mat_result(mat_result, fallback) try: diff --git a/src/flyquery/core/services/ingestion/stages/profile.py b/src/flyquery/core/services/ingestion/stages/profile.py index 1c6be8b3..301c7244 100644 --- a/src/flyquery/core/services/ingestion/stages/profile.py +++ b/src/flyquery/core/services/ingestion/stages/profile.py @@ -18,7 +18,9 @@ - null_fraction - approx_count_distinct (via approx_count_distinct()) - min / max (numeric + temporal columns only) - - top 5 values (low-cardinality only: distinct_estimate ≤ 100) + - full distinct value set, capped at 100 (low-cardinality only: + distinct_estimate ≤ 100) -- surfaced into the NL→SQL prompts so + filter/CASE literals are copied verbatim from real values Skips the whole column if the snapshot's n_rows_actual exceeds FLYQUERY_PROFILE_ROW_THRESHOLD (default 10M rows). @@ -31,6 +33,7 @@ import asyncio import json import logging +import re import uuid from typing import Any @@ -39,6 +42,49 @@ logger = logging.getLogger(__name__) +# Generic, language-agnostic markers for pre-aggregated subtotal / rollup +# values that can coexist with detail rows in a categorical dimension. +# This is a CURATED set of common total markers (English + Spanish), NOT +# tied to any specific dataset/column name. A value matching this is flagged +# as a likely subtotal so the query prompt can avoid mixing subtotal + detail +# rows (summing across all rows double-counts; filtering to it drops detail). +# Token boundary is a string edge or a non-alphanumeric separator (space, +# underscore, hyphen, etc.) so labels like "Total_Department" are caught while +# words that merely embed a marker (e.g. "allocation", "North America") are not. +_SUBTOTAL_MARKERS = ( + r"sub[ _-]?total|grand[ _-]?total|gran[ _-]?total|totals?|totales|" + r"all|todos|todas|suma|consolidad[oa]s?|overall" +) +# A value is flagged ONLY when it is essentially a total *marker by itself* +# (the whole value is the marker), OR a machine-generated pivot label where the +# marker is joined to another token by ``_``/``-`` (e.g. ``Total_Department``, +# ``Department-Total``). This deliberately does NOT match space-separated +# natural-language line items like ``Total Revenue`` / ``Total Nexium`` -- those +# are legitimate measure values the agent must keep, not pre-aggregated rows. +_SUBTOTAL_EXACT = re.compile(rf"^(?:{_SUBTOTAL_MARKERS})$", re.IGNORECASE) +_SUBTOTAL_JOINED = re.compile( + rf"(?:^|[_-])(?:{_SUBTOTAL_MARKERS})(?=[_-])|(?<=[_-])(?:{_SUBTOTAL_MARKERS})$", + re.IGNORECASE, +) +_BLANK_PLACEHOLDERS = {"(blank)", "(empty)", "(null)", "(en blanco)", "(vacío)", "(vacio)"} + + +def _looks_like_subtotal(value: str) -> bool: + """Heuristic: True only for unambiguous total/rollup pivot labels. + + Conservative + side-effect free: matches a standalone total marker, a + separator-joined pivot label (``Total_Department``), or a blank-ish + placeholder -- but NOT space-separated natural-language values such as + ``Total Revenue``. Consumed downstream as a prompt hint only. + """ + if value is None: + return False + stripped = value.strip() + if stripped == "" or stripped.lower() in _BLANK_PLACEHOLDERS: + return True + return bool(_SUBTOTAL_EXACT.match(stripped) or _SUBTOTAL_JOINED.search(stripped)) + + # Data-type compatibility groups _NUMERIC_TYPES = frozenset( { @@ -100,6 +146,9 @@ async def run_profile( columns = await _load_columns(tenant_id, snapshot_id, session_factory) profiled = 0 + # Collect profiles first so a second pass can detect self-referencing + # hierarchy columns (manager->report) before persisting. + computed: dict[str, tuple[uuid.UUID, str, dict[str, Any]]] = {} for col in columns: col_id: uuid.UUID = col["id"] col_name: str = col["qualified_name"].rsplit(".", 1)[-1] @@ -109,8 +158,23 @@ async def run_profile( _profile_column_sync, parquet_key, col_name, data_type, n_rows_actual ) if profile is not None: - await _persist_profile(col_id, profile, tenant_id, session_factory) - profiled += 1 + computed[col_name] = (col_id, data_type, profile) + + # Self-reference detection: annotate columns whose values are mostly + # contained in a higher-cardinality "entity" column of the same table + # (e.g. a manager/owner column whose values are people from the employee + # column). Purely structural (value containment) -- no name/vocabulary + # heuristics -- so it generalises to any self-referencing hierarchy. + try: + refs = await asyncio.to_thread(_detect_self_references, parquet_key, computed, n_rows_actual) + for ref_col, entity_col in refs.items(): + computed[ref_col][2]["references_column"] = entity_col + except Exception as exc: # noqa: BLE001 -- detection is best-effort + logger.warning("stage=profile self-reference detection failed snapshot=%s err=%s", snapshot_id, exc) + + for col_id, _dt, profile in computed.values(): + await _persist_profile(col_id, profile, tenant_id, session_factory) + profiled += 1 logger.info( "stage=profile snapshot_id=%s columns_profiled=%d", @@ -120,6 +184,79 @@ async def run_profile( return {"snapshot_id": str(snapshot_id), "columns_profiled": profiled} +def _detect_self_references( + parquet_key: str, + computed: dict[str, tuple[uuid.UUID, str, dict[str, Any]]], + n_rows: int, +) -> dict[str, str]: + """Find columns that reference a higher-cardinality entity column. + + A reference (foreign-key-like, including a self-referencing org + hierarchy) is detected purely structurally: a text column ``R`` whose + distinct values are mostly a SUBSET of another, higher-cardinality text + column ``E`` in the same table. ``R`` must be on the many-to-one side + (meaningfully fewer distinct values than ``E``) so two near-duplicate + name columns are not flagged as a hierarchy. + + Returns ``{ref_col: entity_col}``. No names/keywords are inspected -- + this generalises to any dataset's manager/owner/parent columns. + """ + import duckdb + + text_cols = { + name: prof["distinct_estimate"] + for name, (_cid, dt, prof) in computed.items() + if not _is_numeric(dt) and not _is_temporal(dt) and prof.get("distinct_estimate") + } + if len(text_cols) < 2: + return {} + # Entity columns: high-cardinality name/id columns (the "one" side). + entity_cols = [c for c, d in text_cols.items() if d >= max(8, 0.2 * n_rows)] + if not entity_cols: + return {} + + refs: dict[str, str] = {} + con = duckdb.connect() + try: + for ref_col, d_ref in text_cols.items(): + if d_ref < 3: + continue + for ent_col in entity_cols: + if ent_col == ref_col or d_ref > 0.7 * text_cols[ent_col]: + continue # ref must be the many-to-one (smaller) side + s_ref = '"' + ref_col.replace('"', '""') + '"' + s_ent = '"' + ent_col.replace('"', '""') + '"' + try: + row = con.execute( + f"SELECT count(DISTINCT {s_ref}), " + f"count(DISTINCT CASE WHEN {s_ref} IN " + f"(SELECT {s_ent} FROM read_parquet(?)) THEN {s_ref} END) " + f"FROM read_parquet(?) WHERE {s_ref} IS NOT NULL AND {s_ref} <> ''", + [parquet_key, parquet_key], + ).fetchone() + except Exception: # noqa: BLE001 -- skip uncomparable columns + continue + if row and row[0] and (row[1] / row[0]) >= 0.6: + # Discriminate a genuine cross-reference (the value is a + # DIFFERENT entity than the row's own -- a manager, owner, + # parent) from a row-wise DUPLICATE of the entity column (the + # SAME entity copied, e.g. a second name column). On a + # duplicate, ref == entity on most rows; on a real reference + # they differ. Skip duplicates. + eq = con.execute( + f"SELECT avg(CASE WHEN {s_ref} = {s_ent} THEN 1.0 ELSE 0.0 END) " + f"FROM read_parquet(?) WHERE {s_ref} IS NOT NULL AND {s_ent} IS NOT NULL", + [parquet_key], + ).fetchone() + if eq and eq[0] is not None and eq[0] > 0.5: + continue # row-wise copy -> not a hierarchy reference + refs[ref_col] = ent_col + break + finally: + con.close() + return refs + + # --------------------------------------------------------------------------- # DuckDB profiling (runs in thread) # --------------------------------------------------------------------------- @@ -172,7 +309,13 @@ def _profile_column_sync( profile["min"] = str(col_min) if col_min is not None else None profile["max"] = str(col_max) if col_max is not None else None - # Top values for low-cardinality columns (distinct ≤ 100) + # Top values for low-cardinality columns (distinct ≤ 100). + # We store the FULL distinct set (capped at 100) rather than + # just the top 5: the NL→SQL grounding/generation agents copy + # WHERE/CASE literals verbatim from these values, so a + # truncated list silently breaks any filter on a value that + # fell outside the top 5 (e.g. the P&L-line members of an + # operating-profit formula, or a brand outside the 5 biggest). if distinct_estimate <= 100 and distinct_estimate > 0: top_rows = conn.execute( f"SELECT {safe_col}, count(*) AS cnt " @@ -180,11 +323,26 @@ def _profile_column_sync( f"WHERE {safe_col} IS NOT NULL " f"GROUP BY {safe_col} " f"ORDER BY cnt DESC " - f"LIMIT 5", + f"LIMIT 100", [parquet_key], ).fetchall() profile["top_values"] = [{"value": str(r[0]), "count": r[1]} for r in top_rows] + # Subtotal detection (heuristic hint, cheap + side-effect free). + # For a low-cardinality TEXT dimension, flag values whose text + # matches a generic total/aggregate marker (en/es) or a blank + # placeholder. Such values are likely pre-aggregated rollup rows + # coexisting with detail rows; the query prompt consumes this to + # avoid mixing subtotal + detail (summing double-counts; filtering + # to the subtotal drops detail). No measure join is available + # here, so this stays purely structural/textual. + if not _is_numeric(data_type) and not _is_temporal(data_type): + subtotal_values = [ + str(r[0]) for r in top_rows if _looks_like_subtotal(str(r[0])) + ] + if subtotal_values: + profile["subtotal_values"] = subtotal_values + return profile finally: diff --git a/src/flyquery/core/services/query/query_service.py b/src/flyquery/core/services/query/query_service.py index b11ecf6f..ffbd8b41 100644 --- a/src/flyquery/core/services/query/query_service.py +++ b/src/flyquery/core/services/query/query_service.py @@ -128,6 +128,33 @@ def _render_grounding_prompt( out.append(f"- `{qn}` :: {text}") out.append("") + # 2b. The "Column value catalogue" lists EVERY column with its real + # values (distinct set for low-cardinality columns; numeric + # range otherwise). This is the ground truth the agent must copy + # filter/CASE literals from -- it prevents guessing wrong + # literals (`Year IN (2023)` when the values are `FY23`), maps a + # question entity to the column whose values contain it + # (`DAPA` lives in a column's values, not a column name), and + # reveals tall/EAV layouts (P&L line items are VALUES of a single + # column) and scaled-duplicate measures (`FY` vs `FY (Real)`). + inv_columns = [h for h in inventory if (getattr(h, "metadata", {}) or {}).get("kind") == "COLUMN"] + cols_with_values = [h for h in inv_columns if (getattr(h, "metadata", {}) or {}).get("values")] + if cols_with_values: + out.append(f"# Column value catalogue ({len(cols_with_values)} columns)") + out.append( + "Real values per column. When the question names an entity (a brand, " + "year, market, category, P&L line, team…) that is NOT a column name, " + "find the column whose values contain it and filter THAT column. Copy " + "filter/CASE literals VERBATIM from these values (values may be encoded, " + "e.g. a year shown as `FY23`). If several columns share members, prefer " + "the one whose values match the question most precisely." + ) + for h in cols_with_values: + md = getattr(h, "metadata", None) or {} + qn = md.get("qualified_name") or "?" + out.append(f"- `{qn}` :: {md.get('values')}") + out.append("") + examples = bundle.get("examples", []) or [] if examples: out.append(f"# Approved Q→SQL examples ({len(examples)})") @@ -214,6 +241,13 @@ def _render_generation_prompt( inv = schema_inventory or [] inv_tables = [h for h in inv if (getattr(h, "metadata", {}) or {}).get("kind") == "TABLE"] + # Map qualified_name -> value fingerprint so the generator copies + # filter/CASE literals verbatim from real values rather than guessing. + value_index: dict[str, str] = {} + for h in inv: + md = getattr(h, "metadata", None) or {} + if md.get("kind") == "COLUMN" and md.get("values"): + value_index[md.get("qualified_name")] = md.get("values") if inv_tables: out.append(f"# Complete dataset catalogue ({len(inv_tables)} tables)") out.append( @@ -243,9 +277,11 @@ def _render_generation_prompt( out.append(f"- `{getattr(t, 'table_qualified_name', t)}`") out.append("") if g_columns: - out.append("## Columns in scope") + out.append("## Columns in scope (with real values — copy literals verbatim)") for c in g_columns: - out.append(f"- `{getattr(c, 'column_qualified_name', c)}`") + cqn = getattr(c, "column_qualified_name", c) + vals = value_index.get(cqn) + out.append(f"- `{cqn}`" + (f" :: {vals}" if vals else "")) out.append("") if g_joins: out.append("## Approved joins") @@ -257,6 +293,20 @@ def _render_generation_prompt( ) out.append("") + # Full column-value catalogue -- the grounding agent may under-select + # columns, so expose every column's real values here too. This is the + # source of truth for WHERE / CASE literals. + if value_index: + out.append(f"# Column value catalogue ({len(value_index)} columns)") + out.append( + "Real values per column. Copy filter/CASE literals VERBATIM from these. " + "If the question names an entity that is not a column name, filter the " + "column whose values contain it." + ) + for qn, vals in value_index.items(): + out.append(f"- `{qn}` :: {vals}") + out.append("") + out.append("# Task") out.append( "Generate up to N candidate DuckDB SQL queries that answer the question, " @@ -267,6 +317,36 @@ def _render_generation_prompt( "rather than `FROM orbis_companies.IVI_MALAGA_SL__Activos`.\n" "- Quote any column name that isn't a plain identifier (e.g. date-shaped " 'names like `2024-12-31` must be `"2024-12-31"`).\n' + "- Copy every WHERE / CASE / IN literal VERBATIM from the column value " + "catalogue above -- never invent or reformat a value (a year is `FY23`, " + "not `2023`; a market may be `Brazil` or `44000BR Brazil` -- use exactly " + "what is listed).\n" + "- When the metric the user names is not a column but appears among a " + "column's listed values, filter that column (tall/EAV layout): e.g. P&L " + "line items like `Total Revenue` / `Manpower` are VALUES of a single " + "category column, selected with `CASE WHEN \"\" = 'Total Revenue' …`.\n" + "- When two numeric columns are near-duplicates whose ranges differ by a " + "constant factor (~10^k), they are the same measure at different scales -- " + "prefer the larger-magnitude one for monetary sums.\n" + "- Do NOT add a WHERE filter on a dimension the question did not ask to " + "slice by -- aggregate across ALL of its values, and do NOT drop a row " + "just because a category value's name contains 'total'/'all' (those are " + "usually legitimate, often 'unallocated', buckets). Exclude a value only " + "if you can confirm it is literally the sum of the other rows.\n" + "- Return what is ASKED FOR: if the question asks for names, a list, " + "'who', 'which', or 'dame los nombres/quiénes', SELECT the identifying " + "column(s) (e.g. the name) and return the matching ROWS -- do NOT collapse " + "to a COUNT. Use COUNT/aggregates only when a count or total is requested. " + "If BOTH a count and the names are asked, return the names (the count is " + "derivable from the row count).\n" + "- HIERARCHY questions: when the question asks about a person's TEAM, " + "direct reports, the people 'at their charge' / under them, their org, or " + "movements in THEIR structure, it is a self-referencing hierarchy. A " + "column marked 'HIERARCHY: holds entities/people from column X' holds each " + "row's manager/owner. The person's team = the ROWS where such a column " + "equals that person (filter it with case-insensitive LIKE '%name%'), NOT " + "the person's own row. Try EVERY hierarchy column (a person may appear in " + "more than one), and match names tolerantly (accents/spacing).\n" "- Be a SINGLE statement (no multi-statement; no DDL).\n" "- Be a SELECT (DuckDB-flavored)." ) @@ -542,7 +622,11 @@ async def answer( # into the persisted query record for reproducibility. metric_name = grounded.metrics[0].metric_name compiled, metric_version = await self._compiled_metric_sql( - metric_name, dataset_id, tenant_id=tenant_id, workspace_id=workspace_id + metric_name, + dataset_id, + tenant_id=tenant_id, + workspace_id=workspace_id, + extra_filter=getattr(grounded.metrics[0], "extra_filter", None), ) if compiled: chosen_sql = compiled @@ -577,7 +661,17 @@ async def answer( gen_run = await self._generation_agent.run(gen_prompt) gen_out = getattr(gen_run, "output", gen_run) candidates_json = [c.model_dump() for c in gen_out.candidates] - chosen_sql = gen_out.candidates[0].sql + # Don't blindly take the highest-confidence candidate: probe them + # (DuckDB only, no extra LLM) and prefer one that passes the firewall + # and returns non-empty, non-degenerate rows. Empty candidate list + # degrades to "" (FAILED) instead of raising an IndexError. + chosen_sql = await self._select_best_candidate( + [c.sql for c in gen_out.candidates if c.sql], + dataset_id=dataset_id, + scopes=scopes, + dataset_allowlist=dataset_allowlist, + pins=prior_snapshot_pins, + ) # ------------------------------------------------------------------ # 5. AST classify + scope guard @@ -666,6 +760,7 @@ async def answer( attached = await self._table_resolver.resolve( dataset_id, list(ast.table_refs), + pins=prior_snapshot_pins, ) result = await self._executor.execute(chosen_sql, attached) retries = 0 @@ -715,7 +810,9 @@ async def answer( ) retries += 1 continue - attached = await self._table_resolver.resolve(dataset_id, list(ast.table_refs)) + attached = await self._table_resolver.resolve( + dataset_id, list(ast.table_refs), pins=prior_snapshot_pins + ) result = await self._executor.execute(chosen_sql, attached) retries += 1 @@ -747,6 +844,24 @@ async def answer( # 9. Clarification frame (emitted alongside answer when confidence is low) # ------------------------------------------------------------------ clarification = self._clarification(grounded) + # A syntactically-valid query that returns 0 rows (or a single + # all-NULL/zero aggregate) is suspicious: the usual cause is a + # filter literal that doesn't match how the data is encoded. Rather + # than report it as a confident empty answer, surface a clarification + # and downgrade confidence so the caller knows to verify. + suspicious_empty = isinstance(result, ExecutionResult) and self._is_suspicious_empty(result) + if clarification is None and suspicious_empty: + from flyquery.interfaces.query import ClarificationFrame + + clarification = ClarificationFrame( + questions=[ + "The query executed successfully but returned no matching data " + "(0 rows / empty result). The filter values may not match how the " + "data is encoded -- please verify the exact column values (e.g. " + "category labels or period format) or rephrase the question." + ], + reasons=[], + ) clarification_emitted = clarification is not None # ------------------------------------------------------------------ @@ -796,7 +911,12 @@ async def answer( # ------------------------------------------------------------------ # 12. Auto-learn (only on first-shot OK + no PII + no clarification) # ------------------------------------------------------------------ - if execution_status == "OK" and isinstance(result, ExecutionResult) and not clarification_emitted: + if ( + execution_status == "OK" + and isinstance(result, ExecutionResult) + and result.row_count > 0 + and not clarification_emitted + ): await self._auto_learner.maybe_propose( tenant_id=tenant_id, workspace_id=workspace_id, @@ -811,6 +931,16 @@ async def answer( # ------------------------------------------------------------------ # 13. Persist conversation turn (Phase E drill-down) # ------------------------------------------------------------------ + # THIS turn's snapshot pins: the snapshot each resolved table was + # answered against. Tables already pinned by an earlier turn keep + # their pin (prior wins); newly-referenced tables pin to current. + # Persisting THIS turn's pins (not the prior turn's) is what makes + # drill-down reproducible across a mid-conversation re-ingest. + this_turn_pins: dict[str, str] = { + **(await self._table_resolver.current_snapshots(dataset_id, list(ast.table_refs))), + **prior_snapshot_pins, + } + if ( conversation_id is not None and self._conversation_service is not None @@ -824,7 +954,7 @@ async def answer( executed_sql=chosen_sql, summary=explanation_obj.summary if explanation_obj else None, table_qnames_json=list(ast.table_refs), - snapshot_pins_json=prior_snapshot_pins, + snapshot_pins_json=this_turn_pins, elapsed_ms=elapsed, ) @@ -839,13 +969,85 @@ async def answer( chart_hint=explanation_obj.chart_hint if explanation_obj else None, explanation=explanation_obj.summary if explanation_obj else None, clarification=clarification, - grounded_summary=self._grounded_summary(grounded), + grounded_summary=self._grounded_summary( + grounded, confidence_cap=0.4 if suspicious_empty else None + ), + snapshot_pins=this_turn_pins, ) # ------------------------------------------------------------------ # Internal helpers # ------------------------------------------------------------------ + @staticmethod + def _is_suspicious_empty(result) -> bool: + """True when an executed result is empty/degenerate enough to doubt. + + Catches the canonical wrong-literal symptom: a valid query that + matched nothing (0 rows), or a single-row single-column aggregate + whose only value is NULL / 0 / 0.0 (e.g. a SUM/CASE pivot where + every branch missed). + """ + if result.row_count == 0: + return True + rows = getattr(result, "rows", None) or [] + if result.row_count == 1 and len(rows) == 1 and isinstance(rows[0], dict) and len(rows[0]) == 1: + (only_value,) = rows[0].values() + return only_value is None or only_value == 0 + return False + + async def _select_best_candidate( + self, + candidate_sqls: list[str], + *, + dataset_id: uuid.UUID, + scopes: set[str], + dataset_allowlist: set[uuid.UUID] | None, + pins: dict[str, str], + ) -> str: + """Pick the candidate SQL that best answers the question. + + Generation emits N candidates ranked by self-reported confidence, but + the top one sometimes filters on the wrong column (or under-searches a + set of hierarchy columns) and returns 0 rows while a lower-ranked + candidate is correct. So we probe the candidates and prefer the first + that (a) passes the firewall, (b) executes, and (c) returns non-empty, + non-degenerate rows. This is DuckDB-only -- NO extra LLM calls -- and + general: it just prefers a candidate that actually returns data. + + Falls back to the first candidate that executed at all, else the first + candidate (so the existing scope/critic handling downstream is + unchanged when nothing is clearly better). + """ + if len(candidate_sqls) <= 1: + return candidate_sqls[0] if candidate_sqls else "" + + first_executed: str | None = None + for sql in candidate_sqls: + ast = self._ast_classifier.classify(sql) + table_kinds = await self._table_kinds_by_name(list(ast.table_refs), dataset_id) + dataset_of_table = await self._dataset_of_tables(list(ast.table_refs), dataset_id) + try: + self._scope_guard.check( + classification=ast, + scopes=scopes, + table_kinds_by_name=table_kinds, + dataset_allowlist=dataset_allowlist, + dataset_of_table=dataset_of_table, + ) + except ScopeGuardError: + continue # unsafe candidate -- skip + if sorted({t for t in ast.table_refs if t} - set(table_kinds.keys())): + continue # references a table not in the dataset -- skip + attached = await self._table_resolver.resolve(dataset_id, list(ast.table_refs), pins=pins) + result = await self._executor.execute(sql, attached) + if isinstance(result, ExecutionResult): + if not self._is_suspicious_empty(result): + return sql # passes firewall + returns real rows -- best + if first_executed is None: + first_executed = sql # remember first successful-but-empty + return first_executed or candidate_sqls[0] + async def _table_kinds_by_name( self, table_names: list[str], @@ -886,11 +1088,19 @@ async def _compiled_metric_sql( *, tenant_id: str, workspace_id: uuid.UUID, + extra_filter: str | None = None, ) -> tuple[str | None, int | None]: """Fetch + bind the compiled SQL for a PUBLISHED metric. Returns ``(bound_sql, current_version)`` so the version can be pinned in the query record, or ``(None, None)`` when no usable metric is found. + + ``extra_filter`` is the per-question slice the grounding agent derived + (e.g. ``Market = 'Brazil' AND Year = 'FY24'``) to be appended to the + metric's WHERE via the compiler's ``{extra_filter_clause}`` slot. It is + an LLM-supplied predicate, so it is re-run through the publish-time + firewall before binding; an unsafe filter is dropped (the metric still + returns its unfiltered value) rather than executed. """ if self._semantic_repo is None: return None, None @@ -903,9 +1113,31 @@ async def _compiled_metric_sql( return None, None if not row or not row.get("compiled_sql_template"): return None, None - bound = SemanticCompiler.bind(row["compiled_sql_template"]) + + safe_filter = self._firewall_extra_filter(row["compiled_sql_template"], extra_filter) + bound = SemanticCompiler.bind(row["compiled_sql_template"], extra_filter=safe_filter) return bound, row.get("current_version") + @staticmethod + def _firewall_extra_filter(template: str, extra_filter: str | None) -> str | None: + """Validate an LLM-supplied metric filter via the publish-time firewall. + + Returns the filter when the bound SQL passes ``assert_safe_template``, + else ``None`` (filter dropped). Defensive: any firewall/parse failure + also drops the filter rather than risking an unsafe predicate. + """ + if not extra_filter: + return None + try: + from flyquery.core.services.semantic.firewall import assert_safe_template + + probe = SemanticCompiler.bind(template, extra_filter=extra_filter) + assert_safe_template(probe) + return extra_filter + except Exception as exc: # noqa: BLE001 -- any failure → drop the filter + logger.warning("dropping unsafe semantic extra_filter %r: %s", extra_filter, exc) + return None + def _clarification(self, grounded) -> Any: """Build a ClarificationFrame if grounding confidence is low.""" from flyquery.interfaces.query import ClarificationFrame @@ -917,11 +1149,19 @@ def _clarification(self, grounded) -> Any: ) return None - def _grounded_summary(self, grounded) -> dict: - """Convert GroundedContext to a summary dict for the response.""" + def _grounded_summary(self, grounded, confidence_cap: float | None = None) -> dict: + """Convert GroundedContext to a summary dict for the response. + + ``confidence_cap`` lets the caller lower the reported confidence when + the executed result is suspicious (e.g. 0 rows from a wrong literal), + so a confidently-wrong empty answer is not surfaced at high confidence. + """ + confidence = grounded.confidence + if confidence_cap is not None: + confidence = min(confidence, confidence_cap) return { "path": grounded.path, - "confidence": grounded.confidence, + "confidence": confidence, "table_count": len(grounded.tables), "missing_info": grounded.missing_info, } diff --git a/src/flyquery/core/services/retrieval/reranker.py b/src/flyquery/core/services/retrieval/reranker.py index d3a9fa40..6c117f78 100644 --- a/src/flyquery/core/services/retrieval/reranker.py +++ b/src/flyquery/core/services/retrieval/reranker.py @@ -21,10 +21,16 @@ from __future__ import annotations +import logging from typing import Any, Protocol from flyquery.core.services.retrieval.search_index import Hit +logger = logging.getLogger(__name__) + +# Guard so the "reranking disabled" warning is emitted at most once per process. +_warned_noop_fallback = False + class Reranker(Protocol): """Protocol for a reranking step in the retrieval pipeline.""" @@ -88,10 +94,21 @@ def build_reranker(settings: Any) -> NoopReranker | CrossEncoderReranker: :param settings: ``FlyquerySettings`` instance :return: a ready-to-use reranker """ + global _warned_noop_fallback model_name = getattr(settings, "reranker_model", "") or "" if not model_name: return NoopReranker() try: return CrossEncoderReranker(model_name) - except Exception: # noqa: BLE001 + except Exception as exc: # noqa: BLE001 + if not _warned_noop_fallback: + _warned_noop_fallback = True + logger.warning( + "reranker model=%s unavailable (%s) -- falling back to NoopReranker. " + "Relevance reranking is DISABLED; results are truncated by retrieval " + "order only (install sentence-transformers / make the cross-encoder " + "model loadable to enable it).", + model_name, + exc, + ) return NoopReranker() diff --git a/src/flyquery/core/services/retrieval/search_index.py b/src/flyquery/core/services/retrieval/search_index.py index 8d10f5cc..836eed03 100644 --- a/src/flyquery/core/services/retrieval/search_index.py +++ b/src/flyquery/core/services/retrieval/search_index.py @@ -42,6 +42,115 @@ class Hit: metadata: dict = field(default_factory=dict) +def value_fingerprint( + data_type: str | None, + sample_values_json: object, + profile_json: object, + *, + max_values: int = 40, + max_chars: int = 400, +) -> str: + """Compact, human-readable summary of a column's ACTUAL values. + + Surfaced into the grounding/generation prompts so the agents copy + WHERE / CASE literals verbatim from real values instead of guessing + -- e.g. a fiscal year stored as ``FY23`` (not ``2023``), the members + of a tall/EAV category column (``P&L Line System`` rows like + ``Total Revenue`` / ``Manpower``), or the magnitude gap between a + scaled-duplicate measure (``FY`` ~0.02 vs ``FY (Real)`` ~25748). + + Returns ``""`` when there is nothing useful to show. + """ + prof = profile_json if isinstance(profile_json, dict) else {} + + # NOTE: profiling stores ``subtotal_values`` (name-based candidates for + # pre-aggregated rows). We deliberately do NOT surface them as an + # exclusion directive: a "Total_*" value in a dimension is just as often a + # legitimate additive bucket (e.g. unallocated/corporate) as a true rollup, + # and any hint makes the agent wrongly drop it. Whether to exclude requires + # the structural test (does the value's aggregate == the sum of the others?) + # which is not available per-column at profile time. The general "aggregate + # across ALL values / don't drop a value" prompt rule handles this safely. + subtotal_note = "" + + # Self-referencing hierarchy hint: this column's values are entities from + # another (higher-cardinality) column -- e.g. a manager column whose values + # are people from the employee column. Surfaced even for high-cardinality + # columns that have no listable values, because that is exactly when the + # agent cannot otherwise tell who a person reports to. + ref_col = prof.get("references_column") + ref_note = ( + f" | HIERARCHY: holds entities/people from column '{ref_col}' (e.g. each row's " + f"manager/owner/parent). To get a given person's group/team/reports, filter THIS " + f"column to that person (case-insensitive LIKE), not the person's own row." + if ref_col + else "" + ) + + # Categorical: the stored distinct value set (low-cardinality columns). + top_values = prof.get("top_values") or [] + if top_values: + seen: set[str] = set() + uniq: list[str] = [] + for tv in top_values: + v = tv.get("value") if isinstance(tv, dict) else tv + if v is None: + continue + s = str(v) + if s not in seen: + seen.add(s) + uniq.append(s) + shown = uniq[:max_values] + body = " | ".join(shown) + if len(body) > max_chars: + body = body[:max_chars].rsplit("|", 1)[0].strip() + " | …" + more = "" if len(uniq) <= len(shown) else f" (+{len(uniq) - len(shown)} more)" + return f"values: {body}{more}{subtotal_note}{ref_note}" if body else ref_note.strip(" |") + + # Numeric / temporal: range + cardinality (exposes scaled duplicates). + col_min, col_max = prof.get("min"), prof.get("max") + if col_min is not None or col_max is not None: + rng = f"range: {col_min} .. {col_max}" + dist = prof.get("distinct_estimate") + if dist is not None: + rng += f" (~{dist} distinct)" + return rng + ref_note + + # Fallback: a few raw sample values (high-cardinality columns). + samples = sample_values_json if isinstance(sample_values_json, list) else [] + if samples: + seen2: set[str] = set() + uniq2: list[str] = [] + for v in samples: + s = str(v) + if s not in seen2: + seen2.add(s) + uniq2.append(s) + if uniq2: + return "e.g.: " + " | ".join(uniq2[:8]) + ref_note + return ref_note.strip(" |") + + +def _column_hit(r, score: float) -> "Hit": + """Build a ranked schema-object Hit, enriched with a value fingerprint. + + Used by the BM25 + vector column searches so the ranked "Top-ranked + column matches" the grounding agent sees carry real values, not just + name + description. + """ + fp = value_fingerprint(r.data_type, r.sample_values_json, r.profile_json) + text = f"{r.qualified_name}: {r.data_type}\n{r.description or ''}" + if fp: + text += f"\n{fp}" + return Hit( + source_kind="schema_object", + id=r.id, + text=text, + score=score, + metadata={"qualified_name": r.qualified_name, "table_id": str(r.table_id), "values": fp}, + ) + + class SearchIndex: """Read-only query helpers that operate on a shared ``AsyncSession``.""" @@ -60,10 +169,12 @@ async def bm25_schema_objects(self, query: str, dataset_id: uuid.UUID, limit: in sa.text( """ SELECT o.id, o.qualified_name, o.description, o.data_type, o.table_id, + o.sample_values_json, o.profile_json, ts_rank(o.content_tsv, plainto_tsquery('english', :q)) AS score FROM flyquery_schema_objects o JOIN flyquery_tables t ON t.id = o.table_id WHERE t.dataset_id = :ds AND o.is_active = true + AND o.snapshot_id = t.current_snapshot_id AND o.content_tsv @@ plainto_tsquery('english', :q) ORDER BY score DESC LIMIT :lim @@ -71,16 +182,7 @@ async def bm25_schema_objects(self, query: str, dataset_id: uuid.UUID, limit: in ), {"q": query, "ds": dataset_id, "lim": limit}, ) - return [ - Hit( - source_kind="schema_object", - id=r.id, - text=f"{r.qualified_name}: {r.data_type}\n{r.description or ''}", - score=float(r.score), - metadata={"qualified_name": r.qualified_name, "table_id": str(r.table_id)}, - ) - for r in rows.mappings() - ] + return [_column_hit(r, float(r.score)) for r in rows.mappings()] async def vector_schema_objects( self, @@ -99,26 +201,19 @@ async def vector_schema_objects( sa.text( """ SELECT o.id, o.qualified_name, o.description, o.data_type, o.table_id, + o.sample_values_json, o.profile_json, 1 - (o.embedding <=> CAST(:emb AS vector)) AS score FROM flyquery_schema_objects o JOIN flyquery_tables t ON t.id = o.table_id - WHERE t.dataset_id = :ds AND o.is_active = true AND o.embedding IS NOT NULL + WHERE t.dataset_id = :ds AND o.is_active = true + AND o.snapshot_id = t.current_snapshot_id AND o.embedding IS NOT NULL ORDER BY o.embedding <=> CAST(:emb AS vector) LIMIT :lim """ ), {"emb": str(query_embedding), "ds": dataset_id, "lim": limit}, ) - return [ - Hit( - source_kind="schema_object", - id=r.id, - text=f"{r.qualified_name}: {r.data_type}\n{r.description or ''}", - score=float(r.score), - metadata={"qualified_name": r.qualified_name, "table_id": str(r.table_id)}, - ) - for r in rows.mappings() - ] + return [_column_hit(r, float(r.score)) for r in rows.mappings()] async def all_schema_objects( self, @@ -158,7 +253,9 @@ async def all_schema_objects( ON c.table_id = o.table_id AND c.kind = 'COLUMN' AND c.is_active = true + AND c.snapshot_id = t.current_snapshot_id WHERE t.dataset_id = :ds AND o.is_active = true AND o.kind = 'TABLE' + AND o.snapshot_id = t.current_snapshot_id GROUP BY o.id, o.qualified_name, o.description, o.table_id, o.kind ORDER BY o.qualified_name """ @@ -175,10 +272,12 @@ async def all_schema_objects( await self._session.execute( sa.text( """ - SELECT o.id, o.qualified_name, o.description, o.data_type, o.table_id, o.kind + SELECT o.id, o.qualified_name, o.description, o.data_type, o.table_id, o.kind, + o.sample_values_json, o.profile_json FROM flyquery_schema_objects o JOIN flyquery_tables t ON t.id = o.table_id WHERE t.dataset_id = :ds AND o.is_active = true AND o.kind = 'COLUMN' + AND o.snapshot_id = t.current_snapshot_id ORDER BY o.qualified_name LIMIT :lim """ @@ -223,16 +322,21 @@ async def all_schema_objects( ) for r in column_rows: + fp = value_fingerprint(r["data_type"], r["sample_values_json"], r["profile_json"]) + text = f"{r['qualified_name']}: {r['data_type'] or ''}\n{r['description'] or ''}" + if fp: + text += f"\n{fp}" hits.append( Hit( source_kind="schema_object", id=r["id"], - text=f"{r['qualified_name']}: {r['data_type'] or ''}\n{r['description'] or ''}", + text=text, score=1.0, metadata={ "qualified_name": r["qualified_name"], "table_id": str(r["table_id"]), "kind": "COLUMN", + "values": fp, }, ) ) diff --git a/src/flyquery/web/controllers/query_controller.py b/src/flyquery/web/controllers/query_controller.py index 93169d67..0ddac2b3 100644 --- a/src/flyquery/web/controllers/query_controller.py +++ b/src/flyquery/web/controllers/query_controller.py @@ -51,7 +51,12 @@ from flyquery.core.services.execution.scope_guard import ScopeGuard, ScopeGuardError from flyquery.core.services.execution.table_resolver import TableResolver from flyquery.core.services.query.query_repository import QueryRepository -from flyquery.core.services.query.query_service import QueryService +from flyquery.core.services.query.query_service import ( + QueryService, + _render_critic_prompt, + _render_generation_prompt, + _render_grounding_prompt, +) from flyquery.core.services.query.result_uploader import ResultUploader from flyquery.core.services.retrieval.embedder import Embedder from flyquery.core.services.retrieval.hybrid_retriever import HybridRetriever @@ -131,6 +136,54 @@ def __init__( self._scope_guard = ScopeGuard() self._executor = DuckDBExecutor(settings) + async def _guarded_execute( + self, + sql: str, + ast: Any, + table_kinds: dict[str, str], + resolver: TableResolver, + dataset_id: uuid.UUID, + bundle: dict, + ) -> Any: + """Apply ScopeGuard + bad-tables firewall, then execute. + + Mirrors the guards in ``QueryService.answer`` so the streaming path + enforces the same dataset isolation and table-existence checks. + Returns an ``ExecutionResult`` or an ``ExecutionError`` (which the + caller's critic loop can attempt to refine). + """ + from flyquery.core.services.execution.duckdb_executor import ExecutionError + + try: + self._scope_guard.check( + classification=ast, + scopes=_DEFAULT_USER_SCOPES, + table_kinds_by_name=table_kinds, + dataset_allowlist=None, + dataset_of_table={t: str(dataset_id) for t in ast.table_refs}, + ) + except ScopeGuardError as exc: + return ExecutionError(message=f"Rejected by firewall: {exc}") + + ref_set = {t for t in ast.table_refs if t} + bad_tables = sorted(ref_set - set(table_kinds.keys())) + if bad_tables: + real_tables = sorted(table_kinds.keys()) + [ + (getattr(h, "metadata", {}) or {}).get("qualified_name", "").rsplit(".", 1)[-1] + for h in (bundle.get("schema_inventory") or []) + if (getattr(h, "metadata", {}) or {}).get("kind") == "TABLE" + ] + real_tables = [t for t in dict.fromkeys(real_tables) if t] + return ExecutionError( + message=( + f"Table(s) {bad_tables!r} do not exist in this dataset. " + f"Pick ONLY from: {real_tables[:80]!r}." + ) + ) + + attached = await resolver.resolve(dataset_id, list(ast.table_refs)) + return await self._executor.execute(sql, attached) + def _build_service(self, db_session: AsyncSession) -> QueryService: """Build a per-request QueryService around the provided session.""" index = SearchIndex(db_session) @@ -335,24 +388,30 @@ async def explain( bundle["schema_objects"] = reranked grounding_agent = build_grounding_agent(self._settings) - grounded = await grounding_agent.run( - {"question": body.question, "bundle": bundle, "starting_point_sql": None} + grounded_run = await grounding_agent.run( + _render_grounding_prompt( + question=body.question, bundle=bundle, starting_point_sql=None + ) ) + grounded = getattr(grounded_run, "output", grounded_run) generation_agent = build_generation_agent(self._settings) - gen_out = await generation_agent.run( - {"grounded": grounded, "question": body.question, "starting_point_sql": None} + gen_run = await generation_agent.run( + _render_generation_prompt( + body.question, grounded, None, schema_inventory=bundle.get("schema_inventory") + ) ) - candidate = gen_out.candidates[0] + gen_out = getattr(gen_run, "output", gen_run) + candidate = gen_out.candidates[0] if gen_out.candidates else None clarification: ClarificationFrame | None = None if grounded.confidence < self._settings.grounding_min_confidence and grounded.missing_info: clarification = ClarificationFrame(questions=grounded.missing_info, reasons=[]) return ExplainResponse( - sql=candidate.sql, - reasoning=candidate.reasoning, - confidence=candidate.confidence, + sql=candidate.sql if candidate else "", + reasoning=candidate.reasoning if candidate else "generation produced no candidate", + confidence=candidate.confidence if candidate else 0.0, grounded_summary={ "path": grounded.path, "confidence": grounded.confidence, @@ -398,15 +457,21 @@ async def validate( bundle["schema_objects"] = reranked grounding_agent = build_grounding_agent(self._settings) - grounded = await grounding_agent.run( - {"question": body.question, "bundle": bundle, "starting_point_sql": None} + grounded_run = await grounding_agent.run( + _render_grounding_prompt( + question=body.question, bundle=bundle, starting_point_sql=None + ) ) + grounded = getattr(grounded_run, "output", grounded_run) generation_agent = build_generation_agent(self._settings) - gen_out = await generation_agent.run( - {"grounded": grounded, "question": body.question, "starting_point_sql": None} + gen_run = await generation_agent.run( + _render_generation_prompt( + body.question, grounded, None, schema_inventory=bundle.get("schema_inventory") + ) ) - chosen_sql = gen_out.candidates[0].sql + gen_out = getattr(gen_run, "output", gen_run) + chosen_sql = gen_out.candidates[0].sql if gen_out.candidates else "" ast = self._ast_classifier.classify(chosen_sql) @@ -494,21 +559,28 @@ async def _stream_events( retriever = HybridRetriever(index=index, embedder=self._embedder, rrf_k=self._settings.rrf_k) reranker = build_reranker(self._settings) - # Stage 1: retrieve + ground + # Stage 1: retrieve + ground (same retrieval params + rendered + # prompt as the sync POST /query path, so the streaming path is + # not blind to the column-value catalogue, examples, metrics). bundle = await retriever.retrieve( request.question, dataset_id=request.dataset_id, workspace_id=workspace_id, top_k_schema=self._settings.top_k_schema * 3, + top_k_examples=self._settings.top_k_examples, + top_k_metrics=self._settings.top_k_metrics, ) schema_hits = bundle.get("schema_objects", []) reranked = await reranker.rerank(request.question, schema_hits, top_n=self._settings.top_k_schema) bundle["schema_objects"] = reranked grounding_agent = build_grounding_agent(self._settings) - grounded = await grounding_agent.run( - {"question": request.question, "bundle": bundle, "starting_point_sql": None} + grounded_run = await grounding_agent.run( + _render_grounding_prompt( + question=request.question, bundle=bundle, starting_point_sql=None + ) ) + grounded = getattr(grounded_run, "output", grounded_run) yield _sse_frame( "schema_linked", @@ -537,11 +609,14 @@ async def _stream_events( # Stage 3: generate SQL generation_agent = build_generation_agent(self._settings) - gen_out = await generation_agent.run( - {"grounded": grounded, "question": request.question, "starting_point_sql": None} + gen_run = await generation_agent.run( + _render_generation_prompt( + request.question, grounded, None, schema_inventory=bundle.get("schema_inventory") + ) ) + gen_out = getattr(gen_run, "output", gen_run) candidates = gen_out.candidates - chosen_sql = candidates[0].sql + chosen_sql = candidates[0].sql if candidates else "" yield _sse_frame( "sql_generated", @@ -554,28 +629,38 @@ async def _stream_events( }, ) - # Stage 4: execute (with critic loop) + # Stage 4: AST + firewall/scope guards + execute (with critic loop). + # _guarded_execute applies the SAME ScopeGuard + bad-tables firewall + # the sync path enforces, so streaming callers cannot bypass dataset + # isolation or run SQL against a non-existent/cross-dataset table. ast = self._ast_classifier.classify(chosen_sql) table_resolver = TableResolver(session=db_session, settings=self._settings) - attached = await table_resolver.resolve(request.dataset_id, list(ast.table_refs)) - - exec_result = await self._executor.execute(chosen_sql, attached) + table_kinds = await _table_kinds_by_name(db_session, list(ast.table_refs), request.dataset_id) + exec_result = await self._guarded_execute( + chosen_sql, ast, table_kinds, table_resolver, request.dataset_id, bundle + ) retries = 0 while isinstance(exec_result, ExecutionError) and retries < self._settings.max_refine_retries: critic_agent = build_critic_agent(self._settings) - refined = await critic_agent.run( - { - "sql": chosen_sql, - "error": exec_result.message, - "grounded": grounded, - "question": request.question, - } + refined_run = await critic_agent.run( + _render_critic_prompt( + question=request.question, + failing_sql=chosen_sql, + error_message=exec_result.message, + grounded=grounded, + schema_inventory=bundle.get("schema_inventory"), + ) ) + refined = getattr(refined_run, "output", refined_run) chosen_sql = refined.sql ast = self._ast_classifier.classify(chosen_sql) - attached = await table_resolver.resolve(request.dataset_id, list(ast.table_refs)) - exec_result = await self._executor.execute(chosen_sql, attached) + table_kinds = await _table_kinds_by_name( + db_session, list(ast.table_refs), request.dataset_id + ) + exec_result = await self._guarded_execute( + chosen_sql, ast, table_kinds, table_resolver, request.dataset_id, bundle + ) retries += 1 snapshot_pins: dict = {} @@ -705,6 +790,26 @@ async def _stream_events( yield _sse_frame("final", answer.model_dump(mode="json")) +async def _table_kinds_by_name( + session: AsyncSession, table_names: list[str], dataset_id: uuid.UUID +) -> dict[str, str]: + """Return {name: kind} for the active tables in the dataset (firewall input).""" + if not table_names: + return {} + import sqlalchemy as sa + + rows = await session.execute( + sa.text( + """ + SELECT name, kind FROM flyquery_tables + WHERE dataset_id = :ds AND name = ANY(:names) AND is_active = true + """ + ), + {"ds": dataset_id, "names": list(table_names)}, + ) + return {r["name"]: r["kind"] for r in rows.mappings()} + + def _now_ms() -> int: """Return current monotonic time in milliseconds.""" import time From 277f96ae6cf9b56f19cc0936900acdbee26575d8 Mon Sep 17 00:00:00 2001 From: Jose Agustin Puente Date: Tue, 2 Jun 2026 10:28:09 +0200 Subject: [PATCH 02/20] fix(ci): satisfy PR gate (lockstep, lint, unit/integration tests) - builder.py is a lock-step (canon-pinned) module; revert it and pass the determinism setting via the existing extra_settings={"temperature": 0.0} instead of a new parameter, so the lockstep gate stays green - move the table-kinds lookup out of the query controller into TableResolver (service layer) so the "no raw SQL in controllers" gate passes - ruff: inline a negated return (SIM103), drop a forward-ref quote (UP037), and apply ruff format - tests: extend the fake TableResolvers with pins / current_snapshots / table_kinds_by_name; seed current_snapshot_id in the retrieval integration fixture (retrieval is now scoped to current_snapshot_id, as publish sets it) --- src/flyquery/core/agents/builder.py | 10 ----- .../core/agents/column_name_proposer_agent.py | 2 +- src/flyquery/core/agents/describe_agent.py | 2 +- .../core/agents/rename_detection_agent.py | 2 +- .../core/services/execution/ast_classifier.py | 4 +- .../core/services/execution/table_resolver.py | 21 ++++++++-- .../ingestion/readers/excel_reader.py | 13 +++---- .../core/services/ingestion/stages/profile.py | 4 +- .../core/services/retrieval/search_index.py | 2 +- .../web/controllers/query_controller.py | 38 +++---------------- tests/integration/test_hybrid_retrieval.py | 8 ++++ tests/unit/test_query_controller_sse.py | 8 +++- tests/unit/test_query_service.py | 5 ++- 13 files changed, 54 insertions(+), 65 deletions(-) diff --git a/src/flyquery/core/agents/builder.py b/src/flyquery/core/agents/builder.py index a15e048d..3044bfb2 100644 --- a/src/flyquery/core/agents/builder.py +++ b/src/flyquery/core/agents/builder.py @@ -48,7 +48,6 @@ def build_agent( instructions: str, settings: FlyquerySettings, max_output_tokens: int | None = None, - temperature: float | None = None, extra_settings: dict[str, Any] | None = None, ) -> Any: """Construct a :class:`FireflyAgent` with the standard knobs. @@ -68,13 +67,6 @@ def build_agent( requiring callers to plumb the env var themselves. max_output_tokens: Optional override for this specific call. ``None`` falls back to ``settings.agent_max_output_tokens``. - temperature: Optional sampling temperature folded into - ``model_settings``. ``None`` (the default) leaves the - provider default untouched -- grounding / generation / - critic rely on that diversity (generation samples N - candidates). Naming / description stages pass ``0.0`` so - near-identical re-ingests yield identical names and avoid - schema-change churn. extra_settings: Optional extra ``model_settings`` entries. Caller-provided keys WIN on conflict so a stage can cap below the global budget (e.g. a 1-token classifier). @@ -91,8 +83,6 @@ def build_agent( resolved_max = resolve_max_output_tokens(settings, override=max_output_tokens) model_settings: dict[str, Any] = {"max_tokens": resolved_max} - if temperature is not None: - model_settings["temperature"] = temperature if extra_settings: # Caller-provided settings win on conflict -- a stage can cap # itself below the default by passing ``max_tokens=128`` in diff --git a/src/flyquery/core/agents/column_name_proposer_agent.py b/src/flyquery/core/agents/column_name_proposer_agent.py index e317931d..800e2590 100644 --- a/src/flyquery/core/agents/column_name_proposer_agent.py +++ b/src/flyquery/core/agents/column_name_proposer_agent.py @@ -118,7 +118,7 @@ def build_column_name_proposer_agent(settings): settings=settings, # Deterministic naming: identical re-ingests must yield identical # column names, otherwise reconcile sees phantom schema churn. - temperature=0.0, + extra_settings={"temperature": 0.0}, ) diff --git a/src/flyquery/core/agents/describe_agent.py b/src/flyquery/core/agents/describe_agent.py index 4333e382..0adf0640 100644 --- a/src/flyquery/core/agents/describe_agent.py +++ b/src/flyquery/core/agents/describe_agent.py @@ -142,5 +142,5 @@ def build_describe_agent(settings): settings=settings, # Deterministic descriptions/semantic types: identical columns on # re-ingest must produce identical metadata, no schema-change churn. - temperature=0.0, + extra_settings={"temperature": 0.0}, ) diff --git a/src/flyquery/core/agents/rename_detection_agent.py b/src/flyquery/core/agents/rename_detection_agent.py index dd951a38..b17791d3 100644 --- a/src/flyquery/core/agents/rename_detection_agent.py +++ b/src/flyquery/core/agents/rename_detection_agent.py @@ -64,5 +64,5 @@ def build_rename_detection_agent(settings): max_output_tokens=2048, # Deterministic: the same removed/candidate pair must always # resolve the same way so re-ingests don't flip-flop renames. - temperature=0.0, + extra_settings={"temperature": 0.0}, ) diff --git a/src/flyquery/core/services/execution/ast_classifier.py b/src/flyquery/core/services/execution/ast_classifier.py index dfcd0836..5402588e 100644 --- a/src/flyquery/core/services/execution/ast_classifier.py +++ b/src/flyquery/core/services/execution/ast_classifier.py @@ -83,9 +83,7 @@ def classify(self, sql: str) -> AstClassification: # ``table_refs``; the downstream bad-tables guard then flags it # as a non-existent table and the (otherwise valid) query is # rejected — see QueryService bad-tables set-difference. - cte_names = { - cte.alias_or_name for cte in stmt.find_all(sqlglot.expressions.CTE) if cte.alias_or_name - } + cte_names = {cte.alias_or_name for cte in stmt.find_all(sqlglot.expressions.CTE) if cte.alias_or_name} tables = tuple( sorted( { diff --git a/src/flyquery/core/services/execution/table_resolver.py b/src/flyquery/core/services/execution/table_resolver.py index 0c18785e..8650ba58 100644 --- a/src/flyquery/core/services/execution/table_resolver.py +++ b/src/flyquery/core/services/execution/table_resolver.py @@ -102,9 +102,24 @@ async def resolve( out[r["name"]] = f"{base}/{key}" return out - async def current_snapshots( - self, dataset_id: uuid.UUID, table_names: list[str] - ) -> dict[str, str]: + async def table_kinds_by_name(self, dataset_id: uuid.UUID, table_names: list[str]) -> dict[str, str]: + """Return ``{name: kind}`` for the active tables in the dataset. + + Used by the firewall/bad-tables guard. Lives here (service layer) + rather than in a controller so the raw SQL stays out of the web tier. + """ + if not table_names: + return {} + rows = await self._session.execute( + sa.text(""" + SELECT name, kind FROM flyquery_tables + WHERE dataset_id = :ds AND name = ANY(:names) AND is_active = true + """), + {"ds": dataset_id, "names": list(table_names)}, + ) + return {r["name"]: r["kind"] for r in rows.mappings()} + + async def current_snapshots(self, dataset_id: uuid.UUID, table_names: list[str]) -> dict[str, str]: """Return ``{table_name: current_snapshot_id}`` for the given tables. Used to record THIS turn's snapshot pins so a later drill-down turn diff --git a/src/flyquery/core/services/ingestion/readers/excel_reader.py b/src/flyquery/core/services/ingestion/readers/excel_reader.py index c909facd..91c943c5 100644 --- a/src/flyquery/core/services/ingestion/readers/excel_reader.py +++ b/src/flyquery/core/services/ingestion/readers/excel_reader.py @@ -138,14 +138,11 @@ def _as_number(cell: Any) -> float | None: return None numbers = [_as_number(c) for c in non_empty] - if any(num is None for num in numbers): - # Some populated cell is a non-numeric string -> not a spacer. - return False - - # Every populated cell is numeric and none is a text label. This covers - # both the all-numeric case and, as a strict subset, the contiguous - # ``1..k`` column-numbering run -- both are spacers, never label rows. - return True + # A spacer row has EVERY populated cell numeric and no text label. This + # covers both the all-numeric case and, as a strict subset, the contiguous + # ``1..k`` column-numbering run -- both are spacers, never label rows. Any + # non-numeric (None) populated cell means it is not a spacer. + return all(num is not None for num in numbers) class ExcelReader: diff --git a/src/flyquery/core/services/ingestion/stages/profile.py b/src/flyquery/core/services/ingestion/stages/profile.py index 301c7244..4938650f 100644 --- a/src/flyquery/core/services/ingestion/stages/profile.py +++ b/src/flyquery/core/services/ingestion/stages/profile.py @@ -337,9 +337,7 @@ def _profile_column_sync( # to the subtotal drops detail). No measure join is available # here, so this stays purely structural/textual. if not _is_numeric(data_type) and not _is_temporal(data_type): - subtotal_values = [ - str(r[0]) for r in top_rows if _looks_like_subtotal(str(r[0])) - ] + subtotal_values = [str(r[0]) for r in top_rows if _looks_like_subtotal(str(r[0]))] if subtotal_values: profile["subtotal_values"] = subtotal_values diff --git a/src/flyquery/core/services/retrieval/search_index.py b/src/flyquery/core/services/retrieval/search_index.py index 836eed03..beb828b0 100644 --- a/src/flyquery/core/services/retrieval/search_index.py +++ b/src/flyquery/core/services/retrieval/search_index.py @@ -131,7 +131,7 @@ def value_fingerprint( return ref_note.strip(" |") -def _column_hit(r, score: float) -> "Hit": +def _column_hit(r, score: float) -> Hit: """Build a ranked schema-object Hit, enriched with a value fingerprint. Used by the BM25 + vector column searches so the ranked "Top-ranked diff --git a/src/flyquery/web/controllers/query_controller.py b/src/flyquery/web/controllers/query_controller.py index 0ddac2b3..532cfbf0 100644 --- a/src/flyquery/web/controllers/query_controller.py +++ b/src/flyquery/web/controllers/query_controller.py @@ -389,9 +389,7 @@ async def explain( grounding_agent = build_grounding_agent(self._settings) grounded_run = await grounding_agent.run( - _render_grounding_prompt( - question=body.question, bundle=bundle, starting_point_sql=None - ) + _render_grounding_prompt(question=body.question, bundle=bundle, starting_point_sql=None) ) grounded = getattr(grounded_run, "output", grounded_run) @@ -458,9 +456,7 @@ async def validate( grounding_agent = build_grounding_agent(self._settings) grounded_run = await grounding_agent.run( - _render_grounding_prompt( - question=body.question, bundle=bundle, starting_point_sql=None - ) + _render_grounding_prompt(question=body.question, bundle=bundle, starting_point_sql=None) ) grounded = getattr(grounded_run, "output", grounded_run) @@ -576,9 +572,7 @@ async def _stream_events( grounding_agent = build_grounding_agent(self._settings) grounded_run = await grounding_agent.run( - _render_grounding_prompt( - question=request.question, bundle=bundle, starting_point_sql=None - ) + _render_grounding_prompt(question=request.question, bundle=bundle, starting_point_sql=None) ) grounded = getattr(grounded_run, "output", grounded_run) @@ -635,7 +629,7 @@ async def _stream_events( # isolation or run SQL against a non-existent/cross-dataset table. ast = self._ast_classifier.classify(chosen_sql) table_resolver = TableResolver(session=db_session, settings=self._settings) - table_kinds = await _table_kinds_by_name(db_session, list(ast.table_refs), request.dataset_id) + table_kinds = await table_resolver.table_kinds_by_name(request.dataset_id, list(ast.table_refs)) exec_result = await self._guarded_execute( chosen_sql, ast, table_kinds, table_resolver, request.dataset_id, bundle ) @@ -655,8 +649,8 @@ async def _stream_events( refined = getattr(refined_run, "output", refined_run) chosen_sql = refined.sql ast = self._ast_classifier.classify(chosen_sql) - table_kinds = await _table_kinds_by_name( - db_session, list(ast.table_refs), request.dataset_id + table_kinds = await table_resolver.table_kinds_by_name( + request.dataset_id, list(ast.table_refs) ) exec_result = await self._guarded_execute( chosen_sql, ast, table_kinds, table_resolver, request.dataset_id, bundle @@ -790,26 +784,6 @@ async def _stream_events( yield _sse_frame("final", answer.model_dump(mode="json")) -async def _table_kinds_by_name( - session: AsyncSession, table_names: list[str], dataset_id: uuid.UUID -) -> dict[str, str]: - """Return {name: kind} for the active tables in the dataset (firewall input).""" - if not table_names: - return {} - import sqlalchemy as sa - - rows = await session.execute( - sa.text( - """ - SELECT name, kind FROM flyquery_tables - WHERE dataset_id = :ds AND name = ANY(:names) AND is_active = true - """ - ), - {"ds": dataset_id, "names": list(table_names)}, - ) - return {r["name"]: r["kind"] for r in rows.mappings()} - - def _now_ms() -> int: """Return current monotonic time in milliseconds.""" import time diff --git a/tests/integration/test_hybrid_retrieval.py b/tests/integration/test_hybrid_retrieval.py index dc9abd3f..54bbdb66 100644 --- a/tests/integration/test_hybrid_retrieval.py +++ b/tests/integration/test_hybrid_retrieval.py @@ -78,6 +78,14 @@ async def _seed_table_with_column( ), {"id": snap_id, "t": tenant, "ws": ws_id, "ds": ds_id, "tbl": tbl_id, "hash": "testhash"}, ) + # Publish: point the table at this snapshot. Retrieval is scoped to + # ``current_snapshot_id`` (so re-ingests don't return stale/duplicate + # columns), so a seeded table must have its current snapshot set -- exactly + # as the publish stage does in real ingestion. + await s.execute( + sa.text("UPDATE flyquery_tables SET current_snapshot_id = :snap WHERE id = :tbl"), + {"snap": snap_id, "tbl": tbl_id}, + ) if embedding is not None: vec = str(embedding) await s.execute( diff --git a/tests/unit/test_query_controller_sse.py b/tests/unit/test_query_controller_sse.py index 9f137c09..c786e094 100644 --- a/tests/unit/test_query_controller_sse.py +++ b/tests/unit/test_query_controller_sse.py @@ -89,7 +89,13 @@ class _FakeTableResolver: def __init__(self): self._session = _FakeSession() - async def resolve(self, dataset_id, table_names, object_store_base=None): + async def resolve(self, dataset_id, table_names, object_store_base=None, pins=None): + return {} + + async def table_kinds_by_name(self, dataset_id, table_names): + return {} + + async def current_snapshots(self, dataset_id, table_names): return {} diff --git a/tests/unit/test_query_service.py b/tests/unit/test_query_service.py index 94667aad..6cd6167f 100644 --- a/tests/unit/test_query_service.py +++ b/tests/unit/test_query_service.py @@ -88,7 +88,10 @@ class _FakeTableResolver: def __init__(self): self._session = _FakeSession() - async def resolve(self, dataset_id, table_names, object_store_base=None): + async def resolve(self, dataset_id, table_names, object_store_base=None, pins=None): + return {} + + async def current_snapshots(self, dataset_id, table_names): return {} From 7847a81770a3cbccd60405868c03e1738225d949 Mon Sep 17 00:00:00 2001 From: Jose Agustin Puente Date: Tue, 2 Jun 2026 13:06:03 +0200 Subject: [PATCH 03/20] feat(ingestion): reconstruct multi-row period headers in XLSX sections Financial exports (Orbis/BvD) place one date-header row above a stack of sub-sections. Section-splitting orphaned that header above each sub-section's title, dropping the year columns and making the detailed financial tables (Ratios de Rentabilidad, Memo lineas, etc.) unqueryable by period. A data-first section now inherits the nearest recent period header as its column row, encoded as a backward-compatible 3-index section path ([header:data_start:end]); contiguous sections keep the legacy 2-index form. Guards against misfires: - period values are full-match only (INV-2024-0007 / Form 2020 are not years) - only a single leftmost label column may precede the inherited years - a label-headed table closes the period band (no stale-header bleed) - phantom null columns are compacted; header-row index is bounds-checked Adds unit coverage for inheritance, band-closing/no-false-inherit, path round-trip and legacy-path parsing. --- .../ingestion/readers/excel_reader.py | 189 +++++++++++++++--- .../test_excel_period_header_inheritance.py | 115 +++++++++++ 2 files changed, 271 insertions(+), 33 deletions(-) create mode 100644 tests/unit/test_excel_period_header_inheritance.py diff --git a/src/flyquery/core/services/ingestion/readers/excel_reader.py b/src/flyquery/core/services/ingestion/readers/excel_reader.py index 91c943c5..d2fca8f3 100644 --- a/src/flyquery/core/services/ingestion/readers/excel_reader.py +++ b/src/flyquery/core/services/ingestion/readers/excel_reader.py @@ -55,6 +55,7 @@ from __future__ import annotations import asyncio +import datetime import re import tempfile from pathlib import Path @@ -68,7 +69,18 @@ ) _NAME_SAFE_RE = re.compile(r"[^A-Za-z0-9_]+") -_SECTION_RE = re.compile(r"^(?P.+)#section\[(?P\d+):(?P\d+)\]$") +# ``#section[
:]`` (header row + data on the next rows, contiguous) +# OR ``#section[
::]`` when the header row is NOT +# contiguous with the data (an inherited period header -- see below). +_SECTION_RE = re.compile(r"^(?P.+)#section\[(?P\d+):(?P\d+)(?::(?P\d+))?\]$") +# A period *value* must be the WHOLE cell (a bare year, an ISO date with an +# optional time, or an FY/H/Q-prefixed year) -- NOT merely a string that +# happens to contain a 4-digit year (which would match invoice/reference codes +# like ``INV-2024-0007`` or ``Form 2020`` and wrongly flag a row as a header). +_PERIOD_RE = re.compile( + r"^(?:fy|h[12]|q[1-4])?[\s/-]?(?:19|20)\d{2}(?:-\d{2}-\d{2})?(?:[ t]\d{2}:\d{2}(?::\d{2})?)?$", + re.IGNORECASE, +) # Heuristic constants _MIN_HEADER_NON_EMPTY = 2 # a row needs >= 2 non-empty cells to be a header @@ -76,6 +88,9 @@ # When the first header candidate looks like a numeric/spacer row, look this # many rows ahead for a clearly-better string-label row before settling. _HEADER_LOOKAHEAD = 3 +# Max rows a data-first section may look BACK to inherit a period/date header +# (financial reports repeat a date header above each block of sub-sections). +_PERIOD_HEADER_MAX_DISTANCE = 60 def _normalise_leading_blanks(rows: list[list[Any]]) -> list[list[Any]]: @@ -145,6 +160,37 @@ def _as_number(cell: Any) -> float | None: return all(num is not None for num in numbers) +def _is_period_value(cell: Any) -> bool: + """True when a cell IS an accounting period / date / year label. + + Full-match (not substring) so reference/invoice codes that merely embed a + year (``INV-2024-0007``, ``Form 2020``) are not misread as period headers. + """ + if isinstance(cell, (datetime.date, datetime.datetime)): + return True + if isinstance(cell, str): + return bool(_PERIOD_RE.match(cell.strip())) + return False + + +def _is_period_header_row(row: list[Any]) -> bool: + """True when a row is a period/date header (the bulk of its cells are years/dates). + + Financial-report exports place a single date header (``2024-12-31 ...``) + above a block of sub-sections; we use this to let a following data-first + section inherit those column labels instead of guessing names. + """ + non_empty = [c for c in row if c not in ("", None)] + if len(non_empty) < _MIN_HEADER_NON_EMPTY: + return False + period = sum(1 for c in non_empty if _is_period_value(c)) + return period >= 2 and period * 5 >= len(non_empty) * 3 # >= 60% period-like + + +def _populated_cols(row: list[Any]) -> set[int]: + return {c for c, v in enumerate(row) if v not in ("", None)} + + class ExcelReader: formats = ("xlsx", "xls", "ods") @@ -200,6 +246,7 @@ def _extract_sections(rows: list[list[Any]]) -> list[dict[str, Any]]: sections: list[dict[str, Any]] = [] i = 0 pending_label: str | None = None + last_period_header_idx: int | None = None n = len(rows) while i < n: row = rows[i] @@ -229,7 +276,7 @@ def _extract_sections(rows: list[list[Any]]) -> list[dict[str, Any]]: # a better row exists -- genuinely numeric / period / date headers # (no string-label row just below) are left untouched, as are # single-row sheets. - header_idx = i + own_header_idx = i if _is_numeric_spacer_row(row) and not _looks_like_label_row(row): look_end = min(i + 1 + _HEADER_LOOKAHEAD, n) for la in range(i + 1, look_end): @@ -241,9 +288,45 @@ def _extract_sections(rows: list[list[Any]]) -> list[dict[str, Any]]: if len(la_ne) >= _MIN_HEADER_NON_EMPTY and _looks_like_label_row(rows[la]): # Found a better string-label header just below; treat # the skipped numeric/title rows as pre-header. - header_idx = la + own_header_idx = la break - j = header_idx + 1 + + # Period-header inheritance. Financial-report exports (Orbis/BvD, + # etc.) place ONE date header (``2024-12-31 2023-12-31 ...``) above + # a block of sub-sections (P&L, ratios, ...), each introduced by its + # own title. Section-splitting starts each sub-section at its first + # DATA row, orphaning that shared header above the title -- so the + # value columns get opaque/guessed names instead of the years. When + # a section starts directly with data (its own header row is neither + # label-like nor a period header) and a recent period header covers + # its value columns, adopt that period header as this section's + # column header and treat the section's own first row as data. + own_is_period = _is_period_header_row(rows[own_header_idx]) + own_is_label = _looks_like_label_row(rows[own_header_idx]) + header_row_idx = own_header_idx + data_start = own_header_idx + 1 + inherited = False + if ( + last_period_header_idx is not None + and not own_is_label + and not own_is_period + and own_header_idx - last_period_header_idx <= _PERIOD_HEADER_MAX_DISTANCE + ): + sec_cols = _populated_cols(rows[own_header_idx]) + ph_cols = _populated_cols(rows[last_period_header_idx]) + extra = sec_cols - ph_cols + # The period header must cover the section's value columns. The + # ONLY column it may legitimately not cover is a row-label column + # to the LEFT of the period columns -- never a trailing value + # column (that would shift the inherited year labels by one). + if len(ph_cols & sec_cols) >= _MIN_HEADER_NON_EMPTY and ( + not extra or (len(extra) == 1 and min(extra) < min(ph_cols)) + ): + header_row_idx = last_period_header_idx + data_start = own_header_idx + inherited = True + + j = data_start consecutive_empty = 0 data_end = j # exclusive while j < n: @@ -262,22 +345,30 @@ def _extract_sections(rows: list[list[Any]]) -> list[dict[str, Any]]: data_end = j + 1 j += 1 - n_data_rows = data_end - (header_idx + 1) + # Maintain the active period header. A genuine period/date header + # opens (or renews) a band that the following data-first sub-sections + # inherit; a real label-headed table CLOSES the band so a stale date + # header can't bleed into an unrelated (positionally-overlapping) + # table further down. + if own_is_period: + last_period_header_idx = own_header_idx + elif own_is_label: + last_period_header_idx = None + + n_data_rows = data_end - data_start if n_data_rows >= 1: - # Compute the union of populated column indices across - # the entire section. This is the real column count after - # compaction (we drop empty/merged-padding columns at - # materialise time). - populated_cols: set[int] = set() - for k in range(header_idx, data_end): - for col_idx, cell in enumerate(rows[k]): - if cell not in ("", None): - populated_cols.add(col_idx) + # Populated columns. For a contiguous section the header row is + # part of the table, so include it. For an INHERITED header we + # count only DATA columns, so a period the sub-section does not + # report does not become an all-NULL column. + populated_cols: set[int] = set() if inherited else set(_populated_cols(rows[header_row_idx])) + for k in range(data_start, data_end): + populated_cols |= _populated_cols(rows[k]) sections.append( { "label": pending_label or f"section_{len(sections):02d}", - "header_row_idx": header_idx, - "data_start_idx": header_idx + 1, + "header_row_idx": header_row_idx, + "data_start_idx": data_start, "data_end_idx": data_end, "n_cols": len(populated_cols), "n_data_rows": n_data_rows, @@ -328,9 +419,7 @@ def _enumerate_sync(source_path: str, rules: TableExtractionRules) -> list[Propo out.append( ProposedTable( name=ExcelReader._sanitise(sheet_name), - sheet_or_json_path=( - f"{sheet_name}#section[{s['header_row_idx']}:{s['data_end_idx']}]" - ), + sheet_or_json_path=ExcelReader._section_path(sheet_name, s), n_columns=s["n_cols"], n_rows_estimate=s["n_data_rows"], ) @@ -350,9 +439,7 @@ def _enumerate_sync(source_path: str, rules: TableExtractionRules) -> list[Propo out.append( ProposedTable( name=final_name, - sheet_or_json_path=( - f"{sheet_name}#section[{s['header_row_idx']}:{s['data_end_idx']}]" - ), + sheet_or_json_path=ExcelReader._section_path(sheet_name, s), n_columns=s["n_cols"], n_rows_estimate=s["n_data_rows"], ) @@ -360,16 +447,30 @@ def _enumerate_sync(source_path: str, rules: TableExtractionRules) -> list[Propo return out @staticmethod - def _parse_section_path(path: str) -> tuple[str, int | None, int | None]: - """Split ``#section[:]`` -> (sheet, start, end). + def _section_path(sheet_name: str, s: dict[str, Any]) -> str: + """Encode a section span. ``[h:e]`` when header+data are contiguous, + ``[h:ds:e]`` when the header row is inherited (not adjacent to data).""" + h, ds, e = s["header_row_idx"], s["data_start_idx"], s["data_end_idx"] + return f"{sheet_name}#section[{h}:{e}]" if ds == h + 1 else f"{sheet_name}#section[{h}:{ds}:{e}]" - For backward compat, a plain sheet name (no ``#section[...]``) - returns ``(sheet, None, None)``. + @staticmethod + def _parse_section_path(path: str) -> tuple[str, int | None, int | None, int | None]: + """Split a section path -> ``(sheet, header_idx, data_start, data_end)``. + + Accepts both ``#section[
:]`` (contiguous; data starts + at ``header+1``) and ``#section[
::]`` (an + inherited period header that is NOT adjacent to its data). For backward + compat, a plain sheet name (no ``#section[...]``) returns all ``None``. """ m = _SECTION_RE.match(path or "") if not m: - return path or "", None, None - return m.group("sheet"), int(m.group("start")), int(m.group("end")) + return path or "", None, None, None + header_idx = int(m.group("a")) + if m.group("c") is not None: + data_start, data_end = int(m.group("b")), int(m.group("c")) + else: + data_start, data_end = header_idx + 1, int(m.group("b")) + return m.group("sheet"), header_idx, data_start, data_end @staticmethod def _materialise_sync( @@ -388,7 +489,7 @@ def _materialise_sync( from python_calamine import CalamineWorkbook # pyright: ignore[reportMissingImports] Path(target_parquet_key).parent.mkdir(parents=True, exist_ok=True) - sheet_name, sec_start, sec_end = ExcelReader._parse_section_path( + sheet_name, header_idx, data_start, data_end = ExcelReader._parse_section_path( table.sheet_or_json_path or table.name ) wb = CalamineWorkbook.from_path(source_path) @@ -397,9 +498,27 @@ def _materialise_sync( # the stored section indices slice the intended rows (HDR-UNSTABLE). rows = _normalise_leading_blanks(sheet.to_python(skip_empty_area=True)) - if sec_start is not None and sec_end is not None: - # Section-encoded path -- slice precisely. - section_rows = rows[sec_start:sec_end] + inherited_header = False + if header_idx is not None and data_end is not None: + # Section-encoded path. The header row + the data rows, which may be + # NON-contiguous when the header was inherited from a period header + # above the section's title (financial-report layout). For the + # common contiguous case (data_start == header_idx + 1) this is + # exactly ``rows[header_idx:data_end]``. + # + # ``rows[header_idx]`` is a scalar index, so guard it: if the sheet + # changed between enumerate and materialise (re-ingest drift -- the + # raison d'être of HDR-UNSTABLE) the index can fall past the end. The + # old slice degraded silently; we raise a contextual ValueError + # instead of an opaque IndexError. + if header_idx >= len(rows): + raise ValueError( + f"sheet {sheet_name!r}: header row {header_idx} out of range " + f"(rows={len(rows)}) for table {table.name!r} " + f"(path={table.sheet_or_json_path!r}); sheet changed since enumerate?" + ) + inherited_header = data_start != header_idx + 1 + section_rows = [rows[header_idx]] + rows[data_start:data_end] else: # Legacy / no-section path -- apply the merged-cell title heuristic. body_start = 0 @@ -429,8 +548,12 @@ def _materialise_sync( # Compacting to ONLY the populated indices yields rows that # match the visual "5 yearly columns + label" view a human # sees in Excel. + # For an inherited (non-contiguous) header, compact over the DATA rows + # only -- a period the sub-section doesn't report must not survive as an + # all-NULL year column just because the shared header names it. + compact_rows = section_rows[1:] if inherited_header and len(section_rows) > 1 else section_rows populated: set[int] = set() - for r in section_rows: + for r in compact_rows: for col_idx, cell in enumerate(r): if cell not in ("", None): populated.add(col_idx) diff --git a/tests/unit/test_excel_period_header_inheritance.py b/tests/unit/test_excel_period_header_inheritance.py new file mode 100644 index 00000000..6e7fc342 --- /dev/null +++ b/tests/unit/test_excel_period_header_inheritance.py @@ -0,0 +1,115 @@ +# Copyright 2024-2026 Firefly Software Foundation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Unit tests for period-header inheritance in the XLSX section extractor. + +Financial-report exports (Orbis/BvD) place ONE date header above a block of +sub-sections; section-splitting orphans that header above each sub-section's +title. These tests pin the inheritance behavior + its guards (no false +inherit, leftmost-label-only, legacy path round-trip). +""" + +from __future__ import annotations + +import datetime + +from flyquery.core.services.ingestion.readers.excel_reader import ( + ExcelReader, + _is_period_header_row, + _is_period_value, +) + + +def test_is_period_value_full_match_rejects_embedded_year_codes() -> None: + for ok in ("2024", "2024-12-31", "FY2024", "Q1 2024", "H1 2023"): + assert _is_period_value(ok), ok + assert _is_period_value(datetime.datetime(2024, 12, 31)) + # Codes / addresses that merely *contain* a year must NOT be period values. + for bad in ("INV-2024-0007", "Form 2020", "2001 Main St", "REG-2019-X", "86.21", "Andalucia"): + assert not _is_period_value(bad), bad + + +def test_is_period_header_row_requires_majority_period_cells() -> None: + assert _is_period_header_row(["", "2024", "2023", "2022"]) + assert _is_period_header_row([datetime.date(2024, 12, 31), datetime.date(2023, 12, 31)]) + # A single year among labels is not a header. + assert not _is_period_header_row(["Founded 2024", "CEO", "Revenue"]) + + +def _orbis_like_rows() -> list[list[object]]: + """A miniature Orbis-style sheet: + + one date header governs a data-first sub-section introduced by its own + title; then a label-headed table closes the band; then another data-first + section that must NOT inherit the (now stale) date header. + """ + return [ + ["Financial data", "", "", ""], # 0 title + ["", "2024", "2023", "2022"], # 1 period header (cols 1-3) + ["Profit & Loss", "", "", ""], # 2 title + ["Revenue", 100, 90, 80], # 3 data-first -> inherits row 1 + ["Costs", 40, 30, 20], # 4 data + ["", "", "", ""], # 5 blank + ["", "", "", ""], # 6 blank (section break) + ["Board", "", "", ""], # 7 title + ["Name", "Role", "", ""], # 8 label header (closes the period band) + ["Alice", "CEO", "", ""], # 9 data + ["", "", "", ""], # 10 blank + ["", "", "", ""], # 11 blank + ["Extra metrics", "", "", ""], # 12 title + ["Metric A", 1, 2, 3], # 13 data-first, columns OVERLAP the date header + ["Metric B", 4, 5, 6], # 14 data + ] + + +def test_data_first_section_inherits_period_header() -> None: + secs = ExcelReader._extract_sections(_orbis_like_rows()) + pnl = next(s for s in secs if s["label"] == "Profit & Loss") + # Header is the date row (1), data is non-contiguous (starts at 3). + assert pnl["header_row_idx"] == 1 + assert pnl["data_start_idx"] == 3 + assert pnl["data_end_idx"] == 5 + + +def test_label_headed_table_does_not_inherit_and_closes_the_band() -> None: + secs = ExcelReader._extract_sections(_orbis_like_rows()) + board = next(s for s in secs if s["label"] == "Board") + # Board has its OWN label header -> contiguous, no inheritance. + assert board["data_start_idx"] == board["header_row_idx"] + 1 + + # The later "Extra metrics" section shares column positions with the date + # header, but the band was CLOSED by the Board table -> it must NOT inherit. + extra = next(s for s in secs if s["label"] == "Extra metrics") + assert extra["data_start_idx"] == extra["header_row_idx"] + 1 + + +def test_section_path_round_trip_contiguous_and_inherited() -> None: + # Contiguous -> 2-index form (byte-identical to legacy). + s_contig = {"header_row_idx": 5, "data_start_idx": 6, "data_end_idx": 9} + p = ExcelReader._section_path("Sheet1", s_contig) + assert p == "Sheet1#section[5:9]" + assert ExcelReader._parse_section_path(p) == ("Sheet1", 5, 6, 9) + + # Inherited (non-contiguous) -> 3-index form. + s_inh = {"header_row_idx": 1, "data_start_idx": 3, "data_end_idx": 5} + p2 = ExcelReader._section_path("Sheet1", s_inh) + assert p2 == "Sheet1#section[1:3:5]" + assert ExcelReader._parse_section_path(p2) == ("Sheet1", 1, 3, 5) + + +def test_parse_section_path_legacy_and_plain() -> None: + # Legacy 2-index path still parses (already-stored tables). + assert ExcelReader._parse_section_path("S#section[2:7]") == ("S", 2, 3, 7) + # Plain sheet name -> all None. + assert ExcelReader._parse_section_path("JustASheet") == ("JustASheet", None, None, None) From c135bcc35a5340025ebac05022d34a7163e1099c Mon Sep 17 00:00:00 2001 From: Jose Agustin Puente Date: Tue, 30 Jun 2026 13:08:07 +0200 Subject: [PATCH 04/20] =?UTF-8?q?feat(query+ingest):=20unify=20value-ancho?= =?UTF-8?q?ring=20superset=20onto=20the=20NL=E2=86=92SQL=20branch?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reconciles the two parallel lines of the NL→SQL quality work into a single branch that carries every refinement from both, with no capability lost. Kept from this branch (execution-layer robustness): - TableResolver / AstClassifier / profile hardening and the query_controller surface, plus their unit/integration tests. - The XLSX multi-row period-header reconstruction (embedded-year rejection, band-closing, 3-index section paths) and its test. - PII-safe value rendering in the embed corpus. Brought in (the value-anchoring superset): - value_anchoring.py: the dataset-agnostic backbone (per-column value catalogue, value→column + group resolution, entity disambiguation by live row-match count + hierarchy intent, degenerate/zero-row detection, signed (mixed-sign) measure handling incl. the SUM(CASE WHEN cost THEN -m) shape, CTE-aware guards, function firewall). - query_service orchestration: candidate execution-selection, a non-destructive repair loop (never replaces a correct answer with a worse one), zero-row and signed-measure repair, group-coverage advisory. - Deterministic period/date column naming at ingest (year_YYYY / period_YYYY_MM_DD), original-header preservation, and the value-anchoring prompt rules for grounding / generation / critic / explainer. - LexicalReranker as the dependency-free default (a strict win over the no-op). - temperature=0 for the deterministic ingest agents (describe / column-name / rename / relation), applied via the existing extra_settings hook. Cross-line graft: the column hierarchy hint (references_column, computed by the profile stage) is now surfaced in the retrieval column fingerprint, so a self-referencing manager/owner column tells the agent to filter THAT column to find a person's reports instead of their own row. Gate notes: - builder.py stays byte-identical to canon (lockstep) -- temperature=0 rides the existing extra_settings path, no new parameter. - ruff check + format clean; lockstep 21/21. - test_query_service: the _FakeSettings stub gains the value-anchoring knobs (features off, so the orchestration tests stay focused on the core answer() flow), and the retry-on-error test now uses a realistic non-degenerate refined SQL with a table-aware resolver so the critic round is actually exercised. --- src/flyquery/config.py | 17 + .../core/agents/relation_proposer_agent.py | 2 + .../core/services/ingestion/reader.py | 5 + .../core/services/ingestion/stages/parse.py | 67 + .../services/ingestion/stages/reconcile.py | 48 +- .../core/services/query/query_service.py | 1168 +++++++++++------ .../core/services/query/value_anchoring.py | 795 +++++++++++ .../services/retrieval/hybrid_retriever.py | 6 + .../core/services/retrieval/reranker.py | 67 +- .../core/services/retrieval/search_index.py | 276 ++-- src/flyquery/resources/prompts/critic.yaml | 30 +- src/flyquery/resources/prompts/explainer.yaml | 14 +- .../resources/prompts/generation.yaml | 34 + src/flyquery/resources/prompts/grounding.yaml | 29 +- tests/integration/test_reranker.py | 16 +- tests/unit/test_query_service.py | 63 +- 16 files changed, 2044 insertions(+), 593 deletions(-) create mode 100644 src/flyquery/core/services/query/value_anchoring.py diff --git a/src/flyquery/config.py b/src/flyquery/config.py index e8b27add..ab3cc00e 100644 --- a/src/flyquery/config.py +++ b/src/flyquery/config.py @@ -181,6 +181,23 @@ class FlyquerySettings(BaseSettings): reranker_top_n: int = 30 query_expansion_enabled: bool = False + # Value-anchoring / grounding-quality knobs. The ingest pipeline already + # computes a per-column value catalogue (profile_json.top_values, min/max, + # distinct_estimate) + a semantic_type; these control how it is surfaced to + # the SQL writer at query time. All dataset-agnostic. + value_catalog_enabled: bool = True # render real column values into prompts + value_catalog_max_values: int = 25 # distinct values shown per column + value_catalog_char_budget: int = 320 # char cap on the value list per column + value_catalog_max_columns: int = 80 # cap columns that get a value line (prompt budget) + entity_resolution_enabled: bool = True # map question literals -> owning column + entity_resolution_max_literals: int = 8 # cap live value-scan probes per query + zero_row_repair_enabled: bool = True # repair queries that run but return 0 rows + candidate_exec_selection: bool = True # execute top candidates, pick a non-empty/non-degenerate one + synthesis_function_firewall: bool = True # block read_csv_auto/pg_read_file/... in generated SQL + group_resolution_enabled: bool = True # term -> full set of catalogued values it umbrellas + signed_measure_repair_enabled: bool = True # observed-sign probe on subtractions over a signed measure + group_coverage_repair_enabled: bool = True # advise when an IN-list under-covers a detected value group + # PII pii_scanner: Literal["regex", "presidio", "disabled"] = "regex" pii_policy_samples: Literal["warn", "redact", "reject"] = "redact" diff --git a/src/flyquery/core/agents/relation_proposer_agent.py b/src/flyquery/core/agents/relation_proposer_agent.py index 769df771..7405c03d 100644 --- a/src/flyquery/core/agents/relation_proposer_agent.py +++ b/src/flyquery/core/agents/relation_proposer_agent.py @@ -56,4 +56,6 @@ def build_relation_proposer_agent(settings): output_type=ProposedRelations, instructions=prompt.instructions, settings=settings, + # Deterministic relation proposals across re-ingests. + extra_settings={"temperature": 0.0}, ) diff --git a/src/flyquery/core/services/ingestion/reader.py b/src/flyquery/core/services/ingestion/reader.py index f631d0be..0f213ddf 100644 --- a/src/flyquery/core/services/ingestion/reader.py +++ b/src/flyquery/core/services/ingestion/reader.py @@ -51,6 +51,11 @@ class ColumnSchema: data_type: str is_nullable: bool position: int + # The source's ORIGINAL header before any rename (e.g. an Excel year header + # '2024' that the column-name proposer collapsed to ``year_1``). Preserved so + # the query layer can recover what a renamed column actually meant, instead of + # relying on a fixed ordinal convention. None when the name was not renamed. + original_name: str | None = None @dataclass(frozen=True) diff --git a/src/flyquery/core/services/ingestion/stages/parse.py b/src/flyquery/core/services/ingestion/stages/parse.py index fea6ebaf..362b51cd 100644 --- a/src/flyquery/core/services/ingestion/stages/parse.py +++ b/src/flyquery/core/services/ingestion/stages/parse.py @@ -56,6 +56,52 @@ def _sanitise_name(name: str) -> str: return _SAFE_NAME_RE.sub("_", name).strip("_") or "table" +def _period_name_from_header(header: str | None) -> str | None: + """Deterministic column name for a header that IS a calendar period. + + ``'2024'`` / ``'FY2024'`` / ``'2024f'`` -> ``year_2024``; + ``'2024-12-31'`` / ``'31/12/2024'`` -> ``period_2024_12_31``. + Returns None for anything that is not clearly a year/date header (e.g. + ``'Operating revenue'``), so only genuine period columns are stabilised. + Generic — recognises the period from the source's own header, no domain rule. + """ + if not header: + return None + s = str(header).strip() + if not s or len(s) > 40: + return None + for pat, idx in ( + (r"^(\d{4})[-/.](\d{1,2})[-/.](\d{1,2})$", (1, 2, 3)), + (r"^(\d{1,2})[-/.](\d{1,2})[-/.](\d{4})$", (3, 2, 1)), + ): + m = re.match(pat, s) + if m: + y, mo, d = int(m.group(idx[0])), int(m.group(idx[1])), int(m.group(idx[2])) + if 1900 <= y <= 2100 and 1 <= mo <= 12 and 1 <= d <= 31: + return f"period_{y}_{mo:02d}_{d:02d}" + m = re.match(r"(?i)^(?:fy[\s_]*)?(\d{4})f?$", s) + if m: + y = int(m.group(1)) + if 1900 <= y <= 2100: + return f"year_{y}" + return None + + +def _apply_deterministic_period_names(originals: list[str], proposed: list[str]) -> list[str]: + """Override the LLM proposer for columns whose ORIGINAL header is a year/date, + so period columns are named stably + correctly across re-ingests (round-2).""" + out = list(proposed) + changed = False + for i, orig in enumerate(originals): + nm = _period_name_from_header(orig) + if nm and out[i] != nm: + out[i] = nm + changed = True + if changed: + out = _dedupe_names(out, fallback_prefix="period") + return out + + def _sanitise_proposed_name(name: str) -> str: """Best-effort enforcement of snake_case identifier rules on agent output.""" cleaned = _SAFE_NAME_RE.sub("_", name).strip("_").lower() @@ -161,6 +207,22 @@ async def _propose_meaningful_column_names( at least scoped to the section. """ current_names = [c.name for c in mat_result.columns] + + # Deterministically clean year/date headers FIRST -- before the + # needs_proposal gate, which skips columns that already look "meaningful" + # (a date column does). This turns '2024-12-31' -> period_2024_12_31 and + # '2024' -> year_2024 stably across re-ingests, and renames the Parquet so + # the stored column matches. + period_named = _apply_deterministic_period_names(current_names, list(current_names)) + if period_named != current_names: + await _rename_parquet_columns( + parquet_path=parquet_path, + current_columns=current_names, + proposed_columns=period_named, + ) + mat_result = _rebuild_mat_result(mat_result, period_named) + current_names = period_named + if not needs_proposal(current_names): return mat_result @@ -224,6 +286,9 @@ async def _propose_meaningful_column_names( ) proposed = fallback + # Safety net: clean any remaining year/date names the proposer produced. + proposed = _apply_deterministic_period_names(current_names, proposed) + if proposed == current_names: return mat_result @@ -256,6 +321,8 @@ def _rebuild_mat_result( data_type=c.data_type, is_nullable=c.is_nullable, position=c.position, + # remember the original header iff it actually changed + original_name=(c.name if new_names[i] != c.name else None), ) for i, c in enumerate(mat_result.columns) ), diff --git a/src/flyquery/core/services/ingestion/stages/reconcile.py b/src/flyquery/core/services/ingestion/stages/reconcile.py index 54dd9a37..def9e4f0 100644 --- a/src/flyquery/core/services/ingestion/stages/reconcile.py +++ b/src/flyquery/core/services/ingestion/stages/reconcile.py @@ -27,6 +27,7 @@ import hashlib import json import logging +import re import uuid from dataclasses import dataclass from typing import Any, cast @@ -40,6 +41,47 @@ normalize_synonyms_json, ) +_SYNTHETIC_HEADER = re.compile(r"(?i)^(column|col|unnamed|field|sheet)[\s_:.\-]*\d*$") + + +def _plausible_original_header(name: str | None) -> str | None: + """Return a real source header worth preserving, else None. + + Keeps meaningful headers (incl. plain years like '2024') but drops synthetic + placeholders (column5, Unnamed: 0) and obvious null tokens, so the surfaced + 'original header' is signal, not noise. Fully generic. + """ + if not name: + return None + s = str(name).strip() + if not s or len(s) > 60: + return None + if _SYNTHETIC_HEADER.match(s): + return None + if s.lower() in {"none", "null", "nan", "n/a", "na", "-"}: + return None + # A header that is just a number is almost certainly a mis-detected data cell; + # skip it -- UNLESS it is a plausible 4-digit year (a real period header). + try: + float(s.replace(",", "")) + if not (s.isdigit() and len(s) == 4 and 1900 <= int(s) <= 2100): + return None + except ValueError: + pass # non-numeric header -> keep + return s + + +def _governance_with_header(annotation: dict, col: Any) -> str: + """Serialise governance_json, merging the column's plausible original header.""" + gov = normalize_governance_json(annotation.get("governance_json")) + if not isinstance(gov, dict): + gov = {} + oh = _plausible_original_header(getattr(col, "original_name", None)) + if oh and not gov.get("original_header"): + gov = {**gov, "original_header": oh} + return json.dumps(gov) + + # Rename auto-confirm threshold (passed from settings when available) _DEFAULT_AUTO_CONFIRM_THRESHOLD = 0.8 @@ -281,9 +323,9 @@ async def run_reconcile( "pii_tag": annotation.get("pii_tag"), "pii_source": annotation.get("pii_source"), "business_owner": annotation.get("business_owner"), - "governance_json": json.dumps( - normalize_governance_json(annotation.get("governance_json")) - ), + # round-2 #3: preserve the source's original header (pre-rename) + # so the query layer knows what e.g. year_1 actually was. + "governance_json": _governance_with_header(annotation, col), }, ) diff --git a/src/flyquery/core/services/query/query_service.py b/src/flyquery/core/services/query/query_service.py index ffbd8b41..99f5e6c3 100644 --- a/src/flyquery/core/services/query/query_service.py +++ b/src/flyquery/core/services/query/query_service.py @@ -44,6 +44,7 @@ from flyquery.core.services.execution.ast_classifier import AstClassifier from flyquery.core.services.execution.duckdb_executor import ExecutionError, ExecutionResult from flyquery.core.services.execution.scope_guard import ScopeGuard, ScopeGuardError +from flyquery.core.services.query import value_anchoring from flyquery.core.services.semantic.compiler import SemanticCompiler logger = logging.getLogger(__name__) @@ -128,33 +129,6 @@ def _render_grounding_prompt( out.append(f"- `{qn}` :: {text}") out.append("") - # 2b. The "Column value catalogue" lists EVERY column with its real - # values (distinct set for low-cardinality columns; numeric - # range otherwise). This is the ground truth the agent must copy - # filter/CASE literals from -- it prevents guessing wrong - # literals (`Year IN (2023)` when the values are `FY23`), maps a - # question entity to the column whose values contain it - # (`DAPA` lives in a column's values, not a column name), and - # reveals tall/EAV layouts (P&L line items are VALUES of a single - # column) and scaled-duplicate measures (`FY` vs `FY (Real)`). - inv_columns = [h for h in inventory if (getattr(h, "metadata", {}) or {}).get("kind") == "COLUMN"] - cols_with_values = [h for h in inv_columns if (getattr(h, "metadata", {}) or {}).get("values")] - if cols_with_values: - out.append(f"# Column value catalogue ({len(cols_with_values)} columns)") - out.append( - "Real values per column. When the question names an entity (a brand, " - "year, market, category, P&L line, team…) that is NOT a column name, " - "find the column whose values contain it and filter THAT column. Copy " - "filter/CASE literals VERBATIM from these values (values may be encoded, " - "e.g. a year shown as `FY23`). If several columns share members, prefer " - "the one whose values match the question most precisely." - ) - for h in cols_with_values: - md = getattr(h, "metadata", None) or {} - qn = md.get("qualified_name") or "?" - out.append(f"- `{qn}` :: {md.get('values')}") - out.append("") - examples = bundle.get("examples", []) or [] if examples: out.append(f"# Approved Q→SQL examples ({len(examples)})") @@ -209,23 +183,47 @@ def _render_grounding_prompt( return "\n".join(out) +def _lookup_col(qn: str, cat_by_qn: dict) -> dict | None: + if qn in cat_by_qn: + return cat_by_qn[qn] + # tolerate grounding returning a shorter/unqualified column name + tail = qn.rsplit(".", 1)[-1].lower() + for k, v in cat_by_qn.items(): + if k.rsplit(".", 1)[-1].lower() == tail: + return v + return None + + def _render_generation_prompt( question: str, grounded: Any, starting_point_sql: str | None, *, schema_inventory: list[Any] | None = None, + col_catalog: list[dict] | None = None, + resolved_entities: list[dict] | None = None, + resolved_groups: list[dict] | None = None, + hierarchy_intent: bool = False, + examples: list[Any] | None = None, + n_candidates: int = 3, + max_columns: int = 80, + char_budget: int = 320, ) -> str: - """Pack the grounded context into a SQL-generation prompt. - - The ``schema_inventory`` fallback is appended even when grounding - returned a non-empty tables list -- the inventory acts as a - safety net the generation agent can fall back on if it judges - the grounded set incomplete (e.g. needs a join to a table the - grounding agent missed). Without this fallback, generation - hallucinates plausible-but-nonexistent tables like - ``balance_sheet`` whenever grounding under-selects. + """Pack the grounded context + the per-column VALUE CATALOGUE into a prompt. + + The generation prompt now shows, for each in-scope column, its data_type, + semantic role (measure/dimension/time), and the actual distinct VALUES (or + numeric range) the column holds -- so the SQL writer copies real filter + literals instead of inventing them. Question entities that were located in + the data are listed explicitly. All sourced from the dataset's own + ingest-time profiling; nothing is hardcoded. """ + from collections import defaultdict + + cat_by_qn = {c["qualified_name"]: c for c in (col_catalog or [])} + cols_by_table: dict[str, list[dict]] = defaultdict(list) + for c in col_catalog or []: + cols_by_table[c["qualified_name"].rsplit(".", 1)[0]].append(c) out: list[str] = [] out.append("# User question") @@ -239,15 +237,62 @@ def _render_generation_prompt( out.append("```") out.append("") + if resolved_entities: + out.append("# Resolved entities (literals located in the data)") + out.append( + "These exact question literals were FOUND as stored values. Filter on " + "the stated column with the stated value verbatim. When a literal was " + "found in MORE THAN ONE column, the number of rows it matches is shown:" + ) + for e in resolved_entities[:24]: + cnt = e.get("match_count") + tag = "" + if cnt is not None: + role = "repeats → grouping/parent key" if cnt > 1 else "appears once → identity" + tag = f" — matches {cnt} row(s), {role}" + out.append(f"- '{e['literal']}' → column `{e['column']}` (stored value: {e['value']!r}){tag}") + if hierarchy_intent: + out.append( + "NOTE: this is a hierarchy / team / reporting question. Filter the column where the " + "entity REPEATS across rows (the parent/manager key), NOT where it appears once (its " + "own identity row). Prefer the table with the MOST matching rows over a stale one." + ) + top = max( + (e for e in resolved_entities if (e.get("match_count") or 0) > 1), + key=lambda e: e.get("match_count") or 0, + default=None, + ) + if top is not None: + out.append( + f" >> Best binding: filter on `{top['column']}` (the entity matches " + f"{top['match_count']} rows there) — query THAT column in THAT table; ignore " + f"tables/columns where the name appears only 0–1 times." + ) + out.append("") + + if resolved_groups: + out.append("# Resolved value groups (a term that spans several stored values)") + out.append( + "Each question term below is an umbrella over MULTIPLE values of one column — it " + "means the WHOLE set, never a subset:" + ) + for g in resolved_groups[:12]: + col = g["column"].rsplit(".", 1)[-1] + vlist = ", ".join(repr(v) for v in g["values"]) + if g.get("truncated"): + out.append( + f"- '{g['literal']}' spans column `{col}` (the catalogued list is INCOMPLETE) — " + f"use `{col} LIKE '{g['literal']}%'` to capture every member." + ) + else: + out.append( + f"- '{g['literal']}' spans these values in `{col}`: [{vlist}] — " + f"use IN(all of them) or `{col} LIKE '{g['literal']}%'`; never a subset." + ) + out.append("") + inv = schema_inventory or [] inv_tables = [h for h in inv if (getattr(h, "metadata", {}) or {}).get("kind") == "TABLE"] - # Map qualified_name -> value fingerprint so the generator copies - # filter/CASE literals verbatim from real values rather than guessing. - value_index: dict[str, str] = {} - for h in inv: - md = getattr(h, "metadata", None) or {} - if md.get("kind") == "COLUMN" and md.get("values"): - value_index[md.get("qualified_name")] = md.get("values") if inv_tables: out.append(f"# Complete dataset catalogue ({len(inv_tables)} tables)") out.append( @@ -276,13 +321,54 @@ def _render_generation_prompt( for t in g_tables: out.append(f"- `{getattr(t, 'table_qualified_name', t)}`") out.append("") - if g_columns: - out.append("## Columns in scope (with real values — copy literals verbatim)") + + # Full, value-anchored column listing for every in-scope table. This both + # raises recall (the right column may have ranked below top-12) and gives + # the SQL writer the real literal vocabulary for each column. + rendered = 0 + table_qns = [getattr(t, "table_qualified_name", str(t)) for t in g_tables] + if not table_qns: + # No grounded tables: fall back to every table that has columns. + table_qns = list(cols_by_table.keys()) + if table_qns: + out.append("## Columns with values (use these literals verbatim)") + for tqn in table_qns: + cols = cols_by_table.get(tqn) or [] + if not cols: + # match by table-name tail when grounding used a short qn + tail = tqn.rsplit(".", 1)[-1].lower() + for k, v in cols_by_table.items(): + if k.rsplit(".", 1)[-1].lower() == tail: + cols = v + break + if not cols: + continue + out.append(f"### `{tqn}`") + for c in cols: + if rendered >= max_columns: + out.append("- … (column list truncated)") + break + out.append( + "- " + + value_anchoring.render_catalog_from_meta( + c["qualified_name"], c, char_budget=char_budget + ) + ) + rendered += 1 + out.append("") + if rendered >= max_columns: + break + elif g_columns: + out.append("## Columns in scope") for c in g_columns: - cqn = getattr(c, "column_qualified_name", c) - vals = value_index.get(cqn) - out.append(f"- `{cqn}`" + (f" :: {vals}" if vals else "")) + qn = getattr(c, "column_qualified_name", str(c)) + meta = _lookup_col(qn, cat_by_qn) + if meta: + out.append("- " + value_anchoring.render_catalog_from_meta(qn, meta, char_budget=char_budget)) + else: + out.append(f"- `{qn}`") out.append("") + if g_joins: out.append("## Approved joins") for j in g_joins: @@ -293,62 +379,34 @@ def _render_generation_prompt( ) out.append("") - # Full column-value catalogue -- the grounding agent may under-select - # columns, so expose every column's real values here too. This is the - # source of truth for WHERE / CASE literals. - if value_index: - out.append(f"# Column value catalogue ({len(value_index)} columns)") - out.append( - "Real values per column. Copy filter/CASE literals VERBATIM from these. " - "If the question names an entity that is not a column name, filter the " - "column whose values contain it." - ) - for qn, vals in value_index.items(): - out.append(f"- `{qn}` :: {vals}") + if examples: + out.append(f"# Worked examples (approved Q→SQL, {len(examples)})") + for h in examples[:5]: + md = getattr(h, "metadata", None) or {} + out.append(f"- Q: {md.get('question', '')}\n SQL: `{md.get('generated_sql', '')}`") out.append("") out.append("# Task") out.append( - "Generate up to N candidate DuckDB SQL queries that answer the question, " + f"Generate {n_candidates} candidate DuckDB SQL queries that answer the question, " "ordered by confidence (highest first). Each candidate must:\n" - "- Use only the tables and columns listed above. " - "Reference each table by its **unqualified name** (the last segment of the " - "qualified name shown above), e.g. write `FROM IVI_MALAGA_SL__Activos` " - "rather than `FROM orbis_companies.IVI_MALAGA_SL__Activos`.\n" - "- Quote any column name that isn't a plain identifier (e.g. date-shaped " - 'names like `2024-12-31` must be `"2024-12-31"`).\n' - "- Copy every WHERE / CASE / IN literal VERBATIM from the column value " - "catalogue above -- never invent or reformat a value (a year is `FY23`, " - "not `2023`; a market may be `Brazil` or `44000BR Brazil` -- use exactly " - "what is listed).\n" - "- When the metric the user names is not a column but appears among a " - "column's listed values, filter that column (tall/EAV layout): e.g. P&L " - "line items like `Total Revenue` / `Manpower` are VALUES of a single " - "category column, selected with `CASE WHEN \"\" = 'Total Revenue' …`.\n" - "- When two numeric columns are near-duplicates whose ranges differ by a " - "constant factor (~10^k), they are the same measure at different scales -- " - "prefer the larger-magnitude one for monetary sums.\n" - "- Do NOT add a WHERE filter on a dimension the question did not ask to " - "slice by -- aggregate across ALL of its values, and do NOT drop a row " - "just because a category value's name contains 'total'/'all' (those are " - "usually legitimate, often 'unallocated', buckets). Exclude a value only " - "if you can confirm it is literally the sum of the other rows.\n" - "- Return what is ASKED FOR: if the question asks for names, a list, " - "'who', 'which', or 'dame los nombres/quiénes', SELECT the identifying " - "column(s) (e.g. the name) and return the matching ROWS -- do NOT collapse " - "to a COUNT. Use COUNT/aggregates only when a count or total is requested. " - "If BOTH a count and the names are asked, return the names (the count is " - "derivable from the row count).\n" - "- HIERARCHY questions: when the question asks about a person's TEAM, " - "direct reports, the people 'at their charge' / under them, their org, or " - "movements in THEIR structure, it is a self-referencing hierarchy. A " - "column marked 'HIERARCHY: holds entities/people from column X' holds each " - "row's manager/owner. The person's team = the ROWS where such a column " - "equals that person (filter it with case-insensitive LIKE '%name%'), NOT " - "the person's own row. Try EVERY hierarchy column (a person may appear in " - "more than one), and match names tolerantly (accents/spacing).\n" - "- Be a SINGLE statement (no multi-statement; no DDL).\n" - "- Be a SELECT (DuckDB-flavored)." + "- Use only the tables and columns listed above. Reference each table by its " + "**unqualified name** (the last segment of the qualified name).\n" + "- For every WHERE / GROUP BY / JOIN literal, COPY a value shown in the " + "'values:' list of that column VERBATIM (exact case + spelling). Do NOT invent " + "or translate filter literals. If the question's entity matches a value under a " + "DIFFERENT column than you expected, filter on the column that actually holds it " + "(see 'Resolved entities').\n" + "- For a year/period/time column whose values are strings (e.g. 'FY23'), filter " + "with the STRING form shown -- never an integer like 2023, and never use a numeric " + "measure column as the year axis.\n" + "- Aggregate measure columns; filter/group on dimension/time columns.\n" + "- NEVER emit a no-op query (e.g. `WHERE 1=0`, `SUM(CASE WHEN ... THEN 0 ELSE 0 END)`, " + "or a constant SELECT). If you cannot map a needed filter to a real value, widen or " + "omit that filter and lower your confidence rather than returning a placeholder.\n" + '- Quote any column name that isn\'t a plain identifier (e.g. `"2024-12-31"`, ' + '`"P&L Line"`).\n' + "- Be a SINGLE SELECT statement (no multi-statement; no DDL)." ) return "\n".join(out) @@ -360,20 +418,30 @@ def _render_critic_prompt( error_message: str, grounded: Any, schema_inventory: list[Any] | None = None, + value_hints: list[str] | None = None, ) -> str: out: list[str] = [] out.append("# User question") out.append(question.strip()) out.append("") - out.append("# Failing SQL") + out.append("# Previous SQL (needs repair)") out.append("```sql") out.append(failing_sql.strip()) out.append("```") out.append("") - out.append("# DuckDB execution error") + out.append("# Problem") out.append(error_message.strip()) out.append("") + # The actual stored values of the columns the failing query filtered on -- + # so the critic replaces wrong literals with real ones instead of guessing + # again (this is what fixes the silent 0-row failures). + if value_hints: + out.append("# Column value catalogue (verify EVERY filter literal against these)") + for line in value_hints: + out.append(f"- {line}") + out.append("") + # Full dataset catalogue -- the critic's most common failure mode # is rewriting one hallucinated table name into another (e.g. # ``balance_sheet`` -> ``financials.balance_sheet`` rather than @@ -610,26 +678,28 @@ async def answer( grounded = getattr(grounded_run, "output", grounded_run) # ------------------------------------------------------------------ - # 4. SQL generation (semantic-layer fast path OR synthesis) + # 4. Value catalogue + entity / group resolution (G1/G3 + round-2 #1/#2) + # ------------------------------------------------------------------ + col_catalog = bundle.get("column_catalog") or [] + resolution = await self._resolve_entities(dataset_id, question, col_catalog, bundle) + resolved_entities = resolution["entities"] + resolved_groups = resolution["groups"] + hierarchy_intent = resolution["hierarchy_intent"] + + # ------------------------------------------------------------------ + # 5. SQL generation (semantic-layer fast path OR synthesis) # ------------------------------------------------------------------ chosen_sql: str candidates_json: list = [] + candidate_sqls: list[str] = [] if grounded.path == "SEMANTIC_LAYER" and grounded.metrics: - # Fetch + bind the published metric's compiled SQL. When found, the - # bound SQL goes straight to the AST firewall + executor — the - # GenerationAgent is NOT invoked — and the metric version is pinned - # into the persisted query record for reproducibility. metric_name = grounded.metrics[0].metric_name compiled, metric_version = await self._compiled_metric_sql( - metric_name, - dataset_id, - tenant_id=tenant_id, - workspace_id=workspace_id, - extra_filter=getattr(grounded.metrics[0], "extra_filter", None), + metric_name, dataset_id, tenant_id=tenant_id, workspace_id=workspace_id ) if compiled: - chosen_sql = compiled + candidate_sqls = [compiled] candidates_json = [ { "sql": compiled, @@ -639,185 +709,177 @@ async def answer( "metric_version": metric_version, } ] - else: - # Fall through to synthesis if no compiled SQL found - gen_prompt = _render_generation_prompt( - question, - grounded, - starting_point_sql, - schema_inventory=bundle.get("schema_inventory"), - ) - gen_run = await self._generation_agent.run(gen_prompt) - gen_out = getattr(gen_run, "output", gen_run) - candidates_json = [c.model_dump() for c in gen_out.candidates] - chosen_sql = gen_out.candidates[0].sql - else: + if not candidate_sqls: gen_prompt = _render_generation_prompt( question, grounded, starting_point_sql, schema_inventory=bundle.get("schema_inventory"), + col_catalog=col_catalog, + resolved_entities=resolved_entities, + resolved_groups=resolved_groups, + hierarchy_intent=hierarchy_intent, + examples=bundle.get("examples"), + n_candidates=self._settings.generation_candidates, + max_columns=self._settings.value_catalog_max_columns, + char_budget=self._settings.value_catalog_char_budget, ) gen_run = await self._generation_agent.run(gen_prompt) gen_out = getattr(gen_run, "output", gen_run) candidates_json = [c.model_dump() for c in gen_out.candidates] - # Don't blindly take the highest-confidence candidate: probe them - # (DuckDB only, no extra LLM) and prefer one that passes the firewall - # and returns non-empty, non-degenerate rows. Empty candidate list - # degrades to "" (FAILED) instead of raising an IndexError. - chosen_sql = await self._select_best_candidate( - [c.sql for c in gen_out.candidates if c.sql], - dataset_id=dataset_id, - scopes=scopes, - dataset_allowlist=dataset_allowlist, - pins=prior_snapshot_pins, - ) + candidate_sqls = [c.sql for c in gen_out.candidates if getattr(c, "sql", None)] + if not candidate_sqls: + candidate_sqls = [""] # ------------------------------------------------------------------ - # 5. AST classify + scope guard + # 6. Candidate selection by EXECUTION (G5): drop degenerate, prefer a + # candidate that runs AND returns rows. Each candidate passes the + # scope guard + synthesis function firewall (G8) + table guard (G6). # ------------------------------------------------------------------ - ast = self._ast_classifier.classify(chosen_sql) - table_kinds = await self._table_kinds_by_name(list(ast.table_refs), dataset_id) - dataset_of_table = await self._dataset_of_tables(list(ast.table_refs), dataset_id) + ordered = [s for s in candidate_sqls if not value_anchoring.is_degenerate_sql(s)] or candidate_sqls + select_pool = ordered if self._settings.candidate_exec_selection else ordered[:1] + + best: tuple[str, Any, Any] | None = None + scope_reject: ScopeGuardError | None = None + firewall_reject: str | None = None + for cand in select_pool: + run = await self._run_sql_once(cand, dataset_id, scopes, dataset_allowlist, bundle) + if run["status"] == "scope": + scope_reject = run["error"] + continue + if run["status"] == "firewall": + firewall_reject = run["error"] + continue + if best is None: + best = (cand, run["result"], run["ast"]) + res = run["result"] + if ( + isinstance(res, ExecutionResult) + and res.row_count > 0 + and not value_anchoring.is_degenerate_sql(cand) + ): + best = (cand, res, run["ast"]) + break - try: - self._scope_guard.check( - classification=ast, - scopes=scopes, - table_kinds_by_name=table_kinds, - dataset_allowlist=dataset_allowlist, - dataset_of_table=dataset_of_table, - ) - except ScopeGuardError as exc: - elapsed = (time.monotonic_ns() // 1_000_000) - start_ms - query_id = await self._query_repo.create_query( - tenant_id=tenant_id, - workspace_id=workspace_id, - dataset_id=dataset_id, - question=question, - semantic_path_taken=grounded.path, - candidates_json=candidates_json, - chosen_candidate_index=0, - executed_sql=chosen_sql, - ast_classification=ast.classification, - execution_status="REJECTED_BY_FIREWALL", - retries=0, - row_count=None, - elapsed_ms=elapsed, - clarification_emitted=False, - clarification_json=None, - pii_findings_json=None, - error_json={"scope_error": str(exc)}, + if best is None: + # Nothing executed. If the only blockers were scope/firewall, reject. + if scope_reject is not None or firewall_reject is not None: + reason = str(scope_reject) if scope_reject is not None else (firewall_reject or "") + chosen_sql = ordered[0] + ast = self._ast_classifier.classify(chosen_sql) + elapsed = (time.monotonic_ns() // 1_000_000) - start_ms + query_id = await self._query_repo.create_query( + tenant_id=tenant_id, + workspace_id=workspace_id, + dataset_id=dataset_id, + question=question, + semantic_path_taken=grounded.path, + candidates_json=candidates_json, + chosen_candidate_index=0, + executed_sql=chosen_sql, + ast_classification=ast.classification, + execution_status="REJECTED_BY_FIREWALL", + retries=0, + row_count=None, + elapsed_ms=elapsed, + clarification_emitted=False, + clarification_json=None, + pii_findings_json=None, + error_json={"firewall_error": reason}, + ) + return AnswerResult( + query_id=query_id, + sql=chosen_sql, + execution_status="REJECTED_BY_FIREWALL", + preview=None, + row_count=None, + truncated=False, + elapsed_ms=elapsed, + chart_hint=None, + explanation=None, + clarification=self._clarification(grounded), + grounded_summary=self._grounded_summary(grounded), + ) + chosen_sql = ordered[0] + best = ( + chosen_sql, + ExecutionError(message="generation produced no usable SQL"), + self._ast_classifier.classify(chosen_sql), ) - return AnswerResult( - query_id=query_id, - sql=chosen_sql, - execution_status="REJECTED_BY_FIREWALL", - preview=None, - row_count=None, - truncated=False, - elapsed_ms=elapsed, - chart_hint=None, - explanation=None, - clarification=self._clarification(grounded), - grounded_summary=self._grounded_summary(grounded), + + chosen_sql, result, ast = best + chosen_index = candidate_sqls.index(chosen_sql) if chosen_sql in candidate_sqls else 0 + retries = 0 + + def _is_good(r, s) -> bool: + return ( + isinstance(r, ExecutionResult) + and r.row_count > 0 + and not value_anchoring.is_degenerate_sql(s) ) + # round-2 #4: remember the best correct result so an ADVISORY repair can + # never replace a correct answer with a worse one. + best_ok = (chosen_sql, result, ast) if _is_good(result, chosen_sql) else None + + # round-2 #5B/#7: when the result is already OK, an advisory check may still + # ask the critic to reconsider (signed-measure double-subtraction; an IN-list + # that under-covers a value group). It rides the non-destructive loop below, + # so it can only ever improve the answer or be ignored. + adv_msg = None + if _is_good(result, chosen_sql): + adv_msg = await self._advisory_repair(chosen_sql, ast, col_catalog, question, dataset_id, bundle) + # ------------------------------------------------------------------ - # 6. Resolve parquet paths + execute (with critic loop) + # 7. Repair loop: HARD repair (error / degenerate / 0-row-with-filter) OR an + # ADVISORY reconsideration. The critic receives the REAL stored values of + # the filtered columns so it replaces wrong literals/columns/signs instead + # of guessing again, and MAY keep the original SQL if it is already correct. # ------------------------------------------------------------------ - # Pre-execution guard: detect SQL that references a table not in - # the dataset. ``_table_kinds_by_name`` returns ONLY matching - # rows -- a missing table simply has no key in the dict. So - # the bad-tables check is set-difference against - # ``ast.table_refs``, not a None-value sweep. - # - # The LLM occasionally hallucinates ``balance_sheet`` / - # ``income_statement`` / ``financials.*`` despite the prompt - # rules; rather than waiting for DuckDB to emit a generic - # ``Catalog Error: Table does not exist``, we synthesise a - # sharp ExecutionError that the existing critic loop picks - # up. The critic prompt receives the full dataset catalogue - # so the rewrite has the real table names in scope. - ref_set = {t for t in ast.table_refs if t} - bad_tables = sorted(ref_set - set(table_kinds.keys())) - if bad_tables: - real_tables = sorted(table_kinds.keys()) + [ - (getattr(h, "metadata", {}) or {}).get("qualified_name", "").rsplit(".", 1)[-1] - for h in (bundle.get("schema_inventory") or []) - if (getattr(h, "metadata", {}) or {}).get("kind") == "TABLE" - ] - real_tables = [t for t in dict.fromkeys(real_tables) if t] - result: ExecutionResult | ExecutionError = ExecutionError( - message=( - f"Table(s) {bad_tables!r} do not exist in this dataset. " - f"Pick ONLY from this catalogue (and translate as needed: " - f"Spanish `Activos` = Assets, `Cuenta de Pérdidas y Ganancias` " - f"= Profit & Loss): {real_tables[:80]!r}." - ) - ) - else: - attached = await self._table_resolver.resolve( - dataset_id, - list(ast.table_refs), - pins=prior_snapshot_pins, - ) - result = await self._executor.execute(chosen_sql, attached) - retries = 0 - - while isinstance(result, ExecutionError) and retries < self._settings.max_refine_retries: + while ( + self._needs_repair(result, chosen_sql) or adv_msg + ) and retries < self._settings.max_refine_retries: + if self._needs_repair(result, chosen_sql): + critic_msg = self._repair_message(result, chosen_sql, ast, col_catalog) + else: + critic_msg = adv_msg + value_hints = self._build_value_hints(chosen_sql, col_catalog, ast) critic_prompt = _render_critic_prompt( question=question, failing_sql=chosen_sql, - error_message=result.message, + error_message=critic_msg, grounded=grounded, schema_inventory=bundle.get("schema_inventory"), + value_hints=value_hints, ) refined_run = await self._critic_agent.run(critic_prompt) refined = getattr(refined_run, "output", refined_run) - chosen_sql = refined.sql - ast = self._ast_classifier.classify(chosen_sql) - table_kinds = await self._table_kinds_by_name(list(ast.table_refs), dataset_id) - dataset_of_table = await self._dataset_of_tables(list(ast.table_refs), dataset_id) - try: - self._scope_guard.check( - classification=ast, - scopes=scopes, - table_kinds_by_name=table_kinds, - dataset_allowlist=dataset_allowlist, - dataset_of_table=dataset_of_table, - ) - except ScopeGuardError: + new_sql = getattr(refined, "sql", None) or chosen_sql + if new_sql.strip() == chosen_sql.strip(): + break # critic kept the SQL -> accept it as already correct + if value_anchoring.is_degenerate_sql(new_sql): + break # never adopt a placeholder; best_ok (if any) is restored below + chosen_sql = new_sql + run = await self._run_sql_once(chosen_sql, dataset_id, scopes, dataset_allowlist, bundle) + if run["status"] in ("scope", "firewall"): break - # Re-apply the unknown-table guard on the refined SQL too -- - # otherwise the critic could hallucinate a different - # non-existent table and DuckDB would catch it generically. - ref_set = {t for t in ast.table_refs if t} - bad_tables = sorted(ref_set - set(table_kinds.keys())) - if bad_tables: - real_tables = sorted(table_kinds.keys()) + [ - (getattr(h, "metadata", {}) or {}).get("qualified_name", "").rsplit(".", 1)[-1] - for h in (bundle.get("schema_inventory") or []) - if (getattr(h, "metadata", {}) or {}).get("kind") == "TABLE" - ] - real_tables = [t for t in dict.fromkeys(real_tables) if t] - result = ExecutionError( - message=( - f"Refined SQL still references missing table(s) " - f"{bad_tables!r}. The dataset only contains: " - f"{real_tables[:80]!r}." - ) - ) - retries += 1 - continue - attached = await self._table_resolver.resolve( - dataset_id, list(ast.table_refs), pins=prior_snapshot_pins - ) - result = await self._executor.execute(chosen_sql, attached) + result = run["result"] + ast = run["ast"] retries += 1 + if _is_good(result, chosen_sql): + best_ok = (chosen_sql, result, ast) + adv_msg = await self._advisory_repair( + chosen_sql, ast, col_catalog, question, dataset_id, bundle + ) + else: + adv_msg = None + + # round-2 #4: if repair degraded a previously-correct answer, restore it. + if best_ok is not None and not _is_good(result, chosen_sql): + chosen_sql, result, ast = best_ok # ------------------------------------------------------------------ - # 7. Determine execution status + # 8. Determine execution status # ------------------------------------------------------------------ if isinstance(result, ExecutionResult) and retries == 0: execution_status: str = "OK" @@ -841,27 +903,10 @@ async def answer( explanation_obj = getattr(explanation_run, "output", explanation_run) # ------------------------------------------------------------------ - # 9. Clarification frame (emitted alongside answer when confidence is low) + # 9. Clarification frame (low confidence, OR confident-but-still-empty) # ------------------------------------------------------------------ - clarification = self._clarification(grounded) - # A syntactically-valid query that returns 0 rows (or a single - # all-NULL/zero aggregate) is suspicious: the usual cause is a - # filter literal that doesn't match how the data is encoded. Rather - # than report it as a confident empty answer, surface a clarification - # and downgrade confidence so the caller knows to verify. - suspicious_empty = isinstance(result, ExecutionResult) and self._is_suspicious_empty(result) - if clarification is None and suspicious_empty: - from flyquery.interfaces.query import ClarificationFrame - - clarification = ClarificationFrame( - questions=[ - "The query executed successfully but returned no matching data " - "(0 rows / empty result). The filter values may not match how the " - "data is encoded -- please verify the exact column values (e.g. " - "category labels or period format) or rephrase the question." - ], - reasons=[], - ) + final_row_count = result.row_count if isinstance(result, ExecutionResult) else None + clarification = self._clarification(grounded, row_count=final_row_count) clarification_emitted = clarification is not None # ------------------------------------------------------------------ @@ -879,7 +924,7 @@ async def answer( question=question, semantic_path_taken=grounded.path, candidates_json=candidates_json, - chosen_candidate_index=0, + chosen_candidate_index=chosen_index, executed_sql=chosen_sql, ast_classification=ast.classification, execution_status=execution_status, @@ -911,12 +956,7 @@ async def answer( # ------------------------------------------------------------------ # 12. Auto-learn (only on first-shot OK + no PII + no clarification) # ------------------------------------------------------------------ - if ( - execution_status == "OK" - and isinstance(result, ExecutionResult) - and result.row_count > 0 - and not clarification_emitted - ): + if execution_status == "OK" and isinstance(result, ExecutionResult) and not clarification_emitted: await self._auto_learner.maybe_propose( tenant_id=tenant_id, workspace_id=workspace_id, @@ -926,21 +966,12 @@ async def answer( retries=retries, pii_findings=[], query_id=query_id, + row_count=result.row_count, ) # ------------------------------------------------------------------ # 13. Persist conversation turn (Phase E drill-down) # ------------------------------------------------------------------ - # THIS turn's snapshot pins: the snapshot each resolved table was - # answered against. Tables already pinned by an earlier turn keep - # their pin (prior wins); newly-referenced tables pin to current. - # Persisting THIS turn's pins (not the prior turn's) is what makes - # drill-down reproducible across a mid-conversation re-ingest. - this_turn_pins: dict[str, str] = { - **(await self._table_resolver.current_snapshots(dataset_id, list(ast.table_refs))), - **prior_snapshot_pins, - } - if ( conversation_id is not None and self._conversation_service is not None @@ -954,7 +985,7 @@ async def answer( executed_sql=chosen_sql, summary=explanation_obj.summary if explanation_obj else None, table_qnames_json=list(ast.table_refs), - snapshot_pins_json=this_turn_pins, + snapshot_pins_json=prior_snapshot_pins, elapsed_ms=elapsed, ) @@ -969,85 +1000,13 @@ async def answer( chart_hint=explanation_obj.chart_hint if explanation_obj else None, explanation=explanation_obj.summary if explanation_obj else None, clarification=clarification, - grounded_summary=self._grounded_summary( - grounded, confidence_cap=0.4 if suspicious_empty else None - ), - snapshot_pins=this_turn_pins, + grounded_summary=self._grounded_summary(grounded), ) # ------------------------------------------------------------------ # Internal helpers # ------------------------------------------------------------------ - @staticmethod - def _is_suspicious_empty(result) -> bool: - """True when an executed result is empty/degenerate enough to doubt. - - Catches the canonical wrong-literal symptom: a valid query that - matched nothing (0 rows), or a single-row single-column aggregate - whose only value is NULL / 0 / 0.0 (e.g. a SUM/CASE pivot where - every branch missed). - """ - if result.row_count == 0: - return True - rows = getattr(result, "rows", None) or [] - if result.row_count == 1 and len(rows) == 1 and isinstance(rows[0], dict) and len(rows[0]) == 1: - (only_value,) = rows[0].values() - return only_value is None or only_value == 0 - return False - - async def _select_best_candidate( - self, - candidate_sqls: list[str], - *, - dataset_id: uuid.UUID, - scopes: set[str], - dataset_allowlist: set[uuid.UUID] | None, - pins: dict[str, str], - ) -> str: - """Pick the candidate SQL that best answers the question. - - Generation emits N candidates ranked by self-reported confidence, but - the top one sometimes filters on the wrong column (or under-searches a - set of hierarchy columns) and returns 0 rows while a lower-ranked - candidate is correct. So we probe the candidates and prefer the first - that (a) passes the firewall, (b) executes, and (c) returns non-empty, - non-degenerate rows. This is DuckDB-only -- NO extra LLM calls -- and - general: it just prefers a candidate that actually returns data. - - Falls back to the first candidate that executed at all, else the first - candidate (so the existing scope/critic handling downstream is - unchanged when nothing is clearly better). - """ - if len(candidate_sqls) <= 1: - return candidate_sqls[0] if candidate_sqls else "" - - first_executed: str | None = None - for sql in candidate_sqls: - ast = self._ast_classifier.classify(sql) - table_kinds = await self._table_kinds_by_name(list(ast.table_refs), dataset_id) - dataset_of_table = await self._dataset_of_tables(list(ast.table_refs), dataset_id) - try: - self._scope_guard.check( - classification=ast, - scopes=scopes, - table_kinds_by_name=table_kinds, - dataset_allowlist=dataset_allowlist, - dataset_of_table=dataset_of_table, - ) - except ScopeGuardError: - continue # unsafe candidate -- skip - if sorted({t for t in ast.table_refs if t} - set(table_kinds.keys())): - continue # references a table not in the dataset -- skip - attached = await self._table_resolver.resolve(dataset_id, list(ast.table_refs), pins=pins) - result = await self._executor.execute(sql, attached) - if isinstance(result, ExecutionResult): - if not self._is_suspicious_empty(result): - return sql # passes firewall + returns real rows -- best - if first_executed is None: - first_executed = sql # remember first successful-but-empty - return first_executed or candidate_sqls[0] - async def _table_kinds_by_name( self, table_names: list[str], @@ -1088,19 +1047,11 @@ async def _compiled_metric_sql( *, tenant_id: str, workspace_id: uuid.UUID, - extra_filter: str | None = None, ) -> tuple[str | None, int | None]: """Fetch + bind the compiled SQL for a PUBLISHED metric. Returns ``(bound_sql, current_version)`` so the version can be pinned in the query record, or ``(None, None)`` when no usable metric is found. - - ``extra_filter`` is the per-question slice the grounding agent derived - (e.g. ``Market = 'Brazil' AND Year = 'FY24'``) to be appended to the - metric's WHERE via the compiler's ``{extra_filter_clause}`` slot. It is - an LLM-supplied predicate, so it is re-run through the publish-time - firewall before binding; an unsafe filter is dropped (the metric still - returns its unfiltered value) rather than executed. """ if self._semantic_repo is None: return None, None @@ -1113,55 +1064,438 @@ async def _compiled_metric_sql( return None, None if not row or not row.get("compiled_sql_template"): return None, None - - safe_filter = self._firewall_extra_filter(row["compiled_sql_template"], extra_filter) - bound = SemanticCompiler.bind(row["compiled_sql_template"], extra_filter=safe_filter) + bound = SemanticCompiler.bind(row["compiled_sql_template"]) return bound, row.get("current_version") - @staticmethod - def _firewall_extra_filter(template: str, extra_filter: str | None) -> str | None: - """Validate an LLM-supplied metric filter via the publish-time firewall. - - Returns the filter when the bound SQL passes ``assert_safe_template``, - else ``None`` (filter dropped). Defensive: any firewall/parse failure - also drops the filter rather than risking an unsafe predicate. - """ - if not extra_filter: - return None - try: - from flyquery.core.services.semantic.firewall import assert_safe_template - - probe = SemanticCompiler.bind(template, extra_filter=extra_filter) - assert_safe_template(probe) - return extra_filter - except Exception as exc: # noqa: BLE001 -- any failure → drop the filter - logger.warning("dropping unsafe semantic extra_filter %r: %s", extra_filter, exc) - return None - - def _clarification(self, grounded) -> Any: - """Build a ClarificationFrame if grounding confidence is low.""" + def _clarification(self, grounded, *, row_count: int | None = None) -> Any: + """Build a ClarificationFrame if grounding confidence is low or the + (confident) query still returned 0 rows (G7 -- couple clarification to + the observed empty result instead of confidence alone).""" from flyquery.interfaces.query import ClarificationFrame if grounded.confidence < self._settings.grounding_min_confidence and grounded.missing_info: + return ClarificationFrame(questions=grounded.missing_info, reasons=[]) + if row_count == 0: return ClarificationFrame( - questions=grounded.missing_info, + questions=[ + "The query executed but matched 0 rows -- a filter value, period, " + "or entity may not match how it is stored in the data. Please confirm " + "the exact value you mean." + ], reasons=[], ) return None - def _grounded_summary(self, grounded, confidence_cap: float | None = None) -> dict: - """Convert GroundedContext to a summary dict for the response. - - ``confidence_cap`` lets the caller lower the reported confidence when - the executed result is suspicious (e.g. 0 rows from a wrong literal), - so a confidently-wrong empty answer is not surfaced at high confidence. - """ - confidence = grounded.confidence - if confidence_cap is not None: - confidence = min(confidence, confidence_cap) + def _grounded_summary(self, grounded) -> dict: + """Convert GroundedContext to a summary dict for the response.""" return { "path": grounded.path, - "confidence": confidence, + "confidence": grounded.confidence, "table_count": len(grounded.tables), "missing_info": grounded.missing_info, } + + # ------------------------------------------------------------------ + # Value-anchoring / repair helpers (G2/G3/G5/G6/G8) + # ------------------------------------------------------------------ + + async def _run_sql_once( + self, + sql: str, + dataset_id: uuid.UUID, + scopes: set[str], + dataset_allowlist: set[str] | None, + bundle: dict, + ) -> dict: + """Classify, guard, and execute one candidate SQL. + + Returns ``{status, result, ast, error}`` where status is one of + ``ok`` / ``empty`` / ``error`` / ``scope`` / ``firewall``. + """ + ast = self._ast_classifier.classify(sql) + + # G8: block filesystem/exfiltration table-functions on the synthesis path. + if self._settings.synthesis_function_firewall: + dangerous = value_anchoring.find_dangerous_functions(sql) + if dangerous: + return { + "status": "firewall", + "result": None, + "ast": ast, + "error": f"disallowed function(s) in generated SQL: {sorted(dangerous)}", + } + + table_kinds = await self._table_kinds_by_name(list(ast.table_refs), dataset_id) + dataset_of_table = await self._dataset_of_tables(list(ast.table_refs), dataset_id) + try: + self._scope_guard.check( + classification=ast, + scopes=scopes, + table_kinds_by_name=table_kinds, + dataset_allowlist=dataset_allowlist, + dataset_of_table=dataset_of_table, + ) + except ScopeGuardError as exc: + return {"status": "scope", "result": None, "ast": ast, "error": exc} + + # G6: CTE-aware unknown-table guard. CTE / derived-table aliases are NOT + # real tables, so subtract them before the set-difference -- otherwise a + # valid `WITH x AS (...) SELECT ... FROM x` is wrongly rejected. + synthetic = {n.lower() for n in value_anchoring.cte_and_derived_names(sql)} + ref_set = {t for t in ast.table_refs if t and t.lower() not in synthetic} + bad_tables = sorted(ref_set - set(table_kinds.keys())) + if bad_tables: + real_tables = sorted(table_kinds.keys()) + [ + (getattr(h, "metadata", {}) or {}).get("qualified_name", "").rsplit(".", 1)[-1] + for h in (bundle.get("schema_inventory") or []) + if (getattr(h, "metadata", {}) or {}).get("kind") == "TABLE" + ] + real_tables = [t for t in dict.fromkeys(real_tables) if t] + return { + "status": "error", + "result": ExecutionError( + message=( + f"Table(s) {bad_tables!r} do not exist in this dataset. " + f"Use ONLY these tables: {real_tables[:80]!r}." + ) + ), + "ast": ast, + "error": None, + } + + attached = await self._table_resolver.resolve(dataset_id, list(ast.table_refs)) + result = await self._executor.execute(sql, attached) + if isinstance(result, ExecutionResult): + status = "ok" if result.row_count > 0 else "empty" + else: + status = "error" + return {"status": status, "result": result, "ast": ast, "error": None} + + def _needs_repair(self, result, sql: str) -> bool: + """A query needs repair if it errored, is degenerate, or ran to 0 rows + while filtering on equality/IN literals (G2/G5).""" + if isinstance(result, ExecutionError): + return True + if value_anchoring.is_degenerate_sql(sql): + return True + return bool( + self._settings.zero_row_repair_enabled + and isinstance(result, ExecutionResult) + and result.row_count == 0 + and value_anchoring.equality_predicate_columns(sql) + ) + + def _repair_message(self, result, sql: str, ast, col_catalog: list[dict]) -> str: + unknown = self._unknown_columns(ast, col_catalog, sql) + suffix = "" + if unknown: + names = sorted({c.get("qualified_name", "").rsplit(".", 1)[-1] for c in col_catalog}) + suffix = ( + f" Also: column(s) {unknown!r} are not real columns -- use only these " + f"columns: {names[:80]!r}." + ) + if isinstance(result, ExecutionError): + return result.message + suffix + if value_anchoring.is_degenerate_sql(sql): + return ( + "The previous SQL is a no-op (constant/placeholder, e.g. WHERE 1=0 or " + "SUM(CASE..THEN 0 ELSE 0)). Rewrite it to actually compute the answer " + "using real columns and literal values from the catalogue below." + suffix + ) + return ( + "The previous SQL executed but returned 0 ROWS. One or more filter literals " + "or filtered columns is wrong. Replace each WHERE/IN literal with a value that " + "actually appears in that column (see the value catalogue). If the entity belongs " + "to a different column, filter THAT column instead." + suffix + ) + + def _build_value_hints(self, sql: str, col_catalog: list[dict], ast) -> list[str]: + """Render value-catalogue lines for the columns the failing SQL touched.""" + wanted: set[str] = {c.lower() for c in value_anchoring.equality_predicate_columns(sql)} + wanted |= {c.lower() for c in (getattr(ast, "column_refs", ()) or ())} + hints: list[str] = [] + seen: set[str] = set() + for c in col_catalog: + tail = c["qualified_name"].rsplit(".", 1)[-1].lower() + if tail in wanted and tail not in seen: + seen.add(tail) + hints.append(value_anchoring.render_catalog_from_meta(c["qualified_name"], c)) + return hints[:40] + + def _unknown_columns(self, ast, col_catalog: list[dict], sql: str) -> list[str]: + if not col_catalog: + return [] + known = {c["qualified_name"].rsplit(".", 1)[-1].lower() for c in col_catalog} + aliases = value_anchoring.select_aliases(sql) + out: list[str] = [] + for c in getattr(ast, "column_refs", ()) or (): + cl = c.lower() + if cl not in known and cl not in aliases and cl != "*": + out.append(c) + return out[:20] + + async def _advisory_repair(self, sql, ast, col_catalog, question, dataset_id, bundle) -> str | None: + """Non-error reasons to ask the critic to reconsider an already-OK result. + + Rides the non-destructive loop (round-2 #4): under-covered value groups (#7) + and signed-measure double-subtraction (#5B). Returns a combined message or None. + """ + reasons: list[str] = [] + if self._settings.group_coverage_repair_enabled: + lits = value_anchoring.extract_question_literals(question) + for g in value_anchoring.group_coverage_gaps(sql, col_catalog, lits): + col = g["column"].rsplit(".", 1)[-1] + reasons.append( + f"The filter on `{col}` lists only SOME of the values the question's group " + f"covers; it is MISSING {g['missing']!r}. Include ALL of them (IN-list) or use " + f"an anchored LIKE; keep the original only if the exclusion is genuinely intended." + ) + if self._settings.signed_measure_repair_enabled: + hint = await self._signed_measure_hint(sql, ast, col_catalog, dataset_id) + if hint: + reasons.append(hint) + return " ".join(reasons) if reasons else None + + async def _signed_measure_hint(self, sql, ast, col_catalog, dataset_id) -> str | None: + """Probe whether the SQL subtracts a term whose SIGNED measure is already + stored negative (so subtracting double-counts the sign). Best-effort (#5B).""" + try: + mixed = { + c["qualified_name"].rsplit(".", 1)[-1].lower() + for c in col_catalog + if c.get("mixed_sign") and value_anchoring.semantic_role(c.get("semantic_type")) == "measure" + } + if not mixed: + return None + terms = value_anchoring.signed_subtraction_terms(sql) + subtracted = [ + t + for t in terms + if t["sign"] < 0 and t["measure_col"].lower() in mixed and t["dim_col"] and t["literals"] + ] + if not subtracted: + return None + tables = [t for t in ast.table_refs if t] + if not tables: + return None + attached = await self._table_resolver.resolve(dataset_id, tables) + if not attached: + return None + import asyncio + + offenders = await asyncio.to_thread(_probe_signed_terms, attached, subtracted) + if not offenders: + return None + parts = "; ".join(f"{o['dim']} IN {o['literals']} sums to {o['sum']:.0f}" for o in offenders[:6]) + # build the corrected single-signed-sum pattern from ALL the formula's + # terms (the generic fix: the data already carries the sign). + all_terms = [ + t for t in terms if t["measure_col"].lower() in mixed and t["dim_col"] and t["literals"] + ] + allowed = sorted({lit for t in all_terms for lit in t["literals"]}) + dim = all_terms[0]["dim_col"] + meas = all_terms[0]["measure_col"] + lits_sql = ", ".join("'" + lit.replace("'", "''") + "'" for lit in allowed) + return ( + f"SIGN ERROR (must fix): this formula SUBTRACTS terms whose measure is ALREADY STORED " + f"NEGATIVE ({parts}). Subtracting an already-negative value double-counts the sign and " + f"inflates the result above total revenue. The data already carries the economic sign, so " + f"REWRITE the whole +/- expression as ONE signed sum over all its line-items: " + f'SUM(CASE WHEN "{dim}" IN ({lits_sql}) THEN "{meas}" ELSE 0 END) -- keep the original ' + f"WHERE filters and any GROUP BY. Do NOT keep the subtraction chain." + ) + except Exception as exc: # noqa: BLE001 - best-effort + logger.debug("signed-measure probe failed: %s", exc) + return None + + async def _resolve_entities( + self, + dataset_id: uuid.UUID, + question: str, + col_catalog: list[dict], + bundle: dict, + ) -> dict: + """Map question literals to the columns that actually store them (G3). + + First via the low-cardinality value catalogue (cheap), then -- for + unresolved entity-looking literals (e.g. person names in a high-card + column) -- via a bounded live DuckDB scan of the dataset's tables. + """ + empty = {"entities": [], "groups": [], "hierarchy_intent": False} + if not self._settings.entity_resolution_enabled: + return empty + literals = value_anchoring.extract_question_literals(question) + if not literals: + return empty + + hierarchy = value_anchoring.relationship_intent(question) + # round-2 #1: a term that umbrellas >=2 values of one column -> a group. + groups: list[dict] = [] + if self._settings.group_resolution_enabled: + groups = value_anchoring.resolve_value_groups(literals, col_catalog) + group_keys = {(g["literal"].lower(), g["column"]) for g in groups} + group_lits = {g["literal"].lower() for g in groups} + + resolved = value_anchoring.resolve_from_catalog(literals, col_catalog) + # a single value superseded by a group is dropped (the group is the truth) + resolved = [r for r in resolved if (r["literal"].lower(), r["column"]) not in group_keys] + done = {r["literal"].lower() for r in resolved} | group_lits + remaining = [lit for lit in literals if lit.lower() not in done][ + : self._settings.entity_resolution_max_literals + ] + if remaining: + try: + resolved += await self._scan_columns_for_values(dataset_id, remaining, bundle) + except Exception as exc: # noqa: BLE001 - resolution is best-effort + logger.warning("live entity resolution failed: %s", exc) + + # de-dup entities by (literal, column), keeping the highest match_count + merged: dict[tuple[str, str], dict] = {} + for r in resolved: + key = (r["literal"].lower(), r["column"]) + cur = merged.get(key) + if cur is None or (r.get("match_count") or 0) > (cur.get("match_count") or 0): + merged[key] = r + # de-dup groups by (literal, column) + gseen: set[tuple[str, str]] = set() + gout: list[dict] = [] + for g in groups: + k = (g["literal"].lower(), g["column"]) + if k not in gseen: + gseen.add(k) + gout.append(g) + entities = sorted(merged.values(), key=lambda r: r.get("match_count") or 0, reverse=True)[:25] + return {"entities": entities, "groups": gout[:12], "hierarchy_intent": hierarchy} + + async def _scan_columns_for_values( + self, + dataset_id: uuid.UUID, + literals: list[str], + bundle: dict, + ) -> list[dict]: + table_names = [ + (getattr(h, "metadata", {}) or {}).get("qualified_name", "").rsplit(".", 1)[-1] + for h in (bundle.get("schema_inventory") or []) + if (getattr(h, "metadata", {}) or {}).get("kind") == "TABLE" + ] + table_names = [t for t in dict.fromkeys(table_names) if t] + if not table_names: + return [] + attached = await self._table_resolver.resolve(dataset_id, table_names) + if not attached: + return [] + import asyncio + + return await asyncio.to_thread(_scan_sync, attached, literals) + + +def _probe_signed_terms(attached_tables: dict[str, str], terms: list[dict]) -> list[dict]: + """Sum each subtracted term's measure over its line-items; report the ones that + sum NEGATIVE (already stored negative → subtracting double-counts). Best-effort.""" + try: + import duckdb + except ImportError: # pragma: no cover + return [] + paths = list(attached_tables.values()) + if not paths: + return [] + offenders: list[dict] = [] + conn = None + try: + conn = duckdb.connect(":memory:") + conn.execute("SET threads=2") + for t in terms: + mq = t["measure_col"].replace(chr(34), chr(34) * 2) + dq = t["dim_col"].replace(chr(34), chr(34) * 2) + in_list = ", ".join("'" + str(lit).replace("'", "''") + "'" for lit in t["literals"]) + total = None + for path in paths: + try: + cols = { + c[0].lower() + for c in conn.execute(f"DESCRIBE SELECT * FROM read_parquet('{path}')").fetchall() + } + if t["measure_col"].lower() not in cols or t["dim_col"].lower() not in cols: + continue + s = conn.execute( + f"SELECT SUM(TRY_CAST(\"{mq}\" AS DOUBLE)) FROM read_parquet('{path}') " + f'WHERE CAST("{dq}" AS VARCHAR) IN ({in_list})' + ).fetchone() + if s and s[0] is not None: + total = (total or 0.0) + float(s[0]) + except Exception: # noqa: BLE001 + continue + if total is not None and total < 0: + offenders.append({"dim": t["dim_col"], "literals": t["literals"], "sum": total}) + except Exception: # noqa: BLE001 + return offenders + finally: + if conn is not None: + conn.close() + return offenders + + +def _scan_sync(attached_tables: dict[str, str], literals: list[str]) -> list[dict]: + """Find which column stores each question literal: one bounded scan per table. + + For each table we run a single pass that, per VARCHAR column, returns the + first stored value equal (case-insensitively) to any of the literals. This + resolves high-cardinality entities (person/brand names) the low-cardinality + value catalogue can't carry. Best-effort + dataset-agnostic. + """ + try: + import duckdb + except ImportError: # pragma: no cover + return [] + lits = [s.lower() for s in literals if s] + if not lits: + return [] + in_list = ", ".join("'" + s.replace("'", "''") + "'" for s in lits) + found: list[dict] = [] + seen: set[tuple[str, str]] = set() + for tname, path in attached_tables.items(): + conn = None + try: + conn = duckdb.connect(":memory:") + conn.execute("SET threads=2") + desc = conn.execute(f"DESCRIBE SELECT * FROM read_parquet('{path}')").fetchall() + vcols = [ + d[0] for d in desc if str(d[1]).upper().startswith(("VARCHAR", "TEXT", "STRING", "CHAR")) + ][:80] + if not vcols: + continue + cols_sql = [] + for i, c in enumerate(vcols): + cq = c.replace(chr(34), chr(34) * 2) + pred = f'lower(CAST("{cq}" AS VARCHAR)) IN ({in_list})' + cols_sql.append(f'MAX(CASE WHEN {pred} THEN CAST("{cq}" AS VARCHAR) END) AS m{i}') + # match_count: how many rows this column has the literal in. A value + # that REPEATS is a grouping/parent key; one that appears once is an + # identity. Same single scan -- no extra cost. + cols_sql.append(f"SUM(CASE WHEN {pred} THEN 1 ELSE 0 END) AS c{i}") + row = conn.execute(f"SELECT {', '.join(cols_sql)} FROM read_parquet('{path}')").fetchone() + if not row: + continue + for i, c in enumerate(vcols): + val = row[2 * i] + cnt = row[2 * i + 1] + if val is None: + continue + key = (str(val).lower(), f"{tname}.{c}") + if key in seen: + continue + seen.add(key) + found.append( + { + "literal": str(val), + "column": f"{tname}.{c}", + "value": val, + "match_count": int(cnt or 0), + } + ) + except Exception: # noqa: BLE001 - resolution is best-effort + continue + finally: + if conn is not None: + conn.close() + return found diff --git a/src/flyquery/core/services/query/value_anchoring.py b/src/flyquery/core/services/query/value_anchoring.py new file mode 100644 index 00000000..1b8c0b19 --- /dev/null +++ b/src/flyquery/core/services/query/value_anchoring.py @@ -0,0 +1,795 @@ +# Copyright 2024-2026 Firefly Software Foundation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Value-anchoring helpers for the NL->SQL pipeline (dataset-agnostic). + +These pure functions are the backbone of the grounding/generation quality +improvements. They turn the per-column artifacts the ingest pipeline already +computes (``profile_json.top_values`` / ``min`` / ``max`` / +``distinct_estimate``, ``sample_values_json``, ``governance_json.semantic_type``) +into prompt text the SQL writer can copy literals from, resolve question +entities to the columns that store them, and detect degenerate / unsafe SQL. + +Nothing here hardcodes a column name, label, or domain assumption -- every +function operates on whatever the dataset's own profiling produced. +""" + +from __future__ import annotations + +import json +import re +from typing import Any + +import sqlglot +from sqlglot import exp + +# ---------------------------------------------------------------------- +# Semantic role (measure vs dimension vs time) +# ---------------------------------------------------------------------- + +_MEASURE_TYPES = { + "amount", + "count", + "decimal", + "ratio", + "percentage", + "percent", + "rate", + "score", + "currency", + "measure", + "quantity", + "number", + "money", + "metric", +} +_TIME_TYPES = {"year", "quarter", "month", "week", "day", "date", "datetime", "period", "fiscal_year"} +_DIMENSION_TYPES = { + "enum", + "tag", + "name", + "code", + "category", + "identifier", + "id", + "boolean", + "label", + "text", + "status", + "geo", + "country", + "region", +} + + +def semantic_role(semantic_type: str | None) -> str | None: + """Map an ingest-computed semantic_type to measure / time / dimension.""" + st = (semantic_type or "").strip().lower() + if not st: + return None + if st in _TIME_TYPES: + return "time" + if st in _MEASURE_TYPES: + return "measure" + if st in _DIMENSION_TYPES: + return "dimension" + return None + + +def _as_obj(v: Any) -> Any: + """JSONB columns usually arrive decoded; tolerate a str just in case.""" + if isinstance(v, str): + try: + return json.loads(v) + except Exception: # noqa: BLE001 + return None + return v + + +def coerce_profile( + profile_json: Any, + sample_values_json: Any, + *, + max_values: int = 25, +) -> dict: + """Return ``{distinct, values, min, max}`` from the ingest artifacts. + + ``values`` is the de-duplicated, capped list of distinct/top values for a + low-cardinality column (drawn from ``profile_json.top_values`` first, then + ``sample_values_json``). ``min``/``max`` come from the numeric profile. + """ + profile = _as_obj(profile_json) or {} + samples = _as_obj(sample_values_json) or [] + distinct = profile.get("distinct_estimate") if isinstance(profile, dict) else None + mn = profile.get("min") if isinstance(profile, dict) else None + mx = profile.get("max") if isinstance(profile, dict) else None + + raw: list = [] + tv = profile.get("top_values") if isinstance(profile, dict) else None + if isinstance(tv, list): + for item in tv: + if isinstance(item, dict) and "value" in item: + raw.append(item["value"]) + else: + raw.append(item) + if not raw and isinstance(samples, list): + raw = list(samples) + + seen: set[str] = set() + values: list[str] = [] + for v in raw: + s = "NULL" if v is None else str(v) + if s not in seen: + seen.add(s) + values.append(s) + if len(values) >= max_values: + break + # mixed_sign: the column stores BOTH negative and positive numbers (so some + # categories/line-items are already stored as negatives). Derived purely from + # the min/max the profiler already computed -- no domain assumption. + mixed = False + try: + if mn is not None and mx is not None and float(mn) < 0 < float(mx): + mixed = True + except (TypeError, ValueError): + pass + return {"distinct": distinct, "values": values, "min": mn, "max": mx, "mixed_sign": mixed} + + +def render_column_catalog_line( + qualified_name: str, + data_type: str | None, + semantic_type: str | None, + profile_json: Any, + sample_values_json: Any, + *, + max_values: int = 25, + char_budget: int = 280, +) -> str: + """Render one column's value catalogue line for a prompt. + + Examples:: + + `t.Year` (VARCHAR, time, 4 distinct) values: 'FY23','FY24','FY25','FY26' + `t.P&L Line` (VARCHAR, dimension, 20 distinct) values: 'Total Revenue','Manpower',... + `t.FY` (DOUBLE, measure) range: -184.90 .. 361.49 + """ + col = qualified_name.rsplit(".", 1)[-1] + prof = coerce_profile(profile_json, sample_values_json, max_values=max_values) + role = semantic_role(semantic_type) + head_bits = [data_type or "?"] + if role: + head_bits.append(role) + if prof["distinct"] is not None: + head_bits.append(f"{prof['distinct']} distinct") + head = f"`{col}` ({', '.join(head_bits)})" + + if prof["values"]: + vtext = ", ".join(_q(v) for v in prof["values"]) + if len(vtext) > char_budget: + vtext = vtext[:char_budget].rsplit(",", 1)[0] + ", …" + return f"{head} values: {vtext}" + if prof["min"] is not None or prof["max"] is not None: + return f"{head} range: {_num(prof['min'])} .. {_num(prof['max'])}" + return head + + +def render_catalog_from_meta(qualified_name: str, meta: dict, *, char_budget: int = 320) -> str: + """Render a catalogue line from an already-coerced col_catalog item. + + ``meta`` keys: data_type, semantic_type, distinct, values, min, max. + """ + col = qualified_name.rsplit(".", 1)[-1] + bits = [meta.get("data_type") or "?"] + role = semantic_role(meta.get("semantic_type")) + if role: + bits.append(role) + if meta.get("distinct") is not None: + bits.append(f"{meta['distinct']} distinct") + # Echo the source's ORIGINAL header (pre-rename) when the ingest renamed the + # column (e.g. an Excel year header collapsed to year_1). Lets the model know + # what year_1 actually was, instead of relying on a fixed ordinal convention. + oh = meta.get("original_header") + if oh: + bits.append(f"original header: {_q(str(oh))}") + head = f"`{col}` ({', '.join(bits)})" + vals = meta.get("values") or [] + if vals: + vt = ", ".join(_q(str(v)) for v in vals) + if len(vt) > char_budget: + vt = vt[:char_budget].rsplit(",", 1)[0] + ", …" + return f"{head} values: {vt}" + if meta.get("min") is not None or meta.get("max") is not None: + line = f"{head} range: {_num(meta.get('min'))} .. {_num(meta.get('max'))}" + if role == "measure" and meta.get("mixed_sign"): + line += ( + " — SIGNED (stores both negatives and positives; some line-items are already stored negative)" + ) + return line + return head + + +def _q(v: str) -> str: + if v == "NULL": + return "NULL" + return "'" + v.replace("'", "''") + "'" + + +def _num(v: Any) -> str: + try: + return f"{float(v):.2f}" + except (TypeError, ValueError): + return str(v) + + +# ---------------------------------------------------------------------- +# Entity extraction + value->column resolution (G3) +# ---------------------------------------------------------------------- + +_STOP = { + "the", + "and", + "for", + "with", + "que", + "los", + "las", + "del", + "una", + "uno", + "what", + "which", + "how", + "many", + "cual", + "cuales", + "cuantos", + "cuanto", + "team", + "equipo", + "average", + "promedio", + "total", + "year", + "ratio", +} + + +def extract_question_literals(question: str) -> list[str]: + """Pull candidate entity literals out of a NL question (heuristic, generic). + + Captures quoted phrases, ALL-CAPS / Capitalized multi-word runs (proper + nouns, person names, product/brand/business-unit names) and standalone + upper-case codes. Over-extraction is fine -- the resolver only keeps + literals that actually match a stored column value. + """ + out: list[str] = [] + # quoted phrases + for m in re.findall(r"['\"]([^'\"]{2,})['\"]", question): + out.append(m.strip()) + # runs of capitalized / all-caps words (>=1 word), e.g. "FRANCISCO JAVIER ..." + for m in re.findall(r"\b([A-ZÀ-Ý][\wÀ-ý&/.-]*(?:\s+[A-ZÀ-Ý][\wÀ-ý&/.-]*)*)\b", question): + tok = m.strip() + if len(tok) >= 2 and tok.lower() not in _STOP: + out.append(tok) + # standalone all-caps tokens (OBU, DAPA, CVRM, RIV) + for m in re.findall(r"\b([A-Z][A-Z0-9&/]{1,})\b", question): + if m.lower() not in _STOP: + out.append(m) + # de-dup preserving order, drop pure substrings already covered + seen: set[str] = set() + uniq: list[str] = [] + for t in out: + key = t.lower() + if key not in seen: + seen.add(key) + uniq.append(t) + return uniq + + +def resolve_from_catalog( + literals: list[str], + col_catalog: list[dict], +) -> list[dict]: + """Map literals to columns using already-fetched low-cardinality values. + + ``col_catalog`` items: ``{qualified_name, values: [str]}``. Returns + ``[{literal, column, value}]`` for case-insensitive exact matches. + """ + found: list[dict] = [] + seen: set[tuple[str, str]] = set() + for lit in literals: + ll = lit.lower() + for c in col_catalog: + for v in c.get("values", []) or []: + vl = str(v).lower() + if vl == ll or (len(ll) >= 4 and ll in vl) or (len(vl) >= 4 and vl in ll): + key = (lit.lower(), c["qualified_name"]) + if key not in seen: + seen.add(key) + found.append({"literal": lit, "column": c["qualified_name"], "value": v}) + break + return found + + +# Words that signal a hierarchy / "reports-to" question, where the answer is the +# set of rows whose PARENT column equals the entity (the value that REPEATS), not +# the single identity row. Generic NL cues (EN + ES); the load-bearing signal is +# row-match cardinality (this only nudges the choice). Never reads the schema. +_HIERARCHY_INTENT = ( + "team of", + "team for", + "reports to", + "report to", + "direct reports", + "reporting to", + "under ", + "manages", + "managed by", + "supervises", + "supervised by", + "led by", + "in charge of", + "members of", + "people in", + "headcount of", + "size of the team", + "roster of", + "equipo de", + "a cargo de", + "a su cargo", + "reportan a", + "reporta a", + "bajo ", + "dirige", + "dirigido por", + "supervisa", + "supervisado por", + "depende de", + "dependen de", + "miembros de", + "integrantes de", + "dimensionamiento", + "personas en", +) + + +def relationship_intent(question: str) -> bool: + """True if the question is about a hierarchy / team / reporting relationship.""" + q = " " + (question or "").lower() + " " + return any(kw in q for kw in _HIERARCHY_INTENT) + + +def _is_prefix_token(literal: str, value: str) -> bool: + """True if ``literal`` is an anchored token-prefix of ``value``. + + 'Field' prefixes 'Field Sales' / 'Field-Access' (boundary follows), but NOT + 'Fieldwork'. Case-insensitive. This is the structural definition of a term + that fans out to several sub-values. + """ + ll = literal.strip().lower() + vl = str(value).strip().lower() + if not ll or not vl or vl == ll or not vl.startswith(ll): + return False + nxt = vl[len(ll) : len(ll) + 1] + return nxt == "" or not nxt.isalnum() + + +def resolve_value_groups(literals: list[str], col_catalog: list[dict]) -> list[dict]: + """Map a question term to the FULL SET of catalogued values it umbrellas. + + When a literal is an anchored token-prefix of >=2 distinct values of the SAME + column ('Field' -> {'Field Sales','Field Medical','Field Access',...}), return + a group so the model filters the whole set, not a subset. Gated to 'pure + umbrellas': skip a literal that is itself an exact stored value. ``truncated`` + flags that the column has more distinct values than were catalogued (so an + IN-list would be incomplete and an anchored LIKE is safer). Dataset-agnostic: + driven only by the column's own distinct values. + """ + groups: list[dict] = [] + for lit in literals: + ll = lit.strip().lower() + if len(ll) < 2: + continue + for c in col_catalog: + vals = [str(v) for v in (c.get("values") or [])] + if not vals: + continue + if any(str(v).strip().lower() == ll for v in vals): + continue # the term IS a value -> plain entity, not an umbrella + matches = [v for v in vals if _is_prefix_token(lit, v)] + if len({m.lower() for m in matches}) >= 2: + distinct = c.get("distinct") + groups.append( + { + "literal": lit, + "column": c["qualified_name"], + "values": matches, + "truncated": bool(distinct is not None and distinct > len(vals)), + } + ) + return groups + + +# ---------------------------------------------------------------------- +# SQL analysis: degenerate detection, predicate literals, CTEs, functions +# ---------------------------------------------------------------------- + + +def _parse(sql: str): + try: + tree = sqlglot.parse_one(sql, read="duckdb") + except Exception: # noqa: BLE001 + return None + return tree + + +def is_degenerate_sql(sql: str) -> bool: + """True if the SQL is a no-op: constant-false WHERE or constant-only aggregates. + + Catches placeholder queries like ``... WHERE 1=0`` and + ``SUM(CASE WHEN ... THEN 0 ELSE 0 END)`` that execute cleanly but answer + nothing. Structural + schema-agnostic. + """ + tree = _parse(sql) + if tree is None: + return False + + # 1) constant-false WHERE + for where in tree.find_all(exp.Where): + cond = where.this + if cond is None: + continue + try: + from sqlglot.optimizer.simplify import simplify + + simp = simplify(cond.copy()) + if isinstance(simp, exp.Boolean) and simp.this is False: + return True + except Exception: # noqa: BLE001 + pass + if ( + isinstance(cond, exp.EQ) + and isinstance(cond.this, exp.Literal) + and isinstance(cond.expression, exp.Literal) + and cond.this.name != cond.expression.name + ): + return True + + # 2) every projected expression is a constant aggregate / literal + selects = list(tree.find_all(exp.Select)) + if selects: + top = selects[0] + exprs = [e for e in top.expressions] + if exprs and all(_is_constant_projection(e) for e in exprs): + return True + return False + + +def _is_constant_projection(e: exp.Expression) -> bool: + node = e.this if isinstance(e, exp.Alias) else e + if isinstance(node, exp.Literal): + return True + if isinstance(node, exp.AggFunc): + arg = node.this + if isinstance(arg, exp.Literal): + return True + if isinstance(arg, exp.Case) and _case_all_same_literal(arg): + return True + return False + + +def _case_all_same_literal(case_expr: exp.Case) -> bool: + lits: list[exp.Expression] = [] + for ifexpr in case_expr.args.get("ifs", []) or []: + lits.append(ifexpr.args.get("true")) + default = case_expr.args.get("default") + if default is not None: + lits.append(default) + if not lits: + return False + names: set[str] = set() + for lit in lits: + if not isinstance(lit, exp.Literal): + return False + names.add(lit.name) + return len(names) <= 1 + + +def equality_predicate_columns(sql: str) -> list[str]: + """Column names used in ``=`` / ``IN`` / ``LIKE`` predicates (for repair). + + These are the columns whose stored values the critic should re-check when a + query executes but returns 0 rows. + """ + tree = _parse(sql) + if tree is None: + return [] + cols: list[str] = [] + seen: set[str] = set() + for pred in tree.find_all(exp.EQ, exp.In, exp.Like, exp.ILike): + target = pred.this + col = target.find(exp.Column) if target is not None else None + if isinstance(col, exp.Column) and col.name and col.name.lower() not in seen: + seen.add(col.name.lower()) + cols.append(col.name) + return cols + + +def predicate_literals(sql: str) -> dict: + """Return ``{column_name(lower): set(literal strings)}`` for =/IN predicates.""" + tree = _parse(sql) + out: dict[str, set] = {} + if tree is None: + return out + for pred in tree.find_all(exp.EQ, exp.In): + target = pred.this + col = target.find(exp.Column) if target is not None else None + if not isinstance(col, exp.Column) or not col.name: + continue + lits: set = set() + if isinstance(pred, exp.EQ) and isinstance(pred.expression, exp.Literal): + lits.add(pred.expression.name) + elif isinstance(pred, exp.In): + for e in pred.expressions or []: + if isinstance(e, exp.Literal): + lits.add(e.name) + if lits: + out.setdefault(col.name.lower(), set()).update(lits) + return out + + +def group_coverage_gaps(sql: str, col_catalog: list[dict], literals: list[str]) -> list[dict]: + """IN/= predicates that are a STRICT SUBSET of a detected value group (round-2 #7). + + Returns ``[{column, missing}]`` when the SQL listed SOME members of a value + group the question umbrellas but not all. Advisory only. + """ + groups = resolve_value_groups(literals, col_catalog) + if not groups: + return [] + preds = predicate_literals(sql) + gaps: list[dict] = [] + for g in groups: + colname = g["column"].rsplit(".", 1)[-1].lower() + listed = preds.get(colname) + if not listed: + continue + listed_l = {x.lower() for x in listed} + group_vals = {str(v) for v in g["values"]} + group_l = {v.lower() for v in group_vals} + missing = [v for v in group_vals if v.lower() not in listed_l] + if missing and (listed_l & group_l): # listed some-but-not-all + gaps.append({"column": g["column"], "missing": missing}) + return gaps + + +def cte_and_derived_names(sql: str) -> set[str]: + """Names that are CTE aliases or derived-table/subquery aliases (not real tables).""" + tree = _parse(sql) + if tree is None: + return set() + names: set[str] = set() + for cte in tree.find_all(exp.CTE): + if cte.alias: + names.add(cte.alias) + for sub in tree.find_all(exp.Subquery): + if sub.alias: + names.add(sub.alias) + return {n for n in names if n} + + +def referenced_columns(sql: str) -> list[str]: + """Distinct column identifiers referenced anywhere in the SQL.""" + tree = _parse(sql) + if tree is None: + return [] + out: list[str] = [] + seen: set[str] = set() + for c in tree.find_all(exp.Column): + if c.name and c.name.lower() not in seen: + seen.add(c.name.lower()) + out.append(c.name) + return out + + +def select_aliases(sql: str) -> set[str]: + """Aliases defined in the query (SELECT-list + CTE column outputs).""" + tree = _parse(sql) + if tree is None: + return set() + out: set[str] = set() + for a in tree.find_all(exp.Alias): + if a.alias: + out.add(a.alias.lower()) + return out + + +def _flatten_signed(expr, sign: int, out: list) -> None: + if isinstance(expr, exp.Paren): + _flatten_signed(expr.this, sign, out) + elif isinstance(expr, exp.Sub): + _flatten_signed(expr.this, sign, out) + _flatten_signed(expr.expression, -sign, out) + elif isinstance(expr, exp.Add): + _flatten_signed(expr.this, sign, out) + _flatten_signed(expr.expression, sign, out) + else: + out.append((sign, expr)) + + +def _cond_dim_literals(cond): + """From a ``dim = lit`` / ``dim IN (lits)`` condition -> (dim_col, [literals]).""" + if isinstance(cond, exp.EQ): + c = cond.this.find(exp.Column) if cond.this is not None else None + if isinstance(c, exp.Column) and isinstance(cond.expression, exp.Literal): + return c.name, [cond.expression.name] + elif isinstance(cond, exp.In): + c = cond.this.find(exp.Column) if cond.this is not None else None + lits = [e.name for e in (cond.expressions or []) if isinstance(e, exp.Literal)] + if isinstance(c, exp.Column) and lits: + return c.name, lits + return None, None + + +def _literal_value(x): + """Numeric value of a literal possibly wrapped in a unary minus, else None.""" + if isinstance(x, exp.Neg) and isinstance(x.this, exp.Literal): + try: + return -float(x.this.name) + except (TypeError, ValueError): + return None + if isinstance(x, exp.Literal): + try: + return float(x.name) + except (TypeError, ValueError): + return None + return None + + +def _measure_and_sign(expr): + """For a CASE THEN expression, return (sign, measure_col) when it is a measure + column or its negation (``-m``, ``m * -1``, ``(-m)``); else (None, None). + + This is what lets the detector see a CASE branch that NEGATES the measure + (e.g. ``WHEN cost THEN -"FY (Real)"``) -- the same sign double-count expressed + without a SUM(...)-SUM(...) chain. + """ + e = expr + sign = 1 + for _ in range(6): # bounded unwrap + if isinstance(e, exp.Paren): + e = e.this + elif isinstance(e, exp.Neg): + sign = -sign + e = e.this + elif isinstance(e, exp.Mul): + lv = _literal_value(e.expression) + other = e.this + if lv is None: + lv = _literal_value(e.this) + other = e.expression + if lv is None: + break + if lv < 0: + sign = -sign + e = other + else: + break + col = e if isinstance(e, exp.Column) else (e.find(exp.Column) if e is not None else None) + if isinstance(col, exp.Column) and col.name: + return sign, col.name + return None, None + + +def _agg_case_branches(node) -> list[tuple]: + """AGG(CASE WHEN dim (=|IN) lits THEN [±]measure ...) -> list of + (branch_sign, measure_col, dim_col, [lits]) across ALL branches.""" + if isinstance(node, exp.Alias): + node = node.this + if not isinstance(node, exp.AggFunc): + return [] + arg = node.this + if not isinstance(arg, exp.Case): + return [] + out: list[tuple] = [] + for ifx in arg.args.get("ifs") or []: + bsign, mcol = _measure_and_sign(ifx.args.get("true")) + if mcol is None: + continue + dim_col, lits = _cond_dim_literals(ifx.this) + if not dim_col or not lits: + continue + out.append((bsign, mcol, dim_col, lits)) + return out + + +def signed_subtraction_terms(sql: str) -> list[dict]: + """Terms of an additive formula applied over a measure (round-2 #5B). + + Returns ``[{sign, measure_col, dim_col, literals}]`` for measure terms combined + by +/-, covering BOTH shapes the generator uses: + * a ``SUM(...) - SUM(...) - ...`` chain of per-line-item aggregates, and + * a single ``SUM(CASE WHEN rev THEN m WHEN cost THEN -m ...)`` whose branches + negate the measure. + The caller probes whether a SUBTRACTED term's measure is already stored negative + (so subtracting / negating double-counts the sign). + """ + tree = _parse(sql) + if tree is None: + return [] + selects = list(tree.find_all(exp.Select)) + if not selects: + return [] + out: list[dict] = [] + for e in selects[0].expressions: + node = e.this if isinstance(e, exp.Alias) else e + if isinstance(node, (exp.Sub, exp.Add, exp.Paren)): + leaves: list = [] + _flatten_signed(node, 1, leaves) + for chain_sign, leaf in leaves: + for bsign, mcol, dim, lits in _agg_case_branches(leaf): + out.append( + {"sign": chain_sign * bsign, "measure_col": mcol, "dim_col": dim, "literals": lits} + ) + elif isinstance(node, exp.AggFunc): + for bsign, mcol, dim, lits in _agg_case_branches(node): + out.append({"sign": bsign, "measure_col": mcol, "dim_col": dim, "literals": lits}) + return out + + +# Generated SQL must never reach out to the filesystem / external sources. +# The executor only exposes the dataset's parquet tables as views; a model +# that emits read_csv_auto/read_parquet/pg_read_file would bypass that. +_DANGEROUS_FUNCS = { + "read_csv", + "read_csv_auto", + "read_parquet", + "parquet_scan", + "read_json", + "read_json_auto", + "read_ndjson", + "read_ndjson_auto", + "read_text", + "read_blob", + "glob", + "sniff_csv", + "pg_read_file", + "pg_read_binary_file", + "pg_ls_dir", + "load", + "install", + "csv_scan", +} + + +def find_dangerous_functions(sql: str) -> set[str]: + """Return any filesystem/exfiltration table-function names present in the SQL.""" + tree = _parse(sql) + if tree is None: + return set() + hits: set[str] = set() + for fn in tree.find_all(exp.Func, exp.Anonymous): + name = (getattr(fn, "name", "") or "").lower() + if not name and hasattr(fn, "sql_name"): + try: + name = fn.sql_name().lower() + except Exception: # noqa: BLE001 + name = "" + if name in _DANGEROUS_FUNCS: + hits.add(name) + # also catch raw COPY commands + if tree.find(exp.Command) is not None and re.search(r"\bcopy\b", sql, re.IGNORECASE): + hits.add("copy") + return hits diff --git a/src/flyquery/core/services/retrieval/hybrid_retriever.py b/src/flyquery/core/services/retrieval/hybrid_retriever.py index 46e97708..666856e6 100644 --- a/src/flyquery/core/services/retrieval/hybrid_retriever.py +++ b/src/flyquery/core/services/retrieval/hybrid_retriever.py @@ -129,9 +129,15 @@ async def retrieve( # bypasses the top-K truncation. full_inventory = await self._index.all_schema_objects(dataset_id, limit=500) + # Per-column value catalogue (distinct/top values, range, semantic_type) + # for the whole dataset -- feeds value-anchored generation + entity + # resolution + the repair loop. Computed at ingest, just read here. + column_catalog = await self._index.column_value_catalog(dataset_id) + return { "schema_objects": schema_objects, "schema_inventory": full_inventory, + "column_catalog": column_catalog, "examples": examples[:top_k_examples], "metrics": metrics[:top_k_metrics], "glossary": glossary, diff --git a/src/flyquery/core/services/retrieval/reranker.py b/src/flyquery/core/services/retrieval/reranker.py index 6c117f78..32e29882 100644 --- a/src/flyquery/core/services/retrieval/reranker.py +++ b/src/flyquery/core/services/retrieval/reranker.py @@ -22,15 +22,22 @@ from __future__ import annotations import logging +import re from typing import Any, Protocol from flyquery.core.services.retrieval.search_index import Hit logger = logging.getLogger(__name__) -# Guard so the "reranking disabled" warning is emitted at most once per process. +# Guard so the cross-encoder-unavailable warning is emitted at most once per process. _warned_noop_fallback = False +_TOKEN = re.compile(r"[\wÀ-ý]+", re.UNICODE) + + +def _tokens(text: str) -> set[str]: + return {t.lower() for t in _TOKEN.findall(text or "") if len(t) >= 2} + class Reranker(Protocol): """Protocol for a reranking step in the retrieval pipeline.""" @@ -44,16 +51,40 @@ class NoopReranker: """Identity reranker that preserves the original order.""" async def rerank(self, query: str, hits: list[Hit], top_n: int) -> list[Hit]: # noqa: ARG002 - """Return the first ``top_n`` hits unchanged. - - :param query: NL query string (unused) - :param hits: candidate hits from the retriever - :param top_n: how many to return - :return: first ``top_n`` elements of ``hits`` - """ + """Return the first ``top_n`` hits unchanged.""" return hits[:top_n] +class LexicalReranker: + """Dependency-free reranker: token-overlap between the query and each hit. + + A real cross-encoder is better, but when ``sentence-transformers`` is not + installed this is a strict improvement over the identity ``NoopReranker``: + it boosts hits whose text (now including the column's indexed VALUES) shares + tokens with the question, blending the lexical score with the retriever's + RRF score so a token-exact value/name match surfaces the owning column. + Fully dataset-agnostic. + """ + + async def rerank(self, query: str, hits: list[Hit], top_n: int) -> list[Hit]: + if not hits: + return [] + qtok = _tokens(query) + if not qtok: + return hits[:top_n] + + def score(h: Hit) -> float: + htok = _tokens(h.text) + if not htok: + return 0.0 + overlap = len(qtok & htok) + lex = overlap / (len(qtok) ** 0.5) + return lex + 0.25 * float(getattr(h, "score", 0.0) or 0.0) + + order = sorted(range(len(hits)), key=lambda i: score(hits[i]), reverse=True) + return [hits[i] for i in order[:top_n]] + + class CrossEncoderReranker: """Reranker backed by a sentence-transformers CrossEncoder model. @@ -83,32 +114,36 @@ async def rerank(self, query: str, hits: list[Hit], top_n: int) -> list[Hit]: return [hits[i] for i in order[:top_n]] -def build_reranker(settings: Any) -> NoopReranker | CrossEncoderReranker: +def build_reranker(settings: Any) -> NoopReranker | LexicalReranker | CrossEncoderReranker: """Factory: return a ``CrossEncoderReranker`` when possible. - Falls back to ``NoopReranker`` when: + Falls back to the dependency-free ``LexicalReranker`` (NOT a no-op) when: - ``settings.reranker_model`` is empty / falsy - ``sentence-transformers`` is not installed - The specified model cannot be loaded (network error, etc.) + The previous default silently degraded to an identity pass-through, leaving + wide-table column precision unimproved; the lexical fallback is a strict win + on any dataset and is what makes value-aware retrieval reach the prompt. + :param settings: ``FlyquerySettings`` instance :return: a ready-to-use reranker """ global _warned_noop_fallback model_name = getattr(settings, "reranker_model", "") or "" if not model_name: - return NoopReranker() + return LexicalReranker() try: return CrossEncoderReranker(model_name) except Exception as exc: # noqa: BLE001 if not _warned_noop_fallback: _warned_noop_fallback = True logger.warning( - "reranker model=%s unavailable (%s) -- falling back to NoopReranker. " - "Relevance reranking is DISABLED; results are truncated by retrieval " - "order only (install sentence-transformers / make the cross-encoder " - "model loadable to enable it).", + "reranker model=%s unavailable (%s) -- falling back to the " + "dependency-free LexicalReranker (token-overlap). Cross-encoder " + "reranking is disabled; install sentence-transformers / make the " + "model loadable to re-enable it.", model_name, exc, ) - return NoopReranker() + return LexicalReranker() diff --git a/src/flyquery/core/services/retrieval/search_index.py b/src/flyquery/core/services/retrieval/search_index.py index beb828b0..c94090a6 100644 --- a/src/flyquery/core/services/retrieval/search_index.py +++ b/src/flyquery/core/services/retrieval/search_index.py @@ -30,6 +30,8 @@ import sqlalchemy as sa from sqlalchemy.ext.asyncio import AsyncSession +from flyquery.core.services.query.value_anchoring import coerce_profile, semantic_role + @dataclass(frozen=True) class Hit: @@ -42,112 +44,101 @@ class Hit: metadata: dict = field(default_factory=dict) -def value_fingerprint( - data_type: str | None, - sample_values_json: object, - profile_json: object, - *, - max_values: int = 40, - max_chars: int = 400, -) -> str: - """Compact, human-readable summary of a column's ACTUAL values. - - Surfaced into the grounding/generation prompts so the agents copy - WHERE / CASE literals verbatim from real values instead of guessing - -- e.g. a fiscal year stored as ``FY23`` (not ``2023``), the members - of a tall/EAV category column (``P&L Line System`` rows like - ``Total Revenue`` / ``Manpower``), or the magnitude gap between a - scaled-duplicate measure (``FY`` ~0.02 vs ``FY (Real)`` ~25748). - - Returns ``""`` when there is nothing useful to show. +def _semantic_type(governance_json) -> str | None: + g = governance_json + if isinstance(g, dict): + return g.get("semantic_type") + return None + + +def _original_header(governance_json) -> str | None: + g = governance_json + if not isinstance(g, dict): + return None + v = g.get("original_header") + if not v: + return None + s = str(v).strip() + # don't surface a header that is just a number (mis-detected data cell), + # unless it is a plausible 4-digit year. + try: + float(s.replace(",", "")) + if not (s.isdigit() and len(s) == 4 and 1900 <= int(s) <= 2100): + return None + except ValueError: + pass + return s or None + + +def _col_value_suffix(profile_json, sample_values_json, semantic_type, *, max_values: int = 25) -> str: + """Compact ``[role, N distinct] values: a, b, ...`` / ``range: min..max`` suffix. + + Appended to a column hit's text so (a) the lexical reranker can match a + question token to a stored value, and (b) the grounding agent sees the real + vocabulary. Dataset-agnostic. """ - prof = profile_json if isinstance(profile_json, dict) else {} - - # NOTE: profiling stores ``subtotal_values`` (name-based candidates for - # pre-aggregated rows). We deliberately do NOT surface them as an - # exclusion directive: a "Total_*" value in a dimension is just as often a - # legitimate additive bucket (e.g. unallocated/corporate) as a true rollup, - # and any hint makes the agent wrongly drop it. Whether to exclude requires - # the structural test (does the value's aggregate == the sum of the others?) - # which is not available per-column at profile time. The general "aggregate - # across ALL values / don't drop a value" prompt rule handles this safely. - subtotal_note = "" - - # Self-referencing hierarchy hint: this column's values are entities from - # another (higher-cardinality) column -- e.g. a manager column whose values - # are people from the employee column. Surfaced even for high-cardinality - # columns that have no listable values, because that is exactly when the - # agent cannot otherwise tell who a person reports to. - ref_col = prof.get("references_column") + prof = coerce_profile(profile_json, sample_values_json, max_values=max_values) + # Self-referencing hierarchy hint: when the profile stage detected that this + # column's values are entities drawn from another (higher-cardinality) column + # -- e.g. a manager column whose values are people from the employee column -- + # surface it so the agent filters THIS column to find a person's reports/team + # instead of the person's own row. Surfaced even for high-cardinality columns + # with no listable values, because that is exactly when the agent otherwise + # cannot tell who reports to whom. + ref_col = profile_json.get("references_column") if isinstance(profile_json, dict) else None ref_note = ( - f" | HIERARCHY: holds entities/people from column '{ref_col}' (e.g. each row's " - f"manager/owner/parent). To get a given person's group/team/reports, filter THIS " - f"column to that person (case-insensitive LIKE), not the person's own row." + f" | HIERARCHY: holds entities from column '{ref_col}' (each row's " + f"manager/owner/parent); to get a person's group/team/reports filter THIS " + f"column to that person (case-insensitive LIKE), not their own row." if ref_col else "" ) - - # Categorical: the stored distinct value set (low-cardinality columns). - top_values = prof.get("top_values") or [] - if top_values: - seen: set[str] = set() - uniq: list[str] = [] - for tv in top_values: - v = tv.get("value") if isinstance(tv, dict) else tv - if v is None: - continue - s = str(v) - if s not in seen: - seen.add(s) - uniq.append(s) - shown = uniq[:max_values] - body = " | ".join(shown) - if len(body) > max_chars: - body = body[:max_chars].rsplit("|", 1)[0].strip() + " | …" - more = "" if len(uniq) <= len(shown) else f" (+{len(uniq) - len(shown)} more)" - return f"values: {body}{more}{subtotal_note}{ref_note}" if body else ref_note.strip(" |") - - # Numeric / temporal: range + cardinality (exposes scaled duplicates). - col_min, col_max = prof.get("min"), prof.get("max") - if col_min is not None or col_max is not None: - rng = f"range: {col_min} .. {col_max}" - dist = prof.get("distinct_estimate") - if dist is not None: - rng += f" (~{dist} distinct)" - return rng + ref_note - - # Fallback: a few raw sample values (high-cardinality columns). - samples = sample_values_json if isinstance(sample_values_json, list) else [] - if samples: - seen2: set[str] = set() - uniq2: list[str] = [] - for v in samples: - s = str(v) - if s not in seen2: - seen2.add(s) - uniq2.append(s) - if uniq2: - return "e.g.: " + " | ".join(uniq2[:8]) + ref_note - return ref_note.strip(" |") - - -def _column_hit(r, score: float) -> Hit: - """Build a ranked schema-object Hit, enriched with a value fingerprint. - - Used by the BM25 + vector column searches so the ranked "Top-ranked - column matches" the grounding agent sees carry real values, not just - name + description. - """ - fp = value_fingerprint(r.data_type, r.sample_values_json, r.profile_json) - text = f"{r.qualified_name}: {r.data_type}\n{r.description or ''}" - if fp: - text += f"\n{fp}" + bits = [] + role = semantic_role(semantic_type) + if role: + bits.append(role) + if prof["distinct"] is not None: + bits.append(f"{prof['distinct']} distinct") + head = f" [{', '.join(bits)}]" if bits else "" + if prof["values"]: + v = ", ".join(prof["values"]) + if len(v) > 320: + v = v[:320].rsplit(",", 1)[0] + ", …" + return f"{head} values: {v}{ref_note}" + if prof.get("min") is not None or prof.get("max") is not None: + line = f"{head} range: {prof.get('min')}..{prof.get('max')}" + if role == "measure" and prof.get("mixed_sign"): + line += " SIGNED(neg+pos)" + return line + ref_note + return head + ref_note + + +def _schema_hit(r, score: float) -> Hit: + """Build a column/table schema_object Hit with value + type metadata.""" + kind = r.get("kind", None) + semantic_type = _semantic_type(r["governance_json"]) if "governance_json" in r else None + suffix = "" + if kind == "COLUMN": + suffix = _col_value_suffix( + r.get("profile_json", None), + r.get("sample_values_json", None), + semantic_type, + ) + text = f"{r['qualified_name']}: {r['data_type'] or ''}\n{r['description'] or ''}{suffix}" return Hit( source_kind="schema_object", - id=r.id, + id=r["id"], text=text, score=score, - metadata={"qualified_name": r.qualified_name, "table_id": str(r.table_id), "values": fp}, + metadata={ + "qualified_name": r["qualified_name"], + "table_id": str(r["table_id"]), + "kind": kind, + "data_type": r["data_type"], + "semantic_type": semantic_type, + "profile_json": r.get("profile_json", None), + "sample_values_json": r.get("sample_values_json", None), + }, ) @@ -168,13 +159,12 @@ async def bm25_schema_objects(self, query: str, dataset_id: uuid.UUID, limit: in rows = await self._session.execute( sa.text( """ - SELECT o.id, o.qualified_name, o.description, o.data_type, o.table_id, - o.sample_values_json, o.profile_json, + SELECT o.id, o.qualified_name, o.description, o.data_type, o.table_id, o.kind, + o.profile_json, o.sample_values_json, o.governance_json, ts_rank(o.content_tsv, plainto_tsquery('english', :q)) AS score FROM flyquery_schema_objects o JOIN flyquery_tables t ON t.id = o.table_id WHERE t.dataset_id = :ds AND o.is_active = true - AND o.snapshot_id = t.current_snapshot_id AND o.content_tsv @@ plainto_tsquery('english', :q) ORDER BY score DESC LIMIT :lim @@ -182,7 +172,7 @@ async def bm25_schema_objects(self, query: str, dataset_id: uuid.UUID, limit: in ), {"q": query, "ds": dataset_id, "lim": limit}, ) - return [_column_hit(r, float(r.score)) for r in rows.mappings()] + return [_schema_hit(r, float(r["score"])) for r in rows.mappings()] async def vector_schema_objects( self, @@ -200,20 +190,19 @@ async def vector_schema_objects( rows = await self._session.execute( sa.text( """ - SELECT o.id, o.qualified_name, o.description, o.data_type, o.table_id, - o.sample_values_json, o.profile_json, + SELECT o.id, o.qualified_name, o.description, o.data_type, o.table_id, o.kind, + o.profile_json, o.sample_values_json, o.governance_json, 1 - (o.embedding <=> CAST(:emb AS vector)) AS score FROM flyquery_schema_objects o JOIN flyquery_tables t ON t.id = o.table_id - WHERE t.dataset_id = :ds AND o.is_active = true - AND o.snapshot_id = t.current_snapshot_id AND o.embedding IS NOT NULL + WHERE t.dataset_id = :ds AND o.is_active = true AND o.embedding IS NOT NULL ORDER BY o.embedding <=> CAST(:emb AS vector) LIMIT :lim """ ), {"emb": str(query_embedding), "ds": dataset_id, "lim": limit}, ) - return [_column_hit(r, float(r.score)) for r in rows.mappings()] + return [_schema_hit(r, float(r["score"])) for r in rows.mappings()] async def all_schema_objects( self, @@ -253,9 +242,7 @@ async def all_schema_objects( ON c.table_id = o.table_id AND c.kind = 'COLUMN' AND c.is_active = true - AND c.snapshot_id = t.current_snapshot_id WHERE t.dataset_id = :ds AND o.is_active = true AND o.kind = 'TABLE' - AND o.snapshot_id = t.current_snapshot_id GROUP BY o.id, o.qualified_name, o.description, o.table_id, o.kind ORDER BY o.qualified_name """ @@ -273,11 +260,10 @@ async def all_schema_objects( sa.text( """ SELECT o.id, o.qualified_name, o.description, o.data_type, o.table_id, o.kind, - o.sample_values_json, o.profile_json + o.profile_json, o.sample_values_json, o.governance_json FROM flyquery_schema_objects o JOIN flyquery_tables t ON t.id = o.table_id WHERE t.dataset_id = :ds AND o.is_active = true AND o.kind = 'COLUMN' - AND o.snapshot_id = t.current_snapshot_id ORDER BY o.qualified_name LIMIT :lim """ @@ -322,25 +308,57 @@ async def all_schema_objects( ) for r in column_rows: - fp = value_fingerprint(r["data_type"], r["sample_values_json"], r["profile_json"]) - text = f"{r['qualified_name']}: {r['data_type'] or ''}\n{r['description'] or ''}" - if fp: - text += f"\n{fp}" - hits.append( - Hit( - source_kind="schema_object", - id=r["id"], - text=text, - score=1.0, - metadata={ - "qualified_name": r["qualified_name"], - "table_id": str(r["table_id"]), - "kind": "COLUMN", - "values": fp, - }, + hits.append(_schema_hit(r, 1.0)) + return hits + + async def column_value_catalog(self, dataset_id: uuid.UUID, *, limit: int = 2000) -> list[dict]: + """Return every column's value catalogue for the dataset. + + Used (a) to resolve question literals to the columns that store them + and (b) to render a complete, value-anchored column list per in-scope + table. Each item: ``{qualified_name, table_id, data_type, semantic_type, + distinct, values, min, max}``. Dataset-agnostic — reads only the + ingest-computed ``profile_json`` / ``sample_values_json`` / + ``governance_json``. + """ + rows = ( + ( + await self._session.execute( + sa.text( + """ + SELECT o.qualified_name, o.data_type, o.table_id, + o.profile_json, o.sample_values_json, o.governance_json + FROM flyquery_schema_objects o + JOIN flyquery_tables t ON t.id = o.table_id + WHERE t.dataset_id = :ds AND o.is_active = true AND o.kind = 'COLUMN' + ORDER BY o.qualified_name + LIMIT :lim + """ + ), + {"ds": dataset_id, "lim": limit}, ) ) - return hits + .mappings() + .all() + ) + out: list[dict] = [] + for r in rows: + prof = coerce_profile(r["profile_json"], r["sample_values_json"], max_values=40) + out.append( + { + "qualified_name": r["qualified_name"], + "table_id": str(r["table_id"]), + "data_type": r["data_type"], + "semantic_type": _semantic_type(r["governance_json"]), + "distinct": prof["distinct"], + "values": prof["values"], + "min": prof["min"], + "max": prof["max"], + "mixed_sign": prof["mixed_sign"], + "original_header": _original_header(r["governance_json"]), + } + ) + return out async def approved_examples( self, @@ -378,7 +396,7 @@ async def approved_examples( ELSE 0.5 END AS score FROM flyquery_examples - WHERE workspace_id = :workspace_id AND quality = 'APPROVED' {ds_filter} + WHERE workspace_id = :workspace_id AND quality IN ('APPROVED', 'PROPOSED') {ds_filter} ORDER BY score DESC LIMIT :lim """ @@ -392,7 +410,7 @@ async def approved_examples( SELECT id, question, generated_sql, 0.5 AS score FROM flyquery_examples - WHERE workspace_id = :workspace_id AND quality = 'APPROVED' {ds_filter} + WHERE workspace_id = :workspace_id AND quality IN ('APPROVED', 'PROPOSED') {ds_filter} ORDER BY created_at DESC LIMIT :lim """ diff --git a/src/flyquery/resources/prompts/critic.yaml b/src/flyquery/resources/prompts/critic.yaml index 10458bdd..576346d6 100644 --- a/src/flyquery/resources/prompts/critic.yaml +++ b/src/flyquery/resources/prompts/critic.yaml @@ -10,8 +10,36 @@ system: | error message, the complete dataset catalogue (every real table + its column fingerprint), and the GroundedContext. - Produce a corrected SQL. Common errors to fix: + The "Problem" may be a DuckDB execution error, OR the previous SQL + executed but returned 0 ROWS, OR it was a degenerate/no-op query, OR an + ADVISORY warning about an otherwise-runnable query (a SIGN warning, or an + IN-list that under-covers a value group). When a "Column value catalogue" + section is present, it lists the REAL stored values of the columns the + previous SQL filtered on -- use it. + IMPORTANT: if the Problem is a purely advisory note AND you have verified the + previous SQL is already correct, you MAY return it UNCHANGED -- do not rewrite + a correct query gratuitously. BUT a "SIGN ERROR (must fix)" or an under-covered + value group is a REAL defect: you MUST apply the fix exactly as instructed + (e.g. replace the subtraction chain with the single signed-sum given), not keep + the original. + + Produce a corrected SQL. Common issues to fix: + + - **SIGN warning (signed measure)** -- the formula subtracts a term whose + measure is already stored NEGATIVE, double-counting the sign. SUM the + signed line-items instead of subtracting an already-negative term. + - **Under-covered value group** -- a question term umbrellas several values + but the IN-list named only some; include ALL of them or use an anchored LIKE. + - **Wrong filter literal (0 rows)** -- the value in a WHERE/IN does not + match how the data stores it (case, spelling, 'FY23' vs 2023, label vs + code). Replace it with a value COPIED VERBATIM from the value catalogue. + - **Wrong column for an entity (0 rows)** -- the entity is stored under a + different column. Move the filter to the column whose catalogue actually + lists that value. + - **Degenerate / no-op** -- if the previous SQL was a placeholder + (WHERE 1=0, SUM(CASE..THEN 0 ELSE 0), constant SELECT), rewrite it to + really compute the answer; never return another no-op. - **Missing table** -- the SQL references a table that doesn't exist (e.g. ``balance_sheet``, ``income_statement``, ``financials.*``). Look at the catalogue in the prompt and diff --git a/src/flyquery/resources/prompts/explainer.yaml b/src/flyquery/resources/prompts/explainer.yaml index 124cd935..d6eca215 100644 --- a/src/flyquery/resources/prompts/explainer.yaml +++ b/src/flyquery/resources/prompts/explainer.yaml @@ -25,10 +25,10 @@ system: | ---------------------------------- When the result contains columns named ``year_1``, ``year_2``, ..., ``year_N`` (or ``yr1``..``yrN``) with no explicit calendar - year, follow the Excel left-to-right convention: ``year_1`` is the - EARLIEST period and ``year_N`` is the MOST RECENT period. A - question about "the most recent year" maps to the highest-numbered - ``year_N``; "a few years ago" maps to a lower-numbered one. Growth - is ``year_N - year_1`` (NOT the other way around). If you are - unsure, say so explicitly — never assert a direction you don't - have data for. + year, do not assume a fixed direction: different exports order + years differently. If the executed SQL or column metadata shows an + original header (the real year) or aligns to a sibling table's real + calendar-year columns, use that. Only when there is NO such evidence + fall back to the Excel left-to-right convention (``year_1`` earliest, + ``year_N`` most recent). If you are unsure of the direction, say so + explicitly — never assert a chronology you don't have evidence for. diff --git a/src/flyquery/resources/prompts/generation.yaml b/src/flyquery/resources/prompts/generation.yaml index e49b97a2..877968f8 100644 --- a/src/flyquery/resources/prompts/generation.yaml +++ b/src/flyquery/resources/prompts/generation.yaml @@ -19,6 +19,40 @@ system: | Trust order: SEMANTIC_LAYER > UPLOADED_TABLE. + Value anchoring (CRITICAL) + -------------------------- + The prompt lists, for each in-scope column, its data type, semantic role + (measure / dimension / time) and the ACTUAL stored values (or numeric + range). You MUST anchor to these: + - Every literal in a WHERE / IN / GROUP BY / JOIN must be COPIED VERBATIM + from that column's "values:" list (exact case + spelling). Never invent, + translate, pluralise, or re-case a filter literal. + - If a question entity (a brand, region, business unit, person, status, ...) + appears under a column DIFFERENT from the one you'd expect, filter the + column that actually contains it. The "Resolved entities" section tells you + where located literals live -- trust it. + - For a year/period/time column whose values are strings (e.g. 'FY23'), + filter with the STRING form shown -- never an integer like 2023. Never use + a numeric MEASURE column as the year/time axis. If a column shows an + "original header" (e.g. `year_1 (... original header: '2024')`), THAT is its + real meaning -- use it to decide which column is the most recent or a given year. + - A term shown under "Resolved value groups" is an UMBRELLA over several stored + values of one column -- filter the WHOLE set (IN of every listed value, or an + anchored LIKE when the list is incomplete), never a subset. + - A measure annotated SIGNED stores both positive and negative values (some + line-items are already stored negative). To apply a user additive formula + like Total = (+)A (-)B (-)C over a SIGNED measure, SUM the signed line-items + -- do NOT subtract a term whose stored values are already negative, which + double-counts the sign. Only negate a term confirmed to be stored positive. + - Aggregate measure columns; filter and group on dimension/time columns. + + Never produce a no-op + --------------------- + A placeholder query (WHERE 1=0, SUM(CASE WHEN ... THEN 0 ELSE 0 END), a + constant SELECT) is NEVER a valid candidate. If you cannot map a required + filter to a real stored value, widen or drop that filter and lower the + candidate's confidence -- do not emit a constant/empty query. + If the GroundedContext provides a starting_point_sql, your candidates should be deltas (added WHERE clause, swapped column, etc.) -- do not rewrite from scratch unless necessary. diff --git a/src/flyquery/resources/prompts/grounding.yaml b/src/flyquery/resources/prompts/grounding.yaml index e2000b09..9bdf7781 100644 --- a/src/flyquery/resources/prompts/grounding.yaml +++ b/src/flyquery/resources/prompts/grounding.yaml @@ -64,14 +64,27 @@ system: | 4. **Never invent.** Never output a qualified_name that doesn't appear in the catalogue or top-ranked columns. If nothing matches, set ``confidence`` low and explain in ``missing_info``. - 5. **Ordinal-year chronology.** When a table has columns named - ``year_1``, ``year_2``, ..., ``year_N`` (or ``yr1``..``yrN``) - with no explicit calendar year, follow the Excel left-to-right - convention: ``year_1`` is the EARLIEST period and ``year_N`` - is the MOST RECENT period. A question about "the most recent - year" picks the highest-numbered column; "a few years ago" - picks a lower-numbered one. Do not swap this direction in - either the SELECT projection or any WHERE/ORDER BY clauses. + 5. **Ordinal-year chronology -- consult evidence FIRST.** When a table has + columns like ``year_1``..``year_N`` (or ``yr1``..``yrN``) with no explicit + calendar year, decide which is most-recent in this order: + (a) if a column shows an "original header" (e.g. + ``year_1 (... original header: '2024')``), that header IS its real period -- + use it and never contradict it; + (b) else if a SIBLING table in the same dataset carries real calendar-year + columns (e.g. ``year_2024``..``year_2015``), align the ordinal columns to + that ordering; + (c) ONLY if neither exists, fall back as a LAST RESORT to the Excel + left-to-right convention (``year_1`` = earliest, ``year_N`` = most recent) + and lower your confidence. Different exports order years differently, so + never assume the direction when evidence is available. + 6. **Use real values + roles.** Column entries may carry their stored + VALUES (e.g. ``values: 'FY23','FY24'``) and a role tag + (``measure`` / ``dimension`` / ``time``). When the question names an + entity, prefer the column whose listed values actually contain it + (it may not be the obviously-named column). Treat measures as the + things to aggregate and dimensions/time as the things to filter and + group by. Include in ``columns`` every column needed to filter the + question's entities, not just the projected measure. Drill-down ---------- diff --git a/tests/integration/test_reranker.py b/tests/integration/test_reranker.py index 1b29c9e0..d4160c35 100644 --- a/tests/integration/test_reranker.py +++ b/tests/integration/test_reranker.py @@ -20,7 +20,7 @@ import pytest -from flyquery.core.services.retrieval.reranker import NoopReranker, build_reranker +from flyquery.core.services.retrieval.reranker import LexicalReranker, NoopReranker, build_reranker from flyquery.core.services.retrieval.search_index import Hit @@ -54,23 +54,25 @@ async def test_noop_reranker_handles_empty() -> None: @pytest.mark.asyncio -async def test_build_reranker_returns_noop_when_no_model() -> None: +async def test_build_reranker_returns_lexical_when_no_model() -> None: class FakeSettings: reranker_model = "" r = build_reranker(FakeSettings()) - assert isinstance(r, NoopReranker) + # No model configured -> the dependency-free LexicalReranker (a strict win + # over the identity NoopReranker, which left wide-table precision unimproved). + assert isinstance(r, LexicalReranker) @pytest.mark.asyncio -async def test_build_reranker_falls_back_on_bad_model() -> None: +async def test_build_reranker_falls_back_to_lexical_on_bad_model() -> None: class FakeSettings: reranker_model = "nonexistent/model-that-does-not-exist" r = build_reranker(FakeSettings()) - # Should fall back silently to Noop when sentence-transformers isn't installed - # or the model can't be loaded. - assert isinstance(r, NoopReranker) + # Falls back to LexicalReranker when sentence-transformers isn't installed or + # the cross-encoder model can't be loaded (token-overlap still beats no-op). + assert isinstance(r, LexicalReranker) @pytest.mark.asyncio diff --git a/tests/unit/test_query_service.py b/tests/unit/test_query_service.py index 6cd6167f..f0368847 100644 --- a/tests/unit/test_query_service.py +++ b/tests/unit/test_query_service.py @@ -116,6 +116,28 @@ def __iter__(self): return iter(self._rows) +class _TableAwareSession: + """Session whose table-kind lookup reports one TABLE so a realistic + ``... FROM `` query clears the scope + unknown-table guards.""" + + def __init__(self, table_name: str): + self._table_name = table_name + + async def execute(self, stmt, params=None): + return _FakeMappingResult([{"name": self._table_name, "kind": "TABLE"}]) + + +class _TableAwareResolver: + def __init__(self, table_name: str = "t"): + self._session = _TableAwareSession(table_name) + + async def resolve(self, dataset_id, table_names, object_store_base=None, pins=None): + return {} + + async def current_snapshots(self, dataset_id, table_names): + return {} + + class _FakeQueryRepo: """In-memory query repo stub.""" @@ -161,6 +183,21 @@ class _FakeSettings: top_k_metrics = 8 max_refine_retries = 2 grounding_min_confidence = 0.55 + generation_candidates = 3 + # Value-anchoring knobs: disabled here so these orchestration tests exercise + # the core answer() flow (call order / persistence / auto-learn). The + # value-anchoring paths need a real dataset value-scan and are covered by the + # value_anchoring unit tests + integration/e2e. + value_catalog_char_budget = 320 + value_catalog_max_columns = 80 + entity_resolution_enabled = False + entity_resolution_max_literals = 8 + zero_row_repair_enabled = False + candidate_exec_selection = False + synthesis_function_firewall = False + group_resolution_enabled = False + signed_measure_repair_enabled = False + group_coverage_repair_enabled = False def _make_grounded(confidence: float = 0.9, path: str = "SYNTHESIS") -> GroundedContext: @@ -219,6 +256,8 @@ def _make_service( auto_learner=None, semantic_repo=None, generation_agent=None, + critic_agent=None, + table_resolver=None, ): if grounded is None: grounded = _make_grounded() @@ -236,6 +275,10 @@ def _make_service( auto_learner = _FakeAutoLearner() if generation_agent is None: generation_agent = _FakeAgent(candidates) + if critic_agent is None: + critic_agent = _FakeAgent(RefinedSql(sql="SELECT 2", reasoning="fixed", confidence=0.8)) + if table_resolver is None: + table_resolver = _FakeTableResolver() explanation = ResultExplanation(summary="The answer is 1.", chart_hint="none") @@ -244,11 +287,11 @@ def _make_service( reranker=_FakeReranker(), grounding_agent=_FakeAgent(grounded), generation_agent=generation_agent, - critic_agent=_FakeAgent(RefinedSql(sql="SELECT 2", reasoning="fixed", confidence=0.8)), + critic_agent=critic_agent, explainer_agent=_FakeAgent(explanation), ast_classifier=AstClassifier(), scope_guard=ScopeGuard(), - table_resolver=_FakeTableResolver(), + table_resolver=table_resolver, executor=executor, query_repo=query_repo, settings=_FakeSettings(), @@ -340,8 +383,10 @@ async def test_answer_calls_auto_learner_on_first_shot(): @pytest.mark.asyncio async def test_answer_retries_on_execution_error(): - """On ExecutionError, the CriticAgent is called and the result is REFINED_OK or FAILED.""" - # First call fails; critic returns "SELECT 2"; second call also fails → FAILED + """On ExecutionError the CriticAgent is called, its refined (non-degenerate) + SQL is re-executed, and the retry is counted (REFINED_OK or FAILED).""" + # First execution fails; the critic returns a different, runnable SQL; the + # second execution succeeds -> one counted retry, REFINED_OK. call_count = [0] class _AlternatingExecutor: @@ -352,7 +397,15 @@ async def execute(self, sql, attached_tables): return ExecutionResult(rows=[{"v": 2}], columns=["v"], row_count=1, truncated=False) repo = _FakeQueryRepo() - svc = _make_service(executor=_AlternatingExecutor(), query_repo=repo) + svc = _make_service( + executor=_AlternatingExecutor(), + query_repo=repo, + candidates=_make_candidates("SELECT v FROM t"), + critic_agent=_FakeAgent( + RefinedSql(sql="SELECT v FROM t WHERE v > 0", reasoning="fixed", confidence=0.8) + ), + table_resolver=_TableAwareResolver(), + ) result = await svc.answer( tenant_id="ten-a", From f56ebfacccce1a2ced5a4d84290e4c33153d3e31 Mon Sep 17 00:00:00 2001 From: Andres Contreras Date: Wed, 14 Oct 2026 11:21:28 -0700 Subject: [PATCH 05/20] Preserve executed SQL receipts and honor redacted value access --- .../core/services/ingestion/stages/embed.py | 11 +++-- .../core/services/query/query_service.py | 12 ++--- .../core/services/query/value_anchoring.py | 8 ++- .../core/services/retrieval/search_index.py | 14 ++++-- tests/unit/test_embed_stage.py | 49 +++++++++++++++++++ tests/unit/test_query_service.py | 48 ++++++++++++++++-- tests/unit/test_sql_read_boundary.py | 2 +- 7 files changed, 123 insertions(+), 21 deletions(-) diff --git a/src/flyquery/core/services/ingestion/stages/embed.py b/src/flyquery/core/services/ingestion/stages/embed.py index d3d92119..30f45350 100644 --- a/src/flyquery/core/services/ingestion/stages/embed.py +++ b/src/flyquery/core/services/ingestion/stages/embed.py @@ -1,4 +1,5 @@ # Copyright 2024-2026 Firefly Software Foundation +# SPDX-License-Identifier: Apache-2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -103,7 +104,7 @@ async def run_embed( SELECT id, qualified_name, data_type, description, synonyms_json, profile_json, sample_values_json FROM flyquery_schema_objects - WHERE snapshot_id = :sid AND tenant_id = :tenant + WHERE snapshot_id = :sid AND tenant_id = :tenant AND is_active = true ORDER BY kind, qualified_name """ ), @@ -174,15 +175,17 @@ def _render_values(row: dict, *, max_chars: int = 300) -> str: PII safety: prefer the PII-gated ``sample_values_json`` -- the pii_tag stage wipes it to ``[]`` when a redact/reject policy fires, so an empty list here means "do not surface raw samples". When no gated samples are - present we fall back to ``profile_json.top_values``, the stored distinct - set for low-cardinality columns (aggregate / low-cardinality, so lower - PII risk). The result is capped to ``max_chars`` either way. + recorded we may use ``profile_json.top_values``. An explicitly empty + sample list blocks that fallback, including for low-cardinality data. + The result is capped to ``max_chars`` either way. """ seen: set[str] = set() uniq: list[str] = [] # Preferred source: PII-gated samples (empty list = intentionally wiped). samples = row.get("sample_values_json") + if samples == []: + return "" if isinstance(samples, list) and samples: for v in samples: if v is None: diff --git a/src/flyquery/core/services/query/query_service.py b/src/flyquery/core/services/query/query_service.py index 99f5e6c3..794ef667 100644 --- a/src/flyquery/core/services/query/query_service.py +++ b/src/flyquery/core/services/query/query_service.py @@ -818,14 +818,14 @@ def _is_good(r, s) -> bool: and not value_anchoring.is_degenerate_sql(s) ) - # round-2 #4: remember the best correct result so an ADVISORY repair can - # never replace a correct answer with a worse one. + # Retain an executed, nonempty result if a repair fails. Row count is + # an execution check; it does not establish semantic correctness. best_ok = (chosen_sql, result, ast) if _is_good(result, chosen_sql) else None # round-2 #5B/#7: when the result is already OK, an advisory check may still # ask the critic to reconsider (signed-measure double-subtraction; an IN-list # that under-covers a value group). It rides the non-destructive loop below, - # so it can only ever improve the answer or be ignored. + # and preserves the previous executed result when a proposal fails. adv_msg = None if _is_good(result, chosen_sql): adv_msg = await self._advisory_repair(chosen_sql, ast, col_catalog, question, dataset_id, bundle) @@ -859,10 +859,10 @@ def _is_good(r, s) -> bool: break # critic kept the SQL -> accept it as already correct if value_anchoring.is_degenerate_sql(new_sql): break # never adopt a placeholder; best_ok (if any) is restored below - chosen_sql = new_sql - run = await self._run_sql_once(chosen_sql, dataset_id, scopes, dataset_allowlist, bundle) + run = await self._run_sql_once(new_sql, dataset_id, scopes, dataset_allowlist, bundle) if run["status"] in ("scope", "firewall"): break + chosen_sql = new_sql result = run["result"] ast = run["ast"] retries += 1 @@ -874,7 +874,7 @@ def _is_good(r, s) -> bool: else: adv_msg = None - # round-2 #4: if repair degraded a previously-correct answer, restore it. + # Restore the executed fallback when repair produces no usable result. if best_ok is not None and not _is_good(result, chosen_sql): chosen_sql, result, ast = best_ok diff --git a/src/flyquery/core/services/query/value_anchoring.py b/src/flyquery/core/services/query/value_anchoring.py index 1b8c0b19..bf224a7a 100644 --- a/src/flyquery/core/services/query/value_anchoring.py +++ b/src/flyquery/core/services/query/value_anchoring.py @@ -1,4 +1,5 @@ # Copyright 2024-2026 Firefly Software Foundation +# SPDX-License-Identifier: Apache-2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -109,8 +110,11 @@ def coerce_profile( low-cardinality column (drawn from ``profile_json.top_values`` first, then ``sample_values_json``). ``min``/``max`` come from the numeric profile. """ - profile = _as_obj(profile_json) or {} - samples = _as_obj(sample_values_json) or [] + samples = _as_obj(sample_values_json) + # The ingestion PII policy uses [] to revoke sample access. Profile + # values and numeric ranges must not undo that decision in prompts. + profile = {} if samples == [] else (_as_obj(profile_json) or {}) + samples = samples or [] distinct = profile.get("distinct_estimate") if isinstance(profile, dict) else None mn = profile.get("min") if isinstance(profile, dict) else None mx = profile.get("max") if isinstance(profile, dict) else None diff --git a/src/flyquery/core/services/retrieval/search_index.py b/src/flyquery/core/services/retrieval/search_index.py index c94090a6..c47facf3 100644 --- a/src/flyquery/core/services/retrieval/search_index.py +++ b/src/flyquery/core/services/retrieval/search_index.py @@ -1,4 +1,5 @@ # Copyright 2024-2026 Firefly Software Foundation +# SPDX-License-Identifier: Apache-2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -118,10 +119,13 @@ def _schema_hit(r, score: float) -> Hit: kind = r.get("kind", None) semantic_type = _semantic_type(r["governance_json"]) if "governance_json" in r else None suffix = "" + samples = r.get("sample_values_json", None) + value_access = samples != [] + profile = r.get("profile_json", None) if value_access else {} if kind == "COLUMN": suffix = _col_value_suffix( - r.get("profile_json", None), - r.get("sample_values_json", None), + profile, + samples, semantic_type, ) text = f"{r['qualified_name']}: {r['data_type'] or ''}\n{r['description'] or ''}{suffix}" @@ -136,8 +140,9 @@ def _schema_hit(r, score: float) -> Hit: "kind": kind, "data_type": r["data_type"], "semantic_type": semantic_type, - "profile_json": r.get("profile_json", None), - "sample_values_json": r.get("sample_values_json", None), + "profile_json": profile, + "sample_values_json": samples, + "value_access": value_access, }, ) @@ -355,6 +360,7 @@ async def column_value_catalog(self, dataset_id: uuid.UUID, *, limit: int = 2000 "min": prof["min"], "max": prof["max"], "mixed_sign": prof["mixed_sign"], + "value_access": r["sample_values_json"] != [], "original_header": _original_header(r["governance_json"]), } ) diff --git a/tests/unit/test_embed_stage.py b/tests/unit/test_embed_stage.py index d0a9ac63..e000a47d 100644 --- a/tests/unit/test_embed_stage.py +++ b/tests/unit/test_embed_stage.py @@ -1,4 +1,5 @@ # Copyright 2024-2026 Firefly Software Foundation +# SPDX-License-Identifier: Apache-2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -30,6 +31,54 @@ from flyquery.core.services.ingestion.stages.embed import _build_embed_text +def test_redacted_samples_do_not_return_through_profile_values() -> None: + row = { + "qualified_name": "people.email", + "pii_tag": "EMAIL_ADDRESS", + "sample_values_json": [], + "profile_json": {"top_values": [{"value": "synthetic@example.invalid", "count": 1}]}, + } + text = _build_embed_text(row) + assert "synthetic@example.invalid" not in text + assert "Values:" not in text + + +def test_redacted_catalog_values_and_ranges_remain_unavailable() -> None: + from flyquery.core.services.query.value_anchoring import coerce_profile + + profile = {"top_values": [{"value": "private-id"}], "min": 17, "max": 17} + result = coerce_profile(profile, []) + assert result["values"] == [] + assert result["min"] is None + assert result["max"] is None + + +def test_unredacted_profile_values_remain_available() -> None: + from flyquery.core.services.query.value_anchoring import coerce_profile + + result = coerce_profile({"top_values": [{"value": "approved-category"}]}, None) + assert result["values"] == ["approved-category"] + + +def test_redacted_retrieval_metadata_does_not_export_the_raw_profile() -> None: + from flyquery.core.services.retrieval.search_index import _schema_hit + + row = { + "id": "synthetic-column", + "table_id": "synthetic-table", + "kind": "COLUMN", + "qualified_name": "people.email", + "data_type": "VARCHAR", + "description": "Email address", + "sample_values_json": [], + "profile_json": {"top_values": [{"value": "synthetic@example.invalid"}]}, + } + hit = _schema_hit(row, 1.0) + assert "synthetic@example.invalid" not in str(hit.metadata) + assert "synthetic@example.invalid" not in hit.text + assert hit.metadata["value_access"] is False + + class TestBuildEmbedText: def test_qualified_name_and_type(self) -> None: row = { diff --git a/tests/unit/test_query_service.py b/tests/unit/test_query_service.py index 1d9c30d4..1cbdc575 100644 --- a/tests/unit/test_query_service.py +++ b/tests/unit/test_query_service.py @@ -118,14 +118,14 @@ def __iter__(self): class _TableAwareSession: - """Session whose table-kind lookup reports one TABLE so a realistic + """Session whose table-kind lookup reports one UPLOADED table so a realistic ``... FROM `` query clears the scope + unknown-table guards.""" def __init__(self, table_name: str): self._table_name = table_name async def execute(self, stmt, params=None): - return _FakeMappingResult([{"name": self._table_name, "kind": "TABLE"}]) + return _FakeMappingResult([{"name": self._table_name, "kind": "UPLOADED"}]) class _TableAwareResolver: @@ -416,8 +416,9 @@ async def execute(self, sql, attached_tables): scopes={"flyquery.query:read"}, ) - assert result.execution_status in ("REFINED_OK", "FAILED") - assert repo.created_queries[0]["retries"] >= 1 + assert result.execution_status == "REFINED_OK" + assert repo.created_queries[0]["retries"] == 1 + assert call_count[0] == 2 @pytest.mark.asyncio @@ -612,3 +613,42 @@ async def execute(self, sql, attached_tables): ) assert result.execution_status not in ("OK", "REFINED_OK") assert executor.calls == 1 + + +@pytest.mark.asyncio +async def test_rejected_advisory_sql_keeps_the_executed_query_and_result_together(tmp_path): + from flyquery.core.services.execution.duckdb_executor import DuckDBExecutor + + file = tmp_path / "unregistered.csv" + file.write_text("evidence\nsynthetic-unregistered-file\n") + + class Settings: + duckdb_memory_limit = "256MB" + default_row_cap = 100 + + repo = _FakeQueryRepo() + original_sql = "SELECT 7 AS value" + svc = _make_service( + candidates=_make_candidates(original_sql), + executor=DuckDBExecutor(Settings()), + query_repo=repo, + critic_agent=_FakeAgent( + RefinedSql(sql=f"SELECT * FROM read_csv_auto('{file}')", reasoning="fixture", confidence=0.8) + ), + ) + + async def advisory(*args): + return "Reconsider this synthetic result" + + svc._advisory_repair = advisory + result = await svc.answer( + tenant_id="ten-a", + workspace_id=uuid.uuid4(), + dataset_id=uuid.uuid4(), + question="synthetic advisory", + scopes={"flyquery.query:read"}, + ) + assert result.execution_status == "OK" + assert result.sql == original_sql + assert result.preview == [{"value": 7}] + assert repo.created_queries[0]["executed_sql"] == original_sql diff --git a/tests/unit/test_sql_read_boundary.py b/tests/unit/test_sql_read_boundary.py index d5a842bb..e0393705 100644 --- a/tests/unit/test_sql_read_boundary.py +++ b/tests/unit/test_sql_read_boundary.py @@ -39,7 +39,7 @@ async def __aexit__(self, *args): pass async def execute(self, statement, params): - assert params == {"ds": dataset, "names": ["orders"]} + assert params == {"ds": dataset, "names": ["orders"], "pins": "{}"} return Rows() class TableRepository: From 69e06362b06eedd8f1dfb39c9482dc2c5e90b12f Mon Sep 17 00:00:00 2001 From: Andres Contreras Date: Wed, 14 Oct 2026 11:23:47 -0700 Subject: [PATCH 06/20] Pin executed snapshots across conversation turns --- .../core/services/query/query_service.py | 20 +++++- tests/unit/test_query_service.py | 64 +++++++++++++++++++ 2 files changed, 82 insertions(+), 2 deletions(-) diff --git a/src/flyquery/core/services/query/query_service.py b/src/flyquery/core/services/query/query_service.py index 794ef667..b6796f64 100644 --- a/src/flyquery/core/services/query/query_service.py +++ b/src/flyquery/core/services/query/query_service.py @@ -662,6 +662,7 @@ async def answer( bundle["starting_point_sql"] = starting_point_sql bundle["prior_table_qnames"] = prior_table_qnames + bundle["snapshot_pins"] = dict(prior_snapshot_pins) # ------------------------------------------------------------------ # 3. Grounding — pydantic-ai's Agent.run expects a STRING prompt, @@ -972,6 +973,9 @@ def _is_good(r, s) -> bool: # ------------------------------------------------------------------ # 13. Persist conversation turn (Phase E drill-down) # ------------------------------------------------------------------ + execution_snapshot_pins = { + name: bundle["snapshot_pins"][name] for name in ast.table_refs if name in bundle["snapshot_pins"] + } if ( conversation_id is not None and self._conversation_service is not None @@ -985,7 +989,7 @@ def _is_good(r, s) -> bool: executed_sql=chosen_sql, summary=explanation_obj.summary if explanation_obj else None, table_qnames_json=list(ast.table_refs), - snapshot_pins_json=prior_snapshot_pins, + snapshot_pins_json=execution_snapshot_pins, elapsed_ms=elapsed, ) @@ -1001,6 +1005,7 @@ def _is_good(r, s) -> bool: explanation=explanation_obj.summary if explanation_obj else None, clarification=clarification, grounded_summary=self._grounded_summary(grounded), + snapshot_pins=execution_snapshot_pins, ) # ------------------------------------------------------------------ @@ -1163,7 +1168,7 @@ async def _run_sql_once( "error": None, } - attached = await self._table_resolver.resolve(dataset_id, list(ast.table_refs)) + attached = await self._resolve_attached_tables(dataset_id, list(ast.table_refs), bundle) result = await self._executor.execute(sql, attached) if isinstance(result, ExecutionResult): status = "ok" if result.row_count > 0 else "empty" @@ -1171,6 +1176,17 @@ async def _run_sql_once( status = "error" return {"status": status, "result": result, "ast": ast, "error": None} + async def _resolve_attached_tables(self, dataset_id, table_names: list[str], bundle: dict) -> dict: + pins = bundle.setdefault("snapshot_pins", {}) + unpinned = [name for name in table_names if name not in pins] + if unpinned: + pins.update(await self._table_resolver.current_snapshots(dataset_id, unpinned)) + # Resolve using captured IDs so re-ingestion cannot change the data + # between candidate selection, repair, and a later conversation turn. + return await self._table_resolver.resolve( + dataset_id, table_names, pins={name: pins[name] for name in table_names if name in pins} + ) + def _needs_repair(self, result, sql: str) -> bool: """A query needs repair if it errored, is degenerate, or ran to 0 rows while filtering on equality/IN literals (G2/G5).""" diff --git a/tests/unit/test_query_service.py b/tests/unit/test_query_service.py index 1cbdc575..5c738ecd 100644 --- a/tests/unit/test_query_service.py +++ b/tests/unit/test_query_service.py @@ -652,3 +652,67 @@ async def advisory(*args): assert result.sql == original_sql assert result.preview == [{"value": 7}] assert repo.created_queries[0]["executed_sql"] == original_sql + + +@pytest.mark.asyncio +async def test_conversation_reuses_the_actual_first_snapshot_after_reingestion(tmp_path): + import pyarrow as pa + import pyarrow.parquet as pq + + from flyquery.core.services.execution.duckdb_executor import DuckDBExecutor + + old_snapshot, new_snapshot = str(uuid.uuid4()), str(uuid.uuid4()) + paths = {} + for snapshot, value in ((old_snapshot, 10), (new_snapshot, 99)): + path = tmp_path / f"{snapshot}.parquet" + pq.write_table(pa.table({"total": [value]}), path) + paths[snapshot] = str(path) + + class Settings: + duckdb_memory_limit = "256MB" + default_row_cap = 100 + + class Resolver(_TableAwareResolver): + current = old_snapshot + + async def current_snapshots(self, dataset_id, table_names): + return {name: self.current for name in table_names} + + async def resolve(self, dataset_id, table_names, object_store_base=None, pins=None): + return {name: paths[(pins or {}).get(name, self.current)] for name in table_names} + + class Conversation: + turn = None + + async def last_turn(self, conversation_id): + return self.turn + + async def append_turn(self, **kwargs): + self.turn = kwargs + + resolver = Resolver("orders") + conversation = Conversation() + svc = _make_service( + candidates=_make_candidates("SELECT total FROM orders"), + executor=DuckDBExecutor(Settings()), + table_resolver=resolver, + ) + svc._conversation_service = conversation + arguments = { + "tenant_id": "ten-a", + "workspace_id": uuid.uuid4(), + "dataset_id": uuid.uuid4(), + "conversation_id": uuid.uuid4(), + "question": "synthetic snapshot", + "scopes": {"flyquery.query:read"}, + } + first = await svc.answer(**arguments) + assert first.preview == [{"total": 10}] + assert first.snapshot_pins == {"orders": old_snapshot} + assert conversation.turn["snapshot_pins_json"] == first.snapshot_pins + + resolver.current = new_snapshot + second = await svc.answer(**arguments) + assert second.preview == [{"total": 10}] + assert second.snapshot_pins == first.snapshot_pins + assert conversation.turn["snapshot_pins_json"] == first.snapshot_pins From 03c70f1ec9e3953eb4c5f4ed1391be9223a968f6 Mon Sep 17 00:00:00 2001 From: Andres Contreras Date: Wed, 14 Oct 2026 11:25:12 -0700 Subject: [PATCH 07/20] Describe the value catalog in retrieval types --- src/flyquery/core/services/query/query_service.py | 2 +- src/flyquery/core/services/retrieval/hybrid_retriever.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/flyquery/core/services/query/query_service.py b/src/flyquery/core/services/query/query_service.py index b6796f64..6132b726 100644 --- a/src/flyquery/core/services/query/query_service.py +++ b/src/flyquery/core/services/query/query_service.py @@ -843,7 +843,7 @@ def _is_good(r, s) -> bool: if self._needs_repair(result, chosen_sql): critic_msg = self._repair_message(result, chosen_sql, ast, col_catalog) else: - critic_msg = adv_msg + critic_msg = adv_msg or "" value_hints = self._build_value_hints(chosen_sql, col_catalog, ast) critic_prompt = _render_critic_prompt( question=question, diff --git a/src/flyquery/core/services/retrieval/hybrid_retriever.py b/src/flyquery/core/services/retrieval/hybrid_retriever.py index 666856e6..1d2df39c 100644 --- a/src/flyquery/core/services/retrieval/hybrid_retriever.py +++ b/src/flyquery/core/services/retrieval/hybrid_retriever.py @@ -84,8 +84,8 @@ async def retrieve( top_k_schema: int = 12, top_k_examples: int = 5, top_k_metrics: int = 8, - ) -> dict[str, list[Hit]]: - """Run full hybrid retrieval and return a bundle of hit lists. + ) -> dict[str, list[Hit] | list[dict[str, Any]]]: + """Run full hybrid retrieval and return hits with a column value catalog. :param query: natural-language question :param dataset_id: dataset scope for schema objects / metrics From 5d4059b83b531abd051d1088ef76c3105b707c8c Mon Sep 17 00:00:00 2001 From: Andres Contreras Date: Wed, 14 Oct 2026 11:48:46 -0700 Subject: [PATCH 08/20] Reject inadmissible requests before retrieval and model invocation --- .../core/services/query/query_service.py | 39 +++++++++++++++++++ tests/unit/test_query_service.py | 36 +++++++++++++++++ 2 files changed, 75 insertions(+) diff --git a/src/flyquery/core/services/query/query_service.py b/src/flyquery/core/services/query/query_service.py index 6132b726..3786e029 100644 --- a/src/flyquery/core/services/query/query_service.py +++ b/src/flyquery/core/services/query/query_service.py @@ -626,6 +626,45 @@ async def answer( """ start_ms = time.monotonic_ns() // 1_000_000 + if not scopes.intersection( + {"flyquery.query:read", "flyquery.sql:execute", "flyquery.derived:write", "*"} + ) or (dataset_allowlist is not None and str(dataset_id) not in dataset_allowlist): + elapsed = (time.monotonic_ns() // 1_000_000) - start_ms + # Retain caller-supplied denial evidence without attaching the + # record to an unauthorized dataset or invoking retrieval/models. + query_id = await self._query_repo.create_query( + tenant_id=tenant_id, + workspace_id=workspace_id, + dataset_id=None, + question=question, + semantic_path_taken=None, + candidates_json=[], + chosen_candidate_index=None, + executed_sql=None, + ast_classification=None, + execution_status="REJECTED_BY_FIREWALL", + retries=0, + row_count=None, + elapsed_ms=elapsed, + clarification_emitted=False, + clarification_json=None, + pii_findings_json=None, + error_json={"code": "SCOPE_ADMISSION_DENIED", "requested_dataset_id": str(dataset_id)}, + ) + return AnswerResult( + query_id=query_id, + sql=None, + execution_status="REJECTED_BY_FIREWALL", + preview=None, + row_count=None, + truncated=False, + elapsed_ms=elapsed, + chart_hint=None, + explanation=None, + clarification=None, + grounded_summary=None, + ) + # ------------------------------------------------------------------ # 1. Hybrid retrieval # ------------------------------------------------------------------ diff --git a/tests/unit/test_query_service.py b/tests/unit/test_query_service.py index 5c738ecd..a892f999 100644 --- a/tests/unit/test_query_service.py +++ b/tests/unit/test_query_service.py @@ -716,3 +716,39 @@ async def append_turn(self, **kwargs): assert second.preview == [{"total": 10}] assert second.snapshot_pins == first.snapshot_pins assert conversation.turn["snapshot_pins_json"] == first.snapshot_pins + + +@pytest.mark.asyncio +@pytest.mark.parametrize("missing_scope", [True, False]) +async def test_admission_denial_precedes_retrieval_and_agent_calls(missing_scope): + retrievals = [] + + class Retriever(_FakeRetriever): + async def retrieve(self, *args, **kwargs): + retrievals.append(kwargs) + return await super().retrieve(*args, **kwargs) + + generation = _CountingAgent(_make_candidates("SELECT 1 AS value")) + grounding = _CountingAgent(_make_grounded()) + svc = _make_service(generation_agent=generation) + svc._retriever = Retriever() + svc._grounding_agent = grounding + result = await svc.answer( + tenant_id="ten-a", + workspace_id=uuid.uuid4(), + dataset_id=uuid.uuid4(), + question="synthetic denied request", + scopes=set() if missing_scope else {"flyquery.query:read"}, + dataset_allowlist=None if missing_scope else set(), + ) + assert result.execution_status == "REJECTED_BY_FIREWALL" + assert result.sql is None + assert retrievals == [] + assert grounding.calls == 0 + assert generation.calls == 0 + receipt = svc._query_repo.created_queries[0] + assert receipt["dataset_id"] is None + assert receipt["executed_sql"] is None + assert receipt["candidates_json"] == [] + assert receipt["retries"] == 0 + assert receipt["error_json"]["code"] == "SCOPE_ADMISSION_DENIED" From b3cbf5ddc62ce950d1aaf316f04b8ac3c8d3d677 Mon Sep 17 00:00:00 2001 From: Andres Contreras Date: Wed, 14 Oct 2026 11:52:40 -0700 Subject: [PATCH 09/20] Confine value anchoring to eligible registered snapshots --- .../core/services/query/query_service.py | 243 +++++------ tests/unit/test_value_read_boundary.py | 377 ++++++++++++++++++ 2 files changed, 500 insertions(+), 120 deletions(-) create mode 100644 tests/unit/test_value_read_boundary.py diff --git a/src/flyquery/core/services/query/query_service.py b/src/flyquery/core/services/query/query_service.py index 3786e029..1e56652c 100644 --- a/src/flyquery/core/services/query/query_service.py +++ b/src/flyquery/core/services/query/query_service.py @@ -1306,19 +1306,23 @@ async def _advisory_repair(self, sql, ast, col_catalog, question, dataset_id, bu f"an anchored LIKE; keep the original only if the exclusion is genuinely intended." ) if self._settings.signed_measure_repair_enabled: - hint = await self._signed_measure_hint(sql, ast, col_catalog, dataset_id) + hint = await self._signed_measure_hint(sql, ast, col_catalog, dataset_id, bundle) if hint: reasons.append(hint) return " ".join(reasons) if reasons else None - async def _signed_measure_hint(self, sql, ast, col_catalog, dataset_id) -> str | None: + async def _signed_measure_hint(self, sql, ast, col_catalog, dataset_id, bundle) -> str | None: """Probe whether the SQL subtracts a term whose SIGNED measure is already stored negative (so subtracting double-counts the sign). Best-effort (#5B).""" try: + tables = [t for t in ast.table_refs if t] + eligible = _eligible_value_columns(col_catalog, tables) mixed = { c["qualified_name"].rsplit(".", 1)[-1].lower() for c in col_catalog - if c.get("mixed_sign") and value_anchoring.semantic_role(c.get("semantic_type")) == "measure" + if _allows_value_access(c) + and c.get("mixed_sign") + and value_anchoring.semantic_role(c.get("semantic_type")) == "measure" } if not mixed: return None @@ -1330,15 +1334,20 @@ async def _signed_measure_hint(self, sql, ast, col_catalog, dataset_id) -> str | ] if not subtracted: return None - tables = [t for t in ast.table_refs if t] - if not tables: + eligible = { + table: columns + for table, columns in eligible.items() + if any( + term["measure_col"].lower() in columns and term["dim_col"].lower() in columns + for term in subtracted + ) + } + if not eligible: return None - attached = await self._table_resolver.resolve(dataset_id, tables) + attached = await self._resolve_attached_tables(dataset_id, list(eligible), bundle) if not attached: return None - import asyncio - - offenders = await asyncio.to_thread(_probe_signed_terms, attached, subtracted) + offenders = await self._probe_signed_terms(attached, subtracted, eligible) if not offenders: return None parts = "; ".join(f"{o['dim']} IN {o['literals']} sums to {o['sum']:.0f}" for o in offenders[:6]) @@ -1363,6 +1372,36 @@ async def _signed_measure_hint(self, sql, ast, col_catalog, dataset_id) -> str | logger.debug("signed-measure probe failed: %s", exc) return None + async def _probe_signed_terms( + self, attached: dict[str, str], terms: list[dict], eligible: dict + ) -> list[dict]: + offenders: list[dict] = [] + for term in terms[:6]: + # A partial literal set can reverse the sign and produce a false repair. + if not term["literals"] or len(term["literals"]) > 25: + continue + total = None + for table, path in attached.items(): + columns = eligible.get(table, {}) + measure = columns.get(term["measure_col"].lower()) + dimension = columns.get(term["dim_col"].lower()) + if measure is None or dimension is None: + continue + in_list = ", ".join(_sql_literal(str(lit)) for lit in term["literals"]) + sql = ( + f"SELECT SUM(TRY_CAST({_sql_identifier(measure['column'])} AS DOUBLE)) AS total " + f"FROM {_sql_identifier(table)} " + f"WHERE CAST({_sql_identifier(dimension['column'])} AS VARCHAR) IN ({in_list})" + ) + result = await self._executor.execute(sql, {table: path}) + if isinstance(result, ExecutionResult) and result.rows: + value = result.rows[0].get("total") + if value is not None: + total = (total or 0.0) + float(value) + if total is not None and total < 0: + offenders.append({"dim": term["dim_col"], "literals": term["literals"], "sum": total}) + return offenders + async def _resolve_entities( self, dataset_id: uuid.UUID, @@ -1383,6 +1422,7 @@ async def _resolve_entities( if not literals: return empty + col_catalog = [column for column in col_catalog if _allows_value_access(column)] hierarchy = value_anchoring.relationship_intent(question) # round-2 #1: a term that umbrellas >=2 values of one column -> a group. groups: list[dict] = [] @@ -1434,123 +1474,86 @@ async def _scan_columns_for_values( if (getattr(h, "metadata", {}) or {}).get("kind") == "TABLE" ] table_names = [t for t in dict.fromkeys(table_names) if t] - if not table_names: - return [] - attached = await self._table_resolver.resolve(dataset_id, table_names) - if not attached: + eligible = _eligible_value_columns(bundle.get("column_catalog") or [], table_names) + eligible = { + table: { + name: column + for name, column in columns.items() + if str(column.get("data_type") or "") + .upper() + .startswith(("VARCHAR", "TEXT", "STRING", "CHAR")) + } + for table, columns in eligible.items() + } + eligible = {table: columns for table, columns in eligible.items() if columns} + literals = list(dict.fromkeys(lit.lower() for lit in literals if lit))[ + : self._settings.entity_resolution_max_literals + ] + if not eligible or not literals: return [] - import asyncio - - return await asyncio.to_thread(_scan_sync, attached, literals) - - -def _probe_signed_terms(attached_tables: dict[str, str], terms: list[dict]) -> list[dict]: - """Sum each subtracted term's measure over its line-items; report the ones that - sum NEGATIVE (already stored negative → subtracting double-counts). Best-effort.""" - try: - import duckdb - except ImportError: # pragma: no cover - return [] - paths = list(attached_tables.values()) - if not paths: - return [] - offenders: list[dict] = [] - conn = None - try: - conn = duckdb.connect(":memory:") - conn.execute("SET threads=2") - for t in terms: - mq = t["measure_col"].replace(chr(34), chr(34) * 2) - dq = t["dim_col"].replace(chr(34), chr(34) * 2) - in_list = ", ".join("'" + str(lit).replace("'", "''") + "'" for lit in t["literals"]) - total = None - for path in paths: - try: - cols = { - c[0].lower() - for c in conn.execute(f"DESCRIBE SELECT * FROM read_parquet('{path}')").fetchall() - } - if t["measure_col"].lower() not in cols or t["dim_col"].lower() not in cols: - continue - s = conn.execute( - f"SELECT SUM(TRY_CAST(\"{mq}\" AS DOUBLE)) FROM read_parquet('{path}') " - f'WHERE CAST("{dq}" AS VARCHAR) IN ({in_list})' - ).fetchone() - if s and s[0] is not None: - total = (total or 0.0) + float(s[0]) - except Exception: # noqa: BLE001 - continue - if total is not None and total < 0: - offenders.append({"dim": t["dim_col"], "literals": t["literals"], "sum": total}) - except Exception: # noqa: BLE001 - return offenders - finally: - if conn is not None: - conn.close() - return offenders - - -def _scan_sync(attached_tables: dict[str, str], literals: list[str]) -> list[dict]: - """Find which column stores each question literal: one bounded scan per table. - - For each table we run a single pass that, per VARCHAR column, returns the - first stored value equal (case-insensitively) to any of the literals. This - resolves high-cardinality entities (person/brand names) the low-cardinality - value catalogue can't carry. Best-effort + dataset-agnostic. - """ - try: - import duckdb - except ImportError: # pragma: no cover - return [] - lits = [s.lower() for s in literals if s] - if not lits: - return [] - in_list = ", ".join("'" + s.replace("'", "''") + "'" for s in lits) - found: list[dict] = [] - seen: set[tuple[str, str]] = set() - for tname, path in attached_tables.items(): - conn = None - try: - conn = duckdb.connect(":memory:") - conn.execute("SET threads=2") - desc = conn.execute(f"DESCRIBE SELECT * FROM read_parquet('{path}')").fetchall() - vcols = [ - d[0] for d in desc if str(d[1]).upper().startswith(("VARCHAR", "TEXT", "STRING", "CHAR")) - ][:80] - if not vcols: + attached = await self._resolve_attached_tables(dataset_id, list(eligible), bundle) + in_list = ", ".join(_sql_literal(lit) for lit in literals) + found: list[dict] = [] + for table, path in attached.items(): + columns = list(eligible.get(table, {}).values())[:80] + if not columns: continue - cols_sql = [] - for i, c in enumerate(vcols): - cq = c.replace(chr(34), chr(34) * 2) - pred = f'lower(CAST("{cq}" AS VARCHAR)) IN ({in_list})' - cols_sql.append(f'MAX(CASE WHEN {pred} THEN CAST("{cq}" AS VARCHAR) END) AS m{i}') - # match_count: how many rows this column has the literal in. A value - # that REPEATS is a grouping/parent key; one that appears once is an - # identity. Same single scan -- no extra cost. - cols_sql.append(f"SUM(CASE WHEN {pred} THEN 1 ELSE 0 END) AS c{i}") - row = conn.execute(f"SELECT {', '.join(cols_sql)} FROM read_parquet('{path}')").fetchone() - if not row: + expressions: list[str] = [] + for i, column in enumerate(columns): + identifier = _sql_identifier(column["column"]) + predicate = f"lower(CAST({identifier} AS VARCHAR)) IN ({in_list})" + expressions.append( + f"MAX(CASE WHEN {predicate} THEN CAST({identifier} AS VARCHAR) END) AS m{i}" + ) + expressions.append(f"SUM(CASE WHEN {predicate} THEN 1 ELSE 0 END) AS c{i}") + result = await self._executor.execute( + f"SELECT {', '.join(expressions)} FROM {_sql_identifier(table)}", {table: path} + ) + if not isinstance(result, ExecutionResult) or not result.rows: continue - for i, c in enumerate(vcols): - val = row[2 * i] - cnt = row[2 * i + 1] - if val is None: - continue - key = (str(val).lower(), f"{tname}.{c}") - if key in seen: + row = result.rows[0] + for i, column in enumerate(columns): + value = row.get(f"m{i}") + if value is None: continue - seen.add(key) found.append( { - "literal": str(val), - "column": f"{tname}.{c}", - "value": val, - "match_count": int(cnt or 0), + "literal": str(value), + "column": column["qualified_name"], + "value": value, + "match_count": int(row.get(f"c{i}") or 0), } ) - except Exception: # noqa: BLE001 - resolution is best-effort + return found + + +def _allows_value_access(column: dict) -> bool: + samples = column.get("sample_values_json") + return ( + column.get("value_access") is True + and samples != [] + and (samples is None or isinstance(samples, list)) + ) + + +def _eligible_value_columns(catalog: list[dict], tables: list[str]) -> dict[str, dict[str, dict]]: + eligible: dict[str, dict[str, dict]] = {} + blocked = {column.get("qualified_name") for column in catalog if not _allows_value_access(column)} + for column in catalog: + qualified = column.get("qualified_name") + if not isinstance(qualified, str) or qualified in blocked or not _allows_value_access(column): continue - finally: - if conn is not None: - conn.close() - return found + parent, separator, name = qualified.rpartition(".") + table = parent.rsplit(".", 1)[-1] + if not separator or not name or table not in tables: + continue + eligible.setdefault(table, {})[name.lower()] = {**column, "column": name} + return eligible + + +def _sql_identifier(value: str) -> str: + return '"' + value.replace('"', '""') + '"' + + +def _sql_literal(value: str) -> str: + return "'" + value.replace("'", "''") + "'" diff --git a/tests/unit/test_value_read_boundary.py b/tests/unit/test_value_read_boundary.py new file mode 100644 index 00000000..83bf3c0f --- /dev/null +++ b/tests/unit/test_value_read_boundary.py @@ -0,0 +1,377 @@ +# Copyright 2024-2026 Firefly Software Foundation +# SPDX-License-Identifier: Apache-2.0 +"""Native value reads use synthetic owned Parquet, never models or a database.""" + +from __future__ import annotations + +import uuid +from types import SimpleNamespace + +import pyarrow as pa +import pyarrow.parquet as pq +import pytest + +from flyquery.core.services.execution.ast_classifier import AstClassifier +from flyquery.core.services.execution.duckdb_executor import DuckDBExecutor, ExecutionError +from flyquery.core.services.query.query_service import QueryService + + +class _Settings: + duckdb_memory_limit = "256MB" + default_row_cap = 3 + entity_resolution_max_literals = 8 + group_coverage_repair_enabled = False + signed_measure_repair_enabled = True + entity_resolution_enabled = True + group_resolution_enabled = True + + +class _Executor(DuckDBExecutor): + def __init__(self, *, deny=False): + super().__init__(_Settings()) + self.calls = [] + self.deny = deny + + async def execute(self, sql, attached_tables, derived_tables=None): + self.calls.append((sql, dict(attached_tables))) + if self.deny: + return ExecutionError("synthetic executor denial") + return await super().execute(sql, attached_tables, derived_tables) + + +class _Resolver: + def __init__(self, snapshots, current="old"): + self.snapshots = snapshots + self.current = current + self.captures = [] + self.resolutions = [] + + async def current_snapshots(self, dataset_id, table_names): + self.captures.append(list(table_names)) + return dict.fromkeys(table_names, self.current) + + async def resolve(self, dataset_id, table_names, pins=None): + self.resolutions.append(dict(pins or {})) + return {name: str(self.snapshots[(pins or {}).get(name, self.current)]) for name in table_names} + + +def _write(path, rows): + pq.write_table(pa.Table.from_pylist(rows), path) + return path + + +def _service(resolver, executor=None): + service = object.__new__(QueryService) + service._table_resolver = resolver + service._executor = executor or _Executor() + service._settings = _Settings() + return service + + +def _bundle(catalog, *, table="orders", pins=None): + return { + "schema_inventory": [SimpleNamespace(metadata={"kind": "TABLE", "qualified_name": table})], + "column_catalog": catalog, + "snapshot_pins": dict(pins or {}), + } + + +def _column(name, **metadata): + return {"qualified_name": name, "data_type": "VARCHAR", **metadata} + + +@pytest.mark.asyncio +@pytest.mark.parametrize( + "metadata", + [{"value_access": False}, {}, {"value_access": True, "sample_values_json": []}], + ids=["redacted", "missing-authorization", "redaction-marker"], +) +async def test_live_scan_excludes_columns_without_affirmative_value_access(tmp_path, metadata): + path = _write(tmp_path / "owned.parquet", [{"name": "Synthetic Restricted Value"}]) + resolver = _Resolver({"old": path}) + service = _service(resolver) + bundle = _bundle([_column("orders.name", **metadata)]) + + found = await service._scan_columns_for_values(uuid.uuid4(), ["Synthetic Restricted Value"], bundle) + + assert found == [] + assert service._executor.calls == [] + assert resolver.resolutions == [] + + +@pytest.mark.asyncio +async def test_live_scan_reads_only_catalog_authorized_columns(tmp_path): + path = _write( + tmp_path / "owned.parquet", + [ + { + "public_name": "Synthetic Value", + "redacted": "Synthetic Value", + "unregistered": "Synthetic Value", + } + ], + ) + service = _service(_Resolver({"old": path})) + bundle = _bundle( + [_column("orders.public_name", value_access=True), _column("orders.redacted", value_access=False)] + ) + + found = await service._scan_columns_for_values(uuid.uuid4(), ["Synthetic Value"], bundle) + + assert [entry["column"] for entry in found] == ["orders.public_name"] + assert service._executor.calls + assert all("redacted" not in sql and "unregistered" not in sql for sql, _ in service._executor.calls) + + +@pytest.mark.asyncio +async def test_live_scan_uses_executor_denial_without_unfenced_fallback(tmp_path): + path = _write(tmp_path / "owned.parquet", [{"name": "Synthetic Value"}]) + service = _service(_Resolver({"old": path}), _Executor(deny=True)) + + found = await service._scan_columns_for_values( + uuid.uuid4(), ["Synthetic Value"], _bundle([_column("orders.name", value_access=True)]) + ) + + assert found == [] + assert len(service._executor.calls) == 1 + + +@pytest.mark.asyncio +async def test_live_scan_handles_real_quoted_registered_paths_and_identifiers(tmp_path): + path = _write(tmp_path / "owned'quoted.parquet", [{'name"column': "Synthetic Value"}]) + service = _service(_Resolver({"old": path})) + table = 'orders"table' + + found = await service._scan_columns_for_values( + uuid.uuid4(), + ["Synthetic Value"], + _bundle([_column(f'{table}.name"column', value_access=True)], table=table), + ) + + assert [entry["column"] for entry in found] == [f'{table}.name"column'] + assert service._executor.calls[0][1] == {table: str(path)} + + +@pytest.mark.asyncio +async def test_live_scan_cannot_expand_registered_glob_to_unregistered_files(tmp_path): + _write(tmp_path / "allowed.parquet", [{"name": "Synthetic Allowed"}]) + _write(tmp_path / "unregistered.parquet", [{"name": "Synthetic Outside"}]) + service = _service(_Resolver({"old": tmp_path / "*.parquet"})) + + found = await service._scan_columns_for_values( + uuid.uuid4(), ["Synthetic Outside"], _bundle([_column("orders.name", value_access=True)]) + ) + + assert found == [] + assert service._executor.calls + + +@pytest.mark.asyncio +async def test_live_scan_cannot_interpret_registered_path_as_a_sql_join(tmp_path): + allowed = _write(tmp_path / "allowed.parquet", [{"public_name": "Synthetic Allowed"}]) + outside = _write(tmp_path / "unregistered.parquet", [{"secret_label": "Synthetic Outside"}]) + hostile = f"{allowed}') CROSS JOIN read_parquet('{outside}" + service = _service(_Resolver({"old": hostile})) + + found = await service._scan_columns_for_values( + uuid.uuid4(), ["Synthetic Outside"], _bundle([_column("orders.secret_label", value_access=True)]) + ) + + assert found == [] + assert service._executor.calls + + +@pytest.mark.asyncio +async def test_conflicting_value_metadata_cannot_restore_a_blocked_column(tmp_path): + path = _write(tmp_path / "owned.parquet", [{"name": "Synthetic Restricted"}]) + service = _service(_Resolver({"old": path})) + bundle = _bundle( + [ + _column("orders.name", value_access=False), + _column("orders.name", value_access=True), + ] + ) + + assert await service._scan_columns_for_values(uuid.uuid4(), ["Synthetic Restricted"], bundle) == [] + assert service._executor.calls == [] + + +@pytest.mark.asyncio +async def test_entity_catalog_does_not_override_denied_value_access(tmp_path): + path = _write(tmp_path / "owned.parquet", [{"name": "Synthetic Restricted"}]) + service = _service(_Resolver({"old": path})) + catalog = [_column("orders.name", value_access=False, values=["Synthetic Restricted"])] + + resolution = await service._resolve_entities( + uuid.uuid4(), "Find 'Synthetic Restricted'", catalog, _bundle(catalog) + ) + + assert resolution["entities"] == [] + assert resolution["groups"] == [] + assert service._executor.calls == [] + + +@pytest.mark.asyncio +async def test_live_scan_reuses_captured_snapshot_after_reingestion(tmp_path): + old = _write(tmp_path / "old.parquet", [{"name": "Synthetic Original"}]) + new = _write(tmp_path / "new.parquet", [{"name": "Synthetic Replacement"}]) + resolver = _Resolver({"old": old, "new": new}) + service = _service(resolver) + bundle = _bundle([_column("orders.name", value_access=True)]) + dataset_id = uuid.uuid4() + + first = await service._scan_columns_for_values(dataset_id, ["Synthetic Original"], bundle) + resolver.current = "new" + second = await service._scan_columns_for_values( + dataset_id, ["Synthetic Original", "Synthetic Replacement"], bundle + ) + + assert first == second + assert first[0]["value"] == "Synthetic Original" + assert bundle["snapshot_pins"] == {"orders": "old"} + assert len(resolver.captures) == 1 + assert resolver.resolutions == [{"orders": "old"}, {"orders": "old"}] + + +_SIGNED_SQL = ( + "SELECT SUM(CASE WHEN line = 'Revenue' THEN amount ELSE 0 END) " + "- SUM(CASE WHEN line = 'Cost' THEN amount ELSE 0 END) FROM orders" +) + + +def _signed_catalog(*, measure_access=True, dimension_access=True): + return [ + _column("orders.line", value_access=dimension_access), + _column( + "orders.amount", + data_type="DOUBLE", + semantic_type="amount", + mixed_sign=True, + value_access=measure_access, + ), + ] + + +@pytest.mark.asyncio +@pytest.mark.parametrize("blocked", ["measure", "dimension"]) +async def test_signed_probe_requires_both_columns_to_allow_values(tmp_path, blocked): + path = _write(tmp_path / "owned.parquet", [{"line": "Cost", "amount": -7.0}]) + catalog = _signed_catalog(measure_access=blocked != "measure", dimension_access=blocked != "dimension") + service = _service(_Resolver({"old": path})) + + hint = await service._advisory_repair( + _SIGNED_SQL, + AstClassifier().classify(_SIGNED_SQL), + catalog, + "Synthetic question", + uuid.uuid4(), + _bundle(catalog), + ) + + assert hint is None + assert service._executor.calls == [] + + +@pytest.mark.asyncio +async def test_signed_probe_uses_the_same_pinned_registered_snapshot(tmp_path): + old = _write(tmp_path / "old'quoted.parquet", [{"line": "Cost", "amount": -7.0}]) + new = _write(tmp_path / "new.parquet", [{"line": "Cost", "amount": 7.0}]) + resolver = _Resolver({"old": old, "new": new}, current="new") + service = _service(resolver) + catalog = _signed_catalog() + bundle = _bundle(catalog, pins={"orders": "old"}) + + hint = await service._advisory_repair( + _SIGNED_SQL, + AstClassifier().classify(_SIGNED_SQL), + catalog, + "Synthetic question", + uuid.uuid4(), + bundle, + ) + + assert hint and "SIGN ERROR" in hint + assert resolver.captures == [] + assert resolver.resolutions == [{"orders": "old"}] + assert service._executor.calls + assert all(attached == {"orders": str(old)} for _, attached in service._executor.calls) + + +@pytest.mark.asyncio +@pytest.mark.parametrize("metadata", [{}, {"value_access": True, "sample_values_json": []}]) +async def test_signed_probe_does_not_infer_missing_or_redacted_access(tmp_path, metadata): + path = _write(tmp_path / "owned.parquet", [{"line": "Cost", "amount": -7.0}]) + catalog = _signed_catalog() + catalog[0].pop("value_access") + catalog[0].update(metadata) + service = _service(_Resolver({"old": path})) + + hint = await service._advisory_repair( + _SIGNED_SQL, + AstClassifier().classify(_SIGNED_SQL), + catalog, + "Synthetic question", + uuid.uuid4(), + _bundle(catalog), + ) + + assert hint is None + assert service._executor.calls == [] + + +@pytest.mark.asyncio +async def test_signed_probe_cannot_interpret_registered_path_as_a_sql_join(tmp_path): + allowed = _write(tmp_path / "allowed.parquet", [{"line": "Cost"}]) + outside = _write(tmp_path / "unregistered.parquet", [{"amount": -7.0}]) + hostile = f"{allowed}') CROSS JOIN read_parquet('{outside}" + service = _service(_Resolver({"old": hostile})) + catalog = _signed_catalog() + + hint = await service._advisory_repair( + _SIGNED_SQL, + AstClassifier().classify(_SIGNED_SQL), + catalog, + "Synthetic question", + uuid.uuid4(), + _bundle(catalog), + ) + + assert hint is None + assert service._executor.calls + + +@pytest.mark.asyncio +async def test_signed_probe_honors_executor_denial_without_fallback(tmp_path): + path = _write(tmp_path / "owned.parquet", [{"line": "Cost", "amount": -7.0}]) + service = _service(_Resolver({"old": path}), _Executor(deny=True)) + catalog = _signed_catalog() + + hint = await service._advisory_repair( + _SIGNED_SQL, + AstClassifier().classify(_SIGNED_SQL), + catalog, + "Synthetic question", + uuid.uuid4(), + _bundle(catalog), + ) + + assert hint is None + assert len(service._executor.calls) == 1 + + +@pytest.mark.asyncio +async def test_signed_probe_never_reports_a_sum_from_a_truncated_literal_set(tmp_path): + labels = [f"Synthetic Cost {i}" for i in range(26)] + rows = [{"line": label, "amount": -1.0 if i < 25 else 30.0} for i, label in enumerate(labels)] + path = _write(tmp_path / "owned.parquet", rows) + service = _service(_Resolver({"old": path})) + catalog = _signed_catalog() + quoted = ", ".join(f"'{label}'" for label in labels) + sql = _SIGNED_SQL.replace("line = 'Cost'", f"line IN ({quoted})") + + hint = await service._advisory_repair( + sql, AstClassifier().classify(sql), catalog, "Synthetic question", uuid.uuid4(), _bundle(catalog) + ) + + assert hint is None + assert service._executor.calls == [] From 1090110543d46d208a8ae3835aff8195a419c065 Mon Sep 17 00:00:00 2001 From: Andres Contreras Date: Wed, 14 Oct 2026 12:05:22 -0700 Subject: [PATCH 10/20] Require read capability before query retrieval --- .../core/services/query/query_service.py | 6 +-- tests/unit/test_query_admission_review.py | 44 +++++++++++++++++++ 2 files changed, 47 insertions(+), 3 deletions(-) create mode 100644 tests/unit/test_query_admission_review.py diff --git a/src/flyquery/core/services/query/query_service.py b/src/flyquery/core/services/query/query_service.py index 1e56652c..2626832d 100644 --- a/src/flyquery/core/services/query/query_service.py +++ b/src/flyquery/core/services/query/query_service.py @@ -626,9 +626,9 @@ async def answer( """ start_ms = time.monotonic_ns() // 1_000_000 - if not scopes.intersection( - {"flyquery.query:read", "flyquery.sql:execute", "flyquery.derived:write", "*"} - ) or (dataset_allowlist is not None and str(dataset_id) not in dataset_allowlist): + if not scopes.intersection({"flyquery.query:read", "flyquery.sql:execute", "*"}) or ( + dataset_allowlist is not None and str(dataset_id) not in dataset_allowlist + ): elapsed = (time.monotonic_ns() // 1_000_000) - start_ms # Retain caller-supplied denial evidence without attaching the # record to an unauthorized dataset or invoking retrieval/models. diff --git a/tests/unit/test_query_admission_review.py b/tests/unit/test_query_admission_review.py new file mode 100644 index 00000000..f4b1c5e7 --- /dev/null +++ b/tests/unit/test_query_admission_review.py @@ -0,0 +1,44 @@ +# Copyright 2024-2026 Firefly Software Foundation +# SPDX-License-Identifier: Apache-2.0 +"""Independent service admission checks use no model or repository I/O.""" + +import uuid +from types import SimpleNamespace + +import pytest + +from flyquery.core.services.query.query_service import QueryService + + +@pytest.mark.asyncio +async def test_write_only_scope_cannot_reach_read_retrieval(): + calls = [] + + class Audit: + async def create_query(self, **kwargs): + calls.append("audit") + assert kwargs["dataset_id"] is None + assert kwargs["executed_sql"] is None + return uuid.uuid4() + + class Retrieval: + async def retrieve(self, *args, **kwargs): + calls.append("retrieval") + raise AssertionError("Write-only admission reached read retrieval") + + service = object.__new__(QueryService) + service._query_repo = Audit() + service._retriever = Retrieval() + service._settings = SimpleNamespace(top_k_schema=2, top_k_examples=2, top_k_metrics=2) + + result = await service.answer( + tenant_id="synthetic-review", + workspace_id=uuid.uuid4(), + dataset_id=uuid.uuid4(), + question="Synthetic write-only request", + scopes={"flyquery.derived:write"}, + ) + + assert result.execution_status == "REJECTED_BY_FIREWALL" + assert result.sql is None + assert calls == ["audit"] From c4d08621eb9117a37756c3c9addd6ff6ef165ad8 Mon Sep 17 00:00:00 2001 From: Andres Contreras Date: Wed, 14 Oct 2026 11:51:26 -0700 Subject: [PATCH 11/20] Preserve sampling privacy decisions before filtering evidence --- docs/pii.md | 32 ++-- .../core/services/ingestion/stages/sample.py | 36 +++- .../test_sample_privacy_pipeline.py | 168 ++++++++++++++++++ tests/unit/test_sample_policy_persistence.py | 132 ++++++++++++++ 4 files changed, 349 insertions(+), 19 deletions(-) create mode 100644 tests/integration/test_sample_privacy_pipeline.py create mode 100644 tests/unit/test_sample_policy_persistence.py diff --git a/docs/pii.md b/docs/pii.md index 4166f01e..82e57515 100644 --- a/docs/pii.md +++ b/docs/pii.md @@ -22,9 +22,10 @@ columns are queryable and whether sample values are retained. PII scanning runs in two places: -1. **Stage 4 (sample)** — before samples are persisted, a scanner tests - candidate values. A column that triggers a match never has its sample - values written to `schema_objects.sample_values_json`. +1. **Stage 4 (sample)** — the configured scanner checks the original value + batch before filtering it. Redact/reject applies to the column immediately; + the stored empty list prevents later profiles from supplying its values. + Warn mode keeps only clean samples. A disabled scanner is an explicit opt-out. 2. **Stage 8 (PII tag)** — the `PIIScanner` port classifies each column from `(column_name + description + sample_values)` and sets `pii_tag + pii_source` on the `flyquery_schema_objects` row. @@ -89,9 +90,9 @@ development with synthetic data. | Policy | What happens on PII match | |--------|--------------------------| -| `warn` | Log the finding; continue. Sample values are persisted. `pii_findings_json` populated on the ingest job. | -| `redact` (recommended) | Purge `sample_values_json` in the same transaction. Log the finding. Column remains queryable. | -| `reject` | Set `schema_objects.is_active=false` on the column. Column is not queryable until a human reviews and clears the flag. | +| `warn` | Tag the column and continue. Sampling still drops individual PII values. Profiles may expose values when clean samples remain; this policy does not promise redaction. | +| `redact` (recommended) | Tag the column and store `sample_values_json=[]`. Embedding inputs, schema retrieval metadata, and value catalogs cannot recover values from its profile. The column remains queryable. | +| `reject` | Tag the column, store the empty sample list, and set `is_active=false`. Embedding and retrieval exclude the column until it is reviewed. | `FLYQUERY_PII_POLICY_RESULTS` controls what happens when PII is detected in query result rows (post-execution scan by the Explainer): @@ -120,16 +121,19 @@ The PII gate runs BEFORE sample persistence on first ingest: ``` Stage 4 (sample): For each column value batch: - 1. Run PIIScanner on the values - 2. IF match AND policy=redact → discard; do NOT write to sample_values_json - 3. IF match AND policy=reject → mark column is_active=false; skip sample - 4. IF match AND policy=warn → log finding; write sample anyway - 5. IF no match → write to sample_values_json + 1. Classify the original values, name, and description + 2. IF match AND policy=redact → tag; persist [] + 3. IF match AND policy=reject → tag; deactivate column; persist [] + 4. IF match AND policy=warn → tag; persist only individually clean values + 5. IF no match → persist clean values + 6. IF all values were filtered or the column was already tagged → persist [] ``` -This ordering ensures that PII values never touch the database, even -transiently. The scanner runs in memory; values that fail the gate are -discarded without being committed. +Filtering a batch must not erase its classification. Otherwise, a generic +column name could pass the later tag stage while raw profile values reached +the agents. The empty list is an explicit denial; a missing sample list may +still use ordinary profile values. Original Parquet files remain unchanged, +and this sampling policy does not remove source data or stored profiles. --- diff --git a/src/flyquery/core/services/ingestion/stages/sample.py b/src/flyquery/core/services/ingestion/stages/sample.py index 19be7a9c..36a9fe0e 100644 --- a/src/flyquery/core/services/ingestion/stages/sample.py +++ b/src/flyquery/core/services/ingestion/stages/sample.py @@ -1,4 +1,5 @@ # Copyright 2024-2026 Firefly Software Foundation +# SPDX-License-Identifier: Apache-2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -17,12 +18,12 @@ For each new/changed column in the snapshot: 1. Skip if pii_tag is already set (and != 'NONE') — column is known PII. 2. Read N values from the Parquet snapshot (DuckDB). -3. Pass each value through PiiScanner.scan_single() — refuse to persist if PII. -4. Persist clean samples to flyquery_schema_objects.sample_values_json. +3. Apply the column policy to the original values before filtering evidence. +4. Persist clean samples, or an explicit empty list that denies profile fallback. CRITICAL ordering guarantee (per spec): PII inline gate runs BEFORE persisting -any sample. A value that triggers scan_single is silently dropped; if ALL -values are PII-tainted, no sample is persisted for that column. +any sample. Warn mode still drops individual PII samples; disabling the scanner +explicitly opts out. Redact/reject never retain samples from a flagged column. """ from __future__ import annotations @@ -36,6 +37,7 @@ import sqlalchemy as sa from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker +from flyquery.core.services.ingestion.stages.pii_tag import _apply_tag_and_policy from flyquery.core.services.pii.factory import build_pii_scanner logger = logging.getLogger(__name__) @@ -68,6 +70,7 @@ async def run_sample( # Skip columns already known to carry PII if pii_tag is not None and pii_tag != "NONE": + await _persist_samples(col_id, [], tenant_id, session_factory) logger.debug( "stage=sample skip col=%s reason=pii_flagged tag=%s", col_name, @@ -81,6 +84,28 @@ async def run_sample( if not raw_values: continue + # Filtering first would erase the evidence used by the later PII stage, + # allowing raw profile values to bypass redact/reject on generic names. + tag = await scanner.scan_column( + name=col_name, + description=col["description"], + samples=[str(v) for v in raw_values], + data_type=col["data_type"] or "", + ) + if tag is not None: + policy = settings.pii_policy_samples + await _apply_tag_and_policy( + col_id=col_id, + tag_name=tag.tag, + source=tag.source, + policy=policy, + tenant_id=tenant_id, + session_factory=session_factory, + ) + if policy in {"redact", "reject"}: + await _persist_samples(col_id, [], tenant_id, session_factory) + continue + # PII inline gate: keep only clean values clean_samples: list[str] = [] for v in raw_values: @@ -94,6 +119,7 @@ async def run_sample( col_name, len(raw_values), ) + await _persist_samples(col_id, [], tenant_id, session_factory) continue await _persist_samples(col_id, clean_samples, tenant_id, session_factory) @@ -154,7 +180,7 @@ async def _load_columns( result = await s.execute( sa.text( """ - SELECT id, qualified_name, pii_tag + SELECT id, qualified_name, pii_tag, description, data_type FROM flyquery_schema_objects WHERE snapshot_id = :sid AND tenant_id = :tenant diff --git a/tests/integration/test_sample_privacy_pipeline.py b/tests/integration/test_sample_privacy_pipeline.py new file mode 100644 index 00000000..70e06e0b --- /dev/null +++ b/tests/integration/test_sample_privacy_pipeline.py @@ -0,0 +1,168 @@ +# Copyright 2026 Firefly Software Foundation +# SPDX-License-Identifier: Apache-2.0 +"""Native Parquet-to-PostgreSQL privacy decisions through retrieval.""" + +import hashlib +import json +import os +import uuid +from types import SimpleNamespace + +import duckdb +import pytest +from sqlalchemy import text +from sqlalchemy.ext.asyncio import async_sessionmaker, create_async_engine + +from flyquery.core.services.ingestion.stages.embed import run_embed +from flyquery.core.services.ingestion.stages.pii_tag import run_pii_tag +from flyquery.core.services.ingestion.stages.profile import run_profile +from flyquery.core.services.ingestion.stages.sample import run_sample +from flyquery.core.services.retrieval.search_index import SearchIndex +from flyquery.models.entities import Base, Dataset, SchemaObject, SchemaSnapshot, Table, Workspace + + +class _CaptureEmbedder: + model = "privacy-fixture-no-provider" + dimensions = 1536 + + def __init__(self): + self.inputs = [] + + async def embed_batch(self, inputs): + self.inputs.extend(inputs) + return [None] * len(inputs) + + +@pytest.mark.integration +@pytest.mark.parametrize( + "policy,scanner,values", + [ + ("redact", "regex", ["fixture@example.test"]), + ("reject", "regex", ["fixture@example.test"]), + ("redact", "regex", ["ordinary", "fixture@example.test"]), + ("reject", "regex", ["ordinary", "fixture@example.test"]), + ("warn", "regex", ["fixture@example.test"]), + ("warn", "regex", ["ordinary", "fixture@example.test"]), + ("redact", "disabled", ["fixture@example.test"]), + ("redact", "regex", ["alpha", "beta"]), + ], +) +async def test_original_pii_decision_survives_profile_and_retrieval(tmp_path, policy, scanner, values): + path = tmp_path / "original.parquet" + with duckdb.connect() as connection: + connection.execute("CREATE TABLE fixture(note VARCHAR)") + connection.executemany("INSERT INTO fixture VALUES (?)", [(value,) for value in values]) + connection.execute("COPY fixture TO ? (FORMAT PARQUET)", [str(path)]) + original = hashlib.sha256(path.read_bytes()).hexdigest() + schema = "privacy_" + uuid.uuid4().hex + url = os.environ["FLYQUERY_DATABASE_URL_ADMIN"].replace("+psycopg", "+asyncpg") + engine = create_async_engine(url, connect_args={"server_settings": {"search_path": schema + ",public"}}) + sessions = async_sessionmaker(engine, expire_on_commit=False) + tenant = "privacy-" + uuid.uuid4().hex + workspace, dataset, table, snapshot, column = [uuid.uuid4() for _ in range(5)] + try: + async with engine.begin() as connection: + await connection.execute(text(f'CREATE SCHEMA "{schema}"')) + await connection.run_sync(Base.metadata.create_all) + async with sessions() as session, session.begin(): + session.add(Workspace(id=workspace, tenant_id=tenant, slug="privacy", name="Privacy")) + await session.flush() + session.add(Dataset(id=dataset, tenant_id=tenant, workspace_id=workspace, name="Synthetic")) + await session.flush() + session.add( + Table( + id=table, + tenant_id=tenant, + workspace_id=workspace, + dataset_id=dataset, + name="records", + qualified_name="records", + current_snapshot_id=snapshot, + ) + ) + await session.flush() + session.add( + SchemaSnapshot( + id=snapshot, + tenant_id=tenant, + workspace_id=workspace, + dataset_id=dataset, + table_id=table, + snapshot_hash=original, + n_columns=1, + n_rows_actual=len(values), + status="READY", + triggered_by="USER", + created_by="privacy-fixture", + ) + ) + session.add( + SchemaObject( + id=column, + tenant_id=tenant, + workspace_id=workspace, + table_id=table, + snapshot_id=snapshot, + kind="COLUMN", + qualified_name="records.note", + data_type="VARCHAR", + description="Synthetic text", + is_active=True, + source_hash="privacy-fixture", + ) + ) + settings = SimpleNamespace( + pii_scanner=scanner, pii_policy_samples=policy, sample_n=10, profile_row_threshold=1000 + ) + arguments = { + "tenant_id": tenant, + "snapshot_id": snapshot, + "session_factory": sessions, + "settings": settings, + } + await run_sample(**arguments, parquet_key=str(path)) + await run_profile(**arguments, parquet_key=str(path), n_rows_actual=len(values)) + await run_pii_tag(**arguments) + embedder = _CaptureEmbedder() + await run_embed(tenant_id=tenant, snapshot_id=snapshot, session_factory=sessions, embedder=embedder) + async with sessions() as session: + index = SearchIndex(session) + hits = await index.all_schema_objects(dataset) + bm25 = await index.bm25_schema_objects("Synthetic", dataset) + catalog = await index.column_value_catalog(dataset) + rendered = json.dumps( + { + "inputs": embedder.inputs, + "hits": [hit.__dict__ for hit in hits + bm25], + "catalog": catalog, + }, + default=str, + ) + stored = await session.get(SchemaObject, column) + tainted = "fixture@example.test" in values + if scanner == "regex" and tainted and policy in {"redact", "reject"}: + assert "fixture@example.test" not in rendered + assert stored.sample_values_json == [] + assert stored.pii_tag == "EMAIL" + if policy == "reject": + assert stored.is_active is False + assert not hits and not catalog and not embedder.inputs + elif scanner == "disabled": + assert stored.sample_values_json == values + assert stored.pii_tag is None + assert "fixture@example.test" in rendered + elif policy == "warn": + assert stored.pii_tag == "EMAIL" + assert stored.is_active + assert stored.sample_values_json == [v for v in values if "@" not in v] + if "ordinary" in values: + assert "fixture@example.test" in rendered + else: + assert stored.sample_values_json == values + assert stored.pii_tag is None + assert all(value in rendered for value in values) + assert hashlib.sha256(path.read_bytes()).hexdigest() == original + finally: + async with engine.begin() as connection: + await connection.execute(text(f'DROP SCHEMA IF EXISTS "{schema}" CASCADE')) + await engine.dispose() diff --git a/tests/unit/test_sample_policy_persistence.py b/tests/unit/test_sample_policy_persistence.py new file mode 100644 index 00000000..87d68613 --- /dev/null +++ b/tests/unit/test_sample_policy_persistence.py @@ -0,0 +1,132 @@ +# Copyright 2026 Firefly Software Foundation +# SPDX-License-Identifier: Apache-2.0 +"""Sampling must preserve a privacy decision before dropping its evidence.""" + +import uuid +from types import SimpleNamespace +from unittest.mock import AsyncMock, Mock + +import pytest + +from flyquery.core.services.ingestion.stages import sample + + +@pytest.mark.parametrize("policy", ["redact", "reject"]) +@pytest.mark.parametrize("values", [["fixture@example.test"], ["ordinary", "fixture@example.test"]]) +async def test_original_pii_finding_applies_policy_before_sample_persistence(monkeypatch, policy, values): + column_id = uuid.uuid4() + monkeypatch.setattr( + sample, + "_load_columns", + AsyncMock( + return_value=[ + { + "id": column_id, + "qualified_name": "records.note", + "pii_tag": None, + "description": "Synthetic text", + "data_type": "VARCHAR", + } + ] + ), + ) + monkeypatch.setattr(sample, "_read_parquet_column", Mock(return_value=values)) + events = [] + + async def apply(**kwargs): + events.append(("policy", kwargs)) + + async def persist(*args): + events.append(("persist", args)) + + monkeypatch.setattr(sample, "_apply_tag_and_policy", apply, raising=False) + monkeypatch.setattr(sample, "_persist_samples", persist) + await sample.run_sample( + tenant_id="native", + snapshot_id=uuid.uuid4(), + parquet_key="owned.parquet", + session_factory=Mock(), + settings=SimpleNamespace(pii_scanner="regex", pii_policy_samples=policy, sample_n=10), + ) + assert [event[0] for event in events] == ["policy", "persist"] + assert events[0][1]["tag_name"] == "EMAIL" + assert events[0][1]["source"] == "REGEX" + assert events[0][1]["policy"] == policy + assert events[1][1][1] == [] + + +@pytest.mark.parametrize( + "policy,scanner,values,expected", + [ + ("redact", "regex", ["alpha", "beta"], ["alpha", "beta"]), + ("redact", "disabled", ["fixture@example.test"], ["fixture@example.test"]), + ("warn", "regex", ["ordinary", "fixture@example.test"], ["ordinary"]), + ("warn", "regex", ["fixture@example.test"], []), + ], +) +async def test_sampling_retains_clean_values_and_explicit_opt_out( + monkeypatch, policy, scanner, values, expected +): + monkeypatch.setattr( + sample, + "_load_columns", + AsyncMock( + return_value=[ + { + "id": uuid.uuid4(), + "qualified_name": "records.note", + "pii_tag": None, + "description": "Synthetic text", + "data_type": "VARCHAR", + } + ] + ), + ) + monkeypatch.setattr(sample, "_read_parquet_column", Mock(return_value=values)) + persist = AsyncMock() + apply = AsyncMock() + monkeypatch.setattr(sample, "_persist_samples", persist) + monkeypatch.setattr(sample, "_apply_tag_and_policy", apply, raising=False) + await sample.run_sample( + tenant_id="native", + snapshot_id=uuid.uuid4(), + parquet_key="owned.parquet", + session_factory=Mock(), + settings=SimpleNamespace(pii_scanner=scanner, pii_policy_samples=policy, sample_n=10), + ) + assert persist.await_args.args[1] == expected + if policy == "warn": + assert apply.await_args.kwargs["policy"] == "warn" + else: + apply.assert_not_awaited() + + +async def test_previously_tagged_column_denies_profile_fallback_without_reading_file(monkeypatch): + monkeypatch.setattr( + sample, + "_load_columns", + AsyncMock( + return_value=[ + { + "id": uuid.uuid4(), + "qualified_name": "records.note", + "pii_tag": "EMAIL", + "description": "Synthetic text", + "data_type": "VARCHAR", + } + ] + ), + ) + read = Mock(side_effect=AssertionError("A known PII column must not be sampled")) + persist = AsyncMock() + monkeypatch.setattr(sample, "_read_parquet_column", read) + monkeypatch.setattr(sample, "_persist_samples", persist) + await sample.run_sample( + tenant_id="native", + snapshot_id=uuid.uuid4(), + parquet_key="owned.parquet", + session_factory=Mock(), + settings=SimpleNamespace(pii_scanner="regex", pii_policy_samples="redact", sample_n=10), + ) + read.assert_not_called() + assert persist.await_args.args[1] == [] From fa2e09f05cf6f26e01f9ca6f3f2dd87adbe89fbd Mon Sep 17 00:00:00 2001 From: Andres Contreras Date: Wed, 14 Oct 2026 12:00:50 -0700 Subject: [PATCH 12/20] Classify profiled values beyond the sampling prefix --- docs/pii.md | 10 ++-- .../core/services/ingestion/stages/pii_tag.py | 15 ++++-- .../test_sample_privacy_pipeline.py | 14 +++-- tests/unit/test_pii_profile_gate.py | 52 +++++++++++++++++++ 4 files changed, 78 insertions(+), 13 deletions(-) create mode 100644 tests/unit/test_pii_profile_gate.py diff --git a/docs/pii.md b/docs/pii.md index 82e57515..878df0c5 100644 --- a/docs/pii.md +++ b/docs/pii.md @@ -26,9 +26,10 @@ PII scanning runs in two places: batch before filtering it. Redact/reject applies to the column immediately; the stored empty list prevents later profiles from supplying its values. Warn mode keeps only clean samples. A disabled scanner is an explicit opt-out. -2. **Stage 8 (PII tag)** — the `PIIScanner` port classifies each column - from `(column_name + description + sample_values)` and sets `pii_tag + - pii_source` on the `flyquery_schema_objects` row. +2. **Stage 8 (PII tag)** — the configured scanner classifies each column + using its name, description, samples, and up to 100 stored profile values. + It sets `pii_tag` and `pii_source` before embedding and retrieval. A value + after the sampled prefix can therefore still trigger redact/reject. The scanner and policy are both configurable — globally via environment variables or per-dataset via `ingest_policy_json`. @@ -134,6 +135,9 @@ column name could pass the later tag stage while raw profile values reached the agents. The empty list is an explicit denial; a missing sample list may still use ordinary profile values. Original Parquet files remain unchanged, and this sampling policy does not remove source data or stored profiles. +Detection is limited to the values sampled or retained by the profiler and +the selected scanner's patterns. Values outside that coverage can be missed; +this is not a guarantee that arbitrary source data contains no PII. --- diff --git a/src/flyquery/core/services/ingestion/stages/pii_tag.py b/src/flyquery/core/services/ingestion/stages/pii_tag.py index 6bae8b7a..2d5f9ff3 100644 --- a/src/flyquery/core/services/ingestion/stages/pii_tag.py +++ b/src/flyquery/core/services/ingestion/stages/pii_tag.py @@ -1,4 +1,5 @@ # Copyright 2024-2026 Firefly Software Foundation +# SPDX-License-Identifier: Apache-2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,7 +16,7 @@ """Stage 8 — PII tag. For each active COLUMN in the snapshot: - 1. Build (name, description, samples, data_type) from DB. + 1. Build (name, description, samples, profile values, data_type) from DB. 2. Call PiiScanner.scan_column(). 3. If a PiiTag is returned, update pii_tag + pii_source and apply policy: warn — log + keep samples as-is @@ -35,6 +36,7 @@ from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker from flyquery.core.services.pii.factory import build_pii_scanner +from flyquery.core.services.query.value_anchoring import coerce_profile logger = logging.getLogger(__name__) @@ -57,13 +59,16 @@ async def run_pii_tag( col_id: uuid.UUID = col["id"] col_name: str = col["qualified_name"].rsplit(".", 1)[-1] samples: list[str] = col["sample_values_json"] or [] + # The profile covers values beyond the sampled prefix. Classification + # must inspect them before any retrieval or embedding can expose them. + profile_values = coerce_profile(col.get("profile_json"), None, max_values=100)["values"] description: str | None = col["description"] data_type: str = col["data_type"] or "" tag = await scanner.scan_column( name=col_name, description=description, - samples=samples, + samples=samples + profile_values, data_type=data_type, ) @@ -111,7 +116,7 @@ async def _load_columns( sa.text( """ SELECT id, qualified_name, data_type, description, - sample_values_json + sample_values_json, profile_json FROM flyquery_schema_objects WHERE snapshot_id = :sid AND tenant_id = :tenant @@ -165,14 +170,14 @@ async def _apply_tag_and_policy( ) elif policy == "reject": - # Tag + deactivate column (human must review) + # Tag + revoke value access + deactivate column (human must review) async with session_factory() as s, s.begin(): await s.execute( sa.text( """ UPDATE flyquery_schema_objects SET pii_tag = :tag, pii_source = :source, - is_active = false + sample_values_json = '[]'::jsonb, is_active = false WHERE id = :id AND tenant_id = :tenant """ ), diff --git a/tests/integration/test_sample_privacy_pipeline.py b/tests/integration/test_sample_privacy_pipeline.py index 70e06e0b..94ab0489 100644 --- a/tests/integration/test_sample_privacy_pipeline.py +++ b/tests/integration/test_sample_privacy_pipeline.py @@ -45,6 +45,10 @@ async def embed_batch(self, inputs): ("warn", "regex", ["ordinary", "fixture@example.test"]), ("redact", "disabled", ["fixture@example.test"]), ("redact", "regex", ["alpha", "beta"]), + ("redact", "regex", [f"ordinary-{i}" for i in range(8)] + ["fixture@example.test"]), + ("reject", "regex", [f"ordinary-{i}" for i in range(8)] + ["fixture@example.test"]), + ("warn", "regex", [f"ordinary-{i}" for i in range(8)] + ["fixture@example.test"]), + ("redact", "disabled", [f"ordinary-{i}" for i in range(8)] + ["fixture@example.test"]), ], ) async def test_original_pii_decision_survives_profile_and_retrieval(tmp_path, policy, scanner, values): @@ -112,7 +116,7 @@ async def test_original_pii_decision_survives_profile_and_retrieval(tmp_path, po ) ) settings = SimpleNamespace( - pii_scanner=scanner, pii_policy_samples=policy, sample_n=10, profile_row_threshold=1000 + pii_scanner=scanner, pii_policy_samples=policy, sample_n=8, profile_row_threshold=1000 ) arguments = { "tenant_id": tenant, @@ -148,17 +152,17 @@ async def test_original_pii_decision_survives_profile_and_retrieval(tmp_path, po assert stored.is_active is False assert not hits and not catalog and not embedder.inputs elif scanner == "disabled": - assert stored.sample_values_json == values + assert stored.sample_values_json == values[:8] assert stored.pii_tag is None assert "fixture@example.test" in rendered elif policy == "warn": assert stored.pii_tag == "EMAIL" assert stored.is_active - assert stored.sample_values_json == [v for v in values if "@" not in v] - if "ordinary" in values: + assert stored.sample_values_json == [v for v in values[:8] if "@" not in v] + if any(value.startswith("ordinary") for value in values): assert "fixture@example.test" in rendered else: - assert stored.sample_values_json == values + assert stored.sample_values_json == values[:8] assert stored.pii_tag is None assert all(value in rendered for value in values) assert hashlib.sha256(path.read_bytes()).hexdigest() == original diff --git a/tests/unit/test_pii_profile_gate.py b/tests/unit/test_pii_profile_gate.py new file mode 100644 index 00000000..a562a960 --- /dev/null +++ b/tests/unit/test_pii_profile_gate.py @@ -0,0 +1,52 @@ +# Copyright 2026 Firefly Software Foundation +# SPDX-License-Identifier: Apache-2.0 +"""PII outside the sampled prefix must not bypass the profile boundary.""" + +import uuid +from types import SimpleNamespace +from unittest.mock import AsyncMock, Mock + +import pytest + +from flyquery.core.services.ingestion.stages import pii_tag + + +@pytest.mark.parametrize( + "policy,scanner", [("redact", "regex"), ("reject", "regex"), ("warn", "regex"), ("redact", "disabled")] +) +async def test_profile_values_are_classified_before_retrieval(monkeypatch, policy, scanner): + samples = [f"ordinary-{i}" for i in range(8)] + column_id = uuid.uuid4() + monkeypatch.setattr( + pii_tag, + "_load_columns", + AsyncMock( + return_value=[ + { + "id": column_id, + "qualified_name": "records.note", + "sample_values_json": samples, + "description": "Synthetic text", + "data_type": "VARCHAR", + "profile_json": { + "top_values": [{"value": v} for v in samples + ["fixture@example.test"]] + }, + } + ] + ), + ) + apply = AsyncMock() + monkeypatch.setattr(pii_tag, "_apply_tag_and_policy", apply) + result = await pii_tag.run_pii_tag( + tenant_id="native", + snapshot_id=uuid.uuid4(), + session_factory=Mock(), + settings=SimpleNamespace(pii_scanner=scanner, pii_policy_samples=policy), + ) + if scanner == "disabled": + assert result["columns_tagged"] == 0 + apply.assert_not_awaited() + else: + assert result["columns_tagged"] == 1 + assert apply.await_args.kwargs["tag_name"] == "EMAIL" + assert apply.await_args.kwargs["policy"] == policy From 4f2d82428b37feaef8c9540227c636891bb4fd41 Mon Sep 17 00:00:00 2001 From: Andres Contreras Date: Wed, 14 Oct 2026 12:11:14 -0700 Subject: [PATCH 13/20] Apply the configured provider prompt cache to agent runs --- docs/integration-with-firefly-os.md | 2 +- docs/prompts.md | 28 +++++++-- src/flyquery/core/agents/builder.py | 3 + src/flyquery/core/observability/__init__.py | 60 +++++++----------- tests/unit/test_prompt_cache_wiring.py | 67 +++++++++++++++++++++ 5 files changed, 117 insertions(+), 43 deletions(-) create mode 100644 tests/unit/test_prompt_cache_wiring.py diff --git a/docs/integration-with-firefly-os.md b/docs/integration-with-firefly-os.md index 74d9424c..464be42d 100644 --- a/docs/integration-with-firefly-os.md +++ b/docs/integration-with-firefly-os.md @@ -215,7 +215,7 @@ and flyquery. A CI gate blocks any PR that drifts. | `web/agent_deps.py` | Agent-token FastAPI dependency | | `web/openapi_override.py` | OpenAPI spec customisation | | `core/agents/builder.py` | `build_agent` factory | -| `core/observability/__init__.py` | `DEFAULT_MIDDLEWARE` stack | +| `core/observability/__init__.py` | Configured provider prompt-cache policy | | `core/services/auth/agent_token_service.py` | Token verify logic | | `core/services/auth/redis_rate_limiter.py` | Redis rate limiter | | `web/controllers/agent_tokens_controller.py` | Token CRUD endpoints | diff --git a/docs/prompts.md b/docs/prompts.md index ba3053c6..fe1e5a5f 100644 --- a/docs/prompts.md +++ b/docs/prompts.md @@ -23,8 +23,8 @@ flyquery uses seven `FireflyAgent` instances, all built via the lock-step - Takes a structured Pydantic `output_type` — no tool calls; LLM output is parsed directly into the schema. - Is built fresh per call (`auto_register=False`) to avoid shared state. -- Wraps in the `DEFAULT_MIDDLEWARE` observability stack (elapsed + token usage - recorded to `flyquery_cost_events`). +- Uses Agentic's logging and observability defaults and the factory's + configured prompt-cache policy. Source of truth: `src/flyquery/core/agents/*.py`. @@ -480,11 +480,31 @@ def build_my_agent(settings): The `build_agent` factory (lock-step with flycanon/flyradar) wires: - `auto_register=False` — each agent instance is fresh per call; no shared pydantic-ai registry state. -- Observability middleware (`DEFAULT_MIDDLEWARE`) — records `elapsed_ms` and - token usage to `flyquery_cost_events`. +- Agentic's default logging and observability middleware, without duplicate + instances. `build_agent_middleware()` adds the configured cache policy. - `max_output_tokens` — defaults to `FLYQUERY_AGENT_MAX_OUTPUT_TOKENS=8192`. `RenameDetectionAgent` overrides to 2048. +### Provider prompt caching + +`FLYQUERY_PROMPT_CACHE` defaults to `on`. Set it to `off`, `0`, `false`, or +`no` to stop the factory from adding prompt-cache middleware. The factory +reads the setting each time it constructs an agent; agents already running +keep their existing policy. + +For direct Anthropic models, the policy marks static system instructions for +a five-minute provider cache. It does not mark conversation messages or tool +definitions. It adds no shared OpenAI cache routing key and creates no Gemini +cached-content resources. Claude through Bedrock/OpenRouter and other providers +receive no additional cache configuration from this policy. + +This is provider prompt caching, not a flyquery result cache. Each request +still runs its agent; SQL results and user/tool responses are not memoized or +reused by this middleware. Turning the switch off does not disable a provider's +automatic caching or override cache settings explicitly supplied by a caller. +The local tests verify the settings received by real `FireflyAgent` runs using +`TestModel`; they do not measure provider cache hits, billing, or retention. + **Agent test mocking note:** Per the `agent_test_mocking` memory, `stream.usage()` and `result.usage()` in mocks must return `None` (not a `MagicMock`). Returning `MagicMock` causes arithmetic errors in the diff --git a/src/flyquery/core/agents/builder.py b/src/flyquery/core/agents/builder.py index 3044bfb2..276b45df 100644 --- a/src/flyquery/core/agents/builder.py +++ b/src/flyquery/core/agents/builder.py @@ -1,4 +1,5 @@ # Copyright 2024-2026 Firefly Software Foundation +# SPDX-License-Identifier: Apache-2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -38,6 +39,7 @@ from typing import Any from flyquery.config import FlyquerySettings +from flyquery.core.observability import build_agent_middleware def build_agent( @@ -95,6 +97,7 @@ def build_agent( instructions=instructions, output_type=output_type, model_settings=model_settings, + middleware=build_agent_middleware(), auto_register=False, ) diff --git a/src/flyquery/core/observability/__init__.py b/src/flyquery/core/observability/__init__.py index 789e2a2c..8afd598b 100644 --- a/src/flyquery/core/observability/__init__.py +++ b/src/flyquery/core/observability/__init__.py @@ -1,4 +1,5 @@ # Copyright 2024-2026 Firefly Software Foundation +# SPDX-License-Identifier: Apache-2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -17,10 +18,8 @@ * :func:`timed_agent_run` -- async context manager that records the per-stage latency and propagates the W3C correlation context into the agent's structured logs. -* :data:`DEFAULT_MIDDLEWARE` -- the agentic middleware stack every - ``FireflyAgent`` is built with: usage tracking, logging, - prompt-cache, validation. The orchestrator's RetryMiddleware lives - separately so a stage can opt out (e.g. the deterministic ones). +* :func:`build_agent_middleware` -- the configured provider prompt-cache + policy. Agentic supplies logging and observability defaults separately. * :func:`log_outbound` -- thin wrapper around :func:`structlog.get_logger` to emit the ``outbound_call`` line for every LLM / webhook call. """ @@ -30,16 +29,10 @@ import logging import os import time -from collections.abc import AsyncIterator, Sequence +from collections.abc import AsyncIterator from contextlib import asynccontextmanager from typing import Any -from fireflyframework_agentic.agents.builtin_middleware import ( - LoggingMiddleware, - ObservabilityMiddleware, - ValidationMiddleware, # noqa: F401 -- referenced from the module docstring as an extension point -) -from fireflyframework_agentic.agents.middleware import AgentMiddleware from fireflyframework_agentic.agents.prompt_cache import PromptCacheMiddleware logger = logging.getLogger(__name__) @@ -56,33 +49,24 @@ def _prompt_cache_enabled() -> bool: return raw not in {"off", "0", "false", "no"} -#: Anthropic prompt-cache middleware -- single shared instance reused -#: by every service so the cache settings stay consistent (same TTL, -#: same blocks marked). System prompts are massive and identical -#: across the dozens of LLM calls per discovery, so this is the -#: cheapest, highest-leverage cost optimisation we have. -PROMPT_CACHE_MIDDLEWARE = PromptCacheMiddleware( - cache_system_prompt=True, - cache_last_message=True, - cache_ttl_seconds=300, - enabled=_prompt_cache_enabled(), -) - - -DEFAULT_MIDDLEWARE: Sequence[AgentMiddleware] = ( - PROMPT_CACHE_MIDDLEWARE, - LoggingMiddleware(), - ObservabilityMiddleware(), -) -"""Middleware stack applied to every :class:`FireflyAgent` constructed -by an intelligence stage. Listed in execution order: outermost first. - -Stages that want bespoke middleware (e.g. a hard cost-cap on the -duplicity detector, output validation via -:class:`ValidationMiddleware` with a tenant-specific reviewer) -append to this tuple instead of replacing it, so the baseline -behaviour stays consistent. -""" +def build_agent_middleware() -> list[PromptCacheMiddleware]: + """Read the switch for each agent; cache only static instructions. + + Agentic already supplies logging and observability. Without a tenant + cache authority, do not mark conversation/tool content or share an OpenAI + routing key. This middleware never stores model responses in flyquery. + """ + if not _prompt_cache_enabled(): + return [] + return [ + PromptCacheMiddleware( + cache_system_prompt=True, + cache_last_message=False, + cache_tool_definitions=False, + cache_ttl_seconds=300, + openai_cache_key="", + ) + ] @asynccontextmanager diff --git a/tests/unit/test_prompt_cache_wiring.py b/tests/unit/test_prompt_cache_wiring.py new file mode 100644 index 00000000..ef31c0f4 --- /dev/null +++ b/tests/unit/test_prompt_cache_wiring.py @@ -0,0 +1,67 @@ +# Copyright 2026 Firefly Software Foundation +# SPDX-License-Identifier: Apache-2.0 +"""The factory must apply the configured cache policy to actual agent runs.""" + +import pytest +from pydantic_ai.models.test import TestModel + +from flyquery.config import FlyquerySettings +from flyquery.core.agents.builder import build_agent + + +class RecordingModel(TestModel): + def __init__(self, **kwargs): + super().__init__(**kwargs) + self.settings_seen = [] + + async def request(self, messages, model_settings, model_request_parameters): + self.settings_seen.append(dict(model_settings or {})) + return await super().request(messages, model_settings, model_request_parameters) + + +def _agent(model): + return build_agent( + name="cache-policy-fixture", + model=model, + output_type=str, + instructions="Static synthetic instructions", + settings=FlyquerySettings(), + ) + + +async def test_enabled_cache_changes_real_run_settings_without_caching_messages_or_results(monkeypatch): + monkeypatch.setenv("FLYQUERY_PROMPT_CACHE", "on") + model = RecordingModel(model_name="claude-sonnet-4-6", custom_output_text="fixture response") + agent = _agent(model) + first = await agent.run("Synthetic tenant-one input") + second = await agent.run("Synthetic tenant-two input", message_history=first.all_messages()) + assert first.output == second.output == "fixture response" + assert len(model.settings_seen) == 2 + for settings in model.settings_seen: + assert settings["anthropic_cache_instructions"] == "5m" + assert "anthropic_cache_messages" not in settings + assert "anthropic_cache_tool_definitions" not in settings + assert "openai_prompt_cache_key" not in settings + names = [type(middleware).__name__ for middleware in agent._middleware] + assert names.count("PromptCacheMiddleware") == 1 + assert names.count("LoggingMiddleware") == 1 + assert names.count("ObservabilityMiddleware") <= 1 + + +@pytest.mark.parametrize("disabled", ["off", "0", "false", "no", " OFF "]) +async def test_switch_is_read_for_each_factory_call_and_disabled_has_no_cache_settings(monkeypatch, disabled): + monkeypatch.setenv("FLYQUERY_PROMPT_CACHE", "on") + first_model = RecordingModel(model_name="claude-sonnet-4-6", custom_output_text="first") + await _agent(first_model).run("Synthetic first input") + monkeypatch.setenv("FLYQUERY_PROMPT_CACHE", disabled) + second_model = RecordingModel(model_name="claude-sonnet-4-6", custom_output_text="second") + await _agent(second_model).run("Synthetic second input") + assert first_model.settings_seen[0]["anthropic_cache_instructions"] == "5m" + assert not any("cache" in key for key in second_model.settings_seen[0]) + + +async def test_openai_has_no_shared_cache_routing_key(monkeypatch): + monkeypatch.setenv("FLYQUERY_PROMPT_CACHE", "on") + model = RecordingModel(model_name="gpt-4.1", custom_output_text="fixture") + await _agent(model).run("Synthetic tenant input") + assert not any("cache" in key for key in model.settings_seen[0]) From 0565a2805001f5849e064df95f6a37050d11b738 Mon Sep 17 00:00:00 2001 From: Andres Contreras Date: Wed, 14 Oct 2026 12:40:38 -0700 Subject: [PATCH 14/20] Lock public Agentic dependencies and review service source variants --- .dockerignore | 19 + .github/workflows/docker-publish.yaml | 27 +- .github/workflows/pr-gate.yaml | 101 +- .gitignore | 6 +- Dockerfile | 41 +- README.md | 7 +- Taskfile.yml | 6 +- docs/architecture.md | 22 +- docs/cicd.md | 27 +- docs/glossary.md | 7 +- docs/integration-with-firefly-os.md | 10 +- docs/prompts.md | 4 +- docs/quality.md | 19 +- docs/release.md | 30 +- docs/troubleshooting.md | 22 +- pyproject.toml | 14 +- scripts/check_lockstep.py | 71 +- scripts/lockstep_variants.v1.json | 20 + tests/unit/test_lockstep_variants.py | 97 + uv.lock | 4154 +++++++++++++++++++++++++ 20 files changed, 4474 insertions(+), 230 deletions(-) create mode 100644 .dockerignore create mode 100644 scripts/lockstep_variants.v1.json create mode 100644 tests/unit/test_lockstep_variants.py create mode 100644 uv.lock diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 00000000..5102428c --- /dev/null +++ b/.dockerignore @@ -0,0 +1,19 @@ +# Copyright 2026 Firefly Software Foundation +# SPDX-License-Identifier: Apache-2.0 +.git +.venv +venv +__pycache__ +.pytest_cache +.ruff_cache +.mypy_cache +.env +.env.* +.local_blobs +.local +vendor +sdks +build +dist +*.log +*.whl diff --git a/.github/workflows/docker-publish.yaml b/.github/workflows/docker-publish.yaml index 4e717bdb..ed7ba4cc 100644 --- a/.github/workflows/docker-publish.yaml +++ b/.github/workflows/docker-publish.yaml @@ -1,4 +1,5 @@ # Copyright 2026 Firefly Software Foundation +# SPDX-License-Identifier: Apache-2.0 # # Multi-arch image build + GHCR push. # @@ -12,16 +13,8 @@ # (the owner is normalised to lower-case below, since # GHCR requires lower-case repository namespaces). # -# The Dockerfile uses BuildKit named contexts for the pyfly + -# fireflyframework-agentic sibling repos. We clone them into ./vendor/ -# and pass them via ``build-contexts:`` so the same Dockerfile works -# both locally (siblings on disk) and in CI. -# -# The Docling OCR engine is an opt-in runtime extra (``pip install -# 'flyquery[docling]'``) selected via ``FLYCANON_PDF_OCR_ENGINE=docling``. -# The image does not bake docling because the PyTorch + HF wheels add -# ~2.5 GB per architecture; operators that want layout-aware OCR -# extend the runtime stage (see docs/deployment.md). +# The Dockerfile validates the tracked server lock and installs its frozen +# public dependency graph. No adjacent framework checkout is required. name: Docker publish (multi-arch) @@ -56,8 +49,6 @@ concurrency: env: REGISTRY: ghcr.io - PYFLY_REF: v26.05.05 - AGENTIC_REF: v26.05.21 jobs: publish: @@ -73,15 +64,6 @@ jobs: name="${GITHUB_REPOSITORY##*/}" echo "image=${{ env.REGISTRY }}/${owner}/${name}" >> "$GITHUB_OUTPUT" - - name: Check out sibling firefly framework repos - run: | - git clone --depth=1 --branch "$PYFLY_REF" \ - https://github.com/fireflyframework/fireflyframework-pyfly.git \ - ./vendor/pyfly - git clone --depth=1 --branch "$AGENTIC_REF" \ - https://github.com/fireflyframework/fireflyframework-agentic.git \ - ./vendor/fireflyframework-agentic - - uses: docker/setup-qemu-action@v3 with: platforms: linux/amd64,linux/arm64 @@ -131,9 +113,6 @@ jobs: sbom: false tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} - build-contexts: | - pyfly=./vendor/pyfly - fireflyframework-agentic=./vendor/fireflyframework-agentic cache-from: type=gha,scope=flyquery cache-to: type=gha,mode=max,scope=flyquery diff --git a/.github/workflows/pr-gate.yaml b/.github/workflows/pr-gate.yaml index 31072537..601a489f 100644 --- a/.github/workflows/pr-gate.yaml +++ b/.github/workflows/pr-gate.yaml @@ -1,4 +1,5 @@ # Copyright 2026 Firefly Software Foundation +# SPDX-License-Identifier: Apache-2.0 # # PR gate -- runs on every pull request, on push to main, and on # workflow_dispatch. @@ -8,19 +9,14 @@ # 2. typecheck : pyright (best-effort, advisory) # 3. unit : pytest tests/unit # 4. integration : pytest tests/integration (Postgres+Redis+MinIO via testcontainers) -# 5. lockstep-check : 21 byte-equivalent files vs canon-pinned SHAs +# 5. lockstep-check : 19 historical baselines + 2 reviewed service variants # 6. sdk-python : import-smoke + ruff under sdks/python # 7. sdk-java : ``mvn verify`` under sdks/java # # Notes # ----- -# * pyfly + fireflyframework-agentic live in the public -# ``fireflyframework`` organization. The -# per-job ``Check out sibling firefly framework repos`` step -# clones the tagged refs into ``./vendor/`` and ``sed``-rewrites -# ``[tool.uv.sources]`` to point there for the duration of CI. -# * Pin the framework refs in ``env.{PYFLY_REF,AGENTIC_REF}`` so -# the gate is reproducible. +# * Public first-party sources are recorded in pyproject.toml and uv.lock. +# * Validate the lock before frozen sync; CI must not resolve new dependencies. name: PR gate @@ -50,8 +46,6 @@ concurrency: env: PYTHON_VERSION: "3.13" - PYFLY_REF: v26.05.05 - AGENTIC_REF: v26.05.21 jobs: lint: @@ -65,26 +59,14 @@ jobs: - uses: actions/setup-python@v5 with: python-version: ${{ env.PYTHON_VERSION }} - - name: Check out sibling firefly framework repos - run: | - git clone --depth=1 --branch "$PYFLY_REF" \ - https://github.com/fireflyframework/fireflyframework-pyfly.git \ - ./vendor/pyfly - git clone --depth=1 --branch "$AGENTIC_REF" \ - https://github.com/fireflyframework/fireflyframework-agentic.git \ - ./vendor/fireflyframework-agentic - - name: Repoint uv path sources at ./vendor - run: | - sed -i \ - -e 's|path = "\.\./\.\./fireflyframework/fireflyframework-pyfly"|path = "./vendor/pyfly"|' \ - -e 's|path = "\.\./\.\./fireflyframework/fireflyframework-agentic"|path = "./vendor/fireflyframework-agentic"|' \ - pyproject.toml - name: uv sync (dev + s3) - run: uv sync --extra dev --extra s3 --extra file-readers + run: | + uv lock --check + uv sync --frozen --extra dev --extra s3 --extra file-readers - name: ruff check - run: uv run ruff check src tests + run: uv run --frozen ruff check src tests - name: ruff format --check - run: uv run ruff format --check src tests + run: uv run --frozen ruff format --check src tests typecheck: name: Typecheck (advisory) @@ -98,24 +80,12 @@ jobs: - uses: actions/setup-python@v5 with: python-version: ${{ env.PYTHON_VERSION }} - - name: Check out sibling firefly framework repos - run: | - git clone --depth=1 --branch "$PYFLY_REF" \ - https://github.com/fireflyframework/fireflyframework-pyfly.git \ - ./vendor/pyfly - git clone --depth=1 --branch "$AGENTIC_REF" \ - https://github.com/fireflyframework/fireflyframework-agentic.git \ - ./vendor/fireflyframework-agentic - - name: Repoint uv path sources at ./vendor - run: | - sed -i \ - -e 's|path = "\.\./\.\./fireflyframework/fireflyframework-pyfly"|path = "./vendor/pyfly"|' \ - -e 's|path = "\.\./\.\./fireflyframework/fireflyframework-agentic"|path = "./vendor/fireflyframework-agentic"|' \ - pyproject.toml - name: uv sync (dev) - run: uv sync --extra dev --extra file-readers + run: | + uv lock --check + uv sync --frozen --extra dev --extra file-readers - name: pyright - run: uv run pyright src/flyquery + run: uv run --frozen pyright src/flyquery unit: name: Unit tests @@ -128,22 +98,10 @@ jobs: - uses: actions/setup-python@v5 with: python-version: ${{ env.PYTHON_VERSION }} - - name: Check out sibling firefly framework repos - run: | - git clone --depth=1 --branch "$PYFLY_REF" \ - https://github.com/fireflyframework/fireflyframework-pyfly.git \ - ./vendor/pyfly - git clone --depth=1 --branch "$AGENTIC_REF" \ - https://github.com/fireflyframework/fireflyframework-agentic.git \ - ./vendor/fireflyframework-agentic - - name: Repoint uv path sources at ./vendor - run: | - sed -i \ - -e 's|path = "\.\./\.\./fireflyframework/fireflyframework-pyfly"|path = "./vendor/pyfly"|' \ - -e 's|path = "\.\./\.\./fireflyframework/fireflyframework-agentic"|path = "./vendor/fireflyframework-agentic"|' \ - pyproject.toml - name: uv sync (dev) - run: uv sync --extra dev --extra file-readers + run: | + uv lock --check + uv sync --frozen --extra dev --extra file-readers - name: pytest tests/unit env: # Dummy LLM keys so pydantic-ai providers can instantiate @@ -152,7 +110,7 @@ jobs: OPENAI_API_KEY: sk-dummy-key ANTHROPIC_API_KEY: sk-dummy-key AWS_DEFAULT_REGION: eu-west-1 - run: uv run pytest -q tests/unit -m 'not integration' + run: uv run --frozen pytest -q tests/unit -m 'not integration' integration: name: Integration tests @@ -166,22 +124,10 @@ jobs: - uses: actions/setup-python@v5 with: python-version: ${{ env.PYTHON_VERSION }} - - name: Check out sibling firefly framework repos - run: | - git clone --depth=1 --branch "$PYFLY_REF" \ - https://github.com/fireflyframework/fireflyframework-pyfly.git \ - ./vendor/pyfly - git clone --depth=1 --branch "$AGENTIC_REF" \ - https://github.com/fireflyframework/fireflyframework-agentic.git \ - ./vendor/fireflyframework-agentic - - name: Repoint uv path sources at ./vendor - run: | - sed -i \ - -e 's|path = "\.\./\.\./fireflyframework/fireflyframework-pyfly"|path = "./vendor/pyfly"|' \ - -e 's|path = "\.\./\.\./fireflyframework/fireflyframework-agentic"|path = "./vendor/fireflyframework-agentic"|' \ - pyproject.toml - name: uv sync (dev + s3 for MinIO conformance) - run: uv sync --extra dev --extra s3 --extra file-readers + run: | + uv lock --check + uv sync --frozen --extra dev --extra s3 --extra file-readers - name: Build the pinned upstream MinIO test server run: docker build --tag flyquery-integration-minio:${{ github.sha }} tests/integration/minio - name: pytest tests/integration @@ -195,7 +141,7 @@ jobs: OPENAI_API_KEY: sk-dummy-key ANTHROPIC_API_KEY: sk-dummy-key AWS_DEFAULT_REGION: eu-west-1 - run: uv run pytest tests/integration -q --timeout=300 -m 'not llm' + run: uv run --frozen pytest tests/integration -q --timeout=300 -m 'not llm' lockstep-check: name: Lockstep check (canon-pinned SHAs) @@ -206,9 +152,8 @@ jobs: with: python-version: ${{ env.PYTHON_VERSION }} # The lockstep script imports nothing from pyfly/agentic; it - # walks the 21 lock-step files, computes SHA-256 after a - # canon-normalising substitution, and compares to the pinned - # JSON. No uv sync + no sibling clones needed. + # checks nineteen historical baseline hashes and two reviewed + # full-file service variants. No dependency installation needed. - name: Run lockstep check run: python scripts/check_lockstep.py diff --git a/.gitignore b/.gitignore index 4c655643..afcc2ae1 100644 --- a/.gitignore +++ b/.gitignore @@ -32,9 +32,9 @@ wheels/ .uv/ .pip/ -# uv.lock is generated locally; CI runs ``uv sync`` (not ``uv sync -# --frozen``) so the lockfile doesn't need to ride in git. -uv.lock +# The server lock is reviewed release source; SDK development locks remain local. +**/uv.lock +!/uv.lock # --- Java SDK build artefacts ------------------------------------------------ sdks/java/target/ diff --git a/Dockerfile b/Dockerfile index 15b5b38c..1fc508ef 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,5 @@ # Copyright 2024-2026 Firefly Software Foundation +# SPDX-License-Identifier: Apache-2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -16,18 +17,8 @@ # # Multi-stage Docker build for flyquery. # -# Sibling-path deps (pyfly, fireflyframework-agentic) are passed in as -# named BuildKit contexts so the build context stays scoped to this -# directory. -# -# Usage: -# docker buildx build \ -# --build-context pyfly=../../fireflyframework/fireflyframework-pyfly \ -# --build-context fireflyframework-agentic=../../fireflyframework/fireflyframework-agentic \ -# --tag flyquery:latest \ -# . -# -# See docker-compose.yml for the canonical invocation. +# Dependencies come from public first-party sources pinned by uv.lock. +# Build: docker build --tag flyquery:local . ARG PYTHON_VERSION=3.13 @@ -43,31 +34,17 @@ RUN apt-get update \ ENV UV_PROJECT_ENVIRONMENT=/app/.venv \ UV_LINK_MODE=copy -# Stage sibling sources (only what uv needs to install the editable wheel). -COPY --from=pyfly /pyproject.toml /build/pyfly/pyproject.toml -COPY --from=pyfly /README.md /build/pyfly/README.md -COPY --from=pyfly /src /build/pyfly/src - -COPY --from=fireflyframework-agentic /pyproject.toml /build/fireflyframework-agentic/pyproject.toml -COPY --from=fireflyframework-agentic /README.md /build/fireflyframework-agentic/README.md -COPY --from=fireflyframework-agentic /LICENSE /build/fireflyframework-agentic/LICENSE -COPY --from=fireflyframework-agentic /fireflyframework_agentic /build/fireflyframework-agentic/fireflyframework_agentic - # Stage the project manifests for layer caching. README.md is required # by hatchling because pyproject.toml declares ``readme = "README.md"``. WORKDIR /app COPY pyproject.toml /app/pyproject.toml COPY README.md /app/README.md -COPY uv.lock* /app/ - -# Rewrite path-source entries so uv resolves siblings inside the container. -RUN sed -i \ - -e 's|path = "\.\./\.\./fireflyframework/fireflyframework-pyfly"|path = "/build/pyfly"|' \ - -e 's|path = "\.\./\.\./fireflyframework/fireflyframework-agentic"|path = "/build/fireflyframework-agentic"|' \ - /app/pyproject.toml +COPY LICENSE /app/LICENSE +COPY uv.lock /app/uv.lock RUN --mount=type=cache,target=/root/.cache/uv \ - uv sync --no-install-project --no-dev --no-editable + uv lock --check \ + && uv sync --frozen --no-install-project --no-dev --no-editable # Copy the application source + migrations and finalise the install. COPY src/ /app/src/ @@ -78,7 +55,7 @@ COPY docker-entrypoint.sh /app/docker-entrypoint.sh RUN chmod +x /app/docker-entrypoint.sh RUN --mount=type=cache,target=/root/.cache/uv \ - uv sync --no-dev --no-editable + uv sync --frozen --no-dev --no-editable # ---- Stage 2: runtime ----------------------------------------------------- @@ -112,7 +89,7 @@ RUN apt-get update \ && useradd --uid 10001 --shell /usr/sbin/nologin --no-create-home flyquery WORKDIR /app -# Copy artefacts as the unprivileged ``canon`` user so the runtime always +# Copy artefacts as the unprivileged ``flyquery`` user so the runtime always # has read access to bundled resources (e.g. resources/prompts/*.yaml) # regardless of whatever host umask produced the source tree. COPY --from=builder --chown=flyquery:flyquery /app/.venv /app/.venv diff --git a/README.md b/README.md index a18ae113..62f5b7bc 100644 --- a/README.md +++ b/README.md @@ -294,9 +294,10 @@ The **hexagonal adapter ring** means every external boundary (object store, file reader, vector store, PII scanner, semantic compiler, rate limiter) is a Python `Protocol`; the domain core never depends on a concrete implementation. -Lock-step modules (`web/conventions/*`, `agent_deps.py`, `agent_token_service.py`, -`builder.py`) are byte-equivalent with flycanon and flyradar. A CI gate -(`scripts/check_lockstep.py`) blocks PRs that drift. +The source-contract gate (`scripts/check_lockstep.py`) preserves nineteen +normalized historical shared baselines and two explicitly reviewed +service-specific agent/cache variants. It blocks unreviewed drift; it does +not claim that current canon or radar main has identical source files. See [docs/architecture.md](docs/architecture.md) for the full picture. diff --git a/Taskfile.yml b/Taskfile.yml index ca296114..35427a2e 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -1,4 +1,5 @@ # Copyright 2026 Firefly Software Foundation +# SPDX-License-Identifier: Apache-2.0 version: '3' env: @@ -26,7 +27,8 @@ tasks: desc: Sync dependencies via uv cmds: - uv venv - - uv sync --extra dev --extra s3 + - uv lock --check + - uv sync --frozen --extra dev --extra s3 --extra file-readers migrate: desc: Run alembic migrations (admin role) @@ -73,7 +75,7 @@ tasks: - task: test:integration lockstep: - desc: Verify lock-step files match pinned canon SHAs + desc: Verify historical source baselines and reviewed service variants cmds: - uv run python scripts/check_lockstep.py diff --git a/docs/architecture.md b/docs/architecture.md index 29ba291e..5efba86f 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -587,9 +587,17 @@ per-request timeout or row-cap argument. See the ## 9. Lock-step modules -The following files are kept byte-equivalent with flycanon and flyradar. -`scripts/check_lockstep.py` diffs them against pinned SHAs in CI; PRs are -blocked on mismatch. +`scripts/check_lockstep.py` checks 21 local source contracts. Nineteen retain +their normalized historical shared-baseline hashes in +`scripts/lockstep_pins.json`. These pins protect against accidental drift; +the script does not download or compare current canon/radar source. + +Two paths are reviewed service-specific variants: `core/agents/builder.py` +and `core/observability/__init__.py`. Their complete file bytes are pinned in +`scripts/lockstep_variants.v1.json`, with a reason and canonical source +reference. At canon revision `aa2486ac98bf2bb92f0187ac30ca80900fae8abd`, +the factory has its own Azure resolver and there is no generic observability +module. Preserving those differences avoids asserting false full-file parity. ``` src/flyquery/web/agent_deps.py (~3.7 KB) @@ -612,6 +620,8 @@ src/flyquery/core/observability/__init__.py src/flyquery/web/openapi_override.py ``` -21 files total. Any change to these in flyquery must also be reflected in the -canon and radar twins (or vice versa). Post-patch diff is checked via -`task lockstep-check`. +Run `task lockstep` after changes. Unknown exception paths, missing +reasons or hashes, missing files, and any subsequent variant/source drift +fail the gate. Authentication and the other nineteen baselines cannot be +exempted by adding an entry to the variant manifest. Hash changes require +source review; a passing hash check does not replace behavior or security tests. diff --git a/docs/cicd.md b/docs/cicd.md index 983c1c35..707d6ae9 100644 --- a/docs/cicd.md +++ b/docs/cicd.md @@ -223,30 +223,29 @@ Apache-2.0 license. ## 5. Workflow: Lock-step check -Runs on every PR and push to `main`. Blocks if any lock-step module in flyquery -has drifted from its pinned SHA in flycanon or flyradar. +The `lockstep-check` job in `pr-gate.yaml` checks the local source contracts +for PRs and main pushes selected by that workflow's path filters. ```yaml -# .github/workflows/lockstep-check.yml (structure) +# .github/workflows/pr-gate.yaml (source-contract job) jobs: - lockstep: + lockstep-check: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - run: uv run python scripts/check_lockstep.py - env: - FLYCANON_REF: ${{ vars.FLYCANON_PINNED_SHA }} - FLYRADAR_REF: ${{ vars.FLYRADAR_PINNED_SHA }} + - run: python scripts/check_lockstep.py ``` The script checks: -1. Fetches the pinned SHA of flycanon and flyradar from GitHub vars. -2. Downloads the lock-step files from those SHAs. -3. Diffs byte-by-byte against flyquery's copies. -4. Exits non-zero if any file drifts. +1. Loads the nineteen retained historical normalized baseline pins. +2. Validates the versioned manifest for the two allowed service variants. +3. Checks normalized baseline hashes or exact full-file variant hashes. +4. Exits nonzero on drift, missing files, invalid metadata, or unknown exceptions. + +It makes no remote calls and does not imply parity with current canon/radar +main. The [architecture guide](architecture.md#9-lock-step-modules) records +the service-specific boundary and canonical source reference. Fixing a lock-step drift: see [troubleshooting.md § 12](troubleshooting.md#12-lock-step-drift-ci-failure). diff --git a/docs/glossary.md b/docs/glossary.md index f2b239b2..46b9c44e 100644 --- a/docs/glossary.md +++ b/docs/glossary.md @@ -163,9 +163,10 @@ A Postgres role attribute that exempts the role from RLS policies. The (runtime) must NOT have BYPASSRLS. **lock-step** -Byte-equivalent modules shared across flycanon, flyradar, and flyquery. Any -change to a lock-step module must be applied to all three services. Verified -by `scripts/check_lockstep.py` in CI. +The local source-contract check: nineteen normalized historical shared +baselines and two reviewed service-specific agent/cache variants. It rejects +drift without asserting that current canon/radar main has identical files. +See [architecture](architecture.md#9-lock-step-modules). **hybrid retrieval** The retrieval strategy combining BM25 (full-text search via `content_tsv`) diff --git a/docs/integration-with-firefly-os.md b/docs/integration-with-firefly-os.md index 464be42d..3360470b 100644 --- a/docs/integration-with-firefly-os.md +++ b/docs/integration-with-firefly-os.md @@ -197,8 +197,9 @@ enforces them at the database level. ## 5. Lock-step modules -The following files are kept byte-equivalent across flycanon, flyradar, -and flyquery. A CI gate blocks any PR that drifts. +The source-contract gate preserves nineteen normalized historical shared +baselines. The builder and observability module are service-specific variants +with reviewed full-file pins; the check does not compare live canon/radar main. | Module | Purpose | |--------|---------| @@ -220,8 +221,9 @@ and flyquery. A CI gate blocks any PR that drifts. | `core/services/auth/redis_rate_limiter.py` | Redis rate limiter | | `web/controllers/agent_tokens_controller.py` | Token CRUD endpoints | -Any bug fix in one service's lock-step module must be applied to all three. -Use `task lockstep-check` to verify. +Use `task lockstep` to reject drift. Do not copy changes across services +without checking their current APIs. The [architecture guide](architecture.md#9-lock-step-modules) +documents the two bounded variants, their provenance, and the retained baselines. --- diff --git a/docs/prompts.md b/docs/prompts.md index fe1e5a5f..e87d6855 100644 --- a/docs/prompts.md +++ b/docs/prompts.md @@ -16,7 +16,7 @@ ## 1. Overview -flyquery uses seven `FireflyAgent` instances, all built via the lock-step +flyquery uses seven `FireflyAgent` instances, all built via the shared `build_agent` factory from `core/agents/builder.py`. Each agent: - Has a single `_INSTRUCTIONS` string that defines its behaviour. @@ -477,7 +477,7 @@ def build_my_agent(settings): ) ``` -The `build_agent` factory (lock-step with flycanon/flyradar) wires: +The service-specific `build_agent` factory wires: - `auto_register=False` — each agent instance is fresh per call; no shared pydantic-ai registry state. - Agentic's default logging and observability middleware, without duplicate diff --git a/docs/quality.md b/docs/quality.md index b7973d6a..6e6cfd12 100644 --- a/docs/quality.md +++ b/docs/quality.md @@ -255,22 +255,15 @@ ANTHROPIC_API_KEY= uv run pytest tests/integration/ -m llm --tb=short -q ## 8. Lock-step drift CI gate -`scripts/check_lockstep.py` verifies that all files in the lock-step set -(see [architecture.md § Lock-step modules](architecture.md#9-lock-step-modules)) -are byte-equivalent with the pinned SHAs of flycanon and flyradar. +`scripts/check_lockstep.py` checks nineteen normalized historical baselines +and two reviewed service-specific variants. It does not compare live canon +or radar repositories. See the [source-contract scope](architecture.md#9-lock-step-modules) +for the manifest and provenance. ```bash # Run manually -python scripts/check_lockstep.py --verbose -# → OK: web/conventions/middleware.py (matches flycanon sha abc123) -# → DRIFT: web/conventions/errors.py (differs from flycanon sha def456) -# +++ 42c42 -# - old line -# + new line - -# In CI -FLYCANON_REF=$FLYCANON_PINNED_SHA python scripts/check_lockstep.py -# Exit 1 if any file drifts +python scripts/check_lockstep.py +# Exit 1 on source drift or an invalid variant manifest. ``` See [cicd.md](cicd.md) for the workflow configuration. diff --git a/docs/release.md b/docs/release.md index 1b69bd8f..7c8a476b 100644 --- a/docs/release.md +++ b/docs/release.md @@ -63,18 +63,38 @@ task openapi-snapshot The drift gate at `tests/integration/test_openapi_snapshot.py` will fail CI if you forget. +### Reproducible server dependencies + +The server now tracks `uv.lock`. Earlier releases resolved dependencies again +on CI and image builds; those builds could select different transitive versions. +CI and Docker first run `uv lock --check`, then `uv sync --frozen`. The check +rejects a stale project manifest before the frozen install; `--frozen` alone +would not check whether the manifest changed. + +The graph uses the public Agentic 26.10.1 wheel and retains the qualified +pyfly 26.06.113 tag. Update dependencies with the normal resolver, review the +lock diff, and rerun the native gates. Do not publish local candidate paths or +replace conflicts with dependency overrides. SDK development locks remain local. + +Native query execution and nonempty-candidate selection do not establish that +an answer matches the user's intended entities or filters. Candidate selection +is a heuristic; these safety and dependency checks do not close semantic query +QA or the handling of unmatched literals. + ### 3. Lockstep -21 byte-equivalent files are shared with flycanon + flyradar. The -check normalises `flyquery -> flycanon` then SHA-256s the result -against pinned hashes: +The gate preserves nineteen normalized historical shared-baseline hashes +and two reviewed service-specific full-file hashes. It validates local +contracts rather than comparing current canon/radar source: ```bash uv run python scripts/check_lockstep.py ``` -If this fails, do NOT just rebump the pin -- the change has to land -in canon / radar first. +If this fails, review the source change and its behavior before changing any +pin. The variant manifest permits only the agent builder and observability +module, with a reason and canonical source provenance. It cannot exempt an +authentication file. See [architecture](architecture.md#9-lock-step-modules). ### 4. SDK regen + builds diff --git a/docs/troubleshooting.md b/docs/troubleshooting.md index 52a64d03..b0b5a4d1 100644 --- a/docs/troubleshooting.md +++ b/docs/troubleshooting.md @@ -362,23 +362,21 @@ conversation's snapshot pins reference the previous upload's data. ### Symptom: CI fails with `scripts/check_lockstep.py: drift detected in src/flyquery/web/conventions/middleware.py` -**Root cause:** A file in the lock-step set was modified in flyquery without -corresponding updates in flycanon or flyradar (or vice versa). +**Root cause:** A local source file differs from its reviewed historical +baseline or service-specific pin, or the variant manifest is invalid. **Fix:** ```bash -# See which file drifted and which service has the canonical version -python scripts/check_lockstep.py --verbose - -# Copy the canonical version from the service that should lead -cp ../flycanon/src/flycanon/web/conventions/middleware.py \ - src/flyquery/web/conventions/middleware.py - -# Commit -git add src/flyquery/web/conventions/middleware.py -git commit -m "chore: sync middleware.py with flycanon (lock-step)" +python scripts/check_lockstep.py ``` +Review the reported source diff before restoring a file or changing a pin. +Current canon/radar files may have different APIs; copying them blindly can +break flyquery. Only the builder and observability paths permit reviewed +service variants. Authentication changes still fail their historical pins. +The [architecture guide](architecture.md#9-lock-step-modules) explains the +manifest and canonical provenance; rerun behavior tests after a correction. + --- ## 13. SDK installation failures diff --git a/pyproject.toml b/pyproject.toml index 7e5ff2e1..5d8f9652 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -19,7 +19,7 @@ dependencies = [ # GenAI metaframework -- FireflyAgent over pydantic-ai + the OpenAI # embeddings provider. flyquery builds its own pgvector hybrid retriever # and declares sqlglot directly below for its Text-to-SQL pipeline. - "fireflyframework-agentic[rest,security,redis,openai-embeddings]>=26.5.11", + "fireflyframework-agentic[security,openai-embeddings]>=26.10.1", # HTTP + tenacity (outbound). "httpx>=0.28.0", @@ -113,21 +113,11 @@ file-readers = [ requires = ["hatchling>=1.18"] build-backend = "hatchling.build" -[tool.uv] -# fireflyframework-agentic depends on pydantic-ai>=1.99, whose transitive -# ``pydantic-ai-slim[mistral]`` drags in ``mistralai>=2.0.0`` (PyPI pre-release -# only) and forces ``opentelemetry-semantic-conventions==0.60b1``. flyquery -# never uses the mistral provider, so pin mistralai to the stable 1.x line. -# Drop once mistralai 2.x reaches stable or pydantic-ai stops requesting it. -override-dependencies = [ - "mistralai>=1.0.0,<2.0.0", -] - [tool.uv.sources] # pyfly and agentic are consumed from their published git tags so fresh # clones / CI resolve them without any sibling path. pyfly = { git = "https://github.com/fireflyframework/fireflyframework-pyfly.git", tag = "v26.06.113" } -fireflyframework-agentic = { git = "https://github.com/fireflyframework/fireflyframework-agentic.git", tag = "v26.05.30" } +fireflyframework-agentic = { url = "https://github.com/fireflyframework/fireflyframework-agentic/releases/download/v26.10.1/fireflyframework_agentic-26.10.1-py3-none-any.whl" } [tool.hatch.build.targets.wheel] packages = ["src/flyquery"] diff --git a/scripts/check_lockstep.py b/scripts/check_lockstep.py index b4412a40..599a376f 100644 --- a/scripts/check_lockstep.py +++ b/scripts/check_lockstep.py @@ -1,5 +1,6 @@ #!/usr/bin/env python # Copyright 2024-2026 Firefly Software Foundation +# SPDX-License-Identifier: Apache-2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -13,18 +14,13 @@ # See the License for the specific language governing permissions and # limitations under the License. -"""Lock-step CI gate (spec §14). +"""Check nineteen normalized historical baselines and two reviewed variants. -Computes the SHA-256 of each lock-step file (after a deterministic -service-name de-substitution: replaces 'flyquery' -> 'flycanon', -'FLYQUERY' -> 'FLYCANON', etc. — same regex set as the copy -script in Tasks 10-11) and compares against the pinned canon SHA in -scripts/lockstep_pins.json. - -Drift = exit code 1. Pinned SHAs are refreshed when an intentional -canon-side change lands and we propagate it across canon/radar/flyquery -in lock-step (rare). +The baseline pins are local historical contracts, not a comparison with live +canon main. Only the two listed service-specific paths may use full-file pins +from the versioned manifest; every other path keeps its original baseline. """ + from __future__ import annotations import hashlib @@ -33,7 +29,6 @@ import sys from pathlib import Path - LOCKSTEP_FILES = [ "src/flyquery/web/agent_deps.py", "src/flyquery/web/openapi_override.py", @@ -58,10 +53,45 @@ "src/flyquery/web/controllers/agent_tokens_controller.py", ] +SERVICE_VARIANTS = { + "src/flyquery/core/agents/builder.py", + "src/flyquery/core/observability/__init__.py", +} + + +def _service_variants(root: Path) -> dict[str, dict[str, str]]: + manifest = json.loads((root / "scripts" / "lockstep_variants.v1.json").read_text()) + if not isinstance(manifest, dict) or type(manifest.get("version")) is not int or manifest["version"] != 1: + raise ValueError("UNSUPPORTED VARIANT VERSION") + source = manifest.get("canonical_source") + if ( + not isinstance(source, dict) + or source.get("repository") != "https://github.com/fireflyframework/flycanon" + or not isinstance(source.get("revision"), str) + or not re.fullmatch(r"[0-9a-f]{40}", source["revision"]) + ): + raise ValueError("INVALID CANONICAL SOURCE") + variants = manifest.get("variants") + if not isinstance(variants, dict): + raise ValueError("INVALID VARIANT MANIFEST") + if set(variants) - SERVICE_VARIANTS: + raise ValueError("UNKNOWN VARIANT PATH") + if set(variants) != SERVICE_VARIANTS: + raise ValueError("MISSING VARIANT PIN") + for rel, entry in variants.items(): + if ( + not isinstance(entry, dict) + or not isinstance(entry.get("rationale"), str) + or not entry["rationale"].strip() + ): + raise ValueError(f"INVALID VARIANT RATIONALE: {rel}") + if not isinstance(entry.get("sha256"), str) or not re.fullmatch(r"[0-9a-f]{64}", entry["sha256"]): + raise ValueError(f"INVALID VARIANT PIN: {rel}") + return variants + def _normalise(text: str) -> bytes: - """Reverse the flyquery substitutions to canon's form, so the SHA is - canon-pinned regardless of which service we're checking.""" + """Apply the unchanged historic service substitutions used by baseline pins.""" text = re.sub(r"\bflyquery\b", "flycanon", text) text = re.sub(r"\bFLYQUERY\b", "FLYCANON", text) text = re.sub(r"\bflyquery_", "canon_", text) @@ -71,6 +101,11 @@ def _normalise(text: str) -> bytes: def main() -> int: root = Path(__file__).resolve().parent.parent + try: + variants = _service_variants(root) + except (OSError, ValueError) as exc: + print(f"INVALID VARIANT MANIFEST: {exc}") + return 1 pins_path = root / "scripts" / "lockstep_pins.json" pins: dict[str, str] = json.loads(pins_path.read_text()) if pins_path.exists() else {} drift: list[str] = [] @@ -79,16 +114,18 @@ def main() -> int: if not p.exists(): drift.append(f"MISSING: {rel}") continue - sha = hashlib.sha256(_normalise(p.read_text())).hexdigest() - pinned = pins.get(rel) + variant = variants.get(rel) + sha = hashlib.sha256(p.read_bytes() if variant else _normalise(p.read_text())).hexdigest() + pinned = variant["sha256"] if variant else pins.get(rel) if pinned is None: drift.append(f"UNPINNED: {rel} -> {sha}") elif pinned != sha: - drift.append(f"DRIFT: {rel}\n pinned: {pinned}\n current: {sha}") + label = "SERVICE VARIANT DRIFT" if variant else "DRIFT" + drift.append(f"{label}: {rel}\n pinned: {pinned}\n current: {sha}") if drift: print("\n".join(drift)) return 1 - print(f"lockstep OK: {len(LOCKSTEP_FILES)} files match pins") + print("lockstep OK: 19 historical baselines and 2 reviewed service variants match pins") return 0 diff --git a/scripts/lockstep_variants.v1.json b/scripts/lockstep_variants.v1.json new file mode 100644 index 00000000..a3c4a93a --- /dev/null +++ b/scripts/lockstep_variants.v1.json @@ -0,0 +1,20 @@ +{ + "version": 1, + "canonical_source": { + "repository": "https://github.com/fireflyframework/flycanon", + "revision": "aa2486ac98bf2bb92f0187ac30ca80900fae8abd", + "builder_sha256": "4859aa020705b651fbc94e703f8fb4785767f80b79ceb9db1b4c5a058940948b", + "observability_module_exists": false, + "existing_rlm_cache_switch": "FLYCANON_RLM_PROMPT_CACHE" + }, + "variants": { + "src/flyquery/core/agents/builder.py": { + "sha256": "f213fff74c37c1b5fe7c0a14f3b55439064531b9086e5d45b1c125d6254063c7", + "rationale": "The current canon factory preserves Azure model resolution and has different settings. flyquery retains its own model factory and adds the tested instruction-only prompt-cache policy; full-file parity with canon is not asserted." + }, + "src/flyquery/core/observability/__init__.py": { + "sha256": "1458f4346d80dff5a13873153645836d1043f232c0c1872a1be010b0a4d3c02a", + "rationale": "Canon at the referenced release has no generic core/observability module. flyquery owns its per-construction FLYQUERY_PROMPT_CACHE switch, adds no user/tool cache flags or shared OpenAI routing key, and relies on Agentic logging/observability defaults." + } + } +} diff --git a/tests/unit/test_lockstep_variants.py b/tests/unit/test_lockstep_variants.py new file mode 100644 index 00000000..f5b3b021 --- /dev/null +++ b/tests/unit/test_lockstep_variants.py @@ -0,0 +1,97 @@ +# Copyright 2026 Firefly Software Foundation +# SPDX-License-Identifier: Apache-2.0 +"""Reviewed service variants cannot exempt arbitrary or subsequently changed code.""" + +import json +import shutil +import subprocess +import sys +from pathlib import Path + +import pytest + +ROOT = Path(__file__).resolve().parents[2] +MANIFEST = "scripts/lockstep_variants.v1.json" +VARIANT = "src/flyquery/core/agents/builder.py" +AUTH = "src/flyquery/core/services/auth/agent_token_service.py" + + +@pytest.fixture +def copy_gate(tmp_path): + files = list(json.loads((ROOT / "scripts/lockstep_pins.json").read_text())) + for rel in files + ["scripts/check_lockstep.py", "scripts/lockstep_pins.json", MANIFEST]: + target = tmp_path / rel + target.parent.mkdir(parents=True, exist_ok=True) + shutil.copyfile(ROOT / rel, target) + return tmp_path + + +def _run(root): + return subprocess.run( + [sys.executable, str(root / "scripts/check_lockstep.py")], capture_output=True, text=True + ) + + +@pytest.mark.parametrize( + "change,expected", + [ + ("unknown_path", "UNKNOWN VARIANT PATH"), + ("missing_rationale", "INVALID VARIANT RATIONALE"), + ("missing_sha", "INVALID VARIANT PIN"), + ("invalid_sha", "INVALID VARIANT PIN"), + ("missing_source", "INVALID CANONICAL SOURCE"), + ("version", "UNSUPPORTED VARIANT VERSION"), + ("boolean_version", "UNSUPPORTED VARIANT VERSION"), + ], +) +def test_invalid_exception_manifest_fails_closed(copy_gate, change, expected): + path = copy_gate / MANIFEST + manifest = json.loads(path.read_text()) + if change == "unknown_path": + manifest["variants"][AUTH] = manifest["variants"][VARIANT].copy() + elif change == "missing_rationale": + manifest["variants"][VARIANT].pop("rationale") + elif change == "missing_sha": + manifest["variants"][VARIANT].pop("sha256") + elif change == "invalid_sha": + manifest["variants"][VARIANT]["sha256"] = "not-a-pin" + elif change == "missing_source": + manifest.pop("canonical_source") + elif change == "boolean_version": + manifest["version"] = True + else: + manifest["version"] = 999 + path.write_text(json.dumps(manifest)) + result = _run(copy_gate) + assert result.returncode == 1 + assert expected in result.stdout + + +def test_authentication_source_drift_still_fails(copy_gate): + path = copy_gate / AUTH + path.write_text(path.read_text() + "\n# unauthorized authentication drift\n") + result = _run(copy_gate) + assert result.returncode == 1 + assert "DRIFT: " + AUTH in result.stdout + + +def test_service_variant_source_drift_fails(copy_gate): + path = copy_gate / VARIANT + path.write_text(path.read_text() + "\n# unreviewed variant drift\n") + result = _run(copy_gate) + assert result.returncode == 1 + assert "SERVICE VARIANT DRIFT: " + VARIANT in result.stdout + + +def test_missing_variant_source_fails(copy_gate): + (copy_gate / VARIANT).unlink() + result = _run(copy_gate) + assert result.returncode == 1 + assert "MISSING: " + VARIANT in result.stdout + + +def test_missing_exception_manifest_fails(copy_gate): + (copy_gate / MANIFEST).unlink() + result = _run(copy_gate) + assert result.returncode == 1 + assert "INVALID VARIANT MANIFEST" in result.stdout diff --git a/uv.lock b/uv.lock new file mode 100644 index 00000000..a002b41b --- /dev/null +++ b/uv.lock @@ -0,0 +1,4154 @@ +version = 1 +revision = 3 +requires-python = "==3.13.*" + +[[package]] +name = "ag-ui-protocol" +version = "0.1.22" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pydantic" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e8/f7/9bf788e7d3608725d022a248a58427040f4f930ab87ddb54bd29ee4d9a51/ag_ui_protocol-0.1.22.tar.gz", hash = "sha256:d21f265284a50d9fc87ad7bcbd58f737b4b16eef7b5375f13a6e925117b52046", size = 18110, upload-time = "2026-08-31T18:20:04.334Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/be/6c/af3d577e68c9474c99600e65b2c6283772aae187edca6f0f2f5cbd9f565a/ag_ui_protocol-0.1.22-py3-none-any.whl", hash = "sha256:fca13ee7820f8f53e869c19e09ddd75826c1799b27c2adb6f2e567295433c704", size = 22068, upload-time = "2026-08-31T18:20:03.43Z" }, +] + +[[package]] +name = "aio-pika" +version = "10.1.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "aiormq" }, + { name = "yarl" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/66/2e/ea7a52d1ca58eaa132c58049c82bc7ce179f495f1014487632a579d5b73e/aio_pika-10.1.1.tar.gz", hash = "sha256:4849fa2b6404a3a5ebb1dc07237160e6b5d4323170075bbd43aa7c8df0ed8275", size = 93620, upload-time = "2026-10-10T10:33:37.631Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ae/bd/bd8437b933f5b0fc974f223ab760dc4607b0bdb3c93b9d70e6fd5aa4e758/aio_pika-10.1.1-py3-none-any.whl", hash = "sha256:ebb3158982d63a2fbc3dc18b14f70444c328218cdad77a37152f5f98985b653e", size = 59808, upload-time = "2026-10-10T10:33:36.055Z" }, +] + +[[package]] +name = "aiobotocore" +version = "3.9.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "aiohttp" }, + { name = "aioitertools" }, + { name = "botocore" }, + { name = "jmespath" }, + { name = "multidict" }, + { name = "python-dateutil" }, + { name = "wrapt" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a5/95/4f7e0453d5e81bdb1b40ecf09f135bb88e12ce27fdb3efa125022dcca5d7/aiobotocore-3.9.2.tar.gz", hash = "sha256:8e32238c5bd77717ab1ac90077ff51ab141d025528115ccc7cc9b50b2d176e5f", size = 524343, upload-time = "2026-10-01T02:01:59.522Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/09/ab/c8f982c4dfaab49200e31820a4ffe6275356f7dcaaa1024735d8f8b4e048/aiobotocore-3.9.2-py3-none-any.whl", hash = "sha256:363b4892423b272eb84afbb58000da0be6ccd0cf8a68b98438c957d05b841efc", size = 102571, upload-time = "2026-10-01T02:01:57.883Z" }, +] + +[[package]] +name = "aiofile" +version = "3.12.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "caio" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/14/31/edb06aabd8f8f0b56d659f30800795f40b93cba96be946ce179f6931e3a5/aiofile-3.12.3.tar.gz", hash = "sha256:caa6aa746b5e47e2165f7abd741b6415e49cf4d44fddc0f61844612cc3924d41", size = 21600, upload-time = "2026-08-04T22:59:27.171Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4e/79/6e45e778c4c3cab39e0937b007b720c15f76c50c6453d153282d0fcc3588/aiofile-3.12.3-py3-none-any.whl", hash = "sha256:5c1bcc9e929c50834608e8cc1a4cc1d7503eb60c15a535b779fd39e2f372c017", size = 22122, upload-time = "2026-08-04T22:59:25.838Z" }, +] + +[[package]] +name = "aiofiles" +version = "25.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/41/c3/534eac40372d8ee36ef40df62ec129bee4fdb5ad9706e58a29be53b2c970/aiofiles-25.1.0.tar.gz", hash = "sha256:a8d728f0a29de45dc521f18f07297428d56992a742f0cd2701ba86e44d23d5b2", size = 46354, upload-time = "2025-10-09T20:51:04.358Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/bc/8a/340a1555ae33d7354dbca4faa54948d76d89a27ceef032c8c3bc661d003e/aiofiles-25.1.0-py3-none-any.whl", hash = "sha256:abe311e527c862958650f9438e859c1fa7568a141b22abcd015e120e86a85695", size = 14668, upload-time = "2025-10-09T20:51:03.174Z" }, +] + +[[package]] +name = "aiohappyeyeballs" +version = "2.7.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ce/f4/eec0465c2f67b2664688d0240b3212d5196fd89e741df67ddb81f8d35658/aiohappyeyeballs-2.7.1.tar.gz", hash = "sha256:065665c041c42a5938ed220bdcd7230f22527fbec085e1853d2402c8a3615d9d", size = 24757, upload-time = "2026-07-01T17:11:55.501Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/71/43/1947f06babed6b3f1d7f38b0c767f52df66bfb2bc10b468c4a7de9eceff2/aiohappyeyeballs-2.7.1-py3-none-any.whl", hash = "sha256:9243213661e29250eb41368e5daa826fc017156c3b8a11440826b2e3ed376472", size = 15038, upload-time = "2026-07-01T17:11:54.055Z" }, +] + +[[package]] +name = "aiohttp" +version = "3.14.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "aiohappyeyeballs" }, + { name = "aiosignal" }, + { name = "attrs" }, + { name = "frozenlist" }, + { name = "multidict" }, + { name = "propcache" }, + { name = "yarl" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/6c/4c/bdccd81e9ee225b69c60e7766c9a5b05364f118f4d383713b89a682d772d/aiohttp-3.14.5.tar.gz", hash = "sha256:5558a7f5a05af9ecf744af91e5baefc436f93c9333e656c27ec253f9a6bbe178", size = 8078052, upload-time = "2026-10-11T01:05:12.408Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d3/e1/2841e020ebb7aefae5513586193e011e06313d9a6bdbd296622afbbce204/aiohttp-3.14.5-cp313-cp313-android_24_arm64_v8a.whl", hash = "sha256:9ad7e6aa38c20da1be697874349c4c273c8a03b7887169665081706398d0439a", size = 538932, upload-time = "2026-10-11T01:00:54.3Z" }, + { url = "https://files.pythonhosted.org/packages/f7/a6/7fb8ea8fe96bcc7b7c7a36d10f021d99d01a8dc8a4b3f0ddacecfad9a80e/aiohttp-3.14.5-cp313-cp313-android_24_x86_64.whl", hash = "sha256:f59c7673465908cbe506117176156c127f29f917677afceada34957179221d91", size = 553329, upload-time = "2026-10-11T01:00:56.442Z" }, + { url = "https://files.pythonhosted.org/packages/de/64/d056e3c27647dc25af1a592cf356245382ea7c808171b9dac7677afedfc8/aiohttp-3.14.5-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:1b5416552740edf07234cc9437d0706f2acb67b93c198670b1a68e1b2b587dec", size = 521367, upload-time = "2026-10-11T01:00:58.345Z" }, + { url = "https://files.pythonhosted.org/packages/3e/e4/95226147e11d4db916fd1d495dcf85af8e3816e38333e42718241196e848/aiohttp-3.14.5-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:43351bdb5e4c3cb7d1772368e988534e869a74db7778079a83782c11c69535c7", size = 528322, upload-time = "2026-10-11T01:01:00.211Z" }, + { url = "https://files.pythonhosted.org/packages/17/cd/1d3c9192cafdb51cad62b2d3ded96cff9cc8af51893210aadd448a325389/aiohttp-3.14.5-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:c8c4478bef6d57fcfda15dae461ea3c9f06aa7b257c58df3f2300174ccbb185a", size = 539874, upload-time = "2026-10-11T01:01:02.06Z" }, + { url = "https://files.pythonhosted.org/packages/f6/0c/dfa33aecc7d4d1dc75e05248f5eac5a0edf4d09e7b44d93ab62529b0c1db/aiohttp-3.14.5-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:c2c30484dd1417ef98b51021ffa2cc0d7f3c78918adaaaab7e70817335ab3e02", size = 813836, upload-time = "2026-10-11T01:01:04.01Z" }, + { url = "https://files.pythonhosted.org/packages/33/17/4a63738052d20567d55529d6daa1b9480d906fd52930fbcf6d3fbed618f0/aiohttp-3.14.5-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:dab9ac5a67c8d1f070c00fa8fccb7cbd1b8dcc1a8d6b42f37540df9b3d4cc603", size = 548070, upload-time = "2026-10-11T01:01:06.035Z" }, + { url = "https://files.pythonhosted.org/packages/15/e5/b57e58695a757fd4c02497c033fced96a69c631b13866c43d336530c9670/aiohttp-3.14.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:e1cc2bfaee8c214f06080a7c7d5772419b8a1108e8e5349236189811823fb02a", size = 545786, upload-time = "2026-10-11T01:01:07.817Z" }, + { url = "https://files.pythonhosted.org/packages/9a/68/8c2c67a3aedf46e00f3c42f04fbc6983de80d4ed5786151e33681ba45883/aiohttp-3.14.5-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:74efb69332b85675b1eabd760a8cfc2e2cf42c60607c66f88014c1bdfb40942d", size = 1886492, upload-time = "2026-10-11T01:01:09.834Z" }, + { url = "https://files.pythonhosted.org/packages/ab/4b/74aab5e8d28c62e8f795b4fe8f38cf5586fd264a9a27bd2141ef6490333d/aiohttp-3.14.5-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:42b5e616946dbaf505e2bff18c9af2cd4ef9e7ef300ee58a6e951a5b7cf147ae", size = 1870057, upload-time = "2026-10-11T01:01:12.045Z" }, + { url = "https://files.pythonhosted.org/packages/a8/f7/eafc3b1988302b1815d9fd4a21071be5c360d616c0a430d02fd92dc97688/aiohttp-3.14.5-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f9033b43f511f27547c557dcaba0177649e10a3725336ccd2cce0fdc1dc4850d", size = 1925119, upload-time = "2026-10-11T01:01:14.09Z" }, + { url = "https://files.pythonhosted.org/packages/a1/04/78d8f294f74dd570f3898ff20402349fce524176045df98ba727d6846a68/aiohttp-3.14.5-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:15a310d3c71398e3d7bfc93a1a73fbe664315cd9e9016b8efc1cff85eeab7155", size = 2053137, upload-time = "2026-10-11T01:01:16.344Z" }, + { url = "https://files.pythonhosted.org/packages/32/51/395d225ef36f5a50d8e548dcd3141bfdbcd31fb6eed859022c573d2c4d66/aiohttp-3.14.5-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1ffa3a523a36d8628f98c06492ae16a31a23d14c0b4ec721757b477319f656d6", size = 1911038, upload-time = "2026-10-11T01:01:18.653Z" }, + { url = "https://files.pythonhosted.org/packages/ff/a4/2aec1aa06d82e8a244843b5dae31d78061e5e76744270a86dd0ee051c889/aiohttp-3.14.5-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:5fb6a6e919bfb703227bc1ce6579281b84b1a2ba57deb9794dfdbec7dcd1e40c", size = 1702205, upload-time = "2026-10-11T01:01:20.904Z" }, + { url = "https://files.pythonhosted.org/packages/16/27/6051bfde7b6f418f70edd60d655fa426abb3355fa0981764739d87ecf160/aiohttp-3.14.5-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:43e1b7994a8b038125f722bff07492ef501110722c2727c408995d9fb864c421", size = 1848588, upload-time = "2026-10-11T01:01:22.918Z" }, + { url = "https://files.pythonhosted.org/packages/9e/44/55efc06fc26c4e6e1c095f231b4c222bf2d86d64a8eebbc24b2bb5958ea8/aiohttp-3.14.5-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:5f3e96071686755d9cd3600c3880183eb94b012178e92746d68101800f0ed8a3", size = 1887540, upload-time = "2026-10-11T01:01:25.278Z" }, + { url = "https://files.pythonhosted.org/packages/48/dc/1502bfdc2a65760d386ac6a00090b0addaa8a3c9c60b3f8127fad3a9afb2/aiohttp-3.14.5-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:cd88b01f3d37b7a2a34f91d98f14720206f1ea3d540843fab2d649dd5fb91fec", size = 1895030, upload-time = "2026-10-11T01:01:27.316Z" }, + { url = "https://files.pythonhosted.org/packages/93/7e/44174bb6288264418c9eec07a5e35180969c0d5a796c7af544db3cb8a33a/aiohttp-3.14.5-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:f2ed8b64dc0c651c0f5a9c926777719770021251b8f336d97c4b80b660836ce1", size = 1693244, upload-time = "2026-10-11T01:01:29.39Z" }, + { url = "https://files.pythonhosted.org/packages/47/dd/b507d64e50db23888582fff08eda13998b12f9dea70c072edaac19218380/aiohttp-3.14.5-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:a9918e58faf62ba2c7147927d06057aec78f42475aff5048047ec47e7265a600", size = 1926308, upload-time = "2026-10-11T01:01:31.634Z" }, + { url = "https://files.pythonhosted.org/packages/98/4b/5b51b4f63e3f2793151f4aea49c48fe1e00baeb7cec9c7a206de499f8de0/aiohttp-3.14.5-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:42f320d4a5b00b9af0bddcfec5407dc6f2d9816f006b2f79ebbaa31f16895df3", size = 1888406, upload-time = "2026-10-11T01:01:33.715Z" }, + { url = "https://files.pythonhosted.org/packages/ff/13/d5e818a5eaba9f822016727299f41c0e1075799f82a6433ec508a93ab867/aiohttp-3.14.5-cp313-cp313-win32.whl", hash = "sha256:3ae800a20947e2c2e53088047d021e6bf7d51560cc49f6a0737a1f79d2e3a13c", size = 479970, upload-time = "2026-10-11T01:01:35.677Z" }, + { url = "https://files.pythonhosted.org/packages/8d/d0/8eca2c65aa467320990d78fb2005f38ed3588944280c39ff9deb6423fef1/aiohttp-3.14.5-cp313-cp313-win_amd64.whl", hash = "sha256:d05e94cdfe0d15d0206f970722d2554780ce562787b21b218b275447f8751319", size = 505985, upload-time = "2026-10-11T01:01:37.574Z" }, + { url = "https://files.pythonhosted.org/packages/7a/f8/4cdd65305d2fca14b886bea9ed2abb1fe726287872524e56e3d26692b47d/aiohttp-3.14.5-cp313-cp313-win_arm64.whl", hash = "sha256:f001b571ead90ca1770f1e616db255351a1703317f20374c361ef22f12c06d09", size = 487629, upload-time = "2026-10-11T01:01:39.477Z" }, + { url = "https://files.pythonhosted.org/packages/68/30/173960c42b05a6c59f7558e4b12a4b0d9ba376cf6aa9bde7f9e08a30ca8d/aiohttp-3.14.5-py3-none-any.whl", hash = "sha256:efc21a454892828368b11c2c780de0ff8bc991f73f6b99c6b66e56205470929b", size = 279517, upload-time = "2026-10-11T01:05:08.523Z" }, +] + +[[package]] +name = "aioitertools" +version = "0.13.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/fd/3c/53c4a17a05fb9ea2313ee1777ff53f5e001aefd5cc85aa2f4c2d982e1e38/aioitertools-0.13.0.tar.gz", hash = "sha256:620bd241acc0bbb9ec819f1ab215866871b4bbd1f73836a55f799200ee86950c", size = 19322, upload-time = "2025-11-06T22:17:07.609Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/10/a1/510b0a7fadc6f43a6ce50152e69dbd86415240835868bb0bd9b5b88b1e06/aioitertools-0.13.0-py3-none-any.whl", hash = "sha256:0be0292b856f08dfac90e31f4739432f4cb6d7520ab9eb73e143f4f2fa5259be", size = 24182, upload-time = "2025-11-06T22:17:06.502Z" }, +] + +[[package]] +name = "aiokafka" +version = "0.14.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "async-timeout" }, + { name = "packaging" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/89/5f/dfc1180fd22d1acdc91949ec36e97199c43742dacb057cb8efed3679ed04/aiokafka-0.14.0.tar.gz", hash = "sha256:8ffdc945798ba4d3d132b705d4244d0a1f493925efb57c637a2ca88ee82794e1", size = 601374, upload-time = "2026-04-29T10:43:03.574Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/30/b0/c9384541b2e4cc52a16402fc53fb9d44af0d78d37954cf8c7271c376ad47/aiokafka-0.14.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:db16e43fac4c1c5006131046c1bf370c580d6ac4495a10ac7778245710943179", size = 345859, upload-time = "2026-04-29T10:42:45.449Z" }, + { url = "https://files.pythonhosted.org/packages/7f/d1/fc266d9f4ffba4f197356c6ffdfbb0fe32e7cb874e240f299935d058ac06/aiokafka-0.14.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:32a8e91d88cf3ccf0778927715610d6579888c5f4748db4c2022cda25d628a48", size = 348284, upload-time = "2026-04-29T10:42:47.104Z" }, + { url = "https://files.pythonhosted.org/packages/b2/8e/0c4c270786dac79f3fca74c6166c3a25b61b0d26132be0d69f0d7f206f0a/aiokafka-0.14.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:aad4a575a506e7784e25e430f27026fe2f4378560b21b7f4e8c9a54f0d06eaee", size = 1117867, upload-time = "2026-04-29T10:42:48.394Z" }, + { url = "https://files.pythonhosted.org/packages/9d/7f/3b89fbd0a3be9edfd5b51e20bb5cd695c851219b63c501c051cf84367fa9/aiokafka-0.14.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:75e4a003502c9c3b5c705fa7c00d634ba146bf38fa5d525b80bb6ff6e3e779fe", size = 1108860, upload-time = "2026-04-29T10:42:50.249Z" }, + { url = "https://files.pythonhosted.org/packages/b3/59/849aba75cff93277bf6bf8b630de79e902949ff7ec48e4b12a64e6e32cae/aiokafka-0.14.0-cp313-cp313-win32.whl", hash = "sha256:a128e213cbc2bce0ea3db65a68920e52cebeeb8209bf001ac7aa022a8bd54d7d", size = 310889, upload-time = "2026-04-29T10:42:52.038Z" }, + { url = "https://files.pythonhosted.org/packages/c4/e5/52eab8f8515d23da7b5d90e2c5ba10eab9494a0314f749e3f73e003f4a50/aiokafka-0.14.0-cp313-cp313-win_amd64.whl", hash = "sha256:d6fa16bef3544be87bd1a7a8317b9d85e3da59f3202326d9ff22735ed052746e", size = 329470, upload-time = "2026-04-29T10:42:53.536Z" }, +] + +[[package]] +name = "aiormq" +version = "7.2.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pamqp" }, + { name = "yarl" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/2d/15/475b169da189c38ce4ba4ebec0cd4ff859f3e0dc17e8abc14552f1b7f456/aiormq-7.2.2.tar.gz", hash = "sha256:1434fba7efc56523684506d3118008aae88ab38383d92da3f9f37d9859256784", size = 77592, upload-time = "2026-10-10T10:29:05.82Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4a/71/937ac2016ff02f5a72745318e83ff9d83684a4b2fb8f45e54210b9ffa233/aiormq-7.2.2-py3-none-any.whl", hash = "sha256:977622e8d3ba8d7ced7fd3a74217d24e359975edd920d4c102f9ec183fbc40a4", size = 39769, upload-time = "2026-10-10T10:29:04.198Z" }, +] + +[[package]] +name = "aiosignal" +version = "1.4.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "frozenlist" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/61/62/06741b579156360248d1ec624842ad0edf697050bbaf7c3e46394e106ad1/aiosignal-1.4.0.tar.gz", hash = "sha256:f47eecd9468083c2029cc99945502cb7708b082c232f9aca65da147157b251c7", size = 25007, upload-time = "2025-07-03T22:54:43.528Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl", hash = "sha256:053243f8b92b990551949e63930a839ff0cf0b0ebbe0597b0f3fb19e1a0fe82e", size = 7490, upload-time = "2025-07-03T22:54:42.156Z" }, +] + +[[package]] +name = "aiosqlite" +version = "0.22.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/4e/8a/64761f4005f17809769d23e518d915db74e6310474e733e3593cfc854ef1/aiosqlite-0.22.1.tar.gz", hash = "sha256:043e0bd78d32888c0a9ca90fc788b38796843360c855a7262a532813133a0650", size = 14821, upload-time = "2025-12-23T19:25:43.997Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/00/b7/e3bf5133d697a08128598c8d0abc5e16377b51465a33756de24fa7dee953/aiosqlite-0.22.1-py3-none-any.whl", hash = "sha256:21c002eb13823fad740196c5a2e9d8e62f6243bd9e7e4a1f87fb5e44ecb4fceb", size = 17405, upload-time = "2025-12-23T19:25:42.139Z" }, +] + +[[package]] +name = "alembic" +version = "1.20.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mako" }, + { name = "sqlalchemy" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ed/aa/02910bdb8e2f1444f6654d5b296cd827d126f82209050ee7b1000f92ac4b/alembic-1.20.0.tar.gz", hash = "sha256:db505480647bc60386c5369402f4a57a506b7539c9e9ef5e270d45cbbe4939bf", size = 2093272, upload-time = "2026-09-11T19:09:11.126Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3f/27/78a89b55b0904d222183164e079b4ca56208e94eff1d35ad1f1ad5be9b06/alembic-1.20.0-py3-none-any.whl", hash = "sha256:77eb101048d95f982c0353e9233404889dcd7a6fc244c107836c0e2fc9cf7d9d", size = 268719, upload-time = "2026-09-11T19:09:12.88Z" }, +] + +[[package]] +name = "annotated-doc" +version = "0.0.5" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/5a/8e/38aa427ed5402449e226975b649c5dc73ccadfefeb95e6aecb8f8ea4b6b6/annotated_doc-0.0.5.tar.gz", hash = "sha256:c7e58ce09192557605d8bbd92836d7e1d520ac9580096042c0bfd197efacf1bb", size = 10758, upload-time = "2026-07-28T13:50:58.129Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3e/30/e900b21425a860e195f32e37657aa1f7c7f2b1bfb26f03ca209b90933c06/annotated_doc-0.0.5-py3-none-any.whl", hash = "sha256:117bac03a25ede5df5440e855b32d556049ca169ead221505badf432fed4b101", size = 5302, upload-time = "2026-07-28T13:50:57.239Z" }, +] + +[[package]] +name = "annotated-types" +version = "0.8.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/5f/56/a8120250d128bed162cd73c76d45f6ef9991f3e068f62a8ee060afa3104a/annotated_types-0.8.0.tar.gz", hash = "sha256:13b2beaad985e05e2d6407ee4c4f35590b11f8d693a258a561055cac8f64cab7", size = 15893, upload-time = "2026-07-23T20:16:13.995Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/99/91/8acff4f5e50511b911bbccb72b8628a49c68ce14148cd9f6431094859a90/annotated_types-0.8.0-py3-none-any.whl", hash = "sha256:f072f4d804ea359e4eaf198b1af7a8b0943881a87f31bb764f8bf219bb9419e0", size = 13427, upload-time = "2026-07-23T20:16:12.938Z" }, +] + +[[package]] +name = "anthropic" +version = "1.14.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anyio" }, + { name = "docstring-parser" }, + { name = "httpx2" }, + { name = "jiter" }, + { name = "opentelemetry-api" }, + { name = "pydantic" }, + { name = "sniffio" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/0f/c2/be99fac19b24c22b00d2a63ac1756b203bd3058ff54a14028c43b9f33116/anthropic-1.14.0.tar.gz", hash = "sha256:d9284895864a8457ed87f0accc51fd488ad9743952e597c814e7dc9d78ac8e38", size = 1715378, upload-time = "2026-10-14T17:13:33.508Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5d/66/c395049fa6bf20b7f244adc8b7466f86a416b11f03528fa325868483de3a/anthropic-1.14.0-py3-none-any.whl", hash = "sha256:abd787048378abfabeebbad917ae0f9eae1eb4dfaa0a754096b5eea02dcf8c12", size = 2043565, upload-time = "2026-10-14T17:13:35.513Z" }, +] + +[[package]] +name = "anyio" +version = "4.15.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "idna" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a9/d2/f4d173e22df740bc37b1db102b386ba719b66e95b0f0d751f556b387e6d2/anyio-4.15.1.tar.gz", hash = "sha256:9f28306018cbd6d329e64a36d58256edff76dd996fe423bc957326e578b82a94", size = 276966, upload-time = "2026-09-05T10:42:39.44Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/12/b8/4bd346e22b28902df4d651910f5242c28d84e4a5c2435ca5c3f797ed7e2e/anyio-4.15.1-py3-none-any.whl", hash = "sha256:6152fdbbf9a77fdec97731721bebf7c4c44f7c29b424b0065826173efc7ed101", size = 132079, upload-time = "2026-09-05T10:42:37.923Z" }, +] + +[[package]] +name = "argcomplete" +version = "3.7.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/87/6f/5a73f04007ca950701765949209f068da628bd11f9c2da287278ce91e0ee/argcomplete-3.7.2.tar.gz", hash = "sha256:aad8b69a0b9969edb62db0d1752354c0d50717b10e0cbb00e2a958381b9fc6b9", size = 74473, upload-time = "2026-08-06T04:53:21.662Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/46/bd/551ee6af426af84ca33e02622be722925c196608e9127d731ef17c47f06e/argcomplete-3.7.2-py3-none-any.whl", hash = "sha256:6029205678bdd9c1c728a155f5f9ecf5812393f969eef58807641a2bc2aa5b19", size = 43294, upload-time = "2026-08-06T04:53:20.246Z" }, +] + +[[package]] +name = "argon2-cffi" +version = "25.1.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "argon2-cffi-bindings" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/0e/89/ce5af8a7d472a67cc819d5d998aa8c82c5d860608c4db9f46f1162d7dab9/argon2_cffi-25.1.0.tar.gz", hash = "sha256:694ae5cc8a42f4c4e2bf2ca0e64e51e23a040c6a517a85074683d3959e1346c1", size = 45706, upload-time = "2025-06-03T06:55:32.073Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4f/d3/a8b22fa575b297cd6e3e3b0155c7e25db170edf1c74783d6a31a2490b8d9/argon2_cffi-25.1.0-py3-none-any.whl", hash = "sha256:fdc8b074db390fccb6eb4a3604ae7231f219aa669a2652e0f20e16ba513d5741", size = 14657, upload-time = "2025-06-03T06:55:30.804Z" }, +] + +[[package]] +name = "argon2-cffi-bindings" +version = "26.1.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cffi" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/0b/43/bb8b6e8708d49a5ab36781333af092d9f483b198a2710d01281204640055/argon2_cffi_bindings-26.1.0.tar.gz", hash = "sha256:63505c71542a44b68b1e38060450fb006404170da375feb31af153e7f9c6205d", size = 1790807, upload-time = "2026-08-20T07:44:22.492Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e7/d2/0ae991f1b2181e5be49007c574710a800ad36c2978683addb3e67c474e55/argon2_cffi_bindings-26.1.0-cp310-abi3-macosx_11_0_arm64.whl", hash = "sha256:21ca0396fe5ec995dd54431c32698189666f9224810acfa752e50d2bd94d9df2", size = 25521, upload-time = "2026-08-20T07:32:43.019Z" }, + { url = "https://files.pythonhosted.org/packages/7e/e4/ad91d8297638aa2258aad4501c306aca99480dfe76ccd638173fa3702db9/argon2_cffi_bindings-26.1.0-cp310-abi3-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:78de2d65e0b9ea7ce9d1b1c3e87297b2d7305a02c266ee2a2d6910daddd7ee69", size = 27177, upload-time = "2026-08-20T07:32:44.158Z" }, + { url = "https://files.pythonhosted.org/packages/6f/86/5363df11b86d02cf3662208e7406496327649cc90eb365bf6f4e8a54a41f/argon2_cffi_bindings-26.1.0-cp310-abi3-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:27f1821903e2ceadcb88ec2b45ef190897b7682449c772f4d9b53e42c520cf29", size = 26597, upload-time = "2026-08-20T07:32:45.172Z" }, + { url = "https://files.pythonhosted.org/packages/f4/b5/a14dcc592652347dad23ee93b278a4da5d2a25c9ed3ebd10d68eea823a4f/argon2_cffi_bindings-26.1.0-cp310-abi3-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:d88e5f7e60f28ae0b0cc6b2f16c43e87cd642a196a86f85e0d8bb6fe016fc16d", size = 27403, upload-time = "2026-08-20T07:32:46.13Z" }, + { url = "https://files.pythonhosted.org/packages/b3/81/b4a20d4902af7f796390bf9245ff83c5217dfa7367efa1d14986956c482b/argon2_cffi_bindings-26.1.0-cp310-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:34b7d9c24a4165a2c61cc8ae11d44d48c9ce2830fb536cb7914e11fdd9962728", size = 27132, upload-time = "2026-08-20T07:32:47.13Z" }, + { url = "https://files.pythonhosted.org/packages/7e/1b/c8de358af07b1c490e0fcb863ef98e46ddb486e45567aca5a60bd68d9daa/argon2_cffi_bindings-26.1.0-cp310-abi3-musllinux_1_2_riscv64.whl", hash = "sha256:224865cbbcb7a2bd1356741dff12b0134df726b6d44bb7b500df8e303cbd9e81", size = 27588, upload-time = "2026-08-20T07:32:48.087Z" }, + { url = "https://files.pythonhosted.org/packages/48/2f/7ee62a6e79f9309f9d9982d301b22a00010adb580c05c8109b94d7b33de0/argon2_cffi_bindings-26.1.0-cp310-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:ffff613aaa9ce6236766e2fc6dc560bb5abde7a2e2416e3db1f9ae395a2b4dd4", size = 26785, upload-time = "2026-08-20T07:32:48.977Z" }, + { url = "https://files.pythonhosted.org/packages/e9/10/960d0ee93d4897741bcaf4799c697dae2d81499f66fd1ed042a7dd54c1f4/argon2_cffi_bindings-26.1.0-cp310-abi3-win32.whl", hash = "sha256:a86c069c91a747a2c4e5c51473590aeb48172fff9b2130d23729a42d98665ecb", size = 23898, upload-time = "2026-08-20T07:32:50.114Z" }, + { url = "https://files.pythonhosted.org/packages/6d/3a/0cc14a05810e6add9bce5e87693334baa2222de5f647fa31781885b6573f/argon2_cffi_bindings-26.1.0-cp310-abi3-win_amd64.whl", hash = "sha256:2c36ff87b5dfaa477d0bd51e9d7f6abdae7c8955d2983c97419085d842154b3e", size = 25730, upload-time = "2026-08-20T07:32:51.091Z" }, + { url = "https://files.pythonhosted.org/packages/4e/db/d83cf2af140547f0b9cdaece05b2dc2dcbf991be4667331d073eff771435/argon2_cffi_bindings-26.1.0-cp310-abi3-win_arm64.whl", hash = "sha256:f9c4420a7a864fe1b86ce35befc95b8e39fb852493b81cf798671ddc265de638", size = 24478, upload-time = "2026-08-20T07:32:52.111Z" }, + { url = "https://files.pythonhosted.org/packages/bb/5f/f652055e18d2627e2eed94c7f31a792127cfe38df786635395d742321674/argon2_cffi_bindings-26.1.0-cp313-cp313-pyemscripten_2025_0_wasm32.whl", hash = "sha256:af11ac37a7c53dc16cb7950a6190851b0870fe218b6c60c0bb7ac355234e3083", size = 15434, upload-time = "2026-08-20T07:32:53.143Z" }, +] + +[[package]] +name = "asgiref" +version = "3.12.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e6/26/3b59f2bdae5f640389becb1f673cded775287f5fc4f816309d9ca9a3f93d/asgiref-3.12.1.tar.gz", hash = "sha256:59dcb51c272ad209d59bed5708a64a333083e86017d7fcdd67498eeab7784340", size = 42378, upload-time = "2026-07-14T09:56:18.087Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c0/1b/54f4ad77cd8a584fa70746c47df988e002cf1ee1eba43364d46f87803647/asgiref-3.12.1-py3-none-any.whl", hash = "sha256:fe386d1c2bff7259ea95929266d12a8cf9a8b5a1c2598402967d8792e7a7c094", size = 25478, upload-time = "2026-07-14T09:56:16.926Z" }, +] + +[[package]] +name = "async-timeout" +version = "5.0.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a5/ae/136395dfbfe00dfc94da3f3e136d0b13f394cba8f4841120e34226265780/async_timeout-5.0.1.tar.gz", hash = "sha256:d9321a7a3d5a6a5e187e824d2fa0793ce379a202935782d555d6e9d2735677d3", size = 9274, upload-time = "2024-11-06T16:41:39.6Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fe/ba/e2081de779ca30d473f21f5b30e0e737c438205440784c7dfc81efc2b029/async_timeout-5.0.1-py3-none-any.whl", hash = "sha256:39e3809566ff85354557ec2398b55e096c8364bacac9405a7a1fa429e77fe76c", size = 6233, upload-time = "2024-11-06T16:41:37.9Z" }, +] + +[[package]] +name = "asyncpg" +version = "0.32.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/80/4e/59dc964f962f09e3ed472e5d2d3ba670a41a2be25080dc62ab3db507ff5e/asyncpg-0.32.0.tar.gz", hash = "sha256:45e64e56714d888330b884aad1dfb363d0bf43fb343e3d1a8968525f3bade478", size = 1075156, upload-time = "2026-10-06T20:32:40.251Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6a/ee/b6b5870b51e004880d9a216313ea7d4f180961c5869f32e58e8cb9b71e96/asyncpg-0.32.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:c032869fd9c3c9fd1a86ad67e53f63906159068087c2674dd1e19be3cffff571", size = 683362, upload-time = "2026-10-06T20:31:08.078Z" }, + { url = "https://files.pythonhosted.org/packages/d8/8b/1f450742bc6eab0c015cae26aef94fac2ff29433e3f18a019126c3912c49/asyncpg-0.32.0-cp313-cp313-macosx_11_0_x86_64.whl", hash = "sha256:0c764dce865b41878396e736d4d2c6c6ce3a8e1b61d1f6bb292e30d265ae7ca6", size = 706652, upload-time = "2026-10-06T20:31:09.524Z" }, + { url = "https://files.pythonhosted.org/packages/05/dc/13f3c0ef7e867bafdccd470e5cfae1f2fd9a7085c771546bd4b94018e043/asyncpg-0.32.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:925ce1cc54419d468bfb77632d91e5e2be5be0fdf9d43680c68fe7cedf87051a", size = 3698244, upload-time = "2026-10-06T20:31:10.894Z" }, + { url = "https://files.pythonhosted.org/packages/1f/64/b00ef3fc0d861c28a1937f08d2c7f6e6119c152b414d50fa800c3aee83b5/asyncpg-0.32.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4cec40b66a36b14921c155db78631cd96ed00e225fdf38dd5532e9aef350a498", size = 3801314, upload-time = "2026-10-06T20:31:12.964Z" }, + { url = "https://files.pythonhosted.org/packages/de/1b/215067d97a13206ce1565da920ddbefe5a1e5f89903e6de862fdd0a034a1/asyncpg-0.32.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:1fba43a9a230ce4d2b4593b761b8e03630c613c282b24566e27c7f53695273b1", size = 3598650, upload-time = "2026-10-06T20:31:14.797Z" }, + { url = "https://files.pythonhosted.org/packages/37/45/2bfcb5c9b04df3f17fd367647c9f3ee9fe64ea0612b509a6b1832afcedae/asyncpg-0.32.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:c7a8f7fa8304f757e23cccb8ffef6a6fce0b6320ffc565a884ee3cd0dfad1ac5", size = 3762739, upload-time = "2026-10-06T20:31:17.186Z" }, + { url = "https://files.pythonhosted.org/packages/08/45/e6b37756e6c8979fe070e9821654244f38319493f5b0589e549d9a40c001/asyncpg-0.32.0-cp313-cp313-win32.whl", hash = "sha256:d809399022e244eb86bb532a4ae9a45746e0f6dc5154fd6aa2f6ad63fa3f5373", size = 551065, upload-time = "2026-10-06T20:31:18.812Z" }, + { url = "https://files.pythonhosted.org/packages/ee/46/0a4e92f4310da644b28595b22ef2fff1ffd3dab84953dc8b4c5eef72b764/asyncpg-0.32.0-cp313-cp313-win_amd64.whl", hash = "sha256:38640b106705fef8b0f46cdb5fd9dcf6a638eed5cadb0f441714a21405ca8a0a", size = 625571, upload-time = "2026-10-06T20:31:20.571Z" }, + { url = "https://files.pythonhosted.org/packages/35/f4/48ed4b580b99b1fabc480c707229bb8f1e4ba0f5b24a50822b339efe1e48/asyncpg-0.32.0-cp313-cp313-win_arm64.whl", hash = "sha256:d78145adedfe51dc2fda623e6602cf816dabc2eafcff693bd50484321a1c9034", size = 576342, upload-time = "2026-10-06T20:31:22.29Z" }, +] + +[[package]] +name = "attrs" +version = "26.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/9a/8e/82a0fe20a541c03148528be8cac2408564a6c9a0cc7e9171802bc1d26985/attrs-26.1.0.tar.gz", hash = "sha256:d03ceb89cb322a8fd706d4fb91940737b6642aa36998fe130a9bc96c985eff32", size = 952055, upload-time = "2026-03-19T14:22:25.026Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/64/b4/17d4b0b2a2dc85a6df63d1157e028ed19f90d4cd97c36717afef2bc2f395/attrs-26.1.0-py3-none-any.whl", hash = "sha256:c647aa4a12dfbad9333ca4e71fe62ddc36f4e63b2d260a37a8b83d2f043ac309", size = 67548, upload-time = "2026-03-19T14:22:23.645Z" }, +] + +[[package]] +name = "authlib" +version = "1.9.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cryptography" }, + { name = "joserfc" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c9/dc/087c08741a98d234c9b98beef8a28d3c309f814d14b6156422c5815bf6d6/authlib-1.9.1.tar.gz", hash = "sha256:5c7d9848f47cac340f060f76ae0bc09b59f5c8e89cc1bb032d4370a0c55b5974", size = 182700, upload-time = "2026-10-14T14:17:52.307Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/39/44/a46089266de32a0d809023b6bf31b80a1f26a46954446a7ce695a565cbea/authlib-1.9.1-py2.py3-none-any.whl", hash = "sha256:8b9be8b1e5174dcbf5520e984f1a22dc2edae5b6e40a61d4cedbf86b97e9e69b", size = 266042, upload-time = "2026-10-14T14:17:50.695Z" }, +] + +[[package]] +name = "azure-core" +version = "1.41.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "requests" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a6/f3/b416179e408990df5db0d516283022dde0f5d0111d98c1a848e41853e81c/azure_core-1.41.0.tar.gz", hash = "sha256:f46ff5dfcd230f25cf1c19e8a34b8dc08a337b2503e268bb600a16c00db8ad5a", size = 381042, upload-time = "2026-05-07T23:30:54.302Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5b/db/325c6d7312d2200251c52323878281045aaffcb5586612296484e4280eaa/azure_core-1.41.0-py3-none-any.whl", hash = "sha256:522b4011e8180b1a3dcd2024396a4e7fe9ac37fb8597db47163d230b5efe892d", size = 220920, upload-time = "2026-05-07T23:30:56.357Z" }, +] + +[[package]] +name = "azure-storage-blob" +version = "12.31.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "azure-core" }, + { name = "cryptography" }, + { name = "isodate" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/26/ca/5299cedef5957dd838d4dc46f97bea37335bb39f6610d72b27e1a3317650/azure_storage_blob-12.31.0.tar.gz", hash = "sha256:997b393cfcbdc4b186d5911790d91f80387f7edc12c4d73eab963a2d26e5b2a9", size = 670868, upload-time = "2026-09-30T21:23:22.837Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9b/57/d1f45fbccc0dfbe6b6db7e5fa06199e35219c712f3743677bec1b4e7d78b/azure_storage_blob-12.31.0-py3-none-any.whl", hash = "sha256:0c0cb601d3462491d09ea96023cd791bb9dd4b173bf950daf3cff34ff47ba5b5", size = 455738, upload-time = "2026-09-30T21:23:24.944Z" }, +] + +[[package]] +name = "bcrypt" +version = "5.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d4/36/3329e2518d70ad8e2e5817d5a4cac6bba05a47767ec416c7d020a965f408/bcrypt-5.0.0.tar.gz", hash = "sha256:f748f7c2d6fd375cc93d3fba7ef4a9e3a092421b8dbf34d8d4dc06be9492dfdd", size = 25386, upload-time = "2025-09-25T19:50:47.829Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/13/85/3e65e01985fddf25b64ca67275bb5bdb4040bd1a53b66d355c6c37c8a680/bcrypt-5.0.0-cp313-cp313t-macosx_10_12_universal2.whl", hash = "sha256:f3c08197f3039bec79cee59a606d62b96b16669cff3949f21e74796b6e3cd2be", size = 481806, upload-time = "2025-09-25T19:49:05.102Z" }, + { url = "https://files.pythonhosted.org/packages/44/dc/01eb79f12b177017a726cbf78330eb0eb442fae0e7b3dfd84ea2849552f3/bcrypt-5.0.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:200af71bc25f22006f4069060c88ed36f8aa4ff7f53e67ff04d2ab3f1e79a5b2", size = 268626, upload-time = "2025-09-25T19:49:06.723Z" }, + { url = "https://files.pythonhosted.org/packages/8c/cf/e82388ad5959c40d6afd94fb4743cc077129d45b952d46bdc3180310e2df/bcrypt-5.0.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:baade0a5657654c2984468efb7d6c110db87ea63ef5a4b54732e7e337253e44f", size = 271853, upload-time = "2025-09-25T19:49:08.028Z" }, + { url = "https://files.pythonhosted.org/packages/ec/86/7134b9dae7cf0efa85671651341f6afa695857fae172615e960fb6a466fa/bcrypt-5.0.0-cp313-cp313t-manylinux_2_28_aarch64.whl", hash = "sha256:c58b56cdfb03202b3bcc9fd8daee8e8e9b6d7e3163aa97c631dfcfcc24d36c86", size = 269793, upload-time = "2025-09-25T19:49:09.727Z" }, + { url = "https://files.pythonhosted.org/packages/cc/82/6296688ac1b9e503d034e7d0614d56e80c5d1a08402ff856a4549cb59207/bcrypt-5.0.0-cp313-cp313t-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:4bfd2a34de661f34d0bda43c3e4e79df586e4716ef401fe31ea39d69d581ef23", size = 289930, upload-time = "2025-09-25T19:49:11.204Z" }, + { url = "https://files.pythonhosted.org/packages/d1/18/884a44aa47f2a3b88dd09bc05a1e40b57878ecd111d17e5bba6f09f8bb77/bcrypt-5.0.0-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:ed2e1365e31fc73f1825fa830f1c8f8917ca1b3ca6185773b349c20fd606cec2", size = 272194, upload-time = "2025-09-25T19:49:12.524Z" }, + { url = "https://files.pythonhosted.org/packages/0e/8f/371a3ab33c6982070b674f1788e05b656cfbf5685894acbfef0c65483a59/bcrypt-5.0.0-cp313-cp313t-manylinux_2_34_aarch64.whl", hash = "sha256:83e787d7a84dbbfba6f250dd7a5efd689e935f03dd83b0f919d39349e1f23f83", size = 269381, upload-time = "2025-09-25T19:49:14.308Z" }, + { url = "https://files.pythonhosted.org/packages/b1/34/7e4e6abb7a8778db6422e88b1f06eb07c47682313997ee8a8f9352e5a6f1/bcrypt-5.0.0-cp313-cp313t-manylinux_2_34_x86_64.whl", hash = "sha256:137c5156524328a24b9fac1cb5db0ba618bc97d11970b39184c1d87dc4bf1746", size = 271750, upload-time = "2025-09-25T19:49:15.584Z" }, + { url = "https://files.pythonhosted.org/packages/c0/1b/54f416be2499bd72123c70d98d36c6cd61a4e33d9b89562c22481c81bb30/bcrypt-5.0.0-cp313-cp313t-musllinux_1_1_aarch64.whl", hash = "sha256:38cac74101777a6a7d3b3e3cfefa57089b5ada650dce2baf0cbdd9d65db22a9e", size = 303757, upload-time = "2025-09-25T19:49:17.244Z" }, + { url = "https://files.pythonhosted.org/packages/13/62/062c24c7bcf9d2826a1a843d0d605c65a755bc98002923d01fd61270705a/bcrypt-5.0.0-cp313-cp313t-musllinux_1_1_x86_64.whl", hash = "sha256:d8d65b564ec849643d9f7ea05c6d9f0cd7ca23bdd4ac0c2dbef1104ab504543d", size = 306740, upload-time = "2025-09-25T19:49:18.693Z" }, + { url = "https://files.pythonhosted.org/packages/d5/c8/1fdbfc8c0f20875b6b4020f3c7dc447b8de60aa0be5faaf009d24242aec9/bcrypt-5.0.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:741449132f64b3524e95cd30e5cd3343006ce146088f074f31ab26b94e6c75ba", size = 334197, upload-time = "2025-09-25T19:49:20.523Z" }, + { url = "https://files.pythonhosted.org/packages/a6/c1/8b84545382d75bef226fbc6588af0f7b7d095f7cd6a670b42a86243183cd/bcrypt-5.0.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:212139484ab3207b1f0c00633d3be92fef3c5f0af17cad155679d03ff2ee1e41", size = 352974, upload-time = "2025-09-25T19:49:22.254Z" }, + { url = "https://files.pythonhosted.org/packages/10/a6/ffb49d4254ed085e62e3e5dd05982b4393e32fe1e49bb1130186617c29cd/bcrypt-5.0.0-cp313-cp313t-win32.whl", hash = "sha256:9d52ed507c2488eddd6a95bccee4e808d3234fa78dd370e24bac65a21212b861", size = 148498, upload-time = "2025-09-25T19:49:24.134Z" }, + { url = "https://files.pythonhosted.org/packages/48/a9/259559edc85258b6d5fc5471a62a3299a6aa37a6611a169756bf4689323c/bcrypt-5.0.0-cp313-cp313t-win_amd64.whl", hash = "sha256:f6984a24db30548fd39a44360532898c33528b74aedf81c26cf29c51ee47057e", size = 145853, upload-time = "2025-09-25T19:49:25.702Z" }, + { url = "https://files.pythonhosted.org/packages/2d/df/9714173403c7e8b245acf8e4be8876aac64a209d1b392af457c79e60492e/bcrypt-5.0.0-cp313-cp313t-win_arm64.whl", hash = "sha256:9fffdb387abe6aa775af36ef16f55e318dcda4194ddbf82007a6f21da29de8f5", size = 139626, upload-time = "2025-09-25T19:49:26.928Z" }, + { url = "https://files.pythonhosted.org/packages/84/29/6237f151fbfe295fe3e074ecc6d44228faa1e842a81f6d34a02937ee1736/bcrypt-5.0.0-cp38-abi3-macosx_10_12_universal2.whl", hash = "sha256:fc746432b951e92b58317af8e0ca746efe93e66555f1b40888865ef5bf56446b", size = 494553, upload-time = "2025-09-25T19:49:49.006Z" }, + { url = "https://files.pythonhosted.org/packages/45/b6/4c1205dde5e464ea3bd88e8742e19f899c16fa8916fb8510a851fae985b5/bcrypt-5.0.0-cp38-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:c2388ca94ffee269b6038d48747f4ce8df0ffbea43f31abfa18ac72f0218effb", size = 275009, upload-time = "2025-09-25T19:49:50.581Z" }, + { url = "https://files.pythonhosted.org/packages/3b/71/427945e6ead72ccffe77894b2655b695ccf14ae1866cd977e185d606dd2f/bcrypt-5.0.0-cp38-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:560ddb6ec730386e7b3b26b8b4c88197aaed924430e7b74666a586ac997249ef", size = 278029, upload-time = "2025-09-25T19:49:52.533Z" }, + { url = "https://files.pythonhosted.org/packages/17/72/c344825e3b83c5389a369c8a8e58ffe1480b8a699f46c127c34580c4666b/bcrypt-5.0.0-cp38-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:d79e5c65dcc9af213594d6f7f1fa2c98ad3fc10431e7aa53c176b441943efbdd", size = 275907, upload-time = "2025-09-25T19:49:54.709Z" }, + { url = "https://files.pythonhosted.org/packages/0b/7e/d4e47d2df1641a36d1212e5c0514f5291e1a956a7749f1e595c07a972038/bcrypt-5.0.0-cp38-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:2b732e7d388fa22d48920baa267ba5d97cca38070b69c0e2d37087b381c681fd", size = 296500, upload-time = "2025-09-25T19:49:56.013Z" }, + { url = "https://files.pythonhosted.org/packages/0f/c3/0ae57a68be2039287ec28bc463b82e4b8dc23f9d12c0be331f4782e19108/bcrypt-5.0.0-cp38-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:0c8e093ea2532601a6f686edbc2c6b2ec24131ff5c52f7610dd64fa4553b5464", size = 278412, upload-time = "2025-09-25T19:49:57.356Z" }, + { url = "https://files.pythonhosted.org/packages/45/2b/77424511adb11e6a99e3a00dcc7745034bee89036ad7d7e255a7e47be7d8/bcrypt-5.0.0-cp38-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:5b1589f4839a0899c146e8892efe320c0fa096568abd9b95593efac50a87cb75", size = 275486, upload-time = "2025-09-25T19:49:59.116Z" }, + { url = "https://files.pythonhosted.org/packages/43/0a/405c753f6158e0f3f14b00b462d8bca31296f7ecfc8fc8bc7919c0c7d73a/bcrypt-5.0.0-cp38-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:89042e61b5e808b67daf24a434d89bab164d4de1746b37a8d173b6b14f3db9ff", size = 277940, upload-time = "2025-09-25T19:50:00.869Z" }, + { url = "https://files.pythonhosted.org/packages/62/83/b3efc285d4aadc1fa83db385ec64dcfa1707e890eb42f03b127d66ac1b7b/bcrypt-5.0.0-cp38-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:e3cf5b2560c7b5a142286f69bde914494b6d8f901aaa71e453078388a50881c4", size = 310776, upload-time = "2025-09-25T19:50:02.393Z" }, + { url = "https://files.pythonhosted.org/packages/95/7d/47ee337dacecde6d234890fe929936cb03ebc4c3a7460854bbd9c97780b8/bcrypt-5.0.0-cp38-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:f632fd56fc4e61564f78b46a2269153122db34988e78b6be8b32d28507b7eaeb", size = 312922, upload-time = "2025-09-25T19:50:04.232Z" }, + { url = "https://files.pythonhosted.org/packages/d6/3a/43d494dfb728f55f4e1cf8fd435d50c16a2d75493225b54c8d06122523c6/bcrypt-5.0.0-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:801cad5ccb6b87d1b430f183269b94c24f248dddbbc5c1f78b6ed231743e001c", size = 341367, upload-time = "2025-09-25T19:50:05.559Z" }, + { url = "https://files.pythonhosted.org/packages/55/ab/a0727a4547e383e2e22a630e0f908113db37904f58719dc48d4622139b5c/bcrypt-5.0.0-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:3cf67a804fc66fc217e6914a5635000259fbbbb12e78a99488e4d5ba445a71eb", size = 359187, upload-time = "2025-09-25T19:50:06.916Z" }, + { url = "https://files.pythonhosted.org/packages/1b/bb/461f352fdca663524b4643d8b09e8435b4990f17fbf4fea6bc2a90aa0cc7/bcrypt-5.0.0-cp38-abi3-win32.whl", hash = "sha256:3abeb543874b2c0524ff40c57a4e14e5d3a66ff33fb423529c88f180fd756538", size = 153752, upload-time = "2025-09-25T19:50:08.515Z" }, + { url = "https://files.pythonhosted.org/packages/41/aa/4190e60921927b7056820291f56fc57d00d04757c8b316b2d3c0d1d6da2c/bcrypt-5.0.0-cp38-abi3-win_amd64.whl", hash = "sha256:35a77ec55b541e5e583eb3436ffbbf53b0ffa1fa16ca6782279daf95d146dcd9", size = 150881, upload-time = "2025-09-25T19:50:09.742Z" }, + { url = "https://files.pythonhosted.org/packages/54/12/cd77221719d0b39ac0b55dbd39358db1cd1246e0282e104366ebbfb8266a/bcrypt-5.0.0-cp38-abi3-win_arm64.whl", hash = "sha256:cde08734f12c6a4e28dc6755cd11d3bdfea608d93d958fffbe95a7026ebe4980", size = 144931, upload-time = "2025-09-25T19:50:11.016Z" }, + { url = "https://files.pythonhosted.org/packages/5d/ba/2af136406e1c3839aea9ecadc2f6be2bcd1eff255bd451dd39bcf302c47a/bcrypt-5.0.0-cp39-abi3-macosx_10_12_universal2.whl", hash = "sha256:0c418ca99fd47e9c59a301744d63328f17798b5947b0f791e9af3c1c499c2d0a", size = 495313, upload-time = "2025-09-25T19:50:12.309Z" }, + { url = "https://files.pythonhosted.org/packages/ac/ee/2f4985dbad090ace5ad1f7dd8ff94477fe089b5fab2040bd784a3d5f187b/bcrypt-5.0.0-cp39-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ddb4e1500f6efdd402218ffe34d040a1196c072e07929b9820f363a1fd1f4191", size = 275290, upload-time = "2025-09-25T19:50:13.673Z" }, + { url = "https://files.pythonhosted.org/packages/e4/6e/b77ade812672d15cf50842e167eead80ac3514f3beacac8902915417f8b7/bcrypt-5.0.0-cp39-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:7aeef54b60ceddb6f30ee3db090351ecf0d40ec6e2abf41430997407a46d2254", size = 278253, upload-time = "2025-09-25T19:50:15.089Z" }, + { url = "https://files.pythonhosted.org/packages/36/c4/ed00ed32f1040f7990dac7115f82273e3c03da1e1a1587a778d8cea496d8/bcrypt-5.0.0-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:f0ce778135f60799d89c9693b9b398819d15f1921ba15fe719acb3178215a7db", size = 276084, upload-time = "2025-09-25T19:50:16.699Z" }, + { url = "https://files.pythonhosted.org/packages/e7/c4/fa6e16145e145e87f1fa351bbd54b429354fd72145cd3d4e0c5157cf4c70/bcrypt-5.0.0-cp39-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:a71f70ee269671460b37a449f5ff26982a6f2ba493b3eabdd687b4bf35f875ac", size = 297185, upload-time = "2025-09-25T19:50:18.525Z" }, + { url = "https://files.pythonhosted.org/packages/24/b4/11f8a31d8b67cca3371e046db49baa7c0594d71eb40ac8121e2fc0888db0/bcrypt-5.0.0-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:f8429e1c410b4073944f03bd778a9e066e7fad723564a52ff91841d278dfc822", size = 278656, upload-time = "2025-09-25T19:50:19.809Z" }, + { url = "https://files.pythonhosted.org/packages/ac/31/79f11865f8078e192847d2cb526e3fa27c200933c982c5b2869720fa5fce/bcrypt-5.0.0-cp39-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:edfcdcedd0d0f05850c52ba3127b1fce70b9f89e0fe5ff16517df7e81fa3cbb8", size = 275662, upload-time = "2025-09-25T19:50:21.567Z" }, + { url = "https://files.pythonhosted.org/packages/d4/8d/5e43d9584b3b3591a6f9b68f755a4da879a59712981ef5ad2a0ac1379f7a/bcrypt-5.0.0-cp39-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:611f0a17aa4a25a69362dcc299fda5c8a3d4f160e2abb3831041feb77393a14a", size = 278240, upload-time = "2025-09-25T19:50:23.305Z" }, + { url = "https://files.pythonhosted.org/packages/89/48/44590e3fc158620f680a978aafe8f87a4c4320da81ed11552f0323aa9a57/bcrypt-5.0.0-cp39-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:db99dca3b1fdc3db87d7c57eac0c82281242d1eabf19dcb8a6b10eb29a2e72d1", size = 311152, upload-time = "2025-09-25T19:50:24.597Z" }, + { url = "https://files.pythonhosted.org/packages/5f/85/e4fbfc46f14f47b0d20493669a625da5827d07e8a88ee460af6cd9768b44/bcrypt-5.0.0-cp39-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:5feebf85a9cefda32966d8171f5db7e3ba964b77fdfe31919622256f80f9cf42", size = 313284, upload-time = "2025-09-25T19:50:26.268Z" }, + { url = "https://files.pythonhosted.org/packages/25/ae/479f81d3f4594456a01ea2f05b132a519eff9ab5768a70430fa1132384b1/bcrypt-5.0.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:3ca8a166b1140436e058298a34d88032ab62f15aae1c598580333dc21d27ef10", size = 341643, upload-time = "2025-09-25T19:50:28.02Z" }, + { url = "https://files.pythonhosted.org/packages/df/d2/36a086dee1473b14276cd6ea7f61aef3b2648710b5d7f1c9e032c29b859f/bcrypt-5.0.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:61afc381250c3182d9078551e3ac3a41da14154fbff647ddf52a769f588c4172", size = 359698, upload-time = "2025-09-25T19:50:31.347Z" }, + { url = "https://files.pythonhosted.org/packages/c0/f6/688d2cd64bfd0b14d805ddb8a565e11ca1fb0fd6817175d58b10052b6d88/bcrypt-5.0.0-cp39-abi3-win32.whl", hash = "sha256:64d7ce196203e468c457c37ec22390f1a61c85c6f0b8160fd752940ccfb3a683", size = 153725, upload-time = "2025-09-25T19:50:34.384Z" }, + { url = "https://files.pythonhosted.org/packages/9f/b9/9d9a641194a730bda138b3dfe53f584d61c58cd5230e37566e83ec2ffa0d/bcrypt-5.0.0-cp39-abi3-win_amd64.whl", hash = "sha256:64ee8434b0da054d830fa8e89e1c8bf30061d539044a39524ff7dec90481e5c2", size = 150912, upload-time = "2025-09-25T19:50:35.69Z" }, + { url = "https://files.pythonhosted.org/packages/27/44/d2ef5e87509158ad2187f4dd0852df80695bb1ee0cfe0a684727b01a69e0/bcrypt-5.0.0-cp39-abi3-win_arm64.whl", hash = "sha256:f2347d3534e76bf50bca5500989d6c1d05ed64b440408057a37673282c654927", size = 144953, upload-time = "2025-09-25T19:50:37.32Z" }, +] + +[[package]] +name = "beartype" +version = "0.23.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/79/34/c0cfdaee9c796c8381439fed0fcab62810753b8b0adb1ec88fa7f41eaa5d/beartype-0.23.1.tar.gz", hash = "sha256:8b805f246b32931c74f2b321ea0939fe5bb2ff43c12a3eff19cc4c854b832e1d", size = 1993714, upload-time = "2026-10-11T05:36:55.251Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1c/cb/2f6aa982e2860c1156830db3da7f823b71784ed7d533ca289ea9b6c6347a/beartype-0.23.1-py3-none-any.whl", hash = "sha256:4461b4dc57e3fdd6c8a8464b22cf118002eea107c33e9fef651c69068ab3cce3", size = 1582101, upload-time = "2026-10-11T05:36:52.431Z" }, +] + +[[package]] +name = "blis" +version = "1.3.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/d0/d0/d8cc8c9a4488a787e7fa430f6055e5bd1ddb22c340a751d9e901b82e2efe/blis-1.3.3.tar.gz", hash = "sha256:034d4560ff3cc43e8aa37e188451b0440e3261d989bb8a42ceee865607715ecd", size = 2644873, upload-time = "2025-11-17T12:28:30.511Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e6/f7/d26e62d9be3d70473a63e0a5d30bae49c2fe138bebac224adddcdef8a7ce/blis-1.3.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:1e647341f958421a86b028a2efe16ce19c67dba2a05f79e8f7e80b1ff45328aa", size = 6928322, upload-time = "2025-11-17T12:27:57.965Z" }, + { url = "https://files.pythonhosted.org/packages/4a/78/750d12da388f714958eb2f2fd177652323bbe7ec528365c37129edd6eb84/blis-1.3.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:d563160f874abb78a57e346f07312c5323f7ad67b6370052b6b17087ef234a8e", size = 1229635, upload-time = "2025-11-17T12:28:00.118Z" }, + { url = "https://files.pythonhosted.org/packages/e8/36/eac4199c5b200a5f3e93cad197da8d26d909f218eb444c4f552647c95240/blis-1.3.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:30b8a5b90cb6cb81d1ada9ae05aa55fb8e70d9a0ae9db40d2401bb9c1c8f14c4", size = 2815650, upload-time = "2025-11-17T12:28:02.544Z" }, + { url = "https://files.pythonhosted.org/packages/bf/51/472e7b36a6bedb5242a9757e7486f702c3619eff76e256735d0c8b1679c6/blis-1.3.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:e9f5c53b277f6ac5b3ca30bc12ebab7ea16c8f8c36b14428abb56924213dc127", size = 11359008, upload-time = "2025-11-17T12:28:04.589Z" }, + { url = "https://files.pythonhosted.org/packages/84/da/d0dfb6d6e6321ae44df0321384c32c322bd07b15740d7422727a1a49fc5d/blis-1.3.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:6297e7616c158b305c9a8a4e47ca5fc9b0785194dd96c903b1a1591a7ca21ddf", size = 3011959, upload-time = "2025-11-17T12:28:06.862Z" }, + { url = "https://files.pythonhosted.org/packages/20/c5/2b0b5e556fa0364ed671051ea078a6d6d7b979b1cfef78d64ad3ca5f0c7f/blis-1.3.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:3f966ca74f89f8a33e568b9a1d71992fc9a0d29a423e047f0a212643e21b5458", size = 14232456, upload-time = "2025-11-17T12:28:08.779Z" }, + { url = "https://files.pythonhosted.org/packages/31/07/4cdc81a47bf862c0b06d91f1bc6782064e8b69ac9b5d4ff51d97e4ff03da/blis-1.3.3-cp313-cp313-win_amd64.whl", hash = "sha256:7a0fc4b237a3a453bdc3c7ab48d91439fcd2d013b665c46948d9eaf9c3e45a97", size = 6192624, upload-time = "2025-11-17T12:28:14.197Z" }, +] + +[[package]] +name = "boto3" +version = "1.43.106" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "botocore" }, + { name = "jmespath" }, + { name = "s3transfer" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/49/01/97aaee4d3e94467983a0c1b986ed4f4da48960d7ebc948e7d739c818cb59/boto3-1.43.106.tar.gz", hash = "sha256:c11ad4c429a983493ba10014c7af9831a455c2c0eea91c1cefff74530e480277", size = 112730, upload-time = "2026-09-30T19:36:41.684Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/72/d8/a01764ffd32fbcd66c5575eb85764ae9ea7b7d03dc591592e132c43af1f5/boto3-1.43.106-py3-none-any.whl", hash = "sha256:fdf2e304f9e8864b8613591b18b36ee995560c9666033622eda1cb9057866880", size = 140045, upload-time = "2026-09-30T19:36:40.228Z" }, +] + +[[package]] +name = "botocore" +version = "1.43.106" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "jmespath" }, + { name = "python-dateutil" }, + { name = "urllib3" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/11/b9/10ca68d0092895d5ea60f485a61a9840d5aff9d732c66ed60da53a20b1d4/botocore-1.43.106.tar.gz", hash = "sha256:006870b3b4e40547232ad12c3bb4faec91bbbe0659aafaa3b7fa48a112c4ee97", size = 16271399, upload-time = "2026-09-30T19:36:35.836Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a8/eb/c51d3b54dfaa9267a687359d946dc2a1ca6a27fb4d381773e59b7bd72bf4/botocore-1.43.106-py3-none-any.whl", hash = "sha256:c1fb8818f9957cb5037f73db34ac1a12ba43562e31d6e7f9cb7e5fc64e1dba78", size = 15965506, upload-time = "2026-09-30T19:36:32.625Z" }, +] + +[[package]] +name = "cachetools" +version = "7.2.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/31/44/71476a5812da1ddf2c9a3efd31ae76d01480a1cf03ed13ac28aa8f2402e4/cachetools-7.2.1.tar.gz", hash = "sha256:b1a7537025c06abf96fcc1443e496af9a3fb95e774e70e1f0af226f73f7f2dcc", size = 41357, upload-time = "2026-10-05T18:40:06.361Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f0/c9/2a61d784caf0d869a3326728c57c7203f50cc53f3cca2ee76bf924769eb4/cachetools-7.2.1-py3-none-any.whl", hash = "sha256:63aa53dfe7473c10cccdd5a01dedf76ef2c4b73a58840d9396e7d0752cbdac3b", size = 17006, upload-time = "2026-10-05T18:40:04.827Z" }, +] + +[[package]] +name = "caio" +version = "0.12.9" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/56/51/bd8b64bf700f5b1a956a60bb62276b79a094e8cd0ddc60b1b61c3edd496f/caio-0.12.9.tar.gz", hash = "sha256:99e99419b44ab5511f7468c6a452887dd125b8e4042672a7589f0cf01d254ea8", size = 84084, upload-time = "2026-09-26T09:51:49.433Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e8/bf/ed21d62204e4feece79985f45d2ebce6949c9e3d320e9f9e9638e9dc980a/caio-0.12.9-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ed23f6ad6897fae4c02e3e8d236aa3cc18e766a7c5bb0352ea5e9fb26c5d3335", size = 49024, upload-time = "2026-09-26T09:51:10.472Z" }, + { url = "https://files.pythonhosted.org/packages/cc/c6/fea92dd83cdf28ee20d403a910e194fa5e1a97215a00e5bbbeb699ac582a/caio-0.12.9-cp313-cp313-manylinux_2_34_aarch64.whl", hash = "sha256:c327977b8174337c1aaff27da17ac249d176ef8ea6e2dbf70b49cdd8038d57d3", size = 164835, upload-time = "2026-09-26T09:51:12.213Z" }, + { url = "https://files.pythonhosted.org/packages/ca/0f/8ec37d3d6b47b8c6bd6c68a1d2d9b5de1ea05df59b601575b7003c9439e2/caio-0.12.9-cp313-cp313-manylinux_2_34_x86_64.whl", hash = "sha256:f6ffb3d448016d20d8c40c53864d81bdf7463157969de65841eeb370519dbf78", size = 162567, upload-time = "2026-09-26T09:51:13.559Z" }, + { url = "https://files.pythonhosted.org/packages/ec/5f/b3258150ea0e87f032859df825dd0ec8e9f3a6c798addc6463cf1e4a2298/caio-0.12.9-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a11421fb4ac591e6fea5512d9a8ad1b488e7b28cf610ede973bbfb4be5177454", size = 162299, upload-time = "2026-09-26T09:51:14.977Z" }, + { url = "https://files.pythonhosted.org/packages/f8/6e/5712cbf5168fdb4c65c44b0435daeeac7c00609cdc1fd3414812691fbb68/caio-0.12.9-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:c3f6dc05486ce4e1027f1d2da4d84c1d6bb815886e76f34a9228d370d86a5537", size = 162155, upload-time = "2026-09-26T09:51:16.395Z" }, + { url = "https://files.pythonhosted.org/packages/3a/6a/5a08b26fae45320c8d6f3b42e6225c5316b39f6cea811ba3f890315b4641/caio-0.12.9-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:5c43eaebf220aeb9a388d309a5352e82562a7b9b2ea0102502204413641cfed7", size = 42777, upload-time = "2026-09-26T09:51:17.929Z" }, + { url = "https://files.pythonhosted.org/packages/c0/99/96888ad510c9adf42bfbad9ba139831b58055fd61e1301f6268e9bb490b8/caio-0.12.9-py3-none-any.whl", hash = "sha256:bf12d4f014b2a33e642ed7905b5787656ede2fc24be21f7c086826ff0d32cec3", size = 26154, upload-time = "2026-09-26T09:51:48.071Z" }, +] + +[[package]] +name = "catalogue" +version = "2.0.10" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/38/b4/244d58127e1cdf04cf2dc7d9566f0d24ef01d5ce21811bab088ecc62b5ea/catalogue-2.0.10.tar.gz", hash = "sha256:4f56daa940913d3f09d589c191c74e5a6d51762b3a9e37dd53b7437afd6cda15", size = 19561, upload-time = "2023-09-25T06:29:24.962Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9e/96/d32b941a501ab566a16358d68b6eb4e4acc373fab3c3c4d7d9e649f7b4bb/catalogue-2.0.10-py3-none-any.whl", hash = "sha256:58c2de0020aa90f4a2da7dfad161bf7b3b054c86a5f09fcedc0b2b740c109a9f", size = 17325, upload-time = "2023-09-25T06:29:23.337Z" }, +] + +[[package]] +name = "certifi" +version = "2026.7.22" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a3/c2/24167ea9858356b47a87a50d39908bfdb72ceeefe0041586e704e5376b3a/certifi-2026.7.22.tar.gz", hash = "sha256:741e2c3b351ddf169a738da9f2c048608ff7f2c5cc02f1ebc6b118bb090d5d55", size = 138112, upload-time = "2026-07-22T03:35:12.644Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0b/a7/71ac2cff56fec219ed242bb11b8efb69fcc4bec75db06fb7bfe35de520e6/certifi-2026.7.22-py3-none-any.whl", hash = "sha256:62f22742b58a1a33014a2b6b706588a8d7e2a88ae7bd1a6ebe8c992928483775", size = 136983, upload-time = "2026-07-22T03:35:11.276Z" }, +] + +[[package]] +name = "cffi" +version = "2.1.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pycparser", marker = "implementation_name != 'PyPy'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/9e/ef/008a1939e372c06329a3fce4279c02f328488f3526744906eeec3da7ad5f/cffi-2.1.1.tar.gz", hash = "sha256:dd31f52ea1086513bb9df30f8fcee9b8918323ae067a3d5b78bc826a000712be", size = 530807, upload-time = "2026-08-03T21:21:18.939Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9d/f4/035513d4117049066b4779dc3b7c0c0fdad175fa13731c9f4003f1cd1478/cffi-2.1.1-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:b5bdfd1c873d4e093aabc0ca84c4ca6dbc4f752afb5c86f146d9742580c9da2e", size = 194248, upload-time = "2026-08-03T21:19:59.399Z" }, + { url = "https://files.pythonhosted.org/packages/76/af/2aeb4dbb5fc41a04161ae9ff1518de7cec08e164f44a8ce6a4cf7fd2cd1d/cffi-2.1.1-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:31348097ff5bbe827ccc41795d4dd099d9f0625e7def00ee653c137a490c2a6c", size = 196908, upload-time = "2026-08-03T21:20:00.746Z" }, + { url = "https://files.pythonhosted.org/packages/a7/46/2e5fdde8555706dd98139a910ca11be02809f3f605ce956f655d0214e100/cffi-2.1.1-cp313-cp313-macosx_10_15_x86_64.whl", hash = "sha256:9d2055050ea716bd38b7f7f1579c275386646b4894c155a3e2f3cd62ed41b7c6", size = 184805, upload-time = "2026-08-03T21:20:02.02Z" }, + { url = "https://files.pythonhosted.org/packages/55/41/4c7042f317b9217502988f0873af87e16ad606dc20f84e546e3e6ce9764c/cffi-2.1.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:19ee6127ee34de7d83ce3d371ebc5ed91addbdcc39f9ab15ce4eb35a4e534971", size = 184764, upload-time = "2026-08-03T21:20:03.141Z" }, + { url = "https://files.pythonhosted.org/packages/43/1f/1c3d90d91811c8f86ced9ed637956c54bfe5b79ca98fe976d7f8c8979f6b/cffi-2.1.1-cp313-cp313-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:6a8dddef476fab96d066d578fc88526767b836ab5ab21754e1d5bf3879c31c7c", size = 214722, upload-time = "2026-08-03T21:20:04.377Z" }, + { url = "https://files.pythonhosted.org/packages/37/6f/3b5ce4c3b2192d250f04908f2bfd91ef34552ec8f7716a5d4abdb8d67bb2/cffi-2.1.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:f16c709686a78c727bbbf059f92b0bf41c6fc60deec706d2dc19f529175a6125", size = 222369, upload-time = "2026-08-03T21:20:05.544Z" }, + { url = "https://files.pythonhosted.org/packages/02/10/4b3c75dde3d9663c9e02ba05c2668b954f671d4bbe346413ca8c696b295a/cffi-2.1.1-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:fcd22650c908d7b7da162bbfaab594a1227a15d1643a98c68b122ac642fa2264", size = 210175, upload-time = "2026-08-03T21:20:06.75Z" }, + { url = "https://files.pythonhosted.org/packages/df/62/14f74b9543e605d17701dc797b815958b8bb70b7624ce1b832ddad48ed6c/cffi-2.1.1-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:aa9511c62d14da7aacc9b4bf51f3f697a621e83b2d6919008243c3aad168eea3", size = 208670, upload-time = "2026-08-03T21:20:08.04Z" }, + { url = "https://files.pythonhosted.org/packages/95/95/86342356ff5953b3fb06f7ef7c5bee212d45e770abc7218d451b9148313c/cffi-2.1.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:a931079504ecc49efed7744c476a5c343a92fabf66dec2db95edb1b2fdc770e2", size = 221824, upload-time = "2026-08-03T21:20:09.274Z" }, + { url = "https://files.pythonhosted.org/packages/eb/ff/7b3429ff53aafe931ed8a5fc69f481bbef7ba6de87ddcbb63d08f483f613/cffi-2.1.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a2d7755bef5a12ed488f4ef1f1b69ee9191d7396083b755a5d2295f6edb4768b", size = 225148, upload-time = "2026-08-03T21:20:10.7Z" }, + { url = "https://files.pythonhosted.org/packages/34/34/a95870b9221e09cf4f2ce3178b1a210abdfe63a1bd357da940418d7b8d15/cffi-2.1.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e0bcb7e0f677f543555d2adff3bf19c05f66cdb4796e5ff602442ab2fe3c4ef7", size = 223564, upload-time = "2026-08-03T21:20:12.165Z" }, + { url = "https://files.pythonhosted.org/packages/70/ea/839b50531021a647fb5e929f72cf97bc1ff702b5472166164b5b6e76b851/cffi-2.1.1-cp313-cp313-win32.whl", hash = "sha256:334644fbac4eff73d985a17a91226df55d0f394160c4cfb880e084c8f7161cac", size = 175263, upload-time = "2026-08-03T21:20:13.559Z" }, + { url = "https://files.pythonhosted.org/packages/60/a6/8b149b2c3f2e11aaa1618ef64500b45f50f22c57a977a4dff1aff1f91042/cffi-2.1.1-cp313-cp313-win_amd64.whl", hash = "sha256:1aa5645c30469b09530c4ebca77ebf8f17618293c58f8549cb1a543a50236e7d", size = 185688, upload-time = "2026-08-03T21:20:14.69Z" }, + { url = "https://files.pythonhosted.org/packages/01/9a/11f687cb39d6a3504060d5242f04f48c735afb4d3d533958a20594890cb2/cffi-2.1.1-cp313-cp313-win_arm64.whl", hash = "sha256:63bbfd5ded17c4840ac07cd8f1c21ba9d9708141f840b324f422f41b207e3973", size = 180078, upload-time = "2026-08-03T21:20:15.917Z" }, +] + +[[package]] +name = "chardet" +version = "7.6.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b1/51/cd61c567092a6cec796144510a68aff158ebfc1df82950a45bae65f28413/chardet-7.6.0.tar.gz", hash = "sha256:93d9df6089ded42ed1fe9f57e272c0b74bd0464d45c0c7d50f09f26f31105c3c", size = 914462, upload-time = "2026-08-14T20:36:59.305Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a3/29/16a7419edfbd60e901e6a797cbc3e038cb2a81903bc16c029db755f0156f/chardet-7.6.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:57e6846cc13ce1ff59979f4ec9da770c57e12aa99046073f632de5a51d9a6f20", size = 1088449, upload-time = "2026-08-14T20:36:34.723Z" }, + { url = "https://files.pythonhosted.org/packages/1d/36/3a14b0f8ddeb302f157281ca656a3ce6874b78e2d6af03682f520b487245/chardet-7.6.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:089e3bb81a0a07e94f15461ded9f9ee66d349615b1a9fd557d4de1003e2fc12e", size = 1065126, upload-time = "2026-08-14T20:36:36.21Z" }, + { url = "https://files.pythonhosted.org/packages/d2/4c/f59a39c2bfe4ac99baba8da842e8d2ea0b84dff7ba53a96e7ad8c71602d7/chardet-7.6.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:43ea433e43a23c55e8e17f3fad1e07f5cfe5450c73124b95b0d849c21ad379ee", size = 1482492, upload-time = "2026-08-14T20:36:37.649Z" }, + { url = "https://files.pythonhosted.org/packages/bd/eb/93e8036681157f2217a18769927a035984526e6dbd5e91f28a375ca41c14/chardet-7.6.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2b5d31f9b7f793e15e81cca877e7ccd72bffffa2a3443a9d47be9dfee84fad69", size = 1514185, upload-time = "2026-08-14T20:36:39.119Z" }, + { url = "https://files.pythonhosted.org/packages/10/04/0066d7ab2c135e404a6fa166bb7fa49d1c7bf7af07b86ed95b1c48a348c7/chardet-7.6.0-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:c54b6a8d3b219560fa5cf4c28df932c37471afe047afdc152067104e741f38c1", size = 1454420, upload-time = "2026-08-14T20:36:40.549Z" }, + { url = "https://files.pythonhosted.org/packages/6c/9f/e965f1d9eddfb86cf118f980d329cbee43c4ac4b562448b369a6b6ef36af/chardet-7.6.0-cp313-cp313-win_amd64.whl", hash = "sha256:b3b4c96c4df93899b3c8b9e8159e06b1f55c66d7ca384d91481108e251a06eb0", size = 1159067, upload-time = "2026-08-14T20:36:41.816Z" }, + { url = "https://files.pythonhosted.org/packages/cf/6e/5a0b348fa4cd7847567a28c6e697ccf58391960bfd13a6e7473ee23ca2f2/chardet-7.6.0-py3-none-any.whl", hash = "sha256:4076d795897ce45239825956a1334e134322ecc4bfe84dbb12acd5390de0fbc1", size = 680279, upload-time = "2026-08-14T20:36:57.763Z" }, +] + +[[package]] +name = "charset-normalizer" +version = "3.5.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/33/1c/f41d4e74c28ab327ff3acd36053f7ea506c55872d7a90b0fa71aa3ab0c89/charset_normalizer-3.5.2.tar.gz", hash = "sha256:39de2a259fc954455c57274dc94c79d5842774e1247a016aff30bc0efed0f4ef", size = 172659, upload-time = "2026-09-30T04:39:23.398Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c5/34/68292d68512768591aaff07c59bb53ee31341c87759433a859c4641a50c2/charset_normalizer-3.5.2-cp313-cp313-android_24_arm64_v8a.whl", hash = "sha256:ed905975ab14056a2e5eb1c376cb2e1ebc5396baf84163939c518556fccde9f5", size = 225946, upload-time = "2026-09-30T04:35:55.313Z" }, + { url = "https://files.pythonhosted.org/packages/e3/80/bee0b01b90ccd5322ae1d0abb33fab1bd95b7c2eadaf02aeccf22e04ee83/charset_normalizer-3.5.2-cp313-cp313-android_24_x86_64.whl", hash = "sha256:a66c3bc5ab1f0ff2164fc9965ddd611ff0802173f4b9d24554c563f6ab7e1d6e", size = 238619, upload-time = "2026-09-30T04:35:56.863Z" }, + { url = "https://files.pythonhosted.org/packages/78/6e/60ce52a85a7fd631ae8482ae6d74521014ca2f255892679484dc04d7ef56/charset_normalizer-3.5.2-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:d2374b62878abb00cd8309b32af6c0b715cd02dec0ca74ef12e5069bdc64144a", size = 206701, upload-time = "2026-09-30T04:35:58.639Z" }, + { url = "https://files.pythonhosted.org/packages/36/8c/71aafad23f971afc84c2b295bc0c560739ce1dac558aad9fec22e39f3639/charset_normalizer-3.5.2-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:d376bbd28b3a8999db1a103b3b388aee6f1ddeb3e51bc2172993efdcd86e064d", size = 210506, upload-time = "2026-09-30T04:36:00.147Z" }, + { url = "https://files.pythonhosted.org/packages/91/da/3c5a7798c046df7d2d68ad653cf5b6c5a8bfee225055a843c6f2f42aac1a/charset_normalizer-3.5.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:6045373d5a89a5ec71afde535db987ca28e76dfa276c2d4c818265b375d4b055", size = 366626, upload-time = "2026-09-30T04:36:01.77Z" }, + { url = "https://files.pythonhosted.org/packages/e1/16/710ac3de2ee354e2bd1a9c94efe45a2d27b5c6ad39b2d6a905be2c094b6c/charset_normalizer-3.5.2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:849df64e889b2e17230d58410a03dba311a65b163508fd33679b2b737d4b7858", size = 244624, upload-time = "2026-09-30T04:36:03.389Z" }, + { url = "https://files.pythonhosted.org/packages/d6/39/45c7439f5b63d24f7d5b2a1d760f34af7628782d7144b4cc8ded45c2d4bc/charset_normalizer-3.5.2-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:15c44f7edfd477b06f517a5cc317fc1707edb9de2c865f43d4b6513907473234", size = 235731, upload-time = "2026-09-30T04:36:04.987Z" }, + { url = "https://files.pythonhosted.org/packages/4d/34/38f3154785ce92e9f56eb226f4d35bdfae6b008480dd055f58837a89c810/charset_normalizer-3.5.2-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a89012d6d5476ee112d20d998570ed58df2260a852afb1758809cd6900411d21", size = 270352, upload-time = "2026-09-30T04:36:06.412Z" }, + { url = "https://files.pythonhosted.org/packages/04/f3/859f74e7babc977705026b30593b3be04049632a522fb7000f83c033d747/charset_normalizer-3.5.2-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0c951d5e6dd9c2ff60609476752bee49da4206adde960ebc247766937f72e718", size = 267393, upload-time = "2026-09-30T04:36:07.865Z" }, + { url = "https://files.pythonhosted.org/packages/4b/85/41d27f234b82e47c167a5f6c0f62501dc0c640585ff4aba79e08a390336a/charset_normalizer-3.5.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7218e8f32b0956cfcd048fd42d9d5779809745ca1d86113ca56f66e7ae1549c4", size = 254660, upload-time = "2026-09-30T04:36:09.248Z" }, + { url = "https://files.pythonhosted.org/packages/58/ca/5d1a997587febe5b26d8daffe363b5c1a091cece19828eec6502fd09c5ef/charset_normalizer-3.5.2-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:a19a731138fc27d5682277d3b9df22855cea1239bce7fcec5f78f42ef2d1f3c3", size = 249996, upload-time = "2026-09-30T04:36:10.73Z" }, + { url = "https://files.pythonhosted.org/packages/b3/1f/d1e78246f7ed60c8c8d606b4ac27f66ce49cc3e95f24893ccbeba9f77302/charset_normalizer-3.5.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:62603db9a7caa0802eaa28c1c46fecd7b3a263a774069c24c3c28c302448721c", size = 247028, upload-time = "2026-09-30T04:36:12.294Z" }, + { url = "https://files.pythonhosted.org/packages/8e/37/eba316edd4f0c4d3a5d945924c4eeeae59abac4056aa815d8a4268f863a2/charset_normalizer-3.5.2-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:b6856554c4f44d79fc2307d5768854310a8f0096e501c75637542c82292b0429", size = 240562, upload-time = "2026-09-30T04:36:13.887Z" }, + { url = "https://files.pythonhosted.org/packages/c8/8e/aaa037d40ca9ef045977f1a661048b1aa33f223adfce3452fe9be9f79d14/charset_normalizer-3.5.2-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:1bc0baf5ef96b6ede57d47f4b8fe4d9d84019c3bfcbeb20a41edc6a6ee341f1f", size = 271699, upload-time = "2026-09-30T04:36:15.41Z" }, + { url = "https://files.pythonhosted.org/packages/26/19/1c1c9f75974adf523b87f34b8a2adc5a435cd65916812bcbd0dfa45f9a29/charset_normalizer-3.5.2-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:56bc200a365efb37383b7852e4cc5898d3b2da5987289b543956cf8cad71018a", size = 252030, upload-time = "2026-09-30T04:36:16.839Z" }, + { url = "https://files.pythonhosted.org/packages/bc/90/0660ef18e18df0a4d2a1a0edff7dfbba42d4e50ef2425557a5bb7051f77b/charset_normalizer-3.5.2-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:2c9ad19a6cfcd5ea5c0d41161d22f9df1dcc277e9bef2751391334546a314c00", size = 268565, upload-time = "2026-09-30T04:36:18.468Z" }, + { url = "https://files.pythonhosted.org/packages/79/ba/57adc269824e8658f1a0f97a9e514c247445a9632b3419b97e0ba37f16dc/charset_normalizer-3.5.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e243bd13217235fc7290c621941c3f5cc8b66e4872495be821d7436ba2fb838d", size = 257627, upload-time = "2026-09-30T04:36:19.938Z" }, + { url = "https://files.pythonhosted.org/packages/9a/85/33abd4315c052d3d4f54c92b1ee49bfbc0dc7115a981e462a793b6d2ab87/charset_normalizer-3.5.2-cp313-cp313-pyemscripten_2025_0_wasm32.whl", hash = "sha256:a090bb2c68df85450502e3e20d665e3a5af9c65a84d6508ed477badd49166fd3", size = 143407, upload-time = "2026-09-30T04:36:21.376Z" }, + { url = "https://files.pythonhosted.org/packages/4f/de/6435e18d1aaa5d910b896d551411c96af1f42a0c56c29afc2016c61ccc2e/charset_normalizer-3.5.2-cp313-cp313-win32.whl", hash = "sha256:2b7b3bbfb4fe8ef40600792d762fbaa9057559f9d3fad209525b7a22b99e91fd", size = 183207, upload-time = "2026-09-30T04:36:22.776Z" }, + { url = "https://files.pythonhosted.org/packages/9c/76/b8ec57f4e9ee3253541abf95e4a462c0175fe8032dcd070f1f2421240942/charset_normalizer-3.5.2-cp313-cp313-win_amd64.whl", hash = "sha256:78456a747de8dc58360ffa581f30a002baf5aa28cb262536545e91f113ed7639", size = 206489, upload-time = "2026-09-30T04:36:24.306Z" }, + { url = "https://files.pythonhosted.org/packages/3e/60/c647c6ae47480221e875ea5d743ff94946f7416e3c69415ab772928e8d32/charset_normalizer-3.5.2-cp313-cp313-win_arm64.whl", hash = "sha256:11912e4bb14baae7c5d8791aa55ba0a3a03ec6729073307b0f57270abaa713d3", size = 195501, upload-time = "2026-09-30T04:36:25.846Z" }, + { url = "https://files.pythonhosted.org/packages/8c/ab/176fbfd5b64939c55d652366aa5b9ef1d767af207a3aa6ebeb0d226c484d/charset_normalizer-3.5.2-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:4275811936e2f06feff5e598fb42a1b7ae852da8e39605211892b56b81a34efd", size = 331815, upload-time = "2026-09-30T04:38:26.216Z" }, + { url = "https://files.pythonhosted.org/packages/7e/84/371eac6b30bdbcbf2d632a1a01809103459216fcaae61b8b8d922c1bfb8a/charset_normalizer-3.5.2-cp37-abi3-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:1c50fe28bbc2ced33386f298650d91218076c05420e6cbd790b913adc41659e7", size = 253276, upload-time = "2026-09-30T04:38:28.032Z" }, + { url = "https://files.pythonhosted.org/packages/43/6f/c4fbae58febff71709c51bc7e18fdfa55341dc382704740f9f0cbf03817b/charset_normalizer-3.5.2-cp37-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d19fbd981a488e22cd04883659ca6b08f50b5974f9fd7c95655ef6a043e5893f", size = 241239, upload-time = "2026-09-30T04:38:29.732Z" }, + { url = "https://files.pythonhosted.org/packages/61/71/458c3f42164a07d0c5210798e9e704b39e540a6793b05aba67f3a35243a9/charset_normalizer-3.5.2-cp37-abi3-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:0fed1d06615f022ee3b13caf5e8b180cfea32bb2c5aded8a9d44277afc040f93", size = 231121, upload-time = "2026-09-30T04:38:31.462Z" }, + { url = "https://files.pythonhosted.org/packages/09/54/ab9e89367076f6331bb6c65c4bf14a5361fa5191cb6561bf534f18504e1b/charset_normalizer-3.5.2-cp37-abi3-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:838dcc90063569a0448120554591a1d6c4a4ffe11babf048908793154ab86ade", size = 260350, upload-time = "2026-09-30T04:38:33.239Z" }, + { url = "https://files.pythonhosted.org/packages/7c/c1/061431ecc688d9d76602502cb57cc01e691e682c18f1beb45f9673b5bbd2/charset_normalizer-3.5.2-cp37-abi3-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:2ce45c6627b22c47e390bc91a41c3d13032192e699fa0bea96e9671b373d69b0", size = 255430, upload-time = "2026-09-30T04:38:34.865Z" }, + { url = "https://files.pythonhosted.org/packages/8d/1f/20c8949f0676f7ab811abdeb7f4d7f1cbc6e61ff20bef08b44edeb092bc8/charset_normalizer-3.5.2-cp37-abi3-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:0774bf9bf620249fee3e0b8b9fd3065de213be30f3aa94ce2494b3b638949e26", size = 250612, upload-time = "2026-09-30T04:38:36.649Z" }, + { url = "https://files.pythonhosted.org/packages/2b/9e/46f2fa4c431fc98c4ae76a8cb5bdca54e0341e3cfc3fcfd8e82740250818/charset_normalizer-3.5.2-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:1db38f4c5496827c1a501846d64d14c3b80c7e6714e406cd7dc36a9899fa1011", size = 242083, upload-time = "2026-09-30T04:38:38.26Z" }, + { url = "https://files.pythonhosted.org/packages/bd/39/559be29a0c0f086e0bba6922babd38916cc5e0b58ced4de13ee01ea05508/charset_normalizer-3.5.2-cp37-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:304d8e4d493af723536393eee0c689eb7813f4a474c8b479dee63f1fdd98f621", size = 232738, upload-time = "2026-09-30T04:38:39.81Z" }, + { url = "https://files.pythonhosted.org/packages/ff/6c/387b0e4f756a282831c1d9fc6aeb6c51ca4507ca202767c8de15ce9b12e2/charset_normalizer-3.5.2-cp37-abi3-musllinux_1_2_ppc64le.whl", hash = "sha256:9b7f416ff0978e2f2249330527f0ad6fa02f4932e6199692d3b52da2048c19e4", size = 260703, upload-time = "2026-09-30T04:38:41.346Z" }, + { url = "https://files.pythonhosted.org/packages/96/92/1fdf015f09ef449f50d3ac4b67c90887c9c318b727daa95cc4f866e6521d/charset_normalizer-3.5.2-cp37-abi3-musllinux_1_2_riscv64.whl", hash = "sha256:01077390b03f7988f11d700a2194e69b119741a86b1a638b1db88891e3eced8e", size = 247622, upload-time = "2026-09-30T04:38:42.937Z" }, + { url = "https://files.pythonhosted.org/packages/dc/3c/8e7b8a5671ad5d433669fb2a76f1a0164df2d9b1718b0206bc2a16d840cc/charset_normalizer-3.5.2-cp37-abi3-musllinux_1_2_s390x.whl", hash = "sha256:7e841fb9010836c992c9f12fcbd43a831de93a5f726fc1ccd8ca1d0268c5014c", size = 257500, upload-time = "2026-09-30T04:38:44.604Z" }, + { url = "https://files.pythonhosted.org/packages/b4/f0/45b579df5cabc1d5d53ea1cc35e8437d3ca768c0acccc7041517cb6fbb32/charset_normalizer-3.5.2-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:9cae88599c7219005d879f98e5ed53341e9a122af585e1091200358a3003d2a0", size = 255100, upload-time = "2026-09-30T04:38:46.289Z" }, + { url = "https://files.pythonhosted.org/packages/31/68/fdec18a343f5fb3f310588dd478b09ac4799e0b187dbade3a8cd776f03ef/charset_normalizer-3.5.2-cp37-abi3-win32.whl", hash = "sha256:01b0c0d2262a9e28e8484a278c7e1b5d650e3ac8cf2683d2967e25899f208bdf", size = 174499, upload-time = "2026-09-30T04:38:47.999Z" }, + { url = "https://files.pythonhosted.org/packages/9d/8a/b618149cc5207943a0242068d7a27897f56a62947b5a039085f2a22029f8/charset_normalizer-3.5.2-cp37-abi3-win_amd64.whl", hash = "sha256:9f56f72050826f63dcee7a7f55b0a77168cb3bfc553fd405e7f8f9ece75a4036", size = 200092, upload-time = "2026-09-30T04:38:49.707Z" }, + { url = "https://files.pythonhosted.org/packages/03/cf/4c66866fa9e2b1c78e3c911516d1de497a677b7ac60f1eceda74ce777ca3/charset_normalizer-3.5.2-cp37-abi3-win_arm64.whl", hash = "sha256:40ab6bffa02ae10a0581e6c198be7d2d8ca5c2a0c64e4ed3465d766df457573e", size = 294363, upload-time = "2026-09-30T04:38:51.312Z" }, + { url = "https://files.pythonhosted.org/packages/fc/ad/d07d7862a62ffa6d79d68074d14823243dd235a77c45262acbf6adeb28bf/charset_normalizer-3.5.2-py3-none-any.whl", hash = "sha256:b6b751274acb69d77b3323d6b7dbaa3c7fdfc1eb829b7eb61d262f32e1af9685", size = 68872, upload-time = "2026-09-30T04:39:21.828Z" }, +] + +[[package]] +name = "click" +version = "8.5.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/c7/0e/7fa0ef50764b67090eca4114772a2abf8b6148198475e54c660b97caeee6/click-8.5.0.tar.gz", hash = "sha256:ba0d2089de75ea0310e2dde03160e6ca10009947fb95a182f9b54021bb272e34", size = 382235, upload-time = "2026-08-26T13:33:14.56Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/58/50/6c0d534c5f134586a8e1ba4e330569e32f057e33372ae556463212fb4cd3/click-8.5.0-py3-none-any.whl", hash = "sha256:255bc9599cf7748b4b1a446ccc735421bd08a2ae529a8b88597d3de5664ee360", size = 125251, upload-time = "2026-08-26T13:33:12.928Z" }, +] + +[[package]] +name = "cloudpathlib" +version = "0.26.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/23/25/627c75939f4db1395e7b2e60bec885ed278f7cdbea06b2456d72dcc51c09/cloudpathlib-0.26.0.tar.gz", hash = "sha256:6ea02248f2db7cb10729caf1edbdec92587dfdbbd3df8c71a32aedd4ae55715a", size = 56756, upload-time = "2026-10-02T01:07:19.796Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/97/aa/c333f1be2afab2d033d51a66cb105f4bfc885b0c546e1168fb889a416b9d/cloudpathlib-0.26.0-py3-none-any.whl", hash = "sha256:abcd7f54bcbb2fbb79c0e96b79241f08866760aee6276586882b3558672d571b", size = 66408, upload-time = "2026-10-02T01:07:18.817Z" }, +] + +[[package]] +name = "cloudpickle" +version = "3.1.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/27/fb/576f067976d320f5f0114a8d9fa1215425441bb35627b1993e5afd8111e5/cloudpickle-3.1.2.tar.gz", hash = "sha256:7fda9eb655c9c230dab534f1983763de5835249750e85fbcef43aaa30a9a2414", size = 22330, upload-time = "2025-11-03T09:25:26.604Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/88/39/799be3f2f0f38cc727ee3b4f1445fe6d5e4133064ec2e4115069418a5bb6/cloudpickle-3.1.2-py3-none-any.whl", hash = "sha256:9acb47f6afd73f60dc1df93bb801b472f05ff42fa6c84167d25cb206be1fbf4a", size = 22228, upload-time = "2025-11-03T09:25:25.534Z" }, +] + +[[package]] +name = "cohere" +version = "7.2.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "fastavro" }, + { name = "httpx" }, + { name = "pydantic" }, + { name = "pydantic-core" }, + { name = "requests" }, + { name = "tokenizers" }, + { name = "types-requests" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/69/49/631a5fac290b704ba0be751d0370f8fb931ad7cb2de3c2f8e4b6a4ffb141/cohere-7.2.0.tar.gz", hash = "sha256:eb74b46882dcff913f826945ae9630cee6b67237ca05d763005c4ad9c4ad5bba", size = 219040, upload-time = "2026-09-28T20:41:03.903Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4e/a7/823e5bed159b0df507757743db3e0fb8de2deb39271b83bf6e97897e7536/cohere-7.2.0-py3-none-any.whl", hash = "sha256:d35cb91814d13eac6587e62bf78302b7683cdd036e7697a8e173ec76f2fb4e37", size = 370672, upload-time = "2026-09-28T20:41:02.334Z" }, +] + +[[package]] +name = "colorama" +version = "0.4.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, +] + +[[package]] +name = "confection" +version = "1.3.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ca/65/efd0fe8a936fc8ca2978cb7b82581fb20d901c6039e746a808f746b7647b/confection-1.3.3.tar.gz", hash = "sha256:f0f6810d567ff73993fe74d218ca5e1ffb6a44fb03f391257fc5d033546cbfaa", size = 54895, upload-time = "2026-03-24T18:45:24.331Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8d/e4/d66708bdf0d92fb4d49b22cdff4b10cec38aca5dcd7e81d909bb55c65cd7/confection-1.3.3-py3-none-any.whl", hash = "sha256:b9fef9ee84b237ef4611ec3eb5797b70e13063e6310ad9f15536373f5e313c82", size = 35902, upload-time = "2026-03-24T18:45:22.664Z" }, +] + +[[package]] +name = "coverage" +version = "7.16.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/2f/55/d1eaf3e73781174340a00dc1ba2aee8a65f82fadb18e2797b192b6b3925b/coverage-7.16.2.tar.gz", hash = "sha256:ca64d9f1f384f151b9511bec01126072acd2f313439f8ed015a22d8790aab6fa", size = 971999, upload-time = "2026-09-27T12:29:01.118Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f0/f6/8eb4f220ef24f84fb27d852d4f9bf83e0c73ec1a4a08dd9a87e3f4529739/coverage-7.16.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:1a37c6e478cf687e1aa30a593d19c92c02fad9d122b51ab73f51b8dc7a0c0fc9", size = 223993, upload-time = "2026-09-27T12:26:40.164Z" }, + { url = "https://files.pythonhosted.org/packages/40/23/d4bbaf0c154e0b0c2b5264890dbf6ef098dcb50ec8f2469be9490d191660/coverage-7.16.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0993d0e90858c03943d3cb152e068a20dd4707924deec84dd2230261baae3b1b", size = 224368, upload-time = "2026-09-27T12:26:41.762Z" }, + { url = "https://files.pythonhosted.org/packages/7f/48/fc1e88fd571ec5cb38150b7f89f7696ca1bdf9920e01432febb69774cc85/coverage-7.16.2-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:bb2fc905bbf4e6b7f40806ea79e31515abf6349594cdf0adf27c4215f0463204", size = 255358, upload-time = "2026-09-27T12:26:43.442Z" }, + { url = "https://files.pythonhosted.org/packages/1d/56/6785397d07c29c8e70fbb9a07e97d062b43c21ffc5f12385917847f09f63/coverage-7.16.2-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:4358b9c8c0125b460407f3017c6cce8156e904b32772c5630d27112f52bdbfe5", size = 257955, upload-time = "2026-09-27T12:26:45.725Z" }, + { url = "https://files.pythonhosted.org/packages/27/3b/c8cdd07721e5f99abd81cea970d971997f99bf158c0b85f51bd284179c8b/coverage-7.16.2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1f15254427c9b33eedac4f198eaf9e356eb4f6214551afb43da6194a2c088ad7", size = 259183, upload-time = "2026-09-27T12:26:47.208Z" }, + { url = "https://files.pythonhosted.org/packages/9b/11/606b192fe43d32574ec6238549d48de588fdcc18485682a5ec0a8ac357f2/coverage-7.16.2-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:9a75a4704ff640e46170042eec1f984385a121227c505d5a16ad8e495f452541", size = 261325, upload-time = "2026-09-27T12:26:49.084Z" }, + { url = "https://files.pythonhosted.org/packages/67/90/eea481f8b0305ceeb33f081a5f47e298391dbd1b589de0c4b3b3aa50d3f2/coverage-7.16.2-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:14253fc7bb15749b849795a06f5d3b6d8bc3fb8a4b5ddc341faf7a89dce205fc", size = 255531, upload-time = "2026-09-27T12:26:50.509Z" }, + { url = "https://files.pythonhosted.org/packages/6b/be/dedbf9aea1457b120c27ac10b8fc2a357f37fa2b54c3e7286d42980a0a2a/coverage-7.16.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:921415102a90637fcc2e3f169f61dad7699ecf690e8639fc21b813acbedc0967", size = 257329, upload-time = "2026-09-27T12:26:52.005Z" }, + { url = "https://files.pythonhosted.org/packages/fa/cb/b25c19d5bb2bd0f2e4e27fe8e2ffcae80c7a91ae181c0dc749ed60e9b1a4/coverage-7.16.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:cce2bc991293f15cc4084ca116827b5900c5f34e1a54dfe83f10ab5c43162eb7", size = 255294, upload-time = "2026-09-27T12:26:53.634Z" }, + { url = "https://files.pythonhosted.org/packages/5f/a2/892c5c5f4ad44b7b2ca009aee705191f3f268f15052244f2f9e3539b2e35/coverage-7.16.2-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:e1fa594c887365b69745f25a416806e61085dd07b94c9eae68a6e20730629b23", size = 259444, upload-time = "2026-09-27T12:26:55.243Z" }, + { url = "https://files.pythonhosted.org/packages/ed/99/a562537deba0a3e370182ae71c149be796c39d8087365f17a09188f27145/coverage-7.16.2-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:11e597173af1dc33d5f8a7332ada544199269a223af1ee1770ddd5e245ad0fe8", size = 255111, upload-time = "2026-09-27T12:26:56.851Z" }, + { url = "https://files.pythonhosted.org/packages/2d/20/854ec68641a9b3362ff068a32dfa41637299761617ef253791dbade6fc76/coverage-7.16.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:3e7f99698ba3a7d13988bdd984b7ebf13af4dbe2166dc8502eef90d77603b0a4", size = 256882, upload-time = "2026-09-27T12:26:58.41Z" }, + { url = "https://files.pythonhosted.org/packages/db/0d/748e4518b0ac0f9ff2687c248a6e5f8c0737306e709372632a2556f84443/coverage-7.16.2-cp313-cp313-win32.whl", hash = "sha256:f80bd9f9633eafc73d0a913ba2645c96ba58bba1befc30590f7c0fbfde59d865", size = 226045, upload-time = "2026-09-27T12:26:59.983Z" }, + { url = "https://files.pythonhosted.org/packages/31/fa/6e46edba66a183fe4d99d4bb52c173287e9b8dddabe0888d24cb8210e580/coverage-7.16.2-cp313-cp313-win_amd64.whl", hash = "sha256:8be099e979fc42559328a21828281b4578304191ae46ed4e80a407048a82eee6", size = 226581, upload-time = "2026-09-27T12:27:01.494Z" }, + { url = "https://files.pythonhosted.org/packages/1b/d9/9ef6845367600b336ff75d000444a0d32497d6972c833141bd39356abf68/coverage-7.16.2-cp313-cp313-win_arm64.whl", hash = "sha256:28ff850182a67d117990fa2ce5ea1032836d8c9630dae867e8bdd3bff4533b79", size = 226409, upload-time = "2026-09-27T12:27:03.116Z" }, + { url = "https://files.pythonhosted.org/packages/3f/0c/7a64e1ac90541a8edf50daef0914848011fb057a5bf55284a4811e21939a/coverage-7.16.2-py3-none-any.whl", hash = "sha256:11d28e9123a9156cb405d8d27b44256c9a58fb5decc2073a8f17862057e3aa0f", size = 215754, upload-time = "2026-09-27T12:28:59.075Z" }, +] + +[[package]] +name = "croniter" +version = "6.2.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "python-dateutil" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/37/57/2e2a65aee2a70483cb28e2b7e15a072d00a523207593b44400d4717bb100/croniter-6.2.4.tar.gz", hash = "sha256:fc124f751b1b04805c2a04b061898b436b45ab2320b045e1e052ea895de65189", size = 166267, upload-time = "2026-07-10T09:52:59.955Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cd/ba/d678e5bd329646ca51d3c92addbc77804e86d21f4b6b6a027218e6abb010/croniter-6.2.4-py3-none-any.whl", hash = "sha256:8ef3d544107a5c05a150a2d78f8bf5a8eb9c5c4d93405a736b824109574e3f4d", size = 46677, upload-time = "2026-07-10T09:52:58.425Z" }, +] + +[[package]] +name = "cryptography" +version = "50.0.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cffi", marker = "platform_python_implementation != 'PyPy'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/9d/af/182eb91b0df3fe75c4d9f26fe70684569566745f6ba7e5c9c73a862c5252/cryptography-50.0.2.tar.gz", hash = "sha256:7b46165bb56eb4704e2eaaf86f3c940d19154535d9b0ca7d6d590b04060e00d5", size = 880623, upload-time = "2026-09-30T15:30:04.884Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e5/56/d194340cc4a57535e82e1bee9e89667ac4b7c13b5d3f59686deae3094dd5/cryptography-50.0.2-cp311-abi3-macosx_11_0_arm64.whl", hash = "sha256:fa8f5efb344d6908a1ce62f4a24e2e5780f825d6f53f5f50ec5ffacac72936cb", size = 3914904, upload-time = "2026-09-30T14:43:44.339Z" }, + { url = "https://files.pythonhosted.org/packages/d9/69/c9bd862c3bf43d6399c433caf002df16e2dffd4be49bdf515cda38038711/cryptography-50.0.2-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:79def8d059362e7831389ed3be0ecdf58a89386e1271e35dd9f5af84e81bffd0", size = 4731146, upload-time = "2026-09-30T14:43:47.113Z" }, + { url = "https://files.pythonhosted.org/packages/21/69/64cef1f702bf6657e0cc186ed1a2891d50d29fb41586b254e1c07adea261/cryptography-50.0.2-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:630ebfea3bf689d075f82316324ff7433dc447fe6bc1bfc76524b74b4a9567d2", size = 4719841, upload-time = "2026-09-30T14:43:49.01Z" }, + { url = "https://files.pythonhosted.org/packages/38/6b/61a3f8d8c5e1e49a6cddccafc4015cc1c0021360ab0acb4080e7a423644a/cryptography-50.0.2-cp311-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:f9f6143a8c75945eb960d9eb98905a441394abfa24afaae239d514ffb2586480", size = 4738340, upload-time = "2026-09-30T14:43:50.932Z" }, + { url = "https://files.pythonhosted.org/packages/7b/2e/7212ca32fd43dc91f2f41db20160b268098874b4c9a0e7be94d6835f5b2e/cryptography-50.0.2-cp311-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:a582ab2ae1d34f67112cadc86702774c9ea4374df6bca6afe672817203c99134", size = 5367029, upload-time = "2026-09-30T14:43:52.911Z" }, + { url = "https://files.pythonhosted.org/packages/1a/f1/b474e930c4d910328780e3940da76f5aa5cbc48ce1fc14e44d239d9ea9db/cryptography-50.0.2-cp311-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:4061c0079120205fb760c58acab6443e217307dcf05e3702cf970e0689972856", size = 4753050, upload-time = "2026-09-30T14:43:55.272Z" }, + { url = "https://files.pythonhosted.org/packages/7c/52/9af10e80ac16b0fcc2123f9cbd5e7afbd0fd5075bb7a607c592258a39cda/cryptography-50.0.2-cp311-abi3-manylinux_2_31_armv7l.whl", hash = "sha256:ac9ed99d81760c62fe89d5f0815cdfa1ba9a35141cf30f1c2d044f04b4803d2e", size = 4376724, upload-time = "2026-09-30T14:43:57.24Z" }, + { url = "https://files.pythonhosted.org/packages/71/37/6202e488cc1eb625ea110c292c6bda92823176e023f427d8d5660ce8d632/cryptography-50.0.2-cp311-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:87e9ce85beb6b328ba370cc6e6aea483c92617b4c95b1d33a49297eb662bfb04", size = 4737859, upload-time = "2026-09-30T14:43:59.541Z" }, + { url = "https://files.pythonhosted.org/packages/8f/30/e86d7d518489b0ae2497091a35287abcb1a2ce4037837a34afbe9b1d6964/cryptography-50.0.2-cp311-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:f265528741e048bce55c3463ed721fb0aa45a5888d8add8cfeccb3035451bbdc", size = 5324103, upload-time = "2026-09-30T14:44:01.901Z" }, + { url = "https://files.pythonhosted.org/packages/d3/69/2c833a049475e0a3444e94c7d0aca0aa51d166374a449b09e92ac98138de/cryptography-50.0.2-cp311-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:9dab55f57c74c3cad24c323bacbbd04be4705ba6eb0d92e920b1fc4837ed5079", size = 4752576, upload-time = "2026-09-30T14:44:04.545Z" }, + { url = "https://files.pythonhosted.org/packages/6c/5d/906970b83bbfc1f5bbfb677a143c181f2801f23b6a7204a3b47c42c97e65/cryptography-50.0.2-cp311-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:25784ce8b9621c90c643efb9e1e2162ab3b0224cae446ad5e70e7fcb1ce18b51", size = 4870819, upload-time = "2026-09-30T14:44:06.884Z" }, + { url = "https://files.pythonhosted.org/packages/68/e3/f2298d3bb55e0c4a91841ec4d01b3f020ba8c5fbf15ccdcc6dcf03f97025/cryptography-50.0.2-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:85d0d9a31b9098e98534226d5686b47264b95e62ce459dc2e62fdfc809f9fe93", size = 5030152, upload-time = "2026-09-30T14:44:09.443Z" }, + { url = "https://files.pythonhosted.org/packages/9a/4f/adfc442765721292fff86d314ce385d3249d22db42295c0dd057727b60f3/cryptography-50.0.2-cp311-abi3-win_amd64.whl", hash = "sha256:7afa5a6602a9f29af1f3a2965f831bae7c9d5d597b7cbb716d41ab3b7d89879c", size = 3824692, upload-time = "2026-09-30T14:44:11.671Z" }, + { url = "https://files.pythonhosted.org/packages/2d/49/93f6a6e7a87c9aa68d44d3e1cdb5fe8f60c90d5d2f46acae9a56892816b8/cryptography-50.0.2-cp315-abi3.abi3t-macosx_11_0_arm64.whl", hash = "sha256:edc3342adf8f697fc5f59c887a304356f147b397809440ed64e2fa6af2f50f37", size = 4133708, upload-time = "2026-09-30T14:44:41.807Z" }, + { url = "https://files.pythonhosted.org/packages/8c/75/32ac2a56243d778805c16ca6a32b8f74fb757df7e28d7ecb560afafb59cf/cryptography-50.0.2-cp315-abi3.abi3t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d370b8d1dfcdf7130178137f6fbee6140774a1acc6cacefc4b42643ec11d0a3a", size = 4956267, upload-time = "2026-09-30T14:44:43.693Z" }, + { url = "https://files.pythonhosted.org/packages/aa/a4/2c8d734e43d97f0842ee9f1b7b4bfb3d0cf5e19edebf43c2afe6675c2320/cryptography-50.0.2-cp315-abi3.abi3t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f2f9bd7f90c64fe89253f0a2c05e3c4856072660429ce8831b4235bf29403a67", size = 4966465, upload-time = "2026-09-30T14:44:45.769Z" }, + { url = "https://files.pythonhosted.org/packages/c2/58/ee288c829a6f41f6235ae9dd33d82fd19b45442b65b4c8a3da36963d9f7a/cryptography-50.0.2-cp315-abi3.abi3t-manylinux_2_28_aarch64.whl", hash = "sha256:e275096ea1e60cc595cda2836fd4a6c725d1125108b868be17f53684d164e2cc", size = 4959356, upload-time = "2026-09-30T14:44:48.211Z" }, + { url = "https://files.pythonhosted.org/packages/92/20/9ded6d51ddd9897f6b6e81fb9ebea7951d7cc5d6c890b0ed8abf77a51a80/cryptography-50.0.2-cp315-abi3.abi3t-manylinux_2_28_ppc64le.whl", hash = "sha256:b13478603dcd0a2479ff8e87e2c19a7d525734686fe3c49542472293a204212d", size = 5548822, upload-time = "2026-09-30T14:44:50.86Z" }, + { url = "https://files.pythonhosted.org/packages/02/a8/8df951850d6b31d2a00218f19e2b3f999523437ed7a819df7fa427942fca/cryptography-50.0.2-cp315-abi3.abi3t-manylinux_2_28_x86_64.whl", hash = "sha256:58a0c478eeca76fe5e07993c5a0703def34a6dc6a0cda4f5564639b33112ffe7", size = 5001199, upload-time = "2026-09-30T14:44:53.379Z" }, + { url = "https://files.pythonhosted.org/packages/8b/f9/36b3022218ce75b7cdf068fb95f809f9bd0d820e4955ef43b90c255cc7ac/cryptography-50.0.2-cp315-abi3.abi3t-manylinux_2_31_armv7l.whl", hash = "sha256:d38cdff612d06fa6a32840d5e1b1f7a27cee4a349aa9085d94a67789d6bfd408", size = 4629333, upload-time = "2026-09-30T14:44:55.635Z" }, + { url = "https://files.pythonhosted.org/packages/8c/72/20f99a219f6af47cdd1cbd978c243b92d71496e168a746138af44ded4f29/cryptography-50.0.2-cp315-abi3.abi3t-manylinux_2_34_aarch64.whl", hash = "sha256:fdd28f912fccfec1846a94e2e1e8f9b0012f557f0c46fe4f3eb0d7a87afcf90b", size = 4958822, upload-time = "2026-09-30T14:44:59.639Z" }, + { url = "https://files.pythonhosted.org/packages/f2/20/196f112617fb08eb4d608a2a6c422373d46f9cc2857f38fc0667033c0899/cryptography-50.0.2-cp315-abi3.abi3t-manylinux_2_34_ppc64le.whl", hash = "sha256:cbc8738fd8526d80f35cb3a40d41f41a2e7030bb3b18b09a6778ef63d291c2fd", size = 5506351, upload-time = "2026-09-30T14:45:02.267Z" }, + { url = "https://files.pythonhosted.org/packages/24/95/83378121ef3eaaaf71d4b781577ff794acb39b9e1b87a3f156898c8497ed/cryptography-50.0.2-cp315-abi3.abi3t-manylinux_2_34_x86_64.whl", hash = "sha256:e105ab60406787da31fccc883fc0f733af1efd78f0136a4599692c4083a73d0c", size = 5000859, upload-time = "2026-09-30T14:45:05.009Z" }, + { url = "https://files.pythonhosted.org/packages/22/f7/70fd7ae4d1dbfa7ba29b02e1b9068771519a86027756510b700ce81086a8/cryptography-50.0.2-cp315-abi3.abi3t-musllinux_1_2_aarch64.whl", hash = "sha256:6f8700550aa1474a91e5dc07049c46f98b423b5b1ddd0483e0b51362eeeaf5be", size = 5092151, upload-time = "2026-09-30T15:29:15.932Z" }, + { url = "https://files.pythonhosted.org/packages/d4/be/688367b74de86984bd58d8efacfc7c9e68b89a6a22ced0fb4f38db50254a/cryptography-50.0.2-cp315-abi3.abi3t-musllinux_1_2_x86_64.whl", hash = "sha256:c71be1cbfa5cd9a41ee452acf1eccd82b2c05950358b106ec8ceb83411d1a020", size = 5286120, upload-time = "2026-09-30T15:29:18.309Z" }, + { url = "https://files.pythonhosted.org/packages/39/d1/55f8a3f2ef5d1529e16835ef10cf0fe3d559ce237b46dddc440c0bba3649/cryptography-50.0.2-cp315-abi3.abi3t-win_amd64.whl", hash = "sha256:c423ab384a46c4dff7217b2ea5ba2e11cffdeab6441acd04cf65a369caf0366c", size = 4111557, upload-time = "2026-09-30T15:29:20.155Z" }, + { url = "https://files.pythonhosted.org/packages/23/ad/ac987755d00e1e64273760228d2635ae38dae2be83e3c6e0d3289d91dec3/cryptography-50.0.2-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:0ec5f09541743261e66e291b4a0cbf0fb2997aeaab6d9e9c740b9dba1b58d1c2", size = 3943588, upload-time = "2026-09-30T15:29:22.265Z" }, + { url = "https://files.pythonhosted.org/packages/d5/8d/6d585339bedf85d45044c85d8412dac53f2bb6f918e8b7777efba1787844/cryptography-50.0.2-cp39-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:c5e67125c7dca78d199ec4e116aa93dbb83494808ecbb8211a2cb09b1bf41dbd", size = 4756166, upload-time = "2026-09-30T15:29:24.58Z" }, + { url = "https://files.pythonhosted.org/packages/bf/f1/1c1f6874e8550cfddd4b688ceb38cefb6ed15ceed224d56f133f3d88c214/cryptography-50.0.2-cp39-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:ee247f5c245c9a2fe7c8e2214e295918838e44e00a45a6718451e4004219e767", size = 4749145, upload-time = "2026-09-30T15:29:26.807Z" }, + { url = "https://files.pythonhosted.org/packages/c1/63/61b15dc1a8de03fe0adbe3fd7608b3ad5c73bf50993bbcb1faaa930afe33/cryptography-50.0.2-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:dfe9763530994147d9af1def057a5b9658b00e8f8fe8743d144d1e0911c2e454", size = 4763638, upload-time = "2026-09-30T15:29:28.588Z" }, + { url = "https://files.pythonhosted.org/packages/fc/35/b345bdfa40c9126df1a9d33236aa98418367931b8725f84fc3ae2b98dc59/cryptography-50.0.2-cp39-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:58ddb5a8e3179d12f19e4ea34d2d32e9d63a4baa142c875c1eb59f41b7243acd", size = 5382217, upload-time = "2026-09-30T15:29:30.589Z" }, + { url = "https://files.pythonhosted.org/packages/4f/87/ef344a9e616871f2519c22d6afcda79ddd5d35e9592d95eb6e677608d055/cryptography-50.0.2-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:f21e8a22c8605750c7af886bab299a363721264061b4ac0a30efb73cfd58efc5", size = 4781387, upload-time = "2026-09-30T15:29:32.605Z" }, + { url = "https://files.pythonhosted.org/packages/90/5b/f2fdb13cd0b96f6f932c8627bb292a45f11c64d21620a8e120aee9a3b848/cryptography-50.0.2-cp39-abi3-manylinux_2_31_armv7l.whl", hash = "sha256:9c8402a82ea0dc4ceeab793db05f0fafa8ca139ca34fcde5df0f596103c74107", size = 4403790, upload-time = "2026-09-30T15:29:34.374Z" }, + { url = "https://files.pythonhosted.org/packages/bc/ce/7e4f662b1e3c393513569e402cfc85ac7da0bd3d5435e122a3140219eb2d/cryptography-50.0.2-cp39-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:0ddc924c04591c2811ca024d62ecad4f7f6f08af8939c211438f48a16bd23602", size = 4764319, upload-time = "2026-09-30T15:29:36.149Z" }, + { url = "https://files.pythonhosted.org/packages/3c/3f/86ff33ce34cc0de6847fb96e035a1a760d81652e38643f617c02ad32ef7a/cryptography-50.0.2-cp39-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:a6557e5f38e065ca9fbdaf7cfc7435ecb1d113aa81a022d1b51921ee7432e227", size = 5338560, upload-time = "2026-09-30T15:29:39.053Z" }, + { url = "https://files.pythonhosted.org/packages/40/cf/6b5c8e2fd9202d98988ab7cb5cc5c991704c4ad55f492ff408e4969f83f1/cryptography-50.0.2-cp39-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:1981f1db4630889b9ef7803fadef12b056f428cb6b85c27ba57b774793b6093c", size = 4780973, upload-time = "2026-09-30T15:29:41.251Z" }, + { url = "https://files.pythonhosted.org/packages/10/bf/8d6ebc7dded797bd0f0160d52188021211f011a2b164ef0ae1dac4587465/cryptography-50.0.2-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:7a8701d6b584d76e909e3d305b7d126b41439876a5aaf76cddc67fc230eafa2e", size = 4897738, upload-time = "2026-09-30T15:29:43.106Z" }, + { url = "https://files.pythonhosted.org/packages/d4/aa/f3f6e0de7e6253b8baa8b2d8fb9d50924fa75cee3d4624bd4bc1208ee923/cryptography-50.0.2-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:ce47f66801c20ec6c6632453bb5960fe38939e9306970b48b3a5a26de7745d94", size = 5058280, upload-time = "2026-09-30T15:29:44.827Z" }, + { url = "https://files.pythonhosted.org/packages/f6/b6/a1faf3a27ae9405fb34b1713cc73b2d8a26b04d5c561578fa2e6ef3e5bb9/cryptography-50.0.2-cp39-abi3-win_amd64.whl", hash = "sha256:4e81d95e5bafc2d6e34e4bed780e53e4d5b9a2f928573428aa4d35fbec1eb0de", size = 3854095, upload-time = "2026-09-30T15:29:46.782Z" }, +] + +[[package]] +name = "cuda-bindings" +version = "13.4.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cuda-pathfinder" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/a7/97/7d75105a92ee18b7764f5cf60672d6a966842348a2a049e663fe690902ff/cuda_bindings-13.4.4-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0c3f4cc887eac0d5edb5d7396cc78b336bee151a97e2ba7acf59e8b9380132d0", size = 6316532, upload-time = "2026-10-14T12:35:30.291Z" }, + { url = "https://files.pythonhosted.org/packages/ba/8f/aedec367fea64267594a26ede3704f241e1bee465962f3a92d6186c774b7/cuda_bindings-13.4.4-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5d6adc44f098472d8ac2d6211923eea6081830521852dc77f8c9237bf9320a59", size = 6929120, upload-time = "2026-10-14T12:35:32.508Z" }, +] + +[[package]] +name = "cuda-pathfinder" +version = "1.8.3" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b9/fb/f8e1890428f9f590b4beebd63b068aac1ce32a3331510c847b9f9a78f261/cuda_pathfinder-1.8.3-py3-none-any.whl", hash = "sha256:e29e59829c297a7a5233bd9cc71094fc5bddbd076951482670178f9eade39b1f", size = 62561, upload-time = "2026-10-02T03:20:23.712Z" }, +] + +[[package]] +name = "cuda-toolkit" +version = "13.0.3.0" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/c7/a79086a62c98befcdb8349656c6f114e2db3b8b2422f6e25c97a7f2a9a3c/cuda_toolkit-13.0.3.0-py2.py3-none-any.whl", hash = "sha256:d693caaa261214ddd7dbb60d68e71cbed884e68c2be7509778f3051da0b91c3f", size = 2512, upload-time = "2026-04-14T00:50:08.173Z" }, +] + +[package.optional-dependencies] +cublas = [ + { name = "nvidia-cublas", marker = "(platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux') or (platform_machine == 'AMD64' and sys_platform == 'win32')" }, + { name = "nvidia-cuda-nvrtc", marker = "(platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux') or (platform_machine == 'AMD64' and sys_platform == 'win32')" }, +] +cudart = [ + { name = "nvidia-cuda-runtime", marker = "(platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux') or (platform_machine == 'AMD64' and sys_platform == 'win32')" }, +] +cufft = [ + { name = "nvidia-cufft", marker = "(platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux') or (platform_machine == 'AMD64' and sys_platform == 'win32')" }, + { name = "nvidia-nvjitlink", marker = "(platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux') or (platform_machine == 'AMD64' and sys_platform == 'win32')" }, +] +cufile = [ + { name = "nvidia-cufile", marker = "(platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, +] +cupti = [ + { name = "nvidia-cuda-cupti", marker = "(platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux') or (platform_machine == 'AMD64' and sys_platform == 'win32')" }, +] +curand = [ + { name = "nvidia-curand", marker = "(platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux') or (platform_machine == 'AMD64' and sys_platform == 'win32')" }, +] +cusolver = [ + { name = "nvidia-cublas", marker = "(platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux') or (platform_machine == 'AMD64' and sys_platform == 'win32')" }, + { name = "nvidia-cusolver", marker = "(platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux') or (platform_machine == 'AMD64' and sys_platform == 'win32')" }, + { name = "nvidia-cusparse", marker = "(platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux') or (platform_machine == 'AMD64' and sys_platform == 'win32')" }, + { name = "nvidia-nvjitlink", marker = "(platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux') or (platform_machine == 'AMD64' and sys_platform == 'win32')" }, +] +cusparse = [ + { name = "nvidia-cusparse", marker = "(platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux') or (platform_machine == 'AMD64' and sys_platform == 'win32')" }, + { name = "nvidia-nvjitlink", marker = "(platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux') or (platform_machine == 'AMD64' and sys_platform == 'win32')" }, +] +nvjitlink = [ + { name = "nvidia-nvjitlink", marker = "(platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux') or (platform_machine == 'AMD64' and sys_platform == 'win32')" }, +] +nvrtc = [ + { name = "nvidia-cuda-nvrtc", marker = "(platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux') or (platform_machine == 'AMD64' and sys_platform == 'win32')" }, +] +nvtx = [ + { name = "nvidia-nvtx", marker = "(platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux') or (platform_machine == 'AMD64' and sys_platform == 'win32')" }, +] + +[[package]] +name = "cymem" +version = "2.0.13" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/c0/8f/2f0fbb32535c3731b7c2974c569fb9325e0a38ed5565a08e1139a3b71e82/cymem-2.0.13.tar.gz", hash = "sha256:1c91a92ae8c7104275ac26bd4d29b08ccd3e7faff5893d3858cb6fadf1bc1588", size = 12320, upload-time = "2025-11-14T14:58:36.902Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ce/0f/95a4d1e3bebfdfa7829252369357cf9a764f67569328cd9221f21e2c952e/cymem-2.0.13-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:891fd9030293a8b652dc7fb9fdc79a910a6c76fc679cd775e6741b819ffea476", size = 43478, upload-time = "2025-11-14T14:57:42.682Z" }, + { url = "https://files.pythonhosted.org/packages/bf/a0/8fc929cc29ae466b7b4efc23ece99cbd3ea34992ccff319089c624d667fd/cymem-2.0.13-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:89c4889bd16513ce1644ccfe1e7c473ba7ca150f0621e66feac3a571bde09e7e", size = 42695, upload-time = "2025-11-14T14:57:43.741Z" }, + { url = "https://files.pythonhosted.org/packages/4a/b3/deeb01354ebaf384438083ffe0310209ef903db3e7ba5a8f584b06d28387/cymem-2.0.13-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:45dcaba0f48bef9cc3d8b0b92058640244a95a9f12542210b51318da97c2cf28", size = 250573, upload-time = "2025-11-14T14:57:44.81Z" }, + { url = "https://files.pythonhosted.org/packages/36/36/bc980b9a14409f3356309c45a8d88d58797d02002a9d794dd6c84e809d3a/cymem-2.0.13-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:e96848faaafccc0abd631f1c5fb194eac0caee4f5a8777fdbb3e349d3a21741c", size = 254572, upload-time = "2025-11-14T14:57:46.023Z" }, + { url = "https://files.pythonhosted.org/packages/fd/dd/a12522952624685bd0f8968e26d2ed6d059c967413ce6eb52292f538f1b0/cymem-2.0.13-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e02d3e2c3bfeb21185d5a4a70790d9df40629a87d8d7617dc22b4e864f665fa3", size = 248060, upload-time = "2025-11-14T14:57:47.605Z" }, + { url = "https://files.pythonhosted.org/packages/08/11/5dc933ddfeb2dfea747a0b935cb965b9a7580b324d96fc5f5a1b5ff8df29/cymem-2.0.13-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fece5229fd5ecdcd7a0738affb8c59890e13073ae5626544e13825f26c019d3c", size = 254601, upload-time = "2025-11-14T14:57:48.861Z" }, + { url = "https://files.pythonhosted.org/packages/70/66/d23b06166864fa94e13a98e5922986ce774832936473578febce64448d75/cymem-2.0.13-cp313-cp313-win_amd64.whl", hash = "sha256:38aefeb269597c1a0c2ddf1567dd8605489b661fa0369c6406c1acd433b4c7ba", size = 40103, upload-time = "2025-11-14T14:57:50.396Z" }, + { url = "https://files.pythonhosted.org/packages/2f/9e/c7b21271ab88a21760f3afdec84d2bc09ffa9e6c8d774ad9d4f1afab0416/cymem-2.0.13-cp313-cp313-win_arm64.whl", hash = "sha256:717270dcfd8c8096b479c42708b151002ff98e434a7b6f1f916387a6c791e2ad", size = 36016, upload-time = "2025-11-14T14:57:51.611Z" }, + { url = "https://files.pythonhosted.org/packages/7f/28/d3b03427edc04ae04910edf1c24b993881c3ba93a9729a42bcbb816a1808/cymem-2.0.13-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:7e1a863a7f144ffb345397813701509cfc74fc9ed360a4d92799805b4b865dd1", size = 46429, upload-time = "2025-11-14T14:57:52.582Z" }, + { url = "https://files.pythonhosted.org/packages/35/a9/7ed53e481f47ebfb922b0b42e980cec83e98ccb2137dc597ea156642440c/cymem-2.0.13-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:c16cb80efc017b054f78998c6b4b013cef509c7b3d802707ce1f85a1d68361bf", size = 46205, upload-time = "2025-11-14T14:57:53.64Z" }, + { url = "https://files.pythonhosted.org/packages/61/39/a3d6ad073cf7f0fbbb8bbf09698c3c8fac11be3f791d710239a4e8dd3438/cymem-2.0.13-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:0d78a27c88b26c89bd1ece247d1d5939dba05a1dae6305aad8fd8056b17ddb51", size = 296083, upload-time = "2025-11-14T14:57:55.922Z" }, + { url = "https://files.pythonhosted.org/packages/36/0c/20697c8bc19f624a595833e566f37d7bcb9167b0ce69de896eba7cfc9c2d/cymem-2.0.13-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:6d36710760f817194dacb09d9fc45cb6a5062ed75e85f0ef7ad7aeeb13d80cc3", size = 286159, upload-time = "2025-11-14T14:57:57.106Z" }, + { url = "https://files.pythonhosted.org/packages/82/d4/9326e3422d1c2d2b4a8fb859bdcce80138f6ab721ddafa4cba328a505c71/cymem-2.0.13-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:c8f30971cadd5dcf73bcfbbc5849b1f1e1f40db8cd846c4aa7d3b5e035c7b583", size = 288186, upload-time = "2025-11-14T14:57:58.334Z" }, + { url = "https://files.pythonhosted.org/packages/ed/bc/68da7dd749b72884dc22e898562f335002d70306069d496376e5ff3b6153/cymem-2.0.13-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:9d441d0e45798ec1fd330373bf7ffa6b795f229275f64016b6a193e6e2a51522", size = 290353, upload-time = "2025-11-14T14:58:00.562Z" }, + { url = "https://files.pythonhosted.org/packages/50/23/dbf2ad6ecd19b99b3aab6203b1a06608bbd04a09c522d836b854f2f30f73/cymem-2.0.13-cp313-cp313t-win_amd64.whl", hash = "sha256:d1c950eebb9f0f15e3ef3591313482a5a611d16fc12d545e2018cd607f40f472", size = 44764, upload-time = "2025-11-14T14:58:01.793Z" }, + { url = "https://files.pythonhosted.org/packages/54/3f/35701c13e1fc7b0895198c8b20068c569a841e0daf8e0b14d1dc0816b28f/cymem-2.0.13-cp313-cp313t-win_arm64.whl", hash = "sha256:042e8611ef862c34a97b13241f5d0da86d58aca3cecc45c533496678e75c5a1f", size = 38964, upload-time = "2025-11-14T14:58:02.87Z" }, +] + +[[package]] +name = "distro" +version = "1.9.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/fc/f8/98eea607f65de6527f8a2e8885fc8015d3e6f5775df186e443e0964a11c3/distro-1.9.0.tar.gz", hash = "sha256:2fa77c6fd8940f116ee1d6b94a2f90b13b5ea8d019b98bc8bafdcabcdd9bdbed", size = 60722, upload-time = "2023-12-24T09:54:32.31Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/12/b3/231ffd4ab1fc9d679809f356cebee130ac7daa00d6d6f3206dd4fd137e9e/distro-1.9.0-py3-none-any.whl", hash = "sha256:7bffd925d65168f85027d8da9af6bddab658135b840670a223589bc0c8ef02b2", size = 20277, upload-time = "2023-12-24T09:54:30.421Z" }, +] + +[[package]] +name = "dnspython" +version = "2.9.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ef/4a/50822184bd67cc6493f0fb6a880749158fcd31ab3fa07409acfd91f9fc85/dnspython-2.9.0.tar.gz", hash = "sha256:b44dc6b18f07a8b1c56676a19fbfdb5209415b046a9cece286baafa87ff3f7f1", size = 423560, upload-time = "2026-10-09T00:07:24.352Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/10/02/cdcc9b7c051786a103c3b09e1003a82fa0c66bcb91ffbdabcfbf7b4163b9/dnspython-2.9.0-py3-none-any.whl", hash = "sha256:9a4aedb833c3c1b49214d04d44d3032ab7a9135f7c1d29a549b4ff78fd82fda9", size = 354822, upload-time = "2026-10-09T00:07:22.622Z" }, +] + +[[package]] +name = "docker" +version = "7.2.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pywin32", marker = "sys_platform == 'win32'" }, + { name = "requests" }, + { name = "urllib3" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/88/7f/731ff914b0255d3d065f45fd4e626d4b8c95dbcbaada049f337a6ac16410/docker-7.2.0.tar.gz", hash = "sha256:cebb93773d334f778e023a7ee352a8d6e13ab1bd3b863a4d4a59dec897df43ac", size = 118731, upload-time = "2026-07-09T14:53:46.39Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/75/23/529140fe1aab80fc6992f93a706deec709140a6397439139a054e1515c45/docker-7.2.0-py3-none-any.whl", hash = "sha256:a3f45fdeb9165e2d25d9a1d02ddf3bc70fb572cf5ebbf9b58558c22caf29b71f", size = 148775, upload-time = "2026-07-09T14:53:45.224Z" }, +] + +[[package]] +name = "docstring-parser" +version = "0.18.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e0/4d/f332313098c1de1b2d2ff91cf2674415cc7cddab2ca1b01ae29774bd5fdf/docstring_parser-0.18.0.tar.gz", hash = "sha256:292510982205c12b1248696f44959db3cdd1740237a968ea1e2e7a900eeb2015", size = 29341, upload-time = "2026-04-14T04:09:19.867Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a7/5f/ed01f9a3cdffbd5a008556fc7b2a08ddb1cc6ace7effa7340604b1d16699/docstring_parser-0.18.0-py3-none-any.whl", hash = "sha256:b3fcbed555c47d8479be0796ef7e19c2670d428d72e96da63f3a40122860374b", size = 22484, upload-time = "2026-04-14T04:09:18.638Z" }, +] + +[[package]] +name = "duckdb" +version = "1.5.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/59/0b/d65ea3be00ea79aa276a8388bec588a9cbf409ce637c6d306e5316210d15/duckdb-1.5.6.tar.gz", hash = "sha256:166a91dbfacfc0c9f08cc76c0243cb6d3d4296bfab5bad72a3cfb63140a5b7c8", size = 18032957, upload-time = "2026-09-28T13:38:37.978Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b1/5e/a476197fcba557738a588ec844747a19bc0a24b0e6f1809e308f29d68c0e/duckdb-1.5.6-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ae352646374cacf48e9981cf031191c494865192fc436d13667a2531fc5d1da3", size = 32810376, upload-time = "2026-09-28T13:38:05.148Z" }, + { url = "https://files.pythonhosted.org/packages/0c/6d/5466a2b53ddd557644dfa47a763f68748efccdf282e6ae7c4f1bcfb3da69/duckdb-1.5.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:5a1261e90785e9d29953293e44f60fa073bd1137098924e8de21a037a861b051", size = 17405385, upload-time = "2026-09-28T13:38:07.363Z" }, + { url = "https://files.pythonhosted.org/packages/d4/a0/bf87071170835ee4a34fe764fc11c1c6e7040a0e021b36c1b6f834a4c22f/duckdb-1.5.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:97dd7a555b8f5298b76bc7d48a11cb2c64336e8de9bfde783cffb86ea9f54807", size = 15533132, upload-time = "2026-09-28T13:38:09.681Z" }, + { url = "https://files.pythonhosted.org/packages/31/e0/38095c8e140ecfbe847519ac07bcba94301b8fbb76b2870015e33e07f179/duckdb-1.5.6-cp313-cp313-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:364992ba1089a2b327391cfcb68fd0bd0ce9090cf293baef861a0ba6847abfee", size = 19454994, upload-time = "2026-09-28T13:38:11.836Z" }, + { url = "https://files.pythonhosted.org/packages/70/21/61dd2876bbaa69cf77d7b5c620e52e8b25faae7096f4d2e4a812b52095d7/duckdb-1.5.6-cp313-cp313-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:644f54ce99b3b61844bc9a3fe80e0aecb1ea4084b1fffc4396d1569db6111679", size = 21568700, upload-time = "2026-09-28T13:38:14.258Z" }, + { url = "https://files.pythonhosted.org/packages/4a/4a/100730e7785e85268be4d4d5bd62cfc8314e261d2f42efa208243eef35cb/duckdb-1.5.6-cp313-cp313-win_amd64.whl", hash = "sha256:ced693d33ddcee2e5345f077d342c87d2aaa80e41c514e64c9ff2d4e5963c251", size = 13190707, upload-time = "2026-09-28T13:38:16.875Z" }, + { url = "https://files.pythonhosted.org/packages/f3/2e/bc7f44eab4e89ee5c1cb427bb1168ad021d985042e6841ec0694c3d3d501/duckdb-1.5.6-cp313-cp313-win_arm64.whl", hash = "sha256:41ecc75bb9328d72d154a705c1a653d2c5c60f686a5c0c6578aa80020753c884", size = 14020962, upload-time = "2026-09-28T13:38:19.007Z" }, +] + +[[package]] +name = "email-validator" +version = "2.3.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "dnspython" }, + { name = "idna" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f5/22/900cb125c76b7aaa450ce02fd727f452243f2e91a61af068b40adba60ea9/email_validator-2.3.0.tar.gz", hash = "sha256:9fc05c37f2f6cf439ff414f8fc46d917929974a82244c20eb10231ba60c54426", size = 51238, upload-time = "2025-08-26T13:09:06.831Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/de/15/545e2b6cf2e3be84bc1ed85613edd75b8aea69807a71c26f4ca6a9258e82/email_validator-2.3.0-py3-none-any.whl", hash = "sha256:80f13f623413e6b197ae73bb10bf4eb0908faf509ad8362c5edeb0be7fd450b4", size = 35604, upload-time = "2025-08-26T13:09:05.858Z" }, +] + +[[package]] +name = "et-xmlfile" +version = "2.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d3/38/af70d7ab1ae9d4da450eeec1fa3918940a5fafb9055e934af8d6eb0c2313/et_xmlfile-2.0.0.tar.gz", hash = "sha256:dab3f4764309081ce75662649be815c4c9081e88f0837825f90fd28317d4da54", size = 17234, upload-time = "2024-10-25T17:25:40.039Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c1/8b/5fe2cc11fee489817272089c4203e679c63b570a5aaeb18d852ae3cbba6a/et_xmlfile-2.0.0-py3-none-any.whl", hash = "sha256:7a91720bc756843502c3b7504c77b8fe44217c85c537d85037f0f536151b2caa", size = 18059, upload-time = "2024-10-25T17:25:39.051Z" }, +] + +[[package]] +name = "eval-type-backport" +version = "0.4.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/1c/15/273a4baf8248d6d76220723c3caf039d283774b31a7c46ba686120145b76/eval_type_backport-0.4.0.tar.gz", hash = "sha256:8397d25e6524c2e67b9576bb0636be27dea2192017711220c534ec2de921e9b0", size = 10260, upload-time = "2026-06-02T13:22:06.059Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/50/a7/bb99bf5e6f78736ddb53480f2c3ff3702ffe2196a7c5e1661c03081d398e/eval_type_backport-0.4.0-py3-none-any.whl", hash = "sha256:ad5e2a8db71b6696a56eafb938b0f5a337d3217f256b8e158b469422b4772b20", size = 6432, upload-time = "2026-06-02T13:22:04.827Z" }, +] + +[[package]] +name = "exceptiongroup" +version = "1.3.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/50/79/66800aadf48771f6b62f7eb014e352e5d06856655206165d775e675a02c9/exceptiongroup-1.3.1.tar.gz", hash = "sha256:8b412432c6055b0b7d14c310000ae93352ed6754f70fa8f7c34141f91c4e3219", size = 30371, upload-time = "2025-11-21T23:01:54.787Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8a/0e/97c33bf5009bdbac74fd2beace167cab3f978feb69cc36f1ef79360d6c4e/exceptiongroup-1.3.1-py3-none-any.whl", hash = "sha256:a7a39a3bd276781e98394987d3a5701d0c4edffb633bb7a5144577f82c773598", size = 16740, upload-time = "2025-11-21T23:01:53.443Z" }, +] + +[[package]] +name = "executing" +version = "2.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/52/92/8a611141e42930c0f194f7504063ab87dfe970cf1a5af28e7703df448734/executing-2.3.0.tar.gz", hash = "sha256:15919cb5d667e5cb4e099511971d00d659573fff2dd5c4e6cd8b71636c7858d2", size = 1338003, upload-time = "2026-10-10T14:06:04.64Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4d/dd/8bc67e7d5ffc1d88aa5af511189dfb76dc4e1e5b808fab186146ef2663e5/executing-2.3.0-py3-none-any.whl", hash = "sha256:736e859c9f8701f11fcf516856f26f562e04776387824b43a35a1dfe21c84122", size = 29393, upload-time = "2026-10-10T14:06:02.777Z" }, +] + +[[package]] +name = "fastapi" +version = "0.143.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "annotated-doc" }, + { name = "opentelemetry-api" }, + { name = "pydantic" }, + { name = "starlette" }, + { name = "typing-extensions" }, + { name = "typing-inspection" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/96/16/52ca959230f9820660fd822f488f883d7dc42310716b4cc6d2a944835dcd/fastapi-0.143.1.tar.gz", hash = "sha256:4cafaab64df8534758bf0fce61947f5e27e6cd512798ccbbaad5425086c3b664", size = 469025, upload-time = "2026-10-14T12:53:09.448Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ca/73/30ee3dd8f26fd385e451bbded9e1b54766a277db588e70154dd894f4b698/fastapi-0.143.1-py3-none-any.whl", hash = "sha256:687beb445804e4c4dbe2a76fd83c25e9b973ac48c267defb86f791e099baecc4", size = 144682, upload-time = "2026-10-14T12:53:07.69Z" }, +] + +[[package]] +name = "fastavro" +version = "1.13.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d6/ee/05cae1eeb332f876a1226b382a1f1be4ac8ce66634c313f2746beadab16f/fastavro-1.13.1.tar.gz", hash = "sha256:6f05aa2539bf7a19e9eb3bdaf6580c4d0f082a8230f641eaf9c84e4bcf0e6bc4", size = 1126240, upload-time = "2026-10-08T00:28:07.552Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/06/90/8a88cfc4a09d02a741f7cb365d7545ea380b084bb259808c7cd0a3b701bf/fastavro-1.13.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:9be0b06f90784f5e04bfb29a467c698ab1f88409c0db4821bbc4d86d583bc82a", size = 1044934, upload-time = "2026-10-08T00:28:35.439Z" }, + { url = "https://files.pythonhosted.org/packages/db/7e/6c4fb729cce352547eb181d51de5b45053b497efa3218da0f4dc36f467ad/fastavro-1.13.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:754a483d1f161545da76b3d6a3155b7e37477f1e149f00ccfff740d9ec5c143e", size = 3482761, upload-time = "2026-10-08T00:28:38.051Z" }, + { url = "https://files.pythonhosted.org/packages/bc/97/48b21cf31cda02226adc293a5f54fb59ed2501554f37430f9a5d2737673d/fastavro-1.13.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e3d7e0850230a9af977184dd0677e2bc6341659835d55a73a2fa76c7d2d2d65e", size = 3572084, upload-time = "2026-10-08T00:28:40.402Z" }, + { url = "https://files.pythonhosted.org/packages/8c/b8/06716a0041f7de3afc0fd3beb97a4e14637528cab20f50143aae4ad0131f/fastavro-1.13.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:01810229c86dcec75da8cc08f18f509e7a1883681c5c83c69f85589998440624", size = 3382225, upload-time = "2026-10-08T00:28:43.028Z" }, + { url = "https://files.pythonhosted.org/packages/23/88/54299e18cd31eb5c38a5ef2e2871063413264f897d4da411b78a3fc40642/fastavro-1.13.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:46ff9c48be24798e1926eaa3733f80967439cd7f1c7514e32c64714cb6c405d9", size = 3515919, upload-time = "2026-10-08T00:28:45.184Z" }, + { url = "https://files.pythonhosted.org/packages/45/d3/a1dd7b99b87bf3444d18efd9a9c64e27e9f177a2d0d371f379ac9bccd4ba/fastavro-1.13.1-cp313-cp313-win_amd64.whl", hash = "sha256:bf36a4391f62b3c8292ff8461def7192738eb9311edd26c6d730788e92ee2560", size = 461690, upload-time = "2026-10-08T00:28:46.521Z" }, + { url = "https://files.pythonhosted.org/packages/8a/65/59e941fae25efb3e82c6273f58fadba92eb2d7043f1680d2a7c8b8a90983/fastavro-1.13.1-cp313-cp313-win_arm64.whl", hash = "sha256:deab9d233ca9e3b03021c5b87a7807a1986a0375ef64975cbee9ad104e7eb3ea", size = 423295, upload-time = "2026-10-08T00:28:47.929Z" }, +] + +[[package]] +name = "fastmcp-slim" +version = "4.1.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mcp-types" }, + { name = "platformdirs" }, + { name = "pydantic", extra = ["email"] }, + { name = "pydantic-settings" }, + { name = "python-dotenv" }, + { name = "rich" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b8/88/85aafec43ec9940a360d75f2d8e9517eda01ac38b8b1610b0e9e125d61d3/fastmcp_slim-4.1.0.tar.gz", hash = "sha256:390b2b430195e0cdd0327aff80fe5dceb862b2421baf71de6d4eec92f80f99f8", size = 734647, upload-time = "2026-10-08T22:56:40.642Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/54/6a/d61e1541f4c65872146a576c1379f6f32013fd8c636bcaf0f8e70a04e533/fastmcp_slim-4.1.0-py3-none-any.whl", hash = "sha256:6edb48a78e508ef5ac691bf2a68f3e5000403773655d859eceea1068b894df4a", size = 911585, upload-time = "2026-10-08T22:56:39.136Z" }, +] + +[package.optional-dependencies] +client = [ + { name = "authlib" }, + { name = "exceptiongroup" }, + { name = "httpx2" }, + { name = "mcp" }, + { name = "opentelemetry-api" }, + { name = "py-key-value-aio", extra = ["filetree", "keyring", "memory"] }, + { name = "starlette" }, +] + +[[package]] +name = "filelock" +version = "4.1.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/8c/32/5f1e1408eda63bdecdb814dfd18b1109d239fb9695d51780c2e8a2816e76/filelock-4.1.2.tar.gz", hash = "sha256:c541dd91878706be3ff20e934a0b913972d4eff7a20ddfc17defd2b7328d006c", size = 565129, upload-time = "2026-10-14T14:47:34.513Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1b/84/16cbc2a5a102edf4b745ca43d7b9aaa8e26d46686c8e54d70d3d1225659e/filelock-4.1.2-py3-none-any.whl", hash = "sha256:4d5dc2a1d64d6b48a5f0540814000986fd62ebd3ac9ccbb1d07d669e075db9bb", size = 132861, upload-time = "2026-10-14T14:47:33Z" }, +] + +[[package]] +name = "fireflyframework-agentic" +version = "26.10.1" +source = { url = "https://github.com/fireflyframework/fireflyframework-agentic/releases/download/v26.10.1/fireflyframework_agentic-26.10.1-py3-none-any.whl" } +dependencies = [ + { name = "genai-prices" }, + { name = "httpx" }, + { name = "jinja2" }, + { name = "markdown-it-py" }, + { name = "opentelemetry-api" }, + { name = "opentelemetry-sdk" }, + { name = "pydantic" }, + { name = "pydantic-ai", extra = ["ag-ui", "bedrock", "cohere", "groq", "huggingface", "mistral", "retries", "spec", "temporal", "ui", "xai"] }, + { name = "pydantic-settings" }, + { name = "python-dotenv" }, + { name = "pyyaml" }, +] +wheels = [ + { url = "https://github.com/fireflyframework/fireflyframework-agentic/releases/download/v26.10.1/fireflyframework_agentic-26.10.1-py3-none-any.whl", hash = "sha256:ab9bf27b29e39a2d198c17d47f7bacd7d73c6348299a4e432f3dc56bbb391dda" }, +] + +[package.optional-dependencies] +openai-embeddings = [ + { name = "openai" }, +] +security = [ + { name = "cryptography" }, +] + +[package.metadata] +requires-dist = [ + { name = "asyncpg", marker = "extra == 'postgres'", specifier = ">=0.30.0" }, + { name = "asyncpg", marker = "extra == 'vectorstores-pgvector'", specifier = ">=0.30.0" }, + { name = "boto3", marker = "extra == 'bedrock-embeddings'", specifier = ">=1.35.0" }, + { name = "cairosvg", marker = "extra == 'binary'", specifier = ">=2.9.1" }, + { name = "chromadb", marker = "extra == 'vectorstores-chroma'", specifier = ">=0.5.0" }, + { name = "cohere", marker = "extra == 'cohere-embeddings'", specifier = ">=5.0.0" }, + { name = "cryptography", marker = "extra == 'security'", specifier = ">=50.0.0" }, + { name = "extract-msg", marker = "extra == 'binary'", specifier = ">=0.51" }, + { name = "fireflyframework-agentic", extras = ["postgres", "mongodb", "security", "embeddings", "openai-embeddings", "cohere-embeddings", "google-embeddings", "mistral-embeddings", "voyage-embeddings", "azure-embeddings", "bedrock-embeddings", "ollama-embeddings", "vectorstores-chroma", "vectorstores-pinecone", "vectorstores-qdrant", "vectorstores-pgvector", "vectorstores-sqlite-vec", "watch", "binary", "script-execution"], marker = "extra == 'all'" }, + { name = "genai-prices", specifier = ">=0.1.9,<0.2" }, + { name = "google-generativeai", marker = "extra == 'google-embeddings'", specifier = ">=0.8.0" }, + { name = "httpx", specifier = ">=0.28.0" }, + { name = "httpx", marker = "extra == 'dev'", specifier = ">=0.28.0" }, + { name = "httpx", marker = "extra == 'ollama-embeddings'", specifier = ">=0.28.0" }, + { name = "jinja2", specifier = ">=3.1.0" }, + { name = "langchain-anthropic", marker = "extra == 'evaluation'", specifier = ">=0.3" }, + { name = "langchain-community", marker = "extra == 'evaluation'", specifier = ">=0.3.31,<0.4" }, + { name = "langchain-ollama", marker = "extra == 'evaluation'", specifier = ">=0.3" }, + { name = "langchain-openai", marker = "extra == 'evaluation'", specifier = ">=0.3" }, + { name = "markdown-it-py", specifier = ">=3.0" }, + { name = "mistralai", marker = "extra == 'mistral-embeddings'", specifier = ">=1.0.0" }, + { name = "motor", marker = "extra == 'mongodb'", specifier = ">=3.6.0" }, + { name = "numpy", marker = "extra == 'embeddings'", specifier = ">=1.26.0" }, + { name = "numpy", marker = "extra == 'evaluation'", specifier = ">=1.26.0" }, + { name = "numpy", marker = "extra == 'reasoning-eval'", specifier = ">=2.0.0" }, + { name = "openai", marker = "extra == 'azure-embeddings'", specifier = ">=1.0.0" }, + { name = "openai", marker = "extra == 'openai-embeddings'", specifier = ">=1.0.0" }, + { name = "opentelemetry-api", specifier = ">=1.29.0" }, + { name = "opentelemetry-sdk", specifier = ">=1.29.0" }, + { name = "pandas", marker = "extra == 'reasoning-eval'", specifier = ">=2.2.0" }, + { name = "pdfplumber", marker = "extra == 'dev'", specifier = ">=0.11.0" }, + { name = "pillow", marker = "extra == 'binary'", specifier = ">=12.3.0" }, + { name = "pillow-heif", marker = "extra == 'binary'", specifier = ">=0.18" }, + { name = "pinecone", marker = "extra == 'vectorstores-pinecone'", specifier = ">=5.0.0" }, + { name = "pre-commit", marker = "extra == 'dev'", specifier = ">=3.8.0" }, + { name = "py7zr", marker = "extra == 'binary'", specifier = ">=1.1.4" }, + { name = "pydantic", specifier = ">=2.13,<3" }, + { name = "pydantic-ai", extras = ["ag-ui", "bedrock", "cohere", "groq", "huggingface", "mistral", "retries", "spec", "temporal", "ui", "xai"], specifier = ">=2.53.0,<3" }, + { name = "pydantic-monty", marker = "extra == 'script-execution'", specifier = ">=0.0.18" }, + { name = "pydantic-settings", specifier = ">=2.14.2,<3" }, + { name = "pymongo", marker = "extra == 'mongodb'", specifier = ">=4.18.2" }, + { name = "pypdf", marker = "extra == 'binary'", specifier = ">=6.19.0" }, + { name = "pyright", marker = "extra == 'dev'", specifier = ">=1.1.0" }, + { name = "pytest", marker = "extra == 'dev'", specifier = ">=8.3.0" }, + { name = "pytest-asyncio", marker = "extra == 'dev'", specifier = ">=0.24.0" }, + { name = "pytest-benchmark", marker = "extra == 'dev'", specifier = ">=5.0.0" }, + { name = "pytest-cov", marker = "extra == 'dev'", specifier = ">=6.0.0" }, + { name = "python-dotenv", specifier = ">=1.0.0" }, + { name = "pyyaml", specifier = ">=6.0" }, + { name = "qdrant-client", marker = "extra == 'vectorstores-qdrant'", specifier = ">=1.12.0" }, + { name = "ragas", marker = "extra == 'evaluation'", specifier = ">=0.2.6,<0.2.7" }, + { name = "ruff", marker = "extra == 'dev'", specifier = ">=0.9.0" }, + { name = "sqlalchemy", marker = "extra == 'postgres'", specifier = ">=2.0.0" }, + { name = "sqlite-vec", marker = "extra == 'vectorstores-sqlite-vec'", specifier = ">=0.1.6" }, + { name = "testcontainers", marker = "extra == 'dev'", specifier = ">=4.10.0" }, + { name = "voyageai", marker = "extra == 'voyage-embeddings'", specifier = ">=0.3.0" }, + { name = "watchfiles", marker = "extra == 'watch'", specifier = ">=0.24.0" }, +] +provides-extras = ["all", "azure-embeddings", "bedrock-embeddings", "binary", "cohere-embeddings", "dev", "embeddings", "evaluation", "google-embeddings", "mistral-embeddings", "mongodb", "ollama-embeddings", "openai-embeddings", "postgres", "reasoning-eval", "script-execution", "security", "vectorstores-chroma", "vectorstores-pgvector", "vectorstores-pinecone", "vectorstores-qdrant", "vectorstores-sqlite-vec", "voyage-embeddings", "watch"] + +[[package]] +name = "flyquery" +version = "26.10.1" +source = { editable = "." } +dependencies = [ + { name = "aiofiles" }, + { name = "aiosqlite" }, + { name = "alembic" }, + { name = "asyncpg" }, + { name = "duckdb" }, + { name = "fireflyframework-agentic", extra = ["openai-embeddings", "security"] }, + { name = "httpx" }, + { name = "jinja2" }, + { name = "pgvector" }, + { name = "psycopg", extra = ["binary"] }, + { name = "pyarrow" }, + { name = "pydantic" }, + { name = "pydantic-settings" }, + { name = "pyfly", extra = ["cli", "client", "data-relational", "eda", "fastapi", "observability", "postgresql", "redis", "scheduling", "security"] }, + { name = "pyyaml" }, + { name = "redis" }, + { name = "sqlalchemy", extra = ["asyncio"] }, + { name = "sqlglot" }, + { name = "structlog" }, + { name = "tenacity" }, +] + +[package.optional-dependencies] +azure = [ + { name = "aiohttp" }, + { name = "azure-storage-blob" }, +] +dev = [ + { name = "httpx" }, + { name = "pyright" }, + { name = "pytest" }, + { name = "pytest-asyncio" }, + { name = "pytest-cov" }, + { name = "pytest-timeout" }, + { name = "respx" }, + { name = "ruff" }, + { name = "testcontainers", extra = ["minio", "redis"] }, +] +file-readers = [ + { name = "fastavro" }, + { name = "openpyxl" }, + { name = "python-calamine" }, +] +gcs = [ + { name = "gcloud-aio-storage" }, +] +ml-reranker = [ + { name = "sentence-transformers" }, +] +presidio = [ + { name = "presidio-analyzer" }, + { name = "presidio-anonymizer" }, +] +s3 = [ + { name = "aiobotocore" }, + { name = "botocore" }, +] + +[package.metadata] +requires-dist = [ + { name = "aiobotocore", marker = "extra == 's3'", specifier = ">=2.15" }, + { name = "aiofiles", specifier = ">=24" }, + { name = "aiohttp", marker = "extra == 'azure'", specifier = ">=3.10" }, + { name = "aiosqlite", specifier = ">=0.22" }, + { name = "alembic", specifier = ">=1.14" }, + { name = "asyncpg", specifier = ">=0.30" }, + { name = "azure-storage-blob", marker = "extra == 'azure'", specifier = ">=12.23" }, + { name = "botocore", marker = "extra == 's3'", specifier = ">=1.35" }, + { name = "duckdb", specifier = ">=1.3.2" }, + { name = "fastavro", marker = "extra == 'file-readers'", specifier = ">=1.9" }, + { name = "fireflyframework-agentic", extras = ["security", "openai-embeddings"], url = "https://github.com/fireflyframework/fireflyframework-agentic/releases/download/v26.10.1/fireflyframework_agentic-26.10.1-py3-none-any.whl" }, + { name = "gcloud-aio-storage", marker = "extra == 'gcs'", specifier = ">=9.3" }, + { name = "httpx", specifier = ">=0.28.0" }, + { name = "httpx", marker = "extra == 'dev'", specifier = ">=0.28" }, + { name = "jinja2", specifier = ">=3.1" }, + { name = "openpyxl", marker = "extra == 'file-readers'", specifier = ">=3.1" }, + { name = "pgvector", specifier = ">=0.3.6" }, + { name = "presidio-analyzer", marker = "extra == 'presidio'", specifier = ">=2.2" }, + { name = "presidio-anonymizer", marker = "extra == 'presidio'", specifier = ">=2.2" }, + { name = "psycopg", extras = ["binary"], specifier = ">=3.2" }, + { name = "pyarrow", specifier = ">=17.0" }, + { name = "pydantic", specifier = ">=2.10.0" }, + { name = "pydantic-settings", specifier = ">=2.7.0" }, + { name = "pyfly", extras = ["fastapi", "observability", "security", "data-relational", "postgresql", "eda", "redis", "client", "scheduling", "cli"], git = "https://github.com/fireflyframework/fireflyframework-pyfly.git?tag=v26.06.113" }, + { name = "pyright", marker = "extra == 'dev'", specifier = ">=1.1" }, + { name = "pytest", marker = "extra == 'dev'", specifier = ">=8.0" }, + { name = "pytest-asyncio", marker = "extra == 'dev'", specifier = ">=0.24" }, + { name = "pytest-cov", marker = "extra == 'dev'", specifier = ">=5.0" }, + { name = "pytest-timeout", marker = "extra == 'dev'", specifier = ">=2.3" }, + { name = "python-calamine", marker = "extra == 'file-readers'", specifier = ">=0.3" }, + { name = "pyyaml", specifier = ">=6.0" }, + { name = "redis", specifier = ">=5.2" }, + { name = "respx", marker = "extra == 'dev'", specifier = ">=0.21" }, + { name = "ruff", marker = "extra == 'dev'", specifier = ">=0.8" }, + { name = "sentence-transformers", marker = "extra == 'ml-reranker'", specifier = ">=3.3" }, + { name = "sqlalchemy", extras = ["asyncio"], specifier = ">=2.0" }, + { name = "sqlglot", specifier = ">=26.0.0" }, + { name = "structlog", specifier = ">=25.5.0" }, + { name = "tenacity", specifier = ">=9.0.0" }, + { name = "testcontainers", extras = ["postgres", "redis", "minio"], marker = "extra == 'dev'", specifier = ">=4.0" }, +] +provides-extras = ["dev", "s3", "gcs", "azure", "presidio", "ml-reranker", "file-readers"] + +[[package]] +name = "frozenlist" +version = "1.8.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/2d/f5/c831fac6cc817d26fd54c7eaccd04ef7e0288806943f7cc5bbf69f3ac1f0/frozenlist-1.8.0.tar.gz", hash = "sha256:3ede829ed8d842f6cd48fc7081d7a41001a56f1f38603f9d49bf3020d59a31ad", size = 45875, upload-time = "2025-10-06T05:38:17.865Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2d/40/0832c31a37d60f60ed79e9dfb5a92e1e2af4f40a16a29abcc7992af9edff/frozenlist-1.8.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:8d92f1a84bb12d9e56f818b3a746f3efba93c1b63c8387a73dde655e1e42282a", size = 85717, upload-time = "2025-10-06T05:36:27.341Z" }, + { url = "https://files.pythonhosted.org/packages/30/ba/b0b3de23f40bc55a7057bd38434e25c34fa48e17f20ee273bbde5e0650f3/frozenlist-1.8.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:96153e77a591c8adc2ee805756c61f59fef4cf4073a9275ee86fe8cba41241f7", size = 49651, upload-time = "2025-10-06T05:36:28.855Z" }, + { url = "https://files.pythonhosted.org/packages/0c/ab/6e5080ee374f875296c4243c381bbdef97a9ac39c6e3ce1d5f7d42cb78d6/frozenlist-1.8.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f21f00a91358803399890ab167098c131ec2ddd5f8f5fd5fe9c9f2c6fcd91e40", size = 49417, upload-time = "2025-10-06T05:36:29.877Z" }, + { url = "https://files.pythonhosted.org/packages/d5/4e/e4691508f9477ce67da2015d8c00acd751e6287739123113a9fca6f1604e/frozenlist-1.8.0-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:fb30f9626572a76dfe4293c7194a09fb1fe93ba94c7d4f720dfae3b646b45027", size = 234391, upload-time = "2025-10-06T05:36:31.301Z" }, + { url = "https://files.pythonhosted.org/packages/40/76/c202df58e3acdf12969a7895fd6f3bc016c642e6726aa63bd3025e0fc71c/frozenlist-1.8.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:eaa352d7047a31d87dafcacbabe89df0aa506abb5b1b85a2fb91bc3faa02d822", size = 233048, upload-time = "2025-10-06T05:36:32.531Z" }, + { url = "https://files.pythonhosted.org/packages/f9/c0/8746afb90f17b73ca5979c7a3958116e105ff796e718575175319b5bb4ce/frozenlist-1.8.0-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:03ae967b4e297f58f8c774c7eabcce57fe3c2434817d4385c50661845a058121", size = 226549, upload-time = "2025-10-06T05:36:33.706Z" }, + { url = "https://files.pythonhosted.org/packages/7e/eb/4c7eefc718ff72f9b6c4893291abaae5fbc0c82226a32dcd8ef4f7a5dbef/frozenlist-1.8.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f6292f1de555ffcc675941d65fffffb0a5bcd992905015f85d0592201793e0e5", size = 239833, upload-time = "2025-10-06T05:36:34.947Z" }, + { url = "https://files.pythonhosted.org/packages/c2/4e/e5c02187cf704224f8b21bee886f3d713ca379535f16893233b9d672ea71/frozenlist-1.8.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:29548f9b5b5e3460ce7378144c3010363d8035cea44bc0bf02d57f5a685e084e", size = 245363, upload-time = "2025-10-06T05:36:36.534Z" }, + { url = "https://files.pythonhosted.org/packages/1f/96/cb85ec608464472e82ad37a17f844889c36100eed57bea094518bf270692/frozenlist-1.8.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ec3cc8c5d4084591b4237c0a272cc4f50a5b03396a47d9caaf76f5d7b38a4f11", size = 229314, upload-time = "2025-10-06T05:36:38.582Z" }, + { url = "https://files.pythonhosted.org/packages/5d/6f/4ae69c550e4cee66b57887daeebe006fe985917c01d0fff9caab9883f6d0/frozenlist-1.8.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:517279f58009d0b1f2e7c1b130b377a349405da3f7621ed6bfae50b10adf20c1", size = 243365, upload-time = "2025-10-06T05:36:40.152Z" }, + { url = "https://files.pythonhosted.org/packages/7a/58/afd56de246cf11780a40a2c28dc7cbabbf06337cc8ddb1c780a2d97e88d8/frozenlist-1.8.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:db1e72ede2d0d7ccb213f218df6a078a9c09a7de257c2fe8fcef16d5925230b1", size = 237763, upload-time = "2025-10-06T05:36:41.355Z" }, + { url = "https://files.pythonhosted.org/packages/cb/36/cdfaf6ed42e2644740d4a10452d8e97fa1c062e2a8006e4b09f1b5fd7d63/frozenlist-1.8.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:b4dec9482a65c54a5044486847b8a66bf10c9cb4926d42927ec4e8fd5db7fed8", size = 240110, upload-time = "2025-10-06T05:36:42.716Z" }, + { url = "https://files.pythonhosted.org/packages/03/a8/9ea226fbefad669f11b52e864c55f0bd57d3c8d7eb07e9f2e9a0b39502e1/frozenlist-1.8.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:21900c48ae04d13d416f0e1e0c4d81f7931f73a9dfa0b7a8746fb2fe7dd970ed", size = 233717, upload-time = "2025-10-06T05:36:44.251Z" }, + { url = "https://files.pythonhosted.org/packages/1e/0b/1b5531611e83ba7d13ccc9988967ea1b51186af64c42b7a7af465dcc9568/frozenlist-1.8.0-cp313-cp313-win32.whl", hash = "sha256:8b7b94a067d1c504ee0b16def57ad5738701e4ba10cec90529f13fa03c833496", size = 39628, upload-time = "2025-10-06T05:36:45.423Z" }, + { url = "https://files.pythonhosted.org/packages/d8/cf/174c91dbc9cc49bc7b7aab74d8b734e974d1faa8f191c74af9b7e80848e6/frozenlist-1.8.0-cp313-cp313-win_amd64.whl", hash = "sha256:878be833caa6a3821caf85eb39c5ba92d28e85df26d57afb06b35b2efd937231", size = 43882, upload-time = "2025-10-06T05:36:46.796Z" }, + { url = "https://files.pythonhosted.org/packages/c1/17/502cd212cbfa96eb1388614fe39a3fc9ab87dbbe042b66f97acb57474834/frozenlist-1.8.0-cp313-cp313-win_arm64.whl", hash = "sha256:44389d135b3ff43ba8cc89ff7f51f5a0bb6b63d829c8300f79a2fe4fe61bcc62", size = 39676, upload-time = "2025-10-06T05:36:47.8Z" }, + { url = "https://files.pythonhosted.org/packages/d2/5c/3bbfaa920dfab09e76946a5d2833a7cbdf7b9b4a91c714666ac4855b88b4/frozenlist-1.8.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:e25ac20a2ef37e91c1b39938b591457666a0fa835c7783c3a8f33ea42870db94", size = 89235, upload-time = "2025-10-06T05:36:48.78Z" }, + { url = "https://files.pythonhosted.org/packages/d2/d6/f03961ef72166cec1687e84e8925838442b615bd0b8854b54923ce5b7b8a/frozenlist-1.8.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:07cdca25a91a4386d2e76ad992916a85038a9b97561bf7a3fd12d5d9ce31870c", size = 50742, upload-time = "2025-10-06T05:36:49.837Z" }, + { url = "https://files.pythonhosted.org/packages/1e/bb/a6d12b7ba4c3337667d0e421f7181c82dda448ce4e7ad7ecd249a16fa806/frozenlist-1.8.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:4e0c11f2cc6717e0a741f84a527c52616140741cd812a50422f83dc31749fb52", size = 51725, upload-time = "2025-10-06T05:36:50.851Z" }, + { url = "https://files.pythonhosted.org/packages/bc/71/d1fed0ffe2c2ccd70b43714c6cab0f4188f09f8a67a7914a6b46ee30f274/frozenlist-1.8.0-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:b3210649ee28062ea6099cfda39e147fa1bc039583c8ee4481cb7811e2448c51", size = 284533, upload-time = "2025-10-06T05:36:51.898Z" }, + { url = "https://files.pythonhosted.org/packages/c9/1f/fb1685a7b009d89f9bf78a42d94461bc06581f6e718c39344754a5d9bada/frozenlist-1.8.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:581ef5194c48035a7de2aefc72ac6539823bb71508189e5de01d60c9dcd5fa65", size = 292506, upload-time = "2025-10-06T05:36:53.101Z" }, + { url = "https://files.pythonhosted.org/packages/e6/3b/b991fe1612703f7e0d05c0cf734c1b77aaf7c7d321df4572e8d36e7048c8/frozenlist-1.8.0-cp313-cp313t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3ef2d026f16a2b1866e1d86fc4e1291e1ed8a387b2c333809419a2f8b3a77b82", size = 274161, upload-time = "2025-10-06T05:36:54.309Z" }, + { url = "https://files.pythonhosted.org/packages/ca/ec/c5c618767bcdf66e88945ec0157d7f6c4a1322f1473392319b7a2501ded7/frozenlist-1.8.0-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:5500ef82073f599ac84d888e3a8c1f77ac831183244bfd7f11eaa0289fb30714", size = 294676, upload-time = "2025-10-06T05:36:55.566Z" }, + { url = "https://files.pythonhosted.org/packages/7c/ce/3934758637d8f8a88d11f0585d6495ef54b2044ed6ec84492a91fa3b27aa/frozenlist-1.8.0-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:50066c3997d0091c411a66e710f4e11752251e6d2d73d70d8d5d4c76442a199d", size = 300638, upload-time = "2025-10-06T05:36:56.758Z" }, + { url = "https://files.pythonhosted.org/packages/fc/4f/a7e4d0d467298f42de4b41cbc7ddaf19d3cfeabaf9ff97c20c6c7ee409f9/frozenlist-1.8.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:5c1c8e78426e59b3f8005e9b19f6ff46e5845895adbde20ece9218319eca6506", size = 283067, upload-time = "2025-10-06T05:36:57.965Z" }, + { url = "https://files.pythonhosted.org/packages/dc/48/c7b163063d55a83772b268e6d1affb960771b0e203b632cfe09522d67ea5/frozenlist-1.8.0-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:eefdba20de0d938cec6a89bd4d70f346a03108a19b9df4248d3cf0d88f1b0f51", size = 292101, upload-time = "2025-10-06T05:36:59.237Z" }, + { url = "https://files.pythonhosted.org/packages/9f/d0/2366d3c4ecdc2fd391e0afa6e11500bfba0ea772764d631bbf82f0136c9d/frozenlist-1.8.0-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:cf253e0e1c3ceb4aaff6df637ce033ff6535fb8c70a764a8f46aafd3d6ab798e", size = 289901, upload-time = "2025-10-06T05:37:00.811Z" }, + { url = "https://files.pythonhosted.org/packages/b8/94/daff920e82c1b70e3618a2ac39fbc01ae3e2ff6124e80739ce5d71c9b920/frozenlist-1.8.0-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:032efa2674356903cd0261c4317a561a6850f3ac864a63fc1583147fb05a79b0", size = 289395, upload-time = "2025-10-06T05:37:02.115Z" }, + { url = "https://files.pythonhosted.org/packages/e3/20/bba307ab4235a09fdcd3cc5508dbabd17c4634a1af4b96e0f69bfe551ebd/frozenlist-1.8.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:6da155091429aeba16851ecb10a9104a108bcd32f6c1642867eadaee401c1c41", size = 283659, upload-time = "2025-10-06T05:37:03.711Z" }, + { url = "https://files.pythonhosted.org/packages/fd/00/04ca1c3a7a124b6de4f8a9a17cc2fcad138b4608e7a3fc5877804b8715d7/frozenlist-1.8.0-cp313-cp313t-win32.whl", hash = "sha256:0f96534f8bfebc1a394209427d0f8a63d343c9779cda6fc25e8e121b5fd8555b", size = 43492, upload-time = "2025-10-06T05:37:04.915Z" }, + { url = "https://files.pythonhosted.org/packages/59/5e/c69f733a86a94ab10f68e496dc6b7e8bc078ebb415281d5698313e3af3a1/frozenlist-1.8.0-cp313-cp313t-win_amd64.whl", hash = "sha256:5d63a068f978fc69421fb0e6eb91a9603187527c86b7cd3f534a5b77a592b888", size = 48034, upload-time = "2025-10-06T05:37:06.343Z" }, + { url = "https://files.pythonhosted.org/packages/16/6c/be9d79775d8abe79b05fa6d23da99ad6e7763a1d080fbae7290b286093fd/frozenlist-1.8.0-cp313-cp313t-win_arm64.whl", hash = "sha256:bf0a7e10b077bf5fb9380ad3ae8ce20ef919a6ad93b4552896419ac7e1d8e042", size = 41749, upload-time = "2025-10-06T05:37:07.431Z" }, + { url = "https://files.pythonhosted.org/packages/9a/9a/e35b4a917281c0b8419d4207f4334c8e8c5dbf4f3f5f9ada73958d937dcc/frozenlist-1.8.0-py3-none-any.whl", hash = "sha256:0c18a16eab41e82c295618a77502e17b195883241c563b00f0aa5106fc4eaa0d", size = 13409, upload-time = "2025-10-06T05:38:16.721Z" }, +] + +[[package]] +name = "fsspec" +version = "2026.9.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/77/cd/9be253869fc42e764de7f3dedd6969af7d44ff9c3375214a3442a6f3fc08/fsspec-2026.9.0.tar.gz", hash = "sha256:0f08147951c8cb31d844c3547d631053b127863b60be04cf06e121333ee0e2fe", size = 333545, upload-time = "2026-09-18T17:50:42.825Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6c/c0/a98505f18594f1bce828bb159cec0fcf9860562f1a2c85913409fc8f3d9e/fsspec-2026.9.0-py3-none-any.whl", hash = "sha256:8dd6e646e99ea382bd85f97a45e6b526a442d79423a7dc673f1e2756d05fcb5f", size = 221738, upload-time = "2026-09-18T17:50:41.341Z" }, +] + +[[package]] +name = "gcloud-aio-auth" +version = "5.5.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "aiohttp" }, + { name = "chardet" }, + { name = "cryptography" }, + { name = "pyjwt" }, + { name = "tenacity" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/66/c9/cf630a761d4bbe4de88c52362b55dc29ca24735b1d893a6d6c5990879c47/gcloud_aio_auth-5.5.1.tar.gz", hash = "sha256:8039b9423445e6ad702649e2b73c1352dd380c884cf6401963c5065f583ed30c", size = 15765, upload-time = "2026-10-02T12:44:07.558Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5d/a3/2766b5e0691743d1865aafe2323c8fd343df080597f287e52292c795c2e3/gcloud_aio_auth-5.5.1-py3-none-any.whl", hash = "sha256:3f3ca5a79c176586c142a017346b88535a5ac6ec492329f9e17334216d829894", size = 18359, upload-time = "2026-10-02T12:44:08.325Z" }, +] + +[[package]] +name = "gcloud-aio-storage" +version = "9.6.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "aiofiles" }, + { name = "cryptography" }, + { name = "gcloud-aio-auth" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/15/be/528ac1d1506eaf4526c2c0039d68dec99b243d50a556cd688968d1498e1a/gcloud_aio_storage-9.6.5.tar.gz", hash = "sha256:44a9529e429d7460f1a55b49a0f77906d988ee68483513abb3c0d66dedf43abd", size = 14309, upload-time = "2026-10-02T12:59:14.278Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c3/7d/88c82ec77bbf867734011fa4292c69b11e27c823db3dfb55879e5dbd139f/gcloud_aio_storage-9.6.5-py3-none-any.whl", hash = "sha256:07bf233a065539bebbd1a34ce61505d6dba2b6674f23f8e0319606d2f01111ab", size = 17005, upload-time = "2026-10-02T12:59:15.309Z" }, +] + +[[package]] +name = "genai-prices" +version = "0.1.12" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "httpx2" }, + { name = "pydantic" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/33/92/10212781b3416bc590b6a55c5643073282a2ff26e003b38ab27bad3ae5d2/genai_prices-0.1.12.tar.gz", hash = "sha256:d1493977cb7f61bc436516a166f644f5bbb01e1a83365e2914c99c6298f77ca4", size = 134740, upload-time = "2026-10-14T11:22:23.819Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/86/3f/28a7a4b9d67a9cc21d705ce6476557007841abeba6f2d5b58aa9bda9f795/genai_prices-0.1.12-py3-none-any.whl", hash = "sha256:89d98303c5b7a366a05136ba03884c5951ec9a9ceb28fef62c7fa719f2828182", size = 142670, upload-time = "2026-10-14T11:22:22.688Z" }, +] + +[[package]] +name = "google-auth" +version = "2.62.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cryptography" }, + { name = "pyasn1-modules" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f5/b9/4b2528f30114b106e3c3a7298ba38d85e682fd1f83fe7c4a5b77c7677082/google_auth-2.62.0.tar.gz", hash = "sha256:0bef0ce54bdf9ce226c5d66e4264413bd918141c31bbe49fb52eac882f513d69", size = 398180, upload-time = "2026-10-12T19:20:48.328Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/eb/a3/87fe9b7203ec2e56ea6a57c75e6d632eaf9487c7f7978cdad1d801bee0af/google_auth-2.62.0-py3-none-any.whl", hash = "sha256:4ff4319aeb4ad128409759d397a9fcafad126d0031d241cc0dd6b9a00b43e3f3", size = 267911, upload-time = "2026-10-12T19:20:46.355Z" }, +] + +[package.optional-dependencies] +requests = [ + { name = "requests" }, +] + +[[package]] +name = "google-genai" +version = "2.30.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anyio" }, + { name = "distro" }, + { name = "google-auth", extra = ["requests"] }, + { name = "httpx" }, + { name = "pydantic" }, + { name = "requests" }, + { name = "sniffio" }, + { name = "tenacity" }, + { name = "typing-extensions" }, + { name = "websockets" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/df/8a/76e592bca2a4ff63a8ba8025012ccae2d1a9aa1762af2278f43756045e12/google_genai-2.30.1.tar.gz", hash = "sha256:a348b28b86a98fbc8e0bea759e14ae3ac807954355df8638079715d027cd14d5", size = 736895, upload-time = "2026-10-13T14:11:18.246Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/46/28/faa7c02d87df1343aa8e51c816694a82eb37f41d0e83253e6e75a00b96ec/google_genai-2.30.1-py3-none-any.whl", hash = "sha256:1bb8961c60f7100439a45067a32764a18da0f8d0f95954ffc777d1f8225a2469", size = 1199070, upload-time = "2026-10-13T14:11:16.459Z" }, +] + +[[package]] +name = "googleapis-common-protos" +version = "1.75.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "protobuf" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/8d/2b/6ce81972d5c8cab9705fddce3153be63222d9e12fd96f8baba5038a744dd/googleapis_common_protos-1.75.5.tar.gz", hash = "sha256:c7a866fc34ed29a3b10af627a4b9b1dc2433313ca6e959f0ae4feb132047ed72", size = 156513, upload-time = "2026-09-29T19:26:14.863Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/65/b9/6b29500a1c581ff4d77fd83c6568d068bee06f1b139fb6eb0a4f2d4bce8a/googleapis_common_protos-1.75.5-py3-none-any.whl", hash = "sha256:d7285525c23039db98f2463e6d5a4f9b958b94d497f03a844ece3259c4e72d5d", size = 307737, upload-time = "2026-09-29T19:25:48.735Z" }, +] + +[[package]] +name = "greenlet" +version = "3.5.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/3e/6e/0091f175ccd02b02bc8811bbcbcc6ac2e980be116e3b2f7a736ca322bf84/greenlet-3.5.6.tar.gz", hash = "sha256:8e67c43bdfc88d5fee6db0d3e40175b362fc95fb85f0412d233b9b203c53a575", size = 207653, upload-time = "2026-09-14T15:42:51.806Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f1/a1/e720a38852366c589e1a46cf570b886507ad2cf591050c203365638baab0/greenlet-3.5.6-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:f96f0e30b5a95c7631b12bfe214cbc90ec8fe8cfa36920596c10514a65743519", size = 294627, upload-time = "2026-09-14T14:24:40.102Z" }, + { url = "https://files.pythonhosted.org/packages/eb/c3/58187858df41354a11e6a55b421e7af9059798abdab3a384cc51b8567c38/greenlet-3.5.6-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c75116c9de79949de23006e2d9b35ee82874c594fcf5c0311b439acaa14b8441", size = 614356, upload-time = "2026-09-14T15:12:03.399Z" }, + { url = "https://files.pythonhosted.org/packages/ce/b9/3a7e67d5f05c9760b1ad411fa52264bd69cc08e22a2ebfb4018b90628ced/greenlet-3.5.6-cp313-cp313-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:cad5782f93f7f738b62c6527b6f32a60694d924029f299a8b524758cfa53d815", size = 626756, upload-time = "2026-09-14T15:20:44.269Z" }, + { url = "https://files.pythonhosted.org/packages/c6/7c/40400455f5b5a65bb83e94fde66d1be9e5ec518638113f8083ace746c309/greenlet-3.5.6-cp313-cp313-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a93ee7c6e8fd0f8a83525a51bd777be57ee17787e91d805bd8d6faf9dcada18e", size = 632632, upload-time = "2026-09-14T15:25:07.813Z" }, + { url = "https://files.pythonhosted.org/packages/85/cb/ab0c123c514ed4e94c0dc9ee2e86362633e6b998cfc05de7fc9ac2eb9690/greenlet-3.5.6-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f98e8215e172f567ce80eeaed9107fb4d32b6c44f26983d9b8334658136a205a", size = 623779, upload-time = "2026-09-14T14:36:01.104Z" }, + { url = "https://files.pythonhosted.org/packages/f9/67/1f35cff30a6c51c3f23b63d4afcc7313ab4f97490ba3676fa78178984b27/greenlet-3.5.6-cp313-cp313-manylinux_2_39_riscv64.whl", hash = "sha256:7f731ebac68ea06d628658295cb2d217b10186329fcf9a3b6a149045059bf92e", size = 434933, upload-time = "2026-09-14T15:28:38.858Z" }, + { url = "https://files.pythonhosted.org/packages/a5/26/fda8a5a06e7073333ccb038133c5893b9e0c4fe29d5992a17e83c241bc6e/greenlet-3.5.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:df19e2d0b1620039af5102563fbd96e8938c7f5c3f5828528d641d9fc585525e", size = 1584930, upload-time = "2026-09-14T15:10:08.234Z" }, + { url = "https://files.pythonhosted.org/packages/2f/37/50f8813163148d6234e08b23dcad6a9e37f01d148c8ec976e4c44ea2d918/greenlet-3.5.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:06c0e933290fba8ffe53ead4ae1b8044b0e9754b75cebf381aa2bc3e50d82fac", size = 1647590, upload-time = "2026-09-14T14:35:51.173Z" }, + { url = "https://files.pythonhosted.org/packages/86/da/b7669b09586365654083a62bd0724cf06cb74bd5085a15cdd161271f992f/greenlet-3.5.6-cp313-cp313-win_amd64.whl", hash = "sha256:5b602b4201b965a8354d74e232364a66ff243dd142e350d035f46169bb36e13d", size = 324086, upload-time = "2026-09-14T14:23:48.428Z" }, + { url = "https://files.pythonhosted.org/packages/e5/5d/c9663cfe84a2a9e0aa96f066f5b0594c227ea4c647511e087e2e11d4ac0a/greenlet-3.5.6-cp313-cp313-win_arm64.whl", hash = "sha256:876077e7ebb8c84ed068e2b23d4c62ebb010d60df84b9591af1be2f39010ffb2", size = 308211, upload-time = "2026-09-14T14:28:01.634Z" }, +] + +[[package]] +name = "griffelib" +version = "2.3.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/2b/27/b55f1a5278918be765fb2fd8b20966bc72bbdd3f789f031937cceea7834a/griffelib-2.3.2.tar.gz", hash = "sha256:df00c7a0dee3d86268d76788997a1859272cb1fb7b865658e043d2c0c3d52e60", size = 234729, upload-time = "2026-10-06T09:54:37.222Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/04/e5/0ae74c83c1cab2c14daadf28bd0143eb14bb81503834af987b66badc7b61/griffelib-2.3.2-py3-none-any.whl", hash = "sha256:8e710afededd5607f95bf3c8ccc175ee306e7084459faf27b9f9f44ef2a7a274", size = 169420, upload-time = "2026-10-06T09:54:32.038Z" }, +] + +[[package]] +name = "groq" +version = "1.7.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anyio" }, + { name = "distro" }, + { name = "httpx" }, + { name = "pydantic" }, + { name = "sniffio" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/0c/c1/20cb719bc21aa22df185c4aa60abc17680d7067d41fe0ca3fda98b75822b/groq-1.7.0.tar.gz", hash = "sha256:d582dbb3f071b92ca339baba83af9f57ba6f46a51c34b04565d7cb9badb2785b", size = 158918, upload-time = "2026-08-26T02:36:19.734Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3f/f6/c3d8ea3194d7d7d8292edd4dbb4b6832d29c2eab04887dda4a742e83902c/groq-1.7.0-py3-none-any.whl", hash = "sha256:cb1518f823423d4e52445859eb7d2918a927794cec12f8d5e50d9161e3690fc8", size = 143797, upload-time = "2026-08-26T02:36:18.497Z" }, +] + +[[package]] +name = "grpcio" +version = "1.84.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/3f/4f/4435c0aae54657258d9cfcba78598f3d9e5fe4c82ff18d78558567b90faf/grpcio-1.84.0.tar.gz", hash = "sha256:19aaf172fc2edbefccce3f6e92c5150975dbe56c45744e9e87cf72ebdf85bfbe", size = 13493876, upload-time = "2026-09-14T06:59:33.291Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5d/51/40f99701adb01d4e5316a2aaf13838da1a24d5c879cd8c95156d7c364454/grpcio-1.84.0-cp313-cp313-linux_armv7l.whl", hash = "sha256:209414080da8c20af94df1395b635da52dd57b5edc9e917e1deca0dc1c4bb55e", size = 6427619, upload-time = "2026-09-14T06:58:06.025Z" }, + { url = "https://files.pythonhosted.org/packages/c5/4b/ed8e22a1237e6b2be6ef4f221d074a5b0e0dd8a0da8c944c04aea731f0eb/grpcio-1.84.0-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:e41c3993eee896c617dbd8a505085d28b6e84a0445ed9a1f40f95808473cf678", size = 12336549, upload-time = "2026-09-14T06:58:08.583Z" }, + { url = "https://files.pythonhosted.org/packages/d3/50/00165b05cd73f45996748ea67ce9e55d08936f2fea94a7fd8541cc2d0e54/grpcio-1.84.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:fff5ef3fe1bba7d6147e5f19e01e5e122ac2c076486887ddcb8d42e663400fbe", size = 6989458, upload-time = "2026-09-14T06:58:11.884Z" }, + { url = "https://files.pythonhosted.org/packages/26/38/d0486230e684d916f97429a53041db88410e662a38f2a8d09e2d90375840/grpcio-1.84.0-cp313-cp313-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:b8c62888c3e49debf37ad9773e3c02f77b0c1e811f8fb0962f2b6c3bbab5b97a", size = 7757778, upload-time = "2026-09-14T06:58:14.849Z" }, + { url = "https://files.pythonhosted.org/packages/da/56/548a643decb059ca244499c675ae2c13a15f523ba94592c2774bd80a13c1/grpcio-1.84.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:986e9751d416d7a6eaa2fecdac38da63153d63a4b340ba7d624889c490451500", size = 7159572, upload-time = "2026-09-14T06:58:17.87Z" }, + { url = "https://files.pythonhosted.org/packages/db/f5/42caac81a79ec680f1f7a8eaf7ca90d2f93936ce0c3a073141ba96757f77/grpcio-1.84.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:5933a052946873d01a42119a05420d669bdca436aeba2d1851988ccb12b421c0", size = 7710547, upload-time = "2026-09-14T06:58:20.607Z" }, + { url = "https://files.pythonhosted.org/packages/57/a4/828ad990b2410fee0a55cc73aa1bf98eb5b911c54847374ef4f24b9e877b/grpcio-1.84.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:e094dd21f077af8194923fc263cad872eaa1802bb0156fd7e5ae18e99cd86715", size = 8761519, upload-time = "2026-09-14T06:58:23.875Z" }, + { url = "https://files.pythonhosted.org/packages/d5/a5/1f91af098919eaf5d80d5a61126ad9fae074e5190c25a3014ce1d8d0d890/grpcio-1.84.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:08735e3d08d24ab3132cf87e2e5dea8746cabcc7d676c2b0b7362f195feef9d9", size = 8121424, upload-time = "2026-09-14T06:58:27.006Z" }, + { url = "https://files.pythonhosted.org/packages/8c/8f/77fd4a7a913b636785479922349c4cb98d94d05d15652e556b3ca0df6663/grpcio-1.84.0-cp313-cp313-win32.whl", hash = "sha256:70bb4ce8be0c5606bec259cbd7152374470396413b7863a658a08c849e6b29ff", size = 4477974, upload-time = "2026-09-14T06:58:29.528Z" }, + { url = "https://files.pythonhosted.org/packages/d0/9a/1fa59ddbfc8898e5518d1447e46f771f387f0ed6132ad531395338e51a5c/grpcio-1.84.0-cp313-cp313-win_amd64.whl", hash = "sha256:b61692f0069b3eee2fc8a3a1b7f6c044df9e03fede6ce69b3ca832e1c39f26c5", size = 5255326, upload-time = "2026-09-14T06:58:31.781Z" }, +] + +[[package]] +name = "h11" +version = "0.16.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/01/ee/02a2c011bdab74c6fb3c75474d40b3052059d95df7e73351460c8588d963/h11-0.16.0.tar.gz", hash = "sha256:4e35b956cf45792e4caa5885e69fba00bdbc6ffafbfa020300e549b208ee5ff1", size = 101250, upload-time = "2025-04-24T03:35:25.427Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl", hash = "sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86", size = 37515, upload-time = "2025-04-24T03:35:24.344Z" }, +] + +[[package]] +name = "hf-xet" +version = "1.4.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/53/92/ec9ad04d0b5728dca387a45af7bc98fbb0d73b2118759f5f6038b61a57e8/hf_xet-1.4.3.tar.gz", hash = "sha256:8ddedb73c8c08928c793df2f3401ec26f95be7f7e516a7bee2fbb546f6676113", size = 670477, upload-time = "2026-03-31T22:40:07.874Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/72/43/724d307b34e353da0abd476e02f72f735cdd2bc86082dee1b32ea0bfee1d/hf_xet-1.4.3-cp313-cp313t-macosx_10_12_x86_64.whl", hash = "sha256:7551659ba4f1e1074e9623996f28c3873682530aee0a846b7f2f066239228144", size = 3800935, upload-time = "2026-03-31T22:39:49.618Z" }, + { url = "https://files.pythonhosted.org/packages/2b/d2/8bee5996b699262edb87dbb54118d287c0e1b2fc78af7cdc41857ba5e3c4/hf_xet-1.4.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:bee693ada985e7045997f05f081d0e12c4c08bd7626dc397f8a7c487e6c04f7f", size = 3558942, upload-time = "2026-03-31T22:39:47.938Z" }, + { url = "https://files.pythonhosted.org/packages/c3/a1/e993d09cbe251196fb60812b09a58901c468127b7259d2bf0f68bf6088eb/hf_xet-1.4.3-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:21644b404bb0100fe3857892f752c4d09642586fd988e61501c95bbf44b393a3", size = 4207657, upload-time = "2026-03-31T22:39:39.69Z" }, + { url = "https://files.pythonhosted.org/packages/64/44/9eb6d21e5c34c63e5e399803a6932fa983cabdf47c0ecbcfe7ea97684b8c/hf_xet-1.4.3-cp313-cp313t-manylinux_2_28_aarch64.whl", hash = "sha256:987f09cfe418237812896a6736b81b1af02a3a6dcb4b4944425c4c4fca7a7cf8", size = 3986765, upload-time = "2026-03-31T22:39:37.936Z" }, + { url = "https://files.pythonhosted.org/packages/ea/7b/8ad6f16fdb82f5f7284a34b5ec48645bd575bdcd2f6f0d1644775909c486/hf_xet-1.4.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:60cf7fc43a99da0a853345cf86d23738c03983ee5249613a6305d3e57a5dca74", size = 4188162, upload-time = "2026-03-31T22:39:58.382Z" }, + { url = "https://files.pythonhosted.org/packages/1b/c4/39d6e136cbeea9ca5a23aad4b33024319222adbdc059ebcda5fc7d9d5ff4/hf_xet-1.4.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:2815a49a7a59f3e2edf0cf113ae88e8cb2ca2a221bf353fb60c609584f4884d4", size = 4424525, upload-time = "2026-03-31T22:40:00.225Z" }, + { url = "https://files.pythonhosted.org/packages/46/f2/adc32dae6bdbc367853118b9878139ac869419a4ae7ba07185dc31251b76/hf_xet-1.4.3-cp313-cp313t-win_amd64.whl", hash = "sha256:42ee323265f1e6a81b0e11094564fb7f7e0ec75b5105ffd91ae63f403a11931b", size = 3671610, upload-time = "2026-03-31T22:40:10.42Z" }, + { url = "https://files.pythonhosted.org/packages/e2/19/25d897dcc3f81953e0c2cde9ec186c7a0fee413eb0c9a7a9130d87d94d3a/hf_xet-1.4.3-cp313-cp313t-win_arm64.whl", hash = "sha256:27c976ba60079fb8217f485b9c5c7fcd21c90b0367753805f87cb9f3cdc4418a", size = 3528529, upload-time = "2026-03-31T22:40:09.106Z" }, + { url = "https://files.pythonhosted.org/packages/ac/9f/9c23e4a447b8f83120798f9279d0297a4d1360bdbf59ef49ebec78fe2545/hf_xet-1.4.3-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:d0da85329eaf196e03e90b84c2d0aca53bd4573d097a75f99609e80775f98025", size = 3805048, upload-time = "2026-03-31T22:39:53.105Z" }, + { url = "https://files.pythonhosted.org/packages/0b/f8/7aacb8e5f4a7899d39c787b5984e912e6c18b11be136ef13947d7a66d265/hf_xet-1.4.3-cp37-abi3-macosx_11_0_arm64.whl", hash = "sha256:e23717ce4186b265f69afa66e6f0069fe7efbf331546f5c313d00e123dc84583", size = 3562178, upload-time = "2026-03-31T22:39:51.295Z" }, + { url = "https://files.pythonhosted.org/packages/df/9a/a24b26dc8a65f0ecc0fe5be981a19e61e7ca963b85e062c083f3a9100529/hf_xet-1.4.3-cp37-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:fc360b70c815bf340ed56c7b8c63aacf11762a4b099b2fe2c9bd6d6068668c08", size = 4212320, upload-time = "2026-03-31T22:39:42.922Z" }, + { url = "https://files.pythonhosted.org/packages/53/60/46d493db155d2ee2801b71fb1b0fd67696359047fdd8caee2c914cc50c79/hf_xet-1.4.3-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:39f2d2e9654cd9b4319885733993807aab6de9dfbd34c42f0b78338d6617421f", size = 3991546, upload-time = "2026-03-31T22:39:41.335Z" }, + { url = "https://files.pythonhosted.org/packages/bc/f5/067363e1c96c6b17256910830d1b54099d06287e10f4ec6ec4e7e08371fc/hf_xet-1.4.3-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:49ad8a8cead2b56051aa84d7fce3e1335efe68df3cf6c058f22a65513885baac", size = 4193200, upload-time = "2026-03-31T22:40:01.936Z" }, + { url = "https://files.pythonhosted.org/packages/42/4b/53951592882d9c23080c7644542fda34a3813104e9e11fa1a7d82d419cb8/hf_xet-1.4.3-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:7716d62015477a70ea272d2d68cd7cad140f61c52ee452e133e139abfe2c17ba", size = 4429392, upload-time = "2026-03-31T22:40:03.492Z" }, + { url = "https://files.pythonhosted.org/packages/8a/21/75a6c175b4e79662ad8e62f46a40ce341d8d6b206b06b4320d07d55b188c/hf_xet-1.4.3-cp37-abi3-win_amd64.whl", hash = "sha256:6b591fcad34e272a5b02607485e4f2a1334aebf1bc6d16ce8eb1eb8978ac2021", size = 3677359, upload-time = "2026-03-31T22:40:13.619Z" }, + { url = "https://files.pythonhosted.org/packages/8a/7c/44314ecd0e89f8b2b51c9d9e5e7a60a9c1c82024ac471d415860557d3cd8/hf_xet-1.4.3-cp37-abi3-win_arm64.whl", hash = "sha256:7c2c7e20bcfcc946dc67187c203463f5e932e395845d098cc2a93f5b67ca0b47", size = 3533664, upload-time = "2026-03-31T22:40:12.152Z" }, +] + +[[package]] +name = "hiredis" +version = "3.4.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/38/da/41b341ebed1eb6f1074112936af98bb52880724737887ae9bade9d7ce107/hiredis-3.4.2.tar.gz", hash = "sha256:9a566dc70e9dd84be3550babc56a8e109bb65cafcac635aea027fa425196a7d7", size = 138058, upload-time = "2026-09-22T12:39:20.363Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/38/e8/6d2b68e1889692bf8e48dcbb163c7723c480788a5d7cd034781b0a554ef7/hiredis-3.4.2-cp313-cp313-macosx_10_15_universal2.whl", hash = "sha256:8bdec17c14272b3420d458ef7db9fac1ec3d3cacb39a6a6f860adf1c6c0a450f", size = 140923, upload-time = "2026-09-22T12:38:05.453Z" }, + { url = "https://files.pythonhosted.org/packages/bb/83/1271ef079685808f30077194059070378e1aaefa0a8aa32a2eeaf6ea11a6/hiredis-3.4.2-cp313-cp313-macosx_10_15_x86_64.whl", hash = "sha256:de48b33d4aef8389ff651eb0f0b761bf3962021d7719209ab2edd9ea85106b4b", size = 75187, upload-time = "2026-09-22T12:38:06.872Z" }, + { url = "https://files.pythonhosted.org/packages/3d/f0/7560c4d2c63abd249aad70653108a8a6345c49656723c098cf5af009d528/hiredis-3.4.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:e8f8d3ec07e3a1af1a636e0a976e5f353c11c446203cd7ce9c5f1fd93cfd56b6", size = 71993, upload-time = "2026-09-22T12:38:07.823Z" }, + { url = "https://files.pythonhosted.org/packages/28/17/9fc420f37e9f6ae902f9764fca0f219b98189a1a2d1a068ae49ac5c97da9/hiredis-3.4.2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4ab8ee294d20562d21c9617a458ab2c9571ec3c7abab8400b690b79d0b257803", size = 307044, upload-time = "2026-09-22T12:38:08.772Z" }, + { url = "https://files.pythonhosted.org/packages/53/1a/f9c37491fe9ee971eff9ef662ea2e298e362316db362ae41e0921cdf073f/hiredis-3.4.2-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:d7a6a3b3941b102ef384f6269a7e99e069258a7d91b74a3d5ff2a0f214d5cdce", size = 340095, upload-time = "2026-09-22T12:38:09.945Z" }, + { url = "https://files.pythonhosted.org/packages/bc/d6/bab0f4748558168ca9355c63f9a4655c4db3dffcf2a8dbacb74582a9b5d4/hiredis-3.4.2-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b5ea3875d66c8d335edc12d65f029d2a016ca6484ac69e9095f4e4623ea3d107", size = 351889, upload-time = "2026-09-22T12:38:10.995Z" }, + { url = "https://files.pythonhosted.org/packages/6d/f3/a96b36649b5aef152002fd0e65b221d1300d9afad274f53619083eb5bfd3/hiredis-3.4.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:89d11728ca16590b3b851587f99dd9d2101974f66d94bfd07c38b0578e486841", size = 313399, upload-time = "2026-09-22T12:38:11.978Z" }, + { url = "https://files.pythonhosted.org/packages/64/1a/bee695a722231c26fc1eb85cc66005212c4086705e47790a1281f9c0a3c1/hiredis-3.4.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:7d0d592d54e540648f6107d2744ae40bc637082c12dfe96778957200ab842831", size = 301484, upload-time = "2026-09-22T12:38:13.049Z" }, + { url = "https://files.pythonhosted.org/packages/8d/fe/6819c9b2a818ef4343fc4c6415eae43a857a78a391dc6a375c06b3744f1c/hiredis-3.4.2-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:d24aa3d880eb9e122235b45a0a91afc80cb83c463d8ff9dffa33159e45fe5107", size = 332064, upload-time = "2026-09-22T12:38:14.337Z" }, + { url = "https://files.pythonhosted.org/packages/65/95/1ea7dd6928722477cdbd904ba5be0d22fc5ce5a7e90295ed591dbaeecdff/hiredis-3.4.2-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:93909eb7d3389a80e2774133c297c0ec356e7cabd1c37742f2629501a8e555cb", size = 333375, upload-time = "2026-09-22T12:38:15.679Z" }, + { url = "https://files.pythonhosted.org/packages/14/0a/356156a233f2abee3f15502e1df4fc59c3e2293e034e2e930a35e2fa79f6/hiredis-3.4.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:80820aa4885a82b045753e1e258761fcfe491e09d9fc182a45dea9f160878574", size = 312294, upload-time = "2026-09-22T12:38:16.774Z" }, + { url = "https://files.pythonhosted.org/packages/94/b3/2b1e7cebe655d22346ed44a699755bac6f410d5a6ea4948dd19efc821c04/hiredis-3.4.2-cp313-cp313-win32.whl", hash = "sha256:46bf795db56734f5168e10b243aa98fc2306b4804997410d843c869f250d28c4", size = 38734, upload-time = "2026-09-22T12:38:17.797Z" }, + { url = "https://files.pythonhosted.org/packages/3f/71/f57d794a003e9b689413b98c2cf9ebe8136ed51bfe17ca33a88c2d1ef335/hiredis-3.4.2-cp313-cp313-win_amd64.whl", hash = "sha256:b5c44386f45ae56e5648793ba64371533308e4290f9ce2fbb66ed9de10eb982e", size = 40546, upload-time = "2026-09-22T12:38:18.63Z" }, + { url = "https://files.pythonhosted.org/packages/0c/86/4c23c7dd7e0ca02ff33a5649e8d1644bf57f8f2b756afa7b046a8e3de6d9/hiredis-3.4.2-cp313-cp313-win_arm64.whl", hash = "sha256:92329ad22182fcb1c0bce521fb0ea4ed51b243a1d9e8dd0b87b68072c7a52026", size = 36940, upload-time = "2026-09-22T12:38:19.499Z" }, +] + +[[package]] +name = "httpcore" +version = "1.0.9" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "certifi" }, + { name = "h11" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/06/94/82699a10bca87a5556c9c59b5963f2d039dbd239f25bc2a63907a05a14cb/httpcore-1.0.9.tar.gz", hash = "sha256:6e34463af53fd2ab5d807f399a9b45ea31c3dfa2276f15a2c3f00afff6e176e8", size = 85484, upload-time = "2025-04-24T22:06:22.219Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl", hash = "sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55", size = 78784, upload-time = "2025-04-24T22:06:20.566Z" }, +] + +[[package]] +name = "httpcore2" +version = "2.13.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "h11" }, + { name = "truststore" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/cb/f3/1db7aa2bc2524062192bb0e0323969492d1883152a232fe36eea65f4e35c/httpcore2-2.13.1.tar.gz", hash = "sha256:e0aa977abe17e69a3b820a24542a6fa88702676d83880b8d194dcd18408e5103", size = 68071, upload-time = "2026-09-23T07:47:22.372Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/09/ba/a4568248771ce81957bfb7cc600264a40fbcda092391ee1c415c50be4bea/httpcore2-2.13.1-py3-none-any.whl", hash = "sha256:e1e05d4f25f7d7d496bfb96748f6f4b67657b03da069b3a68c36069f3db73d0a", size = 83423, upload-time = "2026-09-23T07:47:19.365Z" }, +] + +[[package]] +name = "httpx" +version = "0.28.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anyio" }, + { name = "certifi" }, + { name = "httpcore" }, + { name = "idna" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b1/df/48c586a5fe32a0f01324ee087459e112ebb7224f646c0b5023f5e79e9956/httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc", size = 141406, upload-time = "2024-12-06T15:37:23.222Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad", size = 73517, upload-time = "2024-12-06T15:37:21.509Z" }, +] + +[[package]] +name = "httpx2" +version = "2.13.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anyio", marker = "sys_platform != 'emscripten'" }, + { name = "httpcore2", marker = "sys_platform != 'emscripten'" }, + { name = "httpx2-jsfetch", marker = "sys_platform == 'emscripten'" }, + { name = "idna" }, + { name = "truststore", marker = "sys_platform != 'emscripten'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/d5/44/474bef2a0e9d90f1715d32cb98b0738695ca17ba324095fb2497ed7fbd59/httpx2-2.13.1.tar.gz", hash = "sha256:e48744a19e3af5ee48313d0ce5fe941d5422fae5705ea922a4aabf94d7800dfa", size = 100405, upload-time = "2026-09-23T07:47:23.052Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d8/9c/6fe8931fd9f381042a9e4c7d5a7b4cbf7016b252bec0c99a49fce42c3326/httpx2-2.13.1-py3-none-any.whl", hash = "sha256:6dff50fabc270ee5fd25d845d0b078ed20564579744d6d962850975996d2f9a4", size = 95597, upload-time = "2026-09-23T07:47:20.995Z" }, +] + +[[package]] +name = "httpx2-jsfetch" +version = "1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/cd/c4/0e5636363151a2a1795e0a77617168b9ca438e1748ec05fc9b5687f93d64/httpx2_jsfetch-1.0.tar.gz", hash = "sha256:70a0e3eabfef7cce5ad9c629f7d01ca05e418f586646f4ddf14782e4c1454c60", size = 6872, upload-time = "2026-08-07T00:13:07.492Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9b/43/832f631d32e4f1211caa2ba368317739fe71f0b8530e4c9d15dc454bac2a/httpx2_jsfetch-1.0-py3-none-any.whl", hash = "sha256:cb916b707601e69a07721aabc8f3f6659be3a6893bc1ff5c6f9e02241df2da32", size = 6382, upload-time = "2026-08-07T00:13:06.567Z" }, +] + +[[package]] +name = "huggingface-hub" +version = "1.18.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "click" }, + { name = "filelock" }, + { name = "fsspec" }, + { name = "hf-xet", marker = "platform_machine == 'AMD64' or platform_machine == 'aarch64' or platform_machine == 'amd64' or platform_machine == 'arm64' or platform_machine == 'x86_64'" }, + { name = "httpx" }, + { name = "packaging" }, + { name = "pyyaml" }, + { name = "tqdm" }, + { name = "typer" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/fb/d8/748ea0a47f0fa15227fe682f7a80826b4b7c096e4818044b8f56d6cb66d6/huggingface_hub-1.18.0.tar.gz", hash = "sha256:f0c5ecd1ef8c6a60f86f61ee278f2c1570ba9e279c9f54de9094210723b3613b", size = 812699, upload-time = "2026-06-05T09:26:33.401Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0b/03/40a05316cb6616e5b7efd7773656441ab04b4b022c2199e79bb4622a92a3/huggingface_hub-1.18.0-py3-none-any.whl", hash = "sha256:729be4a976fb706dcc02d176bcda8a3f32bdf21a294e8f4b3dda6fbcbc9c1ab1", size = 684411, upload-time = "2026-06-05T09:26:31.48Z" }, +] + +[[package]] +name = "idna" +version = "3.20" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f5/08/8eea9d4b8302028f3abb2c0813953f7aec26d33b7a8960ed760e65ff29fa/idna-3.20.tar.gz", hash = "sha256:a7db850025b95ded1eae8a46181a1a6c56c92c96f0e2b005d9ff8dc0210cab44", size = 216463, upload-time = "2026-09-17T14:11:04.752Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/58/a2/bb081bab032533a855d44de1d56f8e8426114ff1ba5d1f07a438a0a654f8/idna-3.20-py3-none-any.whl", hash = "sha256:ab7ae7122974553370f0bdb919e1a960b2cd1bc1ef0276416d896db81c14582c", size = 69583, upload-time = "2026-09-17T14:11:03.168Z" }, +] + +[[package]] +name = "iniconfig" +version = "2.3.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/01/e1/2069291243c926a2ff1cd706c7f3eeb9b62144bf60f77c9fb9ff2fb26bd3/iniconfig-2.3.1.tar.gz", hash = "sha256:67f4b9c50da0dedf52af349e7749a80a9057a5031199791b906c3bb3ae878960", size = 21209, upload-time = "2026-10-06T22:48:38.076Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/56/43/4ca9e49d27a1fcf6bece6f6aec0ea46bb9112489b93d4b688fb415457bdb/iniconfig-2.3.1-py3-none-any.whl", hash = "sha256:9121e2c1fdb355232495be3194c8dfe87ccc2d5dee45947b78e68f499790d7a7", size = 7552, upload-time = "2026-10-06T22:48:36.959Z" }, +] + +[[package]] +name = "isodate" +version = "0.7.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/54/4d/e940025e2ce31a8ce1202635910747e5a87cc3a6a6bb2d00973375014749/isodate-0.7.2.tar.gz", hash = "sha256:4cd1aa0f43ca76f4a6c6c0292a85f40b35ec2e43e315b59f06e6d32171a953e6", size = 29705, upload-time = "2024-10-08T23:04:11.5Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/15/aa/0aca39a37d3c7eb941ba736ede56d689e7be91cab5d9ca846bde3999eba6/isodate-0.7.2-py3-none-any.whl", hash = "sha256:28009937d8031054830160fce6d409ed342816b543597cece116d966c6d99e15", size = 22320, upload-time = "2024-10-08T23:04:09.501Z" }, +] + +[[package]] +name = "jaraco-classes" +version = "3.4.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "more-itertools" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/06/c0/ed4a27bc5571b99e3cff68f8a9fa5b56ff7df1c2251cc715a652ddd26402/jaraco.classes-3.4.0.tar.gz", hash = "sha256:47a024b51d0239c0dd8c8540c6c7f484be3b8fcf0b2d85c13825780d3b3f3acd", size = 11780, upload-time = "2024-03-31T07:27:36.643Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7f/66/b15ce62552d84bbfcec9a4873ab79d993a1dd4edb922cbfccae192bd5b5f/jaraco.classes-3.4.0-py3-none-any.whl", hash = "sha256:f662826b6bed8cace05e7ff873ce0f9283b5c924470fe664fff1c2f00f581790", size = 6777, upload-time = "2024-03-31T07:27:34.792Z" }, +] + +[[package]] +name = "jaraco-context" +version = "6.1.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/af/50/4763cd07e722bb6285316d390a164bc7e479db9d90daa769f22578f698b4/jaraco_context-6.1.2.tar.gz", hash = "sha256:f1a6c9d391e661cc5b8d39861ff077a7dc24dc23833ccee564b234b81c82dfe3", size = 16801, upload-time = "2026-03-20T22:13:33.922Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f2/58/bc8954bda5fcda97bd7c19be11b85f91973d67a706ed4a3aec33e7de22db/jaraco_context-6.1.2-py3-none-any.whl", hash = "sha256:bf8150b79a2d5d91ae48629d8b427a8f7ba0e1097dd6202a9059f29a36379535", size = 7871, upload-time = "2026-03-20T22:13:32.808Z" }, +] + +[[package]] +name = "jaraco-functools" +version = "4.6.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "more-itertools" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/6c/1f/c23395957d41ccf27c4e535c3d334c4051e5395b3752057ba4cbaec35c56/jaraco_functools-4.6.0.tar.gz", hash = "sha256:880c577ec9720b3a052d5bc611fb9f2269b3d87902ef42440df443b88e443280", size = 20837, upload-time = "2026-07-14T01:28:02.544Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/02/36/ecc85bc96c273dc8a11273ed4782272975e6338d4a3e9228621175edf0e3/jaraco_functools-4.6.0-py3-none-any.whl", hash = "sha256:99e3dc0060c5cbe8fcd1cdb36258e2a65ca40f1566b2033b12abb1bb44dd3c30", size = 11677, upload-time = "2026-07-14T01:28:01.59Z" }, +] + +[[package]] +name = "jeepney" +version = "0.9.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/7b/6f/357efd7602486741aa73ffc0617fb310a29b588ed0fd69c2399acbb85b0c/jeepney-0.9.0.tar.gz", hash = "sha256:cf0e9e845622b81e4a28df94c40345400256ec608d0e55bb8a3feaa9163f5732", size = 106758, upload-time = "2025-02-27T18:51:01.684Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b2/a3/e137168c9c44d18eff0376253da9f1e9234d0239e0ee230d2fee6cea8e55/jeepney-0.9.0-py3-none-any.whl", hash = "sha256:97e5714520c16fc0a45695e5365a2e11b81ea79bba796e26f9f1d178cb182683", size = 49010, upload-time = "2025-02-27T18:51:00.104Z" }, +] + +[[package]] +name = "jinja2" +version = "3.1.6" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markupsafe" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/df/bf/f7da0350254c0ed7c72f3e33cef02e048281fec7ecec5f032d4aac52226b/jinja2-3.1.6.tar.gz", hash = "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d", size = 245115, upload-time = "2025-03-05T20:05:02.478Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67", size = 134899, upload-time = "2025-03-05T20:05:00.369Z" }, +] + +[[package]] +name = "jiter" +version = "0.17.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/9c/1f/8176d92e001f86505424b41664032ae26a882bc9ca41a32c803f373f9195/jiter-0.17.0.tar.gz", hash = "sha256:03e432f226a453851079fb84cd17c6da9991eab723e28d716f14ae3d906e0c12", size = 229037, upload-time = "2026-09-12T15:14:14.253Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/40/eb/2c4a8075ed5ea02b56911e9375d4c8d7784572ff4af32e5a99ae0d071044/jiter-0.17.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:1b18434638228c0c184281609bf3d9459026a0f1ea48fb76c205e3ef72069caa", size = 290991, upload-time = "2026-09-12T15:12:11.641Z" }, + { url = "https://files.pythonhosted.org/packages/ca/b1/34bfa29599d420423baac6ff7cada6674fe63d5a7a2ccb3900b904678783/jiter-0.17.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:ec89771f4272b989487a6364e519db6bbaba323e8bbf949ac89a45ea9c18b7a3", size = 321425, upload-time = "2026-09-12T15:12:13.855Z" }, + { url = "https://files.pythonhosted.org/packages/11/71/a5ac64a62a04aebd556afadab14a6b730001e16df87266ded943a100a1d9/jiter-0.17.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e3f052c671d5f425cca5ea5901cf11a831369fba4a55a3862cab93c323b4c3b", size = 343138, upload-time = "2026-09-12T15:12:15.046Z" }, + { url = "https://files.pythonhosted.org/packages/01/dd/f761e320ea473314cb68612bc6a435393464dbd198051399b36848b4ebf3/jiter-0.17.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:785a216bbaf8f15fc974e964ced7322cd3d774bb0e86949edd78c6bffd6ba35b", size = 325805, upload-time = "2026-09-12T15:12:16.506Z" }, + { url = "https://files.pythonhosted.org/packages/19/1a/27d8e40f0fb29bbc7a5adf30907144396a115dbe93d5d8976c054a6dfe96/jiter-0.17.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d85c558c9f8532bba287a990ac63767c7daf756f0d8c030219f62499b1fa228a", size = 340230, upload-time = "2026-09-12T15:12:17.682Z" }, + { url = "https://files.pythonhosted.org/packages/ac/c0/30bcde78a28155461f965d16b7aca4ffca6d17494d905f7a0bb072e6c64e/jiter-0.17.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5c23849235d2142ce444b2b8c6eceee9f82f4cc0bd5c9081602e4155c6197807", size = 351343, upload-time = "2026-09-12T15:12:19.337Z" }, + { url = "https://files.pythonhosted.org/packages/27/17/91420b156315ae22732f5ee1a7b5725a030aab9dc8fd7dcdacfb4aa588d3/jiter-0.17.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:58df29268a95e910f17db7ec9178eb7f15aa8619aaca3575275c4e6b3f4fe4c5", size = 344990, upload-time = "2026-09-12T15:12:20.705Z" }, + { url = "https://files.pythonhosted.org/packages/6d/a2/ae6d5672644cc11127970277c9aeb0fa6fae376845587f5b0a8e8828167c/jiter-0.17.0-cp313-cp313-manylinux_2_31_riscv64.whl", hash = "sha256:a277f97eba7d66b1ee27eb5dab5b774ff46a10c78d89a1d3dcce04ce1357c8ca", size = 328624, upload-time = "2026-09-12T15:12:23.859Z" }, + { url = "https://files.pythonhosted.org/packages/04/62/45cb1162f6aa586536e4a973fc339d72dc6b08cca030d70a838a307aa778/jiter-0.17.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:fe15ddf316f1f1f643347d3a474e74ce61880c79a11ec5dca53df20c071bd3e8", size = 334731, upload-time = "2026-09-12T15:12:25.229Z" }, + { url = "https://files.pythonhosted.org/packages/d9/5f/45c1574b644da7deda0b7591c349520dcf83ce45b24d7ca19922dab1fc27/jiter-0.17.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:02adebb7ce6413c44d40af9ad59d1c1cd79630ccdcb6f7bdd2d461e48c03d8f9", size = 483649, upload-time = "2026-09-12T15:12:27.557Z" }, + { url = "https://files.pythonhosted.org/packages/c1/d3/ebea1ecb5b241c519f192b30215c79a8e47f42f1621acbcd6f8830728416/jiter-0.17.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:55d0e0e613a3f9ad600cf436e0e2b8057d1b52bcf1d91b2d36ac53451231e6a8", size = 520758, upload-time = "2026-09-12T15:12:28.99Z" }, + { url = "https://files.pythonhosted.org/packages/64/e6/682b641ff0765ea9bdc349dbc7d223de5c8af8ec1abda0db3406992f92fe/jiter-0.17.0-cp313-cp313-win32.whl", hash = "sha256:2c45ad7c973ef33fe5114a953377b35a95240f4542c0724d9f781e47dc24bac7", size = 184334, upload-time = "2026-09-12T15:12:30.813Z" }, + { url = "https://files.pythonhosted.org/packages/b8/d2/9a49aac2b27af4cc5015e368c0cc3588491a532f717a668ffce1f1ac57da/jiter-0.17.0-cp313-cp313-win_amd64.whl", hash = "sha256:a3cebb1fe4a1abb00465f3f8a17e09112603e8b7c59e5c3adbcd9f7815a64acd", size = 226601, upload-time = "2026-09-12T15:12:32.096Z" }, + { url = "https://files.pythonhosted.org/packages/b4/ce/9a43e9f614608eafa78de22aedcff54cd21324467b5d442d5c9b00244145/jiter-0.17.0-cp313-cp313-win_arm64.whl", hash = "sha256:96b8b0c6dc5d78682f54a450785e075aa929cde768304cad363cd4efba5a82ac", size = 183103, upload-time = "2026-09-12T15:12:34.396Z" }, +] + +[[package]] +name = "jmespath" +version = "1.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d3/59/322338183ecda247fb5d1763a6cbe46eff7222eaeebafd9fa65d4bf5cb11/jmespath-1.1.0.tar.gz", hash = "sha256:472c87d80f36026ae83c6ddd0f1d05d4e510134ed462851fd5f754c8c3cbb88d", size = 27377, upload-time = "2026-01-22T16:35:26.279Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/14/2f/967ba146e6d58cf6a652da73885f52fc68001525b4197effc174321d70b4/jmespath-1.1.0-py3-none-any.whl", hash = "sha256:a5663118de4908c91729bea0acadca56526eb2698e83de10cd116ae0f4e97c64", size = 20419, upload-time = "2026-01-22T16:35:24.919Z" }, +] + +[[package]] +name = "joblib" +version = "1.6.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cloudpickle" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/d5/1d/537ab090f302b838943a1b56497dd53059b9a9b46a074936470173a2e207/joblib-1.6.0.tar.gz", hash = "sha256:2ccc96785b12046c08fd6d55839c12857831b54a3c1673ffadd2f04bfc4eda03", size = 327903, upload-time = "2026-08-31T09:39:04.122Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/18/53/84099323c2ec4be98d935f63c033ac4151ee83836ca1050ede3b3aadf155/joblib-1.6.0-py3-none-any.whl", hash = "sha256:3dbbf9f6e4b592a2357b854608e980fe6390d131d7a82f011a377ef2ebef7aba", size = 306115, upload-time = "2026-08-31T09:39:02.298Z" }, +] + +[[package]] +name = "joserfc" +version = "1.7.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cryptography" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/19/94/80fea1514b7c6d7d37804d3fe9ca81455f633347fc98731bd71ffe1faa17/joserfc-1.7.5.tar.gz", hash = "sha256:d5ff536e658e17664f8c1b1ab60dc4aa62aa973fcef1edd33cc44bda45d6f5ea", size = 234990, upload-time = "2026-08-29T13:05:42.057Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/67/c5/82addfd375e5ee6520644e0553e4aadde92d668c4fc99cc716d337fe7bb3/joserfc-1.7.5-py3-none-any.whl", hash = "sha256:add2c2c84e8373b084d526a8b53daba5d7a513a118cd2dcd9fc9f979d0922159", size = 71269, upload-time = "2026-08-29T13:05:40.718Z" }, +] + +[[package]] +name = "jsonpath-python" +version = "1.1.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/98/18/4ca8742534a5993ff383f7602e325ce2d5d7cc93d72ac5e1cdedbea8a458/jsonpath_python-1.1.6.tar.gz", hash = "sha256:dded9932b4ec41fb8726e09c83afa4e6be618f938c2db287cc2a81723c639671", size = 88178, upload-time = "2026-05-07T01:26:34.482Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/55/8a/1270a6803bd821cbfcdda387eaa13cb41a7b1f7b9bd145979b3bfb9d6cb7/jsonpath_python-1.1.6-py3-none-any.whl", hash = "sha256:a1c50afd8d3fbbaf47a4873bc890dcb3c15da96f5c020327977d844d8731a2d4", size = 14453, upload-time = "2026-05-07T01:26:33.306Z" }, +] + +[[package]] +name = "jsonschema" +version = "4.26.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "attrs" }, + { name = "jsonschema-specifications" }, + { name = "referencing" }, + { name = "rpds-py" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b3/fc/e067678238fa451312d4c62bf6e6cf5ec56375422aee02f9cb5f909b3047/jsonschema-4.26.0.tar.gz", hash = "sha256:0c26707e2efad8aa1bfc5b7ce170f3fccc2e4918ff85989ba9ffa9facb2be326", size = 366583, upload-time = "2026-01-07T13:41:07.246Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/69/90/f63fb5873511e014207a475e2bb4e8b2e570d655b00ac19a9a0ca0a385ee/jsonschema-4.26.0-py3-none-any.whl", hash = "sha256:d489f15263b8d200f8387e64b4c3a75f06629559fb73deb8fdfb525f2dab50ce", size = 90630, upload-time = "2026-01-07T13:41:05.306Z" }, +] + +[[package]] +name = "jsonschema-specifications" +version = "2025.9.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "referencing" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/19/74/a633ee74eb36c44aa6d1095e7cc5569bebf04342ee146178e2d36600708b/jsonschema_specifications-2025.9.1.tar.gz", hash = "sha256:b540987f239e745613c7a9176f3edb72b832a4ac465cf02712288397832b5e8d", size = 32855, upload-time = "2025-09-08T01:34:59.186Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/41/45/1a4ed80516f02155c51f51e8cedb3c1902296743db0bbc66608a0db2814f/jsonschema_specifications-2025.9.1-py3-none-any.whl", hash = "sha256:98802fee3a11ee76ecaca44429fda8a41bff98b00a0f2838151b113f210cc6fe", size = 18437, upload-time = "2025-09-08T01:34:57.871Z" }, +] + +[[package]] +name = "keyring" +version = "25.7.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "jaraco-classes" }, + { name = "jaraco-context" }, + { name = "jaraco-functools" }, + { name = "jeepney", marker = "sys_platform == 'linux'" }, + { name = "pywin32-ctypes", marker = "sys_platform == 'win32'" }, + { name = "secretstorage", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/43/4b/674af6ef2f97d56f0ab5153bf0bfa28ccb6c3ed4d1babf4305449668807b/keyring-25.7.0.tar.gz", hash = "sha256:fe01bd85eb3f8fb3dd0405defdeac9a5b4f6f0439edbb3149577f244a2e8245b", size = 63516, upload-time = "2025-11-16T16:26:09.482Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/81/db/e655086b7f3a705df045bf0933bdd9c2f79bb3c97bfef1384598bb79a217/keyring-25.7.0-py3-none-any.whl", hash = "sha256:be4a0b195f149690c166e850609a477c532ddbfbaed96a404d4e43f8d5e2689f", size = 39160, upload-time = "2025-11-16T16:26:08.402Z" }, +] + +[[package]] +name = "logfire" +version = "5.2.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "executing" }, + { name = "opentelemetry-api" }, + { name = "opentelemetry-exporter-otlp-proto-http" }, + { name = "opentelemetry-instrumentation" }, + { name = "opentelemetry-sdk" }, + { name = "opentelemetry-semantic-conventions" }, + { name = "protobuf" }, + { name = "requests" }, + { name = "rich" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/56/5a/e6cccc98d30358b8beee47c61c2a1ca66ac7a76a07de9ba333aa5219b9a6/logfire-5.2.0.tar.gz", hash = "sha256:5fb9ddda303759766e86f5704a1ae96f3a0072906d52e21fbaad2e3c3b03f823", size = 1404990, upload-time = "2026-10-13T17:36:30.746Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/73/cb/bfcd484c16eeac8cdeb2defe1a2ee39bb1b4b6e69324b85515e7818eb678/logfire-5.2.0-py3-none-any.whl", hash = "sha256:c73dd02cfe048f2254e803962aa992d7f53217d121f3488e797926c30442342c", size = 495128, upload-time = "2026-10-13T17:36:27.305Z" }, +] + +[package.optional-dependencies] +httpx = [ + { name = "opentelemetry-instrumentation-httpx" }, +] + +[[package]] +name = "logfire-api" +version = "5.2.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/3e/ef/302ecf3ea120d1ce127fae8a15ee5cfa6d178d956d253d332f49b7bc8f0c/logfire_api-5.2.0.tar.gz", hash = "sha256:06553f4a4b1b54d094dd01708f51cde69ccd5e8a06fc2664bece3491b593390d", size = 99170, upload-time = "2026-10-13T17:36:32.044Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b9/5a/cd2d6e41b04c932c33dd027e119e3b6923c740e7b68da6f78cfb901040b4/logfire_api-5.2.0-py3-none-any.whl", hash = "sha256:f4bd56df590ba7e7a32adb0302c82af38dc4edb9eecd03b1bfa03ffa581eecf8", size = 151057, upload-time = "2026-10-13T17:36:29.201Z" }, +] + +[[package]] +name = "mako" +version = "1.4.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markupsafe" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/5a/09/e07c4b5579a79f4b16f8d4f29f6c54514ac787c4ad506b8c4f28a0e6b0bf/mako-1.4.3.tar.gz", hash = "sha256:cd6537fe88d5fec315c55c2f8529bc4ce7a9a352ad7db3eeaa6a66e2dd4ec37a", size = 412799, upload-time = "2026-09-22T20:54:31.509Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6d/a0/053d6af3e8f871e0073b4a36732d9e65be77a72e5434c31b94f6af78a6bb/mako-1.4.3-py3-none-any.whl", hash = "sha256:723296007c870bfd6b3f0c3230dba7198096e5269297ebf5e4eff9e7ffa39d4f", size = 80164, upload-time = "2026-09-22T20:54:33.128Z" }, +] + +[[package]] +name = "markdown-it-py" +version = "4.2.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mdurl" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/06/ff/7841249c247aa650a76b9ee4bbaeae59370dc8bfd2f6c01f3630c35eb134/markdown_it_py-4.2.0.tar.gz", hash = "sha256:04a21681d6fbb623de53f6f364d352309d4094dd4194040a10fd51833e418d49", size = 82454, upload-time = "2026-05-07T12:08:28.36Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b3/81/4da04ced5a082363ecfa159c010d200ecbd959ae410c10c0264a38cac0f5/markdown_it_py-4.2.0-py3-none-any.whl", hash = "sha256:9f7ebbcd14fe59494226453aed97c1070d83f8d24b6fc3a3bcf9a38092641c4a", size = 91687, upload-time = "2026-05-07T12:08:27.182Z" }, +] + +[[package]] +name = "markupsafe" +version = "3.0.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/38/9b/e422a865e1d5d57d0e509b4e0bf1c1a70a7f6382c29a5aa428df994c8bc8/markupsafe-3.0.4.tar.gz", hash = "sha256:2e9ad7dd851bf45fab9f75cbff4cb493fee9979e8d8c7c9c3ee119022518edd6", size = 153777, upload-time = "2026-10-02T23:07:22.29Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6d/18/4bc5ba32499e87bb2b0ef5b3a9bb9c00a131fa961ddf0be548cb550f548b/markupsafe-3.0.4-cp313-cp313-android_24_arm64_v8a.whl", hash = "sha256:de8b364c423ef0a4bad9069657d617f9a5d2b2062457a89b1fa16ee199c399c1", size = 12786, upload-time = "2026-10-02T23:05:08.709Z" }, + { url = "https://files.pythonhosted.org/packages/4e/6f/17f0c099bf25f3e31e63cc19244d9f6af861a9a4ab778c203997903cfdd0/markupsafe-3.0.4-cp313-cp313-android_24_x86_64.whl", hash = "sha256:34bdde374c5932765d7dc685c4a1d191a3207852d67e8e0a9eb6ea85156181f1", size = 12510, upload-time = "2026-10-02T23:05:09.93Z" }, + { url = "https://files.pythonhosted.org/packages/11/af/1a141081b905036ee904ec4bd945e1f70b4e1b32d33c4e59e8cf1d58b247/markupsafe-3.0.4-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:6bd9e1788e15bfcf6a9082de42e30387e7b85d211ab21e57a939bb8cfaaf8d96", size = 11583, upload-time = "2026-10-02T23:05:10.884Z" }, + { url = "https://files.pythonhosted.org/packages/e7/0a/a89385ae590232622a03e091805cff12f24fabe6c11e0e8bae096cece81c/markupsafe-3.0.4-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:5066b244f576f91afc8ee3ba029a89f99d39c79b1853fe9d39bea9f0afbec148", size = 11801, upload-time = "2026-10-02T23:05:11.913Z" }, + { url = "https://files.pythonhosted.org/packages/ed/85/ea548dc013962eb73653124bc595635fbf9e0fa41d1f181a967ccb784dfb/markupsafe-3.0.4-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:7a83aa6e4805df46fed18e989d3d16f86ef60cb50bbc8d9ce3a6be89165fbf6e", size = 11443, upload-time = "2026-10-02T23:05:12.887Z" }, + { url = "https://files.pythonhosted.org/packages/cc/72/15f2e5ec9cf2eb00d5cdfe968d94e4156a7bd7303832c3f3b2c403a36839/markupsafe-3.0.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:2d1b7d9308288661f56672b1b157d75fc536714d3638487bbea17b6318a78248", size = 11665, upload-time = "2026-10-02T23:05:13.829Z" }, + { url = "https://files.pythonhosted.org/packages/ca/e0/4030bea613677e333c8a2c901fd405055f657f9d06acba5b7357984b6ef7/markupsafe-3.0.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:73e77980c7207854f00fc4e71fb1626868d5740ab4012623d55c7a99ad122a72", size = 12061, upload-time = "2026-10-02T23:05:14.807Z" }, + { url = "https://files.pythonhosted.org/packages/f3/a5/28b76a7449eb702966b88bef599e2360b411fbb3afeee8fe560939be06ec/markupsafe-3.0.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7018d4af1cd272e847aa5917983ab5e83e4f6579f9dbfecd4a79c0ca80b144c2", size = 24395, upload-time = "2026-10-02T23:05:15.909Z" }, + { url = "https://files.pythonhosted.org/packages/07/6c/21232811afc3a063b5e934b1ae2efda52f46154ec382f585149c020e61fe/markupsafe-3.0.4-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:c90d5b3d4e944e065a301d741b3c1d784f6bd1f503aa68b4967e32b2ba313d85", size = 27183, upload-time = "2026-10-02T23:05:16.976Z" }, + { url = "https://files.pythonhosted.org/packages/14/38/6ccdfa5b59049cb36fb80cbc80aee9cf1fc9bb77d1335ad435f2070b08cf/markupsafe-3.0.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:18a801868a884f216e784d7d14db2a4077143ce7610440aee2ce8f734e7cfcde", size = 24772, upload-time = "2026-10-02T23:05:18.209Z" }, + { url = "https://files.pythonhosted.org/packages/63/e0/cec6865dfe88cb48fedd4b20aed6af5158e41092adcbf3e028bcc6ec2108/markupsafe-3.0.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:434139499bb20b502ed3baa1f169e618f924a97e7a777fea1a49446d80106cf6", size = 23017, upload-time = "2026-10-02T23:05:19.286Z" }, + { url = "https://files.pythonhosted.org/packages/ee/76/6ed4940bb7648a9aac457c14f870cfdd5105f139a0fb1f29cd61fafa47d1/markupsafe-3.0.4-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:9e227f3dbe6bde7491cf0a9965d00b88c6b1a4a95d11480ddf88bb96d397c19f", size = 22036, upload-time = "2026-10-02T23:05:20.352Z" }, + { url = "https://files.pythonhosted.org/packages/a1/4f/ed476226d4fe46a09090a36025bf319296810028df55eb12f1253b540f3a/markupsafe-3.0.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:b8cd1f918b26fd7b1832ece557cc18f2d8747309ff8b3f0ef9d4250c5ad67a39", size = 23786, upload-time = "2026-10-02T23:05:21.576Z" }, + { url = "https://files.pythonhosted.org/packages/9a/35/66ff30450e35ef5fba9ebc930c9411747e537fd9447b65e44f5007e2b84d/markupsafe-3.0.4-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:a5fcffb37e602b0b3c1638a97746b9b96125caa9bcf6fa41d337a9261de231ee", size = 22672, upload-time = "2026-10-02T23:05:22.922Z" }, + { url = "https://files.pythonhosted.org/packages/32/0b/72f45ce4b4efcbca4b80cf1b06703eff0be8d37e82abb78f66c85a7ead1e/markupsafe-3.0.4-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:5989cb26b2e1efc6a42216a9f6b5ee495ce5ace2e5b352a9af489976b32d1ee2", size = 24107, upload-time = "2026-10-02T23:05:24.175Z" }, + { url = "https://files.pythonhosted.org/packages/d2/03/71776e5fdcba04614b384cc102e8a4198208579d896fd1394cb7cb9aa900/markupsafe-3.0.4-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:add96447a86d205ab616665d53b2950ee81083757f56e6ea833c8b2917646b46", size = 21615, upload-time = "2026-10-02T23:05:25.215Z" }, + { url = "https://files.pythonhosted.org/packages/ab/5f/801ce02a02e7aee0f784b1ec7843026178f6adeb9c93ac67eb1992a9a84d/markupsafe-3.0.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:2628d3a8cb648ecebb3c5d6b0a1052d400e4d8b7ac0fb786be8d285b50040d17", size = 23076, upload-time = "2026-10-02T23:05:26.423Z" }, + { url = "https://files.pythonhosted.org/packages/4a/85/c43776625428f3bb4a61e8633940400e3efe6409e3c6f5bff26de5e45618/markupsafe-3.0.4-cp313-cp313-win32.whl", hash = "sha256:672d207103e6b16ca098611b0f9efad6bc00afd47c03d6ef62186495ca677dc0", size = 14118, upload-time = "2026-10-02T23:05:27.716Z" }, + { url = "https://files.pythonhosted.org/packages/6f/36/163da64de88a13db79214ef75fa041be7fa13bdb42261cf5b7484de14bfb/markupsafe-3.0.4-cp313-cp313-win_amd64.whl", hash = "sha256:1f1f9477e174582b0a1b583d60b66e1f2cf5d3fe12cee985e4aedf44766600e5", size = 14313, upload-time = "2026-10-02T23:05:28.749Z" }, + { url = "https://files.pythonhosted.org/packages/9f/a8/9b662783ffaa1149221432a923cee562f78b9cbbb8baa3df9b3753e63e1e/markupsafe-3.0.4-cp313-cp313-win_arm64.whl", hash = "sha256:06de8ef6331f6e822c28d577dc8bf43fe398800477c49498f38fc38b67ff33fc", size = 14189, upload-time = "2026-10-02T23:05:29.917Z" }, +] + +[[package]] +name = "mcp" +version = "2.3.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anyio" }, + { name = "httpx2" }, + { name = "jsonschema" }, + { name = "mcp-types" }, + { name = "opentelemetry-api" }, + { name = "pydantic" }, + { name = "pyjwt", extra = ["crypto"] }, + { name = "python-multipart" }, + { name = "pywin32", marker = "sys_platform == 'win32'" }, + { name = "sse-starlette" }, + { name = "starlette" }, + { name = "typing-extensions" }, + { name = "typing-inspection" }, + { name = "uvicorn", marker = "sys_platform != 'emscripten'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/9d/8d/e0d339616f4810e9051d4aba6887afab289ab1f81875fe908b606cdfd0e3/mcp-2.3.0.tar.gz", hash = "sha256:8b147a50441cf059dc88c684e0aeed3687f0aa0f39c6cde7b90330effd2b34d8", size = 4171955, upload-time = "2026-10-02T22:06:56.091Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/20/d7/4a2878f128df729db3ca04e71bfce26405cc2e0c9ebe19c592feeb4c61b9/mcp-2.3.0-py3-none-any.whl", hash = "sha256:dd0c44c089d16453e8ae31a3877a0054d7a2314caaa81f5e0541b9b1734b2377", size = 368664, upload-time = "2026-10-02T22:06:52.119Z" }, +] + +[[package]] +name = "mcp-types" +version = "2.3.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pydantic" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/9e/2d/7c251e34207f6c51000312fc8839111ac45cfe02023f90b44e7f1051dd8e/mcp_types-2.3.0.tar.gz", hash = "sha256:d1e46549edb35ee19a94940fcee6d1addd7e589ab7ea92dda83f5d84781fc362", size = 65898, upload-time = "2026-10-02T22:06:57.863Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ce/48/32583066b155bb5d4507e7887dc88ee23118cc4de8e2a12870c49719e2a8/mcp_types-2.3.0-py3-none-any.whl", hash = "sha256:968efdbdaedfab06adae40d378a34395f1090c5921d4be3c9cde283aaf76d91d", size = 69108, upload-time = "2026-10-02T22:06:54.099Z" }, +] + +[[package]] +name = "mdurl" +version = "0.1.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d6/54/cfe61301667036ec958cb99bd3efefba235e65cdeb9c84d24a8293ba1d90/mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba", size = 8729, upload-time = "2022-08-14T12:40:10.846Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979, upload-time = "2022-08-14T12:40:09.779Z" }, +] + +[[package]] +name = "minio" +version = "7.2.20" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "argon2-cffi" }, + { name = "certifi" }, + { name = "pycryptodome" }, + { name = "typing-extensions" }, + { name = "urllib3" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/40/df/6dfc6540f96a74125a11653cce717603fd5b7d0001a8e847b3e54e72d238/minio-7.2.20.tar.gz", hash = "sha256:95898b7a023fbbfde375985aa77e2cd6a0762268db79cf886f002a9ea8e68598", size = 136113, upload-time = "2025-11-27T00:37:15.569Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3e/9a/b697530a882588a84db616580f2ba5d1d515c815e11c30d219145afeec87/minio-7.2.20-py3-none-any.whl", hash = "sha256:eb33dd2fb80e04c3726a76b13241c6be3c4c46f8d81e1d58e757786f6501897e", size = 93751, upload-time = "2025-11-27T00:37:13.993Z" }, +] + +[[package]] +name = "mistralai" +version = "3.2.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "eval-type-backport" }, + { name = "httpx2" }, + { name = "jsonpath-python" }, + { name = "opentelemetry-api" }, + { name = "opentelemetry-semantic-conventions" }, + { name = "pydantic" }, + { name = "python-dateutil" }, + { name = "typing-inspection" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/5a/dc/7756ce9cf855ec0db089770a176ed652cded4c5ecd61931fb0b9331e655f/mistralai-3.2.0.tar.gz", hash = "sha256:b3f2139bde538fe8ed4a19e2adb624fd46dfd175b609231c0836bba21d738730", size = 643870, upload-time = "2026-10-09T09:41:12.157Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ff/d7/c499fb9a610f4abe2f8e7ad7e18f7f0254ddec49c7971116fe1e110da37b/mistralai-3.2.0-py3-none-any.whl", hash = "sha256:66c1cd32e886b2bc55f67d61cdba6d8c2c38e68720a6b6d69bb3fe7b10034779", size = 1532235, upload-time = "2026-10-09T09:41:10.005Z" }, +] + +[[package]] +name = "more-itertools" +version = "11.2.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/55/e5/8735dc589d9e3571e76cd684e7763dc0fcc940b811f71640410458749689/more_itertools-11.2.0.tar.gz", hash = "sha256:59960f488835254863a857eb501f69e4ec92fdc8822f098c0f48dba530afd487", size = 75940, upload-time = "2026-10-13T16:01:14.428Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d4/f7/86f27473377a8ebdbdfedec5e62e87fbc24c4c88ed0a2a5ea0a12ee2229b/more_itertools-11.2.0-py3-none-any.whl", hash = "sha256:e4c522352a24664c974d0be8382944107ae638281a06391a5a538366b5707fe5", size = 74407, upload-time = "2026-10-13T16:01:13.424Z" }, +] + +[[package]] +name = "mpmath" +version = "1.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e0/47/dd32fa426cc72114383ac549964eecb20ecfd886d1e5ccf5340b55b02f57/mpmath-1.3.0.tar.gz", hash = "sha256:7a28eb2a9774d00c7bc92411c19a89209d5da7c4c9a9e227be8330a23a25b91f", size = 508106, upload-time = "2023-03-07T16:47:11.061Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/43/e3/7d92a15f894aa0c9c4b49b8ee9ac9850d6e63b03c9c32c0367a13ae62209/mpmath-1.3.0-py3-none-any.whl", hash = "sha256:a0b2b9fe80bbcd81a6647ff13108738cfb482d481d826cc0e02f5b35e5c88d2c", size = 536198, upload-time = "2023-03-07T16:47:09.197Z" }, +] + +[[package]] +name = "multidict" +version = "6.9.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d6/99/1d4d69c3512d0ddbfa3a1b69cfd9a151012ab2eb4eabbb096201b1f0b7d8/multidict-6.9.1.tar.gz", hash = "sha256:0f06e60fa190aa7abd0914c2a766736fdc8e9f34878c4346338534b73d1b20e2", size = 182404, upload-time = "2026-09-21T17:59:05.362Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/eb/45/ddf7c76860f5f553a23ad3ca38463ccf5247081618977742c8dc4625355e/multidict-6.9.1-cp313-cp313-android_24_x86_64.whl", hash = "sha256:d7bf9e43282d69561618e8a0ea33368d532ebef42f15c096f427090521dd74f3", size = 63266, upload-time = "2026-09-21T17:55:42.676Z" }, + { url = "https://files.pythonhosted.org/packages/6d/d3/f4ae5945ea2de597eaeb4eca3a74c59783ace54482c9b49435442b63efa8/multidict-6.9.1-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:03d47df72f084f757c1cb771188d5f4e3a805e4abc4d67e32509272343ae9382", size = 55771, upload-time = "2026-09-21T17:55:44.016Z" }, + { url = "https://files.pythonhosted.org/packages/93/7d/15468239920040d01c686e5ae669e6382f7bf31fc3e5e0a6b8f1c3b32d3b/multidict-6.9.1-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:6bc94fe17c3c56e5418f79515b786b101845f70609b0d19d0c1ba13448e5633a", size = 57116, upload-time = "2026-09-21T17:55:45.315Z" }, + { url = "https://files.pythonhosted.org/packages/17/1b/b958f06aac2d8b1e485eb1c105b1b159cbf3868249e5142142451577dad2/multidict-6.9.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:8f2973bbd2bebd9d2e0cd6394c1292a1a19ccd56bdcbe1e174059f1a39be5b40", size = 97692, upload-time = "2026-09-21T17:55:46.674Z" }, + { url = "https://files.pythonhosted.org/packages/93/6c/d6cfe18e61010166d7237d7527c775eb9843e7078feadea45b7628751b60/multidict-6.9.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:de7738b8c0bb74c4cc16bbd7fb49fc2bcf6430dba11b3432cd52768ae40933e8", size = 59556, upload-time = "2026-09-21T17:55:48.22Z" }, + { url = "https://files.pythonhosted.org/packages/46/46/9b4c1127cece0289fb207d04aae5116382ddfcb2a4dc8e0cb49a33f3c7b3/multidict-6.9.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:e5ccad4b7bac125722f48d6f862bed3b514d8526deea06316bb72f152cd30a7c", size = 57357, upload-time = "2026-09-21T17:55:49.998Z" }, + { url = "https://files.pythonhosted.org/packages/bc/fc/c18b07100a6064573e49e538d13d47eb2b5221f48080512df78aef54ab04/multidict-6.9.1-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:a49ff5cdb33654cb7d6a3c377aa2a83ddefaa1db31eb10bcf3c180aa84f9af8a", size = 330433, upload-time = "2026-09-21T17:55:51.435Z" }, + { url = "https://files.pythonhosted.org/packages/62/ff/52a0082adeb69656b634609d4fb0ae65456deaae4cca3d5a12656626dc50/multidict-6.9.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b22ff30006a2f28f8bff878fb93413cbe3a4d1fd517c28081d848c90e9cfd2c8", size = 332487, upload-time = "2026-09-21T17:55:52.937Z" }, + { url = "https://files.pythonhosted.org/packages/39/3e/80bd4729635a7af371ff4dcc312594cf96e73f98854491be8740792de430/multidict-6.9.1-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3adf06c66041aa21eeb8a71e82379b74773298c8e6d3d839b151aae441a99b94", size = 316911, upload-time = "2026-09-21T17:55:54.751Z" }, + { url = "https://files.pythonhosted.org/packages/15/f4/7ea4a907e053e924e2e1694d90560f79f72056504bfd5e8483695f9527d2/multidict-6.9.1-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:963a8d8f97057082679523d0fd4c53a38f86bc58cabe4556faef682ae53fa2fa", size = 344950, upload-time = "2026-09-21T17:55:56.5Z" }, + { url = "https://files.pythonhosted.org/packages/0d/16/9642ae41fbfbdc546aa481c2b07ae1bc087a94ab5f5020b4d9ab77da401f/multidict-6.9.1-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b66ccc5c2cdd26e74fa5d4c29ffae424cc6148bf93ce574821783fb3b6d452c5", size = 350264, upload-time = "2026-09-21T17:55:58.073Z" }, + { url = "https://files.pythonhosted.org/packages/93/f2/e06c8e42074d0a4b8419bfe92afbd1d262190b69549ecbcd2dffa4f103c2/multidict-6.9.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7fd79c521f6290c69125fa2b85fa65d9e657e6a8ffaf722dc881b926bef4aa5c", size = 336213, upload-time = "2026-09-21T17:55:59.723Z" }, + { url = "https://files.pythonhosted.org/packages/98/43/d7cf9ef4700e7c25244590d1b4f20cf12cbed86beba6c17be4d9e48c1099/multidict-6.9.1-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:1d804e4caf5d5da37d6dac1325da5629ebef1e27a294c2b568b295814aa36c7b", size = 302555, upload-time = "2026-09-21T17:56:01.666Z" }, + { url = "https://files.pythonhosted.org/packages/7d/3a/54209920324bc3928f5f2ba28b01a6dd957a9d48c3aaff77e38faaf5668d/multidict-6.9.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:bb0d664505f4b112f384cffeee82e91e3f6448d8e574989479db4439b68cba05", size = 322247, upload-time = "2026-09-21T17:56:03.265Z" }, + { url = "https://files.pythonhosted.org/packages/33/50/df96f961b178b621ab0adbf9221d4fd21534e1064fd9f5e85c1fa27fea55/multidict-6.9.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:9e14d17773b1b3c758ff153659a1824608a0cb562c45f484b5ed8a433428444a", size = 321787, upload-time = "2026-09-21T17:56:04.894Z" }, + { url = "https://files.pythonhosted.org/packages/a7/9b/37f354562a8f82f9c1f63d3a94300fc82126d50320175f0702bbd544f87c/multidict-6.9.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:083735b7f395894e43adb278d5dae901448883a835ff8f1977e285fefdb10418", size = 335498, upload-time = "2026-09-21T17:56:06.783Z" }, + { url = "https://files.pythonhosted.org/packages/1e/44/78e366efc6c004185295cc9eb9711c10f13eadf3b547603b9c5526329976/multidict-6.9.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:b65121091567847a8cb520d364ab22ba90e00d3cc55fa9eb34bb439f0684bcd1", size = 338244, upload-time = "2026-09-21T17:56:09.162Z" }, + { url = "https://files.pythonhosted.org/packages/ad/2b/ab5bd3964691abe4d14b43bdbdb8a621b77cea2ca352dc93159ec0a4575b/multidict-6.9.1-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:ea999ae6e80e66ad5eea287860951b033d0104ca34d6d87c7b5125ebe0e12721", size = 301641, upload-time = "2026-09-21T17:56:11.227Z" }, + { url = "https://files.pythonhosted.org/packages/ea/a8/f6bc899f5aafaba755edc8e4bb934bc00b1e405f8d3fbc1dd10283738074/multidict-6.9.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:095d900c242e00fbe5f321ee072e7278b4153e78c5ce9c1efde167d62c1e4771", size = 340162, upload-time = "2026-09-21T17:56:13.076Z" }, + { url = "https://files.pythonhosted.org/packages/eb/03/a8fc809ef364b8c231c065ea2ea2f97ae86d4f9a0e36b5721759fd606778/multidict-6.9.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6441cc837aea58be7d9baef1b2383eb8311ab9303f500f99ac90b584cd78bb14", size = 332826, upload-time = "2026-09-21T17:56:15.175Z" }, + { url = "https://files.pythonhosted.org/packages/f2/27/32dde80245e2024e9bb7a6ca3c2fb7c695dc74014cba557cc35be6f91e24/multidict-6.9.1-cp313-cp313-win32.whl", hash = "sha256:9c4880d017555d70dea367dd49271830842d48e3891c2da97da7ce8c4abcee40", size = 52378, upload-time = "2026-09-21T17:56:16.959Z" }, + { url = "https://files.pythonhosted.org/packages/be/78/1bac2987edac273a6b27fa50e9204bc3466c94a7b4f6a44828d730f8810f/multidict-6.9.1-cp313-cp313-win_amd64.whl", hash = "sha256:ac51cd64bae51c462ea58ad2492c9b8209667a4ef60c45c4a304518b67598d5d", size = 59449, upload-time = "2026-09-21T17:56:18.336Z" }, + { url = "https://files.pythonhosted.org/packages/e1/32/2a77ce19eea48cb9b3521a202b513ba3349aafa702c8317be0b645ffb74b/multidict-6.9.1-cp313-cp313-win_arm64.whl", hash = "sha256:37a9ebe00c698279213d56e6c64e1962ab1e092918270649b397cac3dc196ca4", size = 54713, upload-time = "2026-09-21T17:56:19.774Z" }, + { url = "https://files.pythonhosted.org/packages/be/59/e26cb779be4c591d1a910f59d29aca9fba4de70349840a833beba2652371/multidict-6.9.1-py3-none-any.whl", hash = "sha256:7bf6478188f4e47bf5686e8a33da4ae28bf43b1b2528d9ee144d28492bfac60b", size = 19176, upload-time = "2026-09-21T17:59:03.501Z" }, +] + +[[package]] +name = "murmurhash" +version = "1.0.15" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/23/2e/88c147931ea9725d634840d538622e94122bceaf346233349b7b5c62964b/murmurhash-1.0.15.tar.gz", hash = "sha256:58e2b27b7847f9e2a6edf10b47a8c8dd70a4705f45dccb7bf76aeadacf56ba01", size = 13291, upload-time = "2025-11-14T09:51:15.272Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/29/2f/ba300b5f04dae0409202d6285668b8a9d3ade43a846abee3ef611cb388d5/murmurhash-1.0.15-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:fe50dc70e52786759358fd1471e309b94dddfffb9320d9dfea233c7684c894ba", size = 27861, upload-time = "2025-11-14T09:50:23.804Z" }, + { url = "https://files.pythonhosted.org/packages/34/02/29c19d268e6f4ea1ed2a462c901eed1ed35b454e2cbc57da592fad663ac6/murmurhash-1.0.15-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1349a7c23f6092e7998ddc5bd28546cc31a595afc61e9fdb3afc423feec3d7ad", size = 27840, upload-time = "2025-11-14T09:50:25.146Z" }, + { url = "https://files.pythonhosted.org/packages/e2/63/58e2de2b5232cd294c64092688c422196e74f9fa8b3958bdf02d33df24b9/murmurhash-1.0.15-cp313-cp313-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:b3ba6d05de2613535b5a9227d4ad8ef40a540465f64660d4a8800634ae10e04f", size = 133080, upload-time = "2025-11-14T09:50:26.566Z" }, + { url = "https://files.pythonhosted.org/packages/aa/9a/d13e2e9f8ba1ced06840921a50f7cece0a475453284158a3018b72679761/murmurhash-1.0.15-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:fa1b70b3cc2801ab44179c65827bbd12009c68b34e9d9ce7125b6a0bd35af63c", size = 132648, upload-time = "2025-11-14T09:50:27.788Z" }, + { url = "https://files.pythonhosted.org/packages/b2/e1/47994f1813fa205c84977b0ff51ae6709f8539af052c7491a5f863d82bdc/murmurhash-1.0.15-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:213d710fb6f4ef3bc11abbfad0fa94a75ffb675b7dc158c123471e5de869f9af", size = 131502, upload-time = "2025-11-14T09:50:29.339Z" }, + { url = "https://files.pythonhosted.org/packages/b9/ea/90c1fd00b4aeb704fb5e84cd666b33ffd7f245155048071ffbb51d2bb57d/murmurhash-1.0.15-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:b65a5c4e7f5d71f7ccac2d2b60bdf7092d7976270878cfec59d5a66a533db823", size = 132736, upload-time = "2025-11-14T09:50:30.545Z" }, + { url = "https://files.pythonhosted.org/packages/00/db/da73462dbfa77f6433b128d2120ba7ba300f8c06dc4f4e022c38d240a5f5/murmurhash-1.0.15-cp313-cp313-win_amd64.whl", hash = "sha256:9aba94c5d841e1904cd110e94ceb7f49cfb60a874bbfb27e0373622998fb7c7c", size = 25682, upload-time = "2025-11-14T09:50:31.624Z" }, + { url = "https://files.pythonhosted.org/packages/bb/83/032729ef14971b938fbef41ee125fc8800020ee229bd35178b6ede8ee934/murmurhash-1.0.15-cp313-cp313-win_arm64.whl", hash = "sha256:263807eca40d08c7b702413e45cca75ecb5883aa337237dc5addb660f1483378", size = 23370, upload-time = "2025-11-14T09:50:33.264Z" }, + { url = "https://files.pythonhosted.org/packages/10/83/7547d9205e9bd2f8e5dfd0b682cc9277594f98909f228eb359489baec1df/murmurhash-1.0.15-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:694fd42a74b7ce257169d14c24aa616aa6cd4ccf8abe50eca0557e08da99d055", size = 29955, upload-time = "2025-11-14T09:50:34.488Z" }, + { url = "https://files.pythonhosted.org/packages/b7/c7/3afd5de7a5b3ae07fe2d3a3271b327ee1489c58ba2b2f2159bd31a25edb9/murmurhash-1.0.15-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a2ea4546ba426390beff3cd10db8f0152fdc9072c4f2583ec7d8aa9f3e4ac070", size = 30108, upload-time = "2025-11-14T09:50:35.53Z" }, + { url = "https://files.pythonhosted.org/packages/02/69/d6637ee67d78ebb2538c00411f28ea5c154886bbe1db16c49435a8a4ab16/murmurhash-1.0.15-cp313-cp313t-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:34e5a91139c40b10f98d0b297907f5d5267b4b1b2e5dd2eb74a021824f751b98", size = 164054, upload-time = "2025-11-14T09:50:36.591Z" }, + { url = "https://files.pythonhosted.org/packages/ab/4c/89e590165b4c7da6bf941441212a721a270195332d3aacfdfdf527d466ca/murmurhash-1.0.15-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:dc35606868a5961cf42e79314ca0bddf5a400ce377b14d83192057928d6252ec", size = 168153, upload-time = "2025-11-14T09:50:37.856Z" }, + { url = "https://files.pythonhosted.org/packages/07/7a/95c42df0c21d2e413b9fcd17317a7587351daeb264dc29c6aec1fdbd26f8/murmurhash-1.0.15-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:43cc6ac3b91ca0f7a5ae9c063ba4d6c26972c97fd7c25280ecc666413e4c5535", size = 164345, upload-time = "2025-11-14T09:50:39.346Z" }, + { url = "https://files.pythonhosted.org/packages/d0/22/9d02c880a88b83bb3ce7d6a38fb727373ab78d82e5f3d8d9fc5612219f90/murmurhash-1.0.15-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:847d712136cb462f0e4bd6229ee2d9eb996d8854eb8312dff3d20c8f5181fda5", size = 161990, upload-time = "2025-11-14T09:50:40.689Z" }, + { url = "https://files.pythonhosted.org/packages/9a/e3/750232524e0dc262e8dcede6536dafc766faadd9a52f1d23746b02948ad8/murmurhash-1.0.15-cp313-cp313t-win_amd64.whl", hash = "sha256:2680851af6901dbe66cc4aa7ef8e263de47e6e1b425ae324caa571bdf18f8d58", size = 28812, upload-time = "2025-11-14T09:50:41.971Z" }, + { url = "https://files.pythonhosted.org/packages/ff/89/4ad9d215ef6ade89f27a72dc4e86b98ef1a43534cc3e6a6900a362a0bf0a/murmurhash-1.0.15-cp313-cp313t-win_arm64.whl", hash = "sha256:189a8de4d657b5da9efd66601b0636330b08262b3a55431f2379097c986995d0", size = 25398, upload-time = "2025-11-14T09:50:43.023Z" }, +] + +[[package]] +name = "narwhals" +version = "2.27.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/bf/21/f64d6b2dbea7bf3f8c38cdc786dcc6ef012ca3d173ad208c782c9a7bedf6/narwhals-2.27.1.tar.gz", hash = "sha256:aed93076a3ea42d9c32c88e4eb5ea422a21937011cbe1f480f9572a523c82094", size = 735013, upload-time = "2026-10-10T06:52:18.113Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/89/5d4c86da1130d9059681e5b6cd7645df5c10279a6a079c5c37dcb2cc6f3f/narwhals-2.27.1-py3-none-any.whl", hash = "sha256:d057df13f5852b8e157596e82eb5e955fad267425df5e420e0ee9863da483b31", size = 483211, upload-time = "2026-10-10T06:52:16.32Z" }, +] + +[[package]] +name = "networkx" +version = "3.7" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/dc/76/3af777226b63a5e64a6b36b1ec5855c14e2b94a37096d4760e595fc43511/networkx-3.7.tar.gz", hash = "sha256:fd77a511bd90f39f3d016351345b52cf5319b813bdca01de3f755d3cca62e96a", size = 1866482, upload-time = "2026-09-21T16:45:16.974Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7e/cd/fe58041e9011f307c490e3e17dd48cc516448f7c698a3f2d9d9d65d7e6a8/networkx-3.7-py3-none-any.whl", hash = "sha256:e3fd2c13a7814cee3746340d8d7f8598a67f16a58bf47fb7f8793fab6efca1b0", size = 2142205, upload-time = "2026-09-21T16:45:14.609Z" }, +] + +[[package]] +name = "nexus-rpc" +version = "1.4.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/35/d5/cd1ffb202b76ebc1b33c1332a3416e55a39929006982adc2b1eb069aaa9b/nexus_rpc-1.4.0.tar.gz", hash = "sha256:3b8b373d4865671789cc43623e3dc0bcbf192562e40e13727e17f1c149050fba", size = 82367, upload-time = "2026-02-25T22:01:34.053Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/11/52/6327a5f4fda01207205038a106a99848a41c83e933cd23ea2cab3d2ebc6c/nexus_rpc-1.4.0-py3-none-any.whl", hash = "sha256:14c953d3519113f8ccec533a9efdb6b10c28afef75d11cdd6d422640c40b3a49", size = 29645, upload-time = "2026-02-25T22:01:33.122Z" }, +] + +[[package]] +name = "nodeenv" +version = "1.11.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/9a/8e/105de02c1322cfada6d9710d9146ef8026419d433c9d08359a2d35805811/nodeenv-1.11.0.tar.gz", hash = "sha256:3ce8fe5b71d16e8af7039ca65257354100bc772965d6bc549070649e53b1b146", size = 99301, upload-time = "2026-09-26T11:29:21.367Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/54/c8/12811c9b48fde162bb72b6f2e78fada9a247a09d7bb5be2050a5d099c77b/nodeenv-1.11.0-py2.py3-none-any.whl", hash = "sha256:edaa16e6c14d7cf395d75d4bbd5a26390f4dc06501a33b4e76282b02cc688a25", size = 34277, upload-time = "2026-09-26T11:29:19.933Z" }, +] + +[[package]] +name = "numpy" +version = "2.5.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/95/b0/c7453d0b6e2073c3264468b106ee1563750cecc910965e67357e3698c83e/numpy-2.5.4.tar.gz", hash = "sha256:9a94cf751c9ad8ebaa835bcd3d40dacf8534ad086b88c38029b65123c7999d2a", size = 20866315, upload-time = "2026-10-10T20:05:31.422Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/67/14/1c3ee0118a8fce08565a5d8482631608426a33af10a01077fada5dc7c119/numpy-2.5.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:2377da2dd3ba2c1200956acbab2a358c83b8e1f8531191672d1cd6ad83250d53", size = 16997729, upload-time = "2026-10-10T20:03:09.291Z" }, + { url = "https://files.pythonhosted.org/packages/83/8c/b0ea9477fb1f0d4484bbc5cba21678cc9969704d8d7f3f158d1db35f8e14/numpy-2.5.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:7415db95818b39ec475a5eea54d9e3b6bc83e3912158e46da3438cdce399804d", size = 12009826, upload-time = "2026-10-10T20:03:11.946Z" }, + { url = "https://files.pythonhosted.org/packages/e2/84/6a3d75b3ba3dfe84ac0053450753d1e6d250a8bf80f66474cc46d1fb643f/numpy-2.5.4-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:6d6a71b9d9a97c03633aa12565ef2825ffa036cc1d99cfd50dacf0f128af4fe2", size = 5445803, upload-time = "2026-10-10T20:03:14.329Z" }, + { url = "https://files.pythonhosted.org/packages/61/18/bb993f267ca20b376e07092a16793a5b31ed3138751e9ba480011a14d742/numpy-2.5.4-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:d8200f16437b289a5bb927c6e184eccc3e8389bc0070fea4cd5b9e13c1757959", size = 6786220, upload-time = "2026-10-10T20:03:16.602Z" }, + { url = "https://files.pythonhosted.org/packages/db/b6/135bb0953b61dc21c6cafa14b424ae666944e4899cf140e00c2b322a1a45/numpy-2.5.4-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1c2e71b04c6cad90026e544501bbe0ab9290fa8a4d845e7e8c0d124fb429c988", size = 15689178, upload-time = "2026-10-10T20:03:18.721Z" }, + { url = "https://files.pythonhosted.org/packages/da/24/3bd070f3269dc609d8f26b2643f62ef91bb415841c0b294805aaf7fe06da/numpy-2.5.4-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6ffa07666f8da0eef81d149934a626d0d95fbd6838432a33e66245423a9062c0", size = 16718044, upload-time = "2026-10-10T20:03:21.386Z" }, + { url = "https://files.pythonhosted.org/packages/c7/8e/9d15bd356b0a019c965312b1a3c6a727cac4cae5bc40045fbc12ce4cff9c/numpy-2.5.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:2fa3328f784fc8277fc48026f6cad516f5c561c5d8e2e39b3c9e0c8f23223b34", size = 17048364, upload-time = "2026-10-10T20:03:24.468Z" }, + { url = "https://files.pythonhosted.org/packages/dc/fe/9d5b560db964f15871885f2250795d15945f8699e17ef90c0c2ff4c875b2/numpy-2.5.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:b86966fbe4ad7de710422175572bcdc75fdedadfb54bc6fab7deabccddd7780b", size = 18474904, upload-time = "2026-10-10T20:03:27.895Z" }, + { url = "https://files.pythonhosted.org/packages/e9/98/d27552990f1bd611ef3e7466adadc78312ea2df63b83aad47fdc3d3ca8df/numpy-2.5.4-cp313-cp313-win32.whl", hash = "sha256:5258bc06526964be5face2fc6f756857a3f24f21ec3e72ca131337a75b165d6c", size = 6134537, upload-time = "2026-10-10T20:03:30.511Z" }, + { url = "https://files.pythonhosted.org/packages/90/8c/140a40398a66b4471211be1affdb6ed24c486d581bd28d07b7f2fcb69540/numpy-2.5.4-cp313-cp313-win_amd64.whl", hash = "sha256:8b4d2fd2d34e5f8c9235ee787de5631a37a28402b15cb80814df973d2be54129", size = 12566113, upload-time = "2026-10-10T20:03:32.612Z" }, + { url = "https://files.pythonhosted.org/packages/34/52/01d205e5e8ccb27b2b0b141e801f22b830198c979111b0fa44771438d9a9/numpy-2.5.4-cp313-cp313-win_arm64.whl", hash = "sha256:bc39ac66a7a9a3fbd6134fda43136b60ffde99c8f4501e64e0d2b24da137babf", size = 10519523, upload-time = "2026-10-10T20:03:35.163Z" }, +] + +[[package]] +name = "nvidia-cublas" +version = "13.1.1.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "nvidia-cuda-nvrtc" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/a7/a1/0bd24ee8c8d03adac032fd2909426a00c88f8c57961b1277ded97f91119f/nvidia_cublas-13.1.1.3-py3-none-manylinux_2_27_aarch64.whl", hash = "sha256:b7a210458267ac818974c53038fbec2e969d5c99f305ab15c72522fa9f001dd5", size = 542848918, upload-time = "2026-04-08T18:46:22.985Z" }, + { url = "https://files.pythonhosted.org/packages/3b/cd/154ca20c38269e05eff77c1464e6c1da89f50a6390b565e9d82e06bc11e1/nvidia_cublas-13.1.1.3-py3-none-manylinux_2_27_x86_64.whl", hash = "sha256:37936a16db8fe4ac1f065c2139360608a543a09275cb1a1af612e08cfa065436", size = 423138758, upload-time = "2026-04-08T18:46:58.655Z" }, +] + +[[package]] +name = "nvidia-cuda-cupti" +version = "13.0.85" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2a/2a/80353b103fc20ce05ef51e928daed4b6015db4aaa9162ed0997090fe2250/nvidia_cuda_cupti-13.0.85-py3-none-manylinux_2_25_aarch64.whl", hash = "sha256:796bd679890ee55fb14a94629b698b6db54bcfd833d391d5e94017dd9d7d3151", size = 10310827, upload-time = "2025-09-04T08:26:42.012Z" }, + { url = "https://files.pythonhosted.org/packages/33/6d/737d164b4837a9bbd202f5ae3078975f0525a55730fe871d8ed4e3b952b0/nvidia_cuda_cupti-13.0.85-py3-none-manylinux_2_25_x86_64.whl", hash = "sha256:4eb01c08e859bf924d222250d2e8f8b8ff6d3db4721288cf35d14252a4d933c8", size = 10715597, upload-time = "2025-09-04T08:26:51.312Z" }, +] + +[[package]] +name = "nvidia-cuda-nvrtc" +version = "13.0.88" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c3/68/483a78f5e8f31b08fb1bb671559968c0ca3a065ac7acabfc7cee55214fd6/nvidia_cuda_nvrtc-13.0.88-py3-none-manylinux2010_x86_64.manylinux_2_12_x86_64.whl", hash = "sha256:ad9b6d2ead2435f11cbb6868809d2adeeee302e9bb94bcf0539c7a40d80e8575", size = 90215200, upload-time = "2025-09-04T08:28:44.204Z" }, + { url = "https://files.pythonhosted.org/packages/b7/dc/6bb80850e0b7edd6588d560758f17e0550893a1feaf436807d64d2da040f/nvidia_cuda_nvrtc-13.0.88-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d27f20a0ca67a4bb34268a5e951033496c5b74870b868bacd046b1b8e0c3267b", size = 43015449, upload-time = "2025-09-04T08:28:20.239Z" }, +] + +[[package]] +name = "nvidia-cuda-runtime" +version = "13.0.96" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/87/4f/17d7b9b8e285199c58ce28e31b5c5bbaa4d8271af06a89b6405258245de2/nvidia_cuda_runtime-13.0.96-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ef9bcbe90493a2b9d810e43d249adb3d02e98dd30200d86607d8d02687c43f55", size = 2261060, upload-time = "2025-10-09T08:55:15.78Z" }, + { url = "https://files.pythonhosted.org/packages/2e/24/d1558f3b68b1d26e706813b1d10aa1d785e4698c425af8db8edc3dced472/nvidia_cuda_runtime-13.0.96-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:7f82250d7782aa23b6cfe765ecc7db554bd3c2870c43f3d1821f1d18aebf0548", size = 2243632, upload-time = "2025-10-09T08:55:36.117Z" }, +] + +[[package]] +name = "nvidia-cudnn-cu13" +version = "9.24.0.43" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "nvidia-cublas" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/ca/30/7c257e3d5cb4fecb147b93895c66e29c93f8e76d74b45bb418ff0587c4ec/nvidia_cudnn_cu13-9.24.0.43-py3-none-manylinux_2_27_aarch64.whl", hash = "sha256:a6812a554a1ff0413e9c52b84c26c050380649ab9615f9c16bded368ce9f421f", size = 650976863, upload-time = "2026-07-02T16:23:39.248Z" }, + { url = "https://files.pythonhosted.org/packages/5c/ba/791cffd048fe5b044e620df55267e3e95c0e6e07d50b41e377c03dfc910f/nvidia_cudnn_cu13-9.24.0.43-py3-none-manylinux_2_27_x86_64.whl", hash = "sha256:71f181cd810e90f9b6023b01186fe82d13d65f0ec098581ee201d39fad769e4b", size = 553099438, upload-time = "2026-07-02T16:27:42.58Z" }, +] + +[[package]] +name = "nvidia-cufft" +version = "12.0.0.61" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "nvidia-nvjitlink" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/8b/ae/f417a75c0259e85c1d2f83ca4e960289a5f814ed0cea74d18c353d3e989d/nvidia_cufft-12.0.0.61-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:2708c852ef8cd89d1d2068bdbece0aa188813a0c934db3779b9b1faa8442e5f5", size = 214053554, upload-time = "2025-09-04T08:31:38.196Z" }, + { url = "https://files.pythonhosted.org/packages/a8/2f/7b57e29836ea8714f81e9898409196f47d772d5ddedddf1592eadb8ab743/nvidia_cufft-12.0.0.61-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:6c44f692dce8fd5ffd3e3df134b6cdb9c2f72d99cf40b62c32dde45eea9ddad3", size = 214085489, upload-time = "2025-09-04T08:31:56.044Z" }, +] + +[[package]] +name = "nvidia-cufile" +version = "1.15.1.6" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3f/70/4f193de89a48b71714e74602ee14d04e4019ad36a5a9f20c425776e72cd6/nvidia_cufile-1.15.1.6-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:08a3ecefae5a01c7f5117351c64f17c7c62efa5fffdbe24fc7d298da19cd0b44", size = 1223672, upload-time = "2025-09-04T08:32:22.779Z" }, + { url = "https://files.pythonhosted.org/packages/ab/73/cc4a14c9813a8a0d509417cf5f4bdaba76e924d58beb9864f5a7baceefbf/nvidia_cufile-1.15.1.6-py3-none-manylinux_2_27_aarch64.whl", hash = "sha256:bdc0deedc61f548bddf7733bdc216456c2fdb101d020e1ab4b88d232d5e2f6d1", size = 1136992, upload-time = "2025-09-04T08:32:14.119Z" }, +] + +[[package]] +name = "nvidia-curand" +version = "10.4.0.35" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1e/72/7c2ae24fb6b63a32e6ae5d241cc65263ea18d08802aaae087d9f013335a2/nvidia_curand-10.4.0.35-py3-none-manylinux_2_27_aarch64.whl", hash = "sha256:133df5a7509c3e292aaa2b477afd0194f06ce4ea24d714d616ff36439cee349a", size = 61962106, upload-time = "2025-08-04T10:21:41.128Z" }, + { url = "https://files.pythonhosted.org/packages/a5/9f/be0a41ca4a4917abf5cb9ae0daff1a6060cc5de950aec0396de9f3b52bc5/nvidia_curand-10.4.0.35-py3-none-manylinux_2_27_x86_64.whl", hash = "sha256:1aee33a5da6e1db083fe2b90082def8915f30f3248d5896bcec36a579d941bfc", size = 59544258, upload-time = "2025-08-04T10:22:03.992Z" }, +] + +[[package]] +name = "nvidia-cusolver" +version = "12.0.4.66" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "nvidia-cublas" }, + { name = "nvidia-cusparse" }, + { name = "nvidia-nvjitlink" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/c8/c3/b30c9e935fc01e3da443ec0116ed1b2a009bb867f5324d3f2d7e533e776b/nvidia_cusolver-12.0.4.66-py3-none-manylinux_2_27_aarch64.whl", hash = "sha256:02c2457eaa9e39de20f880f4bd8820e6a1cfb9f9a34f820eb12a155aa5bc92d2", size = 223467760, upload-time = "2025-09-04T08:33:04.222Z" }, + { url = "https://files.pythonhosted.org/packages/5f/67/cba3777620cdacb99102da4042883709c41c709f4b6323c10781a9c3aa34/nvidia_cusolver-12.0.4.66-py3-none-manylinux_2_27_x86_64.whl", hash = "sha256:0a759da5dea5c0ea10fd307de75cdeb59e7ea4fcb8add0924859b944babf1112", size = 200941980, upload-time = "2025-09-04T08:33:22.767Z" }, +] + +[[package]] +name = "nvidia-cusparse" +version = "12.6.3.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "nvidia-nvjitlink" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/f8/94/5c26f33738ae35276672f12615a64bd008ed5be6d1ebcb23579285d960a9/nvidia_cusparse-12.6.3.3-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:80bcc4662f23f1054ee334a15c72b8940402975e0eab63178fc7e670aa59472c", size = 162155568, upload-time = "2025-09-04T08:33:42.864Z" }, + { url = "https://files.pythonhosted.org/packages/fa/18/623c77619c31d62efd55302939756966f3ecc8d724a14dab2b75f1508850/nvidia_cusparse-12.6.3.3-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:2b3c89c88d01ee0e477cb7f82ef60a11a4bcd57b6b87c33f789350b59759360b", size = 145942937, upload-time = "2025-09-04T08:33:58.029Z" }, +] + +[[package]] +name = "nvidia-cusparselt-cu13" +version = "0.8.1" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/46/e1/cdc1797eadf82d3a9a575a19b33fdc871a97edbec42c00b5b5e914f4aff4/nvidia_cusparselt_cu13-0.8.1-py3-none-manylinux2014_aarch64.whl", hash = "sha256:4dca476c50bf4780d46cd0bfbd82e2bc10a08e4fef7950917ce8d7578d22a23f", size = 221051344, upload-time = "2025-09-05T18:49:51.289Z" }, + { url = "https://files.pythonhosted.org/packages/34/7d/2661f2fb3ac4302f3a246f5fc030213ac60c1fe0bce84f9783dbd831dbb7/nvidia_cusparselt_cu13-0.8.1-py3-none-manylinux2014_x86_64.whl", hash = "sha256:786ce87568c303fadb5afcc7102d454cd3040d75f6f8626f5db460d1871f4dd0", size = 170148586, upload-time = "2025-09-05T18:50:50.248Z" }, +] + +[[package]] +name = "nvidia-nccl-cu13" +version = "2.30.7" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/21/a73174c6157101bdf1ffc22b517f76ff0082613989dd9bc8f43e8034caac/nvidia_nccl_cu13-2.30.7-py3-none-manylinux_2_18_aarch64.whl", hash = "sha256:ca786ffa5a647c75d4d1f5cc72a6c4f537947e2ba8823d7c8aaf768e7a7b9f77", size = 215983881, upload-time = "2026-06-09T03:23:15.633Z" }, + { url = "https://files.pythonhosted.org/packages/3f/34/c500f90c7ae641b8e0f98965b36b8a7ac79cc8b296e8d251fe3eb592ee54/nvidia_nccl_cu13-2.30.7-py3-none-manylinux_2_18_x86_64.whl", hash = "sha256:cefa7fdb9710efd0f39c5f1be1d61ff6fc9a996c451265bd7fbdcf9455ed4b50", size = 215965170, upload-time = "2026-06-09T03:23:39.73Z" }, +] + +[[package]] +name = "nvidia-nvjitlink" +version = "13.4.92" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1d/6b/eef7a9e32872b8f41e145bf10cddc9af26e153c338852811fe9a9baddf9e/nvidia_nvjitlink-13.4.92-py3-none-manylinux2010_x86_64.manylinux_2_12_x86_64.whl", hash = "sha256:e0391f24ed94ec879b84e3da4d4ec320c879aff681f2c7a638462f7199284323", size = 42452378, upload-time = "2026-09-16T20:45:29.042Z" }, + { url = "https://files.pythonhosted.org/packages/1f/a8/1cbd4014898af8b419e69b0d7dbc63da2121ee92d92b47d59f4fe9075349/nvidia_nvjitlink-13.4.92-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:25f74fad0d654271c921ac4dca614bd6258bc21791242fc7b2289dad7ae9c099", size = 40420120, upload-time = "2026-09-16T20:45:19.163Z" }, +] + +[[package]] +name = "nvidia-nvshmem-cu13" +version = "3.4.5" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/dc/0f/05cc9c720236dcd2db9c1ab97fff629e96821be2e63103569da0c9b72f19/nvidia_nvshmem_cu13-3.4.5-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:6dc2a197f38e5d0376ad52cd1a2a3617d3cdc150fd5966f4aee9bcebb1d68fe9", size = 60215947, upload-time = "2025-09-06T00:32:20.022Z" }, + { url = "https://files.pythonhosted.org/packages/3c/35/a9bf80a609e74e3b000fef598933235c908fcefcef9026042b8e6dfde2a9/nvidia_nvshmem_cu13-3.4.5-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:290f0a2ee94c9f3687a02502f3b9299a9f9fe826e6d0287ee18482e78d495b80", size = 60412546, upload-time = "2025-09-06T00:32:41.564Z" }, +] + +[[package]] +name = "nvidia-nvtx" +version = "13.0.85" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c2/f3/d86c845465a2723ad7e1e5c36dcd75ddb82898b3f53be47ebd429fb2fa5d/nvidia_nvtx-13.0.85-py3-none-manylinux1_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:4936d1d6780fbe68db454f5e72a42ff64d1fd6397df9f363ae786930fd5c1cd4", size = 148047, upload-time = "2025-09-04T08:29:01.761Z" }, + { url = "https://files.pythonhosted.org/packages/a8/64/3708a90d1ebe202ffdeb7185f878a3c84d15c2b2c31858da2ce0583e2def/nvidia_nvtx-13.0.85-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:cb7780edb6b14107373c835bf8b72e7a178bac7367e23da7acb108f973f157a6", size = 148878, upload-time = "2025-09-04T08:28:53.627Z" }, +] + +[[package]] +name = "openai" +version = "3.31.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anyio" }, + { name = "httpx2" }, + { name = "jiter" }, + { name = "pydantic" }, + { name = "sniffio" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/73/99/d0c5b9e60eb131bfe5f6f818e9b25650b64004ff84512c0f7e00a246b826/openai-3.31.0.tar.gz", hash = "sha256:58110edba9acaf29cb2a675a1cbcccdd9f2fdb4932baed474dc847a7639e5d02", size = 2117207, upload-time = "2026-10-14T05:39:33.445Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/69/22/66014c8fede0aa2b3381cf80c5102219b78657b3e61776cdab8f0b78675a/openai-3.31.0-py3-none-any.whl", hash = "sha256:e5839f6670483f368de40ce3422f524c1afaf12ff8660539f53489e200db8d78", size = 2235454, upload-time = "2026-10-14T05:39:31.197Z" }, +] + +[[package]] +name = "openpyxl" +version = "3.1.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "et-xmlfile" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/3d/f9/88d94a75de065ea32619465d2f77b29a0469500e99012523b91cc4141cd1/openpyxl-3.1.5.tar.gz", hash = "sha256:cf0e3cf56142039133628b5acffe8ef0c12bc902d2aadd3e0fe5878dc08d1050", size = 186464, upload-time = "2024-06-28T14:03:44.161Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c0/da/977ded879c29cbd04de313843e76868e6e13408a94ed6b987245dc7c8506/openpyxl-3.1.5-py2.py3-none-any.whl", hash = "sha256:5282c12b107bffeef825f4617dc029afaf41d0ea60823bbb665ef3079dc79de2", size = 250910, upload-time = "2024-06-28T14:03:41.161Z" }, +] + +[[package]] +name = "opentelemetry-api" +version = "1.45.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/2e/02/6e0ae9cc61bd3169d401077b507b3ebc344745171e1051ab430be012dcd9/opentelemetry_api-1.45.1.tar.gz", hash = "sha256:aa38ed19bcc084ba42782a73255b3582283eced7ad6dddbd6695189e69adfb75", size = 72804, upload-time = "2026-10-06T17:32:58.133Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1e/41/f7dcf80b81ee8e71c1a2b59f14208bc723edbd89ed027a73b175abf6348e/opentelemetry_api-1.45.1-py3-none-any.whl", hash = "sha256:b31553efa588ae44bc306f863c785c5333a9ecc091248c6ee68b4b6c87fdedfb", size = 60256, upload-time = "2026-10-06T17:32:33.506Z" }, +] + +[[package]] +name = "opentelemetry-exporter-http-transport" +version = "0.66b1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "opentelemetry-api" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/62/0c/e3ebdb4b507f66afcc905e6885a4946969bd75b45988492643356fbbdc63/opentelemetry_exporter_http_transport-0.66b1.tar.gz", hash = "sha256:443080203bf52586ce0b2ad901e8951c61833eab1aa539ae6f1f16fe9e8e7952", size = 11693, upload-time = "2026-10-06T17:32:59.65Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/04/69/6af86ff66492b481c6a4c05dcfd68beb47ed8ba046440a26a2aac76b95c7/opentelemetry_exporter_http_transport-0.66b1-py3-none-any.whl", hash = "sha256:2f95404bdee7f9d2d529c7de56c7bd86d014d774d8fbf137810e0167f8a492bf", size = 12155, upload-time = "2026-10-06T17:32:35.454Z" }, +] + +[package.optional-dependencies] +requests = [ + { name = "requests" }, +] + +[[package]] +name = "opentelemetry-exporter-otlp-common" +version = "0.66b1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "opentelemetry-sdk" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/cb/19/41de712173f43057e4532d42ece7d0c6d4210d353e5752433cb14987643f/opentelemetry_exporter_otlp_common-0.66b1.tar.gz", hash = "sha256:6b1403487a2185ac1feb45fd5546fdf8630ce71c36bcefaadf51e2130e9e23f9", size = 14325, upload-time = "2026-10-06T17:33:01.725Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fc/39/8c23d67665c762aa51840fa06f86e902e8f6f1693bc8d7e3d98cd6e2f753/opentelemetry_exporter_otlp_common-0.66b1-py3-none-any.whl", hash = "sha256:00ff8592c3a7cb729ff3fdc7ffa12372c243bdf2163e80c180994d0c7bd83ee9", size = 12385, upload-time = "2026-10-06T17:32:38.177Z" }, +] + +[[package]] +name = "opentelemetry-exporter-otlp-proto-common" +version = "1.45.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "opentelemetry-proto" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c1/8e/65e85e5137991a3c493b11682151d198638a5bc1dd4b4c5f67e013c57d7c/opentelemetry_exporter_otlp_proto_common-1.45.1.tar.gz", hash = "sha256:2e4adcc3a67bcf57804fc49514f0ef64974ca7590aa3491da389852b4a0628f6", size = 18873, upload-time = "2026-10-06T17:33:04.471Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/84/aa/92f225d353904e7f70b8b3e3c1b02db0cf56f744c2e83c581dc372e78873/opentelemetry_exporter_otlp_proto_common-1.45.1-py3-none-any.whl", hash = "sha256:2f446183ae7047b036226f1d846c41a834b0e8755ad13b51a51dd38952eb466c", size = 15393, upload-time = "2026-10-06T17:32:41.911Z" }, +] + +[[package]] +name = "opentelemetry-exporter-otlp-proto-http" +version = "1.45.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "googleapis-common-protos" }, + { name = "opentelemetry-api" }, + { name = "opentelemetry-exporter-http-transport", extra = ["requests"] }, + { name = "opentelemetry-exporter-otlp-common" }, + { name = "opentelemetry-exporter-otlp-proto-common" }, + { name = "opentelemetry-proto" }, + { name = "opentelemetry-sdk" }, + { name = "requests" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/1b/17/26487707ea4caa97b17e6e4b5fa72133a53512ffa2f5cf7a49ef284b29cb/opentelemetry_exporter_otlp_proto_http-1.45.1.tar.gz", hash = "sha256:45c218405ce3fd879596924b1874bf9a8f6880206d61065c5a912c8e5c297fb7", size = 28839, upload-time = "2026-10-06T17:33:05.713Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/aa/1f/517eaa0187ba106a9da97160ce2add3a371812681dc440930b267f714e42/opentelemetry_exporter_otlp_proto_http-1.45.1-py3-none-any.whl", hash = "sha256:24a97cf3753c7fb52fad44a696e452ff371686339e2acf3309e2eda3d0230700", size = 22180, upload-time = "2026-10-06T17:32:43.946Z" }, +] + +[[package]] +name = "opentelemetry-instrumentation" +version = "0.66b1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "opentelemetry-api" }, + { name = "opentelemetry-semantic-conventions" }, + { name = "packaging" }, + { name = "wrapt" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a5/03/89e47ff8d52a4f83b343e6eb9ef1698ff45357216e5b6b2b21e0da5c5c7d/opentelemetry_instrumentation-0.66b1.tar.gz", hash = "sha256:e79a510f7d87c72d95e964ddb42193a0d9a75668c027d980eab032ea1322a5ce", size = 43308, upload-time = "2026-10-06T17:36:10.703Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/da/b2/d1413681ff43e13ac9860df27e1226d3199ab0b97b352ceea41abcc660a5/opentelemetry_instrumentation-0.66b1-py3-none-any.whl", hash = "sha256:4c4aa14dc9a24a02325a9d4c42c4d0208dbb1374c2b1b8fe6c9392d59f3e1008", size = 36904, upload-time = "2026-10-06T17:35:11.663Z" }, +] + +[[package]] +name = "opentelemetry-instrumentation-asgi" +version = "0.66b1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "asgiref" }, + { name = "opentelemetry-api" }, + { name = "opentelemetry-instrumentation" }, + { name = "opentelemetry-semantic-conventions" }, + { name = "opentelemetry-util-http" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/5a/d9/ff522f5c3e340e9007554923b1a4d2ac451676f8757bafb3d0057f68b5c3/opentelemetry_instrumentation_asgi-0.66b1.tar.gz", hash = "sha256:78cdc5e45e897e16a8dac9d282e8d5bdf9af2d58e1313fa0bdd4a134c6f9dafc", size = 25992, upload-time = "2026-10-06T17:36:14.593Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/67/ea/10ba99110bf3c9fb736af39c96ca8f3668b988cabb6b59309e058c44461c/opentelemetry_instrumentation_asgi-0.66b1-py3-none-any.whl", hash = "sha256:78b3f9bdf0fa38c65935a2ab46d59e0f9de873a51e0c95b0329f106e2ccb5274", size = 15812, upload-time = "2026-10-06T17:35:17.638Z" }, +] + +[[package]] +name = "opentelemetry-instrumentation-httpx" +version = "0.66b1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "opentelemetry-api" }, + { name = "opentelemetry-instrumentation" }, + { name = "opentelemetry-semantic-conventions" }, + { name = "opentelemetry-util-http" }, + { name = "wrapt" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/de/50/41544799b043d14fdfa6fe62fa2518eaba22793fce03e9abde930b92e671/opentelemetry_instrumentation_httpx-0.66b1.tar.gz", hash = "sha256:5865a72c68098c85955a271ab8744b480a36e3ee492d35b8cadb93c7c4dbb618", size = 26637, upload-time = "2026-10-06T17:36:27.265Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4f/c6/e5682b1bfb320b32505e88255c34ae1e99fe9fb220cc465c244e91967eac/opentelemetry_instrumentation_httpx-0.66b1-py3-none-any.whl", hash = "sha256:0342a4002c6dbc6c4bf22cc7e698f50f5c8b77f63325c6f40c94ab87e016bf4d", size = 17723, upload-time = "2026-10-06T17:35:36.501Z" }, +] + +[[package]] +name = "opentelemetry-instrumentation-starlette" +version = "0.66b1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "opentelemetry-api" }, + { name = "opentelemetry-instrumentation" }, + { name = "opentelemetry-instrumentation-asgi" }, + { name = "opentelemetry-semantic-conventions" }, + { name = "opentelemetry-util-http" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/9a/ea/f962c5b52ba6587ab25c49ed199e5dfe01d402e8d530c13ba99430668f23/opentelemetry_instrumentation_starlette-0.66b1.tar.gz", hash = "sha256:ef8274216c67856ac02f2d23daede0819c77a9b4b6cc3f4decb84663b7ac5693", size = 14319, upload-time = "2026-10-06T17:36:39.304Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6c/89/4c8b2ed03712a802cb60a9d8d977c3340dc83a9be75b2fd0b9a011bf8371/opentelemetry_instrumentation_starlette-0.66b1-py3-none-any.whl", hash = "sha256:1ac11a70e345b57a4259f4a47311101b9eafa3b30d4133df25b36b2e6dfc2c88", size = 11094, upload-time = "2026-10-06T17:35:55.235Z" }, +] + +[[package]] +name = "opentelemetry-proto" +version = "1.45.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "protobuf" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/4b/7f/15f014fb195da6c2dbb6c71399b8e76824878718e94de6454038488eed28/opentelemetry_proto-1.45.1.tar.gz", hash = "sha256:79e0fb95e4616691a469439238aa9224d75779b3e108e895d1aa125ab29ca77c", size = 46488, upload-time = "2026-10-06T17:33:11.49Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ab/9a/42ec8180a769516ae757e893b69736826efceac7332553915b4528a91c6d/opentelemetry_proto-1.45.1-py3-none-any.whl", hash = "sha256:f38e2a8413053c180cd3d2637fbb279673ec2f6a6e09c995aafa2f452c52b46e", size = 72488, upload-time = "2026-10-06T17:32:53.057Z" }, +] + +[[package]] +name = "opentelemetry-sdk" +version = "1.45.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "opentelemetry-api" }, + { name = "opentelemetry-semantic-conventions" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a1/79/7392e21a1c8f0c61d90b223e31c7e48cb9d452e91a6b820ad24cca5f23c4/opentelemetry_sdk-1.45.1.tar.gz", hash = "sha256:63d24a6ca645019a631e6a51999c73e93adcac1196ca640b8ae78a7cc4762bf3", size = 218324, upload-time = "2026-10-06T17:33:13.26Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/95/3c/87c42b4bd6dd297536f04cd9383d212ac557ecd49f2cbdcd46da1c9ef5c8/opentelemetry_sdk-1.45.1-py3-none-any.whl", hash = "sha256:c604c11dc429810812348989115fa44bd558772a3d7442afc43d024f2c250ca4", size = 140063, upload-time = "2026-10-06T17:32:55.04Z" }, +] + +[[package]] +name = "opentelemetry-semantic-conventions" +version = "0.66b1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "opentelemetry-api" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/46/e4/dbbfb2a010c4db2224a5114638acede6fe563d33cc20fb1752cebcbe6298/opentelemetry_semantic_conventions-0.66b1.tar.gz", hash = "sha256:497ca63bf383723411e8eaf60c8779e9877633c936bb641080adab59d0eb6ec8", size = 150250, upload-time = "2026-10-06T17:33:14.073Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/bc/14/67f8aa798857f8cf686f515bf93d9bb877ce952ddc8efae0fa25b45ce0d6/opentelemetry_semantic_conventions-0.66b1-py3-none-any.whl", hash = "sha256:d4cddeb4315490b35213f55e2bdc9ac54bb1e4d318927475bed62b35545e581b", size = 206279, upload-time = "2026-10-06T17:32:56.103Z" }, +] + +[[package]] +name = "opentelemetry-util-http" +version = "0.66b1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/7c/b5/df4b61da899f6ebdffdbdf0c8b0f3189ee57151694ccd5b7d50ee2906241/opentelemetry_util_http-0.66b1.tar.gz", hash = "sha256:047dea1a628031f857a5a32261dc0e955bc162d39993ed1cffb8f2cff5ba8a62", size = 11586, upload-time = "2026-10-06T17:36:46.572Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/eb/9b/c77ecaea79ba0de1a11e7f06a7f5eea7043ec23f1860dcf5f03536698e4c/opentelemetry_util_http-0.66b1-py3-none-any.whl", hash = "sha256:8f443d7abcaf29c4a07b373bbd31b5b39132c0ed3c27d015a59dc0323d5b1c58", size = 8387, upload-time = "2026-10-06T17:36:06.984Z" }, +] + +[[package]] +name = "packaging" +version = "25.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a1/d4/1fc4078c65507b51b96ca8f8c3ba19e6a61c8253c72794544580a7b6c24d/packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f", size = 165727, upload-time = "2025-04-19T11:48:59.673Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484", size = 66469, upload-time = "2025-04-19T11:48:57.875Z" }, +] + +[[package]] +name = "pamqp" +version = "4.0.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/31/4c/33a0ddaaac7bc42f9a542dbaaee8b580ceca3f89bf5da7c498d1fa97ff9a/pamqp-4.0.1.tar.gz", hash = "sha256:9dd13b828e346622793981f14a5df817fce5de998c746209d6c0154eb8403970", size = 137192, upload-time = "2026-07-06T16:37:51.732Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/71/14/1dfc08b743ba995a38dee0ea09beb46a05c7fe8ac53d729095905f7bf11d/pamqp-4.0.1-py3-none-any.whl", hash = "sha256:a547f45128b06e42ce8d7a739b0cfcc40f2c724770622eaaff4a3f587b1cf7d0", size = 32773, upload-time = "2026-07-06T16:37:50.623Z" }, +] + +[[package]] +name = "pgvector" +version = "0.5.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f8/23/96aa38899fbf8e103766db608d6e42acac269a96e08f3003fe9da3396fed/pgvector-0.5.1.tar.gz", hash = "sha256:94998a54b801b1075d623b8fa677fcb8210a7977b88f8e2203ab115c155af2e4", size = 35714, upload-time = "2026-10-09T01:50:22.779Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a2/8d/a9c2a531da0ebb54b4a7174450e8534a39db112a141ae3a437de28420111/pgvector-0.5.1-py3-none-any.whl", hash = "sha256:ec5bcd5ffaefe6ecb2dcc9564ca921d284564b969183bc837a144604773af8ea", size = 31056, upload-time = "2026-10-09T01:50:21.614Z" }, +] + +[[package]] +name = "phonenumbers" +version = "9.0.41" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/2f/df/cc0d70f1c79e436ea00d935b6352053d526252b81ce6c130d39eee846fb2/phonenumbers-9.0.41.tar.gz", hash = "sha256:dfa6f74eeac67c044b75313fe0af10774d7d1e1242241437279d4c2fb8027c01", size = 2311017, upload-time = "2026-10-08T10:51:09.778Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/60/1a/4059026e9c8a4c3faeab4a45f5aa67fb77d1f0d9c767085ded69c5c533e2/phonenumbers-9.0.41-py2.py3-none-any.whl", hash = "sha256:ccf2ea44f8aa35c487f26146a31520ecedf8e1af1f57c803678ecb5ef5c01668", size = 2594658, upload-time = "2026-10-08T10:51:07.317Z" }, +] + +[[package]] +name = "platformdirs" +version = "4.13.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/80/a8/66d45abadff219e36e2a824181b8f6a67e7ed4572934d6252c71c29d5731/platformdirs-4.13.0.tar.gz", hash = "sha256:1aa0b0d3f224c1f07c295121e312a5a24a180d6ae5a8425ea1784b3e3863e9c0", size = 61094, upload-time = "2026-10-11T02:05:24.109Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8d/15/1633010b26e88e872c93b67c0b6c5e174fb74cb6fb5c1472b4d51d4a8f22/platformdirs-4.13.0-py3-none-any.whl", hash = "sha256:3dbcf4cd708f21cf876c4eaa90e58412bc4f033d87143f41b1493ff77c25b7e1", size = 32724, upload-time = "2026-10-11T02:05:22.776Z" }, +] + +[[package]] +name = "pluggy" +version = "1.6.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3", size = 69412, upload-time = "2025-05-15T12:30:07.975Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" }, +] + +[[package]] +name = "preshed" +version = "3.0.13" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cymem" }, + { name = "murmurhash" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/43/75/fe6b7bbd0dea530a001b0e24c331b21a0be2786e402abf3c57f5dce43d4b/preshed-3.0.13.tar.gz", hash = "sha256:d75f718bbfd97e992f7827e0fa7faf6a91bdd9c922d5baa4b50d62731396cb89", size = 18338, upload-time = "2026-03-23T08:57:31.378Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0e/2a/401158195d6dc7f6aef0b354d74d0e95c9da124499448c2b3dbb95b71204/preshed-3.0.13-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:c0d0c14187dc0078d8a63bf190ec045a4d13e7748b6caeb557a7d575e411410b", size = 137289, upload-time = "2026-03-23T08:56:46.516Z" }, + { url = "https://files.pythonhosted.org/packages/88/8f/e20e64573988528785447a6893b2e7ab287ecfd85b3888e978b28812fd20/preshed-3.0.13-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:7770987c2e57497cd26124a9be5f652b5b3ccd0def89859ab0da8bca6144a3de", size = 136847, upload-time = "2026-03-23T08:56:47.572Z" }, + { url = "https://files.pythonhosted.org/packages/b9/72/18168f881359c4482d312f8dc196371bdd61c1583a52b34390da4c88bbea/preshed-3.0.13-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:4a7bc48220de579be6bdb0a8715482cf36e2a625a6fd5ad26c9f43485a4a23b5", size = 831478, upload-time = "2026-03-23T08:56:48.769Z" }, + { url = "https://files.pythonhosted.org/packages/fd/3a/3543476091087102775568cea9885dde3453569e9aeee365809108de572f/preshed-3.0.13-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:e5c8462472f790c16708306aef3a102a762bd19dfe3d2f8ee08bd5e12f51b835", size = 839913, upload-time = "2026-03-23T08:56:49.937Z" }, + { url = "https://files.pythonhosted.org/packages/cf/65/b13f01329decc44ef53cfb6b4601ba85382dcb2a4ec78d9250f03a418066/preshed-3.0.13-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c046736239cc8d72670749b79b526e4111839a2fc461a58545d212797649129c", size = 1816452, upload-time = "2026-03-23T08:56:51.233Z" }, + { url = "https://files.pythonhosted.org/packages/d1/c7/f1a996c6832234efd4d543041b582418d41ac480ee55c557ec9e65344637/preshed-3.0.13-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:7c333f18e9a81c8a6de0603fd8781e17115324b117c445ca91abdf7bfb1abe49", size = 1888978, upload-time = "2026-03-23T08:56:52.591Z" }, + { url = "https://files.pythonhosted.org/packages/e3/b9/96fb71499049885ce19545903fdd38877bbc2be0da47e37c04d01f3e9f66/preshed-3.0.13-cp313-cp313-win_amd64.whl", hash = "sha256:461327f8dd36520dcf1fd55a671e0c3c2c97a2d95e22fc85faa31173f4785dda", size = 122134, upload-time = "2026-03-23T08:56:54.392Z" }, + { url = "https://files.pythonhosted.org/packages/ef/a7/32a4903019d936a2316fdd330bedddac287ac26326107d24fb76a1fbc60a/preshed-3.0.13-cp313-cp313-win_arm64.whl", hash = "sha256:35d6c5acb3ee3b12b87a551913063f0cec784055c2af16e028c19fe875f079d0", size = 108497, upload-time = "2026-03-23T08:56:55.816Z" }, +] + +[[package]] +name = "presidio-analyzer" +version = "2.2.362" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "phonenumbers" }, + { name = "pydantic" }, + { name = "pyyaml" }, + { name = "regex" }, + { name = "spacy" }, + { name = "tldextract" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/2f/8a/d6cf4bddbb11d9c78f5c9342bbbcde4f90fe4e3c7de114a836ec4ed8a6cf/presidio_analyzer-2.2.362-py3-none-any.whl", hash = "sha256:4c36438924b1fcb4df92ea5cf2d8dc57508808e116b10923c983b8732aa07d90", size = 201084, upload-time = "2026-03-15T12:40:43.801Z" }, +] + +[[package]] +name = "presidio-anonymizer" +version = "2.2.362" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cryptography" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/17/01/1c3404e8da63a979ae951b8822576bc0e52ca3a46a624ac9439786990c6d/presidio_anonymizer-2.2.362-py3-none-any.whl", hash = "sha256:b2d81542cb797360d18506a1aa73ea0dfacc44abca15248c81dd062f582e6b2b", size = 36603, upload-time = "2026-03-15T12:40:38.651Z" }, +] + +[[package]] +name = "prometheus-client" +version = "0.26.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/52/73/f1334c29c2af4cd9dba6c7817e61b611bd0215e2eb5565c6064a4de18802/prometheus_client-0.26.0.tar.gz", hash = "sha256:04a91bcf94e2cf74a44a1a874d651a2e853ed354b6e822f3b7487751465d5c2b", size = 92910, upload-time = "2026-07-24T19:36:41.893Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/eb/a3/b69efbf4143b5b9859b977770bbbabcc2796b702fa69dc40271e45cd5a56/prometheus_client-0.26.0-py3-none-any.whl", hash = "sha256:fa93d06737aa02bacd05794768508bb97d2fbee28cb3bca04eaae92f0ca953d6", size = 64494, upload-time = "2026-07-24T19:36:40.854Z" }, +] + +[[package]] +name = "prompt-toolkit" +version = "3.0.53" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "wcwidth" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/7d/ea/39b988c938f75cb75d7045b5c69f8bfed47ee2152c8837fb403de29d6fb8/prompt_toolkit-3.0.53.tar.gz", hash = "sha256:9ec8a0ad96d5c56148b3f914aa79c1564c3fde5d2e6b876e7bc327e353cf8fa6", size = 435492, upload-time = "2026-07-26T20:56:14.758Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/54/6f/84908cad2d6aa5144abcf7b42709fe4fdb459bc640ec7ac5786e7693dabc/prompt_toolkit-3.0.53-py3-none-any.whl", hash = "sha256:01c0891d7f9237d5e339f7d3e42cdae80b7534abb1c7c0e3352efba6231492f2", size = 392288, upload-time = "2026-07-26T20:56:12.512Z" }, +] + +[[package]] +name = "propcache" +version = "0.5.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b3/9a/9fbf4e4ec0c2d7f1c32519fff782ef467859b8faa9fbc5331a96f6395d43/propcache-0.5.4.tar.gz", hash = "sha256:ff6b113f50bc066a698db5d944d2c6dc7507168dd3341e255a8892fd0715a558", size = 61545, upload-time = "2026-09-16T00:17:14.386Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/78/4c/3b1365d58a667689e067e13d055fcd92bdf8d9a2fca3d9201b47ed5b3631/propcache-0.5.4-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:36c0d9db44b523ef93d03341b1c42d69ff01d673c053d1b1c6c3a363bcaa39ba", size = 85290, upload-time = "2026-09-16T00:14:52.342Z" }, + { url = "https://files.pythonhosted.org/packages/8f/61/5f9c29c3aa67c30238c4eadf95149b1d983a48f69b86b0cff927a7d6df13/propcache-0.5.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e1d52a05dc417279f7e5c7618c5dfbbc29923aaf9bc0a5c1802ddcebf54c61a0", size = 50027, upload-time = "2026-09-16T00:14:53.67Z" }, + { url = "https://files.pythonhosted.org/packages/25/7d/c1ab1ef09e9d4d835be5d58c0a32a1e1de8397abaa4e502a9d4141328cad/propcache-0.5.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:44149f46500a0a41b95b4d99c2e586a77319539730607b9892974a092788b111", size = 51425, upload-time = "2026-09-16T00:14:54.826Z" }, + { url = "https://files.pythonhosted.org/packages/73/36/0093091ebb270fcd1bc1f6e095f93b2e0ed7f1011c28837dc2dbe5f96b99/propcache-0.5.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:dbab5f5ff6897c81f355d079010cdae85b02e5a0b518b5251523b8ad8ae9ac3c", size = 233595, upload-time = "2026-09-16T00:14:56.09Z" }, + { url = "https://files.pythonhosted.org/packages/ae/8f/0de9d4c8e05ce0be71b436919a216bd7fc5cc6e2691c0602295efb22b9ed/propcache-0.5.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c3e98c55bde2bcf7db3c70d1aed7ae9aa8aebbf19a250c66645cde44cdb8b867", size = 240318, upload-time = "2026-09-16T00:14:57.674Z" }, + { url = "https://files.pythonhosted.org/packages/7d/71/2b35e91455209b85ee98f7859583e0814fab57d3af0f2381aaee34c37304/propcache-0.5.4-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:db3ae52ccc150dbc84704e9d642743897f3e1c54742ff34cacb661e52e3818a9", size = 246649, upload-time = "2026-09-16T00:14:59.352Z" }, + { url = "https://files.pythonhosted.org/packages/ed/74/08e6c1faf26ee2732023a3828787ba535557122774f4a386b1f715cbd8e0/propcache-0.5.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f85915e00dcb1cd9f2f890ead064ed40a27df06f0db65be427b29482ae357572", size = 234316, upload-time = "2026-09-16T00:15:00.696Z" }, + { url = "https://files.pythonhosted.org/packages/5c/9a/08385733c9321c9bb78039d3ff31045e4fca962d9665023c4eb70f998819/propcache-0.5.4-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:c2ba30a89035b57b73e00475de948521602f543d79ce01db10b04b36c4c76fc8", size = 204666, upload-time = "2026-09-16T00:15:02.019Z" }, + { url = "https://files.pythonhosted.org/packages/1d/f4/e87bc7629af9a14a752b218764a78742d73c2c563ac58315da6841f0cbe4/propcache-0.5.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ae58f361bd5dae942717c65d3413b478c70aea9c462599e7b9adad3731db3894", size = 225900, upload-time = "2026-09-16T00:15:03.394Z" }, + { url = "https://files.pythonhosted.org/packages/d9/6d/11014938d3fe9bea2ea2dcf930f26ed565bfb2f5be3c756362ea48c92636/propcache-0.5.4-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:96f7c5c15656040ddcbc51e56dc59b58aa25999d743c126abd425b9766ab43e9", size = 219988, upload-time = "2026-09-16T00:15:04.811Z" }, + { url = "https://files.pythonhosted.org/packages/dc/72/fbf17c589f92c0b3bbf6709a425661f8ef2ed0d46b38985a7d7b5a0f6b91/propcache-0.5.4-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:7cc528e760a8af06f2b13e9b9f362cd90c7c718ea61228a96dbd31ba16ed7f47", size = 233611, upload-time = "2026-09-16T00:15:06.498Z" }, + { url = "https://files.pythonhosted.org/packages/55/7e/dbd637572a279692e5518d117274a9331bf5faac59f191d30e82521a3ec7/propcache-0.5.4-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:425f8cc86ab5018b4b8d4a23bc8e74d964bd3d757c3702e301aa79be76c53f6c", size = 204333, upload-time = "2026-09-16T00:15:07.961Z" }, + { url = "https://files.pythonhosted.org/packages/ba/5a/f99c92068f1e0f5c886899ce0e4a619db376ca98c5279d93f95bd86906af/propcache-0.5.4-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:a5793c7698a53f56f4a1889a4737c7eeb1b7ad0842fa6b1abca22913ff79c8c1", size = 235177, upload-time = "2026-09-16T00:15:09.334Z" }, + { url = "https://files.pythonhosted.org/packages/ee/28/95456fabd2daf6be89049a13fbf03341756014d2959c83d12957d4c49694/propcache-0.5.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:c02c0e570c5c7e077b0181a9f3cdb7d4c3617d1cda6b5c95bd5d34022923d82c", size = 228982, upload-time = "2026-09-16T00:15:10.729Z" }, + { url = "https://files.pythonhosted.org/packages/b1/bb/df90f62c9cf7c93ea235f6f9405143bba802914607317266dd81fc8d737e/propcache-0.5.4-cp313-cp313-win32.whl", hash = "sha256:3e413d7a4a9b4866b7a761d6060d434b64d23cd35122eda3b026a0bbe8196b25", size = 42611, upload-time = "2026-09-16T00:15:12.111Z" }, + { url = "https://files.pythonhosted.org/packages/01/bc/e0a7b84af04ec02d73a48aa71f091e1e4a2107e3074b7ce12195b66901f4/propcache-0.5.4-cp313-cp313-win_amd64.whl", hash = "sha256:0c889f6fa84957bc7e8b4eab71fd16a0455068d5045e3aa40c733071d2b2fd77", size = 45342, upload-time = "2026-09-16T00:15:13.519Z" }, + { url = "https://files.pythonhosted.org/packages/9a/70/50b031cafe72a5c1878b903ee87303f71313345566bf3d6ec202e5ddc9ec/propcache-0.5.4-cp313-cp313-win_arm64.whl", hash = "sha256:69fc35c0779522da366c563e5faf203ffc1f8ff0021d5b1337fa4efa5be73177", size = 42408, upload-time = "2026-09-16T00:15:14.788Z" }, + { url = "https://files.pythonhosted.org/packages/f5/cd/785c64ed382f3f04201870267b02783f63b4678c2acfddc177a3ebcc2727/propcache-0.5.4-py3-none-any.whl", hash = "sha256:62c60aec739ed00124573cce1178138fd690c7676352d67a37328c1cf51d7468", size = 16338, upload-time = "2026-09-16T00:17:13.106Z" }, +] + +[[package]] +name = "protobuf" +version = "6.33.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/66/70/e908e9c5e52ef7c3a6c7902c9dfbb34c7e29c25d2f81ade3856445fd5c94/protobuf-6.33.6.tar.gz", hash = "sha256:a6768d25248312c297558af96a9f9c929e8c4cee0659cb07e780731095f38135", size = 444531, upload-time = "2026-03-18T19:05:00.988Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fc/9f/2f509339e89cfa6f6a4c4ff50438db9ca488dec341f7e454adad60150b00/protobuf-6.33.6-cp310-abi3-win32.whl", hash = "sha256:7d29d9b65f8afef196f8334e80d6bc1d5d4adedb449971fefd3723824e6e77d3", size = 425739, upload-time = "2026-03-18T19:04:48.373Z" }, + { url = "https://files.pythonhosted.org/packages/76/5d/683efcd4798e0030c1bab27374fd13a89f7c2515fb1f3123efdfaa5eab57/protobuf-6.33.6-cp310-abi3-win_amd64.whl", hash = "sha256:0cd27b587afca21b7cfa59a74dcbd48a50f0a6400cfb59391340ad729d91d326", size = 437089, upload-time = "2026-03-18T19:04:50.381Z" }, + { url = "https://files.pythonhosted.org/packages/5c/01/a3c3ed5cd186f39e7880f8303cc51385a198a81469d53d0fdecf1f64d929/protobuf-6.33.6-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:9720e6961b251bde64edfdab7d500725a2af5280f3f4c87e57c0208376aa8c3a", size = 427737, upload-time = "2026-03-18T19:04:51.866Z" }, + { url = "https://files.pythonhosted.org/packages/ee/90/b3c01fdec7d2f627b3a6884243ba328c1217ed2d978def5c12dc50d328a3/protobuf-6.33.6-cp39-abi3-manylinux2014_aarch64.whl", hash = "sha256:e2afbae9b8e1825e3529f88d514754e094278bb95eadc0e199751cdd9a2e82a2", size = 324610, upload-time = "2026-03-18T19:04:53.096Z" }, + { url = "https://files.pythonhosted.org/packages/9b/ca/25afc144934014700c52e05103c2421997482d561f3101ff352e1292fb81/protobuf-6.33.6-cp39-abi3-manylinux2014_s390x.whl", hash = "sha256:c96c37eec15086b79762ed265d59ab204dabc53056e3443e702d2681f4b39ce3", size = 339381, upload-time = "2026-03-18T19:04:54.616Z" }, + { url = "https://files.pythonhosted.org/packages/16/92/d1e32e3e0d894fe00b15ce28ad4944ab692713f2e7f0a99787405e43533a/protobuf-6.33.6-cp39-abi3-manylinux2014_x86_64.whl", hash = "sha256:e9db7e292e0ab79dd108d7f1a94fe31601ce1ee3f7b79e0692043423020b0593", size = 323436, upload-time = "2026-03-18T19:04:55.768Z" }, + { url = "https://files.pythonhosted.org/packages/c4/72/02445137af02769918a93807b2b7890047c32bfb9f90371cbc12688819eb/protobuf-6.33.6-py3-none-any.whl", hash = "sha256:77179e006c476e69bf8e8ce866640091ec42e1beb80b213c3900006ecfba6901", size = 170656, upload-time = "2026-03-18T19:04:59.826Z" }, +] + +[[package]] +name = "psycopg" +version = "3.3.6" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "tzdata", marker = "sys_platform == 'win32'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/76/26/3ea4ca5eaea1c0debcdf7ee7c1613fbe721dc27a03c461c0817ffd8a0601/psycopg-3.3.6.tar.gz", hash = "sha256:c081f2250df751a943036e42db6df4571c66cd0aabe8291a7a506512b12007d2", size = 168171, upload-time = "2026-09-18T13:22:55.152Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4e/de/748bd7609c71cae5d737f0ba9192f19329f70180ecda8fff3cac02c5abe3/psycopg-3.3.6-py3-none-any.whl", hash = "sha256:a1db9f7148b06a28606767efaca51fa6f9398c5c0a3810519be69d7000bdb631", size = 215490, upload-time = "2026-09-18T13:15:29.374Z" }, +] + +[package.optional-dependencies] +binary = [ + { name = "psycopg-binary", marker = "implementation_name != 'pypy'" }, +] + +[[package]] +name = "psycopg-binary" +version = "3.3.6" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b4/c3/c072584b69ad44a747b448cfc9766fecb8aae56e372a017e2ef668790057/psycopg_binary-3.3.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:5ad8f35e67cc16d1fad1fa8c88972dc9b3a3141ea67897399904edab96a301b6", size = 4712284, upload-time = "2026-09-18T13:19:13.451Z" }, + { url = "https://files.pythonhosted.org/packages/0a/b9/4283b785339e8e2318d03048994b093d650ea6289fabaa806b765dc0d449/psycopg_binary-3.3.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:373704aea331d3f3e3402c125a1543f5875e2986ebb54f97d1647942161f803f", size = 4772031, upload-time = "2026-09-18T13:19:18.524Z" }, + { url = "https://files.pythonhosted.org/packages/6f/72/7a1321d359246769fff1affffbd0132785a28f7f63c18524c15a502398f4/psycopg_binary-3.3.6-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:b82491019b884d62318b5f30706c3d7e6d4e5a6cb7eabcb3edc0c1b0fdaceae9", size = 5556392, upload-time = "2026-09-18T13:19:24.418Z" }, + { url = "https://files.pythonhosted.org/packages/de/b0/c6f8a0585a5dacbea74e130bcfc66629390e8f5bbc79d2a8e806e8952150/psycopg_binary-3.3.6-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:cec5ea900390897d0b46130f60bc2883bf19c314f9044235217c8be88b0ef269", size = 5237855, upload-time = "2026-09-18T13:19:31.257Z" }, + { url = "https://files.pythonhosted.org/packages/e2/fc/c3a7a8bbef7e945ec584ac61d460a612363ea398511cd0e220242b1d69f1/psycopg_binary-3.3.6-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:98c02090d88f2ebc0ec1e8da538f77d225ce0fffecf372aa39262e62a1b054ef", size = 6833856, upload-time = "2026-09-18T13:19:43.622Z" }, + { url = "https://files.pythonhosted.org/packages/a9/f2/8e80b921db728ebb68fc105bd7c4277f908210ad755bd6481d5ea7add740/psycopg_binary-3.3.6-cp313-cp313-manylinux_2_38_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:ee2c4728c691245e24501fcd7a97b5b381236b9985bc445bba88cdce7d1b5784", size = 5070730, upload-time = "2026-09-18T13:19:49.968Z" }, + { url = "https://files.pythonhosted.org/packages/54/6a/5b313e0c5348244f0e973aff3258bf86766656256d5ece8d541a53e35b4a/psycopg_binary-3.3.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f19cc87343eaa55255e76b31259a570072ac95d6ae82c92dd34b97691f5e49dc", size = 4598089, upload-time = "2026-09-18T13:19:56.426Z" }, + { url = "https://files.pythonhosted.org/packages/32/e9/db7f76ec24bf6699e92bf604e5c4bae10664a681a8999ef42aa0faf0f2c6/psycopg_binary-3.3.6-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:fdccb3a0e184b03e9baa673b15a809cf36c339c85dbda0ebc25a698846dfbee8", size = 4278481, upload-time = "2026-09-18T13:20:04.681Z" }, + { url = "https://files.pythonhosted.org/packages/61/83/72c67013656f4d6b547caabffb193e91d57e63f90eefdcc6d045c400e97d/psycopg_binary-3.3.6-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:9892188bb15e5803beb51afe8a25add6b56be391a53058e8bca03b74e1e6bf22", size = 4009229, upload-time = "2026-09-18T13:20:11.905Z" }, + { url = "https://files.pythonhosted.org/packages/82/35/5e4500df2c999eb0faed8b184e6958b834172128274f06167a5deef4c19c/psycopg_binary-3.3.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:3af90f92769d8cc10f94515ee7a0aef36ea85ca733a0ce22858f6e0953f41138", size = 4321467, upload-time = "2026-09-18T13:20:17.949Z" }, + { url = "https://files.pythonhosted.org/packages/55/7f/e350e1cf498ba2565c3f87b12f429d2012eb86b76c2b3845a19ee5fbb4d6/psycopg_binary-3.3.6-cp313-cp313-win_amd64.whl", hash = "sha256:0ebfad5d131de9f892ae9e70cc7616207768b6714b66a52d4612b8ceaf78b372", size = 3658179, upload-time = "2026-09-18T13:20:22.691Z" }, +] + +[[package]] +name = "py-key-value-aio" +version = "0.4.6" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "beartype" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ca/99/c346e3474853801ec5ecf4c3ee60cfc6060327ebc31424df4e346620dde4/py_key_value_aio-0.4.6.tar.gz", hash = "sha256:267c03c3e24cb99d3097612f8a5cfd8e11785c6a2975e272db0e303ea1850bfd", size = 112876, upload-time = "2026-09-18T15:29:52.002Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9a/46/12871550fb0613d149144bb9d41f22680d5f46717bc45a76eb5798c20c3f/py_key_value_aio-0.4.6-py3-none-any.whl", hash = "sha256:820b30c7959fc738ea3d00160cdb10cd258f51e38737b2add530defeea1ded77", size = 171289, upload-time = "2026-09-18T15:29:50.665Z" }, +] + +[package.optional-dependencies] +filetree = [ + { name = "aiofile" }, + { name = "anyio" }, +] +keyring = [ + { name = "keyring" }, +] +memory = [ + { name = "cachetools" }, +] + +[[package]] +name = "pyarrow" +version = "26.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ec/34/17c34cb38e5d940e38f0f0d9fdfa0e8a506676409ea9b85aff7e3079f831/pyarrow-26.0.0.tar.gz", hash = "sha256:0cccd36e00ea3afeb52ded61f2721ce71f604853d70c45365c58324eb773d6ae", size = 1239433, upload-time = "2026-10-09T08:26:25.315Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4d/35/ca95493712af97c46a312945c8e9d16b21c5fe2f148be5466168d0290505/pyarrow-26.0.0-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:a6ca849f90cf73fe361f08a5762c783ead9671e4548c1f558cc637b54c9103f2", size = 36336700, upload-time = "2026-10-09T08:14:51.399Z" }, + { url = "https://files.pythonhosted.org/packages/69/ef/b1a675f79c9babfd4fcd99af62141d3c2d1a78a524e311b0c6b80110445a/pyarrow-26.0.0-cp313-cp313-macosx_12_0_x86_64.whl", hash = "sha256:c2ba350957076b1b3a22f549261dc3e9c67ca20816d8bd5f79d7b9c69be4c4c2", size = 38698502, upload-time = "2026-10-09T08:14:57.114Z" }, + { url = "https://files.pythonhosted.org/packages/3b/7c/cea852a832a327a8de797b3a68e5c25ce0f5aa1d20503807671bd90ec642/pyarrow-26.0.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:e3b190ba1d3d22a5a8758597f797111b77d433473744352a184a5ee0a42d672e", size = 50865064, upload-time = "2026-10-09T08:20:01.614Z" }, + { url = "https://files.pythonhosted.org/packages/4f/d6/e95834b29360092376fe4da9956ba41bb7b021869efe6ee9d4172d05cb15/pyarrow-26.0.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:240bd18a7487f8767616a948a69dd4e740a8bc36a1c9da49e4dc9a32c5c2faed", size = 53926722, upload-time = "2026-10-09T08:23:10.829Z" }, + { url = "https://files.pythonhosted.org/packages/e0/7f/98257444e2aea2e1fddceee3af3bd2077236d550428413f80393bd1f888d/pyarrow-26.0.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:2b5fcd69c0e1107b79e55839877db5a6ed04651b73fd6fec581d09e230bed5e4", size = 54443093, upload-time = "2026-10-09T08:23:16.971Z" }, + { url = "https://files.pythonhosted.org/packages/88/ca/dac99cfb25cfa62bf7194600cc99abc14a6bd2af50d7fdb7f15eeaf6e202/pyarrow-26.0.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:f7444ea6975c49a857c68f9bd8fa11acae96dede63d120ffb3bf0a603ea82516", size = 57381937, upload-time = "2026-10-09T08:23:24.95Z" }, + { url = "https://files.pythonhosted.org/packages/c0/ed/138d29fddaf803b90f4527e124bb6aaddc18aaf4a6c50fd0a5f577c94989/pyarrow-26.0.0-cp313-cp313-win_amd64.whl", hash = "sha256:3de30a7432b48b98b9decbd9e25a53bb9251d202c2e6c5a29a50869592ccb117", size = 28478571, upload-time = "2026-10-09T08:23:30.535Z" }, +] + +[[package]] +name = "pyasn1" +version = "0.6.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a4/9a/23310166d960def5897e91fe20e5b724601b02a22e84ba1f94232c0b7f67/pyasn1-0.6.4.tar.gz", hash = "sha256:9c447d8431c947fe4c8febc4ed9e760bc29011a5b01e5c74b67025bd9fb8ce81", size = 151262, upload-time = "2026-07-09T01:12:33.988Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9a/3b/6163796d69c3977d1e4287bea4a6979161cbbdd170ebb430511e8e1999ce/pyasn1-0.6.4-py3-none-any.whl", hash = "sha256:deda9277cfd454080ec40b207fb6df82206a3a2688735233cdcd8d3d565f088b", size = 84410, upload-time = "2026-07-09T01:12:32.92Z" }, +] + +[[package]] +name = "pyasn1-modules" +version = "0.4.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pyasn1" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e9/e6/78ebbb10a8c8e4b61a59249394a4a594c1a7af95593dc933a349c8d00964/pyasn1_modules-0.4.2.tar.gz", hash = "sha256:677091de870a80aae844b1ca6134f54652fa2c8c5a52aa396440ac3106e941e6", size = 307892, upload-time = "2025-03-28T02:41:22.17Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/47/8d/d529b5d697919ba8c11ad626e835d4039be708a35b0d22de83a269a6682c/pyasn1_modules-0.4.2-py3-none-any.whl", hash = "sha256:29253a9207ce32b64c3ac6600edc75368f98473906e8fd1043bd6b5b1de2c14a", size = 181259, upload-time = "2025-03-28T02:41:19.028Z" }, +] + +[[package]] +name = "pycparser" +version = "3.11" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/da/a8/c5fdbeee588bb8ada9458774f43adf1bdd30bd59157055142183e769a024/pycparser-3.11.tar.gz", hash = "sha256:d875f09c3507d00e1aba0eecc6dcadc1352f30fff09dc6bff2f1c2935e97c2bc", size = 113796, upload-time = "2026-10-09T12:56:59.539Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/90/11/0e6f11117525ff0eec40ebac3d313376f102df93ca44ad9e893ee85e4f89/pycparser-3.11-py3-none-any.whl", hash = "sha256:51d5a8ba2be0bbe440b99d2112604c95bbbc3c2748a64260186c541e1729cd80", size = 51178, upload-time = "2026-10-09T12:56:58.131Z" }, +] + +[[package]] +name = "pycryptodome" +version = "4.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/01/95/cf1a4d630500fc98cef83a58b1fd3bb75a74c4fe050f63cf40c052cbf2a2/pycryptodome-4.0.0.tar.gz", hash = "sha256:4ad4dd220fa22f99f5832847ccaea5bee39f140b8e4ea1a29aa77dc969c6490c", size = 1499510, upload-time = "2026-10-14T10:45:42.789Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/db/55/5fb4aab81c45b86edd40544e0b962a2aefca94c75c0bd3b68667861d4918/pycryptodome-4.0.0-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:70274777cdac701de642b31012b2264bf28cb435caaf17b795c96b6456886b62", size = 1358069, upload-time = "2026-10-14T10:45:10.344Z" }, + { url = "https://files.pythonhosted.org/packages/ee/5e/e7558e37b08ff678197173a5899c7700e63432f53dfadd9f40460e1fab52/pycryptodome-4.0.0-cp39-abi3-macosx_10_9_x86_64.whl", hash = "sha256:b8a7461b38e17c959172b3681b01542fbc8cf575ecb241306e4d87441f6824ff", size = 1200030, upload-time = "2026-10-14T10:45:12.254Z" }, + { url = "https://files.pythonhosted.org/packages/b9/ca/b19f26d94ce59fa3cf119091aa951174087cf2fc2cfda5cc2e70a9cd562e/pycryptodome-4.0.0-cp39-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:a47c2c401d1343f66ed22e05f52c577375e727afe275ab9477c13069df271c24", size = 1868374, upload-time = "2026-10-14T10:45:14.253Z" }, + { url = "https://files.pythonhosted.org/packages/55/fa/b3976fde0b81ae42b98151c7b155a986f8ecd1f9cedabcbbdcd4c2063f04/pycryptodome-4.0.0-cp39-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:73767e06cf75fb8ff86fd3cf77eba8e7614914d0c970fe1d41c216bf7b4b89c1", size = 2520237, upload-time = "2026-10-14T10:45:16.668Z" }, + { url = "https://files.pythonhosted.org/packages/1e/48/0cb9d43d19045b47a19a0191bca3f926ad4c47147f4b01a5c85d7d31878c/pycryptodome-4.0.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:fbf39c7f0c6fc3be114d60ebed14a8c219cd3ea19e6c4b14d16f1550d418e134", size = 1872056, upload-time = "2026-10-14T10:45:18.613Z" }, + { url = "https://files.pythonhosted.org/packages/56/ec/c874f25b18b633f4a8f27a5925237310d37dad2b975b63b2da1401d5d2d5/pycryptodome-4.0.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:3cd85d4970ddd20afb08a149cff4ca3bf606f4fe3dd245535dd079a1e752ffeb", size = 2601557, upload-time = "2026-10-14T10:45:20.79Z" }, + { url = "https://files.pythonhosted.org/packages/05/19/e103a1a7d9b1bc9bb66783be7fb77d1ee7d65e3121ca0163295696630d72/pycryptodome-4.0.0-cp39-abi3-win32.whl", hash = "sha256:fdf963015e74982507c4c09961c2ec3213afc9cd991bb1c8f875ec2caac97d37", size = 1167435, upload-time = "2026-10-14T10:45:23.205Z" }, + { url = "https://files.pythonhosted.org/packages/5a/ba/c86194cb41d374837988161242af4217db5a10c9bc93e4136373bf5c07c6/pycryptodome-4.0.0-cp39-abi3-win_amd64.whl", hash = "sha256:077819384ceb90461af9c398c1dfdb7da01a6e17b7c98817831404fb5bd93c1f", size = 1210289, upload-time = "2026-10-14T10:45:25.484Z" }, + { url = "https://files.pythonhosted.org/packages/4e/40/51a1d6234014fb8d68169cc53b44d1b315c30a261794460fef66d3df084c/pycryptodome-4.0.0-cp39-abi3-win_arm64.whl", hash = "sha256:4aea6fe5e78dda66a369d23f49fc69cfc433f8e1a1d36bda3d0466f69860ccb2", size = 1155633, upload-time = "2026-10-14T10:45:27.397Z" }, +] + +[[package]] +name = "pydantic" +version = "2.14.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "annotated-types" }, + { name = "pydantic-core" }, + { name = "typing-extensions" }, + { name = "typing-inspection" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/7c/0b/8e10b2e693af8ec54346a14caf36221334775975a747c9ceaa3f8371d96d/pydantic-2.14.1.tar.gz", hash = "sha256:94f478203dd03404682a1ada216965651dd74b1d2d5ffd62e00e0837caab5c26", size = 900362, upload-time = "2026-10-11T18:37:55.396Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/35/ea/a56b9fe5066f3537b7882f77e9c5dfb26d8c2eefdaed9b5fc73d57b4dc22/pydantic-2.14.1-py3-none-any.whl", hash = "sha256:9195d967ec791692a04438115466764fb8b9a27b31f14a760437694f40d6b454", size = 488106, upload-time = "2026-10-11T18:37:53.437Z" }, +] + +[package.optional-dependencies] +email = [ + { name = "email-validator" }, +] + +[[package]] +name = "pydantic-ai" +version = "2.56.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pydantic-ai-slim", extra = ["anthropic", "cli", "evals", "google", "logfire", "mcp", "openai", "web"] }, +] +sdist = { url = "https://files.pythonhosted.org/packages/3a/5f/ca24cdaf9ce3ae3a48f3cfba9ecb8ddc328d9304306a7d7448702406cb3a/pydantic_ai-2.56.0.tar.gz", hash = "sha256:2553f396e9478a4f0d7f60762bb7ba686837cb765310c2d8328cf56a299455a0", size = 28982, upload-time = "2026-10-13T23:50:08.741Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a6/f6/af7789327b75fadedeb3272597b52df3074bc52b86562e1384daf4ce4d1c/pydantic_ai-2.56.0-py3-none-any.whl", hash = "sha256:bbf067d794fa72031211ec1ed35f6e5fc3efa4a3a1ba655e966cb07f623f34e3", size = 10146, upload-time = "2026-10-13T23:49:55.53Z" }, +] + +[package.optional-dependencies] +ag-ui = [ + { name = "pydantic-ai-slim", extra = ["ag-ui"] }, +] +bedrock = [ + { name = "pydantic-ai-slim", extra = ["bedrock"] }, +] +cohere = [ + { name = "pydantic-ai-slim", extra = ["cohere"] }, +] +groq = [ + { name = "pydantic-ai-slim", extra = ["groq"] }, +] +huggingface = [ + { name = "pydantic-ai-slim", extra = ["huggingface"] }, +] +mistral = [ + { name = "pydantic-ai-slim", extra = ["mistral"] }, +] +retries = [ + { name = "pydantic-ai-slim", extra = ["retries"] }, +] +spec = [ + { name = "pydantic-ai-slim", extra = ["spec"] }, +] +temporal = [ + { name = "pydantic-ai-slim", extra = ["temporal"] }, +] +ui = [ + { name = "pydantic-ai-slim", extra = ["ui"] }, +] +xai = [ + { name = "pydantic-ai-slim", extra = ["xai"] }, +] + +[[package]] +name = "pydantic-ai-slim" +version = "2.56.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anyio" }, + { name = "genai-prices" }, + { name = "griffelib" }, + { name = "httpx2" }, + { name = "opentelemetry-api" }, + { name = "pydantic" }, + { name = "pydantic-graph" }, + { name = "typing-inspection" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a0/27/aa416a938b4eb29731e415c429cb5c80804ff5442e8624d5e9113fc6b2c7/pydantic_ai_slim-2.56.0.tar.gz", hash = "sha256:58e8a3381749d448a7409f6cbf7acd13fa0549fa6668aa06a13e89695fe5f6a6", size = 1883767, upload-time = "2026-10-13T23:50:12.691Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ed/68/e39e2f540e70cac0ee6b9bef3f9274c2f9e99ab7fa25bc10e04afd021c61/pydantic_ai_slim-2.56.0-py3-none-any.whl", hash = "sha256:e257196b6b6d6919e8c2d9fd02365e8ded873e99ff0d283d41c3739b0f47de99", size = 2203183, upload-time = "2026-10-13T23:50:00.72Z" }, +] + +[package.optional-dependencies] +ag-ui = [ + { name = "ag-ui-protocol" }, + { name = "starlette" }, +] +anthropic = [ + { name = "anthropic" }, +] +bedrock = [ + { name = "boto3" }, +] +cli = [ + { name = "argcomplete" }, + { name = "prompt-toolkit" }, + { name = "pyperclip" }, + { name = "pyyaml" }, + { name = "rich" }, +] +cohere = [ + { name = "cohere", marker = "sys_platform != 'emscripten'" }, +] +evals = [ + { name = "pydantic-evals" }, +] +google = [ + { name = "google-genai" }, +] +groq = [ + { name = "groq" }, +] +huggingface = [ + { name = "hf-xet", marker = "platform_machine == 'AMD64' or platform_machine == 'aarch64' or platform_machine == 'amd64' or platform_machine == 'arm64' or platform_machine == 'x86_64'" }, + { name = "huggingface-hub" }, +] +logfire = [ + { name = "logfire", extra = ["httpx"] }, + { name = "opentelemetry-instrumentation-httpx" }, +] +mcp = [ + { name = "fastmcp-slim", extra = ["client"] }, +] +mistral = [ + { name = "mistralai" }, +] +openai = [ + { name = "openai" }, + { name = "tiktoken" }, +] +retries = [ + { name = "httpx" }, + { name = "tenacity" }, +] +spec = [ + { name = "pydantic-handlebars" }, + { name = "pyyaml" }, +] +temporal = [ + { name = "temporalio" }, +] +ui = [ + { name = "starlette" }, +] +web = [ + { name = "starlette" }, + { name = "uvicorn" }, +] +xai = [ + { name = "xai-sdk" }, +] + +[[package]] +name = "pydantic-core" +version = "2.50.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a6/24/af4ec4be49fbc810f35b0bdcacc3d433b56bbfa469fd3bfd4ae116cd9bf1/pydantic_core-2.50.1.tar.gz", hash = "sha256:e50d7b94baac6c7d09927fa5ca5800a0c7ee5015c7fcff65beb3a1931b5a6e09", size = 513515, upload-time = "2026-10-11T18:35:44.82Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ae/57/0e237d7091d2cd44a35d243b7344227f90440166860469cd036afc23a04d/pydantic_core-2.50.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:d5e062c01286d861fd6a1c4ff6e063547b3e713067f2df033c0ff97ac2ca006b", size = 2222774, upload-time = "2026-10-11T18:32:43.103Z" }, + { url = "https://files.pythonhosted.org/packages/f7/b9/c720e56858d4e1539503297ed37063e0c08e0f3541c41b777f6a800f75fa/pydantic_core-2.50.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0c003c3b7f49debb893d2d85ae099ac5959c9839e2f330fadb1fcdf7a6594482", size = 2024738, upload-time = "2026-10-11T18:32:44.587Z" }, + { url = "https://files.pythonhosted.org/packages/4d/b8/fbfc25875219cc060e613170ff10e850c6d8924beb4910da57c2ee3ba1d2/pydantic_core-2.50.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:409e0ea40ec30d9158f33574fd758e689f6045a0f2596701828c27816ca9687d", size = 2047049, upload-time = "2026-10-11T18:32:46.164Z" }, + { url = "https://files.pythonhosted.org/packages/d7/43/34210124d504c553688f2f04b48500b131237528ac545b445e0d6d30e0d5/pydantic_core-2.50.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:131059670f1d2444269b8585cb888963994871932447c08b39ac6a51fcfef658", size = 2173415, upload-time = "2026-10-11T18:32:47.722Z" }, + { url = "https://files.pythonhosted.org/packages/65/cf/6e178e8fdc11da5965bef980983bf46326a42f436871dd51ba0a57f39df1/pydantic_core-2.50.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6dbcbee53bf17196a7f745aa9bf5a9603953a1e365b1f020be3207c676a3e7c4", size = 2361719, upload-time = "2026-10-11T18:32:49.217Z" }, + { url = "https://files.pythonhosted.org/packages/11/14/bd5169d356aa91bf777e28ba0b281c192d286d03c2812c9c9db023a2f00e/pydantic_core-2.50.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:325c23f3e35cfbf0fe3486fa5f7260d1e45885173002d30a28ca019994124255", size = 2439803, upload-time = "2026-10-11T18:32:51.025Z" }, + { url = "https://files.pythonhosted.org/packages/1c/bc/d79d000e5203ebef39af839f2ce77a777fcad6e08ad26af9a2fcd114ffc8/pydantic_core-2.50.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:17e722e156d0444ecaefbe640bdb60928752bf2013e2b7a11cdb099aaae19bec", size = 2158402, upload-time = "2026-10-11T18:32:52.714Z" }, + { url = "https://files.pythonhosted.org/packages/1b/a5/4902cb5fd599422c130bd3124ab31ee8b771199bd56662702eed07d3fec7/pydantic_core-2.50.1-cp313-cp313-manylinux_2_31_riscv64.whl", hash = "sha256:aa8224f10880d9bf1b5993988ba153d42a8b4f3f4f511f93b1f09c93ff613c72", size = 2229755, upload-time = "2026-10-11T18:32:54.126Z" }, + { url = "https://files.pythonhosted.org/packages/1a/f5/c1481f8669f6060d89110c9b1374173fc8767ca276b84f4870bd8acd5e3f/pydantic_core-2.50.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:41bc8237121bd8dc8d888dfd6279fc166ffc88c1f1bf3a8bf00869680533ca4c", size = 2242303, upload-time = "2026-10-11T18:32:55.641Z" }, + { url = "https://files.pythonhosted.org/packages/04/f9/77fc3c7653ba9b6e42049e17e96b25388187d4a7c274ab1cb07f58ac8419/pydantic_core-2.50.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:45c6266d071c241f2a168d45bf8c54344f0effce35e7e6b73afdec11f3687568", size = 2278345, upload-time = "2026-10-11T18:32:57.38Z" }, + { url = "https://files.pythonhosted.org/packages/95/9b/0579c5d12e7f2b16b27e6782427987341fcce07b0725e02ddb0b74add0c4/pydantic_core-2.50.1-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:1deeacb112d14d3f4fcb16b165f7dbaf76c70ba6e82f37ba042bdab51970a0b8", size = 2449947, upload-time = "2026-10-11T18:32:58.896Z" }, + { url = "https://files.pythonhosted.org/packages/a8/ac/1b677db91eba54cc5922f4de6edc46ba45c2bd712dfdc0130382d158e214/pydantic_core-2.50.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:1c96fd793b73d1b92e65570132505498fe7b21eaef73cdf74e67e5dfba7ac9e4", size = 2476889, upload-time = "2026-10-11T18:33:00.665Z" }, + { url = "https://files.pythonhosted.org/packages/4d/2a/3a9f6624ee3ea9ccba5249dde11418bb4c35780a7a92608f8768bd3fea39/pydantic_core-2.50.1-cp313-cp313-win32.whl", hash = "sha256:06ead20d39ffd6f2f6f2a8f8a6de67ff8bb1b4f14a8a30e058502514ee2ac685", size = 2101118, upload-time = "2026-10-11T18:33:02.329Z" }, + { url = "https://files.pythonhosted.org/packages/2d/1f/323f78ddd9d9938aac420c1abb4e8ba799fc8bdab0acc67c0593b837c979/pydantic_core-2.50.1-cp313-cp313-win_amd64.whl", hash = "sha256:7816e98acc08119dc0f340ab167048ecc54126316330c1f0caf7c6756c88e28f", size = 2170840, upload-time = "2026-10-11T18:33:03.919Z" }, + { url = "https://files.pythonhosted.org/packages/cb/09/8497c52a739ae425c3ac2f7f56414cbc711c67d374346174f40fe2062644/pydantic_core-2.50.1-cp313-cp313-win_arm64.whl", hash = "sha256:c17799a62c142d61b8a3c51752a7cbc87fe2ad4ccfab10e628a77b405075c662", size = 2161633, upload-time = "2026-10-11T18:33:05.518Z" }, +] + +[[package]] +name = "pydantic-evals" +version = "2.56.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anyio" }, + { name = "logfire-api" }, + { name = "pydantic" }, + { name = "pydantic-ai-slim" }, + { name = "pyyaml" }, + { name = "rich" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/af/1a/a346e1dcd180d33c641316067e641c872b4ad483793e3d6db03eed4eadfa/pydantic_evals-2.56.0.tar.gz", hash = "sha256:fdcd90326eccaffb539cb991381ea79152f792e6f6226416ee73d7fec92da18b", size = 91885, upload-time = "2026-10-13T23:50:15.654Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/17/16/2209402b932a415cf67b35af3052684afaac96539591a1ff7342dfefdb0e/pydantic_evals-2.56.0-py3-none-any.whl", hash = "sha256:d809ba1a78d21e1770525062775afe21ac627d80e4ec1ced7a584bbca077abdf", size = 107158, upload-time = "2026-10-13T23:50:04.561Z" }, +] + +[[package]] +name = "pydantic-graph" +version = "2.56.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anyio" }, + { name = "logfire-api" }, + { name = "pydantic" }, + { name = "typing-inspection" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/2c/dd/7be24637a329197e21e50a50735e9a33ede1485f9d73da6df30ca2813494/pydantic_graph-2.56.0.tar.gz", hash = "sha256:d740518239671dcc1a160a73116ca16795889b54ae5e7d6c3e98e899881fb2bf", size = 45835, upload-time = "2026-10-13T23:50:16.683Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/85/e6/8b6c4593e056f8146155fab3f2ccbda35f54f5343918ee94b48c27db5dfd/pydantic_graph-2.56.0-py3-none-any.whl", hash = "sha256:69f38003ecd20c8048d0327ee2cf5d27185eb887bb0d752e1cbed718d9836db7", size = 53280, upload-time = "2026-10-13T23:50:06.228Z" }, +] + +[[package]] +name = "pydantic-handlebars" +version = "0.2.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pydantic" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/96/73/e55a1fe1a8788a5fa82d9209e796f4111e28f2d2fecab7173aa6d80516ad/pydantic_handlebars-0.2.1.tar.gz", hash = "sha256:d4124cfbf7d6e3bded9331a08ccccf6f29f3e3a93665b35b5d6061650aeeb49f", size = 176949, upload-time = "2026-05-25T01:24:38.354Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/55/11/364bc401f1d8fdb3947079fc43ffdfbfc9132d065981a03a95d2e87440c4/pydantic_handlebars-0.2.1-py3-none-any.whl", hash = "sha256:c713427d6498cf4b66814447d54753a2748f8a8d3a9f00c194192ddb3df61e52", size = 50476, upload-time = "2026-05-25T01:24:37.104Z" }, +] + +[[package]] +name = "pydantic-settings" +version = "2.16.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pydantic" }, + { name = "python-dotenv" }, + { name = "typing-extensions" }, + { name = "typing-inspection" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/2e/3b/a5d2294799b53b448319978cfb5bd139d5a9d45e862af91661614f14c922/pydantic_settings-2.16.0.tar.gz", hash = "sha256:5b6c578049ede4db0e2ef3b4eaa4ad4069cfa9211f83fb38df899dfade50a614", size = 301031, upload-time = "2026-10-14T12:44:09.998Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/53/f4/b987bf8c51e5b19a95fa66d1ee596074141e085d9c2ddf97920803c7029b/pydantic_settings-2.16.0-py3-none-any.whl", hash = "sha256:7e73acf7f61936a15e5a3b6eedaea29f133357faf7272f2607ba479b049dd7f2", size = 80364, upload-time = "2026-10-14T12:44:08.233Z" }, +] + +[[package]] +name = "pyfly" +version = "26.6.113" +source = { git = "https://github.com/fireflyframework/fireflyframework-pyfly.git?tag=v26.06.113#332776e5a5aa67de07fbcdab938206af9c275284" } +dependencies = [ + { name = "pydantic" }, + { name = "pyyaml" }, +] + +[package.optional-dependencies] +cli = [ + { name = "click" }, + { name = "jinja2" }, + { name = "questionary" }, + { name = "rich" }, +] +client = [ + { name = "httpx" }, +] +data-relational = [ + { name = "aiosqlite" }, + { name = "alembic" }, + { name = "sqlalchemy", extra = ["asyncio"] }, +] +eda = [ + { name = "aio-pika" }, + { name = "aiokafka" }, +] +fastapi = [ + { name = "fastapi" }, +] +observability = [ + { name = "opentelemetry-api" }, + { name = "opentelemetry-instrumentation-starlette" }, + { name = "opentelemetry-sdk" }, + { name = "prometheus-client" }, + { name = "structlog" }, +] +postgresql = [ + { name = "asyncpg" }, +] +redis = [ + { name = "redis", extra = ["hiredis"] }, +] +scheduling = [ + { name = "croniter" }, +] +security = [ + { name = "bcrypt" }, + { name = "cryptography" }, + { name = "pyjwt", extra = ["crypto"] }, + { name = "pyotp" }, +] + +[[package]] +name = "pygments" +version = "2.21.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/49/2e/ced460408999b33da6b31b0021b0f37d329e202d4169aeb164493778f25b/pygments-2.21.0.tar.gz", hash = "sha256:610ca751c9bc2492b38eb9a38a7fbc93edbbb2d7182edaf34e66ae493dee5c8c", size = 5005329, upload-time = "2026-08-17T08:02:48.824Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/71/46/17f022dd3e953bf20a04a028a21ec746d942f8d2af30fa0f124fa0e6a684/pygments-2.21.0-py3-none-any.whl", hash = "sha256:2363c69b61c4a97c838da3b130dcd6468f4848992b21a82f2a63ec34377137d9", size = 1250147, upload-time = "2026-08-17T08:02:44.912Z" }, +] + +[[package]] +name = "pyjwt" +version = "2.15.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/43/ea/5194e52748b0da83d71e082d75496eaec6e58f419f5e184786ded517e6a9/pyjwt-2.15.1.tar.gz", hash = "sha256:4f259e80cdfb6b3fc18a7de51fd1ef9ec79652f25019bae68975ca2468a34df8", size = 121252, upload-time = "2026-09-28T18:40:42.598Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/50/ca/44de4e75f8aadc457f0634be3b542815078ded46dca30efb960edeecad6e/pyjwt-2.15.1-py3-none-any.whl", hash = "sha256:42d59d631f7768a1028a64c7ff581a9bf7519804daf91fc5b6c56e30eec5e193", size = 33860, upload-time = "2026-09-28T18:40:41.429Z" }, +] + +[package.optional-dependencies] +crypto = [ + { name = "cryptography" }, +] + +[[package]] +name = "pyotp" +version = "2.10.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/2d/c6/c5d96a86fd0bf6fa1bbb5c5c341ff3208638b692727a683c8289068d9a11/pyotp-2.10.0.tar.gz", hash = "sha256:d01e9703443616b03c57c700b5cbffd56a1f929c1b0f8f03131bc78c1fca9d3f", size = 18625, upload-time = "2026-06-14T03:48:49.221Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/65/33/7b83bde70eddaaaaef487751a9c3a5cc0c0be54620ded0e120ebdc401ff9/pyotp-2.10.0-py3-none-any.whl", hash = "sha256:1df2f6a1bcc3bb0716172a5215ddc2f8c7c7fd26a13df9927d52e1746934836c", size = 13768, upload-time = "2026-06-14T03:48:47.831Z" }, +] + +[[package]] +name = "pyperclip" +version = "1.11.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e8/52/d87eba7cb129b81563019d1679026e7a112ef76855d6159d24754dbd2a51/pyperclip-1.11.0.tar.gz", hash = "sha256:244035963e4428530d9e3a6101a1ef97209c6825edab1567beac148ccc1db1b6", size = 12185, upload-time = "2025-09-26T14:40:37.245Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/df/80/fc9d01d5ed37ba4c42ca2b55b4339ae6e200b456be3a1aaddf4a9fa99b8c/pyperclip-1.11.0-py3-none-any.whl", hash = "sha256:299403e9ff44581cb9ba2ffeed69c7aa96a008622ad0c46cb575ca75b5b84273", size = 11063, upload-time = "2025-09-26T14:40:36.069Z" }, +] + +[[package]] +name = "pyright" +version = "1.1.414" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "nodeenv" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e1/1b/244c7b710031ada80f27e579ec20d28a2285dfc318fed0339866b1047f12/pyright-1.1.414.tar.gz", hash = "sha256:523c0a97c60da6333234955c277730c9cf4f5bd6d5399e7b7d2b0fc5d3599524", size = 4154638, upload-time = "2026-09-10T12:26:53.181Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d7/ba/18b6e682ead424ad24bcc134339ae5d1b931cd9ae260540592a058a91279/pyright-1.1.414-py3-none-any.whl", hash = "sha256:2a6b4b3298c9eec174c5ed83bd338de6eee82df2992f3e1930e6199d381be36f", size = 6225049, upload-time = "2026-09-10T12:26:51.427Z" }, +] + +[[package]] +name = "pytest" +version = "9.1.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "iniconfig" }, + { name = "packaging" }, + { name = "pluggy" }, + { name = "pygments" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e4/47/b9efed96c114afcfa3c9d3fe98a76a1d14c74a9e266d397cf6eb64be5e01/pytest-9.1.1.tar.gz", hash = "sha256:1088fbde8f2b49d95a549a195707afa7a76a3ce9bcadc26b6d71f0ffda5fe313", size = 1636369, upload-time = "2026-06-19T10:58:32.857Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/24/25/1de2678b631f5a49215c6c96fff41ba892b0a34df68d6d80292b1b48aa7f/pytest-9.1.1-py3-none-any.whl", hash = "sha256:37a86b45efb9a47a61a36449063e8e18d0cab3161329fc099eb21783169c4f0c", size = 386536, upload-time = "2026-06-19T10:58:31.347Z" }, +] + +[[package]] +name = "pytest-asyncio" +version = "1.4.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pytest" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/43/7c/d36d04db312ecf4298932ef77e6e4a9e8ad017906e24e34f0b0c361a2473/pytest_asyncio-1.4.0.tar.gz", hash = "sha256:c6c0d2259945122819f171a32ecea2c349ead889ee28176caaf492143424be42", size = 58514, upload-time = "2026-05-26T09:56:04.083Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/03/e2/08a497ef684b88559c9cc5f4ad53a37e7b99e727094a86d6ea32536d5d3c/pytest_asyncio-1.4.0-py3-none-any.whl", hash = "sha256:933ca923a23075a87fb7070c0ec272a6848489824d887c85c812670932835aa1", size = 16930, upload-time = "2026-05-26T09:56:02.576Z" }, +] + +[[package]] +name = "pytest-cov" +version = "7.1.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "coverage" }, + { name = "pluggy" }, + { name = "pytest" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b1/51/a849f96e117386044471c8ec2bd6cfebacda285da9525c9106aeb28da671/pytest_cov-7.1.0.tar.gz", hash = "sha256:30674f2b5f6351aa09702a9c8c364f6a01c27aae0c1366ae8016160d1efc56b2", size = 55592, upload-time = "2026-03-21T20:11:16.284Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9d/7a/d968e294073affff457b041c2be9868a40c1c71f4a35fcc1e45e5493067b/pytest_cov-7.1.0-py3-none-any.whl", hash = "sha256:a0461110b7865f9a271aa1b51e516c9a95de9d696734a2f71e3e78f46e1d4678", size = 22876, upload-time = "2026-03-21T20:11:14.438Z" }, +] + +[[package]] +name = "pytest-timeout" +version = "2.4.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pytest" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ac/82/4c9ecabab13363e72d880f2fb504c5f750433b2b6f16e99f4ec21ada284c/pytest_timeout-2.4.0.tar.gz", hash = "sha256:7e68e90b01f9eff71332b25001f85c75495fc4e3a836701876183c4bcfd0540a", size = 17973, upload-time = "2025-05-05T19:44:34.99Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fa/b6/3127540ecdf1464a00e5a01ee60a1b09175f6913f0644ac748494d9c4b21/pytest_timeout-2.4.0-py3-none-any.whl", hash = "sha256:c42667e5cdadb151aeb5b26d114aff6bdf5a907f176a007a30b940d3d865b5c2", size = 14382, upload-time = "2025-05-05T19:44:33.502Z" }, +] + +[[package]] +name = "python-calamine" +version = "0.8.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e2/5e/05248d4ebdc2568b2ab0fc354ede490ddbb360e195f59442486763da4404/python_calamine-0.8.3.tar.gz", hash = "sha256:93dba488baad15bb2daed4bf45007ec550a3905aa4d39f764d1573290b72961c", size = 217244, upload-time = "2026-10-09T10:26:20.99Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/22/3a/a590db543b5a1b43a1959157474e0f2c68b5df73a21cd3b800695f96c053/python_calamine-0.8.3-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:eb5f6f4b8e34d71151a50673f3c3886051ef78749b471e35b64b95ac0530636e", size = 874493, upload-time = "2026-10-09T10:25:04.311Z" }, + { url = "https://files.pythonhosted.org/packages/f7/5a/f6456015b6ee4313cb0887fbdaabbeaebff01b53b23772da6b656e80d44c/python_calamine-0.8.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:6cbecb00dc8d7b8c892ef04458b370b815cad92dd8699f2d9b023700dd6b5170", size = 854545, upload-time = "2026-10-09T10:25:05.644Z" }, + { url = "https://files.pythonhosted.org/packages/67/91/bef5113a9fa60434be5b46cb5046c358a7338e25fe371a514158f113cf93/python_calamine-0.8.3-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:150dcd406fb54fddc0f1d92bb6e3f69bd529ec9194c90c65f160eccd11685642", size = 929200, upload-time = "2026-10-09T10:25:07.117Z" }, + { url = "https://files.pythonhosted.org/packages/68/f7/8d6b79e1abad9c60ca9f7cc36fea93856681c0c3a6b48c30be0c42420788/python_calamine-0.8.3-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:39d45c41ae34c64ccb1a8941ef8bea8b0e90e1f1047c6aa68375af403d2fdb7e", size = 921156, upload-time = "2026-10-09T10:25:08.478Z" }, + { url = "https://files.pythonhosted.org/packages/1d/11/fb8ee3c364eb866f246731d7627bae6aba1216001cd22cab84f6a4655bab/python_calamine-0.8.3-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b7540f88efacc1b9bc5f1c9554b5c313fe47f1330414984cf96baf8a4b63e44e", size = 1085303, upload-time = "2026-10-09T10:25:10.278Z" }, + { url = "https://files.pythonhosted.org/packages/e8/e0/e96dec42a7e960fa680cdea57a755dafb746c89e03efc2783446a9f89441/python_calamine-0.8.3-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a293869604990264326cd1f6c676e37a4cd9706f7702bfdfae831dfd0a6ca670", size = 995687, upload-time = "2026-10-09T10:25:11.673Z" }, + { url = "https://files.pythonhosted.org/packages/8f/1f/eca925511a8537c109c135ea32efa39de3a660b5345266ee72c0c1fc9bd1/python_calamine-0.8.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:51359906a25a8b26a225663eb1f2b026f6a5f48d4a0528f55c36677d8894727f", size = 936228, upload-time = "2026-10-09T10:25:13.161Z" }, + { url = "https://files.pythonhosted.org/packages/a1/07/cc4fd25a0b32f940d853c42a8a1b706ef5ab95a65eed9c45a69584a8bed9/python_calamine-0.8.3-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4250864419d4eb4d56e09922290d5096f546100b8ff8018f7fc2e134bd8404e6", size = 995434, upload-time = "2026-10-09T10:25:14.589Z" }, + { url = "https://files.pythonhosted.org/packages/3b/08/4ed37cdcdd1eb23d762c281cad5520981f8bef0171aab0cc4cea867e78bc/python_calamine-0.8.3-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:64621385bf9be48c3b099d7786dccefef9a67f0322ad472a7cc584081c4444a3", size = 1106621, upload-time = "2026-10-09T10:25:16.12Z" }, + { url = "https://files.pythonhosted.org/packages/95/36/1a0be1eaa7c1cad0a41916a30d30aab0043b8a531c386bfc5a4e9c81d06b/python_calamine-0.8.3-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:9e24ea2e915fdf8090016de578fd6dc5d4ea04f595ffe4b303c1397f9b721a86", size = 1195437, upload-time = "2026-10-09T10:25:17.844Z" }, + { url = "https://files.pythonhosted.org/packages/fb/dd/cd100f36c0eac21eacadf30dd1a5bdebc41c4d86c10314100277353d4b61/python_calamine-0.8.3-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:61e5f7df629310311218bee07e4a9b561432685cded1c62cdde52b3e1faeccd2", size = 1149747, upload-time = "2026-10-09T10:25:19.218Z" }, + { url = "https://files.pythonhosted.org/packages/1b/a4/50cf661d21da1464fe824e1697df7ed13e345b12a17210935dbd6de94676/python_calamine-0.8.3-cp313-cp313-win32.whl", hash = "sha256:b295527aed256557ddc1acc16cf988be6c5493cae9306c708d4e2637364702dd", size = 731532, upload-time = "2026-10-09T10:25:20.899Z" }, + { url = "https://files.pythonhosted.org/packages/48/eb/7330453d121093c0f99e028d8999a078f4be55da504276a74b2314ba7c0a/python_calamine-0.8.3-cp313-cp313-win_amd64.whl", hash = "sha256:9a81c051b40a3cd40902208b406a90248b51fb13dc60a41e514a67e0b175518c", size = 782372, upload-time = "2026-10-09T10:25:22.609Z" }, + { url = "https://files.pythonhosted.org/packages/d0/b8/97942441a5603bead41c1c00b50cb396cba1cb9ad3d594cee457872c356a/python_calamine-0.8.3-cp313-cp313-win_arm64.whl", hash = "sha256:2a9094fedab09c55b4fed4b7925c0f816fc0487af9c5de2f922b29005322cef7", size = 752178, upload-time = "2026-10-09T10:25:24.105Z" }, +] + +[[package]] +name = "python-dateutil" +version = "2.9.0.post0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "six" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/66/c0/0c8b6ad9f17a802ee498c46e004a0eb49bc148f2fd230864601a86dcf6db/python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", size = 342432, upload-time = "2024-03-01T18:36:20.211Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892, upload-time = "2024-03-01T18:36:18.57Z" }, +] + +[[package]] +name = "python-dotenv" +version = "1.2.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/74/26/2fbeedb218a787a5eea551c7532cac4e009f83d689dd2faa0d0353473f86/python_dotenv-1.2.4.tar.gz", hash = "sha256:f0d53e69935a851c0dcc78f3ab7aaccd8cabef0b92382b576b824212902873c0", size = 60824, upload-time = "2026-10-01T05:36:10Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/60/d1/38f3a3405989a89ac18390803e70c6ad7c7760da4f9b83cbeca0c44a0c72/python_dotenv-1.2.4-py3-none-any.whl", hash = "sha256:42269a8a5b3fd54ffa6f3d84b18abed50064717576b4ecf03dc4a55d8aa04fdc", size = 23266, upload-time = "2026-10-01T05:36:08.633Z" }, +] + +[[package]] +name = "python-multipart" +version = "0.0.32" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/5b/42/55c32bb9b12693c092ad250a0e82edb5b31ddeda6eb772de5f308b3804ad/python_multipart-0.0.32.tar.gz", hash = "sha256:be54b7f3fa167bb83e4fcd936b887b708f4e57fe75911c02aebf53efaf8d938e", size = 46881, upload-time = "2026-06-04T16:18:58.647Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e1/04/e8135ebd1ad02c56ec633277529b2602ff99ff634be76cdba5744cf554fd/python_multipart-0.0.32-py3-none-any.whl", hash = "sha256:ff6d3f776f16878c894e52e107296ffc890e913c611b1a4ec6c44e2821fe2e23", size = 30042, upload-time = "2026-06-04T16:18:57.319Z" }, +] + +[[package]] +name = "pywin32" +version = "312" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2d/41/12fbfd7f36ed2146d8bc9de96c2741296bf0d490b98508496cff322e274c/pywin32-312-cp313-cp313-win32.whl", hash = "sha256:7a27df850933d16a8eabfbaeb73d52b273e2da667f80d70b01a89d1f6828d02c", size = 6370184, upload-time = "2026-06-04T07:49:36.253Z" }, + { url = "https://files.pythonhosted.org/packages/ba/db/36a78e3403099d31d9746d13fdcde5accc43c1155f375a34d15983a479a7/pywin32-312-cp313-cp313-win_amd64.whl", hash = "sha256:c53e878d15a1c44788082bfe712a905433473aa38f86375b7cf8b45e3acbaaf9", size = 6914298, upload-time = "2026-06-04T07:49:38.876Z" }, + { url = "https://files.pythonhosted.org/packages/84/37/c1697194092b76de9ed47ca124323f02c57ffc8a45c06f88a3d5acaf01eb/pywin32-312-cp313-cp313-win_arm64.whl", hash = "sha256:59aba5d5940842075343a5ddc6b11f1cdf0d1567fe745290359dfbcc7c2eb831", size = 6727640, upload-time = "2026-06-04T07:49:41.083Z" }, +] + +[[package]] +name = "pywin32-ctypes" +version = "0.2.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/85/9f/01a1a99704853cb63f253eea009390c88e7131c67e66a0a02099a8c917cb/pywin32-ctypes-0.2.3.tar.gz", hash = "sha256:d162dc04946d704503b2edc4d55f3dba5c1d539ead017afa00142c38b9885755", size = 29471, upload-time = "2024-08-14T10:15:34.626Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/de/3d/8161f7711c017e01ac9f008dfddd9410dff3674334c233bde66e7ba65bbf/pywin32_ctypes-0.2.3-py3-none-any.whl", hash = "sha256:8a1513379d709975552d202d942d9837758905c8d01eb82b8bcc30918929e7b8", size = 30756, upload-time = "2024-08-14T10:15:33.187Z" }, +] + +[[package]] +name = "pyyaml" +version = "6.0.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/05/8e/961c0007c59b8dd7729d542c61a4d537767a59645b82a0b521206e1e25c2/pyyaml-6.0.3.tar.gz", hash = "sha256:d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f", size = 130960, upload-time = "2025-09-25T21:33:16.546Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/11/0fd08f8192109f7169db964b5707a2f1e8b745d4e239b784a5a1dd80d1db/pyyaml-6.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8da9669d359f02c0b91ccc01cac4a67f16afec0dac22c2ad09f46bee0697eba8", size = 181669, upload-time = "2025-09-25T21:32:23.673Z" }, + { url = "https://files.pythonhosted.org/packages/b1/16/95309993f1d3748cd644e02e38b75d50cbc0d9561d21f390a76242ce073f/pyyaml-6.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2283a07e2c21a2aa78d9c4442724ec1eb15f5e42a723b99cb3d822d48f5f7ad1", size = 173252, upload-time = "2025-09-25T21:32:25.149Z" }, + { url = "https://files.pythonhosted.org/packages/50/31/b20f376d3f810b9b2371e72ef5adb33879b25edb7a6d072cb7ca0c486398/pyyaml-6.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee2922902c45ae8ccada2c5b501ab86c36525b883eff4255313a253a3160861c", size = 767081, upload-time = "2025-09-25T21:32:26.575Z" }, + { url = "https://files.pythonhosted.org/packages/49/1e/a55ca81e949270d5d4432fbbd19dfea5321eda7c41a849d443dc92fd1ff7/pyyaml-6.0.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a33284e20b78bd4a18c8c2282d549d10bc8408a2a7ff57653c0cf0b9be0afce5", size = 841159, upload-time = "2025-09-25T21:32:27.727Z" }, + { url = "https://files.pythonhosted.org/packages/74/27/e5b8f34d02d9995b80abcef563ea1f8b56d20134d8f4e5e81733b1feceb2/pyyaml-6.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0f29edc409a6392443abf94b9cf89ce99889a1dd5376d94316ae5145dfedd5d6", size = 801626, upload-time = "2025-09-25T21:32:28.878Z" }, + { url = "https://files.pythonhosted.org/packages/f9/11/ba845c23988798f40e52ba45f34849aa8a1f2d4af4b798588010792ebad6/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f7057c9a337546edc7973c0d3ba84ddcdf0daa14533c2065749c9075001090e6", size = 753613, upload-time = "2025-09-25T21:32:30.178Z" }, + { url = "https://files.pythonhosted.org/packages/3d/e0/7966e1a7bfc0a45bf0a7fb6b98ea03fc9b8d84fa7f2229e9659680b69ee3/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:eda16858a3cab07b80edaf74336ece1f986ba330fdb8ee0d6c0d68fe82bc96be", size = 794115, upload-time = "2025-09-25T21:32:31.353Z" }, + { url = "https://files.pythonhosted.org/packages/de/94/980b50a6531b3019e45ddeada0626d45fa85cbe22300844a7983285bed3b/pyyaml-6.0.3-cp313-cp313-win32.whl", hash = "sha256:d0eae10f8159e8fdad514efdc92d74fd8d682c933a6dd088030f3834bc8e6b26", size = 137427, upload-time = "2025-09-25T21:32:32.58Z" }, + { url = "https://files.pythonhosted.org/packages/97/c9/39d5b874e8b28845e4ec2202b5da735d0199dbe5b8fb85f91398814a9a46/pyyaml-6.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:79005a0d97d5ddabfeeea4cf676af11e647e41d81c9a7722a193022accdb6b7c", size = 154090, upload-time = "2025-09-25T21:32:33.659Z" }, + { url = "https://files.pythonhosted.org/packages/73/e8/2bdf3ca2090f68bb3d75b44da7bbc71843b19c9f2b9cb9b0f4ab7a5a4329/pyyaml-6.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:5498cd1645aa724a7c71c8f378eb29ebe23da2fc0d7a08071d89469bf1d2defb", size = 140246, upload-time = "2025-09-25T21:32:34.663Z" }, +] + +[[package]] +name = "questionary" +version = "2.1.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "prompt-toolkit" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f6/45/eafb0bba0f9988f6a2520f9ca2df2c82ddfa8d67c95d6625452e97b204a5/questionary-2.1.1.tar.gz", hash = "sha256:3d7e980292bb0107abaa79c68dd3eee3c561b83a0f89ae482860b181c8bd412d", size = 25845, upload-time = "2025-08-28T19:00:20.851Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3c/26/1062c7ec1b053db9e499b4d2d5bc231743201b74051c973dadeac80a8f43/questionary-2.1.1-py3-none-any.whl", hash = "sha256:a51af13f345f1cdea62347589fbb6df3b290306ab8930713bfae4d475a7d4a59", size = 36753, upload-time = "2025-08-28T19:00:19.56Z" }, +] + +[[package]] +name = "redis" +version = "8.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a8/99/604f0b666d4c616d891cf77ebb9db6bb21601344c051aebf1b72b9ff915f/redis-8.1.0.tar.gz", hash = "sha256:6e1a19beef9225c83efd689c7e6b7da2d5215b1f42cd13b7fc3714d0a09c7b25", size = 5254356, upload-time = "2026-07-30T08:51:00.269Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/66/9d/c5731f6e3608663d4d3656fd8d3aecee8b509c3082818f5a13eae925baea/redis-8.1.0-py3-none-any.whl", hash = "sha256:a4fe1aac3d3b3cc791d4b3d5931c5a956045dc951ee74d1c913ee3ac4d2ee9fb", size = 560618, upload-time = "2026-07-30T08:50:58.497Z" }, +] + +[package.optional-dependencies] +hiredis = [ + { name = "hiredis" }, +] + +[[package]] +name = "referencing" +version = "0.37.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "attrs" }, + { name = "rpds-py" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/22/f5/df4e9027acead3ecc63e50fe1e36aca1523e1719559c499951bb4b53188f/referencing-0.37.0.tar.gz", hash = "sha256:44aefc3142c5b842538163acb373e24cce6632bd54bdb01b21ad5863489f50d8", size = 78036, upload-time = "2025-10-13T15:30:48.871Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2c/58/ca301544e1fa93ed4f80d724bf5b194f6e4b945841c5bfd555878eea9fcb/referencing-0.37.0-py3-none-any.whl", hash = "sha256:381329a9f99628c9069361716891d34ad94af76e461dcb0335825aecc7692231", size = 26766, upload-time = "2025-10-13T15:30:47.625Z" }, +] + +[[package]] +name = "regex" +version = "2026.9.29" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/fc/f2/af1da9d3ceed77bfcdce40427d49ba0be94e4fe84245e3bfef68c10e75b6/regex-2026.9.29.tar.gz", hash = "sha256:8b5fcc4771732191b2b7d1dd68d8f0353f47f8d90b6150f6dce58bf1112442cb", size = 419199, upload-time = "2026-09-29T00:49:58.298Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/79/d5/6080f7d1a6e7e36aa720f806ac93c035ba39c209ae6cc510e8ef4c0279c6/regex-2026.9.29-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:f1a0d5117230dd46b399a30a38afa44f79c99f3168988fdc4f425c3f928b39df", size = 497622, upload-time = "2026-09-29T00:47:08.251Z" }, + { url = "https://files.pythonhosted.org/packages/00/71/c87fc7a2e21a42f9d57489db32951c37eef56d153840459a80d464f0321d/regex-2026.9.29-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f0fe9834e5aeccaf19a0d8feb296d66a24be1a7c9922002f842a682cd5abb787", size = 296281, upload-time = "2026-09-29T00:47:09.764Z" }, + { url = "https://files.pythonhosted.org/packages/11/9e/aa0f4cde3bc4688c1d58b0cd8415edd708339bc0bc401a195b0b1e8c8f0c/regex-2026.9.29-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:c90fcf7804ea0a54b896ce0f2b9565350220b8d4890fd0db461a476a4c687963", size = 293472, upload-time = "2026-09-29T00:47:11.723Z" }, + { url = "https://files.pythonhosted.org/packages/90/d4/e835c487850ed922a8d6074f953b888c8ea99775c76b9ed5f8a4d72eab92/regex-2026.9.29-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e11edba5bc344a32b029a7af9d4b3173982dd79eeafa0b9dbd787364414b0509", size = 805966, upload-time = "2026-09-29T00:47:13.235Z" }, + { url = "https://files.pythonhosted.org/packages/2c/57/ba8809847fbae8d2cbc71367c6ded510a7ec88bf52493c65efc1acf4effb/regex-2026.9.29-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:bb90e7177944b6684738c1fc36aabd2dd00d1de3be7dbe09f91e196f1bc0dc81", size = 878346, upload-time = "2026-09-29T00:47:14.877Z" }, + { url = "https://files.pythonhosted.org/packages/1a/52/e3da19fc3cc15ef67ab67e121e87887c3bccfdb683a7a9ec557c460ca5b7/regex-2026.9.29-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d06fcdecc10fc7954d7c8f27a03c96055fe525274dc84a7b0dbdc3d6b9e03dab", size = 919250, upload-time = "2026-09-29T00:47:16.622Z" }, + { url = "https://files.pythonhosted.org/packages/9a/8e/c1ed81f55f992f6aa0b699a592a50c1ce9e6d44ff1aee2c14c0537dcef9c/regex-2026.9.29-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d49c18f1ea294cf4adde2e5ac256e98c82ea9d708462ce4bf799dffa7cfe8a2c", size = 807902, upload-time = "2026-09-29T00:47:18.268Z" }, + { url = "https://files.pythonhosted.org/packages/ad/bc/5a6886eb470e41040e21e05b75024a18b6ebfe7ea400b72094a60f949101/regex-2026.9.29-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:3e778bfccd63075167709136afbc251c1f683758d5bf49c803c60ac3f894ce6b", size = 783514, upload-time = "2026-09-29T00:47:19.921Z" }, + { url = "https://files.pythonhosted.org/packages/cb/52/6d951d453b023c6edb880f1ba474291b53b8ce1cc438b96a9db6d791d991/regex-2026.9.29-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:686ac5350fceae63830bb98805fcb8039325bf4c06d9f6f048ff65229d5bffa5", size = 793466, upload-time = "2026-09-29T00:47:21.552Z" }, + { url = "https://files.pythonhosted.org/packages/99/b9/d5a41adc08360f5eee0dc4846c578f002366947211fc8af5a69a64ee7b9f/regex-2026.9.29-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:26ec4ccce55aa533fbd603d08911b01101a8fcfec987845ac3ae2c7087b2bde3", size = 869464, upload-time = "2026-09-29T00:47:23.276Z" }, + { url = "https://files.pythonhosted.org/packages/4b/32/d76c9d91f5d798e2e9e67f6f85ec4ae35445ac425f7454797311cecb80ca/regex-2026.9.29-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:a655d34b2a6943af32401f3d94f72e9d731f6ad16285815550bf2b4ee69d420a", size = 770278, upload-time = "2026-09-29T00:47:25.193Z" }, + { url = "https://files.pythonhosted.org/packages/24/00/aeebdb540c620a0f7317f6d6fad80a47729ecf0599a24b5c34ec155351f5/regex-2026.9.29-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:0c992c19cd45058a4b92f68f139c93db168b48fb1f322c9a7cd620806afb6b51", size = 861949, upload-time = "2026-09-29T00:47:27.005Z" }, + { url = "https://files.pythonhosted.org/packages/12/62/d0314bcedfd3586197e4596931fa220260eb2385bf53184e5b9ae67db24b/regex-2026.9.29-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ebb8912f565b8cdbbf27debfe00df04202c20e2f651b9e32767930c5eace3621", size = 796602, upload-time = "2026-09-29T00:47:29.233Z" }, + { url = "https://files.pythonhosted.org/packages/ae/c7/d5a8c13a613facb03e0fb55c1ebaaf7bb35d8e2c1abe8bef8dca809fc1d9/regex-2026.9.29-cp313-cp313-win32.whl", hash = "sha256:4d7d93613b01b0199961330e49cfc52d479b3d5776c56c691db31130c0a07d91", size = 269306, upload-time = "2026-09-29T00:47:31.14Z" }, + { url = "https://files.pythonhosted.org/packages/80/a7/bf93a3a6afa5f7bc16b7afb94ae581b01cae620b8ad56bd8f9572a985959/regex-2026.9.29-cp313-cp313-win_amd64.whl", hash = "sha256:61956f074ecd123f55adca68ee3eab46e6a07ad3f8e64e6db95dfacb444f55c4", size = 280307, upload-time = "2026-09-29T00:47:32.709Z" }, + { url = "https://files.pythonhosted.org/packages/b2/7d/388274e53605a86297f433a08102a7bbdcf9379d47683d307ccaefd88e2c/regex-2026.9.29-cp313-cp313-win_arm64.whl", hash = "sha256:bfc71e6d970419c1309b3640305298643e2a734cad3f7cfb6d2ddee4175ab53d", size = 279599, upload-time = "2026-09-29T00:47:34.674Z" }, +] + +[[package]] +name = "requests" +version = "2.34.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "certifi" }, + { name = "charset-normalizer" }, + { name = "idna" }, + { name = "urllib3" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ac/c3/e2a2b89f2d3e2179abd6d00ebd70bff6273f37fb3e0cc209f48b39d00cbf/requests-2.34.2.tar.gz", hash = "sha256:f288924cae4e29463698d6d60bc6a4da69c89185ad1e0bcc4104f584e960b9ed", size = 142856, upload-time = "2026-05-14T19:25:27.735Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a0/f4/c67b0b3f1b9245e8d266f0f112c500d50e5b4e83cb6f3b71b6528104182a/requests-2.34.2-py3-none-any.whl", hash = "sha256:2a0d60c172f83ac6ab31e4554906c0f3b3588d37b5cb939b1c061f4907e278e0", size = 73075, upload-time = "2026-05-14T19:25:26.443Z" }, +] + +[[package]] +name = "requests-file" +version = "3.0.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "requests" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/3c/f8/5dc70102e4d337063452c82e1f0d95e39abfe67aa222ed8a5ddeb9df8de8/requests_file-3.0.1.tar.gz", hash = "sha256:f14243d7796c588f3521bd423c5dea2ee4cc730e54a3cac9574d78aca1272576", size = 6967, upload-time = "2025-10-20T18:56:42.279Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e1/d5/de8f089119205a09da657ed4784c584ede8381a0ce6821212a6d4ca47054/requests_file-3.0.1-py2.py3-none-any.whl", hash = "sha256:d0f5eb94353986d998f80ac63c7f146a307728be051d4d1cd390dbdb59c10fa2", size = 4514, upload-time = "2025-10-20T18:56:41.184Z" }, +] + +[[package]] +name = "respx" +version = "0.23.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "httpx" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/43/98/4e55c9c486404ec12373708d015ebce157966965a5ebe7f28ff2c784d41b/respx-0.23.1.tar.gz", hash = "sha256:242dcc6ce6b5b9bf621f5870c82a63997e8e82bc7c947f9ffe272b8f3dd5a780", size = 29243, upload-time = "2026-04-08T14:37:16.008Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1d/4a/221da6ca167db45693d8d26c7dc79ccfc978a440251bf6721c9aaf251ac0/respx-0.23.1-py2.py3-none-any.whl", hash = "sha256:b18004b029935384bccfa6d7d9d74b4ec9af73a081cc28600fffc0447f4b8c1a", size = 25557, upload-time = "2026-04-08T14:37:14.613Z" }, +] + +[[package]] +name = "rich" +version = "15.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markdown-it-py" }, + { name = "pygments" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c0/8f/0722ca900cc807c13a6a0c696dacf35430f72e0ec571c4275d2371fca3e9/rich-15.0.0.tar.gz", hash = "sha256:edd07a4824c6b40189fb7ac9bc4c52536e9780fbbfbddf6f1e2502c31b068c36", size = 230680, upload-time = "2026-04-12T08:24:00.75Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/82/3b/64d4899d73f91ba49a8c18a8ff3f0ea8f1c1d75481760df8c68ef5235bf5/rich-15.0.0-py3-none-any.whl", hash = "sha256:33bd4ef74232fb73fe9279a257718407f169c09b78a87ad3d296f548e27de0bb", size = 310654, upload-time = "2026-04-12T08:24:02.83Z" }, +] + +[[package]] +name = "rpds-py" +version = "2026.9.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/42/68/3bd46b8a5e01d3c2ebdf9c5e9497912e3fe0cde02bac21a7130ca866e403/rpds_py-2026.9.1.tar.gz", hash = "sha256:4793ef7f78268b124b73fa933440f01d258bbae01de9fa53e9080c9ab0425a12", size = 63948, upload-time = "2026-10-04T16:32:36.469Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/83/ea/ee88fd9e756ff93fb6b1182a47ec09504a242620e33ce1d20679efefe841/rpds_py-2026.9.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:a36b70596407634ca82d4b989a3729074a008537a0522e4c8046a67c729103e9", size = 346229, upload-time = "2026-10-04T16:29:38.82Z" }, + { url = "https://files.pythonhosted.org/packages/57/71/a097d6552f837500fc36e6b23d09cfb9890c3cc47531f9ca64e149799615/rpds_py-2026.9.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:eba5d173f7d5708b22a93815017a4611873ed54db9f268077c0dd1ed99cfc858", size = 340514, upload-time = "2026-10-04T16:29:40.405Z" }, + { url = "https://files.pythonhosted.org/packages/bd/b7/497e85768bf4e0d8ddbaa096a4cac31d1509251dee2728a8490aa367e0b5/rpds_py-2026.9.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:457866b85daf5034296666168b84a69e0b2e89dc4f1af102b46f6448a60b9063", size = 372611, upload-time = "2026-10-04T16:29:41.778Z" }, + { url = "https://files.pythonhosted.org/packages/52/4b/74ab4108916250b6e198e0d3af05bc6835eb046315f22f7a0ceb49667c5a/rpds_py-2026.9.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a3a52a3ba86436ab3aef510fbe21512abc2ddd1993005dfe50514bd2284ef025", size = 377712, upload-time = "2026-10-04T16:29:43.242Z" }, + { url = "https://files.pythonhosted.org/packages/0c/8e/067e77d9d7b3cc793c9d909b7e97e7aadbbb1fb094093b6876902cc96d38/rpds_py-2026.9.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d7841166b7fa64c9c56404617ae4341448847482d45933b13135d26c130519e5", size = 488106, upload-time = "2026-10-04T16:29:44.692Z" }, + { url = "https://files.pythonhosted.org/packages/3c/b4/c5aae6c2dde269bf955f6b7d35065c655a57e47750d9668052ad67e74dda/rpds_py-2026.9.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:926bdd3e3b5998ddf70cc64bc8cf57209571f9044542913afb673799fec77dd0", size = 390795, upload-time = "2026-10-04T16:29:46.129Z" }, + { url = "https://files.pythonhosted.org/packages/a0/36/76fab39973ee11e7f9f357c55138197bb01c86f6502cb76487e3b4f42db0/rpds_py-2026.9.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7868b85224291c6cb6759f9b5adb9745f486d226f62b16a614dd5a2a5ab2b35b", size = 370794, upload-time = "2026-10-04T16:29:47.603Z" }, + { url = "https://files.pythonhosted.org/packages/3d/fe/cd2a80e6d7b871937a60e935c5d507aa390d143f4ff3636f640b9733d5df/rpds_py-2026.9.1-cp313-cp313-manylinux_2_31_riscv64.whl", hash = "sha256:3cd182d7291d29b92c521a0069d9c01ba6193628a9a105531d11b40a6d731a33", size = 375673, upload-time = "2026-10-04T16:29:49.223Z" }, + { url = "https://files.pythonhosted.org/packages/6c/18/7464a9953724e55a3b3206062fa0ffdeaa519584c6aabf65d3956d94f131/rpds_py-2026.9.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e6ea1cda8d8c688278430e4268a42f5e5da3bdd74578dfadc0820c3f1766ce83", size = 398758, upload-time = "2026-10-04T16:29:50.601Z" }, + { url = "https://files.pythonhosted.org/packages/c0/86/1534b436700fd49ff411063b7c4d7e938adfabf90895b6cf1622d5a7d1f6/rpds_py-2026.9.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:5943980471829f6de242a20b109de3111ba6b77e3af0ffc587028ac854b05e6c", size = 550370, upload-time = "2026-10-04T16:29:52.002Z" }, + { url = "https://files.pythonhosted.org/packages/57/1c/e1fa82a8a01e3c5820f3ba98a8b2673f642128eb368fa88871b01dd2c909/rpds_py-2026.9.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:76d3af9732d2dab69f28179b40ba2d87e2f1d5824b4a694780aa787d685e8f36", size = 613106, upload-time = "2026-10-04T16:29:53.655Z" }, + { url = "https://files.pythonhosted.org/packages/29/55/b20b8c4c3dde8755bfcd5b08492a02d0cd2e26929aedf6199ca2a377d42a/rpds_py-2026.9.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:78326f4cb4427a56ba4996c0762b63be45f06b85f086526420d2b3a66e40f84d", size = 578235, upload-time = "2026-10-04T16:29:55.157Z" }, + { url = "https://files.pythonhosted.org/packages/55/42/df3f7bbc3f7ab37a8a9db8d6c2ff2c985422899f1f7926afbf7ec3c0b8b4/rpds_py-2026.9.1-cp313-cp313-win32.whl", hash = "sha256:172e47169583f46ce118cbec68e6795d0da0f4606b488b6434f8276bca0a058c", size = 205293, upload-time = "2026-10-04T16:29:56.669Z" }, + { url = "https://files.pythonhosted.org/packages/31/9c/ba5a9569d719bfdd6ce863df4133ac6a1658cf1b07cc3534c31db729fbbc/rpds_py-2026.9.1-cp313-cp313-win_amd64.whl", hash = "sha256:3e93b2cd69a9830be33e03945cd7cda940a0a8bfcfbff41d6144f0cb0d3d8bd9", size = 222409, upload-time = "2026-10-04T16:29:58.049Z" }, + { url = "https://files.pythonhosted.org/packages/35/72/f28ca566f6c23c35bbf7445f65eb0364577b25a026305995e24f78b83d94/rpds_py-2026.9.1-cp313-cp313-win_arm64.whl", hash = "sha256:d151e148117294133bf8af7eeace085e7e87432db15ab6adf640330298a47f6f", size = 217681, upload-time = "2026-10-04T16:29:59.449Z" }, +] + +[[package]] +name = "ruff" +version = "0.17.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e9/a7/70debb024dfacda67b8e560cc7511f52b34b9348a8cc8c1ec23036dcd51d/ruff-0.17.0.tar.gz", hash = "sha256:5cd03240d8208a557c2a9655a5cb07ebe36aa6bb35065f97d48c1f6adef5a322", size = 5320554, upload-time = "2026-10-09T19:47:29.248Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/bc/f8/ee5ab9da6089eae2a33e6008b01deb1eda19992c1c8e10661e98cee1640f/ruff-0.17.0-py3-none-linux_armv6l.whl", hash = "sha256:0e271826af9a20d18c6cfae8c51e82959167c24859686ddd3eb9a7f0842ce81e", size = 10148907, upload-time = "2026-10-09T19:46:38.695Z" }, + { url = "https://files.pythonhosted.org/packages/9f/d9/2f81fb5a9d580afbb11b1c8ff915233a11f2a1b27405d7991f183c5e1976/ruff-0.17.0-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:5f0ca4a40f81403689c04f12966e22f44e329ae362072d8f1587b7bda87f603b", size = 10224208, upload-time = "2026-10-09T19:46:41.711Z" }, + { url = "https://files.pythonhosted.org/packages/a7/20/643f3c8f75594f937b2bf74801241c56a2e2b8e139d24dff8b66b28cdd7f/ruff-0.17.0-py3-none-macosx_11_0_arm64.whl", hash = "sha256:cbf7149e0927dc3295d5d64679a4765576eef71b00782b2ae969ef82274d6bb9", size = 9273324, upload-time = "2026-10-09T19:46:44.323Z" }, + { url = "https://files.pythonhosted.org/packages/ec/91/627700b233d367736cb274f1bd0b47d1f2b12f68878192812bd875adadc3/ruff-0.17.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:13ee90156522998c3037059d8f66885c8adeeaf7643bdce2caceee196ecd23e0", size = 9953190, upload-time = "2026-10-09T19:46:47.155Z" }, + { url = "https://files.pythonhosted.org/packages/cd/92/91f7b5ed39490f89d6cbf56e1f543c383667a725efa8e2c2dee0f01f5591/ruff-0.17.0-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3d8e4a002a94cd9d0dc48b51dc69d807a172b5b9bf2b668e656424dc5b55ead1", size = 9961746, upload-time = "2026-10-09T19:46:50.098Z" }, + { url = "https://files.pythonhosted.org/packages/87/c5/7310f9fc63ce11ff6394edbd5e85433dfb0e14c9fbf6ccc97f1538491bc7/ruff-0.17.0-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c0b8a60c06a218c337e1161638d34757f83449243e2db161483ddf948e53ad14", size = 10625483, upload-time = "2026-10-09T19:46:53.379Z" }, + { url = "https://files.pythonhosted.org/packages/a5/8d/97443f0dca4a03a0bc7629fd396fd494a1cb6666121e38c5075acb217d8f/ruff-0.17.0-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a330178bdffc4205dbf3bda11d93e059e388fd6546f8cdd304501a9160363c0d", size = 11350129, upload-time = "2026-10-09T19:46:56.486Z" }, + { url = "https://files.pythonhosted.org/packages/9c/0a/c525efd9777be4b6b012e6969a3012648468e7e6c4b3e5b46af69f46e8eb/ruff-0.17.0-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7bb08489e234876fa2da67ae3ea938e9a2156da80293e0e4365abd6973d98329", size = 10906223, upload-time = "2026-10-09T19:47:00.263Z" }, + { url = "https://files.pythonhosted.org/packages/2c/3c/4a01195d93420cad1175bedad13a515dc8a56f95a6e39789b92e582682f5/ruff-0.17.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc73e7c133e82d55b5f15897b2a442d72c0cb4a0c886c46801ce3c247150b60c", size = 10386314, upload-time = "2026-10-09T19:47:03.057Z" }, + { url = "https://files.pythonhosted.org/packages/c7/72/1a3951665485a921f6375f91e754a1854d5a645d41acc3642668064ff64d/ruff-0.17.0-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:db4f74c533403ab70fe4007873f6ae0c9f94a8b03158cf48d78788e47cdbe399", size = 10565464, upload-time = "2026-10-09T19:47:05.831Z" }, + { url = "https://files.pythonhosted.org/packages/90/8c/539b4d8c082f57e18db8ae2be85a460d77861c79dcd5798e32b536a6a06f/ruff-0.17.0-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:3d8cc360e666d1914e47b0777c6906d70cf18891a55532bd0a16844195d70859", size = 10079468, upload-time = "2026-10-09T19:47:08.617Z" }, + { url = "https://files.pythonhosted.org/packages/e0/b8/84286966db79434e8c26b585b0a0f6897cb3ab1c51a4aa4df10c28488b62/ruff-0.17.0-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:d66de796b726c4801e05fa99a2a8d7a780e107be222486c304ab61765561e866", size = 9958556, upload-time = "2026-10-09T19:47:11.324Z" }, + { url = "https://files.pythonhosted.org/packages/69/50/27b6eed27b83fcdd5bfa0d52b83231e29094754374698da404d094487ae3/ruff-0.17.0-py3-none-musllinux_1_2_i686.whl", hash = "sha256:c3f268baf004aea944f040623327119527ea231af15f7fb7890e82cea0679589", size = 10352173, upload-time = "2026-10-09T19:47:14.188Z" }, + { url = "https://files.pythonhosted.org/packages/2a/fa/955399fd13044cd827862044117d784a59e3196f6cce7424908ac9a7f914/ruff-0.17.0-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:864b6c1acb6b0bccf94b5a3938a1531fd09aaca5e5659a2e7bf0f3cf2a685540", size = 10791761, upload-time = "2026-10-09T19:47:16.931Z" }, + { url = "https://files.pythonhosted.org/packages/ae/bf/024e01e1f6aec87768696725e648ed5b438941341eea8f8100beb681961f/ruff-0.17.0-py3-none-win32.whl", hash = "sha256:5e50aa5b84decd9fe5b0bb0e6f71c3b592f1767ed09faa4b7207d933961e35cd", size = 9904112, upload-time = "2026-10-09T19:47:19.75Z" }, + { url = "https://files.pythonhosted.org/packages/cc/77/1ee73df41dcc8d1cdb686ee4bc46ea29704ea175feb6b95c78420f631ab8/ruff-0.17.0-py3-none-win_amd64.whl", hash = "sha256:8ab76bcda86dfd28e13776cb5de3c7bcdcf1ae3d37ed761113d1a5a415dc134c", size = 10115585, upload-time = "2026-10-09T19:47:22.698Z" }, + { url = "https://files.pythonhosted.org/packages/fd/71/eb4f0ccc844aece56963e8578df9c95d4c00f580547d52329d4035d3af18/ruff-0.17.0-py3-none-win_arm64.whl", hash = "sha256:c154c73ff43f9854395e24cac507af13078962e53d2b511605058d22af1fdb88", size = 9872035, upload-time = "2026-10-09T19:47:26.306Z" }, +] + +[[package]] +name = "s3transfer" +version = "0.19.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "botocore" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/76/43/35e4d8aa320bffe8287fe8f65f578fa2d2db0a64212f0e710dce58267854/s3transfer-0.19.2.tar.gz", hash = "sha256:ba0309fd86be3c27dbf78cdd813c13c5e1df16e5874b99d2535ebbdfb9892993", size = 165592, upload-time = "2026-07-22T19:30:44.432Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/bc/e7/5c595c75e9f41a44f30e526eda465ea0b4eec93470e074e4a111b253f13a/s3transfer-0.19.2-py3-none-any.whl", hash = "sha256:d8168eccca828cbb2cd573675333f3bddd254313a9c42494b84c76b539e8ba25", size = 90216, upload-time = "2026-07-22T19:30:43.251Z" }, +] + +[[package]] +name = "safetensors" +version = "0.8.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/45/06/f955dbbb1859e3bd23c8ac6141af5106e7ad5fedec4a3a6e3d60f94b7001/safetensors-0.8.0.tar.gz", hash = "sha256:fabaf3e0f18a6618d9b36560682562157f77c2b71fcffc7b432be2baed9d753d", size = 325846, upload-time = "2026-06-09T07:52:25.563Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/39/a0/f718cda65b05407d228f97602cf60dca269c979867aa5beb25410de26cd3/safetensors-0.8.0-cp310-abi3-macosx_10_12_x86_64.whl", hash = "sha256:c554f85858e05226d3c2828e32395e677434685d6d94594a41643361c5e837f0", size = 473568, upload-time = "2026-06-09T07:52:18.829Z" }, + { url = "https://files.pythonhosted.org/packages/f5/b1/fa7c600e7dceae12e9606c7578cbc9ff1e1ed55844883ee5c92205e86226/safetensors-0.8.0-cp310-abi3-macosx_11_0_arm64.whl", hash = "sha256:c80201d22cbf405b80647a60ada77bba06c8fba2da2743ba1e89cdcc39a81f25", size = 484562, upload-time = "2026-06-09T07:52:17.518Z" }, + { url = "https://files.pythonhosted.org/packages/09/7d/65a7de0af421317bb36a067241e4235fff194eed60b961ed6d3f59a3fc60/safetensors-0.8.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7a46e5ff292c356d6991e60942ba7f79817682d3a2cef0702136448cb9c4d235", size = 502844, upload-time = "2026-06-09T07:52:07.624Z" }, + { url = "https://files.pythonhosted.org/packages/91/4f/3175c9d75634e0e0dda0082794193521035edd7c70a6f212bf33ca06ddf4/safetensors-0.8.0-cp310-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4124502b78f03534117c848f87a39b8f31e577b15eff423bf8bfb95f2a8c30d0", size = 511823, upload-time = "2026-06-09T07:52:09.565Z" }, + { url = "https://files.pythonhosted.org/packages/20/87/846c289e7aa2299eff406335717cf43ce8777194ece8aad75772e0411615/safetensors-0.8.0-cp310-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7bc0a787ba8a35be368ee3574edfa2b1ad389eebd0a72e482ae275490e3f6c98", size = 633461, upload-time = "2026-06-09T07:52:11.128Z" }, + { url = "https://files.pythonhosted.org/packages/76/22/8d64d9df2c45d5ded401df889d0ad90882804ca172d79ec4f0df8f727fe0/safetensors-0.8.0-cp310-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:040070828e36dc8e122178bbbd5830ff9e97920affb84cbe0f46442497bed358", size = 545148, upload-time = "2026-06-09T07:52:13.603Z" }, + { url = "https://files.pythonhosted.org/packages/28/50/f203ff3a3ddfe19308efc83c5a3a29ed02bf786732ec35e68bf9162f3365/safetensors-0.8.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd6f3f93c9a0a7cc2788ee63fb763353d4bd2e89b0751bc78fcf7dda00bea774", size = 516040, upload-time = "2026-06-09T07:52:16.29Z" }, + { url = "https://files.pythonhosted.org/packages/46/fb/cdaed17ceb2948784fd9c36b6fd3e951b608547cea81a48e8ee6f8cfdfcb/safetensors-0.8.0-cp310-abi3-manylinux_2_31_riscv64.whl", hash = "sha256:fcdd41ec4628fee5799f807c73c353629130fbd942aa23d83c623dd6c9d52d78", size = 513832, upload-time = "2026-06-09T07:52:12.37Z" }, + { url = "https://files.pythonhosted.org/packages/0d/49/1e15de264dcc3b77943d2d0c56a95809956883b1c2d6d585c792523f180b/safetensors-0.8.0-cp310-abi3-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8e9f537aa183a38ace122d27303dcd986b26bd2a7591f9181d7f0c396f4677ca", size = 559930, upload-time = "2026-06-09T07:52:14.743Z" }, + { url = "https://files.pythonhosted.org/packages/2a/43/bf38443278eab4b1be1fce2931e2b012ad9cb7df52ada751d0aab8f7659a/safetensors-0.8.0-cp310-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:87eec7ffed2b809f05a398a8becb7d013f19f7837cd15d9748580d6cf30dbaf4", size = 678670, upload-time = "2026-06-09T07:52:20.032Z" }, + { url = "https://files.pythonhosted.org/packages/72/e3/68cd3fa5b48488e84add63e04cb12f3bc28ae4638c06d4508c6e88823d0e/safetensors-0.8.0-cp310-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:4a95ae2b05d7726d751da4ebf626a2ca782b706e101bd894c95bc2450b1cffcc", size = 786679, upload-time = "2026-06-09T07:52:21.322Z" }, + { url = "https://files.pythonhosted.org/packages/29/4b/1c19c509d56e01f4fbb3d0a2e597450f6cc04d1d56cf52defb0a62dfd715/safetensors-0.8.0-cp310-abi3-musllinux_1_2_i686.whl", hash = "sha256:3ae091f16662658bdc019a4ff6cb4c085bb7d725eb5978b183ffd265863b6d2d", size = 765683, upload-time = "2026-06-09T07:52:22.594Z" }, + { url = "https://files.pythonhosted.org/packages/27/43/41c1621732edd934d868a00d1b891584c892a7b62a9aab82ea5a0a5623ee/safetensors-0.8.0-cp310-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:8e080062fcde23be189565e1c3305d16751a218ecf9412c8601e64204eb6f846", size = 722361, upload-time = "2026-06-09T07:52:23.924Z" }, + { url = "https://files.pythonhosted.org/packages/8e/3f/73ccf82579412b4a71c4ca673f10b5f1f888d7cf5af7fe24f27d30307be4/safetensors-0.8.0-cp310-abi3-win32.whl", hash = "sha256:2ddf52eac562eda224f99acfa7889d02968c1fd59a5b011ae7d8137c37e9c02d", size = 342401, upload-time = "2026-06-09T07:52:28.895Z" }, + { url = "https://files.pythonhosted.org/packages/1b/6d/3fba214c1e5e0f69991677ec3bc17023f0421776975e1de0c682dca475e2/safetensors-0.8.0-cp310-abi3-win_amd64.whl", hash = "sha256:096ec1a98435df7beb08853bb5aa9081a84f23d0adc67ed1a0a10550f608373f", size = 355540, upload-time = "2026-06-09T07:52:27.832Z" }, + { url = "https://files.pythonhosted.org/packages/8d/fc/7eedc3510d97878876e32774eebbeb61c43f148a96e915c84229a3e967aa/safetensors-0.8.0-cp310-abi3-win_arm64.whl", hash = "sha256:f7838e5135a406ad3e02efdcb8cf2e5397d368b0154537c4fec682dbc544d452", size = 340500, upload-time = "2026-06-09T07:52:26.745Z" }, +] + +[[package]] +name = "scikit-learn" +version = "1.9.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "joblib" }, + { name = "narwhals" }, + { name = "numpy" }, + { name = "scipy" }, + { name = "threadpoolctl" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/d2/eb/eaf5e07fcc0da7149b0e084f24e54edd7441b9a89ce7e034032ae97fe3a0/scikit_learn-1.9.1.tar.gz", hash = "sha256:629cada3e33e2b9bf376cdc7614a47a4140b8aedc1d836579e359736fbd82977", size = 7786908, upload-time = "2026-09-10T18:34:04.679Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/bb/8d/b60d5e7354ff0ff5cc9400e60273696589d87a30b8b2235886a76d80d062/scikit_learn-1.9.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:2c2b312fd8c02951a364fa120ea08c1cec10d863466bf1701b013152d7537835", size = 8739300, upload-time = "2026-09-10T18:32:55.483Z" }, + { url = "https://files.pythonhosted.org/packages/2f/81/3c6392c03665d2899457a76e535a9a6f597dddddf3220fd2e1d790da88c5/scikit_learn-1.9.1-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:61cd968ab831a76d0ecbaf0347ab2270268716da28f94fd022497e3d6f205f13", size = 8262364, upload-time = "2026-09-10T18:32:57.966Z" }, + { url = "https://files.pythonhosted.org/packages/0f/35/a15b8653499692879821301d48059376d6e68e8b65cd0f22d19b6ee83cd9/scikit_learn-1.9.1-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5990f9c69e431bfaddcde1a6d7c5355243e026bc9b9e560c13893b90dab53fb4", size = 8823698, upload-time = "2026-09-10T18:33:00.632Z" }, + { url = "https://files.pythonhosted.org/packages/23/e5/688703d357e5393f708d98eb189fd415ae69e39f6de03c6bd4005aef6118/scikit_learn-1.9.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:55e79d6e9b0923f1a978179822bd43d7f5543f45e970a00fe861f43486380aba", size = 9121732, upload-time = "2026-09-10T18:33:02.825Z" }, + { url = "https://files.pythonhosted.org/packages/96/45/a10add34c08184d373be9384660c75758128ca881ed27b503b6f6a742478/scikit_learn-1.9.1-cp313-cp313-win_amd64.whl", hash = "sha256:2070f271e5375dc42c6bb93b461ab1c0aa5841d4009267e0cfd95a39dca94a43", size = 8237244, upload-time = "2026-09-10T18:33:05.26Z" }, + { url = "https://files.pythonhosted.org/packages/9e/08/7a89bcdadd1fff0d464d01056417b646c9abcbc54f7297a0a1203bba5ebb/scikit_learn-1.9.1-cp313-cp313-win_arm64.whl", hash = "sha256:613f0a783ca05aa844a4e1ac42d48425058f2c52be73f40f8cd98b7cd111acd6", size = 7875398, upload-time = "2026-09-10T18:33:07.506Z" }, +] + +[[package]] +name = "scipy" +version = "1.18.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/7e/74/66de6258867beb2ef08f35f9f2ac017a52cacd5081714d239ff1a442d458/scipy-1.18.1.tar.gz", hash = "sha256:52c4b7422442aba924d03ad4019852b08a92e64ea187b933135687bfe2747307", size = 30781235, upload-time = "2026-08-21T23:28:50.599Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b6/55/4540ee0f9c42a9ad7109d0d1a8cc70de54c3572b01c6693a2b1c70e90ceb/scipy-1.18.1-cp313-cp313-macosx_10_15_x86_64.whl", hash = "sha256:3ab3523da44749156e1f68b464dc56af11ae4cbc5c739a49d05f32b982eca9f3", size = 31089958, upload-time = "2026-08-21T23:24:35.8Z" }, + { url = "https://files.pythonhosted.org/packages/2a/f5/769f36d14922b8071a43e95d24d18b6bdafad10d7f5cf647867e1ac052bc/scipy-1.18.1-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:e6fb6a55cc0ba97b59a1f288fb86dc6fce8bdfc0fffcbfd015e3a954bf2a2d93", size = 28715106, upload-time = "2026-08-21T23:24:40.775Z" }, + { url = "https://files.pythonhosted.org/packages/9a/d7/21d890274f75ea37a8209d5519e72da3da90302e3b9fb8397a0918386a62/scipy-1.18.1-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:ea324d9dd34c38bfb9bec8ca4d1b407db97dbb74029f566b8e322b1b6fe56fe6", size = 20456846, upload-time = "2026-08-21T23:24:45.066Z" }, + { url = "https://files.pythonhosted.org/packages/ec/01/798430ecea2e78ec7c02663d5f71c007bb6abeca931080debd40d7fa55ea/scipy-1.18.1-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:75b00eb8fb802090aa903f4ea1c7f5a584779f967361e68b7e98e531cc2d7174", size = 23087986, upload-time = "2026-08-21T23:24:49.539Z" }, + { url = "https://files.pythonhosted.org/packages/e6/5f/4634e9d35c68496e4e34cb6946eafab044458e6cedab42b40b6588e475b6/scipy-1.18.1-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d416b16cccfd70fbf62400e84d0bb2f4e6af519a45557f1692c749b37f14b315", size = 33998146, upload-time = "2026-08-21T23:24:54.714Z" }, + { url = "https://files.pythonhosted.org/packages/41/48/6450ed9243315322bbc19ac57b9b70d66a20bf1d38d124c96bc4bf6af9ea/scipy-1.18.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fdaf5ea890a6183d0565f51a61799d67081bd5b1cf03c5f4b3fd3732108625c9", size = 35312578, upload-time = "2026-08-21T23:25:00.44Z" }, + { url = "https://files.pythonhosted.org/packages/00/bd/bf5a4be6a3525676499f6dff307991739ff6fdcad1481b1aeb6745339f58/scipy-1.18.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c825cef2f49e46753726a7181a8e199804a912b29519ada542c6ebc654951899", size = 35612621, upload-time = "2026-08-21T23:25:06.144Z" }, + { url = "https://files.pythonhosted.org/packages/bd/4e/3c45c33e00a77996c4b1cb707929f833ba7b1d522ee29f882512c330676d/scipy-1.18.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e3b417bf8c2c7c16e8f58ad91db17783ec911ac16e7b50eb6eab6e809b4f5b07", size = 37457323, upload-time = "2026-08-21T23:25:12.483Z" }, + { url = "https://files.pythonhosted.org/packages/93/0e/e0348fbc0dbab65c114cf78957e7dfeb49f8e8b556b4d930cc12ff195e18/scipy-1.18.1-cp313-cp313-win_amd64.whl", hash = "sha256:559ed65f60c1af5a03f3912605a1b5114f522c7c32fb23c3376ae8f03219fe28", size = 36622841, upload-time = "2026-08-21T23:25:18.722Z" }, + { url = "https://files.pythonhosted.org/packages/50/a8/6a77f5f267c555108f0a864b6db714363dab567a8266422a79a385f9232b/scipy-1.18.1-cp313-cp313-win_arm64.whl", hash = "sha256:cd479fc04dd9401e3b4f49e76518768ef99c4f517a98c284eb091fd725719adf", size = 24399315, upload-time = "2026-08-21T23:25:23.458Z" }, +] + +[[package]] +name = "secretstorage" +version = "3.5.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cryptography" }, + { name = "jeepney" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/1c/03/e834bcd866f2f8a49a85eaff47340affa3bfa391ee9912a952a1faa68c7b/secretstorage-3.5.0.tar.gz", hash = "sha256:f04b8e4689cbce351744d5537bf6b1329c6fc68f91fa666f60a380edddcd11be", size = 19884, upload-time = "2025-11-23T19:02:53.191Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b7/46/f5af3402b579fd5e11573ce652019a67074317e18c1935cc0b4ba9b35552/secretstorage-3.5.0-py3-none-any.whl", hash = "sha256:0ce65888c0725fcb2c5bc0fdb8e5438eece02c523557ea40ce0703c266248137", size = 15554, upload-time = "2025-11-23T19:02:51.545Z" }, +] + +[[package]] +name = "sentence-transformers" +version = "6.1.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "huggingface-hub" }, + { name = "numpy" }, + { name = "scikit-learn" }, + { name = "scipy" }, + { name = "tokenizers" }, + { name = "torch" }, + { name = "tqdm" }, + { name = "transformers" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c4/a1/53ae87971817e2d8370f8e79b843a881be33ab339502d71c5f82ac31f7af/sentence_transformers-6.1.0.tar.gz", hash = "sha256:299025df51550dc1a38f05be27a9b0bf881c4e5e70542b3b7757d05e00aa3868", size = 576566, upload-time = "2026-09-18T10:44:24.279Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b5/6e/9115e19589c83172bd37ec793cfef7f7c719464053fa6a8882700c1f4488/sentence_transformers-6.1.0-py3-none-any.whl", hash = "sha256:eb8122f4d180f552eda26dc3d77e84e8c11dc2b1d456a406b9f24abb70ceeadd", size = 740560, upload-time = "2026-09-18T10:44:22.841Z" }, +] + +[[package]] +name = "setuptools" +version = "84.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/6d/44/f5da03a8ef95d369145c5bb53050e7877c9f3d312e128605fd9504829143/setuptools-84.0.0.tar.gz", hash = "sha256:f4695c21257f0d9b537ec2692c941d02ee143b7cc1276941349a546573b2ef73", size = 1168449, upload-time = "2026-08-08T18:27:58.365Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/95/9c/c510029fc6ef33a6275cd2c5d3cecd6613dfd6aa401d57c54f1c18852ccf/setuptools-84.0.0-py3-none-any.whl", hash = "sha256:51a52592b3b99e102b609654876bd65f19f999935166d1352678931132b0c670", size = 818216, upload-time = "2026-08-08T18:27:56.719Z" }, +] + +[[package]] +name = "shellingham" +version = "1.5.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/58/15/8b3609fd3830ef7b27b655beb4b4e9c62313a4e8da8c676e142cc210d58e/shellingham-1.5.4.tar.gz", hash = "sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de", size = 10310, upload-time = "2023-10-24T04:13:40.426Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686", size = 9755, upload-time = "2023-10-24T04:13:38.866Z" }, +] + +[[package]] +name = "six" +version = "1.17.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031, upload-time = "2024-12-04T17:35:28.174Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050, upload-time = "2024-12-04T17:35:26.475Z" }, +] + +[[package]] +name = "smart-open" +version = "8.0.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "wrapt" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/51/5f/4c6d2be8dc4737d209f583a9c61e40c7b90d86313308e1d82e79a1b857b4/smart_open-8.0.3.tar.gz", hash = "sha256:398eb1d6af1e887ccd30347af540793235369bd6602dc42f72c44f939ae9c80f", size = 61941, upload-time = "2026-10-12T20:21:50.154Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/79/60e14c5a19f39ebcf4fecd8ae8b0b01418ff5839bd7e66cf02b019d31826/smart_open-8.0.3-py3-none-any.whl", hash = "sha256:c3f67795b1a2bdb62dd9aca9ba4d4018e8f11e4188700b3246ea5ae049f65887", size = 73451, upload-time = "2026-10-12T20:21:48.353Z" }, +] + +[[package]] +name = "sniffio" +version = "1.3.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc", size = 20372, upload-time = "2024-02-25T23:20:04.057Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235, upload-time = "2024-02-25T23:20:01.196Z" }, +] + +[[package]] +name = "spacy" +version = "3.8.16" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "catalogue" }, + { name = "click" }, + { name = "confection" }, + { name = "cymem" }, + { name = "jinja2" }, + { name = "murmurhash" }, + { name = "numpy" }, + { name = "packaging" }, + { name = "preshed" }, + { name = "pydantic" }, + { name = "requests" }, + { name = "setuptools" }, + { name = "spacy-legacy" }, + { name = "spacy-loggers" }, + { name = "srsly" }, + { name = "thinc" }, + { name = "tqdm" }, + { name = "typer" }, + { name = "wasabi" }, + { name = "weasel" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/69/5d/b0b4cd2f6e8a0470e50f7f0cfc1cea6e2f25572e97fb5d404c7941d5e88a/spacy-3.8.16.tar.gz", hash = "sha256:a3d19da23637cc396b42d22fc33852680f675d8ddcb847d3e2a0d094712d1794", size = 1330989, upload-time = "2026-08-24T10:05:57.936Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a5/5a/ebe53a3cd1edf5f8cb4b9465ae2383b0b4f6a2c8bd96afa0408f682df4bb/spacy-3.8.16-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f42f257404e749d9048d3b3b97004692210057d38e03c2f156817258bf6daf2b", size = 6585155, upload-time = "2026-08-24T10:05:05.818Z" }, + { url = "https://files.pythonhosted.org/packages/29/f8/80f9ddf288c494b3a7b737bff3b938ef70328c49aaf0a90738aa90b638b8/spacy-3.8.16-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:ce120d4077050352f344b987354be3e3fddb207436b537cf91a891837657ce2c", size = 6465153, upload-time = "2026-08-24T10:05:08.32Z" }, + { url = "https://files.pythonhosted.org/packages/7d/5f/b039865cf4e2fa82c8defc737c37af4480e70a56d1e1c380865b3df89f54/spacy-3.8.16-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f765cb6cbef82b5d98c46936a1385e87fb05919433fbc6b953e3c093ac30f8ef", size = 34527537, upload-time = "2026-08-24T10:05:11.65Z" }, + { url = "https://files.pythonhosted.org/packages/12/48/60048a3558f591fbaf11a73b342262699178cf44dd6fb88827118be34335/spacy-3.8.16-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:111d817b32755d869e5ed6cc258b55c50c6687f47b78f6ebb2c14b1ce5ee707c", size = 35151231, upload-time = "2026-08-24T10:05:15.911Z" }, + { url = "https://files.pythonhosted.org/packages/96/6e/3e09ebd5635e1c6a2b92baee5d593a907908ce1b38fb1f011dbb0d66c411/spacy-3.8.16-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:8a8a2bf3eb3486a0992176b77ac1d38ca9c669623941fdb8d3dddacb44dfd28e", size = 34649694, upload-time = "2026-08-24T10:05:20.225Z" }, + { url = "https://files.pythonhosted.org/packages/78/8c/b31440943778f8c6a63dc568df5d0d3b4a58c9472784416474e71d04eca5/spacy-3.8.16-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a237491463e351755f0167546f6a821d42971c5275a219a62d468f19f654138b", size = 35664934, upload-time = "2026-08-24T10:05:24.369Z" }, + { url = "https://files.pythonhosted.org/packages/55/f4/a613999ef17bf8252d4e6a62609b9d16a932e1cfd56f9c682e5dd82d91ba/spacy-3.8.16-cp313-cp313-win_amd64.whl", hash = "sha256:cc7e449aec9a313bc037ef5ea45fb0ac99135d92dace8421d68414d16be39543", size = 15163063, upload-time = "2026-08-24T10:05:27.428Z" }, + { url = "https://files.pythonhosted.org/packages/15/6e/97039de4f188ae3c69b5de9c852b4c5c5252896d2bc3d9ed1af93655ba1d/spacy-3.8.16-cp313-cp313-win_arm64.whl", hash = "sha256:024ce6408ea00c7f8c6387a6de65bb67aad40c51c9d63705303c5cb9a8ef51b0", size = 14540066, upload-time = "2026-08-24T10:05:30.354Z" }, +] + +[[package]] +name = "spacy-legacy" +version = "3.0.12" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d9/79/91f9d7cc8db5642acad830dcc4b49ba65a7790152832c4eceb305e46d681/spacy-legacy-3.0.12.tar.gz", hash = "sha256:b37d6e0c9b6e1d7ca1cf5bc7152ab64a4c4671f59c85adaf7a3fcb870357a774", size = 23806, upload-time = "2023-01-23T09:04:15.104Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c3/55/12e842c70ff8828e34e543a2c7176dac4da006ca6901c9e8b43efab8bc6b/spacy_legacy-3.0.12-py2.py3-none-any.whl", hash = "sha256:476e3bd0d05f8c339ed60f40986c07387c0a71479245d6d0f4298dbd52cda55f", size = 29971, upload-time = "2023-01-23T09:04:13.45Z" }, +] + +[[package]] +name = "spacy-loggers" +version = "1.0.5" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/67/3d/926db774c9c98acf66cb4ed7faf6c377746f3e00b84b700d0868b95d0712/spacy-loggers-1.0.5.tar.gz", hash = "sha256:d60b0bdbf915a60e516cc2e653baeff946f0cfc461b452d11a4d5458c6fe5f24", size = 20811, upload-time = "2023-09-11T12:26:52.323Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/33/78/d1a1a026ef3af911159398c939b1509d5c36fe524c7b644f34a5146c4e16/spacy_loggers-1.0.5-py3-none-any.whl", hash = "sha256:196284c9c446cc0cdb944005384270d775fdeaf4f494d8e269466cfa497ef645", size = 22343, upload-time = "2023-09-11T12:26:50.586Z" }, +] + +[[package]] +name = "sqlalchemy" +version = "2.1.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/1f/44/311bac6b6ef81e4dfd0287d04900108b1f5c00c9761dd3c0a2b7b9d0f86b/sqlalchemy-2.1.4.tar.gz", hash = "sha256:7bd7ad604487daa7eab8716471c29a7185f17b5287ce73bb7bc79fea050d8cfd", size = 10544216, upload-time = "2026-10-07T17:33:59.116Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/dc/e4/23174288ed2c03d6dbd5dfacd69e28303ee95f49642a8ed0544932999fb6/sqlalchemy-2.1.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:70006e9e6157200b795beeee04bd5cb15bccb40a14de595eb9f5dcf5945ed244", size = 2460507, upload-time = "2026-10-07T18:04:40.044Z" }, + { url = "https://files.pythonhosted.org/packages/9f/ac/254fadc98bfd600445b976e81c6d777b08a728a415c3b77a8c8d35b89a83/sqlalchemy-2.1.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3341ddc430733cd961bc064889f42712a0b4056733a21c83176842aad67d12a6", size = 4594505, upload-time = "2026-10-07T18:16:58.768Z" }, + { url = "https://files.pythonhosted.org/packages/83/6f/ac7beddc57c9c87bd77bc1c158fcbcdc20822f1873bf33ea3480d04e865f/sqlalchemy-2.1.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:98f7a4bfeaed3722804f737ae2bd4077b35e57d6f4531fe612bac8160cda5acd", size = 4647364, upload-time = "2026-10-07T18:34:51.721Z" }, + { url = "https://files.pythonhosted.org/packages/0a/82/fc3891f261c4738a8b90cfdd805fe292d1af3b77f680a63b7349304c74e5/sqlalchemy-2.1.4-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:ec5d079935f67febe0ab8a3a203ad591b99508adc34ae0027f696dcb20373537", size = 4311619, upload-time = "2026-10-07T18:38:44.002Z" }, + { url = "https://files.pythonhosted.org/packages/b0/1a/160c1320ab20e764a29721dc3fe7c31af34e291c652dca875d1ca6022b9a/sqlalchemy-2.1.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:3d675b0856b6703b29d023517a4c19fecfbb55214ff5c72cd813527e40aed9b4", size = 4518031, upload-time = "2026-10-07T18:17:05.615Z" }, + { url = "https://files.pythonhosted.org/packages/30/2c/15a204333896e5dc63cb089ea20ca3ebc3c892bedf9fa00cc1a65e20d7b5/sqlalchemy-2.1.4-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:a0bb9ee6a38cb36240dc88da11888348f61506047be54de3f09496c3b0ead6f5", size = 4312818, upload-time = "2026-10-07T18:38:46.541Z" }, + { url = "https://files.pythonhosted.org/packages/a6/55/5e78d288f198598f278b4b7baef42f18e039b14b1e1045e9df3cf571300d/sqlalchemy-2.1.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:61a2c48771cf314b6613d327c795902bbc0eb6d6169deb23b35004ba6ad6cc0d", size = 4608584, upload-time = "2026-10-07T18:34:53.69Z" }, + { url = "https://files.pythonhosted.org/packages/ab/f6/e83b93ecc6e6528623fd7aa2af27ff0660d22354b78fe6ccad03f9ecbd9f/sqlalchemy-2.1.4-cp313-cp313-win32.whl", hash = "sha256:3fd608a06bafa768ad5711df4e17eb058bdc490e9df7d39b12a90947471e8712", size = 2373880, upload-time = "2026-10-07T18:22:11.722Z" }, + { url = "https://files.pythonhosted.org/packages/8f/46/afb02975023db6aa4b8608177c2fae17d0b435d9cbfcb5df4fa6e65a8078/sqlalchemy-2.1.4-cp313-cp313-win_amd64.whl", hash = "sha256:b756d74527c56a7e4cfae297f7930c1d75bdf4b23f214c8c13779746d28060cb", size = 2424430, upload-time = "2026-10-07T18:22:23.688Z" }, + { url = "https://files.pythonhosted.org/packages/21/e5/76dc82d59186b98b27589b33b01175c0d49512679276170271d9384418e2/sqlalchemy-2.1.4-cp313-cp313-win_arm64.whl", hash = "sha256:a64d54015233f824f171009977bfbb6b08bd0347b700cf17cb047ffb94c4148f", size = 2385057, upload-time = "2026-10-07T18:11:48.248Z" }, + { url = "https://files.pythonhosted.org/packages/f7/62/dbf11a262f6fbb41390cab2d8e47a30ec0961018b68201607b599dd489f5/sqlalchemy-2.1.4-py3-none-any.whl", hash = "sha256:0b96edcc2cd60fe1e35f67a46f4eb076e57297841b9eae949ac5f196593f00a7", size = 2054935, upload-time = "2026-10-07T18:01:16.403Z" }, +] + +[package.optional-dependencies] +asyncio = [ + { name = "greenlet" }, +] + +[[package]] +name = "sqlglot" +version = "30.22.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/94/e0/db58fbf2527426758dc1e862ce538736978e100e4e78fc9657e9661826ee/sqlglot-30.22.0.tar.gz", hash = "sha256:ec4b83ca8236ea8867f574a382dc15ce35b071c977fecfcc66482d9a3f500661", size = 6088770, upload-time = "2026-10-09T16:09:01.04Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b4/4c/b8474b02b572d9c7a2903e364335d566d52b6128b834b92a7cdfe5597823/sqlglot-30.22.0-py3-none-any.whl", hash = "sha256:90aa461490fcd95d14ec3842a97506ae20f6d3e9313307ad31be793d479cca65", size = 777816, upload-time = "2026-10-09T16:08:59.07Z" }, +] + +[[package]] +name = "srsly" +version = "2.5.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "catalogue" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/4b/9b/a55dbb041cf2e44811323ea3fccada06acdd8dbc8ac856f224e0e093d428/srsly-2.5.4.tar.gz", hash = "sha256:7589a35dd6bf1d177803c4ed454098f2f690b3704b80cca337a50be95ba59b3a", size = 509727, upload-time = "2026-09-27T20:16:18.533Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3d/de/23e456abb1a5f299e08d849bc988d5a18a2d0843f02375b4e689299b8330/srsly-2.5.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:461e8d0bfc448960455afa53767434af23bace5b640f17ff0631e690597309dd", size = 684283, upload-time = "2026-09-27T20:15:31.668Z" }, + { url = "https://files.pythonhosted.org/packages/7c/41/b7306df8e79473e2f317cdc9f6277b8d67c0cd95ec14b125e040f5e92da5/srsly-2.5.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:c8cb46d773244c2d2415068d5333882f9fc910c9abee2c6d251c05813379e23d", size = 683758, upload-time = "2026-09-27T20:15:32.921Z" }, + { url = "https://files.pythonhosted.org/packages/be/dc/c48360817477e7aec4e841d600afa05441efe562b4d7cfd714b64c44fc83/srsly-2.5.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:9a54d7e913f6aadbd46ad25504d083f4e51a8685815fe144661d350a65486494", size = 1220766, upload-time = "2026-09-27T20:15:34.243Z" }, + { url = "https://files.pythonhosted.org/packages/13/af/bb25308da43ce1e6b3ad28b27529bc395721fe6dd21b334fcb7d4ddf2aa3/srsly-2.5.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:23fb905191d81066bd9b91639cf272e3f55170bc40124af6aae98f4cb2f14e54", size = 1226176, upload-time = "2026-09-27T20:15:35.581Z" }, + { url = "https://files.pythonhosted.org/packages/94/bd/16256b4a794fc5b142ecfa24f12756d8845351f21fe6ab27a72266ac7f2e/srsly-2.5.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:2fa56076c0214805e11933f83aca7bc982f3abc93d11ac04974efd8693eb5098", size = 1176102, upload-time = "2026-09-27T20:15:37.146Z" }, + { url = "https://files.pythonhosted.org/packages/cc/b4/eb00741ec116d99b912e8469fba5b2512c45554c2fd0d1dd0a1b5b421c15/srsly-2.5.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:7829bd3597cac2692bff0f9f3e7aa50e562c5b83ad35c7f547f601aa832bb1df", size = 1195080, upload-time = "2026-09-27T20:15:38.506Z" }, + { url = "https://files.pythonhosted.org/packages/1f/c5/6524f38b66d7285847c450fae6aa29552879edbc824526e4fe332bc24b48/srsly-2.5.4-cp313-cp313-win_amd64.whl", hash = "sha256:60fd24af0feacb375dbebbfbaf6bd3c56d744ce44d4aa0d2e0474ed800a34d00", size = 672333, upload-time = "2026-09-27T20:15:39.854Z" }, + { url = "https://files.pythonhosted.org/packages/18/91/06403ec9343cdca467fc8ca78236176edcb2a6ccdbe9df5521084fe9bc3a/srsly-2.5.4-cp313-cp313-win_arm64.whl", hash = "sha256:2071242637b30520b543cbcaa217d2438a1236b2e702aaa7502b322449decf31", size = 666520, upload-time = "2026-09-27T20:15:41.221Z" }, +] + +[[package]] +name = "sse-starlette" +version = "3.5.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anyio" }, + { name = "starlette" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e4/be/0123026f719d1a7936f214a88b553bb5701e04ff2511147c1dab0c5035eb/sse_starlette-3.5.0.tar.gz", hash = "sha256:75de713aa8a9441513cc283220826da079d982770965b951e9437720e8bafdb2", size = 36794, upload-time = "2026-09-28T17:48:14.7Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/be/e4/cdda14023c316d71493bc54fdffc3dd006631b88866145c9d3cc33e0f1df/sse_starlette-3.5.0-py3-none-any.whl", hash = "sha256:3e6e1070df3f0f5d9cea81496de92dbb72f6721871d99748ece67441dd8b7997", size = 17407, upload-time = "2026-09-28T17:48:13.228Z" }, +] + +[[package]] +name = "starlette" +version = "1.8.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anyio" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e9/0c/6efb252d091ecccd7d62048ae11f0ea35cd75a4fbaeea5e30f9c3bf91d10/starlette-1.8.0.tar.gz", hash = "sha256:1565dc0b35d5737a271ed1e0e04e949f4e81198799f216d2667b0a0fb9cf9522", size = 2730457, upload-time = "2026-10-13T07:54:39.53Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c1/b0/5742e4ac7af5eb58ec3470a537a49d7aa507e5539413e504b3a65ef50ba8/starlette-1.8.0-py3-none-any.whl", hash = "sha256:dfdd6b29c26483288088d990eee59631dedadd66ce20d203402a7ca8e3c4656f", size = 79612, upload-time = "2026-10-13T07:54:38.019Z" }, +] + +[[package]] +name = "structlog" +version = "26.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/5e/89/b4a0bcfdf4f71a3dea31379f095929613d7e4528a0996bca6aa964cd0dca/structlog-26.1.0.tar.gz", hash = "sha256:f63a716cbd1b1291cf7661de7794b455acfa4c43c5bcf1630e6ad5ddc1adb3b7", size = 1459881, upload-time = "2026-06-06T07:33:39.348Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a9/18/489c97b834dfff9cf2fc2507cede4bcd4b11e67f84bc462acd1992496f86/structlog-26.1.0-py3-none-any.whl", hash = "sha256:e081a26d6c373e6d201eca24eede26d8ffab07f88f477822e679183428d3d91e", size = 73764, upload-time = "2026-06-06T07:33:38.046Z" }, +] + +[[package]] +name = "sympy" +version = "1.14.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mpmath" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/83/d3/803453b36afefb7c2bb238361cd4ae6125a569b4db67cd9e79846ba2d68c/sympy-1.14.0.tar.gz", hash = "sha256:d3d3fe8df1e5a0b42f0e7bdf50541697dbe7d23746e894990c030e2b05e72517", size = 7793921, upload-time = "2025-04-27T18:05:01.611Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a2/09/77d55d46fd61b4a135c444fc97158ef34a095e5681d0a6c10b75bf356191/sympy-1.14.0-py3-none-any.whl", hash = "sha256:e091cc3e99d2141a0ba2847328f5479b05d94a6635cb96148ccb3f34671bd8f5", size = 6299353, upload-time = "2025-04-27T18:04:59.103Z" }, +] + +[[package]] +name = "temporalio" +version = "1.34.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "nexus-rpc" }, + { name = "protobuf" }, + { name = "types-protobuf" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/13/85/9ece6f400552ed21951c8c5c534056e7d015cb065e3384470ec23ac24f28/temporalio-1.34.0.tar.gz", hash = "sha256:6453cb20e18df485e16578b22c82a9c4bcb1cf7eedd94147dfd373551d80f5b6", size = 3163890, upload-time = "2026-09-30T20:22:56.056Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3c/71/e55380e7820819357afada375d4e5c33d141bb94a08fda35aa0551b4369b/temporalio-1.34.0-cp310-abi3-macosx_10_12_x86_64.whl", hash = "sha256:87118447ad13e1062b79bfc8b44b1695e8328ac9c6be1776e426e87b501b135a", size = 14064102, upload-time = "2026-09-30T20:22:35.601Z" }, + { url = "https://files.pythonhosted.org/packages/db/78/356c8e2f0ec1678b757d4c5e8a1b0b1c65b15b8afb2335ad2944c158ea10/temporalio-1.34.0-cp310-abi3-macosx_11_0_arm64.whl", hash = "sha256:023fff9cd9dd21860061e003880dcf95250700f5afab96c030c9cb258504dab8", size = 13763219, upload-time = "2026-09-30T20:22:38.774Z" }, + { url = "https://files.pythonhosted.org/packages/e9/00/4a4b4e018c4c12b4691211aca1d97db8707ed4c9e31f40dcf09784c9913d/temporalio-1.34.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cdb6e2fb525ea5635afa4a3f1ae4c992c16dbe29dc92939a85153baeb69d95a2", size = 14121901, upload-time = "2026-09-30T20:22:41.428Z" }, + { url = "https://files.pythonhosted.org/packages/c1/20/b032d4a0df51d466fd929d8205e1288e83d97a890f021479f43af9bd6f9b/temporalio-1.34.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:540761f738bdfe5cb5bd7240b659e116a0b5094b94282aef09b8d8c2d66e9c52", size = 14457183, upload-time = "2026-09-30T20:22:44.215Z" }, + { url = "https://files.pythonhosted.org/packages/b6/0d/b08ffeca93bbc29200a5bd85a45cca3c6be0a123de605ecd1798b617df4f/temporalio-1.34.0-cp310-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:87647f87f42ecd45efb675642e2ec8ca34aa42359f5968f31f5391f1db5ebcbe", size = 14179836, upload-time = "2026-09-30T20:22:47.474Z" }, + { url = "https://files.pythonhosted.org/packages/81/55/acde4d1b7c9f23434e263752ef0a3ef58adeb3b95ef8472607414798dfaa/temporalio-1.34.0-cp310-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:71caa4b9061628b22a457c87c3b16da40f7ac6ac1a26ece9aa1ee6b4934404d7", size = 14570248, upload-time = "2026-09-30T20:22:50.569Z" }, + { url = "https://files.pythonhosted.org/packages/cc/c5/6bdc3b02ec483093a71e9f887e8a50ae20fcc79e0578ed7435a81d4271b1/temporalio-1.34.0-cp310-abi3-win_amd64.whl", hash = "sha256:03bd86561188c18d88425178bc690fe0791104b78566dcebd98f59cbdbce0952", size = 15415684, upload-time = "2026-09-30T20:22:53.342Z" }, +] + +[[package]] +name = "tenacity" +version = "9.1.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/47/c6/ee486fd809e357697ee8a44d3d69222b344920433d3b6666ccd9b374630c/tenacity-9.1.4.tar.gz", hash = "sha256:adb31d4c263f2bd041081ab33b498309a57c77f9acf2db65aadf0898179cf93a", size = 49413, upload-time = "2026-02-07T10:45:33.841Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d7/c1/eb8f9debc45d3b7918a32ab756658a0904732f75e555402972246b0b8e71/tenacity-9.1.4-py3-none-any.whl", hash = "sha256:6095a360c919085f28c6527de529e76a06ad89b23659fa881ae0649b867a9d55", size = 28926, upload-time = "2026-02-07T10:45:32.24Z" }, +] + +[[package]] +name = "testcontainers" +version = "4.15.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "docker" }, + { name = "python-dotenv" }, + { name = "typing-extensions" }, + { name = "urllib3" }, + { name = "wrapt" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/4b/13/2cc466bddf26d0085f30a2b2bd56b7f8708b54a54db833eec97c5c69129b/testcontainers-4.15.0.tar.gz", hash = "sha256:085cde086337632e19002719460b7b80bbab2bdd51bb3ea04f77d0de96504706", size = 95340, upload-time = "2026-07-24T23:08:01.731Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/00/7e/424aac8b355597835deb333e757a0e94b5ccf38ad00f07fe6ed1f4e17c88/testcontainers-4.15.0-py3-none-any.whl", hash = "sha256:8796c14e76604031ad39cf0ed3b8e9806283a1fbf5270965c2b1c594caa31b74", size = 160771, upload-time = "2026-07-24T23:08:00.13Z" }, +] + +[package.optional-dependencies] +minio = [ + { name = "minio" }, +] +redis = [ + { name = "redis" }, +] + +[[package]] +name = "thinc" +version = "8.3.13" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "blis" }, + { name = "catalogue" }, + { name = "confection" }, + { name = "cymem" }, + { name = "murmurhash" }, + { name = "numpy" }, + { name = "packaging" }, + { name = "preshed" }, + { name = "pydantic" }, + { name = "setuptools" }, + { name = "srsly" }, + { name = "wasabi" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/13/46/76df95f2c327f9a9cef30c1523bf285627897097163584dcf5f77b2ebce2/thinc-8.3.13.tar.gz", hash = "sha256:68e658549fc1eb3ff92aed5147fcbb9c15d6e9cc0e623b4d0998d16522ffb4f9", size = 194640, upload-time = "2026-03-23T07:22:36.41Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/af/b9/7b46942176df459d1804a9e77b0976f7c56f3abf3ec7485d0e5f836a0382/thinc-8.3.13-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:c2811dfd8d46d8b5d3b39051b23e64006b2994a5143b1978b436938018792af8", size = 817337, upload-time = "2026-03-23T07:22:09.538Z" }, + { url = "https://files.pythonhosted.org/packages/a7/79/53085a72cd8f4fc4e6e313d05ea5aa98e870684f4a0fb318a9875fc0a964/thinc-8.3.13-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5593e6300cb1ebe0c0e546e9c9fb49e7c2627a0aa688795cd4f995a8b820d2ec", size = 788120, upload-time = "2026-03-23T07:22:11.215Z" }, + { url = "https://files.pythonhosted.org/packages/9e/3e/d61b462b16da95ac6885f95bb395e672040ee594833e571a6edcffd234f5/thinc-8.3.13-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:f697174d3fb474966ce50b430bbafa101a6d2f7ffb559dac4b5c59389ef72d22", size = 3844666, upload-time = "2026-03-23T07:22:12.67Z" }, + { url = "https://files.pythonhosted.org/packages/78/4c/898cc654bb123734c71ec5a425c02ca34439517d01ce1c95a6563295580e/thinc-8.3.13-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:e9c7c5c104737b414c8c4ec578e67d78b6c859afe25cbc0684402e721415bd7f", size = 3890658, upload-time = "2026-03-23T07:22:14.668Z" }, + { url = "https://files.pythonhosted.org/packages/cd/56/1abdbf0a4ad628e8a05d6516fe0745969649d805367a3dccad8ee872981b/thinc-8.3.13-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:7a99d0e242d1ccd23f9ae6bea7cd502f8626efa65c156b91d84581d0356696c3", size = 4819933, upload-time = "2026-03-23T07:22:16.85Z" }, + { url = "https://files.pythonhosted.org/packages/f1/22/b84dbdc6be5055bbdb2a7352e2c393f67e8593c137f1b83c82bf1e062b6e/thinc-8.3.13-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e676edd21a747afbe3e6b9f3fca8b962e36d146ded03b070cb0c28e2dfbe9499", size = 5018099, upload-time = "2026-03-23T07:22:18.356Z" }, + { url = "https://files.pythonhosted.org/packages/0f/a8/763cd7ba949334c9d2cddc92dadb68b344cb9546dc01b8d4a733dcaa16c1/thinc-8.3.13-cp313-cp313-win_amd64.whl", hash = "sha256:8ad40307f20e83f77af28ff5c6be0b86af7a8b251d1231c545508d2763157d8f", size = 1720309, upload-time = "2026-03-23T07:22:19.81Z" }, + { url = "https://files.pythonhosted.org/packages/f5/15/a11f7bb3cbc97dfecf32a90552f5a8f8a5c99316a99c6c17bdabf5baf256/thinc-8.3.13-cp313-cp313-win_arm64.whl", hash = "sha256:723949cab11d1925c15447928513a718276316cec6e0de28337cca0a62be0521", size = 1644606, upload-time = "2026-03-23T07:22:21.339Z" }, +] + +[[package]] +name = "threadpoolctl" +version = "3.7.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/00/dc/6c58154c1c65f758ea979e7139cb76993a9cfc662d14e9be3c4a667cfb77/threadpoolctl-3.7.0.tar.gz", hash = "sha256:61348cfb77d53b9242e0017029244b559b810c142ced65b4e21eeca1843959a7", size = 31961, upload-time = "2026-09-15T15:46:20.263Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/43/3f/f88a53f60a472b46f4023f56d204dd7de33d34c5d2acbfa0d70a674e639e/threadpoolctl-3.7.0-py3-none-any.whl", hash = "sha256:cd8b60b5641b45c67bbf73c64c843235fc2d8a480c87389f52f5dbee893b86be", size = 26362, upload-time = "2026-09-15T15:46:19.168Z" }, +] + +[[package]] +name = "tiktoken" +version = "0.14.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "regex" }, + { name = "requests" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/66/62/167a842aa0429d45f5e797354fd4343a96f6043d67d0513c675c7b8d36e6/tiktoken-0.14.0.tar.gz", hash = "sha256:231dec90efcdccf1b565a1416107736f1e09b1a08fe736ef9d6363e626d03874", size = 38898, upload-time = "2026-08-17T19:49:49.514Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/50/53/ee1453623bf65f019328721ccb6587846d2c5b7b82f34e73ca09101f072e/tiktoken-0.14.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9c5fe393aab56469f04e432ff851216d3def3436cf5f07e442a240164bf500f", size = 1094198, upload-time = "2026-08-17T19:48:57.955Z" }, + { url = "https://files.pythonhosted.org/packages/ad/5f/6448cfe278c3664ba9ec5b5ac08344341f7dc3d42888476e215a14eda2be/tiktoken-0.14.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:cbe2cc3bba939bcdaf103e03df9d5039d33887080b315624be28ec69059e5f94", size = 1038820, upload-time = "2026-08-17T19:48:59.015Z" }, + { url = "https://files.pythonhosted.org/packages/69/3b/d67eac1bcce9dee3abe23aff5e3ded3116bbebaf67b80a0811c06d3806fc/tiktoken-0.14.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:2157f52e4b4d7ac5ecc7457b3716834706e7ef9a46f5144029bfeb7cf71f4e06", size = 1186175, upload-time = "2026-08-17T19:49:00.068Z" }, + { url = "https://files.pythonhosted.org/packages/37/62/cae690d9783146b0f81f564ada0f8f611de68178c0c9c7e1e969f0516b48/tiktoken-0.14.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:26e60f6a956ee171ab728b37b8439905d7ea1db435c30f9822f291e9861c861d", size = 1203884, upload-time = "2026-08-17T19:49:01.163Z" }, + { url = "https://files.pythonhosted.org/packages/b9/1e/633e30237b94e383cf814145499079f3bb9cdd4aeafc1bc42e01b0f810a6/tiktoken-0.14.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:380873f330b741c4435574f37edb20813d04603ace2d53e0a63560e1fec83010", size = 1250980, upload-time = "2026-08-17T19:49:02.274Z" }, + { url = "https://files.pythonhosted.org/packages/cb/56/4c12f07b812f84206f38d723eb1ebfdd34bad9309b5dbc0bee6bbcff4cbf/tiktoken-0.14.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:3fd7c14b1cb45b486c39fc9b3443bb341f3e2fc7e6f31247f3435a5836651632", size = 1315434, upload-time = "2026-08-17T19:49:03.434Z" }, + { url = "https://files.pythonhosted.org/packages/c9/e0/c65603f0c44811def666d3fbf611bf2af3b5e1ef613e06c19411419830b3/tiktoken-0.14.0-cp313-cp313-win_amd64.whl", hash = "sha256:90a762670c7f968184723769a06ed51f5cf5ce5dcd1e30164f25c72d85c2d1f1", size = 940883, upload-time = "2026-08-17T19:49:04.583Z" }, +] + +[[package]] +name = "tldextract" +version = "5.4.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "filelock" }, + { name = "idna" }, + { name = "requests" }, + { name = "requests-file" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/fd/5d/45ece871390ccc985f821353543165bcf3784fa97d8484fd0ca5f2726612/tldextract-5.4.0.tar.gz", hash = "sha256:6c9223212c15c25c0da2bf7313893c14f175cb36b64a0c42da67a468e0c61ee3", size = 197271, upload-time = "2026-10-03T21:32:47.229Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b8/e0/d5760e222a7e3f3aec7ef59f6dff952af27d09ec168bcca50751d9698151/tldextract-5.4.0-py3-none-any.whl", hash = "sha256:7f02aed30bd3b6ad5717192eb859a39b20aafc7caf3917d9cf6cb00a58efb34f", size = 107482, upload-time = "2026-10-03T21:32:45.842Z" }, +] + +[[package]] +name = "tokenizers" +version = "0.23.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "huggingface-hub" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e0/7c/2cabb2174e772636683008f2c5621949b645da7d303c596589e84516a184/tokenizers-0.23.3.tar.gz", hash = "sha256:cded33237c77caeef62944d32aa9a7ef42bdce2b3497e18d137e072a8c4be438", size = 385286, upload-time = "2026-10-09T10:16:55.759Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/aa/2e/4ce5b9716f26e526eff6b0502ebed4ea8d7161f03b3c77617c9f25528e97/tokenizers-0.23.3-cp310-abi3-macosx_10_12_x86_64.whl", hash = "sha256:9d2b5c97daf61688c2ad1803ca851800feaba50fb68d5821779e9ea5880d968c", size = 3148800, upload-time = "2026-10-09T10:00:51.457Z" }, + { url = "https://files.pythonhosted.org/packages/b2/72/01e49f032bb346e5aaf06c10c74fe8aeec847173adbadd66eb7c53054bf2/tokenizers-0.23.3-cp310-abi3-macosx_11_0_arm64.whl", hash = "sha256:68649e97d5b43c44c031d8d848874a6eecae8f8fe40ea989aa777a5a83aca716", size = 3101381, upload-time = "2026-10-09T10:00:54.063Z" }, + { url = "https://files.pythonhosted.org/packages/15/fc/ae987741829b1cd547668c4c94be732ae3eefd1d74344e64c3d2ca714acd/tokenizers-0.23.3-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec82e80e65a862275b97c3d90b7a523df8d9519ee48aeb4e9625b2cc909274e0", size = 3519944, upload-time = "2026-10-09T10:00:55.885Z" }, + { url = "https://files.pythonhosted.org/packages/1c/da/cc8f6c030afaf05fbddc608158fbb761dca46913cbeba6b112e59fc82e2a/tokenizers-0.23.3-cp310-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c64a0713180ff16829d4e7f39a658b77ea11443af4e1aa46523692943c9b1414", size = 3397695, upload-time = "2026-10-09T10:00:57.444Z" }, + { url = "https://files.pythonhosted.org/packages/ec/f1/256f78d1365fa2cd3ea6db716883d74667c8cbb6a21f15fa5b89a773cdc2/tokenizers-0.23.3-cp310-abi3-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ddedfd4b3b4be6be24ff6ca645c4a37fddfd305f6f3e354c54cf10b715c48215", size = 3753125, upload-time = "2026-10-09T10:01:00.165Z" }, + { url = "https://files.pythonhosted.org/packages/60/93/eee007ac2fcbf4ecfce7fbc354826cf3611f56bdb886f3e91b1f7dd06b8f/tokenizers-0.23.3-cp310-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2a89614730d7b80940a5d2ed9320e1ec8add5a745c6151d8d05071b7215505b6", size = 4018598, upload-time = "2026-10-09T10:01:02.05Z" }, + { url = "https://files.pythonhosted.org/packages/bf/f9/0c96c4739461fce9d8d865b416728081bf6230022d7163bd6244f35f4b31/tokenizers-0.23.3-cp310-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e88646b8580c5ad7f4361477f1298e9cc01771a1ee9aecfe32c47b8ff614cc38", size = 3602442, upload-time = "2026-10-09T10:01:03.77Z" }, + { url = "https://files.pythonhosted.org/packages/3a/40/6706b82693715581457c6d5423eaa7faae576bb0526c5738a57085eb4449/tokenizers-0.23.3-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:376851d22bcf9d650a5c3090bb83e6cf9e895fbf0595369fa4cd43c1f69b5f87", size = 3396193, upload-time = "2026-10-09T10:01:05.48Z" }, + { url = "https://files.pythonhosted.org/packages/fe/0c/85946de40e25b7364b8f1bcf56def129069acd5bb364b7c86a32919e1a23/tokenizers-0.23.3-cp310-abi3-manylinux_2_31_riscv64.whl", hash = "sha256:bf501c40b72d2d5c8623620210430e9cac1ce47a46e45b34107b70a1557d46b0", size = 3553483, upload-time = "2026-10-09T10:01:07.387Z" }, + { url = "https://files.pythonhosted.org/packages/f1/6b/8d615d92cad1d511ca5ab188d1c7c167f0b3d295cc0d96207f9f82d486d8/tokenizers-0.23.3-cp310-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:114e2b55ed177179d59f4ab98200a4471e11e78f9e4b5a922d146740f96fcf52", size = 9972248, upload-time = "2026-10-09T10:01:09.437Z" }, + { url = "https://files.pythonhosted.org/packages/c9/7d/a922e37ddd58d1b463bbc2ad08120c8f59c60b814cd353519a116b24f8ba/tokenizers-0.23.3-cp310-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:d3407fb7b9c4d75dd68850ffd7180bc0a5d2dbaf0762d888e612f31fec3f9c6b", size = 9802957, upload-time = "2026-10-09T10:01:11.869Z" }, + { url = "https://files.pythonhosted.org/packages/4b/06/5d3f506a86ae0699a0e4ea05c05978f9aee169ef2c1d844e68c971cf8194/tokenizers-0.23.3-cp310-abi3-musllinux_1_2_i686.whl", hash = "sha256:84513ef0aeb8bf8f4ea11a2e8a7ac163ec5288aa115e649a59b470ac5c3107df", size = 10145487, upload-time = "2026-10-09T10:01:14.268Z" }, + { url = "https://files.pythonhosted.org/packages/26/e5/065625317690ea3548d834dad81f48ea1fd32e4964610e658e195d7fe28e/tokenizers-0.23.3-cp310-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:e05ab7baf7f47b406a95fea6f3b0a484b2ddcd9e1d14b68844c457eb755085a3", size = 10266026, upload-time = "2026-10-09T10:16:33.054Z" }, + { url = "https://files.pythonhosted.org/packages/77/4e/babede85d0d19f5e3deeef0063e01848141329934d3d77c31b5cab5ac2b4/tokenizers-0.23.3-cp310-abi3-win32.whl", hash = "sha256:1ebf28794e7e4954e20a7f70fbea410b2d1f0418f7dbbca97ca384fcfef38c25", size = 2588086, upload-time = "2026-10-09T10:16:35.686Z" }, + { url = "https://files.pythonhosted.org/packages/d1/6c/24f074c9a0efb98e61b20aafe6b2641922d5db24e447d5d6daffd9e17555/tokenizers-0.23.3-cp310-abi3-win_amd64.whl", hash = "sha256:1f0823bb00c5fdc98e487354d54dd55a03848d61a1a0bf29a68c77f24f3b26c3", size = 2872101, upload-time = "2026-10-09T10:16:37.533Z" }, + { url = "https://files.pythonhosted.org/packages/53/77/a476b6f73a661c11d113a342d2326b91506cf2285f0995d1212a6bb2022d/tokenizers-0.23.3-cp310-abi3-win_arm64.whl", hash = "sha256:7e48734d2de9260d86f03ab056d2cfeeff3869f61dbd49aaa15a2793b5f3458b", size = 2742580, upload-time = "2026-10-09T10:16:39.244Z" }, +] + +[[package]] +name = "torch" +version = "2.14.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cuda-bindings", marker = "sys_platform == 'linux'" }, + { name = "cuda-toolkit", extra = ["cublas", "cudart", "cufft", "cufile", "cupti", "curand", "cusolver", "cusparse", "nvjitlink", "nvrtc", "nvtx"], marker = "sys_platform == 'linux'" }, + { name = "filelock" }, + { name = "fsspec" }, + { name = "jinja2" }, + { name = "networkx" }, + { name = "nvidia-cudnn-cu13", marker = "sys_platform == 'linux'" }, + { name = "nvidia-cusparselt-cu13", marker = "sys_platform == 'linux'" }, + { name = "nvidia-nccl-cu13", marker = "sys_platform == 'linux'" }, + { name = "nvidia-nvshmem-cu13", marker = "sys_platform == 'linux'" }, + { name = "setuptools" }, + { name = "sympy" }, + { name = "triton", marker = "sys_platform == 'linux'" }, + { name = "typing-extensions" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/7d/11/faaca4f8541c45127b7e0d6bb141221fe944c8466d89986b8466c6c195f9/torch-2.14.1-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:dbe359d705f4d67236743794c296c6dee93a922fd8117eff8c3e880d7d0fb2b9", size = 127315286, upload-time = "2026-09-30T17:52:27.43Z" }, + { url = "https://files.pythonhosted.org/packages/60/1f/0330275c705b846882531c64e80d32b13fb572eeb9b995e87e84154b0712/torch-2.14.1-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:6d530bd11479fb574567af3a1f384af9a77bf5bb9550cde8080b356ca7220d5a", size = 453999200, upload-time = "2026-09-30T17:53:21.716Z" }, + { url = "https://files.pythonhosted.org/packages/7c/cc/bb579ac0c80e077c58204e43b37a254b74dea5873635100bea25789a55d4/torch-2.14.1-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:c8f71aabc67bcbfc9373dc131537a5968d04edce73e88add21354a7cd0a76985", size = 554618164, upload-time = "2026-09-30T17:53:42.73Z" }, + { url = "https://files.pythonhosted.org/packages/7b/4b/32c00cacbe682a4c08d9c6c3e7a7116c912184cc7155f06c64f545db97d1/torch-2.14.1-cp313-cp313-win_amd64.whl", hash = "sha256:711713391d26a1ce5e9fbc6c996d954a8c12e8825374cc77b809a6af29539b8c", size = 124113754, upload-time = "2026-09-30T17:52:33.474Z" }, +] + +[[package]] +name = "tqdm" +version = "4.70.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/0d/ea/b2a5bd54b28a324dae8211928b2d730b6547500342c7e6c6dea08bd0a485/tqdm-4.70.1.tar.gz", hash = "sha256:cefd0eca11b2a37a3aee776544d4f4ae913f02688135b5556b8788dfa474afc4", size = 171846, upload-time = "2026-09-11T07:25:16.601Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a7/03/921a3d3c75785aca9ebfbfcabfbc3a1be12e2ab5265deb026d55a5a3f83e/tqdm-4.70.1-py3-none-any.whl", hash = "sha256:c293e525e6fef9c20e8728fd4612df02a0aa31bb5fe91ecd93e123b1b7bffa73", size = 80199, upload-time = "2026-09-11T07:25:14.599Z" }, +] + +[[package]] +name = "transformers" +version = "5.17.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "huggingface-hub" }, + { name = "numpy" }, + { name = "packaging" }, + { name = "pyyaml" }, + { name = "regex" }, + { name = "safetensors" }, + { name = "tokenizers" }, + { name = "tqdm" }, + { name = "typer" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/0e/9e/750649904a065007a838981785b2bd8d9ff26154c6c341ac67d0b7f82c68/transformers-5.17.0.tar.gz", hash = "sha256:a153be279169b55b92d8000bf4af294aed684503d091cca7804da2dd8a9de000", size = 9817878, upload-time = "2026-09-09T15:39:56.886Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e8/d0/c502b60d684adbd98a8dc7d5bb866842772b816ac4354e4608be240041ae/transformers-5.17.0-py3-none-any.whl", hash = "sha256:78ec1ce21579b38dfb83950a0658cd119f87212a2fcfdff478096ce9d6c03801", size = 12295140, upload-time = "2026-09-09T15:39:53.746Z" }, +] + +[[package]] +name = "triton" +version = "3.8.0" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/87/4d/4c564374bcdadb166fccbf3e45aee0d4a473f88d341761bd2fefe3b8e8c1/triton-3.8.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b7004666652f500ed854a86988e4b3d69d247188b5d2092b5df1e44f4a954099", size = 226476793, upload-time = "2026-08-28T16:08:30.956Z" }, + { url = "https://files.pythonhosted.org/packages/b0/b6/3394d5548404c1cabd1dadadd28d0b3f9478db1dff8180da53bb3f0a1e19/triton-3.8.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1f0497218e26b7d79773ad9c2a3fa3b539ee69f587a13fac2e552b1d322a8015", size = 247975122, upload-time = "2026-08-28T15:56:04.112Z" }, +] + +[[package]] +name = "truststore" +version = "0.10.5" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ee/9f/c5201d42a484c061e528825fc8e2d565f5abd50a4ced6fb7d29c4ec99b2b/truststore-0.10.5.tar.gz", hash = "sha256:30d36967ccaded5cbb38d602c433f53600036c79d502f4533a49b60a03bbefcd", size = 28091, upload-time = "2026-10-12T22:27:31.808Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/51/e9/3a7820be2bb0fe53b6bc9c3be26d3d1158004e4c3ab953aa6840b955b1e9/truststore-0.10.5-py3-none-any.whl", hash = "sha256:9aaaedaefaf06d8b206278cf8b5012bc897f485a874503501e12d776df78951c", size = 19017, upload-time = "2026-10-12T22:27:30.377Z" }, +] + +[[package]] +name = "typer" +version = "0.25.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "annotated-doc" }, + { name = "click" }, + { name = "rich" }, + { name = "shellingham" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e4/51/9aed62104cea109b820bbd6c14245af756112017d309da813ef107d42e7e/typer-0.25.1.tar.gz", hash = "sha256:9616eb8853a09ffeabab1698952f33c6f29ffdbceb4eaeecf571880e8d7664cc", size = 122276, upload-time = "2026-04-30T19:32:16.964Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3f/f9/2b3ff4e56e5fa7debfaf9eb135d0da96f3e9a1d5b27222223c7296336e5f/typer-0.25.1-py3-none-any.whl", hash = "sha256:75caa44ed46a03fb2dab8808753ffacdbfea88495e74c85a28c5eefcf5f39c89", size = 58409, upload-time = "2026-04-30T19:32:18.271Z" }, +] + +[[package]] +name = "types-protobuf" +version = "7.35.1.20260906" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e1/6c/e3e5b3e10bc328126a39637c138f9ebfd734bf14342b9f3540039b4ab995/types_protobuf-7.35.1.20260906.tar.gz", hash = "sha256:efd1a3862d4c967dad5512ef8d56b1530ac84f182c41735b94004756518c4998", size = 69895, upload-time = "2026-09-06T06:35:28.308Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/44/4e/f63e826c68f77ef875506d72f225918800346545ee99847bc28f3394f18d/types_protobuf-7.35.1.20260906-py3-none-any.whl", hash = "sha256:5155e48569e0dabff303fdf578db96cd31ea9a4a63b18018a4ceac6b0ae17462", size = 86419, upload-time = "2026-09-06T06:35:27.247Z" }, +] + +[[package]] +name = "types-requests" +version = "2.33.0.20261006" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "urllib3" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/57/15/9b7e2e2e7c87d01366185b198b3febc6bc0c973f2bf21a62da4ab7d3495e/types_requests-2.33.0.20261006.tar.gz", hash = "sha256:0652999e9306aea345f40732d58fa49a7f6cade6a0d74d92119c5c8d82eddaf0", size = 25316, upload-time = "2026-10-06T08:15:57.782Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4d/72/b82789207b3d360ce9f5a4372c790c52cc3dd928aeb7d4faeec652b651b2/types_requests-2.33.0.20261006-py3-none-any.whl", hash = "sha256:26cc8146505cab33cda9737991929e4144c559bebe05078ccc6998f27c4ca2c1", size = 21445, upload-time = "2026-10-06T08:15:56.658Z" }, +] + +[[package]] +name = "typing-extensions" +version = "4.16.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f6/cc/6253133b5bb138fc3306cebfbda2c520f545d36b5be2c7255cc528bb45d6/typing_extensions-4.16.0.tar.gz", hash = "sha256:dc983d19a509c94dba722ee6abd33940f7c05a89e243c47e907eb4db6f1a43e5", size = 113555, upload-time = "2026-07-02T08:40:05.92Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/49/d3/b8441a820a491ddfc024b0b0cf0393375b75ea13866d9c66727e54c2fc80/typing_extensions-4.16.0-py3-none-any.whl", hash = "sha256:481caa481374e813c1b176ada14e97f1f67a4539ce9cfeb3f350d78d6370c2e8", size = 45571, upload-time = "2026-07-02T08:40:04.659Z" }, +] + +[[package]] +name = "typing-inspection" +version = "0.4.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a3/26/b09b8010994eccc3c09092e6b34058f36a460eea2d4c3e8b910c695975a0/typing_inspection-0.4.4.tar.gz", hash = "sha256:547274fa6b0a561ccf549cc9524b999a578e737d015d8709d021f9d0d13bea47", size = 76928, upload-time = "2026-08-12T12:37:25.997Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/67/81/4add07e5172b7ac40d8ed5ff580409a7801a4fe26d529bdd915401dabfbe/typing_inspection-0.4.4-py3-none-any.whl", hash = "sha256:65b8397ba37ccbce054456aaccddfc91e6e3083c92824df348d96ca832f3f147", size = 14750, upload-time = "2026-08-12T12:37:24.648Z" }, +] + +[[package]] +name = "tzdata" +version = "2026.5" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d9/68/f1b440335057bfce71b6e50a9d09445aa2ecbd08359a337976627b8409e7/tzdata-2026.5.tar.gz", hash = "sha256:8cc73c0a0bfca7dbfa59235d60b2eff82231dee33f53d206db1acd9173cfc0a7", size = 200404, upload-time = "2026-10-03T09:23:14.143Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/94/21/1e5995a1c920cce14e4bffae20c665ec10e7ed03ab25e006cd741092b718/tzdata-2026.5-py2.py3-none-any.whl", hash = "sha256:b683bd1b6659ddcd810ff02ad09ba821d4bf1065072805063eb35c49617905ac", size = 347996, upload-time = "2026-10-03T09:23:12.535Z" }, +] + +[[package]] +name = "urllib3" +version = "2.8.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e3/05/b17359e1cefb4f909b5e40b1b90a496d987258916dbbf88e842c729f510e/urllib3-2.8.0.tar.gz", hash = "sha256:63bf2ead4c879426ebf22ef2a781eeb4aa3b4ae798a0435506f8687fd5bb9b63", size = 458972, upload-time = "2026-09-15T19:29:36.253Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/92/9d/c4e665119135114480843e7ab388fa94d8480650450e6f8e26b70d323a4c/urllib3-2.8.0-py3-none-any.whl", hash = "sha256:0cf3cae568d36aa9576b28dfb35f11328f1cb974ca7647d9475ebb86c75ac6e3", size = 135717, upload-time = "2026-09-15T19:29:34.577Z" }, +] + +[[package]] +name = "uvicorn" +version = "0.54.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "click" }, + { name = "h11" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/da/34/30e9280707135d2cfc589dfff3cb796bd07a3aeb1a3e415ba09dd89d7bb4/uvicorn-0.54.0.tar.gz", hash = "sha256:a2e33cbfaa0306f8e6b0c13e0cb89d7d7a2da3e62b90c66e18c33d9807b28620", size = 112283, upload-time = "2026-09-25T06:52:37.601Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/38/0c/b54a4fdd7f90a3af8b02ebc9ce6712c2c208b7926a2f7bad95c33ebbe943/uvicorn-0.54.0-py3-none-any.whl", hash = "sha256:505bdb0f318731d45f1f712071fc781a8981f6847a31c902c9f5e652d4f67faf", size = 87427, upload-time = "2026-09-25T06:52:35.829Z" }, +] + +[[package]] +name = "wasabi" +version = "1.1.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ac/f9/054e6e2f1071e963b5e746b48d1e3727470b2a490834d18ad92364929db3/wasabi-1.1.3.tar.gz", hash = "sha256:4bb3008f003809db0c3e28b4daf20906ea871a2bb43f9914197d540f4f2e0878", size = 30391, upload-time = "2024-05-31T16:56:18.99Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/06/7c/34330a89da55610daa5f245ddce5aab81244321101614751e7537f125133/wasabi-1.1.3-py3-none-any.whl", hash = "sha256:f76e16e8f7e79f8c4c8be49b4024ac725713ab10cd7f19350ad18a8e3f71728c", size = 27880, upload-time = "2024-05-31T16:56:16.699Z" }, +] + +[[package]] +name = "wcwidth" +version = "0.9.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f0/b4/7830542634bb2d3e62aa3b586a72d5b3b6c91c3168929e7000ef3fed041d/wcwidth-0.9.2.tar.gz", hash = "sha256:ae0ef90b90f6af38b54f1fe6d58662ec33b3cb4b8391958a62416d654231727b", size = 955039, upload-time = "2026-10-05T00:24:05.521Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/59/1e/4532a81fb9dfbf4114a816775e0a36c3a64ee1d1f4bba2094e2da50be5dc/wcwidth-0.9.2-cp310-abi3-macosx_10_9_x86_64.whl", hash = "sha256:7ef5a940bd5e30bac6e721f1a48fce0cd7bb3ece19e9c5d139e72c76c35cfd07", size = 605343, upload-time = "2026-10-05T00:23:22.649Z" }, + { url = "https://files.pythonhosted.org/packages/a0/07/cb6940e81134b7ed25fa312ee9ab536a63db0793b149f88a90e603ceace9/wcwidth-0.9.2-cp310-abi3-macosx_11_0_arm64.whl", hash = "sha256:ae0800c5339423cc53d33a266ad264b42ba8aaa16d4464f6e6b1bee607f50b17", size = 609960, upload-time = "2026-10-05T00:23:27.049Z" }, + { url = "https://files.pythonhosted.org/packages/a4/80/15ad05d40bfa99155639fb9e13b3d77083aa0fab893c816db2543d29005c/wcwidth-0.9.2-cp310-abi3-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:9e542f1f8475b78452a295495d7a5bc3ead565112e9446a64dc93462a41c2a79", size = 762566, upload-time = "2026-10-05T00:23:38.322Z" }, + { url = "https://files.pythonhosted.org/packages/bc/f0/b8ef7758003d66b60f093695831a86dcc726aac01ee6446ffcbda27b61e3/wcwidth-0.9.2-cp310-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:674b518af28d38ee645ff97b74f5760abee5fad4bac74413bfc4b881ef2ce724", size = 771632, upload-time = "2026-10-05T00:23:32.448Z" }, + { url = "https://files.pythonhosted.org/packages/db/6c/f940133c71427c208575910e981942bd78c98b1f7cd0d1425ca4b7457c04/wcwidth-0.9.2-cp310-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:751bef0ab404b6a1dc028b56b4b85d46486be1c55833f80da533e42dc691f389", size = 769763, upload-time = "2026-10-05T00:23:40.175Z" }, + { url = "https://files.pythonhosted.org/packages/92/8f/285f862826f721964ec7c42f81dc53d23afbd723a0f4cd989651f8218e25/wcwidth-0.9.2-cp310-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:c3d80f39ba4653a595edae9aa46a509d14883790a8fc23c5db221ceb207f64b7", size = 782134, upload-time = "2026-10-05T00:23:33.926Z" }, + { url = "https://files.pythonhosted.org/packages/c2/2d/64aa54882a5d556d3654c1f926d9118b797461033e23a158409941a37c8f/wcwidth-0.9.2-cp310-abi3-musllinux_1_2_i686.whl", hash = "sha256:0a47e03d8293590ecce66c45dc20ff7b4b885e3c78093722239585eca0d77ab2", size = 782851, upload-time = "2026-10-05T00:23:41.974Z" }, + { url = "https://files.pythonhosted.org/packages/59/39/52389f6de7fe2e9c14ceb8253dd99034bd86e1c87847ea3c100a97dded9a/wcwidth-0.9.2-cp310-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:67d901a4ad99249eb775b4ee4769ca97fa405d35a75f46e83166910a47003f04", size = 784621, upload-time = "2026-10-05T00:23:43.449Z" }, + { url = "https://files.pythonhosted.org/packages/b3/8b/20225500a076ace27bbcc8a6fd7c55125133c57a618816c7b7b8b73070b1/wcwidth-0.9.2-cp310-abi3-win32.whl", hash = "sha256:ee1fd0db9d9fd711a70f3e7765e0e04c05d26982fa05361456163062549d7da4", size = 593123, upload-time = "2026-10-05T00:23:55.953Z" }, + { url = "https://files.pythonhosted.org/packages/5a/d6/b0690f55ea0483530a18bac917fbadbf54f35122510446fc370f5f1c2453/wcwidth-0.9.2-cp310-abi3-win_amd64.whl", hash = "sha256:2a9746de704242bd4fdaabb31dd46b82f694a56a8d21081ad89b679a89da9fec", size = 597827, upload-time = "2026-10-05T00:23:57.489Z" }, + { url = "https://files.pythonhosted.org/packages/e5/11/6ecf4e9e268ab1a4ec617ffcccc2ee4a71301625f5490912dbaba462fa9c/wcwidth-0.9.2-cp310-abi3-win_arm64.whl", hash = "sha256:b9c6ab615e03723b7f8760ea2f27758d656e7e13b51515c9dca5c3e8b04612fa", size = 598415, upload-time = "2026-10-05T00:23:51.517Z" }, + { url = "https://files.pythonhosted.org/packages/9c/b4/0bfa065af506540d9d558e3e5548cff00bc1f9b24e6e2a8512498e8628de/wcwidth-0.9.2-py3-none-any.whl", hash = "sha256:89ca642c5bf0101157a09366be69fad0379db1f700ae39a920e103234573670e", size = 301667, upload-time = "2026-10-05T00:23:21.097Z" }, +] + +[[package]] +name = "weasel" +version = "1.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cloudpathlib" }, + { name = "confection" }, + { name = "httpx" }, + { name = "packaging" }, + { name = "pydantic" }, + { name = "smart-open" }, + { name = "srsly" }, + { name = "typer" }, + { name = "wasabi" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ce/e5/e272bb9a045105a1fdf4b798d8086f5932a178f4d738f17a74f5c9e0ae9a/weasel-1.0.0.tar.gz", hash = "sha256:7b129b44c90cc543b760532974ca1e4eb30dad2aa2026f57bdce66354ae610fc", size = 38682, upload-time = "2026-03-20T08:10:25.266Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0a/07/57ebf7a6798b016c064bd0ca81b4c6a99daa4dc377b898bc7b41eb6b5af0/weasel-1.0.0-py3-none-any.whl", hash = "sha256:89518acee027f49d743126c3502d35e6dd14f5768be5c37c9af47c171b6005cc", size = 50713, upload-time = "2026-03-20T08:10:23.637Z" }, +] + +[[package]] +name = "websockets" +version = "16.1.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/21/f7/bc3a25c5ec26ce62ce487690becc2f3710bbc7b33338f005ad390db0b986/websockets-16.1.1.tar.gz", hash = "sha256:db234eda965dcce15df96bb9709f587cd87d4d52aaf0e80e2f34ec04c7670c57", size = 182204, upload-time = "2026-07-17T22:51:05.858Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ce/fd/6ec6c6d2850aea25b1b2aa9901a016980bb87d01e89b3eb00470b1b5d471/websockets-16.1.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ab59169ace05dcb49a1d4118f0bde139557adf45091bd85747e36bf5de984dd1", size = 179587, upload-time = "2026-07-17T22:49:38.959Z" }, + { url = "https://files.pythonhosted.org/packages/5f/d8/1d299d2dd34087db39831a34cc645ef8a6f89d78efada6983093513cd81c/websockets-16.1.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:5e3b7d601f6f84156b08cc4a5e541c2b50ad7b36cfc302b657a12477c904a5df", size = 177272, upload-time = "2026-07-17T22:49:40.293Z" }, + { url = "https://files.pythonhosted.org/packages/3d/86/0a70d3ae2f0f2256bb41302d9804dbca65d4360281e7feb3e1f94102ac46/websockets-16.1.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:cd2ca96a082a36964aca83e992f72abeb61b7306c1a6cba4c7d06a7b93750cac", size = 177530, upload-time = "2026-07-17T22:49:41.786Z" }, + { url = "https://files.pythonhosted.org/packages/b5/c2/c676c69444d9db448b3f0a55a98dcc534affce0bce961d9d2f0b8499b10a/websockets-16.1.1-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:f5d497865f05bb222cab7016c6034542e84e5f29f49c6fd3f4939cda7197b5b8", size = 187197, upload-time = "2026-07-17T22:49:43.658Z" }, + { url = "https://files.pythonhosted.org/packages/0b/13/88137fbaf726ebe29d62c1117fa11fa2bbb6209dc79d4ad738efbe36a2aa/websockets-16.1.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bae954c382e013d5ea5b190d2830526bfa45ad121c326da0049b8c769f185db6", size = 188433, upload-time = "2026-07-17T22:49:45.147Z" }, + { url = "https://files.pythonhosted.org/packages/01/6d/46c2f2ce6751cb26f39293e1ecbf8544cb01321397cd476c2756b98c216d/websockets-16.1.1-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e09f753a169951eb4f28c2c774f71069304f66e7277e0f5a2892423599cfa854", size = 189868, upload-time = "2026-07-17T22:49:46.581Z" }, + { url = "https://files.pythonhosted.org/packages/29/2b/170a9e8097636cfde4dc3c592b6e00b18a44a2f5407606d96ca542dd5838/websockets-16.1.1-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:024193f8551a2b0eafbdd160911012c4e6c228c28430c84433253299a9e42d6a", size = 189059, upload-time = "2026-07-17T22:49:47.972Z" }, + { url = "https://files.pythonhosted.org/packages/a7/48/f0d4ebc9ab4b473b8861b9e20fdb663d515d42f7befdf62cdb60fee7a1ec/websockets-16.1.1-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:aabe464bfd13bd25f4821faf111da6fefdc389f870265a53105580e45b0a2e49", size = 187814, upload-time = "2026-07-17T22:49:49.344Z" }, + { url = "https://files.pythonhosted.org/packages/d5/ba/39a41d3ae8e72696a9492581900611c5a91e2b07563b0bcd2523adea9854/websockets-16.1.1-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:a28fcbc9b6baf54a2e23f8655f308e4ccc6afdd7266f8fe7954f320dcda0f785", size = 185229, upload-time = "2026-07-17T22:49:50.787Z" }, + { url = "https://files.pythonhosted.org/packages/3c/36/ac15b604f850d1907f0a85ed721cefe47cd45034b3620069b829746cccbe/websockets-16.1.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:79eace538c6a97e96d0d03d4f9d314f9677f5ed85a8a984992ffd90b13cb8a56", size = 187874, upload-time = "2026-07-17T22:49:52.228Z" }, + { url = "https://files.pythonhosted.org/packages/a8/f3/3fbd5d71d59299c3770faa5884d4f45070236ca5a35ab3a61830812c409a/websockets-16.1.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:496af849a472b531f758dbd4d61338f5000538cb1a7b3d20d9d32a264517f509", size = 186469, upload-time = "2026-07-17T22:49:53.776Z" }, + { url = "https://files.pythonhosted.org/packages/b4/fc/dd90349bba58af2a53ef2ddd9c32716c81eb6d59a0687939fff561860878/websockets-16.1.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:5283810d2646741a0d8da2aa733d6aefa0545809afccb2a5d105a26bc45125f1", size = 188347, upload-time = "2026-07-17T22:49:55.202Z" }, + { url = "https://files.pythonhosted.org/packages/4c/f3/f73ba86427682da59b78c11d77ba56d5b801c32e84afe79b274bbd6a9bb2/websockets-16.1.1-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:4e3b680b1e0a27457e727a0d572fd81dffa87b6dbf8b228ab57da64f7d85aead", size = 185903, upload-time = "2026-07-17T22:49:56.75Z" }, + { url = "https://files.pythonhosted.org/packages/34/7c/f95eb20e80104173b3a0a092291f89ea4047ef6e608e0a57ca06eb14eecb/websockets-16.1.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:69159730a823dde3ea8d08783e8d47ef135a6d7e8d44eb127e32b321c9db8e3e", size = 186855, upload-time = "2026-07-17T22:49:58.467Z" }, + { url = "https://files.pythonhosted.org/packages/b0/35/dd875b3e050ff232d60fa377707f890e369f74d134f1be32e8f68879747c/websockets-16.1.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ed5bb271084b46530ee2ddc0410537a9961152c5ccba2fc98c5276d992ccba87", size = 187140, upload-time = "2026-07-17T22:50:00.016Z" }, + { url = "https://files.pythonhosted.org/packages/e8/dc/5cbfcb41824502f6af93b8f3943a4d06c67c23c7d2e31eb18748c4a5b2a7/websockets-16.1.1-cp313-cp313-win32.whl", hash = "sha256:cfb70b4eb56cac4da0a83588f3ad50d46beb0690391082f3d4e2d488c70b68ea", size = 179928, upload-time = "2026-07-17T22:50:01.685Z" }, + { url = "https://files.pythonhosted.org/packages/b0/c1/71e5deb5b7f8f226997ab64908c184ac3105c0155ce2d486f318e5dd08a8/websockets-16.1.1-cp313-cp313-win_amd64.whl", hash = "sha256:d9531d9cbeac99af6f038fb1bc351403531f7d634a2c2e10e2f7c854c6ed5b68", size = 180242, upload-time = "2026-07-17T22:50:03.117Z" }, + { url = "https://files.pythonhosted.org/packages/be/4d/2d0d67834092e354d2b0498f014a41249a89556bc406cf86f3e1557bb463/websockets-16.1.1-py3-none-any.whl", hash = "sha256:6abbd3e82c731c8e531714466acd5d87b5e88ac3243465337ba71d68e23ae7e3", size = 173814, upload-time = "2026-07-17T22:51:04.184Z" }, +] + +[[package]] +name = "wrapt" +version = "2.5.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/04/22/89e2f3bdae5cb34e0cab0cd86d7172dbf418de4b46c9b17b9c7a560dfa44/wrapt-2.5.1.tar.gz", hash = "sha256:f595bb0185aab3e9dc31950c95d914f56ea8278810c3b928f3426e12ed6d27bc", size = 184455, upload-time = "2026-10-14T00:39:39.24Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e4/6d/cfe55762435f36107815d56a2cfbebe7e3129b593c47a670c6eb1d7917d3/wrapt-2.5.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f98eaf784cd12bc69c77af398084174531007cd81849c962163ccfc6e791f3ea", size = 106068, upload-time = "2026-10-14T00:37:36.087Z" }, + { url = "https://files.pythonhosted.org/packages/01/b9/41642877fe741db56d240833c8822188b663c4c5d52beb087964774035d4/wrapt-2.5.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:ab6db7d2a18d366cc57c2228253cf26443190aba0a6dd0939b3c1e8ac6e29e2c", size = 106190, upload-time = "2026-10-14T00:37:37.768Z" }, + { url = "https://files.pythonhosted.org/packages/37/62/20edad100b93552ec5c172e509a9db898a73d5043ae701fcb6e9986f9d33/wrapt-2.5.1-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:f1630201b0e2a96bb26304b7adfbd91a4ef486abb5a4c48377444a0bed749f37", size = 248519, upload-time = "2026-10-14T00:37:39.321Z" }, + { url = "https://files.pythonhosted.org/packages/3d/e9/8d81185bc9a40cfb43d91fc70a1e80ecde752c95dc98f5452cae82037976/wrapt-2.5.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d800c7689154622b0ba2922ceca44a3cf2ef61c3b9a4c4eeb1d8b3050d7ededa", size = 248488, upload-time = "2026-10-14T00:37:40.96Z" }, + { url = "https://files.pythonhosted.org/packages/8a/88/8431df4fd81f0dfa83e8ede463eed311d083c5a279a56891dc0396b07b0e/wrapt-2.5.1-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:5b53000b424dc2133eaaf22838a2352d3497f5d7c2e7d9a2acfe675ab7225bb1", size = 227392, upload-time = "2026-10-14T00:37:42.599Z" }, + { url = "https://files.pythonhosted.org/packages/db/8a/ee6f8542eeccad6874faf0b7b2e129952c527a482f1d28940e2111fec2d6/wrapt-2.5.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:76f230a9b07e3cb66646d265398f579abb6128b1bb4cb97c74b1ae5d09e96f31", size = 244972, upload-time = "2026-10-14T00:37:44.209Z" }, + { url = "https://files.pythonhosted.org/packages/4d/1f/32c59e7fd522409f3863dfecdab5315ee9ba37f96020b6f0adee9d223310/wrapt-2.5.1-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:fd3f878a4aac3c262447ddf43c5f4c18fc67dfc3ba69c4fb1c7a4c4af96abe7e", size = 225316, upload-time = "2026-10-14T00:37:45.948Z" }, + { url = "https://files.pythonhosted.org/packages/ae/d6/1b9abc1244592034c5db744571e17d663f0f1b0ce6c8ba279c60f6f9c3a8/wrapt-2.5.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0c9480bdee340a1602cae5a777146ab4be3e384fdcb569fffdf8721032314645", size = 237145, upload-time = "2026-10-14T00:37:47.535Z" }, + { url = "https://files.pythonhosted.org/packages/f0/ce/8f3b5482f768c1d60fd2557d049c766543fef5ec707037cb410a57eb65ee/wrapt-2.5.1-cp313-cp313-win32.whl", hash = "sha256:dc401274fcc7b15b3b2c12df2ff34024a11925243a7d3daee91c6d7d14f9addf", size = 100462, upload-time = "2026-10-14T00:37:49.21Z" }, + { url = "https://files.pythonhosted.org/packages/7b/dc/6a5735874ea79816f85c1ec9d92139d7073c20d1881c15ff2108c211354b/wrapt-2.5.1-cp313-cp313-win_amd64.whl", hash = "sha256:09b1893ee4063706574c1813abf479b8b51926633fbdb6f96aab8dc7b0976668", size = 105870, upload-time = "2026-10-14T00:37:50.745Z" }, + { url = "https://files.pythonhosted.org/packages/08/83/a4e8b5a5a32f8dfc5dad8344f1e2b908f7d8d84b11c3c336bf7f79a5144a/wrapt-2.5.1-cp313-cp313-win_arm64.whl", hash = "sha256:f280c115ea64eff3dcbd68a668ce3f63476a4ba386bbabb318017e286196ea2c", size = 102903, upload-time = "2026-10-14T00:37:52.323Z" }, + { url = "https://files.pythonhosted.org/packages/bc/0c/7da7513ddcc8f1d831ec4bfbedc9f7f174ecb91042bc16916fc1e0d06b22/wrapt-2.5.1-py3-none-any.whl", hash = "sha256:c6e6c226b1ca5402d7ae5fb34a0d21f1b49124fe4200e5884d1e19e53c47ac1d", size = 81849, upload-time = "2026-10-14T00:39:37.441Z" }, +] + +[[package]] +name = "xai-sdk" +version = "1.20.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "aiohttp" }, + { name = "googleapis-common-protos" }, + { name = "grpcio" }, + { name = "opentelemetry-sdk" }, + { name = "packaging" }, + { name = "protobuf" }, + { name = "pydantic" }, + { name = "requests" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/bf/2b/a03f4a0495e279ece44920bba9da85abe15c3a14ec8eecd683608db63763/xai_sdk-1.20.0.tar.gz", hash = "sha256:ae10fd1713b20a852ffc9909d83233550a3193bd718f77a891ca1485f08e5fb3", size = 473156, upload-time = "2026-09-24T18:05:37.484Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/55/be/ac8c239f2a38172fb59763d6715bbf24864e24319ccdd7a09894c7644d1c/xai_sdk-1.20.0-py3-none-any.whl", hash = "sha256:cfd64983c48c78a647460a2e8ee136e6a35929249989b6c9be6387fdf86d661f", size = 281393, upload-time = "2026-09-24T18:05:35.82Z" }, +] + +[[package]] +name = "yarl" +version = "1.25.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "idna" }, + { name = "multidict" }, + { name = "propcache" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/75/16/e8be8e2fb175bbf41a0680381a319f1199fae256588241a2ac8677eafb49/yarl-1.25.1.tar.gz", hash = "sha256:03dd38de09bc213e9a8b29761eec33ee1d5318dac0e49d8af36e4d27830e23a7", size = 246245, upload-time = "2026-09-15T19:35:02.264Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7b/ed/2f3129bbcc9a5c8ba12cc2b29d8060a3bab9c8043c456cfd4b5ca3188890/yarl-1.25.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:25868beca8b6765f8f7d0e11fe6dd7c66dd4b0793b9500286d20cc92352126a5", size = 143623, upload-time = "2026-09-15T19:31:37.966Z" }, + { url = "https://files.pythonhosted.org/packages/17/e1/f1bc3390fdca352826676b531d0712736f156919090206700421d46b2c37/yarl-1.25.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:10b2fd95332f0d716d5eee3c9fb2ce8eada19082de7fee83d32e37992fd75c26", size = 104011, upload-time = "2026-09-15T19:31:40.25Z" }, + { url = "https://files.pythonhosted.org/packages/a8/aa/50acc5c3e5da04172ae3c281c75405af4d2ca911e16120ab0563f4dffb66/yarl-1.25.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0f12afda4eea8c8994a76d4df1875c765194f5fbe8a9d197929ea303caee29ec", size = 103677, upload-time = "2026-09-15T19:31:42.46Z" }, + { url = "https://files.pythonhosted.org/packages/30/d2/7d1e0ab9f8390e1fbcede5a6dbf70d23c96ad09b8c5567f3a514d1ddb0e2/yarl-1.25.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:14b79a30a93a3ce2e8832603fd0ab780ada281b0ba5110b519a634f2d7d7d1fc", size = 115392, upload-time = "2026-09-15T19:31:44.371Z" }, + { url = "https://files.pythonhosted.org/packages/71/e1/5ba1e3a2a22139213655e760919038e8ed7e2d4a99826d0bbddb3beb96e5/yarl-1.25.1-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:4bd6340d20ae2c7ca719b87b426e808e90743b676d05d4c26c4fb5ca71f41184", size = 107493, upload-time = "2026-09-15T19:31:46.273Z" }, + { url = "https://files.pythonhosted.org/packages/f5/53/780653d5e0f73831f467cf13548912e5eec97f21dc49fc8daf21da027df4/yarl-1.25.1-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:126a2533570c554719ca40a1288fdee1700b6bc82e7131aa69fa85252d92e651", size = 122537, upload-time = "2026-09-15T19:31:48.654Z" }, + { url = "https://files.pythonhosted.org/packages/03/92/d54fa70236c6036271c9c9c09fd978df5cbe3ef49ef6c46e9b833476d215/yarl-1.25.1-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a3faadac7d812ddac258feb57b9846b60c1b437c4f4b9ad42595c6f6fe4390df", size = 126170, upload-time = "2026-09-15T19:31:50.872Z" }, + { url = "https://files.pythonhosted.org/packages/0e/b7/a82a49bf88340b837ef6972b508a1604ae377b9e6904b46b10cf5f1cf925/yarl-1.25.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:be80550d9bfe83d9b62398a37081a90434e6df2d978ec345c3d2820de6beddab", size = 117012, upload-time = "2026-09-15T19:31:53.189Z" }, + { url = "https://files.pythonhosted.org/packages/ef/78/5d684b411e3f3602464ee9b538db48205038f8605872985f61efb809ced0/yarl-1.25.1-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e07595c7d6f4db270ceede356a1bd1c07a34f1c26f958d1ed0cd7b48e0d2bba3", size = 114950, upload-time = "2026-09-15T19:31:55.694Z" }, + { url = "https://files.pythonhosted.org/packages/2f/11/51d82b852c64f7fad0fc7a7ff3031517204887e874c722bbca839c0b23ac/yarl-1.25.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:eb96ed1ae6c7d072d60840c0434aef07a2df611812810807fbc54263a6053e9a", size = 115428, upload-time = "2026-09-15T19:31:57.966Z" }, + { url = "https://files.pythonhosted.org/packages/e4/49/9d1978049bf646b9ea918313926453c6901b71c92f097467777d47d36a88/yarl-1.25.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:3feb99222553a8cbedfa52c2f59dd84c3f50d5b582c728d522caf8d72769a54b", size = 108428, upload-time = "2026-09-15T19:32:00.048Z" }, + { url = "https://files.pythonhosted.org/packages/43/35/7b8f1ebb45d7ec3dda7d1909bf44f458de41ef91e2937f107733582a5166/yarl-1.25.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:a2ed0ba415ccdf08f14bf544cb78346d0f76086707ffee24921a2c84dbf1305a", size = 121961, upload-time = "2026-09-15T19:32:02.436Z" }, + { url = "https://files.pythonhosted.org/packages/63/d6/d8b689ab7ca26edeb85f6ff28812aac7a25376eefc1780e303a7bfbaceff/yarl-1.25.1-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:2b49375d22299b0a834c2bca72f39aaecc270d96fb24c30424899676f487b22a", size = 114961, upload-time = "2026-09-15T19:32:04.456Z" }, + { url = "https://files.pythonhosted.org/packages/cf/d5/1a1798ea4dc6b7ee3260010a27907ebc697c95dae99817d817ed446d24aa/yarl-1.25.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:ef74070ac553c59eb4f04258722066d6c6135b7baa03b2e9f2da65c096e96d98", size = 120036, upload-time = "2026-09-15T19:32:06.5Z" }, + { url = "https://files.pythonhosted.org/packages/91/8d/b1b35ed7903da6669b1d367cb2c09436acd4ff508029b4f39a0c0c2058fc/yarl-1.25.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0a66db89ea473abeac4b70523cafd94db3772380e565f9d28af7a179b7af71fa", size = 117276, upload-time = "2026-09-15T19:32:09.401Z" }, + { url = "https://files.pythonhosted.org/packages/3a/8f/4db01cef62caff0d7a4593ed694fb8a41a27a11158cab80d290221f13e57/yarl-1.25.1-cp313-cp313-win_amd64.whl", hash = "sha256:1f51020b2eb8a003c84925638ec63c21a750a4bddd3a22ec8eac6a742dadf1b9", size = 101945, upload-time = "2026-09-15T19:32:11.545Z" }, + { url = "https://files.pythonhosted.org/packages/c0/5e/3ce00497c5c0babb74d4130c10c3828ccd215b4819d12020c42429f991ac/yarl-1.25.1-cp313-cp313-win_arm64.whl", hash = "sha256:b10dd0557ba422715b5206b3743192135a6022acca8baec51aa127d0a75db8fe", size = 97270, upload-time = "2026-09-15T19:32:14.127Z" }, + { url = "https://files.pythonhosted.org/packages/54/22/318c7980066769c6bcd9221ed2248294f5698811da099013098c670565ed/yarl-1.25.1-py3-none-any.whl", hash = "sha256:681c758b0490f9e96b78e5fa8e8dc6e648e9185bb6eaebe73183c33ea0c445f3", size = 63617, upload-time = "2026-09-15T19:34:59.616Z" }, +] From 2f1ee7145ea8af51e7f2487fb14b1a7a10667f2f Mon Sep 17 00:00:00 2001 From: Andres Contreras Date: Wed, 14 Oct 2026 12:53:23 -0700 Subject: [PATCH 15/20] Qualify combined query safety and Agentic adoption as 26.10.2 --- CHANGELOG.md | 34 +++++++++++++++++ README.md | 2 +- Taskfile.yml | 4 +- docs/release.md | 6 +-- docs/sdks.md | 4 +- docs/security-model.md | 37 +++++++++---------- openapi.json | 10 +---- pyfly.yaml | 2 +- pyproject.toml | 2 +- sdks/java/README.md | 6 +-- sdks/java/api/openapi.yaml | 20 ++++------ sdks/java/build.gradle | 2 +- sdks/java/pom.xml | 2 +- .../java/com/firefly/flyquery/ApiClient.java | 2 +- .../firefly/flyquery/JavaTimeFormatter.java | 2 +- .../firefly/flyquery/RFC3339DateFormat.java | 2 +- .../flyquery/RFC3339InstantDeserializer.java | 2 +- .../flyquery/RFC3339JavaTimeModule.java | 2 +- .../firefly/flyquery/ServerConfiguration.java | 2 +- .../com/firefly/flyquery/ServerVariable.java | 2 +- .../java/com/firefly/flyquery/StringUtil.java | 2 +- .../com/firefly/flyquery/auth/ApiKeyAuth.java | 2 +- .../firefly/flyquery/auth/Authentication.java | 2 +- .../firefly/flyquery/auth/HttpBasicAuth.java | 2 +- .../firefly/flyquery/auth/HttpBearerAuth.java | 2 +- .../flyquery/model/AgentTokenCreated.java | 2 +- .../flyquery/model/AgentTokenMintRequest.java | 2 +- .../flyquery/model/AgentTokenSummaryDto.java | 2 +- .../firefly/flyquery/model/AgentUsage.java | 2 +- .../flyquery/model/AnswerResponse.java | 2 +- .../flyquery/model/AuditEventRead.java | 2 +- .../flyquery/model/BatchQueryItem.java | 2 +- .../flyquery/model/BatchQueryRequest.java | 2 +- .../flyquery/model/BatchQueryResponse.java | 2 +- .../flyquery/model/BatchQueryResultItem.java | 2 +- .../flyquery/model/BillingBreakdownItem.java | 2 +- .../firefly/flyquery/model/BillingRollup.java | 2 +- .../flyquery/model/BulkFileResult.java | 2 +- .../model/BulkFileUploadResponse.java | 2 +- .../flyquery/model/CallbackConfig.java | 2 +- .../model/CallbackDeliveryListResponse.java | 2 +- .../flyquery/model/CallbackDeliveryRead.java | 2 +- .../flyquery/model/CancelResponse.java | 2 +- .../flyquery/model/ClarificationFrame.java | 2 +- .../firefly/flyquery/model/Confidence.java | 2 +- .../flyquery/model/ConversationCreate.java | 2 +- .../flyquery/model/ConversationRead.java | 2 +- .../model/ConversationTurnRequest.java | 2 +- .../com/firefly/flyquery/model/CostCents.java | 2 +- .../firefly/flyquery/model/CostCents1.java | 2 +- .../firefly/flyquery/model/CostEventRead.java | 2 +- .../firefly/flyquery/model/DatasetCreate.java | 2 +- .../firefly/flyquery/model/DatasetRead.java | 2 +- .../firefly/flyquery/model/DatasetUpdate.java | 2 +- .../flyquery/model/DeriveTableRequest.java | 2 +- .../flyquery/model/DeriveTableResponse.java | 2 +- .../firefly/flyquery/model/DetailInner.java | 2 +- .../firefly/flyquery/model/ExampleCreate.java | 2 +- .../firefly/flyquery/model/ExampleRead.java | 2 +- .../flyquery/model/ExplainResponse.java | 2 +- .../flyquery/model/FileUploadResponse.java | 2 +- .../flyquery/model/GlossaryTermCreate.java | 2 +- .../flyquery/model/GlossaryTermRead.java | 2 +- .../flyquery/model/GlossaryTermUpdate.java | 2 +- .../flyquery/model/HTTPValidationError.java | 2 +- .../flyquery/model/IngestCostCents.java | 2 +- .../model/IngestEventListResponse.java | 2 +- .../flyquery/model/IngestEventRead.java | 2 +- .../flyquery/model/IngestJobCreate.java | 2 +- .../flyquery/model/IngestJobListResponse.java | 2 +- .../firefly/flyquery/model/IngestJobRead.java | 2 +- .../firefly/flyquery/model/LocationInner.java | 2 +- .../flyquery/model/OtherCostCents.java | 2 +- .../model/PaginatedAuditEventRead.java | 2 +- .../model/PaginatedConversationRead.java | 2 +- .../model/PaginatedCostEventRead.java | 2 +- .../flyquery/model/PaginatedDatasetRead.java | 2 +- .../flyquery/model/PaginatedExampleRead.java | 2 +- .../model/PaginatedGlossaryTermRead.java | 2 +- .../model/PaginatedQueryHistoryItem.java | 2 +- .../flyquery/model/PaginatedRelationRead.java | 2 +- .../model/PaginatedSchemaChangeRead.java | 2 +- .../model/PaginatedSchemaObjectRead.java | 2 +- .../model/PaginatedSemanticDimensionRead.java | 2 +- .../model/PaginatedSemanticMetricRead.java | 2 +- .../model/PaginatedSemanticVersionRead.java | 2 +- .../flyquery/model/PaginatedSnapshotRead.java | 2 +- .../flyquery/model/PaginatedTableRead.java | 2 +- .../model/PaginatedWorkspaceRead.java | 2 +- .../firefly/flyquery/model/PurgeAccepted.java | 2 +- .../flyquery/model/QueryCostCents.java | 2 +- .../flyquery/model/QueryDetailRead.java | 2 +- .../flyquery/model/QueryHistoryItem.java | 2 +- .../firefly/flyquery/model/QueryRequest.java | 2 +- .../flyquery/model/QueryResultRead.java | 2 +- .../flyquery/model/RelationApprovalRead.java | 2 +- .../firefly/flyquery/model/RelationRead.java | 2 +- .../flyquery/model/RelationRejectionRead.java | 2 +- .../flyquery/model/ReuploadResponse.java | 2 +- .../flyquery/model/SchemaChangeRead.java | 2 +- .../flyquery/model/SchemaObjectRead.java | 2 +- .../flyquery/model/SchemaObjectUpdate.java | 2 +- .../model/SemanticDimensionCreate.java | 2 +- .../flyquery/model/SemanticDimensionRead.java | 2 +- .../model/SemanticDimensionUpdate.java | 2 +- .../flyquery/model/SemanticMetricCreate.java | 2 +- .../flyquery/model/SemanticMetricRead.java | 2 +- .../flyquery/model/SemanticMetricUpdate.java | 2 +- .../flyquery/model/SemanticVersionRead.java | 2 +- .../firefly/flyquery/model/SnapshotRead.java | 2 +- .../flyquery/model/SqlExecuteRequest.java | 2 +- .../flyquery/model/SqlExecuteResponse.java | 2 +- .../com/firefly/flyquery/model/TableRead.java | 2 +- .../firefly/flyquery/model/TableSummary.java | 2 +- .../flyquery/model/TotalCostCents.java | 2 +- .../com/firefly/flyquery/model/TurnRead.java | 2 +- .../firefly/flyquery/model/UsageSummary.java | 2 +- .../flyquery/model/ValidateResponse.java | 2 +- .../flyquery/model/ValidationError.java | 2 +- .../flyquery/model/WorkspaceCreate.java | 2 +- .../firefly/flyquery/model/WorkspaceRead.java | 2 +- .../flyquery/model/WorkspaceStats.java | 2 +- .../flyquery/model/WorkspaceUpdate.java | 2 +- .../api/AgentConversationsApiTest.java | 2 +- .../flyquery/api/AgentDatasetsApiTest.java | 2 +- .../flyquery/api/AgentExamplesApiTest.java | 2 +- .../flyquery/api/AgentGlossaryApiTest.java | 2 +- .../flyquery/api/AgentIngestJobsApiTest.java | 2 +- .../flyquery/api/AgentQueryApiTest.java | 2 +- .../flyquery/api/AgentRelationsApiTest.java | 2 +- .../api/AgentSemanticDimensionsApiTest.java | 2 +- .../api/AgentSemanticMetricsApiTest.java | 2 +- .../flyquery/api/AgentSqlExecuteApiTest.java | 2 +- .../flyquery/api/AgentTablesApiTest.java | 2 +- .../flyquery/api/AgentTokensApiTest.java | 2 +- .../flyquery/api/AgentVersionApiTest.java | 2 +- .../flyquery/api/AuditEventsApiTest.java | 2 +- .../firefly/flyquery/api/BillingApiTest.java | 2 +- .../flyquery/api/ConversationsApiTest.java | 2 +- .../flyquery/api/CostEventsApiTest.java | 2 +- .../firefly/flyquery/api/DatasetsApiTest.java | 2 +- .../firefly/flyquery/api/ExamplesApiTest.java | 2 +- .../firefly/flyquery/api/FilesApiTest.java | 2 +- .../firefly/flyquery/api/GlossaryApiTest.java | 2 +- .../flyquery/api/IngestJobsApiTest.java | 2 +- .../firefly/flyquery/api/QueriesApiTest.java | 2 +- .../firefly/flyquery/api/QueryApiTest.java | 2 +- .../flyquery/api/RelationsApiTest.java | 2 +- .../flyquery/api/SchemaChangesApiTest.java | 2 +- .../flyquery/api/SchemaObjectsApiTest.java | 2 +- .../api/SemanticDimensionsApiTest.java | 2 +- .../flyquery/api/SemanticMetricsApiTest.java | 2 +- .../flyquery/api/SqlExecuteApiTest.java | 2 +- .../firefly/flyquery/api/StatsApiTest.java | 2 +- .../firefly/flyquery/api/TablesApiTest.java | 2 +- .../flyquery/api/TablesDeriveApiTest.java | 2 +- .../firefly/flyquery/api/VersionApiTest.java | 2 +- .../flyquery/api/WorkspacesApiTest.java | 2 +- .../flyquery/model/AgentTokenCreatedTest.java | 2 +- .../model/AgentTokenMintRequestTest.java | 2 +- .../model/AgentTokenSummaryDtoTest.java | 2 +- .../flyquery/model/AgentUsageTest.java | 2 +- .../flyquery/model/AnswerResponseTest.java | 2 +- .../flyquery/model/AuditEventReadTest.java | 2 +- .../flyquery/model/BatchQueryItemTest.java | 2 +- .../flyquery/model/BatchQueryRequestTest.java | 2 +- .../model/BatchQueryResponseTest.java | 2 +- .../model/BatchQueryResultItemTest.java | 2 +- .../model/BillingBreakdownItemTest.java | 2 +- .../flyquery/model/BillingRollupTest.java | 2 +- .../flyquery/model/BulkFileResultTest.java | 2 +- .../model/BulkFileUploadResponseTest.java | 2 +- .../flyquery/model/CallbackConfigTest.java | 2 +- .../CallbackDeliveryListResponseTest.java | 2 +- .../model/CallbackDeliveryReadTest.java | 2 +- .../flyquery/model/CancelResponseTest.java | 2 +- .../model/ClarificationFrameTest.java | 2 +- .../flyquery/model/ConfidenceTest.java | 2 +- .../model/ConversationCreateTest.java | 2 +- .../flyquery/model/ConversationReadTest.java | 2 +- .../model/ConversationTurnRequestTest.java | 2 +- .../flyquery/model/CostCents1Test.java | 2 +- .../firefly/flyquery/model/CostCentsTest.java | 2 +- .../flyquery/model/CostEventReadTest.java | 2 +- .../flyquery/model/DatasetCreateTest.java | 2 +- .../flyquery/model/DatasetReadTest.java | 2 +- .../flyquery/model/DatasetUpdateTest.java | 2 +- .../model/DeriveTableRequestTest.java | 2 +- .../model/DeriveTableResponseTest.java | 2 +- .../flyquery/model/DetailInnerTest.java | 2 +- .../flyquery/model/ExampleCreateTest.java | 2 +- .../flyquery/model/ExampleReadTest.java | 2 +- .../flyquery/model/ExplainResponseTest.java | 2 +- .../model/FileUploadResponseTest.java | 2 +- .../model/GlossaryTermCreateTest.java | 2 +- .../flyquery/model/GlossaryTermReadTest.java | 2 +- .../model/GlossaryTermUpdateTest.java | 2 +- .../model/HTTPValidationErrorTest.java | 2 +- .../flyquery/model/IngestCostCentsTest.java | 2 +- .../model/IngestEventListResponseTest.java | 2 +- .../flyquery/model/IngestEventReadTest.java | 2 +- .../flyquery/model/IngestJobCreateTest.java | 2 +- .../model/IngestJobListResponseTest.java | 2 +- .../flyquery/model/IngestJobReadTest.java | 2 +- .../flyquery/model/LocationInnerTest.java | 2 +- .../flyquery/model/OtherCostCentsTest.java | 2 +- .../model/PaginatedAuditEventReadTest.java | 2 +- .../model/PaginatedConversationReadTest.java | 2 +- .../model/PaginatedCostEventReadTest.java | 2 +- .../model/PaginatedDatasetReadTest.java | 2 +- .../model/PaginatedExampleReadTest.java | 2 +- .../model/PaginatedGlossaryTermReadTest.java | 2 +- .../model/PaginatedQueryHistoryItemTest.java | 2 +- .../model/PaginatedRelationReadTest.java | 2 +- .../model/PaginatedSchemaChangeReadTest.java | 2 +- .../model/PaginatedSchemaObjectReadTest.java | 2 +- .../PaginatedSemanticDimensionReadTest.java | 2 +- .../PaginatedSemanticMetricReadTest.java | 2 +- .../PaginatedSemanticVersionReadTest.java | 2 +- .../model/PaginatedSnapshotReadTest.java | 2 +- .../model/PaginatedTableReadTest.java | 2 +- .../model/PaginatedWorkspaceReadTest.java | 2 +- .../flyquery/model/PurgeAcceptedTest.java | 2 +- .../flyquery/model/QueryCostCentsTest.java | 2 +- .../flyquery/model/QueryDetailReadTest.java | 2 +- .../flyquery/model/QueryHistoryItemTest.java | 2 +- .../flyquery/model/QueryRequestTest.java | 2 +- .../flyquery/model/QueryResultReadTest.java | 2 +- .../model/RelationApprovalReadTest.java | 2 +- .../flyquery/model/RelationReadTest.java | 2 +- .../model/RelationRejectionReadTest.java | 2 +- .../flyquery/model/ReuploadResponseTest.java | 2 +- .../flyquery/model/SchemaChangeReadTest.java | 2 +- .../flyquery/model/SchemaObjectReadTest.java | 2 +- .../model/SchemaObjectUpdateTest.java | 2 +- .../model/SemanticDimensionCreateTest.java | 2 +- .../model/SemanticDimensionReadTest.java | 2 +- .../model/SemanticDimensionUpdateTest.java | 2 +- .../model/SemanticMetricCreateTest.java | 2 +- .../model/SemanticMetricReadTest.java | 2 +- .../model/SemanticMetricUpdateTest.java | 2 +- .../model/SemanticVersionReadTest.java | 2 +- .../flyquery/model/SnapshotReadTest.java | 2 +- .../flyquery/model/SqlExecuteRequestTest.java | 2 +- .../model/SqlExecuteResponseTest.java | 2 +- .../firefly/flyquery/model/TableReadTest.java | 2 +- .../flyquery/model/TableSummaryTest.java | 2 +- .../flyquery/model/TotalCostCentsTest.java | 2 +- .../firefly/flyquery/model/TurnReadTest.java | 2 +- .../flyquery/model/UsageSummaryTest.java | 2 +- .../flyquery/model/ValidateResponseTest.java | 2 +- .../flyquery/model/ValidationErrorTest.java | 2 +- .../flyquery/model/WorkspaceCreateTest.java | 2 +- .../flyquery/model/WorkspaceReadTest.java | 2 +- .../flyquery/model/WorkspaceStatsTest.java | 2 +- .../flyquery/model/WorkspaceUpdateTest.java | 2 +- sdks/python/README.md | 8 ++-- sdks/python/flyquery_sdk/__init__.py | 4 +- .../api/agent_conversations_api.py | 2 +- .../flyquery_sdk/api/agent_datasets_api.py | 2 +- .../flyquery_sdk/api/agent_examples_api.py | 2 +- .../flyquery_sdk/api/agent_glossary_api.py | 2 +- .../flyquery_sdk/api/agent_ingest_jobs_api.py | 2 +- .../flyquery_sdk/api/agent_query_api.py | 2 +- .../flyquery_sdk/api/agent_relations_api.py | 2 +- .../api/agent_semantic_dimensions_api.py | 2 +- .../api/agent_semantic_metrics_api.py | 2 +- .../flyquery_sdk/api/agent_sql_execute_api.py | 2 +- .../flyquery_sdk/api/agent_tables_api.py | 2 +- .../flyquery_sdk/api/agent_tokens_api.py | 2 +- .../flyquery_sdk/api/agent_version_api.py | 2 +- .../flyquery_sdk/api/audit_events_api.py | 2 +- sdks/python/flyquery_sdk/api/billing_api.py | 2 +- .../flyquery_sdk/api/conversations_api.py | 2 +- .../flyquery_sdk/api/cost_events_api.py | 2 +- sdks/python/flyquery_sdk/api/datasets_api.py | 2 +- sdks/python/flyquery_sdk/api/examples_api.py | 2 +- sdks/python/flyquery_sdk/api/files_api.py | 2 +- sdks/python/flyquery_sdk/api/glossary_api.py | 2 +- .../flyquery_sdk/api/ingest_jobs_api.py | 2 +- sdks/python/flyquery_sdk/api/queries_api.py | 2 +- sdks/python/flyquery_sdk/api/query_api.py | 2 +- sdks/python/flyquery_sdk/api/relations_api.py | 2 +- .../flyquery_sdk/api/schema_changes_api.py | 2 +- .../flyquery_sdk/api/schema_objects_api.py | 2 +- .../api/semantic_dimensions_api.py | 2 +- .../flyquery_sdk/api/semantic_metrics_api.py | 2 +- .../flyquery_sdk/api/sql_execute_api.py | 2 +- sdks/python/flyquery_sdk/api/stats_api.py | 2 +- sdks/python/flyquery_sdk/api/tables_api.py | 2 +- .../flyquery_sdk/api/tables_derive_api.py | 2 +- sdks/python/flyquery_sdk/api/version_api.py | 2 +- .../python/flyquery_sdk/api/workspaces_api.py | 2 +- sdks/python/flyquery_sdk/api_client.py | 4 +- sdks/python/flyquery_sdk/configuration.py | 6 +-- sdks/python/flyquery_sdk/exceptions.py | 2 +- sdks/python/flyquery_sdk/models/__init__.py | 2 +- .../models/agent_token_created.py | 2 +- .../models/agent_token_mint_request.py | 2 +- .../models/agent_token_summary_dto.py | 2 +- .../python/flyquery_sdk/models/agent_usage.py | 2 +- .../flyquery_sdk/models/answer_response.py | 2 +- .../flyquery_sdk/models/audit_event_read.py | 2 +- .../flyquery_sdk/models/batch_query_item.py | 2 +- .../models/batch_query_request.py | 2 +- .../models/batch_query_response.py | 2 +- .../models/batch_query_result_item.py | 2 +- .../models/billing_breakdown_item.py | 2 +- .../flyquery_sdk/models/billing_rollup.py | 2 +- .../flyquery_sdk/models/bulk_file_result.py | 2 +- .../models/bulk_file_upload_response.py | 2 +- .../flyquery_sdk/models/callback_config.py | 2 +- .../models/callback_delivery_list_response.py | 2 +- .../models/callback_delivery_read.py | 2 +- .../flyquery_sdk/models/cancel_response.py | 2 +- .../models/clarification_frame.py | 2 +- sdks/python/flyquery_sdk/models/confidence.py | 2 +- .../models/conversation_create.py | 2 +- .../flyquery_sdk/models/conversation_read.py | 2 +- .../models/conversation_turn_request.py | 2 +- sdks/python/flyquery_sdk/models/cost_cents.py | 2 +- .../python/flyquery_sdk/models/cost_cents1.py | 2 +- .../flyquery_sdk/models/cost_event_read.py | 2 +- .../flyquery_sdk/models/dataset_create.py | 2 +- .../flyquery_sdk/models/dataset_read.py | 2 +- .../flyquery_sdk/models/dataset_update.py | 2 +- .../models/derive_table_request.py | 2 +- .../models/derive_table_response.py | 2 +- .../flyquery_sdk/models/detail_inner.py | 2 +- .../flyquery_sdk/models/example_create.py | 2 +- .../flyquery_sdk/models/example_read.py | 2 +- .../flyquery_sdk/models/explain_response.py | 2 +- .../models/file_upload_response.py | 2 +- .../models/glossary_term_create.py | 2 +- .../flyquery_sdk/models/glossary_term_read.py | 2 +- .../models/glossary_term_update.py | 2 +- .../models/http_validation_error.py | 2 +- .../flyquery_sdk/models/ingest_cost_cents.py | 2 +- .../models/ingest_event_list_response.py | 2 +- .../flyquery_sdk/models/ingest_event_read.py | 2 +- .../flyquery_sdk/models/ingest_job_create.py | 2 +- .../models/ingest_job_list_response.py | 2 +- .../flyquery_sdk/models/ingest_job_read.py | 2 +- .../flyquery_sdk/models/location_inner.py | 2 +- .../flyquery_sdk/models/other_cost_cents.py | 2 +- .../models/paginated_audit_event_read.py | 2 +- .../models/paginated_conversation_read.py | 2 +- .../models/paginated_cost_event_read.py | 2 +- .../models/paginated_dataset_read.py | 2 +- .../models/paginated_example_read.py | 2 +- .../models/paginated_glossary_term_read.py | 2 +- .../models/paginated_query_history_item.py | 2 +- .../models/paginated_relation_read.py | 2 +- .../models/paginated_schema_change_read.py | 2 +- .../models/paginated_schema_object_read.py | 2 +- .../paginated_semantic_dimension_read.py | 2 +- .../models/paginated_semantic_metric_read.py | 2 +- .../models/paginated_semantic_version_read.py | 2 +- .../models/paginated_snapshot_read.py | 2 +- .../models/paginated_table_read.py | 2 +- .../models/paginated_workspace_read.py | 2 +- .../flyquery_sdk/models/purge_accepted.py | 2 +- .../flyquery_sdk/models/query_cost_cents.py | 2 +- .../flyquery_sdk/models/query_detail_read.py | 2 +- .../flyquery_sdk/models/query_history_item.py | 2 +- .../flyquery_sdk/models/query_request.py | 2 +- .../flyquery_sdk/models/query_result_read.py | 2 +- .../models/relation_approval_read.py | 2 +- .../flyquery_sdk/models/relation_read.py | 2 +- .../models/relation_rejection_read.py | 2 +- .../flyquery_sdk/models/reupload_response.py | 2 +- .../flyquery_sdk/models/schema_change_read.py | 2 +- .../flyquery_sdk/models/schema_object_read.py | 2 +- .../models/schema_object_update.py | 2 +- .../models/semantic_dimension_create.py | 2 +- .../models/semantic_dimension_read.py | 2 +- .../models/semantic_dimension_update.py | 2 +- .../models/semantic_metric_create.py | 2 +- .../models/semantic_metric_read.py | 2 +- .../models/semantic_metric_update.py | 2 +- .../models/semantic_version_read.py | 2 +- .../flyquery_sdk/models/snapshot_read.py | 2 +- .../models/sql_execute_request.py | 2 +- .../models/sql_execute_response.py | 2 +- sdks/python/flyquery_sdk/models/table_read.py | 2 +- .../flyquery_sdk/models/table_summary.py | 2 +- .../flyquery_sdk/models/total_cost_cents.py | 2 +- sdks/python/flyquery_sdk/models/turn_read.py | 2 +- .../flyquery_sdk/models/usage_summary.py | 2 +- .../flyquery_sdk/models/validate_response.py | 2 +- .../flyquery_sdk/models/validation_error.py | 2 +- .../flyquery_sdk/models/workspace_create.py | 2 +- .../flyquery_sdk/models/workspace_read.py | 2 +- .../flyquery_sdk/models/workspace_stats.py | 2 +- .../flyquery_sdk/models/workspace_update.py | 2 +- sdks/python/flyquery_sdk/rest.py | 2 +- sdks/python/pyproject.toml | 2 +- sdks/python/setup.py | 4 +- sdks/python/test/test_agent_glossary_api.py | 2 +- .../test_agent_semantic_dimensions_api.py | 2 +- .../test/test_agent_semantic_metrics_api.py | 2 +- src/flyquery/__init__.py | 2 +- tests/integration/test_openapi_snapshot.py | 3 ++ .../test_sample_privacy_pipeline.py | 1 + uv.lock | 2 +- 405 files changed, 477 insertions(+), 454 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dfe4d985..e062b176 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,40 @@ follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and the project uses [CalVer](https://calver.org/) (YY.MM.PP) per the Firefly Framework convention (memory: `firefly_uses_calver`). +## [26.10.2] - 2026-10-14 + +### Changed + +- Use the public fireflyframework-agentic 26.10.1 wheel with the qualified + pyfly 26.06.113 runtime. Track the server dependency lock and validate it + before frozen CI and image installs. +- Apply `FLYQUERY_PROMPT_CACHE` when constructing agents. Enabled mode adds + Anthropic instruction-cache hints; disabled mode omits this middleware. + User messages, tool results and generated answers are not memoized. +- Ground queries with bounded value catalogs, scoped relation candidates and + persisted conversation snapshot pins. Candidate execution probes pass the + registered-table fence and a bounded result limit before candidate selection. +- Keep nineteen historical shared-source baselines and two explicitly reviewed + service variants under source-drift checks. + +### Fixed + +- Reject missing or unauthorized dataset scope before retrieval or model calls, + recording a caller-scoped rejected audit row without reading dataset metadata. +- Classify original samples before filtering them, and inspect retained profile + values before embedding. Redact/reject stores an explicit empty-list denial + so profiles cannot reintroduce protected values into schema knowledge. +- Exclude inactive columns from catalog and retrieval projections. Preserve + original Parquet files and conversation snapshot selections. +- Refresh the OpenAPI Decimal schemas for the resolved Pydantic runtime and + align server, actuator, Python and Java SDK release metadata. + +A nonempty executed candidate is a selection heuristic, not proof that the SQL +matches the requested entities or filters. Statement timeouts and operating +system sandboxing remain deployment responsibilities. Remote object-store +DuckDB reads are not qualified by the local registered-file tests. PII detection +covers sampled and retained profile values; it is not a scan of every source row. + ## [26.6.0] - 2026-06-01 ### Fixed — Semantic layer brought up to its documented contract diff --git a/README.md b/README.md index 62f5b7bc..af79638a 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ JSONL, Parquet, Avro, ORC, Arrow and Feather, plus their `.gz`, [![OpenAPI](https://img.shields.io/badge/api-openapi%203.1-green)](docs/api-reference.md) [![DuckDB](https://img.shields.io/badge/query%20engine-duckdb-yellow)](docs/architecture.md) [![pgvector](https://img.shields.io/badge/vector--store-pgvector-336791)](docs/architecture.md) -[![Version](https://img.shields.io/badge/version-26.10.1-green.svg)](#) +[![Version](https://img.shields.io/badge/version-26.10.2-green.svg)](#) [![License: Apache 2.0](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](LICENSE) diff --git a/Taskfile.yml b/Taskfile.yml index 35427a2e..6b75beca 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -117,7 +117,7 @@ tasks: -g python -o sdks/python --package-name flyquery_sdk - --additional-properties=packageVersion=26.10.1,projectName=flyquery-sdk,library=asyncio + --additional-properties=packageVersion=26.10.2,projectName=flyquery-sdk,library=asyncio --skip-validate-spec - cd sdks/python && uv pip install --system --quiet . || true @@ -142,5 +142,5 @@ tasks: --invoker-package com.firefly.flyquery --api-package com.firefly.flyquery.api --model-package com.firefly.flyquery.model - --additional-properties=artifactId=flyquery-sdk,groupId=com.firefly,artifactVersion=26.10.1,library=webclient,dateLibrary=java8,java8=true,useJakartaEe=true + --additional-properties=artifactId=flyquery-sdk,groupId=com.firefly,artifactVersion=26.10.2,library=webclient,dateLibrary=java8,java8=true,useJakartaEe=true --skip-validate-spec diff --git a/docs/release.md b/docs/release.md index 7c8a476b..492d52e5 100644 --- a/docs/release.md +++ b/docs/release.md @@ -123,9 +123,9 @@ sibling-client behaviour + every accessor. | `docker-publish.yaml` | push to main + `v*.*.*` tags | linux/amd64 + linux/arm64 image to GHCR | | `publish-sdks.yaml` | `v*.*.*` tags only | Java to GitHub Packages, Python wheel/sdist to Release assets | -If `pr-gate` is green on `main` before you tag, the tag-driven -workflows essentially can't fail (they share the same checkout -+ vendor setup). +Green PR checks qualify the source. Publication can still fail on registry +authentication, downloads or packaging; verify the tag workflows and every +published artifact separately before announcing the release. ## Tag + push sequence diff --git a/docs/sdks.md b/docs/sdks.md index 54ad8c25..1f47c3b2 100644 --- a/docs/sdks.md +++ b/docs/sdks.md @@ -21,10 +21,10 @@ Install the Python wheel from the canonical GitHub Release, rather than assuming that a package with the same name on PyPI is maintained by this project: ```bash -uv add https://github.com/fireflyframework/flyquery/releases/download/v26.10.1/flyquery_sdk-26.10.1-py3-none-any.whl +uv add https://github.com/fireflyframework/flyquery/releases/download/v26.10.2/flyquery_sdk-26.10.2-py3-none-any.whl ``` -Keep service and client versions aligned. This release uses version `26.10.1`; +Keep service and client versions aligned. This release uses version `26.10.2`; read the release notes and API snapshot before upgrading. The repository also retains earlier releases and their original assets. diff --git a/docs/security-model.md b/docs/security-model.md index 71c6979c..1d2b88ff 100644 --- a/docs/security-model.md +++ b/docs/security-model.md @@ -285,30 +285,29 @@ Implementation: [AST classifier](../src/flyquery/core/services/execution/ast_cla PII scanning has two gates: -1. **Stage 4 (sample)** — samples are tested before being persisted. A column - that triggers a PII match at sampling time never has its values written to - `sample_values_json`. - -2. **Stage 8 (PII tag)** — the `PIIScanner` port classifies each column from - `(name + description + sample_values)`. Sets `pii_tag` + `pii_source`. +1. Stage 4 checks the original sample batch before filtering values. Detection + applies the configured column policy and persists an empty-list denial for + redact/reject, including all-PII and already-tagged columns. +2. Stage 8 classifies names, descriptions, samples and up to 100 retained profile + values before embedding. This also catches classified values outside the + sampled prefix. ### PII policies -Set globally via env vars or per-dataset via `ingest_policy_json`: - -| Policy | `warn` | `redact` | `reject` | -|--------|--------|----------|---------| -| On PII detection | Log + continue | Purge `sample_values_json`; log | Set `is_active=false` on column; not queryable until reviewed | +Configure policies globally or per dataset through `ingest_policy_json`: -### Late tag flip +| Policy | Behavior after detection | +|--------|--------------------------| +| `warn` | Tag the column; retain clean sampled values. Profile values can remain available. | +| `redact` | Store `sample_values_json=[]`; embedding and retrieval projections cannot fall back to profile values. The column remains queryable. | +| `reject` | Store the same denial and mark the column inactive. Catalog and retrieval projections exclude it. | -If a human annotates `pii_tag` on a column that already has `sample_values_json` -persisted, the samples are scrubbed in-place in the same transaction: - -```python -if update.pii_tag and update.pii_tag != "NONE": - schema_object.sample_values_json = None -``` +Late annotations use the same explicit denial boundary. A missing sample list +is distinct from a denied empty list. Original files and stored profiles remain +unchanged; these policies govern prompt and retrieval exposure, not source-data +removal. Detection is limited to sampled or retained profile values and the +configured scanner's capabilities. Read the [PII guide](pii.md) for scanner +selection, disabled mode and re-ingestion. ### PII in query results diff --git a/openapi.json b/openapi.json index 7aec0dd1..e128c29a 100644 --- a/openapi.json +++ b/openapi.json @@ -906,7 +906,6 @@ "type": "number" }, { - "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$", "type": "string" } ], @@ -918,7 +917,6 @@ "type": "number" }, { - "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$", "type": "string" } ], @@ -930,7 +928,6 @@ "type": "number" }, { - "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$", "type": "string" } ], @@ -942,7 +939,6 @@ "type": "number" }, { - "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$", "type": "string" } ], @@ -1005,7 +1001,6 @@ "type": "number" }, { - "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$", "type": "string" } ], @@ -1479,7 +1474,6 @@ "type": "number" }, { - "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$", "type": "string" } ], @@ -2532,7 +2526,6 @@ "type": "number" }, { - "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$", "type": "string" } ], @@ -4243,7 +4236,6 @@ "type": "number" }, { - "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$", "type": "string" } ], @@ -6214,7 +6206,7 @@ "url": "https://github.com/fireflyframework/flyquery/blob/main/LICENSE" }, "title": "flyquery", - "version": "26.10.1" + "version": "26.10.2" }, "openapi": "3.1.0", "paths": { diff --git a/pyfly.yaml b/pyfly.yaml index 30daf9f7..04bac835 100644 --- a/pyfly.yaml +++ b/pyfly.yaml @@ -12,7 +12,7 @@ pyfly: # and admin tooling identify the service correctly. app: name: flyquery - version: 26.5.12 + version: 26.10.2 description: >- Operational Structured-Data Intelligence (upload-driven). Multi-tenant ingestion + Text-to-SQL over user-uploaded structured diff --git a/pyproject.toml b/pyproject.toml index 5d8f9652..dea8b0f4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,7 @@ [project] name = "flyquery" # CalVer YY.MM.PP per memory `firefly_uses_calver`. -version = "26.10.1" +version = "26.10.2" description = "Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL service over user-uploaded structured files. Part of Firefly Framework." readme = "README.md" requires-python = ">=3.13,<3.14" diff --git a/sdks/java/README.md b/sdks/java/README.md index 53dd3575..fafac709 100644 --- a/sdks/java/README.md +++ b/sdks/java/README.md @@ -18,19 +18,19 @@ default headers. ## Install -For release 26.10.1, use the matching Maven coordinate: +For release 26.10.2, use the matching Maven coordinate: ```xml com.firefly flyquery-sdk - 26.10.1 + 26.10.2 ``` The publisher targets GitHub Packages at `https://maven.pkg.github.com/fireflyframework/flyquery`. GitHub Packages requires -Maven authentication. See the [release](https://github.com/fireflyframework/flyquery/releases/tag/v26.10.1) +Maven authentication. See the [release](https://github.com/fireflyframework/flyquery/releases/tag/v26.10.2) for downloadable artifacts and use the service's matching version. Earlier release artifacts keep their original registry coordinates. diff --git a/sdks/java/api/openapi.yaml b/sdks/java/api/openapi.yaml index a2d723df..49c2e3dd 100644 --- a/sdks/java/api/openapi.yaml +++ b/sdks/java/api/openapi.yaml @@ -13,7 +13,7 @@ info: name: Apache-2.0 url: https://github.com/fireflyframework/flyquery/blob/main/LICENSE title: flyquery - version: 26.10.1 + version: 26.10.2 servers: - description: This service url: / @@ -9830,32 +9830,27 @@ components: Ingest_Cost_Cents: anyOf: - type: number - - pattern: "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$" - type: string + - type: string title: Ingest Cost Cents Other_Cost_Cents: anyOf: - type: number - - pattern: "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$" - type: string + - type: string title: Other Cost Cents Query_Cost_Cents: anyOf: - type: number - - pattern: "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$" - type: string + - type: string title: Query Cost Cents Total_Cost_Cents: anyOf: - type: number - - pattern: "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$" - type: string + - type: string title: Total Cost Cents Cost_Cents: anyOf: - type: number - - pattern: "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$" - type: string + - type: string title: Cost Cents Cost_Cents_1: anyOf: @@ -9867,8 +9862,7 @@ components: Confidence: anyOf: - type: number - - pattern: "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$" - type: string + - type: string title: Confidence Location_inner: anyOf: diff --git a/sdks/java/build.gradle b/sdks/java/build.gradle index 14c03591..a2f1fc4f 100644 --- a/sdks/java/build.gradle +++ b/sdks/java/build.gradle @@ -2,7 +2,7 @@ apply plugin: 'idea' apply plugin: 'eclipse' group = 'com.firefly' -version = '26.10.1' +version = '26.10.2' buildscript { repositories { diff --git a/sdks/java/pom.xml b/sdks/java/pom.xml index 39d1885a..6d336c8e 100644 --- a/sdks/java/pom.xml +++ b/sdks/java/pom.xml @@ -5,7 +5,7 @@ flyquery-sdk jar flyquery-sdk - 26.10.1 + 26.10.2 https://github.com/fireflyframework/flyquery Java SDK for flyquery -- Operational Structured-Data Intelligence. Auto-generated from the flyquery OpenAPI 3.1 spec. Targets Java 25 + Spring Boot 3.5.9 + WebFlux. diff --git a/sdks/java/src/main/java/com/firefly/flyquery/ApiClient.java b/sdks/java/src/main/java/com/firefly/flyquery/ApiClient.java index b45b8d53..9243ebbd 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/ApiClient.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/ApiClient.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/JavaTimeFormatter.java b/sdks/java/src/main/java/com/firefly/flyquery/JavaTimeFormatter.java index 5ccbae57..9e66b6ca 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/JavaTimeFormatter.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/JavaTimeFormatter.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/RFC3339DateFormat.java b/sdks/java/src/main/java/com/firefly/flyquery/RFC3339DateFormat.java index 5fce4a5e..9163b8fd 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/RFC3339DateFormat.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/RFC3339DateFormat.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/RFC3339InstantDeserializer.java b/sdks/java/src/main/java/com/firefly/flyquery/RFC3339InstantDeserializer.java index ee8f71c9..afa868da 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/RFC3339InstantDeserializer.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/RFC3339InstantDeserializer.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/RFC3339JavaTimeModule.java b/sdks/java/src/main/java/com/firefly/flyquery/RFC3339JavaTimeModule.java index 1a69f333..9e3b7665 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/RFC3339JavaTimeModule.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/RFC3339JavaTimeModule.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/ServerConfiguration.java b/sdks/java/src/main/java/com/firefly/flyquery/ServerConfiguration.java index 75b81a48..4b48baff 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/ServerConfiguration.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/ServerConfiguration.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/ServerVariable.java b/sdks/java/src/main/java/com/firefly/flyquery/ServerVariable.java index 259fb6c3..3067203f 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/ServerVariable.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/ServerVariable.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/StringUtil.java b/sdks/java/src/main/java/com/firefly/flyquery/StringUtil.java index e123e981..fb0d91a8 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/StringUtil.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/StringUtil.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/auth/ApiKeyAuth.java b/sdks/java/src/main/java/com/firefly/flyquery/auth/ApiKeyAuth.java index 490becce..daca507d 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/auth/ApiKeyAuth.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/auth/ApiKeyAuth.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/auth/Authentication.java b/sdks/java/src/main/java/com/firefly/flyquery/auth/Authentication.java index fdeca29d..5bf4662e 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/auth/Authentication.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/auth/Authentication.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/auth/HttpBasicAuth.java b/sdks/java/src/main/java/com/firefly/flyquery/auth/HttpBasicAuth.java index 08c1531f..91d6d011 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/auth/HttpBasicAuth.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/auth/HttpBasicAuth.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/auth/HttpBearerAuth.java b/sdks/java/src/main/java/com/firefly/flyquery/auth/HttpBearerAuth.java index aaaa016c..2172ac7e 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/auth/HttpBearerAuth.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/auth/HttpBearerAuth.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/model/AgentTokenCreated.java b/sdks/java/src/main/java/com/firefly/flyquery/model/AgentTokenCreated.java index 47f2cadb..d3e49a79 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/model/AgentTokenCreated.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/model/AgentTokenCreated.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/model/AgentTokenMintRequest.java b/sdks/java/src/main/java/com/firefly/flyquery/model/AgentTokenMintRequest.java index 2e04030d..9ed8f5dd 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/model/AgentTokenMintRequest.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/model/AgentTokenMintRequest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/model/AgentTokenSummaryDto.java b/sdks/java/src/main/java/com/firefly/flyquery/model/AgentTokenSummaryDto.java index 189a66fb..c2f5aff2 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/model/AgentTokenSummaryDto.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/model/AgentTokenSummaryDto.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/model/AgentUsage.java b/sdks/java/src/main/java/com/firefly/flyquery/model/AgentUsage.java index 62b09c81..223c9a16 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/model/AgentUsage.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/model/AgentUsage.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/model/AnswerResponse.java b/sdks/java/src/main/java/com/firefly/flyquery/model/AnswerResponse.java index 379d5b54..a62e4a0f 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/model/AnswerResponse.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/model/AnswerResponse.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/model/AuditEventRead.java b/sdks/java/src/main/java/com/firefly/flyquery/model/AuditEventRead.java index ebf8c9e6..d6ddc3aa 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/model/AuditEventRead.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/model/AuditEventRead.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/model/BatchQueryItem.java b/sdks/java/src/main/java/com/firefly/flyquery/model/BatchQueryItem.java index a87038ff..536dcb1e 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/model/BatchQueryItem.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/model/BatchQueryItem.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/model/BatchQueryRequest.java b/sdks/java/src/main/java/com/firefly/flyquery/model/BatchQueryRequest.java index 11caa064..34e501c0 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/model/BatchQueryRequest.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/model/BatchQueryRequest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/model/BatchQueryResponse.java b/sdks/java/src/main/java/com/firefly/flyquery/model/BatchQueryResponse.java index 91c1a990..65fe0fce 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/model/BatchQueryResponse.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/model/BatchQueryResponse.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/model/BatchQueryResultItem.java b/sdks/java/src/main/java/com/firefly/flyquery/model/BatchQueryResultItem.java index 8bee5cbf..88604c2a 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/model/BatchQueryResultItem.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/model/BatchQueryResultItem.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/model/BillingBreakdownItem.java b/sdks/java/src/main/java/com/firefly/flyquery/model/BillingBreakdownItem.java index 6c9b3fa5..ee00de5f 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/model/BillingBreakdownItem.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/model/BillingBreakdownItem.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/model/BillingRollup.java b/sdks/java/src/main/java/com/firefly/flyquery/model/BillingRollup.java index c5d84508..0bc88903 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/model/BillingRollup.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/model/BillingRollup.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/model/BulkFileResult.java b/sdks/java/src/main/java/com/firefly/flyquery/model/BulkFileResult.java index 67b338bb..c21d6fa2 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/model/BulkFileResult.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/model/BulkFileResult.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/model/BulkFileUploadResponse.java b/sdks/java/src/main/java/com/firefly/flyquery/model/BulkFileUploadResponse.java index a7ac6d35..db899c79 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/model/BulkFileUploadResponse.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/model/BulkFileUploadResponse.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/model/CallbackConfig.java b/sdks/java/src/main/java/com/firefly/flyquery/model/CallbackConfig.java index 996efab4..d13d174c 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/model/CallbackConfig.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/model/CallbackConfig.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/model/CallbackDeliveryListResponse.java b/sdks/java/src/main/java/com/firefly/flyquery/model/CallbackDeliveryListResponse.java index cc96298a..6adc4481 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/model/CallbackDeliveryListResponse.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/model/CallbackDeliveryListResponse.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/model/CallbackDeliveryRead.java b/sdks/java/src/main/java/com/firefly/flyquery/model/CallbackDeliveryRead.java index 684bd1a8..f4ca5b58 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/model/CallbackDeliveryRead.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/model/CallbackDeliveryRead.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/model/CancelResponse.java b/sdks/java/src/main/java/com/firefly/flyquery/model/CancelResponse.java index bcc8a2bc..94add7b7 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/model/CancelResponse.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/model/CancelResponse.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/model/ClarificationFrame.java b/sdks/java/src/main/java/com/firefly/flyquery/model/ClarificationFrame.java index 725a0d18..54d3cc08 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/model/ClarificationFrame.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/model/ClarificationFrame.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/model/Confidence.java b/sdks/java/src/main/java/com/firefly/flyquery/model/Confidence.java index 1e802302..70ce8ead 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/model/Confidence.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/model/Confidence.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/model/ConversationCreate.java b/sdks/java/src/main/java/com/firefly/flyquery/model/ConversationCreate.java index 7a17e98b..1ccba93a 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/model/ConversationCreate.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/model/ConversationCreate.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/model/ConversationRead.java b/sdks/java/src/main/java/com/firefly/flyquery/model/ConversationRead.java index e6560f8c..db73bcff 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/model/ConversationRead.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/model/ConversationRead.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/model/ConversationTurnRequest.java b/sdks/java/src/main/java/com/firefly/flyquery/model/ConversationTurnRequest.java index c2040bc7..c3fabbf2 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/model/ConversationTurnRequest.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/model/ConversationTurnRequest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/model/CostCents.java b/sdks/java/src/main/java/com/firefly/flyquery/model/CostCents.java index 2489c875..2c510c17 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/model/CostCents.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/model/CostCents.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/model/CostCents1.java b/sdks/java/src/main/java/com/firefly/flyquery/model/CostCents1.java index 717c71f8..301a118f 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/model/CostCents1.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/model/CostCents1.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/model/CostEventRead.java b/sdks/java/src/main/java/com/firefly/flyquery/model/CostEventRead.java index b8fa1efb..7f241510 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/model/CostEventRead.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/model/CostEventRead.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/model/DatasetCreate.java b/sdks/java/src/main/java/com/firefly/flyquery/model/DatasetCreate.java index 26d36dab..4066173c 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/model/DatasetCreate.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/model/DatasetCreate.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/model/DatasetRead.java b/sdks/java/src/main/java/com/firefly/flyquery/model/DatasetRead.java index 37cc0b15..3a07046d 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/model/DatasetRead.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/model/DatasetRead.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/model/DatasetUpdate.java b/sdks/java/src/main/java/com/firefly/flyquery/model/DatasetUpdate.java index d04913cf..f806fe06 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/model/DatasetUpdate.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/model/DatasetUpdate.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/model/DeriveTableRequest.java b/sdks/java/src/main/java/com/firefly/flyquery/model/DeriveTableRequest.java index 88eef73b..9b784e10 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/model/DeriveTableRequest.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/model/DeriveTableRequest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/model/DeriveTableResponse.java b/sdks/java/src/main/java/com/firefly/flyquery/model/DeriveTableResponse.java index 4f698894..0fcf6712 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/model/DeriveTableResponse.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/model/DeriveTableResponse.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/model/DetailInner.java b/sdks/java/src/main/java/com/firefly/flyquery/model/DetailInner.java index 493ab361..814cce07 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/model/DetailInner.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/model/DetailInner.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/model/ExampleCreate.java b/sdks/java/src/main/java/com/firefly/flyquery/model/ExampleCreate.java index ae048f1a..b62987ee 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/model/ExampleCreate.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/model/ExampleCreate.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/model/ExampleRead.java b/sdks/java/src/main/java/com/firefly/flyquery/model/ExampleRead.java index be1898b8..998a9949 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/model/ExampleRead.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/model/ExampleRead.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/model/ExplainResponse.java b/sdks/java/src/main/java/com/firefly/flyquery/model/ExplainResponse.java index 382e24c5..ba6df440 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/model/ExplainResponse.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/model/ExplainResponse.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/model/FileUploadResponse.java b/sdks/java/src/main/java/com/firefly/flyquery/model/FileUploadResponse.java index 3e16f08b..d9725e04 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/model/FileUploadResponse.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/model/FileUploadResponse.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/model/GlossaryTermCreate.java b/sdks/java/src/main/java/com/firefly/flyquery/model/GlossaryTermCreate.java index 949a8681..d36628a4 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/model/GlossaryTermCreate.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/model/GlossaryTermCreate.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/model/GlossaryTermRead.java b/sdks/java/src/main/java/com/firefly/flyquery/model/GlossaryTermRead.java index c0463fe6..2f18b68d 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/model/GlossaryTermRead.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/model/GlossaryTermRead.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/model/GlossaryTermUpdate.java b/sdks/java/src/main/java/com/firefly/flyquery/model/GlossaryTermUpdate.java index 414d6a16..47759c7e 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/model/GlossaryTermUpdate.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/model/GlossaryTermUpdate.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/model/HTTPValidationError.java b/sdks/java/src/main/java/com/firefly/flyquery/model/HTTPValidationError.java index 70dbcebe..2b11ddd5 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/model/HTTPValidationError.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/model/HTTPValidationError.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/model/IngestCostCents.java b/sdks/java/src/main/java/com/firefly/flyquery/model/IngestCostCents.java index f08d1bd3..8194560e 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/model/IngestCostCents.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/model/IngestCostCents.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/model/IngestEventListResponse.java b/sdks/java/src/main/java/com/firefly/flyquery/model/IngestEventListResponse.java index 634cdc84..6bdde17b 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/model/IngestEventListResponse.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/model/IngestEventListResponse.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/model/IngestEventRead.java b/sdks/java/src/main/java/com/firefly/flyquery/model/IngestEventRead.java index 1485b7fd..afbe9120 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/model/IngestEventRead.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/model/IngestEventRead.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/model/IngestJobCreate.java b/sdks/java/src/main/java/com/firefly/flyquery/model/IngestJobCreate.java index 4a5a6351..e5148348 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/model/IngestJobCreate.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/model/IngestJobCreate.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/model/IngestJobListResponse.java b/sdks/java/src/main/java/com/firefly/flyquery/model/IngestJobListResponse.java index 69928d7c..11c86265 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/model/IngestJobListResponse.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/model/IngestJobListResponse.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/model/IngestJobRead.java b/sdks/java/src/main/java/com/firefly/flyquery/model/IngestJobRead.java index 8864889f..0e2705b7 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/model/IngestJobRead.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/model/IngestJobRead.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/model/LocationInner.java b/sdks/java/src/main/java/com/firefly/flyquery/model/LocationInner.java index 8964798b..b8762ca1 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/model/LocationInner.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/model/LocationInner.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/model/OtherCostCents.java b/sdks/java/src/main/java/com/firefly/flyquery/model/OtherCostCents.java index 785c583a..998976c9 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/model/OtherCostCents.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/model/OtherCostCents.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/model/PaginatedAuditEventRead.java b/sdks/java/src/main/java/com/firefly/flyquery/model/PaginatedAuditEventRead.java index 4aa37b2f..031445a6 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/model/PaginatedAuditEventRead.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/model/PaginatedAuditEventRead.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/model/PaginatedConversationRead.java b/sdks/java/src/main/java/com/firefly/flyquery/model/PaginatedConversationRead.java index b535fb4c..00997f8f 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/model/PaginatedConversationRead.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/model/PaginatedConversationRead.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/model/PaginatedCostEventRead.java b/sdks/java/src/main/java/com/firefly/flyquery/model/PaginatedCostEventRead.java index cb85fd83..d3571bfb 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/model/PaginatedCostEventRead.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/model/PaginatedCostEventRead.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/model/PaginatedDatasetRead.java b/sdks/java/src/main/java/com/firefly/flyquery/model/PaginatedDatasetRead.java index ecbfc6e4..9c4bc98f 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/model/PaginatedDatasetRead.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/model/PaginatedDatasetRead.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/model/PaginatedExampleRead.java b/sdks/java/src/main/java/com/firefly/flyquery/model/PaginatedExampleRead.java index fd4bc7d4..271cab62 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/model/PaginatedExampleRead.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/model/PaginatedExampleRead.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/model/PaginatedGlossaryTermRead.java b/sdks/java/src/main/java/com/firefly/flyquery/model/PaginatedGlossaryTermRead.java index 47e39a32..0e1ac4ed 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/model/PaginatedGlossaryTermRead.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/model/PaginatedGlossaryTermRead.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/model/PaginatedQueryHistoryItem.java b/sdks/java/src/main/java/com/firefly/flyquery/model/PaginatedQueryHistoryItem.java index ccf53fcd..44602510 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/model/PaginatedQueryHistoryItem.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/model/PaginatedQueryHistoryItem.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/model/PaginatedRelationRead.java b/sdks/java/src/main/java/com/firefly/flyquery/model/PaginatedRelationRead.java index 5a21b9d4..2cd38a55 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/model/PaginatedRelationRead.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/model/PaginatedRelationRead.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/model/PaginatedSchemaChangeRead.java b/sdks/java/src/main/java/com/firefly/flyquery/model/PaginatedSchemaChangeRead.java index 2518fff6..c302707c 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/model/PaginatedSchemaChangeRead.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/model/PaginatedSchemaChangeRead.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/model/PaginatedSchemaObjectRead.java b/sdks/java/src/main/java/com/firefly/flyquery/model/PaginatedSchemaObjectRead.java index 22b51585..31bb4c71 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/model/PaginatedSchemaObjectRead.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/model/PaginatedSchemaObjectRead.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/model/PaginatedSemanticDimensionRead.java b/sdks/java/src/main/java/com/firefly/flyquery/model/PaginatedSemanticDimensionRead.java index 67110ebb..3e34891a 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/model/PaginatedSemanticDimensionRead.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/model/PaginatedSemanticDimensionRead.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/model/PaginatedSemanticMetricRead.java b/sdks/java/src/main/java/com/firefly/flyquery/model/PaginatedSemanticMetricRead.java index 214b45e1..fb2d20f0 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/model/PaginatedSemanticMetricRead.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/model/PaginatedSemanticMetricRead.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/model/PaginatedSemanticVersionRead.java b/sdks/java/src/main/java/com/firefly/flyquery/model/PaginatedSemanticVersionRead.java index c7b3452d..fa296cb6 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/model/PaginatedSemanticVersionRead.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/model/PaginatedSemanticVersionRead.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/model/PaginatedSnapshotRead.java b/sdks/java/src/main/java/com/firefly/flyquery/model/PaginatedSnapshotRead.java index 679898cd..1824031b 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/model/PaginatedSnapshotRead.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/model/PaginatedSnapshotRead.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/model/PaginatedTableRead.java b/sdks/java/src/main/java/com/firefly/flyquery/model/PaginatedTableRead.java index 1b60d77d..79c2cc41 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/model/PaginatedTableRead.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/model/PaginatedTableRead.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/model/PaginatedWorkspaceRead.java b/sdks/java/src/main/java/com/firefly/flyquery/model/PaginatedWorkspaceRead.java index 75ba1b48..347094af 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/model/PaginatedWorkspaceRead.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/model/PaginatedWorkspaceRead.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/model/PurgeAccepted.java b/sdks/java/src/main/java/com/firefly/flyquery/model/PurgeAccepted.java index 3a14dca6..af64fa48 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/model/PurgeAccepted.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/model/PurgeAccepted.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/model/QueryCostCents.java b/sdks/java/src/main/java/com/firefly/flyquery/model/QueryCostCents.java index 374af6da..158b1f33 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/model/QueryCostCents.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/model/QueryCostCents.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/model/QueryDetailRead.java b/sdks/java/src/main/java/com/firefly/flyquery/model/QueryDetailRead.java index 702b8b9e..57bb6090 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/model/QueryDetailRead.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/model/QueryDetailRead.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/model/QueryHistoryItem.java b/sdks/java/src/main/java/com/firefly/flyquery/model/QueryHistoryItem.java index a12f49c4..eb442f1d 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/model/QueryHistoryItem.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/model/QueryHistoryItem.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/model/QueryRequest.java b/sdks/java/src/main/java/com/firefly/flyquery/model/QueryRequest.java index 0a6d201c..4a75ed6a 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/model/QueryRequest.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/model/QueryRequest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/model/QueryResultRead.java b/sdks/java/src/main/java/com/firefly/flyquery/model/QueryResultRead.java index 2396d2c4..4a38afd6 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/model/QueryResultRead.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/model/QueryResultRead.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/model/RelationApprovalRead.java b/sdks/java/src/main/java/com/firefly/flyquery/model/RelationApprovalRead.java index 7f98f71f..56fca67f 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/model/RelationApprovalRead.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/model/RelationApprovalRead.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/model/RelationRead.java b/sdks/java/src/main/java/com/firefly/flyquery/model/RelationRead.java index f877f879..e27363dd 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/model/RelationRead.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/model/RelationRead.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/model/RelationRejectionRead.java b/sdks/java/src/main/java/com/firefly/flyquery/model/RelationRejectionRead.java index f94231f4..c3899926 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/model/RelationRejectionRead.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/model/RelationRejectionRead.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/model/ReuploadResponse.java b/sdks/java/src/main/java/com/firefly/flyquery/model/ReuploadResponse.java index 9c606067..94700b7c 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/model/ReuploadResponse.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/model/ReuploadResponse.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/model/SchemaChangeRead.java b/sdks/java/src/main/java/com/firefly/flyquery/model/SchemaChangeRead.java index d4fab9c6..68973915 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/model/SchemaChangeRead.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/model/SchemaChangeRead.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/model/SchemaObjectRead.java b/sdks/java/src/main/java/com/firefly/flyquery/model/SchemaObjectRead.java index 1279d1ba..e5b2e089 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/model/SchemaObjectRead.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/model/SchemaObjectRead.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/model/SchemaObjectUpdate.java b/sdks/java/src/main/java/com/firefly/flyquery/model/SchemaObjectUpdate.java index 43e90762..131d0e81 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/model/SchemaObjectUpdate.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/model/SchemaObjectUpdate.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/model/SemanticDimensionCreate.java b/sdks/java/src/main/java/com/firefly/flyquery/model/SemanticDimensionCreate.java index fd88a686..faf6ec4a 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/model/SemanticDimensionCreate.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/model/SemanticDimensionCreate.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/model/SemanticDimensionRead.java b/sdks/java/src/main/java/com/firefly/flyquery/model/SemanticDimensionRead.java index 0e541a68..a46c9586 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/model/SemanticDimensionRead.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/model/SemanticDimensionRead.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/model/SemanticDimensionUpdate.java b/sdks/java/src/main/java/com/firefly/flyquery/model/SemanticDimensionUpdate.java index adffc29e..7412f53e 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/model/SemanticDimensionUpdate.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/model/SemanticDimensionUpdate.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/model/SemanticMetricCreate.java b/sdks/java/src/main/java/com/firefly/flyquery/model/SemanticMetricCreate.java index 5596167b..494ce045 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/model/SemanticMetricCreate.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/model/SemanticMetricCreate.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/model/SemanticMetricRead.java b/sdks/java/src/main/java/com/firefly/flyquery/model/SemanticMetricRead.java index cd2c1b3e..c3376307 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/model/SemanticMetricRead.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/model/SemanticMetricRead.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/model/SemanticMetricUpdate.java b/sdks/java/src/main/java/com/firefly/flyquery/model/SemanticMetricUpdate.java index 4482e2a7..0aa1da59 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/model/SemanticMetricUpdate.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/model/SemanticMetricUpdate.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/model/SemanticVersionRead.java b/sdks/java/src/main/java/com/firefly/flyquery/model/SemanticVersionRead.java index 238a1d4f..4b98cef4 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/model/SemanticVersionRead.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/model/SemanticVersionRead.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/model/SnapshotRead.java b/sdks/java/src/main/java/com/firefly/flyquery/model/SnapshotRead.java index 642c6e98..534fb0d0 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/model/SnapshotRead.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/model/SnapshotRead.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/model/SqlExecuteRequest.java b/sdks/java/src/main/java/com/firefly/flyquery/model/SqlExecuteRequest.java index 9b851da2..8e4117d7 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/model/SqlExecuteRequest.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/model/SqlExecuteRequest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/model/SqlExecuteResponse.java b/sdks/java/src/main/java/com/firefly/flyquery/model/SqlExecuteResponse.java index 587b6eab..ece62416 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/model/SqlExecuteResponse.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/model/SqlExecuteResponse.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/model/TableRead.java b/sdks/java/src/main/java/com/firefly/flyquery/model/TableRead.java index 5357d2f9..77603570 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/model/TableRead.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/model/TableRead.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/model/TableSummary.java b/sdks/java/src/main/java/com/firefly/flyquery/model/TableSummary.java index 749301c5..87b335e8 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/model/TableSummary.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/model/TableSummary.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/model/TotalCostCents.java b/sdks/java/src/main/java/com/firefly/flyquery/model/TotalCostCents.java index 6a9e6a00..7901dfe4 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/model/TotalCostCents.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/model/TotalCostCents.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/model/TurnRead.java b/sdks/java/src/main/java/com/firefly/flyquery/model/TurnRead.java index ddbbb97d..4ee77c1e 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/model/TurnRead.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/model/TurnRead.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/model/UsageSummary.java b/sdks/java/src/main/java/com/firefly/flyquery/model/UsageSummary.java index 0f82d72a..15ce0072 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/model/UsageSummary.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/model/UsageSummary.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/model/ValidateResponse.java b/sdks/java/src/main/java/com/firefly/flyquery/model/ValidateResponse.java index 30c393e1..d2bbc78c 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/model/ValidateResponse.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/model/ValidateResponse.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/model/ValidationError.java b/sdks/java/src/main/java/com/firefly/flyquery/model/ValidationError.java index a5e09bfc..0dc237f4 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/model/ValidationError.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/model/ValidationError.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/model/WorkspaceCreate.java b/sdks/java/src/main/java/com/firefly/flyquery/model/WorkspaceCreate.java index 20baf7a9..bb92ef46 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/model/WorkspaceCreate.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/model/WorkspaceCreate.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/model/WorkspaceRead.java b/sdks/java/src/main/java/com/firefly/flyquery/model/WorkspaceRead.java index be6ac9a6..dbe856dc 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/model/WorkspaceRead.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/model/WorkspaceRead.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/model/WorkspaceStats.java b/sdks/java/src/main/java/com/firefly/flyquery/model/WorkspaceStats.java index 438d6e08..f7b08870 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/model/WorkspaceStats.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/model/WorkspaceStats.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/main/java/com/firefly/flyquery/model/WorkspaceUpdate.java b/sdks/java/src/main/java/com/firefly/flyquery/model/WorkspaceUpdate.java index 1fb1794f..0db69a65 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/model/WorkspaceUpdate.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/model/WorkspaceUpdate.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/api/AgentConversationsApiTest.java b/sdks/java/src/test/java/com/firefly/flyquery/api/AgentConversationsApiTest.java index 665616c7..1013fd99 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/api/AgentConversationsApiTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/api/AgentConversationsApiTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/api/AgentDatasetsApiTest.java b/sdks/java/src/test/java/com/firefly/flyquery/api/AgentDatasetsApiTest.java index 86a7df32..25499236 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/api/AgentDatasetsApiTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/api/AgentDatasetsApiTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/api/AgentExamplesApiTest.java b/sdks/java/src/test/java/com/firefly/flyquery/api/AgentExamplesApiTest.java index f54da969..df92a95a 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/api/AgentExamplesApiTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/api/AgentExamplesApiTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/api/AgentGlossaryApiTest.java b/sdks/java/src/test/java/com/firefly/flyquery/api/AgentGlossaryApiTest.java index 0e31e129..4aeeaf1b 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/api/AgentGlossaryApiTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/api/AgentGlossaryApiTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/api/AgentIngestJobsApiTest.java b/sdks/java/src/test/java/com/firefly/flyquery/api/AgentIngestJobsApiTest.java index 0a126261..acce02b8 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/api/AgentIngestJobsApiTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/api/AgentIngestJobsApiTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/api/AgentQueryApiTest.java b/sdks/java/src/test/java/com/firefly/flyquery/api/AgentQueryApiTest.java index 450ac67c..205ed2d8 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/api/AgentQueryApiTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/api/AgentQueryApiTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/api/AgentRelationsApiTest.java b/sdks/java/src/test/java/com/firefly/flyquery/api/AgentRelationsApiTest.java index 3998123a..929c1e0d 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/api/AgentRelationsApiTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/api/AgentRelationsApiTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/api/AgentSemanticDimensionsApiTest.java b/sdks/java/src/test/java/com/firefly/flyquery/api/AgentSemanticDimensionsApiTest.java index 0c6f853e..e1c77dc1 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/api/AgentSemanticDimensionsApiTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/api/AgentSemanticDimensionsApiTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/api/AgentSemanticMetricsApiTest.java b/sdks/java/src/test/java/com/firefly/flyquery/api/AgentSemanticMetricsApiTest.java index cac2dc2a..ccc11626 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/api/AgentSemanticMetricsApiTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/api/AgentSemanticMetricsApiTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/api/AgentSqlExecuteApiTest.java b/sdks/java/src/test/java/com/firefly/flyquery/api/AgentSqlExecuteApiTest.java index 4980ef26..2472fe13 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/api/AgentSqlExecuteApiTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/api/AgentSqlExecuteApiTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/api/AgentTablesApiTest.java b/sdks/java/src/test/java/com/firefly/flyquery/api/AgentTablesApiTest.java index 40f34844..2b22dbb5 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/api/AgentTablesApiTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/api/AgentTablesApiTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/api/AgentTokensApiTest.java b/sdks/java/src/test/java/com/firefly/flyquery/api/AgentTokensApiTest.java index 089342ed..c35c3c5d 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/api/AgentTokensApiTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/api/AgentTokensApiTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/api/AgentVersionApiTest.java b/sdks/java/src/test/java/com/firefly/flyquery/api/AgentVersionApiTest.java index 2e075d34..83d523e2 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/api/AgentVersionApiTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/api/AgentVersionApiTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/api/AuditEventsApiTest.java b/sdks/java/src/test/java/com/firefly/flyquery/api/AuditEventsApiTest.java index 56d2de02..95b1dbb5 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/api/AuditEventsApiTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/api/AuditEventsApiTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/api/BillingApiTest.java b/sdks/java/src/test/java/com/firefly/flyquery/api/BillingApiTest.java index 624ea2f0..997444dc 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/api/BillingApiTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/api/BillingApiTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/api/ConversationsApiTest.java b/sdks/java/src/test/java/com/firefly/flyquery/api/ConversationsApiTest.java index 3fd290c2..81b8ccb3 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/api/ConversationsApiTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/api/ConversationsApiTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/api/CostEventsApiTest.java b/sdks/java/src/test/java/com/firefly/flyquery/api/CostEventsApiTest.java index a973491f..bf134670 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/api/CostEventsApiTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/api/CostEventsApiTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/api/DatasetsApiTest.java b/sdks/java/src/test/java/com/firefly/flyquery/api/DatasetsApiTest.java index 0c689734..e26cff81 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/api/DatasetsApiTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/api/DatasetsApiTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/api/ExamplesApiTest.java b/sdks/java/src/test/java/com/firefly/flyquery/api/ExamplesApiTest.java index 88346531..3d7c7d50 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/api/ExamplesApiTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/api/ExamplesApiTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/api/FilesApiTest.java b/sdks/java/src/test/java/com/firefly/flyquery/api/FilesApiTest.java index 31bc4623..b47f4b7b 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/api/FilesApiTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/api/FilesApiTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/api/GlossaryApiTest.java b/sdks/java/src/test/java/com/firefly/flyquery/api/GlossaryApiTest.java index 075b2df1..7fd2e6e2 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/api/GlossaryApiTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/api/GlossaryApiTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/api/IngestJobsApiTest.java b/sdks/java/src/test/java/com/firefly/flyquery/api/IngestJobsApiTest.java index 383b9016..b53da9bc 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/api/IngestJobsApiTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/api/IngestJobsApiTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/api/QueriesApiTest.java b/sdks/java/src/test/java/com/firefly/flyquery/api/QueriesApiTest.java index 689e96fa..e6cbc1d6 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/api/QueriesApiTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/api/QueriesApiTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/api/QueryApiTest.java b/sdks/java/src/test/java/com/firefly/flyquery/api/QueryApiTest.java index 6b5dd48c..abc77c34 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/api/QueryApiTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/api/QueryApiTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/api/RelationsApiTest.java b/sdks/java/src/test/java/com/firefly/flyquery/api/RelationsApiTest.java index c156272e..ef7ce232 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/api/RelationsApiTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/api/RelationsApiTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/api/SchemaChangesApiTest.java b/sdks/java/src/test/java/com/firefly/flyquery/api/SchemaChangesApiTest.java index d8c8e1ea..7f2eb862 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/api/SchemaChangesApiTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/api/SchemaChangesApiTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/api/SchemaObjectsApiTest.java b/sdks/java/src/test/java/com/firefly/flyquery/api/SchemaObjectsApiTest.java index d5d78ec0..1ecdf2c4 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/api/SchemaObjectsApiTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/api/SchemaObjectsApiTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/api/SemanticDimensionsApiTest.java b/sdks/java/src/test/java/com/firefly/flyquery/api/SemanticDimensionsApiTest.java index d89f57a4..12ec5b6c 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/api/SemanticDimensionsApiTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/api/SemanticDimensionsApiTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/api/SemanticMetricsApiTest.java b/sdks/java/src/test/java/com/firefly/flyquery/api/SemanticMetricsApiTest.java index 34a2000d..194553cb 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/api/SemanticMetricsApiTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/api/SemanticMetricsApiTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/api/SqlExecuteApiTest.java b/sdks/java/src/test/java/com/firefly/flyquery/api/SqlExecuteApiTest.java index 67bdc99f..c67a6d4b 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/api/SqlExecuteApiTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/api/SqlExecuteApiTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/api/StatsApiTest.java b/sdks/java/src/test/java/com/firefly/flyquery/api/StatsApiTest.java index 269ec6d3..20daf128 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/api/StatsApiTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/api/StatsApiTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/api/TablesApiTest.java b/sdks/java/src/test/java/com/firefly/flyquery/api/TablesApiTest.java index d28c2851..1be8d94f 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/api/TablesApiTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/api/TablesApiTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/api/TablesDeriveApiTest.java b/sdks/java/src/test/java/com/firefly/flyquery/api/TablesDeriveApiTest.java index 77d1e25d..c40bc863 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/api/TablesDeriveApiTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/api/TablesDeriveApiTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/api/VersionApiTest.java b/sdks/java/src/test/java/com/firefly/flyquery/api/VersionApiTest.java index 5d5a6a23..f8a40627 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/api/VersionApiTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/api/VersionApiTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/api/WorkspacesApiTest.java b/sdks/java/src/test/java/com/firefly/flyquery/api/WorkspacesApiTest.java index ab25d085..687ab21d 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/api/WorkspacesApiTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/api/WorkspacesApiTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/model/AgentTokenCreatedTest.java b/sdks/java/src/test/java/com/firefly/flyquery/model/AgentTokenCreatedTest.java index fd376e8b..9fcf28b7 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/model/AgentTokenCreatedTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/model/AgentTokenCreatedTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/model/AgentTokenMintRequestTest.java b/sdks/java/src/test/java/com/firefly/flyquery/model/AgentTokenMintRequestTest.java index 934f9112..13b76bdf 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/model/AgentTokenMintRequestTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/model/AgentTokenMintRequestTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/model/AgentTokenSummaryDtoTest.java b/sdks/java/src/test/java/com/firefly/flyquery/model/AgentTokenSummaryDtoTest.java index b672e77e..89f10e25 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/model/AgentTokenSummaryDtoTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/model/AgentTokenSummaryDtoTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/model/AgentUsageTest.java b/sdks/java/src/test/java/com/firefly/flyquery/model/AgentUsageTest.java index 868e6c98..1a96025d 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/model/AgentUsageTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/model/AgentUsageTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/model/AnswerResponseTest.java b/sdks/java/src/test/java/com/firefly/flyquery/model/AnswerResponseTest.java index d86c6eec..a861f316 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/model/AnswerResponseTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/model/AnswerResponseTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/model/AuditEventReadTest.java b/sdks/java/src/test/java/com/firefly/flyquery/model/AuditEventReadTest.java index e12c5489..9874db66 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/model/AuditEventReadTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/model/AuditEventReadTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/model/BatchQueryItemTest.java b/sdks/java/src/test/java/com/firefly/flyquery/model/BatchQueryItemTest.java index 3bead233..7dc426f7 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/model/BatchQueryItemTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/model/BatchQueryItemTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/model/BatchQueryRequestTest.java b/sdks/java/src/test/java/com/firefly/flyquery/model/BatchQueryRequestTest.java index efc95887..9638cffc 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/model/BatchQueryRequestTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/model/BatchQueryRequestTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/model/BatchQueryResponseTest.java b/sdks/java/src/test/java/com/firefly/flyquery/model/BatchQueryResponseTest.java index a86da406..5489e1eb 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/model/BatchQueryResponseTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/model/BatchQueryResponseTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/model/BatchQueryResultItemTest.java b/sdks/java/src/test/java/com/firefly/flyquery/model/BatchQueryResultItemTest.java index 78c14117..e32096a8 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/model/BatchQueryResultItemTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/model/BatchQueryResultItemTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/model/BillingBreakdownItemTest.java b/sdks/java/src/test/java/com/firefly/flyquery/model/BillingBreakdownItemTest.java index c3c8fbf2..1d03e2ca 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/model/BillingBreakdownItemTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/model/BillingBreakdownItemTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/model/BillingRollupTest.java b/sdks/java/src/test/java/com/firefly/flyquery/model/BillingRollupTest.java index 0bce7e46..3e5fb1d8 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/model/BillingRollupTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/model/BillingRollupTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/model/BulkFileResultTest.java b/sdks/java/src/test/java/com/firefly/flyquery/model/BulkFileResultTest.java index 068c6f5c..10753453 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/model/BulkFileResultTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/model/BulkFileResultTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/model/BulkFileUploadResponseTest.java b/sdks/java/src/test/java/com/firefly/flyquery/model/BulkFileUploadResponseTest.java index e4b58947..52b52693 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/model/BulkFileUploadResponseTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/model/BulkFileUploadResponseTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/model/CallbackConfigTest.java b/sdks/java/src/test/java/com/firefly/flyquery/model/CallbackConfigTest.java index be70a0c6..38d14b97 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/model/CallbackConfigTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/model/CallbackConfigTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/model/CallbackDeliveryListResponseTest.java b/sdks/java/src/test/java/com/firefly/flyquery/model/CallbackDeliveryListResponseTest.java index 0b25816b..a33bd46d 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/model/CallbackDeliveryListResponseTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/model/CallbackDeliveryListResponseTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/model/CallbackDeliveryReadTest.java b/sdks/java/src/test/java/com/firefly/flyquery/model/CallbackDeliveryReadTest.java index 1b66b820..5f1243ea 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/model/CallbackDeliveryReadTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/model/CallbackDeliveryReadTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/model/CancelResponseTest.java b/sdks/java/src/test/java/com/firefly/flyquery/model/CancelResponseTest.java index 6d97e399..bb53bb15 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/model/CancelResponseTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/model/CancelResponseTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/model/ClarificationFrameTest.java b/sdks/java/src/test/java/com/firefly/flyquery/model/ClarificationFrameTest.java index 76475c38..fb72d883 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/model/ClarificationFrameTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/model/ClarificationFrameTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/model/ConfidenceTest.java b/sdks/java/src/test/java/com/firefly/flyquery/model/ConfidenceTest.java index bf74af61..74f70d4b 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/model/ConfidenceTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/model/ConfidenceTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/model/ConversationCreateTest.java b/sdks/java/src/test/java/com/firefly/flyquery/model/ConversationCreateTest.java index b57d7207..9c259738 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/model/ConversationCreateTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/model/ConversationCreateTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/model/ConversationReadTest.java b/sdks/java/src/test/java/com/firefly/flyquery/model/ConversationReadTest.java index 7f2b132d..cdefa14f 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/model/ConversationReadTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/model/ConversationReadTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/model/ConversationTurnRequestTest.java b/sdks/java/src/test/java/com/firefly/flyquery/model/ConversationTurnRequestTest.java index 00493c3d..aeeaaba4 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/model/ConversationTurnRequestTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/model/ConversationTurnRequestTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/model/CostCents1Test.java b/sdks/java/src/test/java/com/firefly/flyquery/model/CostCents1Test.java index 98a2add0..fd35c4f8 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/model/CostCents1Test.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/model/CostCents1Test.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/model/CostCentsTest.java b/sdks/java/src/test/java/com/firefly/flyquery/model/CostCentsTest.java index 8f405be9..5f336ddd 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/model/CostCentsTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/model/CostCentsTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/model/CostEventReadTest.java b/sdks/java/src/test/java/com/firefly/flyquery/model/CostEventReadTest.java index 4580c22b..ae0caec9 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/model/CostEventReadTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/model/CostEventReadTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/model/DatasetCreateTest.java b/sdks/java/src/test/java/com/firefly/flyquery/model/DatasetCreateTest.java index fb711dbe..26b3006b 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/model/DatasetCreateTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/model/DatasetCreateTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/model/DatasetReadTest.java b/sdks/java/src/test/java/com/firefly/flyquery/model/DatasetReadTest.java index de2a9e50..2426e5bd 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/model/DatasetReadTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/model/DatasetReadTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/model/DatasetUpdateTest.java b/sdks/java/src/test/java/com/firefly/flyquery/model/DatasetUpdateTest.java index edea739d..34760847 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/model/DatasetUpdateTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/model/DatasetUpdateTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/model/DeriveTableRequestTest.java b/sdks/java/src/test/java/com/firefly/flyquery/model/DeriveTableRequestTest.java index 004121e6..3208fbfb 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/model/DeriveTableRequestTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/model/DeriveTableRequestTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/model/DeriveTableResponseTest.java b/sdks/java/src/test/java/com/firefly/flyquery/model/DeriveTableResponseTest.java index ebbe97dd..df65eec2 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/model/DeriveTableResponseTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/model/DeriveTableResponseTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/model/DetailInnerTest.java b/sdks/java/src/test/java/com/firefly/flyquery/model/DetailInnerTest.java index 9c9dbab3..741d4447 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/model/DetailInnerTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/model/DetailInnerTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/model/ExampleCreateTest.java b/sdks/java/src/test/java/com/firefly/flyquery/model/ExampleCreateTest.java index e234f2a6..7e29a87f 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/model/ExampleCreateTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/model/ExampleCreateTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/model/ExampleReadTest.java b/sdks/java/src/test/java/com/firefly/flyquery/model/ExampleReadTest.java index efac6f85..de0c8b8d 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/model/ExampleReadTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/model/ExampleReadTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/model/ExplainResponseTest.java b/sdks/java/src/test/java/com/firefly/flyquery/model/ExplainResponseTest.java index 3fbec14a..d9092725 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/model/ExplainResponseTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/model/ExplainResponseTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/model/FileUploadResponseTest.java b/sdks/java/src/test/java/com/firefly/flyquery/model/FileUploadResponseTest.java index deb8d91c..52f6075d 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/model/FileUploadResponseTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/model/FileUploadResponseTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/model/GlossaryTermCreateTest.java b/sdks/java/src/test/java/com/firefly/flyquery/model/GlossaryTermCreateTest.java index d35aa7b4..05443222 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/model/GlossaryTermCreateTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/model/GlossaryTermCreateTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/model/GlossaryTermReadTest.java b/sdks/java/src/test/java/com/firefly/flyquery/model/GlossaryTermReadTest.java index 544ad18f..168e97ea 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/model/GlossaryTermReadTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/model/GlossaryTermReadTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/model/GlossaryTermUpdateTest.java b/sdks/java/src/test/java/com/firefly/flyquery/model/GlossaryTermUpdateTest.java index 732cbee9..298d50c6 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/model/GlossaryTermUpdateTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/model/GlossaryTermUpdateTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/model/HTTPValidationErrorTest.java b/sdks/java/src/test/java/com/firefly/flyquery/model/HTTPValidationErrorTest.java index 23cf0b1d..9e558204 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/model/HTTPValidationErrorTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/model/HTTPValidationErrorTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/model/IngestCostCentsTest.java b/sdks/java/src/test/java/com/firefly/flyquery/model/IngestCostCentsTest.java index 6716c2df..dbf4a213 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/model/IngestCostCentsTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/model/IngestCostCentsTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/model/IngestEventListResponseTest.java b/sdks/java/src/test/java/com/firefly/flyquery/model/IngestEventListResponseTest.java index ee4927b2..75d8eeb0 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/model/IngestEventListResponseTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/model/IngestEventListResponseTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/model/IngestEventReadTest.java b/sdks/java/src/test/java/com/firefly/flyquery/model/IngestEventReadTest.java index 550090c4..7504832f 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/model/IngestEventReadTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/model/IngestEventReadTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/model/IngestJobCreateTest.java b/sdks/java/src/test/java/com/firefly/flyquery/model/IngestJobCreateTest.java index 25a806ae..c78464fc 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/model/IngestJobCreateTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/model/IngestJobCreateTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/model/IngestJobListResponseTest.java b/sdks/java/src/test/java/com/firefly/flyquery/model/IngestJobListResponseTest.java index 4b87e76d..24bec05d 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/model/IngestJobListResponseTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/model/IngestJobListResponseTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/model/IngestJobReadTest.java b/sdks/java/src/test/java/com/firefly/flyquery/model/IngestJobReadTest.java index b51f808d..ba7001f0 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/model/IngestJobReadTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/model/IngestJobReadTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/model/LocationInnerTest.java b/sdks/java/src/test/java/com/firefly/flyquery/model/LocationInnerTest.java index d3b9673c..0b565155 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/model/LocationInnerTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/model/LocationInnerTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/model/OtherCostCentsTest.java b/sdks/java/src/test/java/com/firefly/flyquery/model/OtherCostCentsTest.java index d3fb36ca..30e95495 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/model/OtherCostCentsTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/model/OtherCostCentsTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/model/PaginatedAuditEventReadTest.java b/sdks/java/src/test/java/com/firefly/flyquery/model/PaginatedAuditEventReadTest.java index 5ffed0d6..92568b5a 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/model/PaginatedAuditEventReadTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/model/PaginatedAuditEventReadTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/model/PaginatedConversationReadTest.java b/sdks/java/src/test/java/com/firefly/flyquery/model/PaginatedConversationReadTest.java index 0b8fb8f4..1a9d18f8 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/model/PaginatedConversationReadTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/model/PaginatedConversationReadTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/model/PaginatedCostEventReadTest.java b/sdks/java/src/test/java/com/firefly/flyquery/model/PaginatedCostEventReadTest.java index cec853ab..4374a303 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/model/PaginatedCostEventReadTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/model/PaginatedCostEventReadTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/model/PaginatedDatasetReadTest.java b/sdks/java/src/test/java/com/firefly/flyquery/model/PaginatedDatasetReadTest.java index 7dbc4cde..e4c3f770 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/model/PaginatedDatasetReadTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/model/PaginatedDatasetReadTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/model/PaginatedExampleReadTest.java b/sdks/java/src/test/java/com/firefly/flyquery/model/PaginatedExampleReadTest.java index 8d05d3cf..8ec92469 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/model/PaginatedExampleReadTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/model/PaginatedExampleReadTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/model/PaginatedGlossaryTermReadTest.java b/sdks/java/src/test/java/com/firefly/flyquery/model/PaginatedGlossaryTermReadTest.java index cf18ff92..ff893369 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/model/PaginatedGlossaryTermReadTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/model/PaginatedGlossaryTermReadTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/model/PaginatedQueryHistoryItemTest.java b/sdks/java/src/test/java/com/firefly/flyquery/model/PaginatedQueryHistoryItemTest.java index 863819f3..6a821fd0 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/model/PaginatedQueryHistoryItemTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/model/PaginatedQueryHistoryItemTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/model/PaginatedRelationReadTest.java b/sdks/java/src/test/java/com/firefly/flyquery/model/PaginatedRelationReadTest.java index 4b60e9cf..ae2c9974 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/model/PaginatedRelationReadTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/model/PaginatedRelationReadTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/model/PaginatedSchemaChangeReadTest.java b/sdks/java/src/test/java/com/firefly/flyquery/model/PaginatedSchemaChangeReadTest.java index 080aeb57..ba40846a 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/model/PaginatedSchemaChangeReadTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/model/PaginatedSchemaChangeReadTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/model/PaginatedSchemaObjectReadTest.java b/sdks/java/src/test/java/com/firefly/flyquery/model/PaginatedSchemaObjectReadTest.java index dde2dc42..6df0e99c 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/model/PaginatedSchemaObjectReadTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/model/PaginatedSchemaObjectReadTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/model/PaginatedSemanticDimensionReadTest.java b/sdks/java/src/test/java/com/firefly/flyquery/model/PaginatedSemanticDimensionReadTest.java index 404e7186..605265b5 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/model/PaginatedSemanticDimensionReadTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/model/PaginatedSemanticDimensionReadTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/model/PaginatedSemanticMetricReadTest.java b/sdks/java/src/test/java/com/firefly/flyquery/model/PaginatedSemanticMetricReadTest.java index cde881a0..bf83c75a 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/model/PaginatedSemanticMetricReadTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/model/PaginatedSemanticMetricReadTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/model/PaginatedSemanticVersionReadTest.java b/sdks/java/src/test/java/com/firefly/flyquery/model/PaginatedSemanticVersionReadTest.java index 22c1802b..e294f9a2 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/model/PaginatedSemanticVersionReadTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/model/PaginatedSemanticVersionReadTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/model/PaginatedSnapshotReadTest.java b/sdks/java/src/test/java/com/firefly/flyquery/model/PaginatedSnapshotReadTest.java index bbde838c..599f76c9 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/model/PaginatedSnapshotReadTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/model/PaginatedSnapshotReadTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/model/PaginatedTableReadTest.java b/sdks/java/src/test/java/com/firefly/flyquery/model/PaginatedTableReadTest.java index 28c7f638..be7c7130 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/model/PaginatedTableReadTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/model/PaginatedTableReadTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/model/PaginatedWorkspaceReadTest.java b/sdks/java/src/test/java/com/firefly/flyquery/model/PaginatedWorkspaceReadTest.java index 2ef758b7..3db3446e 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/model/PaginatedWorkspaceReadTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/model/PaginatedWorkspaceReadTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/model/PurgeAcceptedTest.java b/sdks/java/src/test/java/com/firefly/flyquery/model/PurgeAcceptedTest.java index c0d4cb3c..9281443b 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/model/PurgeAcceptedTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/model/PurgeAcceptedTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/model/QueryCostCentsTest.java b/sdks/java/src/test/java/com/firefly/flyquery/model/QueryCostCentsTest.java index 9f3b2618..0807c961 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/model/QueryCostCentsTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/model/QueryCostCentsTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/model/QueryDetailReadTest.java b/sdks/java/src/test/java/com/firefly/flyquery/model/QueryDetailReadTest.java index f48a6559..1f49168a 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/model/QueryDetailReadTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/model/QueryDetailReadTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/model/QueryHistoryItemTest.java b/sdks/java/src/test/java/com/firefly/flyquery/model/QueryHistoryItemTest.java index a6fedfa5..73b1ca5c 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/model/QueryHistoryItemTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/model/QueryHistoryItemTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/model/QueryRequestTest.java b/sdks/java/src/test/java/com/firefly/flyquery/model/QueryRequestTest.java index 35c92168..66799dfd 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/model/QueryRequestTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/model/QueryRequestTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/model/QueryResultReadTest.java b/sdks/java/src/test/java/com/firefly/flyquery/model/QueryResultReadTest.java index ecc4a88f..a83083ae 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/model/QueryResultReadTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/model/QueryResultReadTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/model/RelationApprovalReadTest.java b/sdks/java/src/test/java/com/firefly/flyquery/model/RelationApprovalReadTest.java index edb5f06c..ed346491 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/model/RelationApprovalReadTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/model/RelationApprovalReadTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/model/RelationReadTest.java b/sdks/java/src/test/java/com/firefly/flyquery/model/RelationReadTest.java index fdd49486..2b9c5bc0 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/model/RelationReadTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/model/RelationReadTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/model/RelationRejectionReadTest.java b/sdks/java/src/test/java/com/firefly/flyquery/model/RelationRejectionReadTest.java index 5f7e01e9..c03ef16b 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/model/RelationRejectionReadTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/model/RelationRejectionReadTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/model/ReuploadResponseTest.java b/sdks/java/src/test/java/com/firefly/flyquery/model/ReuploadResponseTest.java index 6387c5a5..4ecf074c 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/model/ReuploadResponseTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/model/ReuploadResponseTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/model/SchemaChangeReadTest.java b/sdks/java/src/test/java/com/firefly/flyquery/model/SchemaChangeReadTest.java index d536a957..664af092 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/model/SchemaChangeReadTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/model/SchemaChangeReadTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/model/SchemaObjectReadTest.java b/sdks/java/src/test/java/com/firefly/flyquery/model/SchemaObjectReadTest.java index df933b2f..f9c21985 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/model/SchemaObjectReadTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/model/SchemaObjectReadTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/model/SchemaObjectUpdateTest.java b/sdks/java/src/test/java/com/firefly/flyquery/model/SchemaObjectUpdateTest.java index 20ac543f..f24a84b8 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/model/SchemaObjectUpdateTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/model/SchemaObjectUpdateTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/model/SemanticDimensionCreateTest.java b/sdks/java/src/test/java/com/firefly/flyquery/model/SemanticDimensionCreateTest.java index 2ef460cc..eabf3999 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/model/SemanticDimensionCreateTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/model/SemanticDimensionCreateTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/model/SemanticDimensionReadTest.java b/sdks/java/src/test/java/com/firefly/flyquery/model/SemanticDimensionReadTest.java index 44a57e9a..47ef465d 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/model/SemanticDimensionReadTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/model/SemanticDimensionReadTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/model/SemanticDimensionUpdateTest.java b/sdks/java/src/test/java/com/firefly/flyquery/model/SemanticDimensionUpdateTest.java index 66d7dbde..7835fb91 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/model/SemanticDimensionUpdateTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/model/SemanticDimensionUpdateTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/model/SemanticMetricCreateTest.java b/sdks/java/src/test/java/com/firefly/flyquery/model/SemanticMetricCreateTest.java index c7499953..a6fbbba1 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/model/SemanticMetricCreateTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/model/SemanticMetricCreateTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/model/SemanticMetricReadTest.java b/sdks/java/src/test/java/com/firefly/flyquery/model/SemanticMetricReadTest.java index 77dc30f0..e434cecb 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/model/SemanticMetricReadTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/model/SemanticMetricReadTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/model/SemanticMetricUpdateTest.java b/sdks/java/src/test/java/com/firefly/flyquery/model/SemanticMetricUpdateTest.java index 11f1b7ab..c09e6f90 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/model/SemanticMetricUpdateTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/model/SemanticMetricUpdateTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/model/SemanticVersionReadTest.java b/sdks/java/src/test/java/com/firefly/flyquery/model/SemanticVersionReadTest.java index 097ade3a..57e0b30b 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/model/SemanticVersionReadTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/model/SemanticVersionReadTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/model/SnapshotReadTest.java b/sdks/java/src/test/java/com/firefly/flyquery/model/SnapshotReadTest.java index 1f0d33aa..4cd4d265 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/model/SnapshotReadTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/model/SnapshotReadTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/model/SqlExecuteRequestTest.java b/sdks/java/src/test/java/com/firefly/flyquery/model/SqlExecuteRequestTest.java index e0972cdf..ecb022e2 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/model/SqlExecuteRequestTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/model/SqlExecuteRequestTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/model/SqlExecuteResponseTest.java b/sdks/java/src/test/java/com/firefly/flyquery/model/SqlExecuteResponseTest.java index 613bfee2..91657969 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/model/SqlExecuteResponseTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/model/SqlExecuteResponseTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/model/TableReadTest.java b/sdks/java/src/test/java/com/firefly/flyquery/model/TableReadTest.java index f229f90c..6de07527 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/model/TableReadTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/model/TableReadTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/model/TableSummaryTest.java b/sdks/java/src/test/java/com/firefly/flyquery/model/TableSummaryTest.java index 908725a3..d3f41dbb 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/model/TableSummaryTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/model/TableSummaryTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/model/TotalCostCentsTest.java b/sdks/java/src/test/java/com/firefly/flyquery/model/TotalCostCentsTest.java index 090bbffb..45bd8ca9 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/model/TotalCostCentsTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/model/TotalCostCentsTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/model/TurnReadTest.java b/sdks/java/src/test/java/com/firefly/flyquery/model/TurnReadTest.java index b5896bb7..24dce2c6 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/model/TurnReadTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/model/TurnReadTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/model/UsageSummaryTest.java b/sdks/java/src/test/java/com/firefly/flyquery/model/UsageSummaryTest.java index 8b4ec81f..2df1555b 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/model/UsageSummaryTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/model/UsageSummaryTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/model/ValidateResponseTest.java b/sdks/java/src/test/java/com/firefly/flyquery/model/ValidateResponseTest.java index 490b32ba..7c3fc8e2 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/model/ValidateResponseTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/model/ValidateResponseTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/model/ValidationErrorTest.java b/sdks/java/src/test/java/com/firefly/flyquery/model/ValidationErrorTest.java index 064e618b..7be9f487 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/model/ValidationErrorTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/model/ValidationErrorTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/model/WorkspaceCreateTest.java b/sdks/java/src/test/java/com/firefly/flyquery/model/WorkspaceCreateTest.java index 02ac9d2d..290c3dca 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/model/WorkspaceCreateTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/model/WorkspaceCreateTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/model/WorkspaceReadTest.java b/sdks/java/src/test/java/com/firefly/flyquery/model/WorkspaceReadTest.java index 8717b8e4..62010f0a 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/model/WorkspaceReadTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/model/WorkspaceReadTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/model/WorkspaceStatsTest.java b/sdks/java/src/test/java/com/firefly/flyquery/model/WorkspaceStatsTest.java index 851e2aa3..83aac4e4 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/model/WorkspaceStatsTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/model/WorkspaceStatsTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/java/src/test/java/com/firefly/flyquery/model/WorkspaceUpdateTest.java b/sdks/java/src/test/java/com/firefly/flyquery/model/WorkspaceUpdateTest.java index a62131cf..d78f3558 100644 --- a/sdks/java/src/test/java/com/firefly/flyquery/model/WorkspaceUpdateTest.java +++ b/sdks/java/src/test/java/com/firefly/flyquery/model/WorkspaceUpdateTest.java @@ -2,7 +2,7 @@ * flyquery * Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. * - * The version of the OpenAPI document: 26.10.1 + * The version of the OpenAPI document: 26.10.2 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdks/python/README.md b/sdks/python/README.md index c2b8300b..b4d67e0a 100644 --- a/sdks/python/README.md +++ b/sdks/python/README.md @@ -16,16 +16,16 @@ it does not install the flyquery server, pyfly or fireflyframework-agentic. ## Install -For the 26.10.1 release, install the wheel from GitHub Releases: +For the 26.10.2 release, install the wheel from GitHub Releases: ```bash -uv add https://github.com/fireflyframework/flyquery/releases/download/v26.10.1/flyquery_sdk-26.10.1-py3-none-any.whl +uv add https://github.com/fireflyframework/flyquery/releases/download/v26.10.2/flyquery_sdk-26.10.2-py3-none-any.whl # Or, in an activated Python environment: -pip install https://github.com/fireflyframework/flyquery/releases/download/v26.10.1/flyquery_sdk-26.10.1-py3-none-any.whl +pip install https://github.com/fireflyframework/flyquery/releases/download/v26.10.2/flyquery_sdk-26.10.2-py3-none-any.whl ``` The source distribution is attached to the same -[release](https://github.com/fireflyframework/flyquery/releases/tag/v26.10.1). +[release](https://github.com/fireflyframework/flyquery/releases/tag/v26.10.2). The project publishes Python packages through GitHub Releases. For development, run `uv pip install -e './sdks/python[dev]'` from the repository root. diff --git a/sdks/python/flyquery_sdk/__init__.py b/sdks/python/flyquery_sdk/__init__.py index b0b0d992..d3b0a198 100644 --- a/sdks/python/flyquery_sdk/__init__.py +++ b/sdks/python/flyquery_sdk/__init__.py @@ -7,14 +7,14 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. """ # noqa: E501 -__version__ = "26.10.1" +__version__ = "26.10.2" # Define package exports __all__ = [ diff --git a/sdks/python/flyquery_sdk/api/agent_conversations_api.py b/sdks/python/flyquery_sdk/api/agent_conversations_api.py index e078fc5d..a8e5336b 100644 --- a/sdks/python/flyquery_sdk/api/agent_conversations_api.py +++ b/sdks/python/flyquery_sdk/api/agent_conversations_api.py @@ -3,7 +3,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/api/agent_datasets_api.py b/sdks/python/flyquery_sdk/api/agent_datasets_api.py index b06564d9..ba96cb4b 100644 --- a/sdks/python/flyquery_sdk/api/agent_datasets_api.py +++ b/sdks/python/flyquery_sdk/api/agent_datasets_api.py @@ -3,7 +3,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/api/agent_examples_api.py b/sdks/python/flyquery_sdk/api/agent_examples_api.py index 4a417099..90061427 100644 --- a/sdks/python/flyquery_sdk/api/agent_examples_api.py +++ b/sdks/python/flyquery_sdk/api/agent_examples_api.py @@ -3,7 +3,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/api/agent_glossary_api.py b/sdks/python/flyquery_sdk/api/agent_glossary_api.py index c248a3da..aac0ad2d 100644 --- a/sdks/python/flyquery_sdk/api/agent_glossary_api.py +++ b/sdks/python/flyquery_sdk/api/agent_glossary_api.py @@ -3,7 +3,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/api/agent_ingest_jobs_api.py b/sdks/python/flyquery_sdk/api/agent_ingest_jobs_api.py index 205e030f..460392a9 100644 --- a/sdks/python/flyquery_sdk/api/agent_ingest_jobs_api.py +++ b/sdks/python/flyquery_sdk/api/agent_ingest_jobs_api.py @@ -3,7 +3,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/api/agent_query_api.py b/sdks/python/flyquery_sdk/api/agent_query_api.py index 4bb58203..650b17aa 100644 --- a/sdks/python/flyquery_sdk/api/agent_query_api.py +++ b/sdks/python/flyquery_sdk/api/agent_query_api.py @@ -3,7 +3,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/api/agent_relations_api.py b/sdks/python/flyquery_sdk/api/agent_relations_api.py index b7b5610c..b687cd51 100644 --- a/sdks/python/flyquery_sdk/api/agent_relations_api.py +++ b/sdks/python/flyquery_sdk/api/agent_relations_api.py @@ -3,7 +3,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/api/agent_semantic_dimensions_api.py b/sdks/python/flyquery_sdk/api/agent_semantic_dimensions_api.py index e89daf7e..4e1ed293 100644 --- a/sdks/python/flyquery_sdk/api/agent_semantic_dimensions_api.py +++ b/sdks/python/flyquery_sdk/api/agent_semantic_dimensions_api.py @@ -3,7 +3,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/api/agent_semantic_metrics_api.py b/sdks/python/flyquery_sdk/api/agent_semantic_metrics_api.py index 411e3273..9aa37e58 100644 --- a/sdks/python/flyquery_sdk/api/agent_semantic_metrics_api.py +++ b/sdks/python/flyquery_sdk/api/agent_semantic_metrics_api.py @@ -3,7 +3,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/api/agent_sql_execute_api.py b/sdks/python/flyquery_sdk/api/agent_sql_execute_api.py index 31e1ba34..033b31c5 100644 --- a/sdks/python/flyquery_sdk/api/agent_sql_execute_api.py +++ b/sdks/python/flyquery_sdk/api/agent_sql_execute_api.py @@ -3,7 +3,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/api/agent_tables_api.py b/sdks/python/flyquery_sdk/api/agent_tables_api.py index 234f382f..7911f118 100644 --- a/sdks/python/flyquery_sdk/api/agent_tables_api.py +++ b/sdks/python/flyquery_sdk/api/agent_tables_api.py @@ -3,7 +3,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/api/agent_tokens_api.py b/sdks/python/flyquery_sdk/api/agent_tokens_api.py index 77dc99a3..dad259f7 100644 --- a/sdks/python/flyquery_sdk/api/agent_tokens_api.py +++ b/sdks/python/flyquery_sdk/api/agent_tokens_api.py @@ -3,7 +3,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/api/agent_version_api.py b/sdks/python/flyquery_sdk/api/agent_version_api.py index 245074b9..5459cf11 100644 --- a/sdks/python/flyquery_sdk/api/agent_version_api.py +++ b/sdks/python/flyquery_sdk/api/agent_version_api.py @@ -3,7 +3,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/api/audit_events_api.py b/sdks/python/flyquery_sdk/api/audit_events_api.py index 390c3705..25c97808 100644 --- a/sdks/python/flyquery_sdk/api/audit_events_api.py +++ b/sdks/python/flyquery_sdk/api/audit_events_api.py @@ -3,7 +3,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/api/billing_api.py b/sdks/python/flyquery_sdk/api/billing_api.py index 5c788027..38420c25 100644 --- a/sdks/python/flyquery_sdk/api/billing_api.py +++ b/sdks/python/flyquery_sdk/api/billing_api.py @@ -3,7 +3,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/api/conversations_api.py b/sdks/python/flyquery_sdk/api/conversations_api.py index f4e45ba6..af74ef7d 100644 --- a/sdks/python/flyquery_sdk/api/conversations_api.py +++ b/sdks/python/flyquery_sdk/api/conversations_api.py @@ -3,7 +3,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/api/cost_events_api.py b/sdks/python/flyquery_sdk/api/cost_events_api.py index d6beae0a..1a57cd73 100644 --- a/sdks/python/flyquery_sdk/api/cost_events_api.py +++ b/sdks/python/flyquery_sdk/api/cost_events_api.py @@ -3,7 +3,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/api/datasets_api.py b/sdks/python/flyquery_sdk/api/datasets_api.py index 7bb03af0..a84b059a 100644 --- a/sdks/python/flyquery_sdk/api/datasets_api.py +++ b/sdks/python/flyquery_sdk/api/datasets_api.py @@ -3,7 +3,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/api/examples_api.py b/sdks/python/flyquery_sdk/api/examples_api.py index 520228d8..a2f565a9 100644 --- a/sdks/python/flyquery_sdk/api/examples_api.py +++ b/sdks/python/flyquery_sdk/api/examples_api.py @@ -3,7 +3,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/api/files_api.py b/sdks/python/flyquery_sdk/api/files_api.py index 45d393ae..a9d40e2d 100644 --- a/sdks/python/flyquery_sdk/api/files_api.py +++ b/sdks/python/flyquery_sdk/api/files_api.py @@ -3,7 +3,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/api/glossary_api.py b/sdks/python/flyquery_sdk/api/glossary_api.py index 4cb012f9..beac8a6a 100644 --- a/sdks/python/flyquery_sdk/api/glossary_api.py +++ b/sdks/python/flyquery_sdk/api/glossary_api.py @@ -3,7 +3,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/api/ingest_jobs_api.py b/sdks/python/flyquery_sdk/api/ingest_jobs_api.py index 9fb6a5b1..eb64085d 100644 --- a/sdks/python/flyquery_sdk/api/ingest_jobs_api.py +++ b/sdks/python/flyquery_sdk/api/ingest_jobs_api.py @@ -3,7 +3,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/api/queries_api.py b/sdks/python/flyquery_sdk/api/queries_api.py index 6e989c76..93cb89a1 100644 --- a/sdks/python/flyquery_sdk/api/queries_api.py +++ b/sdks/python/flyquery_sdk/api/queries_api.py @@ -3,7 +3,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/api/query_api.py b/sdks/python/flyquery_sdk/api/query_api.py index e467e4a9..7de5b7a5 100644 --- a/sdks/python/flyquery_sdk/api/query_api.py +++ b/sdks/python/flyquery_sdk/api/query_api.py @@ -3,7 +3,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/api/relations_api.py b/sdks/python/flyquery_sdk/api/relations_api.py index 96bab3de..5211b101 100644 --- a/sdks/python/flyquery_sdk/api/relations_api.py +++ b/sdks/python/flyquery_sdk/api/relations_api.py @@ -3,7 +3,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/api/schema_changes_api.py b/sdks/python/flyquery_sdk/api/schema_changes_api.py index 32ed7772..1ca1bc0b 100644 --- a/sdks/python/flyquery_sdk/api/schema_changes_api.py +++ b/sdks/python/flyquery_sdk/api/schema_changes_api.py @@ -3,7 +3,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/api/schema_objects_api.py b/sdks/python/flyquery_sdk/api/schema_objects_api.py index 788dea02..d7d8dfc0 100644 --- a/sdks/python/flyquery_sdk/api/schema_objects_api.py +++ b/sdks/python/flyquery_sdk/api/schema_objects_api.py @@ -3,7 +3,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/api/semantic_dimensions_api.py b/sdks/python/flyquery_sdk/api/semantic_dimensions_api.py index 60764448..067175bf 100644 --- a/sdks/python/flyquery_sdk/api/semantic_dimensions_api.py +++ b/sdks/python/flyquery_sdk/api/semantic_dimensions_api.py @@ -3,7 +3,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/api/semantic_metrics_api.py b/sdks/python/flyquery_sdk/api/semantic_metrics_api.py index 9ee484fc..ebc50521 100644 --- a/sdks/python/flyquery_sdk/api/semantic_metrics_api.py +++ b/sdks/python/flyquery_sdk/api/semantic_metrics_api.py @@ -3,7 +3,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/api/sql_execute_api.py b/sdks/python/flyquery_sdk/api/sql_execute_api.py index 65035867..cd95a1b8 100644 --- a/sdks/python/flyquery_sdk/api/sql_execute_api.py +++ b/sdks/python/flyquery_sdk/api/sql_execute_api.py @@ -3,7 +3,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/api/stats_api.py b/sdks/python/flyquery_sdk/api/stats_api.py index 91aa6f12..9834b912 100644 --- a/sdks/python/flyquery_sdk/api/stats_api.py +++ b/sdks/python/flyquery_sdk/api/stats_api.py @@ -3,7 +3,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/api/tables_api.py b/sdks/python/flyquery_sdk/api/tables_api.py index 2d8bae94..e6d9f09b 100644 --- a/sdks/python/flyquery_sdk/api/tables_api.py +++ b/sdks/python/flyquery_sdk/api/tables_api.py @@ -3,7 +3,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/api/tables_derive_api.py b/sdks/python/flyquery_sdk/api/tables_derive_api.py index c8ea5dfb..ccacefe2 100644 --- a/sdks/python/flyquery_sdk/api/tables_derive_api.py +++ b/sdks/python/flyquery_sdk/api/tables_derive_api.py @@ -3,7 +3,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/api/version_api.py b/sdks/python/flyquery_sdk/api/version_api.py index bf373641..781be203 100644 --- a/sdks/python/flyquery_sdk/api/version_api.py +++ b/sdks/python/flyquery_sdk/api/version_api.py @@ -3,7 +3,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/api/workspaces_api.py b/sdks/python/flyquery_sdk/api/workspaces_api.py index 4f028bb1..73a629d7 100644 --- a/sdks/python/flyquery_sdk/api/workspaces_api.py +++ b/sdks/python/flyquery_sdk/api/workspaces_api.py @@ -3,7 +3,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/api_client.py b/sdks/python/flyquery_sdk/api_client.py index 025d4e09..32d13496 100644 --- a/sdks/python/flyquery_sdk/api_client.py +++ b/sdks/python/flyquery_sdk/api_client.py @@ -3,7 +3,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. @@ -91,7 +91,7 @@ def __init__( self.default_headers[header_name] = header_value self.cookie = cookie # Set default User-Agent. - self.user_agent = 'OpenAPI-Generator/26.10.1/python' + self.user_agent = 'OpenAPI-Generator/26.10.2/python' self.client_side_validation = configuration.client_side_validation async def __aenter__(self): diff --git a/sdks/python/flyquery_sdk/configuration.py b/sdks/python/flyquery_sdk/configuration.py index a513dc53..4f6cb818 100644 --- a/sdks/python/flyquery_sdk/configuration.py +++ b/sdks/python/flyquery_sdk/configuration.py @@ -3,7 +3,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. @@ -572,8 +572,8 @@ def to_debug_report(self) -> str: return "Python SDK Debug Report:\n"\ "OS: {env}\n"\ "Python Version: {pyversion}\n"\ - "Version of the API: 26.10.1\n"\ - "SDK Package Version: 26.10.1".\ + "Version of the API: 26.10.2\n"\ + "SDK Package Version: 26.10.2".\ format(env=sys.platform, pyversion=sys.version) def get_host_settings(self) -> List[HostSetting]: diff --git a/sdks/python/flyquery_sdk/exceptions.py b/sdks/python/flyquery_sdk/exceptions.py index cfd57d6a..fe4ab4d8 100644 --- a/sdks/python/flyquery_sdk/exceptions.py +++ b/sdks/python/flyquery_sdk/exceptions.py @@ -3,7 +3,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/models/__init__.py b/sdks/python/flyquery_sdk/models/__init__.py index eb39f588..963b9be4 100644 --- a/sdks/python/flyquery_sdk/models/__init__.py +++ b/sdks/python/flyquery_sdk/models/__init__.py @@ -6,7 +6,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/models/agent_token_created.py b/sdks/python/flyquery_sdk/models/agent_token_created.py index 4c5a24b3..ddc5f9a1 100644 --- a/sdks/python/flyquery_sdk/models/agent_token_created.py +++ b/sdks/python/flyquery_sdk/models/agent_token_created.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/models/agent_token_mint_request.py b/sdks/python/flyquery_sdk/models/agent_token_mint_request.py index 3d73c6b6..82c1e1c2 100644 --- a/sdks/python/flyquery_sdk/models/agent_token_mint_request.py +++ b/sdks/python/flyquery_sdk/models/agent_token_mint_request.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/models/agent_token_summary_dto.py b/sdks/python/flyquery_sdk/models/agent_token_summary_dto.py index 27403ece..18c068c5 100644 --- a/sdks/python/flyquery_sdk/models/agent_token_summary_dto.py +++ b/sdks/python/flyquery_sdk/models/agent_token_summary_dto.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/models/agent_usage.py b/sdks/python/flyquery_sdk/models/agent_usage.py index bbcd5080..434005f6 100644 --- a/sdks/python/flyquery_sdk/models/agent_usage.py +++ b/sdks/python/flyquery_sdk/models/agent_usage.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/models/answer_response.py b/sdks/python/flyquery_sdk/models/answer_response.py index df696446..402be1aa 100644 --- a/sdks/python/flyquery_sdk/models/answer_response.py +++ b/sdks/python/flyquery_sdk/models/answer_response.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/models/audit_event_read.py b/sdks/python/flyquery_sdk/models/audit_event_read.py index c9ca5076..27f7b60d 100644 --- a/sdks/python/flyquery_sdk/models/audit_event_read.py +++ b/sdks/python/flyquery_sdk/models/audit_event_read.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/models/batch_query_item.py b/sdks/python/flyquery_sdk/models/batch_query_item.py index 3e6240c8..78707108 100644 --- a/sdks/python/flyquery_sdk/models/batch_query_item.py +++ b/sdks/python/flyquery_sdk/models/batch_query_item.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/models/batch_query_request.py b/sdks/python/flyquery_sdk/models/batch_query_request.py index 70e8cd43..0504acaa 100644 --- a/sdks/python/flyquery_sdk/models/batch_query_request.py +++ b/sdks/python/flyquery_sdk/models/batch_query_request.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/models/batch_query_response.py b/sdks/python/flyquery_sdk/models/batch_query_response.py index ff21d526..e72c61a1 100644 --- a/sdks/python/flyquery_sdk/models/batch_query_response.py +++ b/sdks/python/flyquery_sdk/models/batch_query_response.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/models/batch_query_result_item.py b/sdks/python/flyquery_sdk/models/batch_query_result_item.py index d5aaf37f..b47b20f9 100644 --- a/sdks/python/flyquery_sdk/models/batch_query_result_item.py +++ b/sdks/python/flyquery_sdk/models/batch_query_result_item.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/models/billing_breakdown_item.py b/sdks/python/flyquery_sdk/models/billing_breakdown_item.py index 26d44c2a..e2674553 100644 --- a/sdks/python/flyquery_sdk/models/billing_breakdown_item.py +++ b/sdks/python/flyquery_sdk/models/billing_breakdown_item.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/models/billing_rollup.py b/sdks/python/flyquery_sdk/models/billing_rollup.py index b5b2d8ea..50a91a19 100644 --- a/sdks/python/flyquery_sdk/models/billing_rollup.py +++ b/sdks/python/flyquery_sdk/models/billing_rollup.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/models/bulk_file_result.py b/sdks/python/flyquery_sdk/models/bulk_file_result.py index 74a81136..b3aeddf5 100644 --- a/sdks/python/flyquery_sdk/models/bulk_file_result.py +++ b/sdks/python/flyquery_sdk/models/bulk_file_result.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/models/bulk_file_upload_response.py b/sdks/python/flyquery_sdk/models/bulk_file_upload_response.py index a11a287e..051895bd 100644 --- a/sdks/python/flyquery_sdk/models/bulk_file_upload_response.py +++ b/sdks/python/flyquery_sdk/models/bulk_file_upload_response.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/models/callback_config.py b/sdks/python/flyquery_sdk/models/callback_config.py index adc9d5bb..6b98f579 100644 --- a/sdks/python/flyquery_sdk/models/callback_config.py +++ b/sdks/python/flyquery_sdk/models/callback_config.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/models/callback_delivery_list_response.py b/sdks/python/flyquery_sdk/models/callback_delivery_list_response.py index c81e4262..9698f031 100644 --- a/sdks/python/flyquery_sdk/models/callback_delivery_list_response.py +++ b/sdks/python/flyquery_sdk/models/callback_delivery_list_response.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/models/callback_delivery_read.py b/sdks/python/flyquery_sdk/models/callback_delivery_read.py index be96b13a..a815b082 100644 --- a/sdks/python/flyquery_sdk/models/callback_delivery_read.py +++ b/sdks/python/flyquery_sdk/models/callback_delivery_read.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/models/cancel_response.py b/sdks/python/flyquery_sdk/models/cancel_response.py index 6fdb5110..e5f14718 100644 --- a/sdks/python/flyquery_sdk/models/cancel_response.py +++ b/sdks/python/flyquery_sdk/models/cancel_response.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/models/clarification_frame.py b/sdks/python/flyquery_sdk/models/clarification_frame.py index 6ec8464a..14b951e3 100644 --- a/sdks/python/flyquery_sdk/models/clarification_frame.py +++ b/sdks/python/flyquery_sdk/models/clarification_frame.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/models/confidence.py b/sdks/python/flyquery_sdk/models/confidence.py index f940c710..c455a79d 100644 --- a/sdks/python/flyquery_sdk/models/confidence.py +++ b/sdks/python/flyquery_sdk/models/confidence.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/models/conversation_create.py b/sdks/python/flyquery_sdk/models/conversation_create.py index 9a5e9277..a393650a 100644 --- a/sdks/python/flyquery_sdk/models/conversation_create.py +++ b/sdks/python/flyquery_sdk/models/conversation_create.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/models/conversation_read.py b/sdks/python/flyquery_sdk/models/conversation_read.py index fefd6b93..73280e06 100644 --- a/sdks/python/flyquery_sdk/models/conversation_read.py +++ b/sdks/python/flyquery_sdk/models/conversation_read.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/models/conversation_turn_request.py b/sdks/python/flyquery_sdk/models/conversation_turn_request.py index 980debc3..b2749715 100644 --- a/sdks/python/flyquery_sdk/models/conversation_turn_request.py +++ b/sdks/python/flyquery_sdk/models/conversation_turn_request.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/models/cost_cents.py b/sdks/python/flyquery_sdk/models/cost_cents.py index 05828e00..f8f1be2c 100644 --- a/sdks/python/flyquery_sdk/models/cost_cents.py +++ b/sdks/python/flyquery_sdk/models/cost_cents.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/models/cost_cents1.py b/sdks/python/flyquery_sdk/models/cost_cents1.py index 02ef6be6..b40a5a61 100644 --- a/sdks/python/flyquery_sdk/models/cost_cents1.py +++ b/sdks/python/flyquery_sdk/models/cost_cents1.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/models/cost_event_read.py b/sdks/python/flyquery_sdk/models/cost_event_read.py index a78c5ee6..b7984341 100644 --- a/sdks/python/flyquery_sdk/models/cost_event_read.py +++ b/sdks/python/flyquery_sdk/models/cost_event_read.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/models/dataset_create.py b/sdks/python/flyquery_sdk/models/dataset_create.py index cfce5f9a..532b8db6 100644 --- a/sdks/python/flyquery_sdk/models/dataset_create.py +++ b/sdks/python/flyquery_sdk/models/dataset_create.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/models/dataset_read.py b/sdks/python/flyquery_sdk/models/dataset_read.py index d0c4a8bf..c00e5710 100644 --- a/sdks/python/flyquery_sdk/models/dataset_read.py +++ b/sdks/python/flyquery_sdk/models/dataset_read.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/models/dataset_update.py b/sdks/python/flyquery_sdk/models/dataset_update.py index 944b854f..bdfd3e28 100644 --- a/sdks/python/flyquery_sdk/models/dataset_update.py +++ b/sdks/python/flyquery_sdk/models/dataset_update.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/models/derive_table_request.py b/sdks/python/flyquery_sdk/models/derive_table_request.py index c10dfcb0..9039fd0c 100644 --- a/sdks/python/flyquery_sdk/models/derive_table_request.py +++ b/sdks/python/flyquery_sdk/models/derive_table_request.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/models/derive_table_response.py b/sdks/python/flyquery_sdk/models/derive_table_response.py index ae6b821e..25eb2f6f 100644 --- a/sdks/python/flyquery_sdk/models/derive_table_response.py +++ b/sdks/python/flyquery_sdk/models/derive_table_response.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/models/detail_inner.py b/sdks/python/flyquery_sdk/models/detail_inner.py index b4d35f2d..aecee101 100644 --- a/sdks/python/flyquery_sdk/models/detail_inner.py +++ b/sdks/python/flyquery_sdk/models/detail_inner.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/models/example_create.py b/sdks/python/flyquery_sdk/models/example_create.py index ed3cf262..b684fe8c 100644 --- a/sdks/python/flyquery_sdk/models/example_create.py +++ b/sdks/python/flyquery_sdk/models/example_create.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/models/example_read.py b/sdks/python/flyquery_sdk/models/example_read.py index bd68ef93..aa07f508 100644 --- a/sdks/python/flyquery_sdk/models/example_read.py +++ b/sdks/python/flyquery_sdk/models/example_read.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/models/explain_response.py b/sdks/python/flyquery_sdk/models/explain_response.py index 865eed69..33667c1b 100644 --- a/sdks/python/flyquery_sdk/models/explain_response.py +++ b/sdks/python/flyquery_sdk/models/explain_response.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/models/file_upload_response.py b/sdks/python/flyquery_sdk/models/file_upload_response.py index 441b554d..cd3fac95 100644 --- a/sdks/python/flyquery_sdk/models/file_upload_response.py +++ b/sdks/python/flyquery_sdk/models/file_upload_response.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/models/glossary_term_create.py b/sdks/python/flyquery_sdk/models/glossary_term_create.py index 76e679da..a531f2b9 100644 --- a/sdks/python/flyquery_sdk/models/glossary_term_create.py +++ b/sdks/python/flyquery_sdk/models/glossary_term_create.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/models/glossary_term_read.py b/sdks/python/flyquery_sdk/models/glossary_term_read.py index 4fb20a5a..4e6e9ee0 100644 --- a/sdks/python/flyquery_sdk/models/glossary_term_read.py +++ b/sdks/python/flyquery_sdk/models/glossary_term_read.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/models/glossary_term_update.py b/sdks/python/flyquery_sdk/models/glossary_term_update.py index 47b22c03..3c202ffa 100644 --- a/sdks/python/flyquery_sdk/models/glossary_term_update.py +++ b/sdks/python/flyquery_sdk/models/glossary_term_update.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/models/http_validation_error.py b/sdks/python/flyquery_sdk/models/http_validation_error.py index 46d816b0..c86e55ac 100644 --- a/sdks/python/flyquery_sdk/models/http_validation_error.py +++ b/sdks/python/flyquery_sdk/models/http_validation_error.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/models/ingest_cost_cents.py b/sdks/python/flyquery_sdk/models/ingest_cost_cents.py index d5813b8f..2f0f4441 100644 --- a/sdks/python/flyquery_sdk/models/ingest_cost_cents.py +++ b/sdks/python/flyquery_sdk/models/ingest_cost_cents.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/models/ingest_event_list_response.py b/sdks/python/flyquery_sdk/models/ingest_event_list_response.py index bc32d757..7d9f7749 100644 --- a/sdks/python/flyquery_sdk/models/ingest_event_list_response.py +++ b/sdks/python/flyquery_sdk/models/ingest_event_list_response.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/models/ingest_event_read.py b/sdks/python/flyquery_sdk/models/ingest_event_read.py index 70ccd388..06f09269 100644 --- a/sdks/python/flyquery_sdk/models/ingest_event_read.py +++ b/sdks/python/flyquery_sdk/models/ingest_event_read.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/models/ingest_job_create.py b/sdks/python/flyquery_sdk/models/ingest_job_create.py index badc64eb..fc588064 100644 --- a/sdks/python/flyquery_sdk/models/ingest_job_create.py +++ b/sdks/python/flyquery_sdk/models/ingest_job_create.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/models/ingest_job_list_response.py b/sdks/python/flyquery_sdk/models/ingest_job_list_response.py index 84b1df99..da34fc43 100644 --- a/sdks/python/flyquery_sdk/models/ingest_job_list_response.py +++ b/sdks/python/flyquery_sdk/models/ingest_job_list_response.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/models/ingest_job_read.py b/sdks/python/flyquery_sdk/models/ingest_job_read.py index 760183bc..8f711c11 100644 --- a/sdks/python/flyquery_sdk/models/ingest_job_read.py +++ b/sdks/python/flyquery_sdk/models/ingest_job_read.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/models/location_inner.py b/sdks/python/flyquery_sdk/models/location_inner.py index 5de15ef8..854d8c2d 100644 --- a/sdks/python/flyquery_sdk/models/location_inner.py +++ b/sdks/python/flyquery_sdk/models/location_inner.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/models/other_cost_cents.py b/sdks/python/flyquery_sdk/models/other_cost_cents.py index c7f22d1c..d168f3ba 100644 --- a/sdks/python/flyquery_sdk/models/other_cost_cents.py +++ b/sdks/python/flyquery_sdk/models/other_cost_cents.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/models/paginated_audit_event_read.py b/sdks/python/flyquery_sdk/models/paginated_audit_event_read.py index e47e262d..5b5307c3 100644 --- a/sdks/python/flyquery_sdk/models/paginated_audit_event_read.py +++ b/sdks/python/flyquery_sdk/models/paginated_audit_event_read.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/models/paginated_conversation_read.py b/sdks/python/flyquery_sdk/models/paginated_conversation_read.py index 9f1cb608..244b3174 100644 --- a/sdks/python/flyquery_sdk/models/paginated_conversation_read.py +++ b/sdks/python/flyquery_sdk/models/paginated_conversation_read.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/models/paginated_cost_event_read.py b/sdks/python/flyquery_sdk/models/paginated_cost_event_read.py index 3519a6b5..e125da9a 100644 --- a/sdks/python/flyquery_sdk/models/paginated_cost_event_read.py +++ b/sdks/python/flyquery_sdk/models/paginated_cost_event_read.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/models/paginated_dataset_read.py b/sdks/python/flyquery_sdk/models/paginated_dataset_read.py index f76d0127..c422edd7 100644 --- a/sdks/python/flyquery_sdk/models/paginated_dataset_read.py +++ b/sdks/python/flyquery_sdk/models/paginated_dataset_read.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/models/paginated_example_read.py b/sdks/python/flyquery_sdk/models/paginated_example_read.py index cc134a16..b53b7b46 100644 --- a/sdks/python/flyquery_sdk/models/paginated_example_read.py +++ b/sdks/python/flyquery_sdk/models/paginated_example_read.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/models/paginated_glossary_term_read.py b/sdks/python/flyquery_sdk/models/paginated_glossary_term_read.py index 880c7ea1..1af75798 100644 --- a/sdks/python/flyquery_sdk/models/paginated_glossary_term_read.py +++ b/sdks/python/flyquery_sdk/models/paginated_glossary_term_read.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/models/paginated_query_history_item.py b/sdks/python/flyquery_sdk/models/paginated_query_history_item.py index a9ec80f3..d484cce5 100644 --- a/sdks/python/flyquery_sdk/models/paginated_query_history_item.py +++ b/sdks/python/flyquery_sdk/models/paginated_query_history_item.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/models/paginated_relation_read.py b/sdks/python/flyquery_sdk/models/paginated_relation_read.py index 18f459ef..f7d0cfdb 100644 --- a/sdks/python/flyquery_sdk/models/paginated_relation_read.py +++ b/sdks/python/flyquery_sdk/models/paginated_relation_read.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/models/paginated_schema_change_read.py b/sdks/python/flyquery_sdk/models/paginated_schema_change_read.py index 8668f60c..e4e27c6b 100644 --- a/sdks/python/flyquery_sdk/models/paginated_schema_change_read.py +++ b/sdks/python/flyquery_sdk/models/paginated_schema_change_read.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/models/paginated_schema_object_read.py b/sdks/python/flyquery_sdk/models/paginated_schema_object_read.py index 5d314371..ccdf6819 100644 --- a/sdks/python/flyquery_sdk/models/paginated_schema_object_read.py +++ b/sdks/python/flyquery_sdk/models/paginated_schema_object_read.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/models/paginated_semantic_dimension_read.py b/sdks/python/flyquery_sdk/models/paginated_semantic_dimension_read.py index afaa26fa..4cd4c312 100644 --- a/sdks/python/flyquery_sdk/models/paginated_semantic_dimension_read.py +++ b/sdks/python/flyquery_sdk/models/paginated_semantic_dimension_read.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/models/paginated_semantic_metric_read.py b/sdks/python/flyquery_sdk/models/paginated_semantic_metric_read.py index c743705e..a11302a3 100644 --- a/sdks/python/flyquery_sdk/models/paginated_semantic_metric_read.py +++ b/sdks/python/flyquery_sdk/models/paginated_semantic_metric_read.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/models/paginated_semantic_version_read.py b/sdks/python/flyquery_sdk/models/paginated_semantic_version_read.py index 4816e1a1..6c8d7f0d 100644 --- a/sdks/python/flyquery_sdk/models/paginated_semantic_version_read.py +++ b/sdks/python/flyquery_sdk/models/paginated_semantic_version_read.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/models/paginated_snapshot_read.py b/sdks/python/flyquery_sdk/models/paginated_snapshot_read.py index d61f4780..f761f518 100644 --- a/sdks/python/flyquery_sdk/models/paginated_snapshot_read.py +++ b/sdks/python/flyquery_sdk/models/paginated_snapshot_read.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/models/paginated_table_read.py b/sdks/python/flyquery_sdk/models/paginated_table_read.py index 0fa8b6d2..c9ccd539 100644 --- a/sdks/python/flyquery_sdk/models/paginated_table_read.py +++ b/sdks/python/flyquery_sdk/models/paginated_table_read.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/models/paginated_workspace_read.py b/sdks/python/flyquery_sdk/models/paginated_workspace_read.py index b10f3da8..197e1a42 100644 --- a/sdks/python/flyquery_sdk/models/paginated_workspace_read.py +++ b/sdks/python/flyquery_sdk/models/paginated_workspace_read.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/models/purge_accepted.py b/sdks/python/flyquery_sdk/models/purge_accepted.py index 656595d3..796bbced 100644 --- a/sdks/python/flyquery_sdk/models/purge_accepted.py +++ b/sdks/python/flyquery_sdk/models/purge_accepted.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/models/query_cost_cents.py b/sdks/python/flyquery_sdk/models/query_cost_cents.py index 4063a9d6..ed2fbab9 100644 --- a/sdks/python/flyquery_sdk/models/query_cost_cents.py +++ b/sdks/python/flyquery_sdk/models/query_cost_cents.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/models/query_detail_read.py b/sdks/python/flyquery_sdk/models/query_detail_read.py index c382cdf9..3564affc 100644 --- a/sdks/python/flyquery_sdk/models/query_detail_read.py +++ b/sdks/python/flyquery_sdk/models/query_detail_read.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/models/query_history_item.py b/sdks/python/flyquery_sdk/models/query_history_item.py index 31f2cf54..c28a6d70 100644 --- a/sdks/python/flyquery_sdk/models/query_history_item.py +++ b/sdks/python/flyquery_sdk/models/query_history_item.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/models/query_request.py b/sdks/python/flyquery_sdk/models/query_request.py index c0c66bf5..e4999381 100644 --- a/sdks/python/flyquery_sdk/models/query_request.py +++ b/sdks/python/flyquery_sdk/models/query_request.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/models/query_result_read.py b/sdks/python/flyquery_sdk/models/query_result_read.py index 05a975a5..612762f4 100644 --- a/sdks/python/flyquery_sdk/models/query_result_read.py +++ b/sdks/python/flyquery_sdk/models/query_result_read.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/models/relation_approval_read.py b/sdks/python/flyquery_sdk/models/relation_approval_read.py index 56c6827c..4118e6dd 100644 --- a/sdks/python/flyquery_sdk/models/relation_approval_read.py +++ b/sdks/python/flyquery_sdk/models/relation_approval_read.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/models/relation_read.py b/sdks/python/flyquery_sdk/models/relation_read.py index 1063c531..d91a83c5 100644 --- a/sdks/python/flyquery_sdk/models/relation_read.py +++ b/sdks/python/flyquery_sdk/models/relation_read.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/models/relation_rejection_read.py b/sdks/python/flyquery_sdk/models/relation_rejection_read.py index dc6a3085..d244a320 100644 --- a/sdks/python/flyquery_sdk/models/relation_rejection_read.py +++ b/sdks/python/flyquery_sdk/models/relation_rejection_read.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/models/reupload_response.py b/sdks/python/flyquery_sdk/models/reupload_response.py index ec2824cf..8a7605e0 100644 --- a/sdks/python/flyquery_sdk/models/reupload_response.py +++ b/sdks/python/flyquery_sdk/models/reupload_response.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/models/schema_change_read.py b/sdks/python/flyquery_sdk/models/schema_change_read.py index e28b4b61..1dda1ea6 100644 --- a/sdks/python/flyquery_sdk/models/schema_change_read.py +++ b/sdks/python/flyquery_sdk/models/schema_change_read.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/models/schema_object_read.py b/sdks/python/flyquery_sdk/models/schema_object_read.py index e582d4b4..223e09e8 100644 --- a/sdks/python/flyquery_sdk/models/schema_object_read.py +++ b/sdks/python/flyquery_sdk/models/schema_object_read.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/models/schema_object_update.py b/sdks/python/flyquery_sdk/models/schema_object_update.py index aed72c40..e0cef5c7 100644 --- a/sdks/python/flyquery_sdk/models/schema_object_update.py +++ b/sdks/python/flyquery_sdk/models/schema_object_update.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/models/semantic_dimension_create.py b/sdks/python/flyquery_sdk/models/semantic_dimension_create.py index 7eb8f42a..0f2d66f2 100644 --- a/sdks/python/flyquery_sdk/models/semantic_dimension_create.py +++ b/sdks/python/flyquery_sdk/models/semantic_dimension_create.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/models/semantic_dimension_read.py b/sdks/python/flyquery_sdk/models/semantic_dimension_read.py index 8d498f1e..400c505c 100644 --- a/sdks/python/flyquery_sdk/models/semantic_dimension_read.py +++ b/sdks/python/flyquery_sdk/models/semantic_dimension_read.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/models/semantic_dimension_update.py b/sdks/python/flyquery_sdk/models/semantic_dimension_update.py index 2d44bf24..b98f4609 100644 --- a/sdks/python/flyquery_sdk/models/semantic_dimension_update.py +++ b/sdks/python/flyquery_sdk/models/semantic_dimension_update.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/models/semantic_metric_create.py b/sdks/python/flyquery_sdk/models/semantic_metric_create.py index ebd5ebe3..b9fa7922 100644 --- a/sdks/python/flyquery_sdk/models/semantic_metric_create.py +++ b/sdks/python/flyquery_sdk/models/semantic_metric_create.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/models/semantic_metric_read.py b/sdks/python/flyquery_sdk/models/semantic_metric_read.py index 2b047161..4edb45f9 100644 --- a/sdks/python/flyquery_sdk/models/semantic_metric_read.py +++ b/sdks/python/flyquery_sdk/models/semantic_metric_read.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/models/semantic_metric_update.py b/sdks/python/flyquery_sdk/models/semantic_metric_update.py index c46331ce..6f1e600b 100644 --- a/sdks/python/flyquery_sdk/models/semantic_metric_update.py +++ b/sdks/python/flyquery_sdk/models/semantic_metric_update.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/models/semantic_version_read.py b/sdks/python/flyquery_sdk/models/semantic_version_read.py index ded651df..8df3c5d0 100644 --- a/sdks/python/flyquery_sdk/models/semantic_version_read.py +++ b/sdks/python/flyquery_sdk/models/semantic_version_read.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/models/snapshot_read.py b/sdks/python/flyquery_sdk/models/snapshot_read.py index 5cf1387b..fbd543d1 100644 --- a/sdks/python/flyquery_sdk/models/snapshot_read.py +++ b/sdks/python/flyquery_sdk/models/snapshot_read.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/models/sql_execute_request.py b/sdks/python/flyquery_sdk/models/sql_execute_request.py index 012dc1a1..ef883f5e 100644 --- a/sdks/python/flyquery_sdk/models/sql_execute_request.py +++ b/sdks/python/flyquery_sdk/models/sql_execute_request.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/models/sql_execute_response.py b/sdks/python/flyquery_sdk/models/sql_execute_response.py index d5fb4139..bc8f9a68 100644 --- a/sdks/python/flyquery_sdk/models/sql_execute_response.py +++ b/sdks/python/flyquery_sdk/models/sql_execute_response.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/models/table_read.py b/sdks/python/flyquery_sdk/models/table_read.py index dcf29d56..4d62bb61 100644 --- a/sdks/python/flyquery_sdk/models/table_read.py +++ b/sdks/python/flyquery_sdk/models/table_read.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/models/table_summary.py b/sdks/python/flyquery_sdk/models/table_summary.py index 0b5ee248..74974109 100644 --- a/sdks/python/flyquery_sdk/models/table_summary.py +++ b/sdks/python/flyquery_sdk/models/table_summary.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/models/total_cost_cents.py b/sdks/python/flyquery_sdk/models/total_cost_cents.py index 8746b934..c8ab9cc0 100644 --- a/sdks/python/flyquery_sdk/models/total_cost_cents.py +++ b/sdks/python/flyquery_sdk/models/total_cost_cents.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/models/turn_read.py b/sdks/python/flyquery_sdk/models/turn_read.py index 9a8f92e0..0a999ead 100644 --- a/sdks/python/flyquery_sdk/models/turn_read.py +++ b/sdks/python/flyquery_sdk/models/turn_read.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/models/usage_summary.py b/sdks/python/flyquery_sdk/models/usage_summary.py index a53ab8ff..438d3bf8 100644 --- a/sdks/python/flyquery_sdk/models/usage_summary.py +++ b/sdks/python/flyquery_sdk/models/usage_summary.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/models/validate_response.py b/sdks/python/flyquery_sdk/models/validate_response.py index 25ec9dff..9bc3ce4a 100644 --- a/sdks/python/flyquery_sdk/models/validate_response.py +++ b/sdks/python/flyquery_sdk/models/validate_response.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/models/validation_error.py b/sdks/python/flyquery_sdk/models/validation_error.py index a0b93f50..429d359c 100644 --- a/sdks/python/flyquery_sdk/models/validation_error.py +++ b/sdks/python/flyquery_sdk/models/validation_error.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/models/workspace_create.py b/sdks/python/flyquery_sdk/models/workspace_create.py index 904d87e8..a6bfd479 100644 --- a/sdks/python/flyquery_sdk/models/workspace_create.py +++ b/sdks/python/flyquery_sdk/models/workspace_create.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/models/workspace_read.py b/sdks/python/flyquery_sdk/models/workspace_read.py index 376bfb84..680d7a40 100644 --- a/sdks/python/flyquery_sdk/models/workspace_read.py +++ b/sdks/python/flyquery_sdk/models/workspace_read.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/models/workspace_stats.py b/sdks/python/flyquery_sdk/models/workspace_stats.py index edacf70b..bf12851c 100644 --- a/sdks/python/flyquery_sdk/models/workspace_stats.py +++ b/sdks/python/flyquery_sdk/models/workspace_stats.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/models/workspace_update.py b/sdks/python/flyquery_sdk/models/workspace_update.py index 91632f78..05f8ee20 100644 --- a/sdks/python/flyquery_sdk/models/workspace_update.py +++ b/sdks/python/flyquery_sdk/models/workspace_update.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/flyquery_sdk/rest.py b/sdks/python/flyquery_sdk/rest.py index b1ad2916..c0b1792a 100644 --- a/sdks/python/flyquery_sdk/rest.py +++ b/sdks/python/flyquery_sdk/rest.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/pyproject.toml b/sdks/python/pyproject.toml index f23af687..25e9645b 100644 --- a/sdks/python/pyproject.toml +++ b/sdks/python/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "flyquery_sdk" -version = "26.10.1" +version = "26.10.2" description = "Async-first Python client for flyquery — Tabular Intelligence: Text-to-SQL service over user-uploaded structured files." authors = [ { name = "Firefly Software Foundation", email = "team@firefly.io" }, diff --git a/sdks/python/setup.py b/sdks/python/setup.py index 05820601..803994af 100644 --- a/sdks/python/setup.py +++ b/sdks/python/setup.py @@ -3,7 +3,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. @@ -19,7 +19,7 @@ # prerequisite: setuptools # http://pypi.python.org/pypi/setuptools NAME = "flyquery-sdk" -VERSION = "26.10.1" +VERSION = "26.10.2" PYTHON_REQUIRES = ">= 3.9" REQUIRES = [ "python-dateutil >= 2.8.2", diff --git a/sdks/python/test/test_agent_glossary_api.py b/sdks/python/test/test_agent_glossary_api.py index 0b1908fa..fc9c0da4 100644 --- a/sdks/python/test/test_agent_glossary_api.py +++ b/sdks/python/test/test_agent_glossary_api.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/test/test_agent_semantic_dimensions_api.py b/sdks/python/test/test_agent_semantic_dimensions_api.py index 61aba6e1..1914581d 100644 --- a/sdks/python/test/test_agent_semantic_dimensions_api.py +++ b/sdks/python/test/test_agent_semantic_dimensions_api.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/sdks/python/test/test_agent_semantic_metrics_api.py b/sdks/python/test/test_agent_semantic_metrics_api.py index db4ca7fd..d2d16cdf 100644 --- a/sdks/python/test/test_agent_semantic_metrics_api.py +++ b/sdks/python/test/test_agent_semantic_metrics_api.py @@ -5,7 +5,7 @@ Operational Structured-Data Intelligence (upload-driven) -- multi-tenant ingestion + Text-to-SQL over user-uploaded structured files (CSV / TSV / XLSX / XLS / ODS / JSON / JSONL / Parquet / Avro / ORC / Arrow / Feather + .gz/.zip/.bz2 variants). Materialises uploads to Parquet on object storage; indexes a long-lived schema knowledge base; answers natural-language questions via a multi-agent pipeline. Part of Firefly Framework. - The version of the OpenAPI document: 26.10.1 + The version of the OpenAPI document: 26.10.2 Generated by OpenAPI Generator (https://openapi-generator.tech) Do not edit the class manually. diff --git a/src/flyquery/__init__.py b/src/flyquery/__init__.py index 2814d501..9b527e34 100644 --- a/src/flyquery/__init__.py +++ b/src/flyquery/__init__.py @@ -16,4 +16,4 @@ from __future__ import annotations -__version__ = "26.10.1" +__version__ = "26.10.2" diff --git a/tests/integration/test_openapi_snapshot.py b/tests/integration/test_openapi_snapshot.py index 202b148c..78f1163a 100644 --- a/tests/integration/test_openapi_snapshot.py +++ b/tests/integration/test_openapi_snapshot.py @@ -27,6 +27,9 @@ def test_openapi_snapshot_matches_running_app(): actual = json.loads(snapshot_path.read_text()) # We accept differences in `info.version` (CalVer-bumped) but the # paths + components must match exactly. + assert actual.get("components") == expected.get("components"), ( + "OpenAPI schema drift! Run `task openapi-snapshot` before building SDKs." + ) expected_keys = set(expected.get("paths", {}).keys()) actual_keys = set(actual.get("paths", {}).keys()) assert expected_keys == actual_keys, ( diff --git a/tests/integration/test_sample_privacy_pipeline.py b/tests/integration/test_sample_privacy_pipeline.py index 94ab0489..ccc73048 100644 --- a/tests/integration/test_sample_privacy_pipeline.py +++ b/tests/integration/test_sample_privacy_pipeline.py @@ -100,6 +100,7 @@ async def test_original_pii_decision_survives_profile_and_retrieval(tmp_path, po created_by="privacy-fixture", ) ) + await session.flush() session.add( SchemaObject( id=column, diff --git a/uv.lock b/uv.lock index a002b41b..6d01923a 100644 --- a/uv.lock +++ b/uv.lock @@ -1117,7 +1117,7 @@ provides-extras = ["all", "azure-embeddings", "bedrock-embeddings", "binary", "c [[package]] name = "flyquery" -version = "26.10.1" +version = "26.10.2" source = { editable = "." } dependencies = [ { name = "aiofiles" }, From b2daad627f76c5304b60e1ba7e2b3b28adc16892 Mon Sep 17 00:00:00 2001 From: Andres Contreras Date: Wed, 14 Oct 2026 12:55:36 -0700 Subject: [PATCH 16/20] Derive application metadata from the release version --- CHANGELOG.md | 5 +++-- src/flyquery/app.py | 5 ++++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e062b176..8405a68d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -34,8 +34,9 @@ Firefly Framework convention (memory: `firefly_uses_calver`). align server, actuator, Python and Java SDK release metadata. A nonempty executed candidate is a selection heuristic, not proof that the SQL -matches the requested entities or filters. Statement timeouts and operating -system sandboxing remain deployment responsibilities. Remote object-store +matches the requested entities or filters. The engine does not enforce its +statement-timeout setting or provide an operating system sandbox. Deployment +resource limits do not implement that missing query deadline. Remote object-store DuckDB reads are not qualified by the local registered-file tests. PII detection covers sampled and retained profile values; it is not a scan of every source row. diff --git a/src/flyquery/app.py b/src/flyquery/app.py index 98232259..26206d85 100644 --- a/src/flyquery/app.py +++ b/src/flyquery/app.py @@ -1,4 +1,5 @@ # Copyright 2024-2026 Firefly Software Foundation +# SPDX-License-Identifier: Apache-2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -31,11 +32,13 @@ from pyfly.core import pyfly_application from pyfly.starters.core import enable_core_stack +from flyquery import __version__ + @enable_core_stack @pyfly_application( name="flyquery", - version="26.6.0", + version=__version__, description=( "flyquery -- Operational Structured-Data Intelligence " "(upload-driven). Multi-tenant ingestion + Text-to-SQL " From a465f06a11ad5ca87e6f17559fad7db76b905fc0 Mon Sep 17 00:00:00 2001 From: Andres Contreras Date: Wed, 14 Oct 2026 13:09:40 -0700 Subject: [PATCH 17/20] Return typed pages from agent table SDK operations --- openapi.json | 35 +++++++ sdks/java/api/openapi.yaml | 20 ++++ sdks/java/docs/AgentTablesApi.md | 45 +++++---- .../firefly/flyquery/api/AgentTablesApi.java | 91 ++++++++++++------- sdks/python/docs/AgentTablesApi.md | 55 +++++++---- .../flyquery_sdk/api/agent_tables_api.py | 89 +++++++++++++----- .../tests/test_agent_table_responses.py | 78 ++++++++++++++++ .../controllers/agent/tables_controller.py | 14 +-- 8 files changed, 325 insertions(+), 102 deletions(-) create mode 100644 sdks/python/tests/test_agent_table_responses.py diff --git a/openapi.json b/openapi.json index e128c29a..5404bf97 100644 --- a/openapi.json +++ b/openapi.json @@ -6782,6 +6782,13 @@ ], "responses": { "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Paginated[TableRead]" + } + } + }, "description": "Successful response" } }, @@ -8645,6 +8652,13 @@ ], "responses": { "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Paginated[TableRead]" + } + } + }, "description": "Successful response" } }, @@ -8770,6 +8784,13 @@ ], "responses": { "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Paginated[SchemaChangeRead]" + } + } + }, "description": "Successful response" } }, @@ -8804,6 +8825,13 @@ ], "responses": { "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Paginated[SchemaObjectRead]" + } + } + }, "description": "Successful response" } }, @@ -8838,6 +8866,13 @@ ], "responses": { "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Paginated[SnapshotRead]" + } + } + }, "description": "Successful response" } }, diff --git a/sdks/java/api/openapi.yaml b/sdks/java/api/openapi.yaml index 49c2e3dd..518e5673 100644 --- a/sdks/java/api/openapi.yaml +++ b/sdks/java/api/openapi.yaml @@ -458,6 +458,10 @@ paths: - $ref: "#/components/parameters/CorrelationIdHeader" responses: "200": + content: + application/json: + schema: + $ref: "#/components/schemas/Paginated[TableRead]" description: Successful response security: - AgentToken: [] @@ -1708,6 +1712,10 @@ paths: - $ref: "#/components/parameters/CorrelationIdHeader" responses: "200": + content: + application/json: + schema: + $ref: "#/components/schemas/Paginated[TableRead]" description: Successful response security: - AgentToken: [] @@ -1790,6 +1798,10 @@ paths: - $ref: "#/components/parameters/CorrelationIdHeader" responses: "200": + content: + application/json: + schema: + $ref: "#/components/schemas/Paginated[SchemaChangeRead]" description: Successful response security: - AgentToken: [] @@ -1812,6 +1824,10 @@ paths: - $ref: "#/components/parameters/CorrelationIdHeader" responses: "200": + content: + application/json: + schema: + $ref: "#/components/schemas/Paginated[SchemaObjectRead]" description: Successful response security: - AgentToken: [] @@ -1834,6 +1850,10 @@ paths: - $ref: "#/components/parameters/CorrelationIdHeader" responses: "200": + content: + application/json: + schema: + $ref: "#/components/schemas/Paginated[SnapshotRead]" description: Successful response security: - AgentToken: [] diff --git a/sdks/java/docs/AgentTablesApi.md b/sdks/java/docs/AgentTablesApi.md index e935bc2a..909af4c5 100644 --- a/sdks/java/docs/AgentTablesApi.md +++ b/sdks/java/docs/AgentTablesApi.md @@ -244,7 +244,7 @@ public class Example { ## listChanges -> listChanges(tableId, xAgentToken, xCorrelationId) +> PaginatedSchemaChangeRead listChanges(tableId, xAgentToken, xCorrelationId) @@ -275,7 +275,8 @@ public class Example { String xAgentToken = "fqt_live_aBcDeF1234567890aBcDeF1234567890"; // String | Machine-to-machine bearer token. Replaces X-Tenant-Id and X-Workspace-Id on agent-tier endpoints -- the token's claims encode the tenant + workspace + scopes. Issue via ``POST /api/v1/agent-tokens``. UUID xCorrelationId = UUID.fromString("550e8400-e29b-41d4-a716-446655440000"); // UUID | Optional client-supplied correlation id. The service uses this in every log line and downstream call. If absent the service mints a new UUID and echoes it in the response header. try { - apiInstance.listChanges(tableId, xAgentToken, xCorrelationId); + PaginatedSchemaChangeRead result = apiInstance.listChanges(tableId, xAgentToken, xCorrelationId); + System.out.println(result); } catch (ApiException e) { System.err.println("Exception when calling AgentTablesApi#listChanges"); System.err.println("Status code: " + e.getCode()); @@ -298,7 +299,7 @@ public class Example { ### Return type -null (empty response body) +[**PaginatedSchemaChangeRead**](PaginatedSchemaChangeRead.md) ### Authorization @@ -307,7 +308,7 @@ null (empty response body) ### HTTP request headers - **Content-Type**: Not defined -- **Accept**: Not defined +- **Accept**: application/json ### HTTP response details @@ -318,7 +319,7 @@ null (empty response body) ## listObjects -> listObjects(tableId, xAgentToken, xCorrelationId) +> PaginatedSchemaObjectRead listObjects(tableId, xAgentToken, xCorrelationId) @@ -349,7 +350,8 @@ public class Example { String xAgentToken = "fqt_live_aBcDeF1234567890aBcDeF1234567890"; // String | Machine-to-machine bearer token. Replaces X-Tenant-Id and X-Workspace-Id on agent-tier endpoints -- the token's claims encode the tenant + workspace + scopes. Issue via ``POST /api/v1/agent-tokens``. UUID xCorrelationId = UUID.fromString("550e8400-e29b-41d4-a716-446655440000"); // UUID | Optional client-supplied correlation id. The service uses this in every log line and downstream call. If absent the service mints a new UUID and echoes it in the response header. try { - apiInstance.listObjects(tableId, xAgentToken, xCorrelationId); + PaginatedSchemaObjectRead result = apiInstance.listObjects(tableId, xAgentToken, xCorrelationId); + System.out.println(result); } catch (ApiException e) { System.err.println("Exception when calling AgentTablesApi#listObjects"); System.err.println("Status code: " + e.getCode()); @@ -372,7 +374,7 @@ public class Example { ### Return type -null (empty response body) +[**PaginatedSchemaObjectRead**](PaginatedSchemaObjectRead.md) ### Authorization @@ -381,7 +383,7 @@ null (empty response body) ### HTTP request headers - **Content-Type**: Not defined -- **Accept**: Not defined +- **Accept**: application/json ### HTTP response details @@ -392,7 +394,7 @@ null (empty response body) ## listSnapshots -> listSnapshots(tableId, xAgentToken, xCorrelationId) +> PaginatedSnapshotRead listSnapshots(tableId, xAgentToken, xCorrelationId) @@ -423,7 +425,8 @@ public class Example { String xAgentToken = "fqt_live_aBcDeF1234567890aBcDeF1234567890"; // String | Machine-to-machine bearer token. Replaces X-Tenant-Id and X-Workspace-Id on agent-tier endpoints -- the token's claims encode the tenant + workspace + scopes. Issue via ``POST /api/v1/agent-tokens``. UUID xCorrelationId = UUID.fromString("550e8400-e29b-41d4-a716-446655440000"); // UUID | Optional client-supplied correlation id. The service uses this in every log line and downstream call. If absent the service mints a new UUID and echoes it in the response header. try { - apiInstance.listSnapshots(tableId, xAgentToken, xCorrelationId); + PaginatedSnapshotRead result = apiInstance.listSnapshots(tableId, xAgentToken, xCorrelationId); + System.out.println(result); } catch (ApiException e) { System.err.println("Exception when calling AgentTablesApi#listSnapshots"); System.err.println("Status code: " + e.getCode()); @@ -446,7 +449,7 @@ public class Example { ### Return type -null (empty response body) +[**PaginatedSnapshotRead**](PaginatedSnapshotRead.md) ### Authorization @@ -455,7 +458,7 @@ null (empty response body) ### HTTP request headers - **Content-Type**: Not defined -- **Accept**: Not defined +- **Accept**: application/json ### HTTP response details @@ -466,7 +469,7 @@ null (empty response body) ## listTables -> listTables(datasetId, xAgentToken, xCorrelationId) +> PaginatedTableRead listTables(datasetId, xAgentToken, xCorrelationId) @@ -497,7 +500,8 @@ public class Example { String xAgentToken = "fqt_live_aBcDeF1234567890aBcDeF1234567890"; // String | Machine-to-machine bearer token. Replaces X-Tenant-Id and X-Workspace-Id on agent-tier endpoints -- the token's claims encode the tenant + workspace + scopes. Issue via ``POST /api/v1/agent-tokens``. UUID xCorrelationId = UUID.fromString("550e8400-e29b-41d4-a716-446655440000"); // UUID | Optional client-supplied correlation id. The service uses this in every log line and downstream call. If absent the service mints a new UUID and echoes it in the response header. try { - apiInstance.listTables(datasetId, xAgentToken, xCorrelationId); + PaginatedTableRead result = apiInstance.listTables(datasetId, xAgentToken, xCorrelationId); + System.out.println(result); } catch (ApiException e) { System.err.println("Exception when calling AgentTablesApi#listTables"); System.err.println("Status code: " + e.getCode()); @@ -520,7 +524,7 @@ public class Example { ### Return type -null (empty response body) +[**PaginatedTableRead**](PaginatedTableRead.md) ### Authorization @@ -529,7 +533,7 @@ null (empty response body) ### HTTP request headers - **Content-Type**: Not defined -- **Accept**: Not defined +- **Accept**: application/json ### HTTP response details @@ -540,7 +544,7 @@ null (empty response body) ## searchTables -> searchTables(xAgentToken, q, name, datasetId, kind, isActive, limit, offset, xCorrelationId) +> PaginatedTableRead searchTables(xAgentToken, q, name, datasetId, kind, isActive, limit, offset, xCorrelationId) @@ -577,7 +581,8 @@ public class Example { Integer offset = 0; // Integer | UUID xCorrelationId = UUID.fromString("550e8400-e29b-41d4-a716-446655440000"); // UUID | Optional client-supplied correlation id. The service uses this in every log line and downstream call. If absent the service mints a new UUID and echoes it in the response header. try { - apiInstance.searchTables(xAgentToken, q, name, datasetId, kind, isActive, limit, offset, xCorrelationId); + PaginatedTableRead result = apiInstance.searchTables(xAgentToken, q, name, datasetId, kind, isActive, limit, offset, xCorrelationId); + System.out.println(result); } catch (ApiException e) { System.err.println("Exception when calling AgentTablesApi#searchTables"); System.err.println("Status code: " + e.getCode()); @@ -606,7 +611,7 @@ public class Example { ### Return type -null (empty response body) +[**PaginatedTableRead**](PaginatedTableRead.md) ### Authorization @@ -615,7 +620,7 @@ null (empty response body) ### HTTP request headers - **Content-Type**: Not defined -- **Accept**: Not defined +- **Accept**: application/json ### HTTP response details diff --git a/sdks/java/src/main/java/com/firefly/flyquery/api/AgentTablesApi.java b/sdks/java/src/main/java/com/firefly/flyquery/api/AgentTablesApi.java index 85accdab..6efae8fc 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/api/AgentTablesApi.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/api/AgentTablesApi.java @@ -2,6 +2,10 @@ import com.firefly.flyquery.ApiClient; +import com.firefly.flyquery.model.PaginatedSchemaChangeRead; +import com.firefly.flyquery.model.PaginatedSchemaObjectRead; +import com.firefly.flyquery.model.PaginatedSnapshotRead; +import com.firefly.flyquery.model.PaginatedTableRead; import com.firefly.flyquery.model.SchemaObjectRead; import com.firefly.flyquery.model.TableRead; import java.util.UUID; @@ -28,7 +32,7 @@ import reactor.core.publisher.Mono; import reactor.core.publisher.Flux; -@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", date = "2026-06-01T11:28:27.907207+02:00[Europe/Madrid]", comments = "Generator version: 7.22.0") +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", date = "2026-10-14T13:03:40.178870-07:00[America/Los_Angeles]", comments = "Generator version: 7.22.0") public class AgentTablesApi { private ApiClient apiClient; @@ -334,6 +338,7 @@ public ResponseSpec getTableByNameWithResponseSpec(@jakarta.annotation.Nonnull S * @param tableId The tableId parameter * @param xAgentToken Machine-to-machine bearer token. Replaces X-Tenant-Id and X-Workspace-Id on agent-tier endpoints -- the token's claims encode the tenant + workspace + scopes. Issue via ``POST /api/v1/agent-tokens``. * @param xCorrelationId Optional client-supplied correlation id. The service uses this in every log line and downstream call. If absent the service mints a new UUID and echoes it in the response header. + * @return PaginatedSchemaChangeRead * @throws WebClientResponseException if an error occurs while attempting to invoke the API */ private ResponseSpec listChangesRequestCreation(@jakarta.annotation.Nonnull String tableId, @jakarta.annotation.Nonnull String xAgentToken, @jakarta.annotation.Nullable UUID xCorrelationId) throws WebClientResponseException { @@ -360,14 +365,16 @@ private ResponseSpec listChangesRequestCreation(@jakarta.annotation.Nonnull Stri headerParams.add("X-Agent-Token", apiClient.parameterToString(xAgentToken)); if (xCorrelationId != null) headerParams.add("X-Correlation-Id", apiClient.parameterToString(xCorrelationId)); - final String[] localVarAccepts = { }; + final String[] localVarAccepts = { + "application/json" + }; final List localVarAccept = apiClient.selectHeaderAccept(localVarAccepts); final String[] localVarContentTypes = { }; final MediaType localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes); String[] localVarAuthNames = new String[] { "AgentToken" }; - ParameterizedTypeReference localVarReturnType = new ParameterizedTypeReference() {}; + ParameterizedTypeReference localVarReturnType = new ParameterizedTypeReference() {}; return apiClient.invokeAPI("/api/v1/agent/tables/{table_id}/changes", HttpMethod.GET, pathParams, queryParams, postBody, headerParams, cookieParams, formParams, localVarAccept, localVarContentType, localVarAuthNames, localVarReturnType); } @@ -378,10 +385,11 @@ private ResponseSpec listChangesRequestCreation(@jakarta.annotation.Nonnull Stri * @param tableId The tableId parameter * @param xAgentToken Machine-to-machine bearer token. Replaces X-Tenant-Id and X-Workspace-Id on agent-tier endpoints -- the token's claims encode the tenant + workspace + scopes. Issue via ``POST /api/v1/agent-tokens``. * @param xCorrelationId Optional client-supplied correlation id. The service uses this in every log line and downstream call. If absent the service mints a new UUID and echoes it in the response header. + * @return PaginatedSchemaChangeRead * @throws WebClientResponseException if an error occurs while attempting to invoke the API */ - public Mono listChanges(@jakarta.annotation.Nonnull String tableId, @jakarta.annotation.Nonnull String xAgentToken, @jakarta.annotation.Nullable UUID xCorrelationId) throws WebClientResponseException { - ParameterizedTypeReference localVarReturnType = new ParameterizedTypeReference() {}; + public Mono listChanges(@jakarta.annotation.Nonnull String tableId, @jakarta.annotation.Nonnull String xAgentToken, @jakarta.annotation.Nullable UUID xCorrelationId) throws WebClientResponseException { + ParameterizedTypeReference localVarReturnType = new ParameterizedTypeReference() {}; return listChangesRequestCreation(tableId, xAgentToken, xCorrelationId).bodyToMono(localVarReturnType); } @@ -392,10 +400,11 @@ public Mono listChanges(@jakarta.annotation.Nonnull String tableId, @jakar * @param tableId The tableId parameter * @param xAgentToken Machine-to-machine bearer token. Replaces X-Tenant-Id and X-Workspace-Id on agent-tier endpoints -- the token's claims encode the tenant + workspace + scopes. Issue via ``POST /api/v1/agent-tokens``. * @param xCorrelationId Optional client-supplied correlation id. The service uses this in every log line and downstream call. If absent the service mints a new UUID and echoes it in the response header. + * @return ResponseEntity<PaginatedSchemaChangeRead> * @throws WebClientResponseException if an error occurs while attempting to invoke the API */ - public Mono> listChangesWithHttpInfo(@jakarta.annotation.Nonnull String tableId, @jakarta.annotation.Nonnull String xAgentToken, @jakarta.annotation.Nullable UUID xCorrelationId) throws WebClientResponseException { - ParameterizedTypeReference localVarReturnType = new ParameterizedTypeReference() {}; + public Mono> listChangesWithHttpInfo(@jakarta.annotation.Nonnull String tableId, @jakarta.annotation.Nonnull String xAgentToken, @jakarta.annotation.Nullable UUID xCorrelationId) throws WebClientResponseException { + ParameterizedTypeReference localVarReturnType = new ParameterizedTypeReference() {}; return listChangesRequestCreation(tableId, xAgentToken, xCorrelationId).toEntity(localVarReturnType); } @@ -420,6 +429,7 @@ public ResponseSpec listChangesWithResponseSpec(@jakarta.annotation.Nonnull Stri * @param tableId The tableId parameter * @param xAgentToken Machine-to-machine bearer token. Replaces X-Tenant-Id and X-Workspace-Id on agent-tier endpoints -- the token's claims encode the tenant + workspace + scopes. Issue via ``POST /api/v1/agent-tokens``. * @param xCorrelationId Optional client-supplied correlation id. The service uses this in every log line and downstream call. If absent the service mints a new UUID and echoes it in the response header. + * @return PaginatedSchemaObjectRead * @throws WebClientResponseException if an error occurs while attempting to invoke the API */ private ResponseSpec listObjectsRequestCreation(@jakarta.annotation.Nonnull String tableId, @jakarta.annotation.Nonnull String xAgentToken, @jakarta.annotation.Nullable UUID xCorrelationId) throws WebClientResponseException { @@ -446,14 +456,16 @@ private ResponseSpec listObjectsRequestCreation(@jakarta.annotation.Nonnull Stri headerParams.add("X-Agent-Token", apiClient.parameterToString(xAgentToken)); if (xCorrelationId != null) headerParams.add("X-Correlation-Id", apiClient.parameterToString(xCorrelationId)); - final String[] localVarAccepts = { }; + final String[] localVarAccepts = { + "application/json" + }; final List localVarAccept = apiClient.selectHeaderAccept(localVarAccepts); final String[] localVarContentTypes = { }; final MediaType localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes); String[] localVarAuthNames = new String[] { "AgentToken" }; - ParameterizedTypeReference localVarReturnType = new ParameterizedTypeReference() {}; + ParameterizedTypeReference localVarReturnType = new ParameterizedTypeReference() {}; return apiClient.invokeAPI("/api/v1/agent/tables/{table_id}/objects", HttpMethod.GET, pathParams, queryParams, postBody, headerParams, cookieParams, formParams, localVarAccept, localVarContentType, localVarAuthNames, localVarReturnType); } @@ -464,10 +476,11 @@ private ResponseSpec listObjectsRequestCreation(@jakarta.annotation.Nonnull Stri * @param tableId The tableId parameter * @param xAgentToken Machine-to-machine bearer token. Replaces X-Tenant-Id and X-Workspace-Id on agent-tier endpoints -- the token's claims encode the tenant + workspace + scopes. Issue via ``POST /api/v1/agent-tokens``. * @param xCorrelationId Optional client-supplied correlation id. The service uses this in every log line and downstream call. If absent the service mints a new UUID and echoes it in the response header. + * @return PaginatedSchemaObjectRead * @throws WebClientResponseException if an error occurs while attempting to invoke the API */ - public Mono listObjects(@jakarta.annotation.Nonnull String tableId, @jakarta.annotation.Nonnull String xAgentToken, @jakarta.annotation.Nullable UUID xCorrelationId) throws WebClientResponseException { - ParameterizedTypeReference localVarReturnType = new ParameterizedTypeReference() {}; + public Mono listObjects(@jakarta.annotation.Nonnull String tableId, @jakarta.annotation.Nonnull String xAgentToken, @jakarta.annotation.Nullable UUID xCorrelationId) throws WebClientResponseException { + ParameterizedTypeReference localVarReturnType = new ParameterizedTypeReference() {}; return listObjectsRequestCreation(tableId, xAgentToken, xCorrelationId).bodyToMono(localVarReturnType); } @@ -478,10 +491,11 @@ public Mono listObjects(@jakarta.annotation.Nonnull String tableId, @jakar * @param tableId The tableId parameter * @param xAgentToken Machine-to-machine bearer token. Replaces X-Tenant-Id and X-Workspace-Id on agent-tier endpoints -- the token's claims encode the tenant + workspace + scopes. Issue via ``POST /api/v1/agent-tokens``. * @param xCorrelationId Optional client-supplied correlation id. The service uses this in every log line and downstream call. If absent the service mints a new UUID and echoes it in the response header. + * @return ResponseEntity<PaginatedSchemaObjectRead> * @throws WebClientResponseException if an error occurs while attempting to invoke the API */ - public Mono> listObjectsWithHttpInfo(@jakarta.annotation.Nonnull String tableId, @jakarta.annotation.Nonnull String xAgentToken, @jakarta.annotation.Nullable UUID xCorrelationId) throws WebClientResponseException { - ParameterizedTypeReference localVarReturnType = new ParameterizedTypeReference() {}; + public Mono> listObjectsWithHttpInfo(@jakarta.annotation.Nonnull String tableId, @jakarta.annotation.Nonnull String xAgentToken, @jakarta.annotation.Nullable UUID xCorrelationId) throws WebClientResponseException { + ParameterizedTypeReference localVarReturnType = new ParameterizedTypeReference() {}; return listObjectsRequestCreation(tableId, xAgentToken, xCorrelationId).toEntity(localVarReturnType); } @@ -506,6 +520,7 @@ public ResponseSpec listObjectsWithResponseSpec(@jakarta.annotation.Nonnull Stri * @param tableId The tableId parameter * @param xAgentToken Machine-to-machine bearer token. Replaces X-Tenant-Id and X-Workspace-Id on agent-tier endpoints -- the token's claims encode the tenant + workspace + scopes. Issue via ``POST /api/v1/agent-tokens``. * @param xCorrelationId Optional client-supplied correlation id. The service uses this in every log line and downstream call. If absent the service mints a new UUID and echoes it in the response header. + * @return PaginatedSnapshotRead * @throws WebClientResponseException if an error occurs while attempting to invoke the API */ private ResponseSpec listSnapshotsRequestCreation(@jakarta.annotation.Nonnull String tableId, @jakarta.annotation.Nonnull String xAgentToken, @jakarta.annotation.Nullable UUID xCorrelationId) throws WebClientResponseException { @@ -532,14 +547,16 @@ private ResponseSpec listSnapshotsRequestCreation(@jakarta.annotation.Nonnull St headerParams.add("X-Agent-Token", apiClient.parameterToString(xAgentToken)); if (xCorrelationId != null) headerParams.add("X-Correlation-Id", apiClient.parameterToString(xCorrelationId)); - final String[] localVarAccepts = { }; + final String[] localVarAccepts = { + "application/json" + }; final List localVarAccept = apiClient.selectHeaderAccept(localVarAccepts); final String[] localVarContentTypes = { }; final MediaType localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes); String[] localVarAuthNames = new String[] { "AgentToken" }; - ParameterizedTypeReference localVarReturnType = new ParameterizedTypeReference() {}; + ParameterizedTypeReference localVarReturnType = new ParameterizedTypeReference() {}; return apiClient.invokeAPI("/api/v1/agent/tables/{table_id}/snapshots", HttpMethod.GET, pathParams, queryParams, postBody, headerParams, cookieParams, formParams, localVarAccept, localVarContentType, localVarAuthNames, localVarReturnType); } @@ -550,10 +567,11 @@ private ResponseSpec listSnapshotsRequestCreation(@jakarta.annotation.Nonnull St * @param tableId The tableId parameter * @param xAgentToken Machine-to-machine bearer token. Replaces X-Tenant-Id and X-Workspace-Id on agent-tier endpoints -- the token's claims encode the tenant + workspace + scopes. Issue via ``POST /api/v1/agent-tokens``. * @param xCorrelationId Optional client-supplied correlation id. The service uses this in every log line and downstream call. If absent the service mints a new UUID and echoes it in the response header. + * @return PaginatedSnapshotRead * @throws WebClientResponseException if an error occurs while attempting to invoke the API */ - public Mono listSnapshots(@jakarta.annotation.Nonnull String tableId, @jakarta.annotation.Nonnull String xAgentToken, @jakarta.annotation.Nullable UUID xCorrelationId) throws WebClientResponseException { - ParameterizedTypeReference localVarReturnType = new ParameterizedTypeReference() {}; + public Mono listSnapshots(@jakarta.annotation.Nonnull String tableId, @jakarta.annotation.Nonnull String xAgentToken, @jakarta.annotation.Nullable UUID xCorrelationId) throws WebClientResponseException { + ParameterizedTypeReference localVarReturnType = new ParameterizedTypeReference() {}; return listSnapshotsRequestCreation(tableId, xAgentToken, xCorrelationId).bodyToMono(localVarReturnType); } @@ -564,10 +582,11 @@ public Mono listSnapshots(@jakarta.annotation.Nonnull String tableId, @jak * @param tableId The tableId parameter * @param xAgentToken Machine-to-machine bearer token. Replaces X-Tenant-Id and X-Workspace-Id on agent-tier endpoints -- the token's claims encode the tenant + workspace + scopes. Issue via ``POST /api/v1/agent-tokens``. * @param xCorrelationId Optional client-supplied correlation id. The service uses this in every log line and downstream call. If absent the service mints a new UUID and echoes it in the response header. + * @return ResponseEntity<PaginatedSnapshotRead> * @throws WebClientResponseException if an error occurs while attempting to invoke the API */ - public Mono> listSnapshotsWithHttpInfo(@jakarta.annotation.Nonnull String tableId, @jakarta.annotation.Nonnull String xAgentToken, @jakarta.annotation.Nullable UUID xCorrelationId) throws WebClientResponseException { - ParameterizedTypeReference localVarReturnType = new ParameterizedTypeReference() {}; + public Mono> listSnapshotsWithHttpInfo(@jakarta.annotation.Nonnull String tableId, @jakarta.annotation.Nonnull String xAgentToken, @jakarta.annotation.Nullable UUID xCorrelationId) throws WebClientResponseException { + ParameterizedTypeReference localVarReturnType = new ParameterizedTypeReference() {}; return listSnapshotsRequestCreation(tableId, xAgentToken, xCorrelationId).toEntity(localVarReturnType); } @@ -592,6 +611,7 @@ public ResponseSpec listSnapshotsWithResponseSpec(@jakarta.annotation.Nonnull St * @param datasetId The datasetId parameter * @param xAgentToken Machine-to-machine bearer token. Replaces X-Tenant-Id and X-Workspace-Id on agent-tier endpoints -- the token's claims encode the tenant + workspace + scopes. Issue via ``POST /api/v1/agent-tokens``. * @param xCorrelationId Optional client-supplied correlation id. The service uses this in every log line and downstream call. If absent the service mints a new UUID and echoes it in the response header. + * @return PaginatedTableRead * @throws WebClientResponseException if an error occurs while attempting to invoke the API */ private ResponseSpec listTablesRequestCreation(@jakarta.annotation.Nonnull String datasetId, @jakarta.annotation.Nonnull String xAgentToken, @jakarta.annotation.Nullable UUID xCorrelationId) throws WebClientResponseException { @@ -618,14 +638,16 @@ private ResponseSpec listTablesRequestCreation(@jakarta.annotation.Nonnull Strin headerParams.add("X-Agent-Token", apiClient.parameterToString(xAgentToken)); if (xCorrelationId != null) headerParams.add("X-Correlation-Id", apiClient.parameterToString(xCorrelationId)); - final String[] localVarAccepts = { }; + final String[] localVarAccepts = { + "application/json" + }; final List localVarAccept = apiClient.selectHeaderAccept(localVarAccepts); final String[] localVarContentTypes = { }; final MediaType localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes); String[] localVarAuthNames = new String[] { "AgentToken" }; - ParameterizedTypeReference localVarReturnType = new ParameterizedTypeReference() {}; + ParameterizedTypeReference localVarReturnType = new ParameterizedTypeReference() {}; return apiClient.invokeAPI("/api/v1/agent/datasets/{dataset_id}/tables", HttpMethod.GET, pathParams, queryParams, postBody, headerParams, cookieParams, formParams, localVarAccept, localVarContentType, localVarAuthNames, localVarReturnType); } @@ -636,10 +658,11 @@ private ResponseSpec listTablesRequestCreation(@jakarta.annotation.Nonnull Strin * @param datasetId The datasetId parameter * @param xAgentToken Machine-to-machine bearer token. Replaces X-Tenant-Id and X-Workspace-Id on agent-tier endpoints -- the token's claims encode the tenant + workspace + scopes. Issue via ``POST /api/v1/agent-tokens``. * @param xCorrelationId Optional client-supplied correlation id. The service uses this in every log line and downstream call. If absent the service mints a new UUID and echoes it in the response header. + * @return PaginatedTableRead * @throws WebClientResponseException if an error occurs while attempting to invoke the API */ - public Mono listTables(@jakarta.annotation.Nonnull String datasetId, @jakarta.annotation.Nonnull String xAgentToken, @jakarta.annotation.Nullable UUID xCorrelationId) throws WebClientResponseException { - ParameterizedTypeReference localVarReturnType = new ParameterizedTypeReference() {}; + public Mono listTables(@jakarta.annotation.Nonnull String datasetId, @jakarta.annotation.Nonnull String xAgentToken, @jakarta.annotation.Nullable UUID xCorrelationId) throws WebClientResponseException { + ParameterizedTypeReference localVarReturnType = new ParameterizedTypeReference() {}; return listTablesRequestCreation(datasetId, xAgentToken, xCorrelationId).bodyToMono(localVarReturnType); } @@ -650,10 +673,11 @@ public Mono listTables(@jakarta.annotation.Nonnull String datasetId, @jaka * @param datasetId The datasetId parameter * @param xAgentToken Machine-to-machine bearer token. Replaces X-Tenant-Id and X-Workspace-Id on agent-tier endpoints -- the token's claims encode the tenant + workspace + scopes. Issue via ``POST /api/v1/agent-tokens``. * @param xCorrelationId Optional client-supplied correlation id. The service uses this in every log line and downstream call. If absent the service mints a new UUID and echoes it in the response header. + * @return ResponseEntity<PaginatedTableRead> * @throws WebClientResponseException if an error occurs while attempting to invoke the API */ - public Mono> listTablesWithHttpInfo(@jakarta.annotation.Nonnull String datasetId, @jakarta.annotation.Nonnull String xAgentToken, @jakarta.annotation.Nullable UUID xCorrelationId) throws WebClientResponseException { - ParameterizedTypeReference localVarReturnType = new ParameterizedTypeReference() {}; + public Mono> listTablesWithHttpInfo(@jakarta.annotation.Nonnull String datasetId, @jakarta.annotation.Nonnull String xAgentToken, @jakarta.annotation.Nullable UUID xCorrelationId) throws WebClientResponseException { + ParameterizedTypeReference localVarReturnType = new ParameterizedTypeReference() {}; return listTablesRequestCreation(datasetId, xAgentToken, xCorrelationId).toEntity(localVarReturnType); } @@ -684,6 +708,7 @@ public ResponseSpec listTablesWithResponseSpec(@jakarta.annotation.Nonnull Strin * @param limit The limit parameter * @param offset The offset parameter * @param xCorrelationId Optional client-supplied correlation id. The service uses this in every log line and downstream call. If absent the service mints a new UUID and echoes it in the response header. + * @return PaginatedTableRead * @throws WebClientResponseException if an error occurs while attempting to invoke the API */ private ResponseSpec searchTablesRequestCreation(@jakarta.annotation.Nonnull String xAgentToken, @jakarta.annotation.Nullable String q, @jakarta.annotation.Nullable String name, @jakarta.annotation.Nullable String datasetId, @jakarta.annotation.Nullable String kind, @jakarta.annotation.Nullable Boolean isActive, @jakarta.annotation.Nullable Integer limit, @jakarta.annotation.Nullable Integer offset, @jakarta.annotation.Nullable UUID xCorrelationId) throws WebClientResponseException { @@ -712,14 +737,16 @@ private ResponseSpec searchTablesRequestCreation(@jakarta.annotation.Nonnull Str headerParams.add("X-Agent-Token", apiClient.parameterToString(xAgentToken)); if (xCorrelationId != null) headerParams.add("X-Correlation-Id", apiClient.parameterToString(xCorrelationId)); - final String[] localVarAccepts = { }; + final String[] localVarAccepts = { + "application/json" + }; final List localVarAccept = apiClient.selectHeaderAccept(localVarAccepts); final String[] localVarContentTypes = { }; final MediaType localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes); String[] localVarAuthNames = new String[] { "AgentToken" }; - ParameterizedTypeReference localVarReturnType = new ParameterizedTypeReference() {}; + ParameterizedTypeReference localVarReturnType = new ParameterizedTypeReference() {}; return apiClient.invokeAPI("/api/v1/agent/tables", HttpMethod.GET, pathParams, queryParams, postBody, headerParams, cookieParams, formParams, localVarAccept, localVarContentType, localVarAuthNames, localVarReturnType); } @@ -736,10 +763,11 @@ private ResponseSpec searchTablesRequestCreation(@jakarta.annotation.Nonnull Str * @param limit The limit parameter * @param offset The offset parameter * @param xCorrelationId Optional client-supplied correlation id. The service uses this in every log line and downstream call. If absent the service mints a new UUID and echoes it in the response header. + * @return PaginatedTableRead * @throws WebClientResponseException if an error occurs while attempting to invoke the API */ - public Mono searchTables(@jakarta.annotation.Nonnull String xAgentToken, @jakarta.annotation.Nullable String q, @jakarta.annotation.Nullable String name, @jakarta.annotation.Nullable String datasetId, @jakarta.annotation.Nullable String kind, @jakarta.annotation.Nullable Boolean isActive, @jakarta.annotation.Nullable Integer limit, @jakarta.annotation.Nullable Integer offset, @jakarta.annotation.Nullable UUID xCorrelationId) throws WebClientResponseException { - ParameterizedTypeReference localVarReturnType = new ParameterizedTypeReference() {}; + public Mono searchTables(@jakarta.annotation.Nonnull String xAgentToken, @jakarta.annotation.Nullable String q, @jakarta.annotation.Nullable String name, @jakarta.annotation.Nullable String datasetId, @jakarta.annotation.Nullable String kind, @jakarta.annotation.Nullable Boolean isActive, @jakarta.annotation.Nullable Integer limit, @jakarta.annotation.Nullable Integer offset, @jakarta.annotation.Nullable UUID xCorrelationId) throws WebClientResponseException { + ParameterizedTypeReference localVarReturnType = new ParameterizedTypeReference() {}; return searchTablesRequestCreation(xAgentToken, q, name, datasetId, kind, isActive, limit, offset, xCorrelationId).bodyToMono(localVarReturnType); } @@ -756,10 +784,11 @@ public Mono searchTables(@jakarta.annotation.Nonnull String xAgentToken, @ * @param limit The limit parameter * @param offset The offset parameter * @param xCorrelationId Optional client-supplied correlation id. The service uses this in every log line and downstream call. If absent the service mints a new UUID and echoes it in the response header. + * @return ResponseEntity<PaginatedTableRead> * @throws WebClientResponseException if an error occurs while attempting to invoke the API */ - public Mono> searchTablesWithHttpInfo(@jakarta.annotation.Nonnull String xAgentToken, @jakarta.annotation.Nullable String q, @jakarta.annotation.Nullable String name, @jakarta.annotation.Nullable String datasetId, @jakarta.annotation.Nullable String kind, @jakarta.annotation.Nullable Boolean isActive, @jakarta.annotation.Nullable Integer limit, @jakarta.annotation.Nullable Integer offset, @jakarta.annotation.Nullable UUID xCorrelationId) throws WebClientResponseException { - ParameterizedTypeReference localVarReturnType = new ParameterizedTypeReference() {}; + public Mono> searchTablesWithHttpInfo(@jakarta.annotation.Nonnull String xAgentToken, @jakarta.annotation.Nullable String q, @jakarta.annotation.Nullable String name, @jakarta.annotation.Nullable String datasetId, @jakarta.annotation.Nullable String kind, @jakarta.annotation.Nullable Boolean isActive, @jakarta.annotation.Nullable Integer limit, @jakarta.annotation.Nullable Integer offset, @jakarta.annotation.Nullable UUID xCorrelationId) throws WebClientResponseException { + ParameterizedTypeReference localVarReturnType = new ParameterizedTypeReference() {}; return searchTablesRequestCreation(xAgentToken, q, name, datasetId, kind, isActive, limit, offset, xCorrelationId).toEntity(localVarReturnType); } diff --git a/sdks/python/docs/AgentTablesApi.md b/sdks/python/docs/AgentTablesApi.md index 9cc56a2e..27d55294 100644 --- a/sdks/python/docs/AgentTablesApi.md +++ b/sdks/python/docs/AgentTablesApi.md @@ -251,7 +251,7 @@ Name | Type | Description | Notes [[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) # **list_changes** -> list_changes(table_id, x_agent_token, x_correlation_id=x_correlation_id) +> PaginatedSchemaChangeRead list_changes(table_id, x_agent_token, x_correlation_id=x_correlation_id) ### Example @@ -259,6 +259,7 @@ Name | Type | Description | Notes ```python import flyquery_sdk +from flyquery_sdk.models.paginated_schema_change_read import PaginatedSchemaChangeRead from flyquery_sdk.rest import ApiException from pprint import pprint @@ -288,7 +289,9 @@ async with flyquery_sdk.ApiClient(configuration) as api_client: x_correlation_id = UUID('550e8400-e29b-41d4-a716-446655440000') # UUID | Optional client-supplied correlation id. The service uses this in every log line and downstream call. If absent the service mints a new UUID and echoes it in the response header. (optional) try: - await api_instance.list_changes(table_id, x_agent_token, x_correlation_id=x_correlation_id) + api_response = await api_instance.list_changes(table_id, x_agent_token, x_correlation_id=x_correlation_id) + print("The response of AgentTablesApi->list_changes:\n") + pprint(api_response) except Exception as e: print("Exception when calling AgentTablesApi->list_changes: %s\n" % e) ``` @@ -306,7 +309,7 @@ Name | Type | Description | Notes ### Return type -void (empty response body) +[**PaginatedSchemaChangeRead**](PaginatedSchemaChangeRead.md) ### Authorization @@ -315,7 +318,7 @@ void (empty response body) ### HTTP request headers - **Content-Type**: Not defined - - **Accept**: Not defined + - **Accept**: application/json ### HTTP response details @@ -326,7 +329,7 @@ void (empty response body) [[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) # **list_objects** -> list_objects(table_id, x_agent_token, x_correlation_id=x_correlation_id) +> PaginatedSchemaObjectRead list_objects(table_id, x_agent_token, x_correlation_id=x_correlation_id) ### Example @@ -334,6 +337,7 @@ void (empty response body) ```python import flyquery_sdk +from flyquery_sdk.models.paginated_schema_object_read import PaginatedSchemaObjectRead from flyquery_sdk.rest import ApiException from pprint import pprint @@ -363,7 +367,9 @@ async with flyquery_sdk.ApiClient(configuration) as api_client: x_correlation_id = UUID('550e8400-e29b-41d4-a716-446655440000') # UUID | Optional client-supplied correlation id. The service uses this in every log line and downstream call. If absent the service mints a new UUID and echoes it in the response header. (optional) try: - await api_instance.list_objects(table_id, x_agent_token, x_correlation_id=x_correlation_id) + api_response = await api_instance.list_objects(table_id, x_agent_token, x_correlation_id=x_correlation_id) + print("The response of AgentTablesApi->list_objects:\n") + pprint(api_response) except Exception as e: print("Exception when calling AgentTablesApi->list_objects: %s\n" % e) ``` @@ -381,7 +387,7 @@ Name | Type | Description | Notes ### Return type -void (empty response body) +[**PaginatedSchemaObjectRead**](PaginatedSchemaObjectRead.md) ### Authorization @@ -390,7 +396,7 @@ void (empty response body) ### HTTP request headers - **Content-Type**: Not defined - - **Accept**: Not defined + - **Accept**: application/json ### HTTP response details @@ -401,7 +407,7 @@ void (empty response body) [[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) # **list_snapshots** -> list_snapshots(table_id, x_agent_token, x_correlation_id=x_correlation_id) +> PaginatedSnapshotRead list_snapshots(table_id, x_agent_token, x_correlation_id=x_correlation_id) ### Example @@ -409,6 +415,7 @@ void (empty response body) ```python import flyquery_sdk +from flyquery_sdk.models.paginated_snapshot_read import PaginatedSnapshotRead from flyquery_sdk.rest import ApiException from pprint import pprint @@ -438,7 +445,9 @@ async with flyquery_sdk.ApiClient(configuration) as api_client: x_correlation_id = UUID('550e8400-e29b-41d4-a716-446655440000') # UUID | Optional client-supplied correlation id. The service uses this in every log line and downstream call. If absent the service mints a new UUID and echoes it in the response header. (optional) try: - await api_instance.list_snapshots(table_id, x_agent_token, x_correlation_id=x_correlation_id) + api_response = await api_instance.list_snapshots(table_id, x_agent_token, x_correlation_id=x_correlation_id) + print("The response of AgentTablesApi->list_snapshots:\n") + pprint(api_response) except Exception as e: print("Exception when calling AgentTablesApi->list_snapshots: %s\n" % e) ``` @@ -456,7 +465,7 @@ Name | Type | Description | Notes ### Return type -void (empty response body) +[**PaginatedSnapshotRead**](PaginatedSnapshotRead.md) ### Authorization @@ -465,7 +474,7 @@ void (empty response body) ### HTTP request headers - **Content-Type**: Not defined - - **Accept**: Not defined + - **Accept**: application/json ### HTTP response details @@ -476,7 +485,7 @@ void (empty response body) [[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) # **list_tables** -> list_tables(dataset_id, x_agent_token, x_correlation_id=x_correlation_id) +> PaginatedTableRead list_tables(dataset_id, x_agent_token, x_correlation_id=x_correlation_id) ### Example @@ -484,6 +493,7 @@ void (empty response body) ```python import flyquery_sdk +from flyquery_sdk.models.paginated_table_read import PaginatedTableRead from flyquery_sdk.rest import ApiException from pprint import pprint @@ -513,7 +523,9 @@ async with flyquery_sdk.ApiClient(configuration) as api_client: x_correlation_id = UUID('550e8400-e29b-41d4-a716-446655440000') # UUID | Optional client-supplied correlation id. The service uses this in every log line and downstream call. If absent the service mints a new UUID and echoes it in the response header. (optional) try: - await api_instance.list_tables(dataset_id, x_agent_token, x_correlation_id=x_correlation_id) + api_response = await api_instance.list_tables(dataset_id, x_agent_token, x_correlation_id=x_correlation_id) + print("The response of AgentTablesApi->list_tables:\n") + pprint(api_response) except Exception as e: print("Exception when calling AgentTablesApi->list_tables: %s\n" % e) ``` @@ -531,7 +543,7 @@ Name | Type | Description | Notes ### Return type -void (empty response body) +[**PaginatedTableRead**](PaginatedTableRead.md) ### Authorization @@ -540,7 +552,7 @@ void (empty response body) ### HTTP request headers - **Content-Type**: Not defined - - **Accept**: Not defined + - **Accept**: application/json ### HTTP response details @@ -551,7 +563,7 @@ void (empty response body) [[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) # **search_tables** -> search_tables(x_agent_token, q=q, name=name, dataset_id=dataset_id, kind=kind, is_active=is_active, limit=limit, offset=offset, x_correlation_id=x_correlation_id) +> PaginatedTableRead search_tables(x_agent_token, q=q, name=name, dataset_id=dataset_id, kind=kind, is_active=is_active, limit=limit, offset=offset, x_correlation_id=x_correlation_id) ### Example @@ -559,6 +571,7 @@ void (empty response body) ```python import flyquery_sdk +from flyquery_sdk.models.paginated_table_read import PaginatedTableRead from flyquery_sdk.rest import ApiException from pprint import pprint @@ -594,7 +607,9 @@ async with flyquery_sdk.ApiClient(configuration) as api_client: x_correlation_id = UUID('550e8400-e29b-41d4-a716-446655440000') # UUID | Optional client-supplied correlation id. The service uses this in every log line and downstream call. If absent the service mints a new UUID and echoes it in the response header. (optional) try: - await api_instance.search_tables(x_agent_token, q=q, name=name, dataset_id=dataset_id, kind=kind, is_active=is_active, limit=limit, offset=offset, x_correlation_id=x_correlation_id) + api_response = await api_instance.search_tables(x_agent_token, q=q, name=name, dataset_id=dataset_id, kind=kind, is_active=is_active, limit=limit, offset=offset, x_correlation_id=x_correlation_id) + print("The response of AgentTablesApi->search_tables:\n") + pprint(api_response) except Exception as e: print("Exception when calling AgentTablesApi->search_tables: %s\n" % e) ``` @@ -618,7 +633,7 @@ Name | Type | Description | Notes ### Return type -void (empty response body) +[**PaginatedTableRead**](PaginatedTableRead.md) ### Authorization @@ -627,7 +642,7 @@ void (empty response body) ### HTTP request headers - **Content-Type**: Not defined - - **Accept**: Not defined + - **Accept**: application/json ### HTTP response details diff --git a/sdks/python/flyquery_sdk/api/agent_tables_api.py b/sdks/python/flyquery_sdk/api/agent_tables_api.py index 7911f118..333a355d 100644 --- a/sdks/python/flyquery_sdk/api/agent_tables_api.py +++ b/sdks/python/flyquery_sdk/api/agent_tables_api.py @@ -19,6 +19,10 @@ from typing import Optional from typing_extensions import Annotated from uuid import UUID +from flyquery_sdk.models.paginated_schema_change_read import PaginatedSchemaChangeRead +from flyquery_sdk.models.paginated_schema_object_read import PaginatedSchemaObjectRead +from flyquery_sdk.models.paginated_snapshot_read import PaginatedSnapshotRead +from flyquery_sdk.models.paginated_table_read import PaginatedTableRead from flyquery_sdk.models.schema_object_read import SchemaObjectRead from flyquery_sdk.models.table_read import TableRead @@ -939,7 +943,7 @@ async def list_changes( _content_type: Optional[StrictStr] = None, _headers: Optional[Dict[StrictStr, Any]] = None, _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, - ) -> None: + ) -> PaginatedSchemaChangeRead: """list_changes @@ -982,7 +986,7 @@ async def list_changes( ) _response_types_map: Dict[str, Optional[str]] = { - '200': None, + '200': "PaginatedSchemaChangeRead", } response_data = await self.api_client.call_api( *_param, @@ -1013,7 +1017,7 @@ async def list_changes_with_http_info( _content_type: Optional[StrictStr] = None, _headers: Optional[Dict[StrictStr, Any]] = None, _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, - ) -> ApiResponse[None]: + ) -> ApiResponse[PaginatedSchemaChangeRead]: """list_changes @@ -1056,7 +1060,7 @@ async def list_changes_with_http_info( ) _response_types_map: Dict[str, Optional[str]] = { - '200': None, + '200': "PaginatedSchemaChangeRead", } response_data = await self.api_client.call_api( *_param, @@ -1130,7 +1134,7 @@ async def list_changes_without_preload_content( ) _response_types_map: Dict[str, Optional[str]] = { - '200': None, + '200': "PaginatedSchemaChangeRead", } response_data = await self.api_client.call_api( *_param, @@ -1177,6 +1181,13 @@ def _list_changes_serialize( # process the body parameter + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) # authentication setting @@ -1220,7 +1231,7 @@ async def list_objects( _content_type: Optional[StrictStr] = None, _headers: Optional[Dict[StrictStr, Any]] = None, _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, - ) -> None: + ) -> PaginatedSchemaObjectRead: """list_objects @@ -1263,7 +1274,7 @@ async def list_objects( ) _response_types_map: Dict[str, Optional[str]] = { - '200': None, + '200': "PaginatedSchemaObjectRead", } response_data = await self.api_client.call_api( *_param, @@ -1294,7 +1305,7 @@ async def list_objects_with_http_info( _content_type: Optional[StrictStr] = None, _headers: Optional[Dict[StrictStr, Any]] = None, _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, - ) -> ApiResponse[None]: + ) -> ApiResponse[PaginatedSchemaObjectRead]: """list_objects @@ -1337,7 +1348,7 @@ async def list_objects_with_http_info( ) _response_types_map: Dict[str, Optional[str]] = { - '200': None, + '200': "PaginatedSchemaObjectRead", } response_data = await self.api_client.call_api( *_param, @@ -1411,7 +1422,7 @@ async def list_objects_without_preload_content( ) _response_types_map: Dict[str, Optional[str]] = { - '200': None, + '200': "PaginatedSchemaObjectRead", } response_data = await self.api_client.call_api( *_param, @@ -1458,6 +1469,13 @@ def _list_objects_serialize( # process the body parameter + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) # authentication setting @@ -1501,7 +1519,7 @@ async def list_snapshots( _content_type: Optional[StrictStr] = None, _headers: Optional[Dict[StrictStr, Any]] = None, _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, - ) -> None: + ) -> PaginatedSnapshotRead: """list_snapshots @@ -1544,7 +1562,7 @@ async def list_snapshots( ) _response_types_map: Dict[str, Optional[str]] = { - '200': None, + '200': "PaginatedSnapshotRead", } response_data = await self.api_client.call_api( *_param, @@ -1575,7 +1593,7 @@ async def list_snapshots_with_http_info( _content_type: Optional[StrictStr] = None, _headers: Optional[Dict[StrictStr, Any]] = None, _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, - ) -> ApiResponse[None]: + ) -> ApiResponse[PaginatedSnapshotRead]: """list_snapshots @@ -1618,7 +1636,7 @@ async def list_snapshots_with_http_info( ) _response_types_map: Dict[str, Optional[str]] = { - '200': None, + '200': "PaginatedSnapshotRead", } response_data = await self.api_client.call_api( *_param, @@ -1692,7 +1710,7 @@ async def list_snapshots_without_preload_content( ) _response_types_map: Dict[str, Optional[str]] = { - '200': None, + '200': "PaginatedSnapshotRead", } response_data = await self.api_client.call_api( *_param, @@ -1739,6 +1757,13 @@ def _list_snapshots_serialize( # process the body parameter + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) # authentication setting @@ -1782,7 +1807,7 @@ async def list_tables( _content_type: Optional[StrictStr] = None, _headers: Optional[Dict[StrictStr, Any]] = None, _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, - ) -> None: + ) -> PaginatedTableRead: """list_tables @@ -1825,7 +1850,7 @@ async def list_tables( ) _response_types_map: Dict[str, Optional[str]] = { - '200': None, + '200': "PaginatedTableRead", } response_data = await self.api_client.call_api( *_param, @@ -1856,7 +1881,7 @@ async def list_tables_with_http_info( _content_type: Optional[StrictStr] = None, _headers: Optional[Dict[StrictStr, Any]] = None, _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, - ) -> ApiResponse[None]: + ) -> ApiResponse[PaginatedTableRead]: """list_tables @@ -1899,7 +1924,7 @@ async def list_tables_with_http_info( ) _response_types_map: Dict[str, Optional[str]] = { - '200': None, + '200': "PaginatedTableRead", } response_data = await self.api_client.call_api( *_param, @@ -1973,7 +1998,7 @@ async def list_tables_without_preload_content( ) _response_types_map: Dict[str, Optional[str]] = { - '200': None, + '200': "PaginatedTableRead", } response_data = await self.api_client.call_api( *_param, @@ -2020,6 +2045,13 @@ def _list_tables_serialize( # process the body parameter + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) # authentication setting @@ -2069,7 +2101,7 @@ async def search_tables( _content_type: Optional[StrictStr] = None, _headers: Optional[Dict[StrictStr, Any]] = None, _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, - ) -> None: + ) -> PaginatedTableRead: """search_tables @@ -2130,7 +2162,7 @@ async def search_tables( ) _response_types_map: Dict[str, Optional[str]] = { - '200': None, + '200': "PaginatedTableRead", } response_data = await self.api_client.call_api( *_param, @@ -2167,7 +2199,7 @@ async def search_tables_with_http_info( _content_type: Optional[StrictStr] = None, _headers: Optional[Dict[StrictStr, Any]] = None, _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, - ) -> ApiResponse[None]: + ) -> ApiResponse[PaginatedTableRead]: """search_tables @@ -2228,7 +2260,7 @@ async def search_tables_with_http_info( ) _response_types_map: Dict[str, Optional[str]] = { - '200': None, + '200': "PaginatedTableRead", } response_data = await self.api_client.call_api( *_param, @@ -2326,7 +2358,7 @@ async def search_tables_without_preload_content( ) _response_types_map: Dict[str, Optional[str]] = { - '200': None, + '200': "PaginatedTableRead", } response_data = await self.api_client.call_api( *_param, @@ -2405,6 +2437,13 @@ def _search_tables_serialize( # process the body parameter + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) # authentication setting diff --git a/sdks/python/tests/test_agent_table_responses.py b/sdks/python/tests/test_agent_table_responses.py new file mode 100644 index 00000000..b008e63a --- /dev/null +++ b/sdks/python/tests/test_agent_table_responses.py @@ -0,0 +1,78 @@ +# Copyright 2026 Firefly Software Foundation +# SPDX-License-Identifier: Apache-2.0 +"""Agent schema reads deserialize the same page envelopes as user reads.""" + +import json +import threading +from contextlib import contextmanager +from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer +from uuid import uuid4 + +import pytest +from flyquery_sdk import ApiClient, Configuration +from flyquery_sdk.api import AgentTablesApi +from flyquery_sdk.models import ( + PaginatedSchemaChangeRead, + PaginatedSchemaObjectRead, + PaginatedSnapshotRead, + PaginatedTableRead, +) + + +@contextmanager +def page_server(): + requests = [] + + class Handler(BaseHTTPRequestHandler): + def log_message(self, *args): + pass + + def do_GET(self): + requests.append((self.path, dict(self.headers))) + payload = json.dumps({"items": [], "total": 0, "limit": 100, "offset": 0}).encode() + self.send_response(200) + self.send_header("Content-Type", "application/json") + self.send_header("Content-Length", str(len(payload))) + self.end_headers() + self.wfile.write(payload) + + server = ThreadingHTTPServer(("127.0.0.1", 0), Handler) + thread = threading.Thread(target=server.serve_forever, daemon=True) + thread.start() + try: + yield f"http://127.0.0.1:{server.server_port}", requests + finally: + server.shutdown() + server.server_close() + thread.join(timeout=2) + + +@pytest.mark.asyncio +@pytest.mark.parametrize( + "operation,page_type", + [ + ("list_tables", PaginatedTableRead), + ("search_tables", PaginatedTableRead), + ("list_snapshots", PaginatedSnapshotRead), + ("list_objects", PaginatedSchemaObjectRead), + ("list_changes", PaginatedSchemaChangeRead), + ], +) +async def test_agent_table_reads_return_typed_pages(operation, page_type): + token = "agt_" + "synthetic-local-fixture" * 2 + workspace = str(uuid4()) + with page_server() as (origin, requests): + async with ApiClient(Configuration(host=origin)) as client: + client.default_headers.update({"X-Tenant-Id": "sdk-fixture", "X-Workspace-Id": workspace}) + parameters = {"x_agent_token": token, "_request_timeout": 5.0} + if operation == "list_tables": + parameters["dataset_id"] = str(uuid4()) + elif operation != "search_tables": + parameters["table_id"] = str(uuid4()) + result = await getattr(AgentTablesApi(client), operation)(**parameters) + assert isinstance(result, page_type) + assert result.items == [] and result.total == 0 + assert len(requests) == 1 + assert requests[0][1]["X-Agent-Token"] == token + assert requests[0][1]["X-Tenant-Id"] == "sdk-fixture" + assert requests[0][1]["X-Workspace-Id"] == workspace diff --git a/src/flyquery/web/controllers/agent/tables_controller.py b/src/flyquery/web/controllers/agent/tables_controller.py index 622274f1..46b71f82 100644 --- a/src/flyquery/web/controllers/agent/tables_controller.py +++ b/src/flyquery/web/controllers/agent/tables_controller.py @@ -1,4 +1,5 @@ # Copyright 2024-2026 Firefly Software Foundation +# SPDX-License-Identifier: Apache-2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -42,7 +43,8 @@ from starlette.requests import Request from flyquery.core.services.auth.agent_token_service import AgentTokenService -from flyquery.interfaces.files import SchemaObjectRead, TableRead +from flyquery.interfaces.files import SchemaChangeRead, SchemaObjectRead, SnapshotRead, TableRead +from flyquery.interfaces.pagination import Paginated from flyquery.web.controllers.schema_objects_controller import ( SchemaObjectsController as _UserSchemaObjectsController, ) @@ -105,7 +107,7 @@ async def list_tables( self, http_request: Request, dataset_id: PathVar[uuid.UUID], - ) -> dict: + ) -> Paginated[TableRead]: await self._verify(http_request) return await self._tables.list_tables(http_request, dataset_id) @@ -124,7 +126,7 @@ async def search_tables( is_active: QueryParam[bool] = None, limit: QueryParam[int] = 100, offset: QueryParam[int] = 0, - ) -> dict: + ) -> Paginated[TableRead]: await self._verify(http_request) return await self._tables.search_tables( http_request, @@ -161,7 +163,7 @@ async def list_snapshots( self, http_request: Request, table_id: PathVar[uuid.UUID], - ) -> dict: + ) -> Paginated[SnapshotRead]: await self._verify(http_request) return await self._tables.list_snapshots(http_request, table_id) @@ -170,7 +172,7 @@ async def list_objects( self, http_request: Request, table_id: PathVar[uuid.UUID], - ) -> dict: + ) -> Paginated[SchemaObjectRead]: await self._verify(http_request) return await self._tables.list_objects(http_request, table_id) @@ -179,7 +181,7 @@ async def list_changes( self, http_request: Request, table_id: PathVar[uuid.UUID], - ) -> dict: + ) -> Paginated[SchemaChangeRead]: await self._verify(http_request) return await self._tables.list_changes(http_request, table_id) From 7d8d97cca5d2f4ee432cddeb9bdda3394e14f8cd Mon Sep 17 00:00:00 2001 From: Andres Contreras Date: Wed, 14 Oct 2026 13:15:25 -0700 Subject: [PATCH 18/20] Make agent table Java examples compile with WebClient --- sdks/java/docs/AgentTablesApi.md | 226 ++++++++++++------------------- 1 file changed, 85 insertions(+), 141 deletions(-) diff --git a/sdks/java/docs/AgentTablesApi.md b/sdks/java/docs/AgentTablesApi.md index 909af4c5..59e3a0f4 100644 --- a/sdks/java/docs/AgentTablesApi.md +++ b/sdks/java/docs/AgentTablesApi.md @@ -244,45 +244,35 @@ public class Example { ## listChanges -> PaginatedSchemaChangeRead listChanges(tableId, xAgentToken, xCorrelationId) +> Mono listChanges(tableId, xAgentToken, xCorrelationId) ### Example ```java -// Import classes: +import java.time.Duration; import com.firefly.flyquery.ApiClient; -import com.firefly.flyquery.ApiException; -import com.firefly.flyquery.Configuration; -import com.firefly.flyquery.auth.*; -import com.firefly.flyquery.models.*; import com.firefly.flyquery.api.AgentTablesApi; +import com.firefly.flyquery.model.PaginatedSchemaChangeRead; +import org.springframework.web.reactive.function.client.WebClientResponseException; public class Example { public static void main(String[] args) { - ApiClient defaultClient = Configuration.getDefaultApiClient(); - defaultClient.setBasePath("http://localhost"); - - // Configure API key authorization: AgentToken - ApiKeyAuth AgentToken = (ApiKeyAuth) defaultClient.getAuthentication("AgentToken"); - AgentToken.setApiKey("YOUR API KEY"); - // Uncomment the following line to set a prefix for the API key, e.g. "Token" (defaults to null) - //AgentToken.setApiKeyPrefix("Token"); - - AgentTablesApi apiInstance = new AgentTablesApi(defaultClient); - String tableId = "tableId_example"; // String | - String xAgentToken = "fqt_live_aBcDeF1234567890aBcDeF1234567890"; // String | Machine-to-machine bearer token. Replaces X-Tenant-Id and X-Workspace-Id on agent-tier endpoints -- the token's claims encode the tenant + workspace + scopes. Issue via ``POST /api/v1/agent-tokens``. - UUID xCorrelationId = UUID.fromString("550e8400-e29b-41d4-a716-446655440000"); // UUID | Optional client-supplied correlation id. The service uses this in every log line and downstream call. If absent the service mints a new UUID and echoes it in the response header. + ApiClient client = new ApiClient(); + client.setBasePath(System.getenv("FLYQUERY_URL")); + client.addDefaultHeader("X-Tenant-Id", System.getenv("FLYQUERY_TENANT_ID")); + client.addDefaultHeader("X-Workspace-Id", System.getenv("FLYQUERY_WORKSPACE_ID")); + AgentTablesApi api = new AgentTablesApi(client); + String token = System.getenv("FLYQUERY_AGENT_TOKEN"); + String tableId = System.getenv("FLYQUERY_TABLE_ID"); try { - PaginatedSchemaChangeRead result = apiInstance.listChanges(tableId, xAgentToken, xCorrelationId); - System.out.println(result); - } catch (ApiException e) { - System.err.println("Exception when calling AgentTablesApi#listChanges"); - System.err.println("Status code: " + e.getCode()); - System.err.println("Reason: " + e.getResponseBody()); - System.err.println("Response headers: " + e.getResponseHeaders()); - e.printStackTrace(); + PaginatedSchemaChangeRead page = api.listChanges(tableId, token, null).block(Duration.ofSeconds(15)); + if (page == null) throw new IllegalStateException("The API returned no page"); + System.out.println(page.getItems()); + } catch (WebClientResponseException e) { + System.err.println("HTTP " + e.getStatusCode()); + throw e; } } } @@ -319,45 +309,35 @@ public class Example { ## listObjects -> PaginatedSchemaObjectRead listObjects(tableId, xAgentToken, xCorrelationId) +> Mono listObjects(tableId, xAgentToken, xCorrelationId) ### Example ```java -// Import classes: +import java.time.Duration; import com.firefly.flyquery.ApiClient; -import com.firefly.flyquery.ApiException; -import com.firefly.flyquery.Configuration; -import com.firefly.flyquery.auth.*; -import com.firefly.flyquery.models.*; import com.firefly.flyquery.api.AgentTablesApi; +import com.firefly.flyquery.model.PaginatedSchemaObjectRead; +import org.springframework.web.reactive.function.client.WebClientResponseException; public class Example { public static void main(String[] args) { - ApiClient defaultClient = Configuration.getDefaultApiClient(); - defaultClient.setBasePath("http://localhost"); - - // Configure API key authorization: AgentToken - ApiKeyAuth AgentToken = (ApiKeyAuth) defaultClient.getAuthentication("AgentToken"); - AgentToken.setApiKey("YOUR API KEY"); - // Uncomment the following line to set a prefix for the API key, e.g. "Token" (defaults to null) - //AgentToken.setApiKeyPrefix("Token"); - - AgentTablesApi apiInstance = new AgentTablesApi(defaultClient); - String tableId = "tableId_example"; // String | - String xAgentToken = "fqt_live_aBcDeF1234567890aBcDeF1234567890"; // String | Machine-to-machine bearer token. Replaces X-Tenant-Id and X-Workspace-Id on agent-tier endpoints -- the token's claims encode the tenant + workspace + scopes. Issue via ``POST /api/v1/agent-tokens``. - UUID xCorrelationId = UUID.fromString("550e8400-e29b-41d4-a716-446655440000"); // UUID | Optional client-supplied correlation id. The service uses this in every log line and downstream call. If absent the service mints a new UUID and echoes it in the response header. + ApiClient client = new ApiClient(); + client.setBasePath(System.getenv("FLYQUERY_URL")); + client.addDefaultHeader("X-Tenant-Id", System.getenv("FLYQUERY_TENANT_ID")); + client.addDefaultHeader("X-Workspace-Id", System.getenv("FLYQUERY_WORKSPACE_ID")); + AgentTablesApi api = new AgentTablesApi(client); + String token = System.getenv("FLYQUERY_AGENT_TOKEN"); + String tableId = System.getenv("FLYQUERY_TABLE_ID"); try { - PaginatedSchemaObjectRead result = apiInstance.listObjects(tableId, xAgentToken, xCorrelationId); - System.out.println(result); - } catch (ApiException e) { - System.err.println("Exception when calling AgentTablesApi#listObjects"); - System.err.println("Status code: " + e.getCode()); - System.err.println("Reason: " + e.getResponseBody()); - System.err.println("Response headers: " + e.getResponseHeaders()); - e.printStackTrace(); + PaginatedSchemaObjectRead page = api.listObjects(tableId, token, null).block(Duration.ofSeconds(15)); + if (page == null) throw new IllegalStateException("The API returned no page"); + System.out.println(page.getItems()); + } catch (WebClientResponseException e) { + System.err.println("HTTP " + e.getStatusCode()); + throw e; } } } @@ -394,45 +374,35 @@ public class Example { ## listSnapshots -> PaginatedSnapshotRead listSnapshots(tableId, xAgentToken, xCorrelationId) +> Mono listSnapshots(tableId, xAgentToken, xCorrelationId) ### Example ```java -// Import classes: +import java.time.Duration; import com.firefly.flyquery.ApiClient; -import com.firefly.flyquery.ApiException; -import com.firefly.flyquery.Configuration; -import com.firefly.flyquery.auth.*; -import com.firefly.flyquery.models.*; import com.firefly.flyquery.api.AgentTablesApi; +import com.firefly.flyquery.model.PaginatedSnapshotRead; +import org.springframework.web.reactive.function.client.WebClientResponseException; public class Example { public static void main(String[] args) { - ApiClient defaultClient = Configuration.getDefaultApiClient(); - defaultClient.setBasePath("http://localhost"); - - // Configure API key authorization: AgentToken - ApiKeyAuth AgentToken = (ApiKeyAuth) defaultClient.getAuthentication("AgentToken"); - AgentToken.setApiKey("YOUR API KEY"); - // Uncomment the following line to set a prefix for the API key, e.g. "Token" (defaults to null) - //AgentToken.setApiKeyPrefix("Token"); - - AgentTablesApi apiInstance = new AgentTablesApi(defaultClient); - String tableId = "tableId_example"; // String | - String xAgentToken = "fqt_live_aBcDeF1234567890aBcDeF1234567890"; // String | Machine-to-machine bearer token. Replaces X-Tenant-Id and X-Workspace-Id on agent-tier endpoints -- the token's claims encode the tenant + workspace + scopes. Issue via ``POST /api/v1/agent-tokens``. - UUID xCorrelationId = UUID.fromString("550e8400-e29b-41d4-a716-446655440000"); // UUID | Optional client-supplied correlation id. The service uses this in every log line and downstream call. If absent the service mints a new UUID and echoes it in the response header. + ApiClient client = new ApiClient(); + client.setBasePath(System.getenv("FLYQUERY_URL")); + client.addDefaultHeader("X-Tenant-Id", System.getenv("FLYQUERY_TENANT_ID")); + client.addDefaultHeader("X-Workspace-Id", System.getenv("FLYQUERY_WORKSPACE_ID")); + AgentTablesApi api = new AgentTablesApi(client); + String token = System.getenv("FLYQUERY_AGENT_TOKEN"); + String tableId = System.getenv("FLYQUERY_TABLE_ID"); try { - PaginatedSnapshotRead result = apiInstance.listSnapshots(tableId, xAgentToken, xCorrelationId); - System.out.println(result); - } catch (ApiException e) { - System.err.println("Exception when calling AgentTablesApi#listSnapshots"); - System.err.println("Status code: " + e.getCode()); - System.err.println("Reason: " + e.getResponseBody()); - System.err.println("Response headers: " + e.getResponseHeaders()); - e.printStackTrace(); + PaginatedSnapshotRead page = api.listSnapshots(tableId, token, null).block(Duration.ofSeconds(15)); + if (page == null) throw new IllegalStateException("The API returned no page"); + System.out.println(page.getItems()); + } catch (WebClientResponseException e) { + System.err.println("HTTP " + e.getStatusCode()); + throw e; } } } @@ -469,45 +439,35 @@ public class Example { ## listTables -> PaginatedTableRead listTables(datasetId, xAgentToken, xCorrelationId) +> Mono listTables(datasetId, xAgentToken, xCorrelationId) ### Example ```java -// Import classes: +import java.time.Duration; import com.firefly.flyquery.ApiClient; -import com.firefly.flyquery.ApiException; -import com.firefly.flyquery.Configuration; -import com.firefly.flyquery.auth.*; -import com.firefly.flyquery.models.*; import com.firefly.flyquery.api.AgentTablesApi; +import com.firefly.flyquery.model.PaginatedTableRead; +import org.springframework.web.reactive.function.client.WebClientResponseException; public class Example { public static void main(String[] args) { - ApiClient defaultClient = Configuration.getDefaultApiClient(); - defaultClient.setBasePath("http://localhost"); - - // Configure API key authorization: AgentToken - ApiKeyAuth AgentToken = (ApiKeyAuth) defaultClient.getAuthentication("AgentToken"); - AgentToken.setApiKey("YOUR API KEY"); - // Uncomment the following line to set a prefix for the API key, e.g. "Token" (defaults to null) - //AgentToken.setApiKeyPrefix("Token"); - - AgentTablesApi apiInstance = new AgentTablesApi(defaultClient); - String datasetId = "datasetId_example"; // String | - String xAgentToken = "fqt_live_aBcDeF1234567890aBcDeF1234567890"; // String | Machine-to-machine bearer token. Replaces X-Tenant-Id and X-Workspace-Id on agent-tier endpoints -- the token's claims encode the tenant + workspace + scopes. Issue via ``POST /api/v1/agent-tokens``. - UUID xCorrelationId = UUID.fromString("550e8400-e29b-41d4-a716-446655440000"); // UUID | Optional client-supplied correlation id. The service uses this in every log line and downstream call. If absent the service mints a new UUID and echoes it in the response header. + ApiClient client = new ApiClient(); + client.setBasePath(System.getenv("FLYQUERY_URL")); + client.addDefaultHeader("X-Tenant-Id", System.getenv("FLYQUERY_TENANT_ID")); + client.addDefaultHeader("X-Workspace-Id", System.getenv("FLYQUERY_WORKSPACE_ID")); + AgentTablesApi api = new AgentTablesApi(client); + String token = System.getenv("FLYQUERY_AGENT_TOKEN"); + String datasetId = System.getenv("FLYQUERY_DATASET_ID"); try { - PaginatedTableRead result = apiInstance.listTables(datasetId, xAgentToken, xCorrelationId); - System.out.println(result); - } catch (ApiException e) { - System.err.println("Exception when calling AgentTablesApi#listTables"); - System.err.println("Status code: " + e.getCode()); - System.err.println("Reason: " + e.getResponseBody()); - System.err.println("Response headers: " + e.getResponseHeaders()); - e.printStackTrace(); + PaginatedTableRead page = api.listTables(datasetId, token, null).block(Duration.ofSeconds(15)); + if (page == null) throw new IllegalStateException("The API returned no page"); + System.out.println(page.getItems()); + } catch (WebClientResponseException e) { + System.err.println("HTTP " + e.getStatusCode()); + throw e; } } } @@ -544,51 +504,35 @@ public class Example { ## searchTables -> PaginatedTableRead searchTables(xAgentToken, q, name, datasetId, kind, isActive, limit, offset, xCorrelationId) +> Mono searchTables(xAgentToken, q, name, datasetId, kind, isActive, limit, offset, xCorrelationId) ### Example ```java -// Import classes: +import java.time.Duration; import com.firefly.flyquery.ApiClient; -import com.firefly.flyquery.ApiException; -import com.firefly.flyquery.Configuration; -import com.firefly.flyquery.auth.*; -import com.firefly.flyquery.models.*; import com.firefly.flyquery.api.AgentTablesApi; +import com.firefly.flyquery.model.PaginatedTableRead; +import org.springframework.web.reactive.function.client.WebClientResponseException; public class Example { public static void main(String[] args) { - ApiClient defaultClient = Configuration.getDefaultApiClient(); - defaultClient.setBasePath("http://localhost"); - - // Configure API key authorization: AgentToken - ApiKeyAuth AgentToken = (ApiKeyAuth) defaultClient.getAuthentication("AgentToken"); - AgentToken.setApiKey("YOUR API KEY"); - // Uncomment the following line to set a prefix for the API key, e.g. "Token" (defaults to null) - //AgentToken.setApiKeyPrefix("Token"); - - AgentTablesApi apiInstance = new AgentTablesApi(defaultClient); - String xAgentToken = "fqt_live_aBcDeF1234567890aBcDeF1234567890"; // String | Machine-to-machine bearer token. Replaces X-Tenant-Id and X-Workspace-Id on agent-tier endpoints -- the token's claims encode the tenant + workspace + scopes. Issue via ``POST /api/v1/agent-tokens``. - String q = "q_example"; // String | - String name = "name_example"; // String | - String datasetId = "datasetId_example"; // String | - String kind = "kind_example"; // String | - Boolean isActive = null; // Boolean | - Integer limit = 100; // Integer | - Integer offset = 0; // Integer | - UUID xCorrelationId = UUID.fromString("550e8400-e29b-41d4-a716-446655440000"); // UUID | Optional client-supplied correlation id. The service uses this in every log line and downstream call. If absent the service mints a new UUID and echoes it in the response header. + ApiClient client = new ApiClient(); + client.setBasePath(System.getenv("FLYQUERY_URL")); + client.addDefaultHeader("X-Tenant-Id", System.getenv("FLYQUERY_TENANT_ID")); + client.addDefaultHeader("X-Workspace-Id", System.getenv("FLYQUERY_WORKSPACE_ID")); + AgentTablesApi api = new AgentTablesApi(client); + String token = System.getenv("FLYQUERY_AGENT_TOKEN"); + String datasetId = System.getenv("FLYQUERY_DATASET_ID"); try { - PaginatedTableRead result = apiInstance.searchTables(xAgentToken, q, name, datasetId, kind, isActive, limit, offset, xCorrelationId); - System.out.println(result); - } catch (ApiException e) { - System.err.println("Exception when calling AgentTablesApi#searchTables"); - System.err.println("Status code: " + e.getCode()); - System.err.println("Reason: " + e.getResponseBody()); - System.err.println("Response headers: " + e.getResponseHeaders()); - e.printStackTrace(); + PaginatedTableRead page = api.searchTables(token, null, null, datasetId, null, true, 100, 0, null).block(Duration.ofSeconds(15)); + if (page == null) throw new IllegalStateException("The API returned no page"); + System.out.println(page.getItems()); + } catch (WebClientResponseException e) { + System.err.println("HTTP " + e.getStatusCode()); + throw e; } } } From 89ad2f65e2fafa04a33b6fd9e5f90645c97a6ea3 Mon Sep 17 00:00:00 2001 From: Andres Contreras Date: Wed, 14 Oct 2026 13:18:51 -0700 Subject: [PATCH 19/20] Make agent table Python examples executable with scoped clients --- sdks/python/docs/AgentTablesApi.md | 331 +++++++++++++---------------- 1 file changed, 145 insertions(+), 186 deletions(-) diff --git a/sdks/python/docs/AgentTablesApi.md b/sdks/python/docs/AgentTablesApi.md index 27d55294..e573b946 100644 --- a/sdks/python/docs/AgentTablesApi.md +++ b/sdks/python/docs/AgentTablesApi.md @@ -258,42 +258,35 @@ Name | Type | Description | Notes * Api Key Authentication (AgentToken): ```python -import flyquery_sdk -from flyquery_sdk.models.paginated_schema_change_read import PaginatedSchemaChangeRead -from flyquery_sdk.rest import ApiException -from pprint import pprint - -# Defining the host is optional and defaults to http://localhost -# See configuration.py for a list of all supported configuration parameters. -configuration = flyquery_sdk.Configuration( - host = "http://localhost" -) - -# The client must configure the authentication and authorization parameters -# in accordance with the API server security policy. -# Examples for each auth method are provided below, use the example that -# satisfies your auth use case. - -# Configure API key authorization: AgentToken -configuration.api_key['AgentToken'] = os.environ["API_KEY"] - -# Uncomment below to setup prefix (e.g. Bearer) for API key, if needed -# configuration.api_key_prefix['AgentToken'] = 'Bearer' - -# Enter a context with an instance of the API client -async with flyquery_sdk.ApiClient(configuration) as api_client: - # Create an instance of the API class - api_instance = flyquery_sdk.AgentTablesApi(api_client) - table_id = 'table_id_example' # str | - x_agent_token = 'fqt_live_aBcDeF1234567890aBcDeF1234567890' # str | Machine-to-machine bearer token. Replaces X-Tenant-Id and X-Workspace-Id on agent-tier endpoints -- the token's claims encode the tenant + workspace + scopes. Issue via ``POST /api/v1/agent-tokens``. - x_correlation_id = UUID('550e8400-e29b-41d4-a716-446655440000') # UUID | Optional client-supplied correlation id. The service uses this in every log line and downstream call. If absent the service mints a new UUID and echoes it in the response header. (optional) - - try: - api_response = await api_instance.list_changes(table_id, x_agent_token, x_correlation_id=x_correlation_id) - print("The response of AgentTablesApi->list_changes:\n") - pprint(api_response) - except Exception as e: - print("Exception when calling AgentTablesApi->list_changes: %s\n" % e) +import asyncio +import os + +from flyquery_sdk import ApiClient, Configuration +from flyquery_sdk.api import AgentTablesApi +from flyquery_sdk.exceptions import ApiException +from flyquery_sdk.models import PaginatedSchemaChangeRead + + +async def main(): + async with ApiClient(Configuration(host=os.environ["FLYQUERY_URL"])) as client: + client.default_headers.update({ + "X-Tenant-Id": os.environ["FLYQUERY_TENANT_ID"], + "X-Workspace-Id": os.environ["FLYQUERY_WORKSPACE_ID"], + }) + api = AgentTablesApi(client) + try: + page: PaginatedSchemaChangeRead = await api.list_changes( + table_id=os.environ["FLYQUERY_TABLE_ID"], + x_agent_token=os.environ["FLYQUERY_AGENT_TOKEN"], + _request_timeout=15.0, + ) + print(page.total) + except ApiException as exc: + print(f"HTTP {exc.status}") + raise + + +asyncio.run(main()) ``` @@ -336,42 +329,35 @@ Name | Type | Description | Notes * Api Key Authentication (AgentToken): ```python -import flyquery_sdk -from flyquery_sdk.models.paginated_schema_object_read import PaginatedSchemaObjectRead -from flyquery_sdk.rest import ApiException -from pprint import pprint - -# Defining the host is optional and defaults to http://localhost -# See configuration.py for a list of all supported configuration parameters. -configuration = flyquery_sdk.Configuration( - host = "http://localhost" -) - -# The client must configure the authentication and authorization parameters -# in accordance with the API server security policy. -# Examples for each auth method are provided below, use the example that -# satisfies your auth use case. - -# Configure API key authorization: AgentToken -configuration.api_key['AgentToken'] = os.environ["API_KEY"] - -# Uncomment below to setup prefix (e.g. Bearer) for API key, if needed -# configuration.api_key_prefix['AgentToken'] = 'Bearer' - -# Enter a context with an instance of the API client -async with flyquery_sdk.ApiClient(configuration) as api_client: - # Create an instance of the API class - api_instance = flyquery_sdk.AgentTablesApi(api_client) - table_id = 'table_id_example' # str | - x_agent_token = 'fqt_live_aBcDeF1234567890aBcDeF1234567890' # str | Machine-to-machine bearer token. Replaces X-Tenant-Id and X-Workspace-Id on agent-tier endpoints -- the token's claims encode the tenant + workspace + scopes. Issue via ``POST /api/v1/agent-tokens``. - x_correlation_id = UUID('550e8400-e29b-41d4-a716-446655440000') # UUID | Optional client-supplied correlation id. The service uses this in every log line and downstream call. If absent the service mints a new UUID and echoes it in the response header. (optional) - - try: - api_response = await api_instance.list_objects(table_id, x_agent_token, x_correlation_id=x_correlation_id) - print("The response of AgentTablesApi->list_objects:\n") - pprint(api_response) - except Exception as e: - print("Exception when calling AgentTablesApi->list_objects: %s\n" % e) +import asyncio +import os + +from flyquery_sdk import ApiClient, Configuration +from flyquery_sdk.api import AgentTablesApi +from flyquery_sdk.exceptions import ApiException +from flyquery_sdk.models import PaginatedSchemaObjectRead + + +async def main(): + async with ApiClient(Configuration(host=os.environ["FLYQUERY_URL"])) as client: + client.default_headers.update({ + "X-Tenant-Id": os.environ["FLYQUERY_TENANT_ID"], + "X-Workspace-Id": os.environ["FLYQUERY_WORKSPACE_ID"], + }) + api = AgentTablesApi(client) + try: + page: PaginatedSchemaObjectRead = await api.list_objects( + table_id=os.environ["FLYQUERY_TABLE_ID"], + x_agent_token=os.environ["FLYQUERY_AGENT_TOKEN"], + _request_timeout=15.0, + ) + print(page.total) + except ApiException as exc: + print(f"HTTP {exc.status}") + raise + + +asyncio.run(main()) ``` @@ -414,42 +400,35 @@ Name | Type | Description | Notes * Api Key Authentication (AgentToken): ```python -import flyquery_sdk -from flyquery_sdk.models.paginated_snapshot_read import PaginatedSnapshotRead -from flyquery_sdk.rest import ApiException -from pprint import pprint - -# Defining the host is optional and defaults to http://localhost -# See configuration.py for a list of all supported configuration parameters. -configuration = flyquery_sdk.Configuration( - host = "http://localhost" -) - -# The client must configure the authentication and authorization parameters -# in accordance with the API server security policy. -# Examples for each auth method are provided below, use the example that -# satisfies your auth use case. - -# Configure API key authorization: AgentToken -configuration.api_key['AgentToken'] = os.environ["API_KEY"] - -# Uncomment below to setup prefix (e.g. Bearer) for API key, if needed -# configuration.api_key_prefix['AgentToken'] = 'Bearer' - -# Enter a context with an instance of the API client -async with flyquery_sdk.ApiClient(configuration) as api_client: - # Create an instance of the API class - api_instance = flyquery_sdk.AgentTablesApi(api_client) - table_id = 'table_id_example' # str | - x_agent_token = 'fqt_live_aBcDeF1234567890aBcDeF1234567890' # str | Machine-to-machine bearer token. Replaces X-Tenant-Id and X-Workspace-Id on agent-tier endpoints -- the token's claims encode the tenant + workspace + scopes. Issue via ``POST /api/v1/agent-tokens``. - x_correlation_id = UUID('550e8400-e29b-41d4-a716-446655440000') # UUID | Optional client-supplied correlation id. The service uses this in every log line and downstream call. If absent the service mints a new UUID and echoes it in the response header. (optional) - - try: - api_response = await api_instance.list_snapshots(table_id, x_agent_token, x_correlation_id=x_correlation_id) - print("The response of AgentTablesApi->list_snapshots:\n") - pprint(api_response) - except Exception as e: - print("Exception when calling AgentTablesApi->list_snapshots: %s\n" % e) +import asyncio +import os + +from flyquery_sdk import ApiClient, Configuration +from flyquery_sdk.api import AgentTablesApi +from flyquery_sdk.exceptions import ApiException +from flyquery_sdk.models import PaginatedSnapshotRead + + +async def main(): + async with ApiClient(Configuration(host=os.environ["FLYQUERY_URL"])) as client: + client.default_headers.update({ + "X-Tenant-Id": os.environ["FLYQUERY_TENANT_ID"], + "X-Workspace-Id": os.environ["FLYQUERY_WORKSPACE_ID"], + }) + api = AgentTablesApi(client) + try: + page: PaginatedSnapshotRead = await api.list_snapshots( + table_id=os.environ["FLYQUERY_TABLE_ID"], + x_agent_token=os.environ["FLYQUERY_AGENT_TOKEN"], + _request_timeout=15.0, + ) + print(page.total) + except ApiException as exc: + print(f"HTTP {exc.status}") + raise + + +asyncio.run(main()) ``` @@ -492,42 +471,35 @@ Name | Type | Description | Notes * Api Key Authentication (AgentToken): ```python -import flyquery_sdk -from flyquery_sdk.models.paginated_table_read import PaginatedTableRead -from flyquery_sdk.rest import ApiException -from pprint import pprint - -# Defining the host is optional and defaults to http://localhost -# See configuration.py for a list of all supported configuration parameters. -configuration = flyquery_sdk.Configuration( - host = "http://localhost" -) - -# The client must configure the authentication and authorization parameters -# in accordance with the API server security policy. -# Examples for each auth method are provided below, use the example that -# satisfies your auth use case. - -# Configure API key authorization: AgentToken -configuration.api_key['AgentToken'] = os.environ["API_KEY"] - -# Uncomment below to setup prefix (e.g. Bearer) for API key, if needed -# configuration.api_key_prefix['AgentToken'] = 'Bearer' - -# Enter a context with an instance of the API client -async with flyquery_sdk.ApiClient(configuration) as api_client: - # Create an instance of the API class - api_instance = flyquery_sdk.AgentTablesApi(api_client) - dataset_id = 'dataset_id_example' # str | - x_agent_token = 'fqt_live_aBcDeF1234567890aBcDeF1234567890' # str | Machine-to-machine bearer token. Replaces X-Tenant-Id and X-Workspace-Id on agent-tier endpoints -- the token's claims encode the tenant + workspace + scopes. Issue via ``POST /api/v1/agent-tokens``. - x_correlation_id = UUID('550e8400-e29b-41d4-a716-446655440000') # UUID | Optional client-supplied correlation id. The service uses this in every log line and downstream call. If absent the service mints a new UUID and echoes it in the response header. (optional) - - try: - api_response = await api_instance.list_tables(dataset_id, x_agent_token, x_correlation_id=x_correlation_id) - print("The response of AgentTablesApi->list_tables:\n") - pprint(api_response) - except Exception as e: - print("Exception when calling AgentTablesApi->list_tables: %s\n" % e) +import asyncio +import os + +from flyquery_sdk import ApiClient, Configuration +from flyquery_sdk.api import AgentTablesApi +from flyquery_sdk.exceptions import ApiException +from flyquery_sdk.models import PaginatedTableRead + + +async def main(): + async with ApiClient(Configuration(host=os.environ["FLYQUERY_URL"])) as client: + client.default_headers.update({ + "X-Tenant-Id": os.environ["FLYQUERY_TENANT_ID"], + "X-Workspace-Id": os.environ["FLYQUERY_WORKSPACE_ID"], + }) + api = AgentTablesApi(client) + try: + page: PaginatedTableRead = await api.list_tables( + dataset_id=os.environ["FLYQUERY_DATASET_ID"], + x_agent_token=os.environ["FLYQUERY_AGENT_TOKEN"], + _request_timeout=15.0, + ) + print(page.total) + except ApiException as exc: + print(f"HTTP {exc.status}") + raise + + +asyncio.run(main()) ``` @@ -570,48 +542,35 @@ Name | Type | Description | Notes * Api Key Authentication (AgentToken): ```python -import flyquery_sdk -from flyquery_sdk.models.paginated_table_read import PaginatedTableRead -from flyquery_sdk.rest import ApiException -from pprint import pprint - -# Defining the host is optional and defaults to http://localhost -# See configuration.py for a list of all supported configuration parameters. -configuration = flyquery_sdk.Configuration( - host = "http://localhost" -) - -# The client must configure the authentication and authorization parameters -# in accordance with the API server security policy. -# Examples for each auth method are provided below, use the example that -# satisfies your auth use case. - -# Configure API key authorization: AgentToken -configuration.api_key['AgentToken'] = os.environ["API_KEY"] - -# Uncomment below to setup prefix (e.g. Bearer) for API key, if needed -# configuration.api_key_prefix['AgentToken'] = 'Bearer' - -# Enter a context with an instance of the API client -async with flyquery_sdk.ApiClient(configuration) as api_client: - # Create an instance of the API class - api_instance = flyquery_sdk.AgentTablesApi(api_client) - x_agent_token = 'fqt_live_aBcDeF1234567890aBcDeF1234567890' # str | Machine-to-machine bearer token. Replaces X-Tenant-Id and X-Workspace-Id on agent-tier endpoints -- the token's claims encode the tenant + workspace + scopes. Issue via ``POST /api/v1/agent-tokens``. - q = 'q_example' # str | (optional) - name = 'name_example' # str | (optional) - dataset_id = 'dataset_id_example' # str | (optional) - kind = 'kind_example' # str | (optional) - is_active = False # bool | (optional) (default to False) - limit = 100 # int | (optional) (default to 100) - offset = 0 # int | (optional) (default to 0) - x_correlation_id = UUID('550e8400-e29b-41d4-a716-446655440000') # UUID | Optional client-supplied correlation id. The service uses this in every log line and downstream call. If absent the service mints a new UUID and echoes it in the response header. (optional) - - try: - api_response = await api_instance.search_tables(x_agent_token, q=q, name=name, dataset_id=dataset_id, kind=kind, is_active=is_active, limit=limit, offset=offset, x_correlation_id=x_correlation_id) - print("The response of AgentTablesApi->search_tables:\n") - pprint(api_response) - except Exception as e: - print("Exception when calling AgentTablesApi->search_tables: %s\n" % e) +import asyncio +import os + +from flyquery_sdk import ApiClient, Configuration +from flyquery_sdk.api import AgentTablesApi +from flyquery_sdk.exceptions import ApiException +from flyquery_sdk.models import PaginatedTableRead + + +async def main(): + async with ApiClient(Configuration(host=os.environ["FLYQUERY_URL"])) as client: + client.default_headers.update({ + "X-Tenant-Id": os.environ["FLYQUERY_TENANT_ID"], + "X-Workspace-Id": os.environ["FLYQUERY_WORKSPACE_ID"], + }) + api = AgentTablesApi(client) + try: + page: PaginatedTableRead = await api.search_tables( + dataset_id=os.environ["FLYQUERY_DATASET_ID"], + x_agent_token=os.environ["FLYQUERY_AGENT_TOKEN"], + _request_timeout=15.0, + ) + print(page.total) + except ApiException as exc: + print(f"HTTP {exc.status}") + raise + + +asyncio.run(main()) ``` From 3428ac424064ea70a6cf0d10cd6acdf028fad651 Mon Sep 17 00:00:00 2001 From: Andres Contreras Date: Wed, 14 Oct 2026 13:29:57 -0700 Subject: [PATCH 20/20] Return typed dataset and conversation discovery pages --- openapi.json | 14 ++++ sdks/java/api/openapi.yaml | 8 ++ sdks/java/docs/AgentConversationsApi.md | 45 +++++------- sdks/java/docs/AgentDatasetsApi.md | 51 +++++-------- .../flyquery/api/AgentConversationsApi.java | 20 +++-- .../flyquery/api/AgentDatasetsApi.java | 20 +++-- sdks/python/docs/AgentConversationsApi.md | 67 ++++++++--------- sdks/python/docs/AgentDatasetsApi.md | 73 ++++++++----------- .../api/agent_conversations_api.py | 18 +++-- .../flyquery_sdk/api/agent_datasets_api.py | 18 +++-- .../tests/test_agent_table_responses.py | 24 +++--- .../agent/conversations_controller.py | 4 +- .../controllers/agent/datasets_controller.py | 4 +- 13 files changed, 192 insertions(+), 174 deletions(-) diff --git a/openapi.json b/openapi.json index 5404bf97..812229e9 100644 --- a/openapi.json +++ b/openapi.json @@ -6368,6 +6368,13 @@ ], "responses": { "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Paginated[ConversationRead]" + } + } + }, "description": "Successful response" } }, @@ -6613,6 +6620,13 @@ ], "responses": { "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Paginated[DatasetRead]" + } + } + }, "description": "Successful response" } }, diff --git a/sdks/java/api/openapi.yaml b/sdks/java/api/openapi.yaml index 518e5673..964218e6 100644 --- a/sdks/java/api/openapi.yaml +++ b/sdks/java/api/openapi.yaml @@ -167,6 +167,10 @@ paths: - $ref: "#/components/parameters/CorrelationIdHeader" responses: "200": + content: + application/json: + schema: + $ref: "#/components/schemas/Paginated[ConversationRead]" description: Successful response security: - AgentToken: [] @@ -346,6 +350,10 @@ paths: - $ref: "#/components/parameters/CorrelationIdHeader" responses: "200": + content: + application/json: + schema: + $ref: "#/components/schemas/Paginated[DatasetRead]" description: Successful response security: - AgentToken: [] diff --git a/sdks/java/docs/AgentConversationsApi.md b/sdks/java/docs/AgentConversationsApi.md index 6efcf05a..73a2c667 100644 --- a/sdks/java/docs/AgentConversationsApi.md +++ b/sdks/java/docs/AgentConversationsApi.md @@ -93,43 +93,34 @@ public class Example { ## listConversations -> listConversations(xAgentToken, xCorrelationId) +> Mono listConversations(xAgentToken, xCorrelationId) List conversations for the agent's workspace (newest first). ### Example ```java -// Import classes: +import java.time.Duration; import com.firefly.flyquery.ApiClient; -import com.firefly.flyquery.ApiException; -import com.firefly.flyquery.Configuration; -import com.firefly.flyquery.auth.*; -import com.firefly.flyquery.models.*; import com.firefly.flyquery.api.AgentConversationsApi; +import com.firefly.flyquery.model.PaginatedConversationRead; +import org.springframework.web.reactive.function.client.WebClientResponseException; public class Example { public static void main(String[] args) { - ApiClient defaultClient = Configuration.getDefaultApiClient(); - defaultClient.setBasePath("http://localhost"); - - // Configure API key authorization: AgentToken - ApiKeyAuth AgentToken = (ApiKeyAuth) defaultClient.getAuthentication("AgentToken"); - AgentToken.setApiKey("YOUR API KEY"); - // Uncomment the following line to set a prefix for the API key, e.g. "Token" (defaults to null) - //AgentToken.setApiKeyPrefix("Token"); - - AgentConversationsApi apiInstance = new AgentConversationsApi(defaultClient); - String xAgentToken = "fqt_live_aBcDeF1234567890aBcDeF1234567890"; // String | Machine-to-machine bearer token. Replaces X-Tenant-Id and X-Workspace-Id on agent-tier endpoints -- the token's claims encode the tenant + workspace + scopes. Issue via ``POST /api/v1/agent-tokens``. - UUID xCorrelationId = UUID.fromString("550e8400-e29b-41d4-a716-446655440000"); // UUID | Optional client-supplied correlation id. The service uses this in every log line and downstream call. If absent the service mints a new UUID and echoes it in the response header. + ApiClient client = new ApiClient(); + client.setBasePath(System.getenv("FLYQUERY_URL")); + client.addDefaultHeader("X-Tenant-Id", System.getenv("FLYQUERY_TENANT_ID")); + client.addDefaultHeader("X-Workspace-Id", System.getenv("FLYQUERY_WORKSPACE_ID")); + AgentConversationsApi api = new AgentConversationsApi(client); + String token = System.getenv("FLYQUERY_AGENT_TOKEN"); try { - apiInstance.listConversations(xAgentToken, xCorrelationId); - } catch (ApiException e) { - System.err.println("Exception when calling AgentConversationsApi#listConversations"); - System.err.println("Status code: " + e.getCode()); - System.err.println("Reason: " + e.getResponseBody()); - System.err.println("Response headers: " + e.getResponseHeaders()); - e.printStackTrace(); + PaginatedConversationRead page = api.listConversations(token, null).block(Duration.ofSeconds(15)); + if (page == null) throw new IllegalStateException("The API returned no page"); + System.out.println(page.getItems()); + } catch (WebClientResponseException e) { + System.err.println("HTTP " + e.getStatusCode()); + throw e; } } } @@ -145,7 +136,7 @@ public class Example { ### Return type -null (empty response body) +[**PaginatedConversationRead**](PaginatedConversationRead.md) ### Authorization @@ -154,7 +145,7 @@ null (empty response body) ### HTTP request headers - **Content-Type**: Not defined -- **Accept**: Not defined +- **Accept**: application/json ### HTTP response details diff --git a/sdks/java/docs/AgentDatasetsApi.md b/sdks/java/docs/AgentDatasetsApi.md index a694adfb..e48c1fb4 100644 --- a/sdks/java/docs/AgentDatasetsApi.md +++ b/sdks/java/docs/AgentDatasetsApi.md @@ -12,49 +12,34 @@ All URIs are relative to *http://localhost* ## listDatasets -> listDatasets(xAgentToken, q, name, status, workspaceId, limit, offset, xCorrelationId) +> Mono listDatasets(xAgentToken, q, name, status, workspaceId, limit, offset, xCorrelationId) Search / filter datasets visible to this agent's tenant. ### Example ```java -// Import classes: +import java.time.Duration; import com.firefly.flyquery.ApiClient; -import com.firefly.flyquery.ApiException; -import com.firefly.flyquery.Configuration; -import com.firefly.flyquery.auth.*; -import com.firefly.flyquery.models.*; import com.firefly.flyquery.api.AgentDatasetsApi; +import com.firefly.flyquery.model.PaginatedDatasetRead; +import org.springframework.web.reactive.function.client.WebClientResponseException; public class Example { public static void main(String[] args) { - ApiClient defaultClient = Configuration.getDefaultApiClient(); - defaultClient.setBasePath("http://localhost"); - - // Configure API key authorization: AgentToken - ApiKeyAuth AgentToken = (ApiKeyAuth) defaultClient.getAuthentication("AgentToken"); - AgentToken.setApiKey("YOUR API KEY"); - // Uncomment the following line to set a prefix for the API key, e.g. "Token" (defaults to null) - //AgentToken.setApiKeyPrefix("Token"); - - AgentDatasetsApi apiInstance = new AgentDatasetsApi(defaultClient); - String xAgentToken = "fqt_live_aBcDeF1234567890aBcDeF1234567890"; // String | Machine-to-machine bearer token. Replaces X-Tenant-Id and X-Workspace-Id on agent-tier endpoints -- the token's claims encode the tenant + workspace + scopes. Issue via ``POST /api/v1/agent-tokens``. - String q = "null"; // String | - String name = "name_example"; // String | - String status = "status_example"; // String | - String workspaceId = "workspaceId_example"; // String | - Integer limit = 100; // Integer | - Integer offset = 0; // Integer | - UUID xCorrelationId = UUID.fromString("550e8400-e29b-41d4-a716-446655440000"); // UUID | Optional client-supplied correlation id. The service uses this in every log line and downstream call. If absent the service mints a new UUID and echoes it in the response header. + ApiClient client = new ApiClient(); + client.setBasePath(System.getenv("FLYQUERY_URL")); + client.addDefaultHeader("X-Tenant-Id", System.getenv("FLYQUERY_TENANT_ID")); + client.addDefaultHeader("X-Workspace-Id", System.getenv("FLYQUERY_WORKSPACE_ID")); + AgentDatasetsApi api = new AgentDatasetsApi(client); + String token = System.getenv("FLYQUERY_AGENT_TOKEN"); try { - apiInstance.listDatasets(xAgentToken, q, name, status, workspaceId, limit, offset, xCorrelationId); - } catch (ApiException e) { - System.err.println("Exception when calling AgentDatasetsApi#listDatasets"); - System.err.println("Status code: " + e.getCode()); - System.err.println("Reason: " + e.getResponseBody()); - System.err.println("Response headers: " + e.getResponseHeaders()); - e.printStackTrace(); + PaginatedDatasetRead page = api.listDatasets(token, null, null, null, null, 100, 0, null).block(Duration.ofSeconds(15)); + if (page == null) throw new IllegalStateException("The API returned no page"); + System.out.println(page.getItems()); + } catch (WebClientResponseException e) { + System.err.println("HTTP " + e.getStatusCode()); + throw e; } } } @@ -76,7 +61,7 @@ public class Example { ### Return type -null (empty response body) +[**PaginatedDatasetRead**](PaginatedDatasetRead.md) ### Authorization @@ -85,7 +70,7 @@ null (empty response body) ### HTTP request headers - **Content-Type**: Not defined -- **Accept**: Not defined +- **Accept**: application/json ### HTTP response details diff --git a/sdks/java/src/main/java/com/firefly/flyquery/api/AgentConversationsApi.java b/sdks/java/src/main/java/com/firefly/flyquery/api/AgentConversationsApi.java index 5c07e5e2..afe3484a 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/api/AgentConversationsApi.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/api/AgentConversationsApi.java @@ -7,6 +7,7 @@ import com.firefly.flyquery.model.ConversationRead; import com.firefly.flyquery.model.ConversationTurnRequest; import com.firefly.flyquery.model.HTTPValidationError; +import com.firefly.flyquery.model.PaginatedConversationRead; import java.util.UUID; import java.util.HashMap; @@ -31,7 +32,7 @@ import reactor.core.publisher.Mono; import reactor.core.publisher.Flux; -@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", date = "2026-06-01T11:28:27.907207+02:00[Europe/Madrid]", comments = "Generator version: 7.22.0") +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", date = "2026-10-14T13:20:41.405226-07:00[America/Los_Angeles]", comments = "Generator version: 7.22.0") public class AgentConversationsApi { private ApiClient apiClient; @@ -158,6 +159,7 @@ public ResponseSpec createWithResponseSpec(@jakarta.annotation.Nonnull String xA *

200 - Successful response * @param xAgentToken Machine-to-machine bearer token. Replaces X-Tenant-Id and X-Workspace-Id on agent-tier endpoints -- the token's claims encode the tenant + workspace + scopes. Issue via ``POST /api/v1/agent-tokens``. * @param xCorrelationId Optional client-supplied correlation id. The service uses this in every log line and downstream call. If absent the service mints a new UUID and echoes it in the response header. + * @return PaginatedConversationRead * @throws WebClientResponseException if an error occurs while attempting to invoke the API */ private ResponseSpec listConversationsRequestCreation(@jakarta.annotation.Nonnull String xAgentToken, @jakarta.annotation.Nullable UUID xCorrelationId) throws WebClientResponseException { @@ -178,14 +180,16 @@ private ResponseSpec listConversationsRequestCreation(@jakarta.annotation.Nonnul headerParams.add("X-Agent-Token", apiClient.parameterToString(xAgentToken)); if (xCorrelationId != null) headerParams.add("X-Correlation-Id", apiClient.parameterToString(xCorrelationId)); - final String[] localVarAccepts = { }; + final String[] localVarAccepts = { + "application/json" + }; final List localVarAccept = apiClient.selectHeaderAccept(localVarAccepts); final String[] localVarContentTypes = { }; final MediaType localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes); String[] localVarAuthNames = new String[] { "AgentToken" }; - ParameterizedTypeReference localVarReturnType = new ParameterizedTypeReference() {}; + ParameterizedTypeReference localVarReturnType = new ParameterizedTypeReference() {}; return apiClient.invokeAPI("/api/v1/agent/conversations", HttpMethod.GET, pathParams, queryParams, postBody, headerParams, cookieParams, formParams, localVarAccept, localVarContentType, localVarAuthNames, localVarReturnType); } @@ -195,10 +199,11 @@ private ResponseSpec listConversationsRequestCreation(@jakarta.annotation.Nonnul *

200 - Successful response * @param xAgentToken Machine-to-machine bearer token. Replaces X-Tenant-Id and X-Workspace-Id on agent-tier endpoints -- the token's claims encode the tenant + workspace + scopes. Issue via ``POST /api/v1/agent-tokens``. * @param xCorrelationId Optional client-supplied correlation id. The service uses this in every log line and downstream call. If absent the service mints a new UUID and echoes it in the response header. + * @return PaginatedConversationRead * @throws WebClientResponseException if an error occurs while attempting to invoke the API */ - public Mono listConversations(@jakarta.annotation.Nonnull String xAgentToken, @jakarta.annotation.Nullable UUID xCorrelationId) throws WebClientResponseException { - ParameterizedTypeReference localVarReturnType = new ParameterizedTypeReference() {}; + public Mono listConversations(@jakarta.annotation.Nonnull String xAgentToken, @jakarta.annotation.Nullable UUID xCorrelationId) throws WebClientResponseException { + ParameterizedTypeReference localVarReturnType = new ParameterizedTypeReference() {}; return listConversationsRequestCreation(xAgentToken, xCorrelationId).bodyToMono(localVarReturnType); } @@ -208,10 +213,11 @@ public Mono listConversations(@jakarta.annotation.Nonnull String xAgentTok *

200 - Successful response * @param xAgentToken Machine-to-machine bearer token. Replaces X-Tenant-Id and X-Workspace-Id on agent-tier endpoints -- the token's claims encode the tenant + workspace + scopes. Issue via ``POST /api/v1/agent-tokens``. * @param xCorrelationId Optional client-supplied correlation id. The service uses this in every log line and downstream call. If absent the service mints a new UUID and echoes it in the response header. + * @return ResponseEntity<PaginatedConversationRead> * @throws WebClientResponseException if an error occurs while attempting to invoke the API */ - public Mono> listConversationsWithHttpInfo(@jakarta.annotation.Nonnull String xAgentToken, @jakarta.annotation.Nullable UUID xCorrelationId) throws WebClientResponseException { - ParameterizedTypeReference localVarReturnType = new ParameterizedTypeReference() {}; + public Mono> listConversationsWithHttpInfo(@jakarta.annotation.Nonnull String xAgentToken, @jakarta.annotation.Nullable UUID xCorrelationId) throws WebClientResponseException { + ParameterizedTypeReference localVarReturnType = new ParameterizedTypeReference() {}; return listConversationsRequestCreation(xAgentToken, xCorrelationId).toEntity(localVarReturnType); } diff --git a/sdks/java/src/main/java/com/firefly/flyquery/api/AgentDatasetsApi.java b/sdks/java/src/main/java/com/firefly/flyquery/api/AgentDatasetsApi.java index 1675228c..b67e01fc 100644 --- a/sdks/java/src/main/java/com/firefly/flyquery/api/AgentDatasetsApi.java +++ b/sdks/java/src/main/java/com/firefly/flyquery/api/AgentDatasetsApi.java @@ -3,6 +3,7 @@ import com.firefly.flyquery.ApiClient; import com.firefly.flyquery.model.DatasetRead; +import com.firefly.flyquery.model.PaginatedDatasetRead; import java.util.UUID; import java.util.HashMap; @@ -27,7 +28,7 @@ import reactor.core.publisher.Mono; import reactor.core.publisher.Flux; -@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", date = "2026-06-01T11:28:27.907207+02:00[Europe/Madrid]", comments = "Generator version: 7.22.0") +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", date = "2026-10-14T13:20:41.405226-07:00[America/Los_Angeles]", comments = "Generator version: 7.22.0") public class AgentDatasetsApi { private ApiClient apiClient; @@ -59,6 +60,7 @@ public void setApiClient(ApiClient apiClient) { * @param limit The limit parameter * @param offset The offset parameter * @param xCorrelationId Optional client-supplied correlation id. The service uses this in every log line and downstream call. If absent the service mints a new UUID and echoes it in the response header. + * @return PaginatedDatasetRead * @throws WebClientResponseException if an error occurs while attempting to invoke the API */ private ResponseSpec listDatasetsRequestCreation(@jakarta.annotation.Nonnull String xAgentToken, @jakarta.annotation.Nullable String q, @jakarta.annotation.Nullable String name, @jakarta.annotation.Nullable String status, @jakarta.annotation.Nullable String workspaceId, @jakarta.annotation.Nullable Integer limit, @jakarta.annotation.Nullable Integer offset, @jakarta.annotation.Nullable UUID xCorrelationId) throws WebClientResponseException { @@ -86,14 +88,16 @@ private ResponseSpec listDatasetsRequestCreation(@jakarta.annotation.Nonnull Str headerParams.add("X-Agent-Token", apiClient.parameterToString(xAgentToken)); if (xCorrelationId != null) headerParams.add("X-Correlation-Id", apiClient.parameterToString(xCorrelationId)); - final String[] localVarAccepts = { }; + final String[] localVarAccepts = { + "application/json" + }; final List localVarAccept = apiClient.selectHeaderAccept(localVarAccepts); final String[] localVarContentTypes = { }; final MediaType localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes); String[] localVarAuthNames = new String[] { "AgentToken" }; - ParameterizedTypeReference localVarReturnType = new ParameterizedTypeReference() {}; + ParameterizedTypeReference localVarReturnType = new ParameterizedTypeReference() {}; return apiClient.invokeAPI("/api/v1/agent/datasets", HttpMethod.GET, pathParams, queryParams, postBody, headerParams, cookieParams, formParams, localVarAccept, localVarContentType, localVarAuthNames, localVarReturnType); } @@ -109,10 +113,11 @@ private ResponseSpec listDatasetsRequestCreation(@jakarta.annotation.Nonnull Str * @param limit The limit parameter * @param offset The offset parameter * @param xCorrelationId Optional client-supplied correlation id. The service uses this in every log line and downstream call. If absent the service mints a new UUID and echoes it in the response header. + * @return PaginatedDatasetRead * @throws WebClientResponseException if an error occurs while attempting to invoke the API */ - public Mono listDatasets(@jakarta.annotation.Nonnull String xAgentToken, @jakarta.annotation.Nullable String q, @jakarta.annotation.Nullable String name, @jakarta.annotation.Nullable String status, @jakarta.annotation.Nullable String workspaceId, @jakarta.annotation.Nullable Integer limit, @jakarta.annotation.Nullable Integer offset, @jakarta.annotation.Nullable UUID xCorrelationId) throws WebClientResponseException { - ParameterizedTypeReference localVarReturnType = new ParameterizedTypeReference() {}; + public Mono listDatasets(@jakarta.annotation.Nonnull String xAgentToken, @jakarta.annotation.Nullable String q, @jakarta.annotation.Nullable String name, @jakarta.annotation.Nullable String status, @jakarta.annotation.Nullable String workspaceId, @jakarta.annotation.Nullable Integer limit, @jakarta.annotation.Nullable Integer offset, @jakarta.annotation.Nullable UUID xCorrelationId) throws WebClientResponseException { + ParameterizedTypeReference localVarReturnType = new ParameterizedTypeReference() {}; return listDatasetsRequestCreation(xAgentToken, q, name, status, workspaceId, limit, offset, xCorrelationId).bodyToMono(localVarReturnType); } @@ -128,10 +133,11 @@ public Mono listDatasets(@jakarta.annotation.Nonnull String xAgentToken, @ * @param limit The limit parameter * @param offset The offset parameter * @param xCorrelationId Optional client-supplied correlation id. The service uses this in every log line and downstream call. If absent the service mints a new UUID and echoes it in the response header. + * @return ResponseEntity<PaginatedDatasetRead> * @throws WebClientResponseException if an error occurs while attempting to invoke the API */ - public Mono> listDatasetsWithHttpInfo(@jakarta.annotation.Nonnull String xAgentToken, @jakarta.annotation.Nullable String q, @jakarta.annotation.Nullable String name, @jakarta.annotation.Nullable String status, @jakarta.annotation.Nullable String workspaceId, @jakarta.annotation.Nullable Integer limit, @jakarta.annotation.Nullable Integer offset, @jakarta.annotation.Nullable UUID xCorrelationId) throws WebClientResponseException { - ParameterizedTypeReference localVarReturnType = new ParameterizedTypeReference() {}; + public Mono> listDatasetsWithHttpInfo(@jakarta.annotation.Nonnull String xAgentToken, @jakarta.annotation.Nullable String q, @jakarta.annotation.Nullable String name, @jakarta.annotation.Nullable String status, @jakarta.annotation.Nullable String workspaceId, @jakarta.annotation.Nullable Integer limit, @jakarta.annotation.Nullable Integer offset, @jakarta.annotation.Nullable UUID xCorrelationId) throws WebClientResponseException { + ParameterizedTypeReference localVarReturnType = new ParameterizedTypeReference() {}; return listDatasetsRequestCreation(xAgentToken, q, name, status, workspaceId, limit, offset, xCorrelationId).toEntity(localVarReturnType); } diff --git a/sdks/python/docs/AgentConversationsApi.md b/sdks/python/docs/AgentConversationsApi.md index 4842f9b5..f384bd7a 100644 --- a/sdks/python/docs/AgentConversationsApi.md +++ b/sdks/python/docs/AgentConversationsApi.md @@ -100,7 +100,7 @@ Name | Type | Description | Notes [[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) # **list_conversations** -> list_conversations(x_agent_token, x_correlation_id=x_correlation_id) +> PaginatedConversationRead list_conversations(x_agent_token, x_correlation_id=x_correlation_id) List conversations for the agent's workspace (newest first). @@ -109,39 +109,34 @@ List conversations for the agent's workspace (newest first). * Api Key Authentication (AgentToken): ```python -import flyquery_sdk -from flyquery_sdk.rest import ApiException -from pprint import pprint - -# Defining the host is optional and defaults to http://localhost -# See configuration.py for a list of all supported configuration parameters. -configuration = flyquery_sdk.Configuration( - host = "http://localhost" -) - -# The client must configure the authentication and authorization parameters -# in accordance with the API server security policy. -# Examples for each auth method are provided below, use the example that -# satisfies your auth use case. - -# Configure API key authorization: AgentToken -configuration.api_key['AgentToken'] = os.environ["API_KEY"] - -# Uncomment below to setup prefix (e.g. Bearer) for API key, if needed -# configuration.api_key_prefix['AgentToken'] = 'Bearer' - -# Enter a context with an instance of the API client -async with flyquery_sdk.ApiClient(configuration) as api_client: - # Create an instance of the API class - api_instance = flyquery_sdk.AgentConversationsApi(api_client) - x_agent_token = 'fqt_live_aBcDeF1234567890aBcDeF1234567890' # str | Machine-to-machine bearer token. Replaces X-Tenant-Id and X-Workspace-Id on agent-tier endpoints -- the token's claims encode the tenant + workspace + scopes. Issue via ``POST /api/v1/agent-tokens``. - x_correlation_id = UUID('550e8400-e29b-41d4-a716-446655440000') # UUID | Optional client-supplied correlation id. The service uses this in every log line and downstream call. If absent the service mints a new UUID and echoes it in the response header. (optional) - - try: - # List conversations for the agent's workspace (newest first). - await api_instance.list_conversations(x_agent_token, x_correlation_id=x_correlation_id) - except Exception as e: - print("Exception when calling AgentConversationsApi->list_conversations: %s\n" % e) +import asyncio +import os + +from flyquery_sdk import ApiClient, Configuration +from flyquery_sdk.api import AgentConversationsApi +from flyquery_sdk.exceptions import ApiException +from flyquery_sdk.models import PaginatedConversationRead + + +async def main(): + async with ApiClient(Configuration(host=os.environ["FLYQUERY_URL"])) as client: + client.default_headers.update({ + "X-Tenant-Id": os.environ["FLYQUERY_TENANT_ID"], + "X-Workspace-Id": os.environ["FLYQUERY_WORKSPACE_ID"], + }) + api = AgentConversationsApi(client) + try: + page: PaginatedConversationRead = await api.list_conversations( + x_agent_token=os.environ["FLYQUERY_AGENT_TOKEN"], + _request_timeout=15.0, + ) + print(page.total) + except ApiException as exc: + print(f"HTTP {exc.status}") + raise + + +asyncio.run(main()) ``` @@ -156,7 +151,7 @@ Name | Type | Description | Notes ### Return type -void (empty response body) +[**PaginatedConversationRead**](PaginatedConversationRead.md) ### Authorization @@ -165,7 +160,7 @@ void (empty response body) ### HTTP request headers - **Content-Type**: Not defined - - **Accept**: Not defined + - **Accept**: application/json ### HTTP response details diff --git a/sdks/python/docs/AgentDatasetsApi.md b/sdks/python/docs/AgentDatasetsApi.md index 2aacbf9a..f5a9c5f7 100644 --- a/sdks/python/docs/AgentDatasetsApi.md +++ b/sdks/python/docs/AgentDatasetsApi.md @@ -10,7 +10,7 @@ Method | HTTP request | Description # **list_datasets** -> list_datasets(x_agent_token, q=q, name=name, status=status, workspace_id=workspace_id, limit=limit, offset=offset, x_correlation_id=x_correlation_id) +> PaginatedDatasetRead list_datasets(x_agent_token, q=q, name=name, status=status, workspace_id=workspace_id, limit=limit, offset=offset, x_correlation_id=x_correlation_id) Search / filter datasets visible to this agent's tenant. @@ -19,45 +19,34 @@ Search / filter datasets visible to this agent's tenant. * Api Key Authentication (AgentToken): ```python -import flyquery_sdk -from flyquery_sdk.rest import ApiException -from pprint import pprint - -# Defining the host is optional and defaults to http://localhost -# See configuration.py for a list of all supported configuration parameters. -configuration = flyquery_sdk.Configuration( - host = "http://localhost" -) - -# The client must configure the authentication and authorization parameters -# in accordance with the API server security policy. -# Examples for each auth method are provided below, use the example that -# satisfies your auth use case. - -# Configure API key authorization: AgentToken -configuration.api_key['AgentToken'] = os.environ["API_KEY"] - -# Uncomment below to setup prefix (e.g. Bearer) for API key, if needed -# configuration.api_key_prefix['AgentToken'] = 'Bearer' - -# Enter a context with an instance of the API client -async with flyquery_sdk.ApiClient(configuration) as api_client: - # Create an instance of the API class - api_instance = flyquery_sdk.AgentDatasetsApi(api_client) - x_agent_token = 'fqt_live_aBcDeF1234567890aBcDeF1234567890' # str | Machine-to-machine bearer token. Replaces X-Tenant-Id and X-Workspace-Id on agent-tier endpoints -- the token's claims encode the tenant + workspace + scopes. Issue via ``POST /api/v1/agent-tokens``. - q = 'null' # str | (optional) (default to 'null') - name = 'name_example' # str | (optional) - status = 'status_example' # str | (optional) - workspace_id = 'workspace_id_example' # str | (optional) - limit = 100 # int | (optional) (default to 100) - offset = 0 # int | (optional) (default to 0) - x_correlation_id = UUID('550e8400-e29b-41d4-a716-446655440000') # UUID | Optional client-supplied correlation id. The service uses this in every log line and downstream call. If absent the service mints a new UUID and echoes it in the response header. (optional) - - try: - # Search / filter datasets visible to this agent's tenant. - await api_instance.list_datasets(x_agent_token, q=q, name=name, status=status, workspace_id=workspace_id, limit=limit, offset=offset, x_correlation_id=x_correlation_id) - except Exception as e: - print("Exception when calling AgentDatasetsApi->list_datasets: %s\n" % e) +import asyncio +import os + +from flyquery_sdk import ApiClient, Configuration +from flyquery_sdk.api import AgentDatasetsApi +from flyquery_sdk.exceptions import ApiException +from flyquery_sdk.models import PaginatedDatasetRead + + +async def main(): + async with ApiClient(Configuration(host=os.environ["FLYQUERY_URL"])) as client: + client.default_headers.update({ + "X-Tenant-Id": os.environ["FLYQUERY_TENANT_ID"], + "X-Workspace-Id": os.environ["FLYQUERY_WORKSPACE_ID"], + }) + api = AgentDatasetsApi(client) + try: + page: PaginatedDatasetRead = await api.list_datasets( + x_agent_token=os.environ["FLYQUERY_AGENT_TOKEN"], + _request_timeout=15.0, + ) + print(page.total) + except ApiException as exc: + print(f"HTTP {exc.status}") + raise + + +asyncio.run(main()) ``` @@ -78,7 +67,7 @@ Name | Type | Description | Notes ### Return type -void (empty response body) +[**PaginatedDatasetRead**](PaginatedDatasetRead.md) ### Authorization @@ -87,7 +76,7 @@ void (empty response body) ### HTTP request headers - **Content-Type**: Not defined - - **Accept**: Not defined + - **Accept**: application/json ### HTTP response details diff --git a/sdks/python/flyquery_sdk/api/agent_conversations_api.py b/sdks/python/flyquery_sdk/api/agent_conversations_api.py index a8e5336b..65c985c6 100644 --- a/sdks/python/flyquery_sdk/api/agent_conversations_api.py +++ b/sdks/python/flyquery_sdk/api/agent_conversations_api.py @@ -23,6 +23,7 @@ from flyquery_sdk.models.conversation_create import ConversationCreate from flyquery_sdk.models.conversation_read import ConversationRead from flyquery_sdk.models.conversation_turn_request import ConversationTurnRequest +from flyquery_sdk.models.paginated_conversation_read import PaginatedConversationRead from flyquery_sdk.api_client import ApiClient, RequestSerialized from flyquery_sdk.api_response import ApiResponse @@ -381,7 +382,7 @@ async def list_conversations( _content_type: Optional[StrictStr] = None, _headers: Optional[Dict[StrictStr, Any]] = None, _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, - ) -> None: + ) -> PaginatedConversationRead: """List conversations for the agent's workspace (newest first). @@ -421,7 +422,7 @@ async def list_conversations( ) _response_types_map: Dict[str, Optional[str]] = { - '200': None, + '200': "PaginatedConversationRead", } response_data = await self.api_client.call_api( *_param, @@ -451,7 +452,7 @@ async def list_conversations_with_http_info( _content_type: Optional[StrictStr] = None, _headers: Optional[Dict[StrictStr, Any]] = None, _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, - ) -> ApiResponse[None]: + ) -> ApiResponse[PaginatedConversationRead]: """List conversations for the agent's workspace (newest first). @@ -491,7 +492,7 @@ async def list_conversations_with_http_info( ) _response_types_map: Dict[str, Optional[str]] = { - '200': None, + '200': "PaginatedConversationRead", } response_data = await self.api_client.call_api( *_param, @@ -561,7 +562,7 @@ async def list_conversations_without_preload_content( ) _response_types_map: Dict[str, Optional[str]] = { - '200': None, + '200': "PaginatedConversationRead", } response_data = await self.api_client.call_api( *_param, @@ -605,6 +606,13 @@ def _list_conversations_serialize( # process the body parameter + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) # authentication setting diff --git a/sdks/python/flyquery_sdk/api/agent_datasets_api.py b/sdks/python/flyquery_sdk/api/agent_datasets_api.py index ba96cb4b..402b1eb3 100644 --- a/sdks/python/flyquery_sdk/api/agent_datasets_api.py +++ b/sdks/python/flyquery_sdk/api/agent_datasets_api.py @@ -20,6 +20,7 @@ from typing_extensions import Annotated from uuid import UUID from flyquery_sdk.models.dataset_read import DatasetRead +from flyquery_sdk.models.paginated_dataset_read import PaginatedDatasetRead from flyquery_sdk.api_client import ApiClient, RequestSerialized from flyquery_sdk.api_response import ApiResponse @@ -62,7 +63,7 @@ async def list_datasets( _content_type: Optional[StrictStr] = None, _headers: Optional[Dict[StrictStr, Any]] = None, _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, - ) -> None: + ) -> PaginatedDatasetRead: """Search / filter datasets visible to this agent's tenant. @@ -120,7 +121,7 @@ async def list_datasets( ) _response_types_map: Dict[str, Optional[str]] = { - '200': None, + '200': "PaginatedDatasetRead", } response_data = await self.api_client.call_api( *_param, @@ -156,7 +157,7 @@ async def list_datasets_with_http_info( _content_type: Optional[StrictStr] = None, _headers: Optional[Dict[StrictStr, Any]] = None, _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, - ) -> ApiResponse[None]: + ) -> ApiResponse[PaginatedDatasetRead]: """Search / filter datasets visible to this agent's tenant. @@ -214,7 +215,7 @@ async def list_datasets_with_http_info( ) _response_types_map: Dict[str, Optional[str]] = { - '200': None, + '200': "PaginatedDatasetRead", } response_data = await self.api_client.call_api( *_param, @@ -308,7 +309,7 @@ async def list_datasets_without_preload_content( ) _response_types_map: Dict[str, Optional[str]] = { - '200': None, + '200': "PaginatedDatasetRead", } response_data = await self.api_client.call_api( *_param, @@ -382,6 +383,13 @@ def _list_datasets_serialize( # process the body parameter + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) # authentication setting diff --git a/sdks/python/tests/test_agent_table_responses.py b/sdks/python/tests/test_agent_table_responses.py index b008e63a..03c7d0b7 100644 --- a/sdks/python/tests/test_agent_table_responses.py +++ b/sdks/python/tests/test_agent_table_responses.py @@ -10,8 +10,10 @@ import pytest from flyquery_sdk import ApiClient, Configuration -from flyquery_sdk.api import AgentTablesApi +from flyquery_sdk.api import AgentConversationsApi, AgentDatasetsApi, AgentTablesApi from flyquery_sdk.models import ( + PaginatedConversationRead, + PaginatedDatasetRead, PaginatedSchemaChangeRead, PaginatedSchemaObjectRead, PaginatedSnapshotRead, @@ -49,16 +51,18 @@ def do_GET(self): @pytest.mark.asyncio @pytest.mark.parametrize( - "operation,page_type", + "api_type,operation,page_type", [ - ("list_tables", PaginatedTableRead), - ("search_tables", PaginatedTableRead), - ("list_snapshots", PaginatedSnapshotRead), - ("list_objects", PaginatedSchemaObjectRead), - ("list_changes", PaginatedSchemaChangeRead), + (AgentTablesApi, "list_tables", PaginatedTableRead), + (AgentTablesApi, "search_tables", PaginatedTableRead), + (AgentTablesApi, "list_snapshots", PaginatedSnapshotRead), + (AgentTablesApi, "list_objects", PaginatedSchemaObjectRead), + (AgentTablesApi, "list_changes", PaginatedSchemaChangeRead), + (AgentDatasetsApi, "list_datasets", PaginatedDatasetRead), + (AgentConversationsApi, "list_conversations", PaginatedConversationRead), ], ) -async def test_agent_table_reads_return_typed_pages(operation, page_type): +async def test_agent_table_reads_return_typed_pages(api_type, operation, page_type): token = "agt_" + "synthetic-local-fixture" * 2 workspace = str(uuid4()) with page_server() as (origin, requests): @@ -67,9 +71,9 @@ async def test_agent_table_reads_return_typed_pages(operation, page_type): parameters = {"x_agent_token": token, "_request_timeout": 5.0} if operation == "list_tables": parameters["dataset_id"] = str(uuid4()) - elif operation != "search_tables": + elif operation in {"list_snapshots", "list_objects", "list_changes"}: parameters["table_id"] = str(uuid4()) - result = await getattr(AgentTablesApi(client), operation)(**parameters) + result = await getattr(api_type(client), operation)(**parameters) assert isinstance(result, page_type) assert result.items == [] and result.total == 0 assert len(requests) == 1 diff --git a/src/flyquery/web/controllers/agent/conversations_controller.py b/src/flyquery/web/controllers/agent/conversations_controller.py index f456dac6..ab038ea1 100644 --- a/src/flyquery/web/controllers/agent/conversations_controller.py +++ b/src/flyquery/web/controllers/agent/conversations_controller.py @@ -1,4 +1,5 @@ # Copyright 2024-2026 Firefly Software Foundation +# SPDX-License-Identifier: Apache-2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -46,6 +47,7 @@ ConversationRead, ConversationTurnRequest, ) +from flyquery.interfaces.pagination import Paginated from flyquery.interfaces.query import AnswerResponse from flyquery.web.controllers.conversations_controller import ( ConversationsController as _UserConversationsController, @@ -141,7 +143,7 @@ async def _do_create() -> ConversationRead: # ------------------------------------------------------------------ @get_mapping("/conversations") - async def list_conversations(self, http_request: Request) -> dict: + async def list_conversations(self, http_request: Request) -> Paginated[ConversationRead]: """List conversations for the agent's workspace (newest first).""" await self._verify(http_request, _SCOPE_CONV_READ) return await self._delegate.list_conversations(http_request) diff --git a/src/flyquery/web/controllers/agent/datasets_controller.py b/src/flyquery/web/controllers/agent/datasets_controller.py index 4de7c5ba..88e22005 100644 --- a/src/flyquery/web/controllers/agent/datasets_controller.py +++ b/src/flyquery/web/controllers/agent/datasets_controller.py @@ -1,4 +1,5 @@ # Copyright 2024-2026 Firefly Software Foundation +# SPDX-License-Identifier: Apache-2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -40,6 +41,7 @@ from flyquery.core.services.auth.agent_token_service import AgentTokenService from flyquery.interfaces.datasets import DatasetRead +from flyquery.interfaces.pagination import Paginated from flyquery.web.controllers.datasets_controller import ( DatasetsController as _UserDatasetsController, ) @@ -93,7 +95,7 @@ async def list_datasets( workspace_id: QueryParam[uuid.UUID] = None, limit: QueryParam[int] = 100, offset: QueryParam[int] = 0, - ) -> dict: + ) -> Paginated[DatasetRead]: """Search / filter datasets visible to this agent's tenant.""" await self._verify(http_request) return await self._delegate.list_datasets(