feat: per-role tool lists and system prompt overlays
Each role in model_registry.json can now carry two optional keys:
system_append — injected into the system prompt at position 7 (after
memory, closest to the turn) for the active chat_role
tools — explicit tool allow-list; intersected with the user's
access-level filter so it can only restrict, never elevate
No changes needed for existing users — missing keys fall back to current
behavior. Add keys to a role to give it a specialty focus:
"coder": {
"primary": "claude_cli",
"system_append": "You are in code-specialist mode...",
"tools": ["web_search", "file_read", "shell_exec", "scratch_write"]
}
Changes:
- model_registry.py: get_role_config() returns system_append + tools
- context_loader.py: role_append param appended as "--- Role Context ---"
- tools/__init__.py: get_tools_for_role/get_openai_tools_for_role accept
optional tool_list and intersect with access-level filter
- orchestrator_engine.py: tool_list threaded through run/resume/checkpoint
- openai_orchestrator.py: tool_list threaded through run/resume/checkpoint;
_build_client now calls get_openai_tools_for_role instead of returning
unfiltered OPENAI_TOOL_SCHEMAS
- routers/orchestrator.py: pulls role_cfg for chat_role, passes both
role_append and tool_list to context loader and engine
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -196,11 +196,13 @@ async def _run_job(job_id: str, req: OrchestrateRequest, user: str) -> None:
|
||||
from session_store import load as load_session, save as save_session, generate_session_id
|
||||
|
||||
tier = req.tier or settings.default_tier
|
||||
role_cfg = model_registry.get_role_config(user, req.chat_role)
|
||||
system_prompt = load_context(
|
||||
tier,
|
||||
include_long=req.include_long,
|
||||
include_mid=req.include_mid,
|
||||
include_short=req.include_short,
|
||||
role_append=role_cfg.get("system_append", ""),
|
||||
)
|
||||
|
||||
session_id = req.session_id or generate_session_id()
|
||||
@@ -209,6 +211,7 @@ async def _run_job(job_id: str, req: OrchestrateRequest, user: str) -> None:
|
||||
|
||||
orch_model = model_registry.get_model_for_role(user, "orchestrator")
|
||||
user_role = get_user_role(user)
|
||||
tool_list = role_cfg.get("tools")
|
||||
|
||||
policy = get_tool_policy(user)
|
||||
confirm_allow = set(policy.get("allow", []))
|
||||
@@ -222,6 +225,7 @@ async def _run_job(job_id: str, req: OrchestrateRequest, user: str) -> None:
|
||||
model_cfg=orch_model,
|
||||
respond_with_final=req.respond_with_claude,
|
||||
user_role=user_role,
|
||||
tool_list=tool_list,
|
||||
confirm_allow=confirm_allow,
|
||||
confirm_deny=confirm_deny,
|
||||
)
|
||||
@@ -239,6 +243,7 @@ async def _run_job(job_id: str, req: OrchestrateRequest, user: str) -> None:
|
||||
model_name=orch_model.get("model_name") if orch_model else None,
|
||||
response_role=req.chat_role,
|
||||
user_role=user_role,
|
||||
tool_list=tool_list,
|
||||
confirm_allow=confirm_allow,
|
||||
confirm_deny=confirm_deny,
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user