Files
recflare/apps/ai
Devin Zuczek 11b037a2f1 more stubs
2026-08-15 13:54:34 -04:00
..
2026-08-15 13:54:34 -04:00
2026-08-15 13:54:34 -04:00
2026-08-15 13:54:34 -04:00
2026-08-15 13:54:34 -04:00
2026-08-15 13:54:34 -04:00
2026-08-15 13:54:34 -04:00
2026-08-15 13:54:34 -04:00
2026-08-15 13:54:34 -04:00

ai

AI worker served on the ai subdomain (ai.recflare.net). The client checks here before offering any of its AI features.

  • GET / — service status { "service": "ai", "status": "ok" }. No auth.

  • GET /gameai/user/access?roomId=<id>[Authorize]. Whether the caller may use Game AI in a room. Always refused:

    {
      "success": false,
      "error_id": "AI.RoomDoesNotSupportGameAI",
      "error": "This room does not support Rec Room Game AI"
    }
    

    No model runs behind this worker, so every room gets that answer. Two things about it are deliberate: it is a 200, not a 4xx (the client branches on success in the body; an error status would surface as a failed request rather than the "not available here" state this is), and roomId is ignored while the token is still validated first, as the reference server does — so an unauthenticated caller gets a 401 rather than the refusal.

  • GET /roomieai/user/access[Authorize]. Roomie AI's energy budget, granted in full:

    {
      "success": true,
      "error_id": null,
      "error": null,
      "value": {
        "MaxEnergyFromSubscriptions": 2147483647,
        "EnergyLeft": 2147483647,
        "NextSubscriptionEnergyRechargeAt": null,
        "OutputAudioEnabled": true
      }
    }
    

    Granted rather than refused because Roomie runs on the CLIENT and only asks this service how much energy it may spend — so for a server that meters nothing, "as much as you can count" is the honest answer. That number is int.MaxValue: the client's field is a signed 32-bit int, and anything larger overflows on the way in and reads as negative, i.e. no energy at all. Nothing depletes, so nothing recharges — hence the null NextSubscriptionEnergyRechargeAt.

    Note the envelope: { success, error_id, error, value }, not the flat body the Game AI check answers with. The two shapes are different on purpose; don't unify them.

The worker exists so the client gets a definite answer on the host its endpoints document already names (AIai, see apps/ns), instead of a failed request to a host with nothing behind it.

API documentation

GET /openapi.json serves a spec generated from describeRoute blocks that sit alongside each handler, with the schemas in src/openapi.ts. It's also aggregated into the docs page www serves at /docs. A test asserts every route appears in it.

The spec is descriptive, not enforced — same rationale as the other workers: a reverse-engineered protocol, lenient handlers, no runtime validation.

Development

Run in dev mode

pnpm dev

Run tests

pnpm test

Deploy

pnpm turbo deploy