Skip to content

Releases: fireflyframework/flyquery

v26.10.4

Choose a tag to compare

@github-actions github-actions released this 16 Oct 11:42
20b8d70

Table and schema reads keep the requested tenant and workspace through their parent joins. Snapshot metadata is returned only when its table, dataset, tenant and workspace match; an invalid pointer no longer exposes metadata from another scope.

The Python SDK includes AgentReadClient for bounded, GET-only dataset, table and schema-object reads. Its scope is fixed when constructed. It validates parent snapshots and rejects incomplete catalogs, redirects and oversized responses. It cannot execute queries. See the SDK guide.

Server and SDK versions are 26.10.4. Both Java JARs include the Apache license; protocol shapes and third-party dependencies are unchanged.

Validation includes passing PR CI, independent source/security review and an additional local PostgreSQL exercise of snapshot-pointer and scope boundaries. The CI report retains 15 integration and 135 Java skips. The forge adapter and prepared-result agent mirror remain separate work.

flyquery 26.10.3

Choose a tag to compare

@ancongui ancongui released this 14 Oct 21:56
89959bc

flyquery now interrupts each DuckDB execution attempt when its configured deadline expires. The budget covers queueing, setup, SQL, row fetching and copy-on-write export. Timed-out statements are recorded as FAILED with SQL state 57014; Critic does not repair this resource failure or restore an earlier success after a repair timeout.

Cancellation waits for the attempt's own worker and connection to close. Original snapshots remain unchanged, scratch output is removed even when native close reports a failure, and cleanup errors remain chained to cancellation. Transient interruption failures are retained and retried. Large positive integer budgets cannot overflow the watchdog's native wait.

This is a cooperative, per-attempt deadline—not a hard process kill or an end-to-end request SLA. Model calls, retrieval and object-store work outside the executor have separate budgets. Existing finite candidate policy, authorization, registered-file fences and the seven typed agent page APIs are preserved.

Python and Java SDK metadata report 26.10.3. The qualified framework pins and nineteen historical source contracts plus two reviewed variants remain unchanged. Operational guides explain the implemented behavior and its limits.

Validation: 467 unit tests; 111 native integrations (15 optional storage skips and one paid-model deselection); native interruption, cancellation and cleanup regressions; SDK source and fresh-installed-wheel tests; actual authenticated seven-page SDK reads; Java 25 Maven validation; lint, types and exact-source CI. Paid providers and cloud deployment were not used. Public artifact verification is recorded separately from local server qualification.

What's Changed

  • Enforce cooperative SQL deadlines and release flyquery 26.10.3 by @ancongui in #10

Full Changelog: v26.10.2...v26.10.3

flyquery 26.10.2

Choose a tag to compare

@github-actions github-actions released this 14 Oct 20:43
fafe943

flyquery 26.10.2 combines bounded query grounding, privacy fixes and adoption of fireflyframework-agentic 26.10.1. The qualified pyfly 26.06.113 runtime is retained.

  • Query grounding uses bounded column-value catalogs and relation candidates; conversation turns preserve their snapshot selections. Candidate probes pass the registered-table fence before execution.
  • Missing or unauthorized dataset scope is rejected before retrieval or model calls, with a caller-scoped audit record.
  • PII scanning checks original samples before filtering and retained profile values before embedding. Redact/reject stores an explicit empty-list denial, preventing profiles from reintroducing protected values into schema knowledge. Original source files remain unchanged.
  • FLYQUERY_PROMPT_CACHE now affects actual agent construction. Enabled mode adds Anthropic instruction-cache hints; user messages, tool results and answers are not memoized. Agentic supplies the default logging/observability middleware once.
  • Seven agent SDK list operations now deserialize their existing table, search, snapshot, object, change, dataset and conversation envelopes. Python and Java examples and response types match the API.
  • The server dependency graph is tracked in uv.lock, checked before frozen installation, with public first-party sources. Nineteen historical shared-source baselines and two reviewed service variants retain source-drift checks.

Local qualification: 451 unit tests; 109 native integration tests using PostgreSQL/pgvector, Redis and pinned-source MinIO; Python SDK 25 tests and type checks; Java 25 Maven verification. Both generated SDKs read all seven typed pages against the installed service. All fourteen changed Python and Java documentation examples compile and run against that API. Native token checks, foreign-tenant visibility, SUM60, SSE event ordering, persisted history and result Parquet contents were also checked.

