Unverified 提交 5bd8a703 authored 作者: Will Chen's avatar Will Chen 提交者: GitHub

Enable type check tool by default (agent mode) and allow "never" for agent tool perms (#2165)

<!-- CURSOR_SUMMARY --> > [!NOTE] > - **Agent tool consent:** Add `"never"` to `AgentToolConsent` schema, update imports to `lib/schemas`, surface "Never allow" in settings UI, and prevent consent prompts/execution for tools marked `"never"` (skipped in `buildAgentToolSet`; error if prompted). > - **Type checks tool:** Remove settings gate so `run_type_checks` is available by default; keep default consent `"always"`; reflected in e2e tool list. > - **UI/UX:** Truncate long tool descriptions to 100 chars in Agent Tools settings. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 50e3ef56792adc578aaefcdf7a61246344a475ad. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> <!-- This is an auto-generated description by cubic. --> --- ## Summary by cubic Enables the Type Checks tool by default in agent mode and adds a “never” consent option to permanently block tools. Agents now skip any tool marked “never”. - **New Features** - Added “Never allow” in Agent Tools settings. - Consent schema now supports ask, always, never. - Agent tool set excludes tools with “never”. - Type Checks tool is available by default (no longer gated by enableAutoFixProblems). - Truncated long tool descriptions in settings to 100 chars. - **Refactors** - Moved AgentToolConsent type to lib/schemas and updated imports. <sup>Written for commit 50e3ef56792adc578aaefcdf7a61246344a475ad. Summary will update on new commits.</sup> <!-- End of auto-generated description by cubic. -->
上级 5e71af36
...@@ -409,6 +409,27 @@ ...@@ -409,6 +409,27 @@
"$schema": "http://json-schema.org/draft-07/schema#" "$schema": "http://json-schema.org/draft-07/schema#"
} }
} }
},
{
"type": "function",
"function": {
"name": "run_type_checks",
"description": "Run TypeScript type checks on the current workspace. You can provide paths to specific files or directories, or omit the argument to get diagnostics for all files.\n\n- If a file path is provided, returns diagnostics for that file only\n- If a directory path is provided, returns diagnostics for all files within that directory\n- If no path is provided, returns diagnostics for all files in the workspace\n- This tool can return type errors that were already present before your edits, so avoid calling it with a very wide scope of files\n- NEVER call this tool on a file unless you've edited it or are about to edit it",
"parameters": {
"type": "object",
"properties": {
"paths": {
"type": "array",
"items": {
"type": "string"
},
"description": "Optional. An array of paths to files or directories to read type errors for. If provided, returns diagnostics for the specified files/directories only. If not provided, returns diagnostics for all files in the workspace."
}
},
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}
}
} }
], ],
"tool_choice": "auto", "tool_choice": "auto",
......
...@@ -13,7 +13,7 @@ import { ...@@ -13,7 +13,7 @@ import {
type AgentTool, type AgentTool,
} from "@/hooks/useAgentTools"; } from "@/hooks/useAgentTools";
import { Loader2, ChevronRight } from "lucide-react"; import { Loader2, ChevronRight } from "lucide-react";
import type { AgentToolConsent } from "@/ipc/ipc_types"; import { AgentToolConsent } from "@/lib/schemas";
export function AgentToolsSettings() { export function AgentToolsSettings() {
const { tools, isLoading, setConsent } = useAgentTools(); const { tools, isLoading, setConsent } = useAgentTools();
...@@ -109,7 +109,7 @@ function ToolConsentRow({ ...@@ -109,7 +109,7 @@ function ToolConsentRow({
<div className="min-w-0 flex-1"> <div className="min-w-0 flex-1">
<div className="font-mono text-sm">{name}</div> <div className="font-mono text-sm">{name}</div>
<div className="text-xs text-muted-foreground truncate"> <div className="text-xs text-muted-foreground truncate">
{description} {description?.slice(0, 100)} {description?.length > 100 && "..."}
</div> </div>
</div> </div>
<Select <Select
...@@ -122,6 +122,7 @@ function ToolConsentRow({ ...@@ -122,6 +122,7 @@ function ToolConsentRow({
<SelectContent> <SelectContent>
<SelectItem value="ask">Ask</SelectItem> <SelectItem value="ask">Ask</SelectItem>
<SelectItem value="always">Always allow</SelectItem> <SelectItem value="always">Always allow</SelectItem>
<SelectItem value="never">Never allow</SelectItem>
</SelectContent> </SelectContent>
</Select> </Select>
</div> </div>
......
...@@ -6,7 +6,7 @@ import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query"; ...@@ -6,7 +6,7 @@ import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
import { IpcClient } from "@/ipc/ipc_client"; import { IpcClient } from "@/ipc/ipc_client";
import type { AgentToolName } from "../pro/main/ipc/handlers/local_agent/tool_definitions"; import type { AgentToolName } from "../pro/main/ipc/handlers/local_agent/tool_definitions";
import type { AgentTool } from "@/ipc/ipc_types"; import type { AgentTool } from "@/ipc/ipc_types";
import type { AgentToolConsent } from "@/ipc/ipc_types"; import { AgentToolConsent } from "@/lib/schemas";
// Re-export types for convenience // Re-export types for convenience
export type { AgentToolName, AgentTool }; export type { AgentToolName, AgentTool };
......
import { z } from "zod"; import { z } from "zod";
import type { ProblemReport, Problem } from "../../shared/tsc_types"; import type { ProblemReport, Problem } from "../../shared/tsc_types";
import { AgentToolConsent } from "@/lib/schemas";
export type { ProblemReport, Problem }; export type { ProblemReport, Problem };
export interface AppOutput { export interface AppOutput {
...@@ -709,12 +710,6 @@ export interface AgentToolConsentResponseParams { ...@@ -709,12 +710,6 @@ export interface AgentToolConsentResponseParams {
decision: AgentToolConsentDecision; decision: AgentToolConsentDecision;
} }
// ============================================================================
// Consent Types
// ============================================================================
export type AgentToolConsent = "ask" | "always";
// ============================================================================ // ============================================================================
// Agent Todo Types // Agent Todo Types
// ============================================================================ // ============================================================================
......
...@@ -242,7 +242,7 @@ export const SmartContextModeSchema = z.enum([ ...@@ -242,7 +242,7 @@ export const SmartContextModeSchema = z.enum([
]); ]);
export type SmartContextMode = z.infer<typeof SmartContextModeSchema>; export type SmartContextMode = z.infer<typeof SmartContextModeSchema>;
export const AgentToolConsentSchema = z.enum(["ask", "always"]); export const AgentToolConsentSchema = z.enum(["ask", "always", "never"]);
export type AgentToolConsent = z.infer<typeof AgentToolConsentSchema>; export type AgentToolConsent = z.infer<typeof AgentToolConsentSchema>;
/** /**
......
...@@ -33,7 +33,7 @@ import { ...@@ -33,7 +33,7 @@ import {
type AgentContext, type AgentContext,
type ToolResult, type ToolResult,
} from "./tools/types"; } from "./tools/types";
import type { AgentToolConsent } from "@/ipc/ipc_types"; import { AgentToolConsent } from "@/lib/schemas";
import { getSupabaseClientCode } from "@/supabase_admin/supabase_context"; import { getSupabaseClientCode } from "@/supabase_admin/supabase_context";
// Combined tool definitions array // Combined tool definitions array
export const TOOL_DEFINITIONS: readonly ToolDefinition[] = [ export const TOOL_DEFINITIONS: readonly ToolDefinition[] = [
...@@ -170,6 +170,8 @@ export async function requireAgentToolConsent( ...@@ -170,6 +170,8 @@ export async function requireAgentToolConsent(
const current = getAgentToolConsent(params.toolName); const current = getAgentToolConsent(params.toolName);
if (current === "always") return true; if (current === "always") return true;
if (current === "never")
throw new Error("Should not ask for consent for a tool marked as 'never'");
// Ask renderer for a decision via event bridge // Ask renderer for a decision via event bridge
const requestId = `agent:${params.toolName}:${crypto.randomUUID()}`; const requestId = `agent:${params.toolName}:${crypto.randomUUID()}`;
...@@ -258,6 +260,11 @@ export function buildAgentToolSet(ctx: AgentContext) { ...@@ -258,6 +260,11 @@ export function buildAgentToolSet(ctx: AgentContext) {
const toolSet: Record<string, any> = {}; const toolSet: Record<string, any> = {};
for (const tool of TOOL_DEFINITIONS) { for (const tool of TOOL_DEFINITIONS) {
const consent = getAgentToolConsent(tool.name);
if (consent === "never") {
continue;
}
if (tool.isEnabled && !tool.isEnabled(ctx)) { if (tool.isEnabled && !tool.isEnabled(ctx)) {
continue; continue;
} }
......
...@@ -7,7 +7,7 @@ import { ...@@ -7,7 +7,7 @@ import {
} from "./types"; } from "./types";
import { generateProblemReport } from "@/ipc/processors/tsc"; import { generateProblemReport } from "@/ipc/processors/tsc";
import type { Problem } from "@/ipc/ipc_types"; import type { Problem } from "@/ipc/ipc_types";
import { readSettings } from "@/main/settings";
import { normalizePath } from "../../../../../../../shared/normalizePath"; import { normalizePath } from "../../../../../../../shared/normalizePath";
const runTypeChecksSchema = z.object({ const runTypeChecksSchema = z.object({
...@@ -76,7 +76,6 @@ export const runTypeChecksTool: ToolDefinition< ...@@ -76,7 +76,6 @@ export const runTypeChecksTool: ToolDefinition<
- NEVER call this tool on a file unless you've edited it or are about to edit it`, - NEVER call this tool on a file unless you've edited it or are about to edit it`,
inputSchema: runTypeChecksSchema, inputSchema: runTypeChecksSchema,
defaultConsent: "always", defaultConsent: "always",
isEnabled: () => !!readSettings().enableAutoFixProblems,
getConsentPreview: (args) => getConsentPreview: (args) =>
args.paths && args.paths.length > 0 args.paths && args.paths.length > 0
......
...@@ -5,7 +5,8 @@ ...@@ -5,7 +5,8 @@
import { z } from "zod"; import { z } from "zod";
import { IpcMainInvokeEvent } from "electron"; import { IpcMainInvokeEvent } from "electron";
import { jsonrepair } from "jsonrepair"; import { jsonrepair } from "jsonrepair";
import { AgentToolConsent, AgentTodo } from "@/ipc/ipc_types"; import { AgentToolConsent } from "@/lib/schemas";
import { AgentTodo } from "@/ipc/ipc_types";
// ============================================================================ // ============================================================================
// XML Escape Helpers // XML Escape Helpers
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论