v2.4.1-sidecar-routing: route per-agent flags to llama-sidecar + tool gap fix

Batch 3c: when an agent has llama_extra_args in AGENTS.md, provider.ts
routes inference through LLAMA_SIDECAR_URL instead of LLAMA_SWAP_URL.
X-Agent-Flags header built from the agent's flags. Boot-time guard
refuses to start if any agent has llama_extra_args but LLAMA_SIDECAR_URL
is unset. PrefixFingerprint gains a route field (swap/sidecar) for
per-turn visibility. 9 provider tests.

AGENTS.md tool gap: all agents (except Prompt Builder) were missing 8
tools that were added after the original tool lists were written:
request_read_access, view_truncated_output, ask_user_input, git_status,
get_blast_radius, get_hot_files, get_middleware, get_routes. The missing
request_read_access caused silent "permission denied" when reading files
outside the project root.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-27 19:28:08 +00:00
parent 90a6761b07
commit bcfc94fa47
8 changed files with 155 additions and 26 deletions

View File

@@ -21,6 +21,7 @@ import { createHash } from 'node:crypto';
import { readFile, stat } from 'node:fs/promises';
import type { Agent, Project, Session } from '../types/api.js';
import { getAgentsMtimes } from './agents.js';
import { resolveRoute } from './inference/provider.js';
const BASE_SYSTEM_PROMPT = (projectPath: string) =>
`You are BooCode Chat, a code investigation assistant. The user is working on a project located at ${projectPath}. Use the file-read tools (view_file, list_dir, grep, find_files) to investigate code when needed. Be concise. Cite file paths and line numbers when discussing code. Do not hallucinate file contents — read the file first. Tool results may be truncated; if so, narrow your query rather than guessing.`;
@@ -98,6 +99,7 @@ export interface PrefixFingerprint {
has_agent_system_prompt: boolean;
has_session_override: boolean;
has_project_override: boolean;
route: 'swap' | 'sidecar';
}
export interface PrefixDrift {
@@ -125,6 +127,7 @@ interface ObservedInputs {
has_agent_system_prompt: boolean;
has_session_override: boolean;
has_project_override: boolean;
route: 'swap' | 'sidecar';
}
interface ObserverEntry {
@@ -183,6 +186,7 @@ export async function buildSystemPromptWithFingerprint(
has_agent_system_prompt: !!(agent && agent.system_prompt.trim().length > 0),
has_session_override: sessionPrompt.length > 0,
has_project_override: projectPrompt.length > 0,
route: resolveRoute(agent).route,
};
const fingerprint: PrefixFingerprint = {
@@ -199,6 +203,7 @@ export async function buildSystemPromptWithFingerprint(
has_agent_system_prompt: inputs.has_agent_system_prompt,
has_session_override: inputs.has_session_override,
has_project_override: inputs.has_project_override,
route: inputs.route,
};
let drift: PrefixDrift | null = null;