Fifteen optional GCS/Azure storage scenarios remain unqualified, and paid-model tests were deliberately excluded. A nonempty executed candidate is a heuristic, not proof that its entities or filters match the question. The engine does not enforce its statement-timeout setting or provide an operating system sandbox. Remote object-store DuckDB reads are not accepted by these local registered-file tests. PII detection is limited to sampled or retained profile values and the configured scanner.

User-route authentication belongs to the deployment gateway; tenant/workspace headers select scope and are not credentials. Agent routes verify issued agent tokens and scopes.

flyquery 26.10.1

Choose a tag to compare

@ancongui ancongui released this 14 Oct 18:16
c9eebb1

Corrected Python authentication instructions

The SDK guide and package metadata now show how to send a bearer token explicitly:

api.default_headers["Authorization"] = "Bearer " + token

The generated client's current OpenAPI authentication schemes cover context headers and agent tokens; Configuration.access_token alone does not emit an Authorization header. A real TCP check confirms the documented header behavior. Configure the deployment's issuer, authentication and permissions separately.

This patch also includes the corrected streaming example: *_without_preload_content returns the raw aiohttp ClientResponse, so use stream.raise_for_status(), stream.content and stream.release().

Version alignment and compatibility

Service and Python/Java SDK metadata, user-agent/debug versions, embedded API version and current installation links now use 26.10.1. APIs, DTOs, SQL boundaries and framework pins are unchanged from 26.10.0. Its original assets and tag remain intact.

The SDK's mandatory lint, formatting, type checks and 18 HTTP/import tests pass. The built wheel contains the corrected instructions. Source CI and the publication workflow check this release before uploading its packages. No paid model-provider calls or cloud application deployments were used.

Client timeouts do not establish server-side cancellation or an operating system sandbox. Remote object-store extensions and distributed execution isolation remain separate qualification boundaries.

What's Changed

  • Correct the generated client's bearer authentication guide by @ancongui in #8
  • Publish corrected SDK authentication documentation in 26.10.1 by @ancongui in #9

Full Changelog: v26.10.0...v26.10.1

flyquery 26.10.0

Choose a tag to compare

@ancongui ancongui released this 14 Oct 17:50
be68d34

Python client and installation

The Python convenience client now passes the required tenant and workspace context when looking up or creating workspaces and datasets. Creation is attempted only after an HTTP 404. Authorization errors, server failures, transport disconnects and malformed responses propagate without an additional write. Concurrent creation conflicts remain visible as HTTP 409.

Install the Python wheel from this release:

uv add https://github.com/fireflyframework/flyquery/releases/download/v26.10.0/flyquery_sdk-26.10.0-py3-none-any.whl

Import the convenience client with from flyquery_sdk.client import FlyqueryClient. For a bearer-protected deployment, explicitly set api.default_headers["Authorization"] = "Bearer " + token on the generated ApiClient; Configuration.access_token alone is not consumed by the current OpenAPI authentication schemes. The current SDK guide includes this checked header recipe. The client installs independently of the server and its frameworks. The updated guides explain workspace UUIDs, explicit generated parameters, user and agent routes, streaming responses and the different generated/HTTPX error types. Service and client metadata use 26.10.0, including runtime headers and the embedded API contract. Existing release assets are preserved.

Registered-data SQL boundary

Read execution now restricts SQL to registered dataset views. Scope checks reject external file readers and unregistered sources, including through nested queries; registered joins and CTEs remain supported. The query path enforces this boundary before execution and before passing query material to downstream agents. Regression tests cover external-read and scope failures.

Build and verification

PR and SDK publication workflows require the Python SDK's lint, formatting, type checks and HTTP-contract tests to pass. Fresh service clones resolve pyfly and fireflyframework-agentic from published framework tags. Integration tests use a pinned official MinIO source build rather than an unavailable historical container image.

The release was checked with source and installed-wheel SDK tests, native pyfly workspace/dataset controllers and PostgreSQL repositories over TCP, SDK-only installation on Python 3.9 and 3.13, Java 25 Maven verification, and all seven service CI checks. Native Direct SQL checks also covered registered Parquet queries, rejected unregistered sources, successful and denied SSE streams, query history, persisted result objects and the workspace enable/disable setting. Original dataset snapshots remained unchanged. Framework-family banners now cover the SDK guides in desktop/mobile and light/dark variants.

