Class CatalogDiscovery
models.json with the account's
observed limits plus a report of everything that was learned and everything that was not.
Sources, in order of trust: the deployment's previous file (its entries, pins and hand-set fields are kept), the shipped fragments (the seed: public facts and entry-tier limits for every model the providers serve), the listings (which of those the account can see, plus quotas and retention where the provider publishes them), and the pings (does the call succeed now, and what limits do the response headers carry). Nothing is invented: a listed model no source knows is reported as unknown with its raw listing, for a person to add.
Per provider: not configured means its seed entries are left out and the report names
the credential to provide; a provider that cannot list (ModelDiscovery not
implemented) has its seed entries pinged blind; a listing failure is reported verbatim and
treated the same way, except the one that says everything: a listing that fails because the
provider's endpoint is not served where this deployment points (an unknown host, which no
retry changes) leaves the provider's seed entries out and closes its entries from the
previous file as UNREACHABLE, without a ping. Per entry: not listed by a provider
that did list means dropped, unless it came from the previous file, which is never shrunk
because history still prices against it, and closed as UNLISTED; reachable means
kept with the observed limits; unreachable means dropped for a seed entry and kept, closed
as UNREACHABLE, for a previous one. Kept is kept: a closed entry is in the file for
the runs it served, and nothing picks it until a later run reopens it. A ping that fails for a reason that says nothing
about the entry (overload, throttling, a 5xx) is repeated a few times, and an entry still
unanswered is kept with the limits it had and flagged unverified, never dropped on a bad
minute. A seed entry naming a model through another geography's profile (us. in a
region that lists eu.), or through a bare on-demand id where the region has a
profile for the model, is rewritten to the profile this region lists, pinged as rewritten,
and reported as such; the catalog id stays, global. ids are the same everywhere and
stay. Providers and entries are visited in order, one at a time, so two runs against the
same account read the same.
Run it from a classpath that carries the provider artifacts and the credentials:
java -cp ... ai.redouble.nucleo.harness.models.discovery.CatalogDiscovery [--out models.json] [--report-only].
The result is validated by loading it through JsonModelsBackend before it is written.
- Since:
- 0.1 (2026-09-12)
- Author:
- Andrey Santrosyan
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic final recordWhat happened with one catalog entry.static final recordWhat happened with one provider.static enumWhat happened with one provider.static final recordThe whole run: the catalog to write, the report to read, and the facts both were made from.static enumWhat a run decided about one entry. -
Method Summary
Modifier and TypeMethodDescriptionstatic voidThe command without the seal: parse the arguments, run, print the report, write the file unless told not to.static voidstatic DefaultComplianceEnvelopeThe envelope a discovery process runs under: every posture permitted, the default with its one knob open.static CatalogDiscovery.Resultrun(boolean includeOlder) The real thing: shipped fragments, the deployment's file if any, every provider on the classpath, live pings.static CatalogDiscovery.ResultThe discovery over part of the classpath's providers: the named keys are re-listed and re-pinged, and every other provider's previous entries ride through exactly as they are - out of scope, never dropped, never pinged.
-
Method Details
-
run
The real thing: shipped fragments, the deployment's file if any, every provider on the classpath, live pings. The discovery's question is what the ACCOUNT can call, so the process it runs in must permit every retention posture; which of those an application may then use is that application's compliance envelope, sealed in its own process. The seal is the host's:main(String[])sealspermitting()when the discovery is the process, and a harness that boots an application to reach its credential store seals it through that application's servlet before callingexecute(String[]). -
run
The discovery over part of the classpath's providers: the named keys are re-listed and re-pinged, and every other provider's previous entries ride through exactly as they are - out of scope, never dropped, never pinged. For a caller that discovers incrementally as credentials arrive, paying only for what changed. Null means every provider. -
permitting
The envelope a discovery process runs under: every posture permitted, the default with its one knob open. -
main
- Throws:
IOException
-
execute
The command without the seal: parse the arguments, run, print the report, write the file unless told not to. The file written is the one--outnames, else the one-Dnucleo.modelsnames; the runtime reads its catalog off the classpath, so where the written file goes to be read - an application'ssrc/main/resources- is the caller's.- Throws:
IOException
-