Persist discovered AI endpoint models in the database per endpoint.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-20 12:13:56 +02:00
parent 2d6fcafc7e
commit c80b5d680d
10 changed files with 222 additions and 35 deletions

View File

@@ -354,7 +354,18 @@ rule RefreshEndpointModels {
requires: url != ""
requires: kind = airplane or api_key != null
-- Discovery calls GET /models and does not require a selected model.
-- On success the discovered list replaces the persisted models for
-- this endpoint kind.
ensures: EndpointModelsLoaded(kind)
ensures: EndpointModelsPersisted(kind)
}
invariant EndpointModelPersistence {
-- Discovered endpoint models are persisted per endpoint kind
-- (online and airplane independently) and survive application
-- restart. Model dropdowns (settings and chat) are populated from
-- the persisted list; it is only overwritten by the next
-- successful RefreshEndpointModels for the same kind.
}
rule TestEndpointModels {

View File

@@ -299,6 +299,21 @@ entity AiCatalogMeta {
value: String
}
entity AiEndpointModel {
-- Models discovered via GET /models on a configured endpoint.
-- Composite primary key: (kind, model_id).
-- Persisted per endpoint kind; replaced wholesale on the next
-- successful refresh for that kind, never cleared otherwise.
kind: String -- "online" | "airplane"
model_id: String
label: String
context_window: Integer?
max_output_tokens: Integer?
supports_tools: Boolean
supports_vision: Boolean
updated_at: Timestamp
}
-- ============================================================================
-- EMBEDDINGS TABLES
-- ============================================================================
@@ -580,6 +595,20 @@ surface AiCatalogMetaRecordSurface {
meta.value
}
surface AiEndpointModelRecordSurface {
context endpoint_model: AiEndpointModel
exposes:
endpoint_model.kind
endpoint_model.model_id
endpoint_model.label
endpoint_model.context_window when endpoint_model.context_window != null
endpoint_model.max_output_tokens when endpoint_model.max_output_tokens != null
endpoint_model.supports_tools
endpoint_model.supports_vision
endpoint_model.updated_at
}
surface EmbeddingKeyRecordSurface {
context key: EmbeddingKey