Skip to content

utils.llm.call_llm silently falls back to fake provider — Copilot provider never registered at boot #33

Description

@kody-w

Summary

utils/llm.py exposes a clean call_llm() helper that's meant to let plug-in agents share the brainstem's authenticated Copilot session. But brainstem.py never calls register_copilot_provider() at boot, so _copilot_token_provider stays None, detect_provider() falls through to chat_fake, and any agent that calls call_llm gets the prompt echoed back as text instead of an LLM response.

How to reproduce

  1. Start the brainstem normally (python brainstem.py).
  2. From any plugin agent, call:
    from utils.llm import call_llm
    print(call_llm([{"role":"user","content":"say hi"}]))
  3. Observe output: fake-llm: say hi instead of a real model response.

Root cause

utils/llm.py line ~44–55 defines register_copilot_provider(token_getter, default_model) and a module-level _copilot_token_provider = None. detect_provider() only returns "copilot" if that variable is set. Nothing in brainstem.py ever sets it — brainstem.py calls its own internal call_copilot() directly.

Impact

This is the silent killer behind the second issue I'm about to file (LearnNew shelling out to a nonexistent CLI). Every plug-in agent that wanted to share the brainstem's session is hitting the fake provider without warning. The fake response (fake-llm: <prompt>) is then injected into generated code as if it were real, producing files with the prompt baked into the function body as a syntax error.

Suggested fix

In brainstem.py at the boot section (after load_soul() and before load_agents()), register the provider:

try:
    from utils.llm import register_copilot_provider as _reg_copilot

    def _llm_token_getter():
        tok, ep = get_copilot_token()
        return tok, ep

    _reg_copilot(_llm_token_getter, default_model=MODEL)
    _tlog("llm.copilot_registered", {"model": MODEL})
except Exception as _llm_err:
    _tlog("llm.copilot_register_failed", {"error": str(_llm_err)}, level="warn")

Also call it inside set_model() so the registered default tracks runtime model switches.

Environment

  • RAPP brainstem 0.15.9
  • macOS 14, Python 3.11 venv
  • Copilot session authenticated via device code

I patched this locally and confirmed LearnNew's body generator (issue #2) starts producing real code afterward.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions