fix: align exec tool config and test timeouts
This commit is contained in:
@@ -6,6 +6,7 @@ Docs: https://docs.clawd.bot
|
|||||||
|
|
||||||
### Changes
|
### Changes
|
||||||
- Exec: add host/security/ask routing for gateway + node exec.
|
- Exec: add host/security/ask routing for gateway + node exec.
|
||||||
|
- Exec: add `/exec` directive for per-session exec defaults (host/security/ask/node).
|
||||||
- macOS: migrate exec approvals to `~/.clawdbot/exec-approvals.json` with per-agent allowlists and skill auto-allow toggle.
|
- macOS: migrate exec approvals to `~/.clawdbot/exec-approvals.json` with per-agent allowlists and skill auto-allow toggle.
|
||||||
- macOS: add approvals socket UI server + node exec lifecycle events.
|
- macOS: add approvals socket UI server + node exec lifecycle events.
|
||||||
- Slash commands: replace `/cost` with `/usage off|tokens|full` to control per-response usage footer; `/usage` no longer aliases `/status`. (Supersedes #1140) — thanks @Nachx639.
|
- Slash commands: replace `/cost` with `/usage off|tokens|full` to control per-response usage footer; `/usage` no longer aliases `/status`. (Supersedes #1140) — thanks @Nachx639.
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ beforeEach(() => {
|
|||||||
killed: false,
|
killed: false,
|
||||||
});
|
});
|
||||||
ensureAuthProfileStore.mockReset().mockReturnValue({ version: 1, profiles: {} });
|
ensureAuthProfileStore.mockReset().mockReturnValue({ version: 1, profiles: {} });
|
||||||
|
loadClawdbotPlugins.mockReset().mockReturnValue({ plugins: [], diagnostics: [] });
|
||||||
migrateLegacyConfig.mockReset().mockImplementation((raw: unknown) => ({
|
migrateLegacyConfig.mockReset().mockImplementation((raw: unknown) => ({
|
||||||
config: raw as Record<string, unknown>,
|
config: raw as Record<string, unknown>,
|
||||||
changes: ["Moved routing.allowFrom → channels.whatsapp.allowFrom."],
|
changes: ["Moved routing.allowFrom → channels.whatsapp.allowFrom."],
|
||||||
@@ -131,6 +132,7 @@ const runCommandWithTimeout = vi.fn().mockResolvedValue({
|
|||||||
});
|
});
|
||||||
|
|
||||||
const ensureAuthProfileStore = vi.fn().mockReturnValue({ version: 1, profiles: {} });
|
const ensureAuthProfileStore = vi.fn().mockReturnValue({ version: 1, profiles: {} });
|
||||||
|
const loadClawdbotPlugins = vi.fn().mockReturnValue({ plugins: [], diagnostics: [] });
|
||||||
|
|
||||||
const legacyReadConfigFileSnapshot = vi.fn().mockResolvedValue({
|
const legacyReadConfigFileSnapshot = vi.fn().mockResolvedValue({
|
||||||
path: "/tmp/clawdbot.json",
|
path: "/tmp/clawdbot.json",
|
||||||
@@ -173,9 +175,8 @@ vi.mock("../agents/skills-status.js", () => ({
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
vi.mock("../plugins/loader.js", () => ({
|
vi.mock("../plugins/loader.js", () => ({
|
||||||
loadClawdbotPlugins: () => ({ plugins: [], diagnostics: [] }),
|
loadClawdbotPlugins,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
vi.mock("../config/config.js", async (importOriginal) => {
|
vi.mock("../config/config.js", async (importOriginal) => {
|
||||||
const actual = await importOriginal();
|
const actual = await importOriginal();
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -387,3 +387,32 @@ export type ToolsConfig = {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type ExecToolConfig = {
|
||||||
|
/** Exec host routing (default: sandbox). */
|
||||||
|
host?: "sandbox" | "gateway" | "node";
|
||||||
|
/** Exec security mode (default: deny). */
|
||||||
|
security?: "deny" | "allowlist" | "full";
|
||||||
|
/** Exec ask mode (default: on-miss). */
|
||||||
|
ask?: "off" | "on-miss" | "always";
|
||||||
|
/** Default node binding for exec.host=node (node id/name). */
|
||||||
|
node?: string;
|
||||||
|
/** Default time (ms) before an exec command auto-backgrounds. */
|
||||||
|
backgroundMs?: number;
|
||||||
|
/** Default timeout (seconds) before auto-killing exec commands. */
|
||||||
|
timeoutSec?: number;
|
||||||
|
/** How long to keep finished sessions in memory (ms). */
|
||||||
|
cleanupMs?: number;
|
||||||
|
/** Emit a system event and heartbeat when a backgrounded exec exits. */
|
||||||
|
notifyOnExit?: boolean;
|
||||||
|
/** apply_patch subtool configuration (experimental). */
|
||||||
|
applyPatch?: {
|
||||||
|
/** Enable apply_patch for OpenAI models (default: false). */
|
||||||
|
enabled?: boolean;
|
||||||
|
/**
|
||||||
|
* Optional allowlist of model ids that can use apply_patch.
|
||||||
|
* Accepts either raw ids (e.g. "gpt-5.2") or full ids (e.g. "openai/gpt-5.2").
|
||||||
|
*/
|
||||||
|
allowModels?: string[];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|||||||
@@ -183,6 +183,24 @@ export const AgentToolsSchema = z
|
|||||||
allowFrom: ElevatedAllowFromSchema,
|
allowFrom: ElevatedAllowFromSchema,
|
||||||
})
|
})
|
||||||
.optional(),
|
.optional(),
|
||||||
|
exec: z
|
||||||
|
.object({
|
||||||
|
host: z.enum(["sandbox", "gateway", "node"]).optional(),
|
||||||
|
security: z.enum(["deny", "allowlist", "full"]).optional(),
|
||||||
|
ask: z.enum(["off", "on-miss", "always"]).optional(),
|
||||||
|
node: z.string().optional(),
|
||||||
|
backgroundMs: z.number().int().positive().optional(),
|
||||||
|
timeoutSec: z.number().int().positive().optional(),
|
||||||
|
cleanupMs: z.number().int().positive().optional(),
|
||||||
|
notifyOnExit: z.boolean().optional(),
|
||||||
|
applyPatch: z
|
||||||
|
.object({
|
||||||
|
enabled: z.boolean().optional(),
|
||||||
|
allowModels: z.array(z.string()).optional(),
|
||||||
|
})
|
||||||
|
.optional(),
|
||||||
|
})
|
||||||
|
.optional(),
|
||||||
sandbox: z
|
sandbox: z
|
||||||
.object({
|
.object({
|
||||||
tools: ToolPolicySchema,
|
tools: ToolPolicySchema,
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ export default defineConfig({
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
test: {
|
test: {
|
||||||
testTimeout: 20_000,
|
testTimeout: 30_000,
|
||||||
include: [
|
include: [
|
||||||
"src/**/*.test.ts",
|
"src/**/*.test.ts",
|
||||||
"extensions/**/*.test.ts",
|
"extensions/**/*.test.ts",
|
||||||
|
|||||||
Reference in New Issue
Block a user