дзеркало
https://github.com/l0ng-ai/openidea.git
синхронізовано 2026-11-09 11:15:40 +02:00
Revert "fix(agents): stop defaulting new tasks to bypass" (#2234)
Reverts #2232: new agent tasks default to Bypass again.
Цей коміт міститься в:
1 джерело
73b3a99699
коміт
60b19b2ffb
8 files changed
+52
-254
No files matched your search
@@ -3,6 +3,7 @@ import type { AgentConfigOption, AgentEntry, AgentStatus, AgentTask } from "@/bi
|
||||
import {
|
||||
applyCompletion,
|
||||
atEdgeLine,
|
||||
bypassDefaults,
|
||||
canSend,
|
||||
completionAt,
|
||||
isPathQuery,
|
||||
@@ -202,8 +203,7 @@ describe("agent composer", () => {
|
||||
"https://agentclientprotocol.com/protocol/session-modes#autopilot",
|
||||
].map(modeIcon),
|
||||
).toEqual(["lock", "edit", "todo", "run", "unlock", "edit", "eye", "lock", "run", "run"]);
|
||||
expect(permissions.current).toBe("off");
|
||||
expect(approvals.current).toBe("ask");
|
||||
expect(bypassDefaults([...config, permissions])).toEqual({ allow_all: "on" });
|
||||
expect(usageLabel({ used: 24_000, size: 200_000 })).toEqual({
|
||||
short: "12%",
|
||||
detail: "24k / 200k tokens",
|
||||
|
||||
@@ -33,7 +33,7 @@ import { defaultTaskProject } from "./project";
|
||||
import { HomeEditor } from "./HomeEditor";
|
||||
import composerStyles from "./Composer.module.css";
|
||||
import tagStyles from "@/ui/InlineTag.module.css";
|
||||
import { HOME, savedDraft, startTask, updateComposer, useAgents } from "./store";
|
||||
import { HOME, updateComposer, useAgents } from "./store";
|
||||
import { emptyDraft } from "./composerModel";
|
||||
|
||||
const command = (name: string, description: string, source: "command" | "skill" = "command"): AgentCommand => ({
|
||||
@@ -264,46 +264,3 @@ describe("workspace task project", () => {
|
||||
await vi.dynamicImportSettled();
|
||||
});
|
||||
});
|
||||
|
||||
describe("new task permissions", () => {
|
||||
it.each([
|
||||
["claude", "mode", "default", "bypassPermissions"],
|
||||
["codex", "mode", "auto", "full-access"],
|
||||
["cursor", "approval", "ask", "bypass"],
|
||||
["copilot", "permissions", "off", "on"],
|
||||
["custom", "mode", "ask", "yolo"],
|
||||
])("keeps %s's offered default and sends an explicit Bypass choice", async (provider, category, safe, bypass) => {
|
||||
const offered = {
|
||||
...claude,
|
||||
id: provider,
|
||||
config: [
|
||||
{
|
||||
id: category,
|
||||
name: category,
|
||||
description: null,
|
||||
category,
|
||||
current: safe,
|
||||
via: "option" as const,
|
||||
values: [safe, bypass].map((value) => ({ value, name: value, description: null })),
|
||||
},
|
||||
],
|
||||
};
|
||||
const draft = savedDraft({ provider });
|
||||
useAgents.setState({ providers: [offered], draft });
|
||||
updateComposer(HOME, { text: "Create a note" });
|
||||
await expect(startTask()).rejects.toThrow("stop here");
|
||||
expect(agentCreate).toHaveBeenLastCalledWith(expect.objectContaining({ config: [{ id: category, value: safe }] }));
|
||||
useAgents.setState({ providers: [{ ...offered, config: [{ ...offered.config[0]!, current: null }] }] });
|
||||
await expect(startTask()).rejects.toThrow("stop here");
|
||||
expect(agentCreate).toHaveBeenLastCalledWith(expect.objectContaining({ config: [] }));
|
||||
// Reloading the saved draft preserves the user's explicit permission choice.
|
||||
useAgents.setState({ draft: savedDraft(JSON.parse(JSON.stringify({ ...draft, config: { [category]: bypass } }))) });
|
||||
await expect(startTask("worktree")).rejects.toThrow("stop here");
|
||||
expect(agentCreate).toHaveBeenLastCalledWith(
|
||||
expect.objectContaining({
|
||||
isolation: "worktree",
|
||||
config: [{ id: category, value: bypass }],
|
||||
}),
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -198,6 +198,20 @@ export function modeIcon(mode: string): string {
|
||||
return "lock";
|
||||
}
|
||||
|
||||
/** The settings that approve everything without asking (a bypass mode, or approvals), by option id. */
|
||||
export function bypassDefaults(config: readonly AgentConfigOption[]): Record<string, string> {
|
||||
const out: Record<string, string> = {};
|
||||
const mode = modeOption(config);
|
||||
const unlock = mode?.values.find((v) => modeIcon(v.value) === "unlock");
|
||||
if (mode && unlock) out[mode.id] = unlock.value;
|
||||
const permissions = config.find((o) => o.category === "permissions");
|
||||
const allowAll = permissions?.values.find((v) => /^(on|true)$/i.test(v.value));
|
||||
if (permissions && allowAll) out[permissions.id] = allowAll.value;
|
||||
const approval = config.find((o) => o.category === "approval");
|
||||
if (approval?.values.some((v) => v.value === "bypass")) out[approval.id] = "bypass";
|
||||
return out;
|
||||
}
|
||||
|
||||
/** Shift+Tab: the mode after the current one. */
|
||||
export function nextValue(option: AgentConfigOption, current = option.current): string | null {
|
||||
if (!option.values.length) return null;
|
||||
|
||||
@@ -20,7 +20,7 @@ import { call, commands, isTauri } from "@/platform/ipc";
|
||||
import { editorService, notifications, notifyTabTitlesChanged, toolWindowService } from "@/workbench/contributions";
|
||||
import { tx } from "@/platform/i18n";
|
||||
import { confirm } from "@/workbench/messages";
|
||||
import { canSend, emptyDraft, toPrompt, type ComposerDraft, type FileRef } from "./composerModel";
|
||||
import { bypassDefaults, canSend, emptyDraft, toPrompt, type ComposerDraft, type FileRef } from "./composerModel";
|
||||
import { withQuote } from "./conversation";
|
||||
import {
|
||||
HOME_KEY,
|
||||
@@ -538,8 +538,12 @@ export async function startTask(
|
||||
providers.find((p) => p.id === draft.provider),
|
||||
draft,
|
||||
);
|
||||
const defaults = bypassDefaults(options);
|
||||
const config = options.flatMap((o) => {
|
||||
const value = o.current;
|
||||
const value =
|
||||
o.category === "model" || o.category === "thought_level"
|
||||
? o.current
|
||||
: (draft.config[o.id] ?? defaults[o.id] ?? null);
|
||||
return value !== null && o.values.some((v) => v.value === value) ? [{ id: o.id, value }] : [];
|
||||
});
|
||||
const task = await call(
|
||||
|
||||
Reference in new issue
Заблокувати користувача