Class DemoController

java.lang.Object
ai.redouble.demo.spring.DemoController

@RestController public class DemoController extends Object
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
    Modifier and Type
    Class
    Description
    static final record 
     
  • Constructor Summary

    Constructors
    Constructor
    Description
    DemoController(NucleoRuntime runtime, FileIndex index, CatalogAdmin admin, tools.jackson.databind.ObjectMapper json, DemoCorpus corpus)
     
  • Method Summary

    Modifier and Type
    Method
    Description
    org.springframework.web.servlet.mvc.method.annotation.ResponseBodyEmitter
    agent(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 through AgentTrace - 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.
    agent(Principal principal)
     
    ask(QuickLLMQuestionInput input, Principal principal)
     
    org.springframework.web.servlet.mvc.method.annotation.ResponseBodyEmitter
    The benchmark: the demo agent wrapped in the runtime's Benchmark, so one query runs on the strongest model this deployment serves (the reference, resolved through Grade.CEILING exactly as the judge is) and then on every open model of every grade this deployment can call, runs times each, with the strongest model judging the answers blind.
    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 decision agent's objective and palette, for the page's panel.
    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 through DecisionTrace - 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 pricing run with its grouping put to a decision model: the same doer, documents, reading tier, reconciliation and report as POST /pricing, with the distinct product names grouped by DecideProductGroupsTool on the deployment's decision model in place of the MEDIUM model's one call.
    The discovery, on a click instead of a terminal: the shared CatalogAdmin lists and pings only the providers whose credentials are new or changed this session, writes the result to the deployment's models.json and adopts it live.
    org.springframework.http.ResponseEntity<Void>
    The embedded documentation lives under META-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.
    pin(PinEdit edit)
    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.
    The question a person asks the directory afterwards: embedded on the same model as the index, ranked by cosine.
     
    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 by DemoCorpus wherever the process runs, and the day the corpus's price story is answered for, which the pricing steps open on.

    Methods inherited from class Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Constructor Details

  • Method Details

    • docs

      @GetMapping("/docs") public org.springframework.http.ResponseEntity<Void> docs()
      The embedded documentation lives under META-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

      @GetMapping("/skills") public List<SkillEntry> skills()
    • agent

      @GetMapping("/agent") public AgentCapabilities agent(Principal principal)
    • 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 through AgentTrace - 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

      @GetMapping("/status") public RuntimeStatus 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 by DemoCorpus wherever the process runs, and the day the corpus's price story is answered for, which the pricing steps open on.
    • connect

      @PostMapping("/connect") public ConnectOutcome connect(@RequestBody 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. The shared CatalogAdmin holds 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

      @PostMapping("/discover") public DiscoverOutcome discover()
      The discovery, on a click instead of a terminal: the shared CatalogAdmin lists and pings only the providers whose credentials are new or changed this session, writes the result to the deployment's models.json and adopts it live. The click is the authorization: the pings spend a few cents on the newly connected accounts.
    • editEntry

      @PostMapping("/catalog/entry") public RuntimeStatus editEntry(@RequestBody EntryEdit edit)
      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

      @PostMapping("/catalog/pin") public RuntimeStatus pin(@RequestBody PinEdit edit)
      One pin of the deployment's own catalog file, set or cleared from the page: the embeddings entry or the decision entry.
    • order

      @PostMapping("/catalog/order") public RuntimeStatus order(@RequestBody OrderEdit edit)
      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 as POST /pricing, with the distinct product names grouped by DecideProductGroupsTool on the deployment's decision model in place of the MEDIUM model's one call.
    • decide

      @GetMapping("/decide") public DecideCapabilities 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 through DecisionTrace - 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's Benchmark, so one query runs on the strongest model this deployment serves (the reference, resolved through Grade.CEILING exactly as the judge is) and then on every open model of every grade this deployment can call, runs times 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 through BenchmarkRace, ending in the reference run's answer and the report, the same one the runtime logged as a table.