Deployment boundaries

The native PostgreSQL test role bypassed RLS; that check validates repository filtering, not database RLS enforcement. The SDK's generated calls accept _request_timeout; the convenience client's constructor timeout applies to HTTPX helpers. Client timeouts do not establish server-side cancellation or an operating system sandbox. Remote object-store extensions and distributed execution isolation require separate qualification. No model-provider calls or cloud application deployments were used for this release validation.

v26.6.0

Choose a tag to compare

@github-actions github-actions released this 01 Jun 09:33
35d6ed5

What's Changed

  • Semantic layer overhaul: make every documented feature real by @ancongui in #1

New Contributors

Full Changelog: v26.5.14...v26.6.0

v26.5.14

Choose a tag to compare

@github-actions github-actions released this 31 May 20:01

flyquery 26.5.14 — Apache 2.0 open-source release

flyquery is now open source under the Apache License 2.0 (© 2024-2026 Firefly Software Foundation); the repository is public.

Changed

  • Replaced the proprietary notice with the full Apache 2.0 LICENSE (root + Python/Java SDKs) and added an Apache 2.0 header to every source file.
  • Set the OpenAPI info.license, the image licenses label, the README badge, the bundled SDK spec/setup.py, and pyproject metadata to Apache-2.0.
  • Aligned all version references to 26.5.14; refreshed the lock-step SHA pins.

SDKs

  • Python: wheel + sdist attached below.
  • Java: com.firefly:flyquery-sdk:26.5.14 on GitHub Packages.

v26.5.13

Choose a tag to compare

@github-actions github-actions released this 31 May 00:31

Full Changelog: v26.5.12...v26.5.13

v26.5.12

Choose a tag to compare

@github-actions github-actions released this 28 May 10:21

Full Changelog: v26.5.11...v26.5.12

v26.5.11

Choose a tag to compare

@ancongui ancongui released this 24 May 15:17

Added — Webhook callbacks for every async ingest job

A receiver-side push channel for the async ingest pipeline. The
caller attaches callback_url (+ optional secret + custom
headers) to POST /api/v1/ingest-jobs or to
POST /api/v1/datasets/{ds}/files:async; on terminal status
(SUCCEEDED / FAILED / CANCELLED) the worker POSTs the
canonical IngestJobRead payload to the configured URL.

  • Transactional outbox -- a new flyquery_callback_outbox table
    (migration 0013_job_callbacks) is written in the SAME transaction
    as the job's status flip. A process crash between the two writes is
    impossible, so a "succeeded" job ALWAYS has its callback queued.
  • CallbackWorker drains the outbox with FOR UPDATE SKIP LOCKED
    so N peer workers scale horizontally without colliding. Five-attempt
    exponential backoff (0s, 30s, 5m, 1h, 6h), then DEAD. New CLI
    subcommand flyquery worker callback and flyquery worker all now
    includes it alongside ingest + retention.
  • HMAC-SHA256 signing -- when a secret is provided, every
    request carries X-Flyquery-Signature: sha256=<hmac> computed over
    the raw body. Dispatcher applies reserved headers (Content-Type,
    X-Flyquery-Event, X-Flyquery-Job-Id, X-Flyquery-Signature)
    LAST so a misconfigured or malicious extra-header bag cannot shadow
    the signature header.
  • Per-request OR per-configuration -- the per-request bundle takes
    precedence, but FLYQUERY_DEFAULT_CALLBACK_URL /
    FLYQUERY_DEFAULT_CALLBACK_SECRET /
    FLYQUERY_DEFAULT_CALLBACK_HEADERS provide a process-wide default
    receiver so an operator can wire every async job to a central hub
    without touching every caller. Whole-bundle precedence (URL +
    secret + headers move together) prevents accidentally leaking the
    default secret to a different receiver.
  • GET /api/v1/ingest-jobs/{id}/callbacks -- paginated audit
    trail. One row per delivery attempt with URL, event type
    (ingest.succeeded / ingest.failed), status (PENDING /
    DELIVERED / FAILED / DEAD), attempt count, last HTTP status
    code + last error, and next scheduled retry. Supports ?status=
    filter.
  • SDK helpers:
    • Python: client.upload_async(..., callback_url=, callback_secret=, callback_headers=) + client.list_job_callbacks(job_id, ...)
      (and _sync mirrors). The auto-generated IngestJobsApi.list_callbacks
      • CallbackConfig / CallbackDeliveryRead /
        CallbackDeliveryListResponse models are also exposed.
    • Java: client.ingestJobs().listCallbacks(...) from the
      regenerated IngestJobsApi. CallbackConfig model can be set
      on IngestJobCreate.callback for createJob(...).
  • New docs: docs/callbacks.md -- full
    contract, receiver example with signature verification, retry
    schedule, ops runbook for DEAD rows. Cross-linked from
    docs/async-ingest.md + docs/workers.md.

Fixed — Critical correctness bugs surfaced by end-to-end testing

  • Publisher DI was silently in-memory -- core/configuration.py
    had a stale @bean ingest_publisher factory that called
    _resolve_eda_publisher() at factory-eval time (before
    EdaAutoConfiguration wired the EventPublisher). The factory won
    precedence over the @service registration on IngestPublisher,
    so every running process held self._publisher = None and every
    publish_ingest_requested silently hit the in-memory branch.
    Workers never received IngestRequested events; async jobs sat in
    PENDING forever and were only rescued by the orphan-PENDING
    reaper 10 minutes later. Factory deleted; the @service
    registration now resolves EventPublisher via constructor
    injection like flycanon / flyradar.
  • Pyfly DI param-name mismatches -- pyfly's resolver is name-first
    with type-fallback. IngestService(publisher: IngestPublisher, ...)
    did not match the snake-cased bean name ingest_publisher. Renamed
    to ingest_publisher on IngestService + IngestJobService. Also
    renamed repository / repo -> snake-cased bean name on
    SchemaObjectService, SchemaChangeService, RelationService,
    SemanticService, SemanticDimensionsService, WorkspaceService
    for forward-safety.
  • triggered_by="WORKER" violated ck_snapshots_trigger -- the
    CHECK constraint accepts only USER / AGENT / SCHEDULED /
    REPARSE. Every async PARSE_AND_INGEST job failed at reconcile
    with CheckViolationError. Worker now writes REPARSE for the
    by-worker path (workers.py:488).
  • governance_json / synonyms_json DTO polymorphism -- legacy
    rows from a prior NULL || dict jsonb-concat bug stored
    governance_json as [null, {...}]. The DTO had been widened to
    dict | list | None as a band-aid; that ambiguity leaked into
    every consumer and broke GET /tables/{id}/objects with a Pydantic
    422. Fixed properly:
    • DTOs tightened to synonyms_json: list[str] /
      governance_json: dict[str, Any].
    • New normaliser core/services/storage/jsonb_normalize.py coerces
      any historical shape to canonical at every consumer + producer
      seam (DTO field_validator + reconcile stage write path).
    • Migration 0012_normalize_jsonb_shapes heals existing polluted
      rows.
  • flyquery_examples insert syntax -- :embedding::vector
    confused SQLAlchemy's bind parser (text parsed the second : as a
    new bind), so asyncpg received a literal :embedding token and
    raised PostgresSyntaxError. Every successful NL query crashed
    with a 500 after the SQL executed (auto-learning save path).
    Changed to CAST(:embedding AS vector).
  • CallbackWorker triggered pyfly's ApplicationRunner convention
    -- a bean method named run() is auto-invoked at API startup with
    a positional args parameter. Renamed to run_forever() so the
    callback drain runs ONLY under the dedicated CLI command.
  • Callback dispatcher header ordering -- caller-supplied extra
    headers were applied AFTER our reserved keys, allowing
    extra_headers={"X-Flyquery-Signature": "evil"} to shadow the real
    signature. Reversed: reserved keys are applied LAST.

Changed

  • POST /api/v1/ingest-jobs now declares its request body via
    Valid[Body[IngestJobCreate]] (was: manual request.json() decode).
    This publishes IngestJobCreate + the nested CallbackConfig
    schemas into openapi.json so SDK generators see them. Wire
    contract unchanged; existing 200/422 behaviour identical.
  • pyfly.yaml, pyproject.toml, Taskfile.yml, both SDK
    pyproject.toml / setup.py / pom.xml / build.gradle, README
    badge, and app.py decorator all now read 26.5.11. (Also fixed
    the app.py drift from 26.5.0.)

Full Changelog: v26.5.10...v26.5.11