Class DemoController
java.lang.Object
ai.redouble.demo.spring.DemoController
The doors of the demo, which the page at
/ (static/index.html) walks a
person through. GET /status reports what this process can do: whether the
dispatcher runs, which providers are on the classpath and which of them hold a credential,
the catalog file it reads or the steps to write one, and the entries it loaded. POST /ask submits one job, the runtime's own
quick-question tool, under a workflow owned by the caller, waits for it and returns the
tool's output; a refusal (no provider configured for the grade asked, a missing credential)
comes back with the runtime's own message, which says what to provide. GET /skills
lists every skill the loader found on the classpath, with the resource origin each declared.
GET /agent shows the demo agent's palette and skill catalog as its model would see
them, and POST /agent runs it on a query.- Since:
- 0.1 (2026-09-11)
- Author:
- Andrey Santrosyan
-
Nested Class Summary
Nested Classes -
Constructor Summary
ConstructorsConstructorDescriptionDemoController(NucleoRuntime runtime, FileIndex index, CatalogAdmin admin, tools.jackson.databind.ObjectMapper json, DemoCorpus corpus) -
Method Summary
Modifier and TypeMethodDescriptionorg.springframework.web.servlet.mvc.method.annotation.ResponseBodyEmitteragent(AgentRequest input, Principal principal) The agent run, streamed as it happens: one JSON line per event of the run and of every job under it throughAgentTrace- the model turns with what they decided and cost, the tool calls with their arguments and results, the notes between them - ending in the answer with the run's totals, or the failure.ask(QuickLLMQuestionInput input, Principal principal) org.springframework.web.servlet.mvc.method.annotation.ResponseBodyEmitterbenchmark(BenchmarkRequest input, Principal principal) The benchmark: the demo agent wrapped in the runtime'sBenchmark, so one query runs on the strongest model this deployment serves (the reference, resolved throughGrade.CEILINGexactly as the judge is) and then on every open model of every grade this deployment can call,runstimes each, with the strongest model judging the answers blind.connect(ConnectRequest input) Credentials pasted into the page, held for this process only (SessionCredentials: a runtime property source, never a file, never echoed back), then tested right then.decide()The decision agent's objective and palette, for the page's panel.org.springframework.web.servlet.mvc.method.annotation.ResponseBodyEmitterThe decision agent run, streamed as it happens: one JSON line per event of the run and of every job under it throughDecisionTrace- each decision with the state the model was shown, the questions and every distribution it answered, each tool run with the artifact it produced - ending in the statements selected, the run's turns and its totals, or the failure.decidePrices(PricingRequest input, Principal principal) The pricing run with its grouping put to a decision model: the same doer, documents, reading tier, reconciliation and report asPOST /pricing, with the distinct product names grouped byDecideProductGroupsToolon the deployment's decision model in place of the MEDIUM model's one call.discover()The discovery, on a click instead of a terminal: the sharedCatalogAdminlists and pings only the providers whose credentials are new or changed this session, writes the result to the deployment'smodels.jsonand adopts it live.org.springframework.http.ResponseEntity<Void> docs()The embedded documentation lives underMETA-INF/resources/docs, generated into the engine jar from the reactor's own markdown at build time; static serving has no directory index, so the bare path forwards to the site's front page.One entry of the deployment's own catalog file, edited from the page: its grade, its status (OPEN or DISABLED), its input or output price, or a confirmation of its inferred facts; a null leaves the field alone.extract(ExtractRequest input, Principal principal) The demo's workflow: every file under a directory through the cheapest tier that reads it, in parallel under admission, indexed, and reported with what each cost.One grade's order of the deployment's own catalog file, set from the page or cleared.One pin of the deployment's own catalog file, set or cleared from the page: the embeddings entry or the decision entry.pricing(PricingRequest input, Principal principal) The second demo, on the first one's result: every indexed document read for the prices it states, the product names grouped by a model a grade up, and code deciding which price is current and which is superseded.search(DemoController.SearchRequest input, Principal principal) The question a person asks the directory afterwards: embedded on the same model as the index, ranked by cosine.skills()status()What the page opens with: whether the dispatcher runs, every provider with whether its credential is present and how to provide it, the catalog file this process reads (or the steps to write one), every entry it loaded, the shipped corpus's absolute path on this machine, located byDemoCorpuswherever the process runs, and the day the corpus's price story is answered for, which the pricing steps open on.
-
Constructor Details
-
DemoController
public DemoController(NucleoRuntime runtime, FileIndex index, CatalogAdmin admin, tools.jackson.databind.ObjectMapper json, DemoCorpus corpus)
-
-
Method Details
-
docs
The embedded documentation lives underMETA-INF/resources/docs, generated into the engine jar from the reactor's own markdown at build time; static serving has no directory index, so the bare path forwards to the site's front page. -
skills
-
agent
-
agent
@PostMapping(value="/agent", produces="application/x-ndjson") public org.springframework.web.servlet.mvc.method.annotation.ResponseBodyEmitter agent(@RequestBody AgentRequest input, Principal principal) The agent run, streamed as it happens: one JSON line per event of the run and of every job under it throughAgentTrace- the model turns with what they decided and cost, the tool calls with their arguments and results, the notes between them - ending in the answer with the run's totals, or the failure. The grade is the caller's: the agent declares MEDIUM, and a request naming a rung runs it there instead, the way the benchmark re-aims the same agent per candidate. -
status
What the page opens with: whether the dispatcher runs, every provider with whether its credential is present and how to provide it, the catalog file this process reads (or the steps to write one), every entry it loaded, the shipped corpus's absolute path on this machine, located byDemoCorpuswherever the process runs, and the day the corpus's price story is answered for, which the pricing steps open on. -
connect
Credentials pasted into the page, held for this process only (SessionCredentials: a runtime property source, never a file, never echoed back), then tested right then. The sharedCatalogAdminholds the rules - a deployment-configured credential is refused rather than shadowed, a session credential may be corrected - and the answer rides back with the fresh status. -
discover
The discovery, on a click instead of a terminal: the sharedCatalogAdminlists and pings only the providers whose credentials are new or changed this session, writes the result to the deployment'smodels.jsonand adopts it live. The click is the authorization: the pings spend a few cents on the newly connected accounts. -
editEntry
One entry of the deployment's own catalog file, edited from the page: its grade, its status (OPEN or DISABLED), its input or output price, or a confirmation of its inferred facts; a null leaves the field alone. A refused edit is a 400 carrying the rule it broke; an edit with no file of the deployment's own to land in is a 409. -
pin
One pin of the deployment's own catalog file, set or cleared from the page: the embeddings entry or the decision entry. -
order
One grade's order of the deployment's own catalog file, set from the page or cleared. -
ask
@PostMapping("/ask") public QuickAnswer ask(@RequestBody QuickLLMQuestionInput input, Principal principal) -
extract
@PostMapping("/extract") public ExtractReport extract(@RequestBody ExtractRequest input, Principal principal) The demo's workflow: every file under a directory through the cheapest tier that reads it, in parallel under admission, indexed, and reported with what each cost. The caller names the directory, a file cap and the run's budgets; a budget stops the run at admission, one file at a time, and the report says which. -
search
@PostMapping("/search") public List<FileIndex.Hit> search(@RequestBody DemoController.SearchRequest input, Principal principal) The question a person asks the directory afterwards: embedded on the same model as the index, ranked by cosine. -
pricing
@PostMapping("/pricing") public PricingReport pricing(@RequestBody PricingRequest input, Principal principal) The second demo, on the first one's result: every indexed document read for the prices it states, the product names grouped by a model a grade up, and code deciding which price is current and which is superseded. The report is the response. -
decidePrices
@PostMapping("/decide-prices") public PricingReport decidePrices(@RequestBody PricingRequest input, Principal principal) The pricing run with its grouping put to a decision model: the same doer, documents, reading tier, reconciliation and report asPOST /pricing, with the distinct product names grouped byDecideProductGroupsToolon the deployment's decision model in place of the MEDIUM model's one call. -
decide
The decision agent's objective and palette, for the page's panel. -
decide
@PostMapping(value="/decide", produces="application/x-ndjson") public org.springframework.web.servlet.mvc.method.annotation.ResponseBodyEmitter decide(Principal principal) The decision agent run, streamed as it happens: one JSON line per event of the run and of every job under it throughDecisionTrace- each decision with the state the model was shown, the questions and every distribution it answered, each tool run with the artifact it produced - ending in the statements selected, the run's turns and its totals, or the failure. The stream ends the way the agent's does: from the run's own terminal event, with the handle's holder ending it itself only when that event never reached the stream. -
benchmark
@PostMapping(value="/benchmark", produces="application/x-ndjson") public org.springframework.web.servlet.mvc.method.annotation.ResponseBodyEmitter benchmark(@RequestBody BenchmarkRequest input, Principal principal) The benchmark: the demo agent wrapped in the runtime'sBenchmark, so one query runs on the strongest model this deployment serves (the reference, resolved throughGrade.CEILINGexactly as the judge is) and then on every open model of every grade this deployment can call,runstimes each, with the strongest model judging the answers blind. The whole ladder races - a cross-grade pin is legal, the gate checks capability and posture, never rung - because the interesting result is exactly the spread: which cheap model holds the reference's score and which strong one is paying for nothing. The response is the race as it runs, one JSON line per event throughBenchmarkRace, ending in the reference run's answer and the report, the same one the runtime logged as a table.
-