GenAI assistant
GenAI assistant — proxy natural-language questions to an external AI service. API-only today; configuration, contract, and operator caveats.
The GenAI assistant is an opt-in feature that lets the ODD Platform proxy natural-language questions to an external AI service that the operator deploys and operates separately. The platform itself does not embed an LLM; it forwards the question, waits for a response, and returns it through its API.
The feature is disabled by default (genai.enabled: false) and is API-only today — the generated TypeScript client (GenaiApi.ts, GenAIRequest.ts, GenAIResponse.ts) ships with the platform UI, but no in-app affordance currently calls it. Operators who turn this on either drive it from their own UI / scripts against the platform's /api/genai/ask endpoint, or wait for a future UI surface.
What gets proxied
Each call from the operator → platform → external AI service has this shape:
[client] → POST /api/genai/ask (JSON: {"body": "<question text>"})
→ platform forwards to: POST {genai.url}/query_data
(JSON: {"question": "<question text>"})
← external service returns raw JSON-encoded string
← platform un-quotes + Java-unescapes, returns JSON: {"body": "<answer>"}
[client] ← 200 OK (JSON: {"body": "<answer>"})The platform does not modify the question text it forwards (just rewraps it from body → question). Any catalog context, retrieval-augmentation, or prompt construction must happen inside the external AI service — the platform is a thin proxy.
Configuration
The three genai.* keys (enabled, url, request_timeout), their defaults, the silent-misconfiguration warning when enabled=true is set without url and request_timeout, the working YAML / environment-variable example, and the platform-restart requirement when any of the three change all live on the operator-facing configuration reference at Configure ODD Platform → GenAI Configuration. That page is the canonical home for the platform's configuration keys; this page links rather than embedding so the two surfaces never drift.
External AI service contract
When genai.enabled=true, the platform's genAiWebClient is configured at startup with baseUrl = genai.url and responseTimeout = Duration.ofMinutes(genai.request_timeout). Each call from /api/genai/ask forwards to the external service as:
Method:
POSTPath:
{genai.url}/query_data(the/query_datasuffix is fixed inGenAIServiceImpl.java:22)Headers: none added by the platform (default WebClient headers; no auth, no API key)
Request body (
application/json):Response body (the platform expects
application/json): a raw JSON-encoded string — that is, the response payload is a single JSON string value (with leading and trailing"quotes). The platform strips the outer quotes viaCharMatcher.is('"').trimFrom(item)and then runsStringEscapeUtils.unescapeJava(...)to interpret embedded escape sequences (\",\n, etc.) before placing the result in theGenAIResponse.bodyfield.
A minimal-but-conforming AI service implementation in Python (Flask), for reference:
The platform sends no authentication to the external service. If the service must reject anonymous traffic, deploy it behind a network policy / mesh / ingress that authenticates / restricts callers — there is no genai.token or similar in GenAIProperties today. The external service is also fully responsible for prompt construction, catalog-aware retrieval, and rate limiting; the platform forwards questions verbatim and returns whatever the service returns.
Platform endpoint
The platform's GenAI surface is a single endpoint:
POST
/api/genai/ask
genAiQuestion
Forward a question to the configured external AI service and return its answer.
Request schema (GenAIRequest):
Response schema (GenAIResponse):
When genai.enabled=false, the endpoint responds with a BadUserRequestException carrying the message "Gen AI is disabled" (HTTP 400) — operators get a clear error rather than a silent no-op.
When the external service times out, the endpoint responds with a GenAIException carrying "Gen AI request take longer that {minutes} min" (HTTP 500) — the timeout duration in the message is the configured genai.request_timeout value, so operators see exactly what they configured.
For non-timeout errors from the external service (HTTP 5xx, connection refused, malformed response), the platform wraps the underlying cause in a GenAIException (HTTP 500) and surfaces it on the /api/genai/ask response. There is no retry loop; a single attempt per request.
UI status
API-only today. The platform UI ships generated clients (odd-platform-ui/src/generated-sources/apis/GenaiApi.ts plus the request/response models) but no view, button, or panel currently calls them — verified via grep across odd-platform-ui/src/ excluding generated-sources/. To use the feature, drive POST /api/genai/ask from your own client (curl, an internal app, a custom in-platform fork). When a UI affordance ships, this section will be updated.
Known limitations
@ConfigurationPropertiesdefaults bite when onlygenai.enabledis set.urldefaults tonull(no field initializer inGenAIProperties.java) andrequest_timeoutdefaults to0(= immediate timeout). The platform accepts the misconfiguration at startup and fails at first request. Setgenai.urlandgenai.request_timeoutexplicitly when enabling — the operator-side guidance lives on Configure ODD Platform → GenAI Configuration. The upstream-side improvement (defaults declared inGenAIPropertiesor a startup validation) is queued as a separate platform issue.No authentication to the external service. If the external AI must reject anonymous callers, do it at the network layer (mesh, ingress, NetworkPolicy) — there is no per-request auth header or token added by the platform.
No retries. A single
POST /query_dataper/api/genai/askinvocation. The external service must be reliable enough that a single attempt is acceptable, or operators must add retry / circuit-breaker logic upstream of the platform's caller.request_timeoutis in minutes (not seconds, not milliseconds). The minimum effective value is 1 minute; setting0means immediate timeout (see above).Bean is built once at startup.
WebClientConfigurationreadsgenai.urlandgenai.request_timeoutto construct thegenAiWebClientbean — changing those values requires a Platform restart for the new WebClient to pick them up.No UI today. Generated TypeScript clients exist but are not wired into any view; the feature is callable only via the API.
Where to next
Configure ODD Platform → GenAI — the same three keys in the platform's full configuration reference, with environment-variable equivalents.
Main Concepts → AI aspects — where GenAI sits among the other AI capabilities (data profiling, ML lineage).
POST /api/genai/ask(operationIdgenAiQuestion, taggenai) — the request/response shape and verb live inopendatadiscovery/odd-platform-specification → openapi.yaml.
Last updated