feat(prompting): Phase C — make tool-backends config-driven (MI50-ready flip)

Enabling MI50 function-calling is now a config flip, not a code change:
cfg.tool_backends (env TOOL_BACKENDS, default "cloud") drives which backends get
tool specs. Once the MI50 llama.cpp server runs with --jinja + a tool-capable
model, set TOOL_BACKENDS="cloud,mi50" and MI50 chat drives the same tool contract
as cloud. Default unchanged (cloud-only), so this is safe with the MI50 down/
unverified — no live flip made (server is currently offline; --jinja unconfirmed).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-05 03:29:34 +00:00
parent e482ad591c
commit 800cab8d36
2 changed files with 12 additions and 6 deletions
+7 -6
View File
@@ -15,10 +15,11 @@ from lyra import tools as toolkit
from lyra.llm import Backend from lyra.llm import Backend
MAX_TOOL_ROUNDS = 5 # cap tool-call iterations per turn MAX_TOOL_ROUNDS = 5 # cap tool-call iterations per turn
# Backends that support function-calling. The MI50's llama.cpp server only does # Which backends get function-calling tools is config-driven (cfg.tool_backends,
# tools when launched with --jinja; until it is, keep tools to cloud so MI50 chat # env TOOL_BACKENDS, default "cloud"). The MI50's llama.cpp server only does tools
# doesn't 500 on the tools param. Add "mi50" here once that flag is set. # when launched with --jinja + a tool-capable model, else it 500s on the tools
TOOL_BACKENDS = {"cloud"} # param — so enabling "mi50" is a config flip once that precondition holds (Phase C),
# not a code change. See docs/superpowers/specs/2026-07-01-poker-prompts-design.md.
_TANGLED = "(I got tangled using my tools there — say that again?)" _TANGLED = "(I got tangled using my tools there — say that again?)"
@@ -97,7 +98,7 @@ def respond(session_id: str, user_msg: str, backend: Backend = "cloud",
turn = mind.assemble(session_id, user_msg, backend, model) turn = mind.assemble(session_id, user_msg, backend, model)
messages = turn.messages messages = turn.messages
tool_specs = toolkit.specs(turn.mode.tools) if backend in TOOL_BACKENDS else None tool_specs = toolkit.specs(turn.mode.tools) if backend in cfg.tool_backends else None
ctx = {"session_id": session_id, "backend": backend} ctx = {"session_id": session_id, "backend": backend}
# Persist the user turn before the tool loop so its timestamp precedes any # Persist the user turn before the tool loop so its timestamp precedes any
@@ -127,7 +128,7 @@ def respond_stream(session_id: str, user_msg: str, backend: Backend = "cloud",
turn = mind.assemble(session_id, user_msg, backend, model) turn = mind.assemble(session_id, user_msg, backend, model)
messages = turn.messages messages = turn.messages
tool_specs = toolkit.specs(turn.mode.tools) if backend in TOOL_BACKENDS else None tool_specs = toolkit.specs(turn.mode.tools) if backend in cfg.tool_backends else None
ctx = {"session_id": session_id, "backend": backend} ctx = {"session_id": session_id, "backend": backend}
mouth = _mouth_target(cfg, backend, model) mouth = _mouth_target(cfg, backend, model)
+5
View File
@@ -46,6 +46,10 @@ class Config:
# External input feed (her #1: react to the world). Comma-separated RSS/Atom URLs. # External input feed (her #1: react to the world). Comma-separated RSS/Atom URLs.
feeds: tuple[str, ...] feeds: tuple[str, ...]
feed_react_prob: float # chance a would-be new thread reacts to a feed item instead feed_react_prob: float # chance a would-be new thread reacts to a feed item instead
# Backends allowed to receive function-calling tools. Default cloud-only. Add
# "mi50" ONLY once its llama.cpp server runs with --jinja + a tool-capable model,
# else it 500s on the tools param (Phase C). Env: TOOL_BACKENDS="cloud,mi50".
tool_backends: tuple[str, ...]
def _csv(name: str, default: str) -> tuple[str, ...]: def _csv(name: str, default: str) -> tuple[str, ...]:
@@ -90,4 +94,5 @@ def load() -> Config:
mouth_model=os.getenv("MOUTH_MODEL") or None, mouth_model=os.getenv("MOUTH_MODEL") or None,
feeds=_csv("LYRA_FEEDS", "https://hnrss.org/frontpage,https://www.pokernews.com/rss.php"), feeds=_csv("LYRA_FEEDS", "https://hnrss.org/frontpage,https://www.pokernews.com/rss.php"),
feed_react_prob=float(os.getenv("FEED_REACT_PROB", "0.5")), feed_react_prob=float(os.getenv("FEED_REACT_PROB", "0.5")),
tool_backends=_csv("TOOL_BACKENDS", "cloud"),
) )