Skip to content

feat: Conditional queries and schema v3 - #15

Merged
shackmann merged 3 commits into
mainfrom
stefan/agents
Sep 21, 2026
Merged

shackmann merged 3 commits into
mainfrom
stefan/agents

Conversation

@shackmann

@shackmann shackmann commented Sep 21, 2026

Copy link
Copy Markdown
Collaborator

Summary

Adds the condition query mode to the SDK and moves the supported service schema from v2 to v3. A caller can now ask the deployment for the joint distribution at one future position given pinned or bounded values of some columns at that same position, through forecast() and all three high-level helpers.

What changes

Public contract (contract.py)

  • SCHEMA_VERSION is v3. The SDK supports exactly one schema, so v2 deployments are refused by validate_service_metadata() after this lands.
  • QueryMode gains condition; new ConditionKind (equality, interval) and SUPPORTED_CONDITION_KINDS.
  • New request types: EqualityCondition(column, value), IntervalCondition(column, lower, upper), and ConditionBlock(query_time_index, conditions). Each validates itself on construction (finite numbers, lower < upper, at least one bound, one condition per column).
  • ForecastRequest accepts condition. It requires query_mode="condition" and the block to go together, and checks the block against the request's own schema and query_times before any round trip: undeclared columns, an index outside the requested horizons, conditioning every column, and pinned columns listed in requested_columns all fail locally.
  • New response types: ConditionPlausibility (equality_log_density, region_log_probability) and IntervalEstimator (points, effective_sample_size). ForecastResponse.plausibility is None on forecast responses. ForecastDiagnostics gains condition_draws and interval_estimator. Condition responses carry only the conditioned position in outputs.query_times.
  • require_condition_support(metadata, block) refuses a block whose mode or kinds the deployment does not advertise, raising UnsupportedServiceContractError before the request is sent.
  • Two new structured error codes: UNSUPPORTED_HEAD_QUERY_COMBINATION and UNSUPPORTED_RETURN_MODE.

Health metadata validation

  • supported_query_modes was required to equal the SDK's list. It is now a non-empty subset, because the service derives the modes from the mounted head and a head that cannot condition legitimately advertises fewer.
  • HealthMetadata gains supported_condition_kinds, a possibly empty subset of the SDK's kinds. The field is required in /healthz; a payload without it fails validation. An advertised value the SDK does not know is still a contract mismatch.

Client (client.py, adapters.py)

  • forecast, forecast_mean, forecast_samples, forecast_quantiles, and build_forecast_payload_from_dataframe accept condition. Passing it sets query_mode="condition"; the client checks the cached /healthz advertisement first.
  • Batched sample requests merge into one conditional answer: condition_draws reports the merged count and plausibility is carried from the first batch, since every batch answers the same request.

Docs and samples

  • README gains a "Conditional Queries" section; the API reference documents the new types, request and response fields, and health fields.
  • New notebooks/forecast_condition.ipynb walks through an equality pin, reading the plausibility, and a mixed equality-plus-interval request.
  • .env.sample, config.sample.yaml, and all fixtures move to v3; health_metadata.json advertises supported_condition_kinds: [].
  • AGENTS.md adds the rule to present comparable items as a Markdown table.

Tests

  • New tests/test_condition_mode.py covers block validation, request-level checks, payload shape, the capability gate, response parsing for both kinds, the client round trip through a fake transport, batched sample merging, the DataFrame adapter, and health-metadata rejection of unknown advertisements.
  • New fixtures: condition_mean_request.json, condition_mean_response.json, condition_interval_response.json.
  • Existing tests updated for the v3 pin and the new health field.

Behavior changes to note for reviewers

  • Deployments still serving schema v2, or whose /healthz lacks supported_condition_kinds, are refused by this SDK version.
  • supported_query_modes validation is relaxed from exact match to subset.

Note

Medium Risk
Breaking schema pin and stricter health field requirements reject older deployments; request/response contract changes affect all predict paths but are guarded by local validation and extensive tests.

Overview
Bumps the SDK’s supported JointFM service contract from schema_version v2 to v3 across configuration samples, docs, and fixtures. Callers must pin JOINTFM_SCHEMA_VERSION=v3; services still on v2 or health payloads missing supported_condition_kinds fail compatibility checks.

Adds the condition query mode so forecasts can target the joint distribution at a single future step given equality pins or interval bounds on other columns at that step. New public types (ConditionBlock, EqualityCondition, IntervalCondition, plausibility/diagnostic types) validate requests locally, serialize into predict payloads, and parse responses including plausibility and condition-specific diagnostics. forecast, the forecast_* helpers, and build_forecast_payload_from_dataframe accept optional condition; the client calls require_condition_support against cached /healthz before posting.

Relaxes health advertisement rules for head-derived capabilities: supported_query_modes and supported_condition_kinds must be non-empty (where required) subsets of what the SDK knows, not exact equality. New structured error codes and docs/notebook (forecast_condition.ipynb) cover the feature; AGENTS.md adds guidance to present comparable items as tables.

Reviewed by Cursor Bugbot for commit aca06f8. Configure here.

Accept a ConditionBlock on forecast_mean, forecast_samples, and
forecast_quantiles so conditional queries reach every high-level
surface, not only forecast(). Document conditional queries in the
README and API reference, add the forecast_condition notebook, and
move the sample env schema pin to v3.
@shackmann
shackmann merged commit 4c038d5 into main Sep 21, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant