diff --git a/web/agent/src/agent.py b/web/agent/src/agent.py index afe3471..2f56376 100644 --- a/web/agent/src/agent.py +++ b/web/agent/src/agent.py @@ -87,6 +87,8 @@ Rules: 7. Use tools sparingly—one search usually suffices. 8. If you hit the search limit, end your reply with an italicized note: *Your question may be too broad. Try asking something more specific.* Do NOT mention "tools" or "tool limits"—the user doesn't know what those are.""" +SOURCES_ONLY_INSTRUCTIONS = """SOURCES ONLY MODE: Give a 1-2 sentence summary maximum. Focus on listing sources in a bulleted list. No detailed explanations.""" + def create_tool_call_limiter(max_calls: int = 3): """Create a process_tool_call callback that limits tool calls.""" @@ -110,7 +112,7 @@ def create_tool_call_limiter(max_calls: int = 3): return process_tool_call -def create_agent(user_roles: list[str] | None = None): +def create_agent(user_roles: list[str] | None = None, sources_only: bool = False): """Create an agent with MCP tools configured for the given user roles.""" toolsets = [] @@ -140,10 +142,15 @@ def create_agent(user_roles: list[str] | None = None): else: logger.info("MCP server unavailable - running without MCP tools") + # Build instructions based on mode + instructions = AGENT_INSTRUCTIONS + if sources_only: + instructions = f"{SOURCES_ONLY_INSTRUCTIONS}\n\n{AGENT_INSTRUCTIONS}" + return Agent( model="anthropic:claude-sonnet-4-5", toolsets=toolsets if toolsets else None, - instructions=AGENT_INSTRUCTIONS, + instructions=instructions, history_processors=[limit_history], model_settings=ModelSettings(max_tokens=4096), ) diff --git a/web/agent/src/main.py b/web/agent/src/main.py index e7e3d3b..c2b3dba 100644 --- a/web/agent/src/main.py +++ b/web/agent/src/main.py @@ -67,8 +67,13 @@ async def handle_agent_request(request: Request) -> Response: except json.JSONDecodeError as e: logger.warning(f"Failed to parse x-user-roles header: {e}") - # Create agent with the user's roles - agent = create_agent(user_roles) + # Extract sources-only mode from header + sources_only = request.headers.get("x-sources-only", "false") == "true" + if sources_only: + logger.info("Sources-only mode enabled") + + # Create agent with the user's roles and mode + agent = create_agent(user_roles, sources_only=sources_only) # Dispatch the request - tool limits handled by ToolCallLimiter in agent.py return await AGUIAdapter.dispatch_request( diff --git a/web/src/app/api/copilotkit/route.ts b/web/src/app/api/copilotkit/route.ts index 8c17e82..b9f6942 100644 --- a/web/src/app/api/copilotkit/route.ts +++ b/web/src/app/api/copilotkit/route.ts @@ -15,13 +15,19 @@ export const POST = async (req: NextRequest) => { const session = await auth0.getSession(); const userRoles = (session?.user?.roles as string[]) || []; - console.log("DEBUG: User roles from session:", userRoles); + // Get sources-only mode from query param + const url = new URL(req.url); + const sourcesOnly = url.searchParams.get("sourcesOnly") === "true"; - // Create HttpAgent with user roles header + console.log("DEBUG: User roles from session:", userRoles); + console.log("DEBUG: Sources only mode:", sourcesOnly); + + // Create HttpAgent with user roles and sources-only headers const agent = new HttpAgent({ url: process.env.AGENT_URL || "http://localhost:8000/", headers: { "x-user-roles": JSON.stringify(userRoles), + "x-sources-only": sourcesOnly ? "true" : "false", }, }); diff --git a/web/src/app/layout.tsx b/web/src/app/layout.tsx index a05ecb9..208f9ba 100644 --- a/web/src/app/layout.tsx +++ b/web/src/app/layout.tsx @@ -1,6 +1,5 @@ import type { Metadata } from "next"; -import { CopilotKit } from "@copilotkit/react-core"; import { Auth0Provider } from "@auth0/nextjs-auth0/client"; import "./globals.css"; import "@copilotkit/react-ui/styles.css"; @@ -19,9 +18,7 @@ export default function RootLayout({