Merge 78924c5463 into da71eaebd2
This commit is contained in:
commit
22a533e501
@ -48,6 +48,7 @@ Notes:
|
||||
- `tools.exec.node` (default: unset)
|
||||
- `tools.exec.pathPrepend`: list of directories to prepend to `PATH` for exec runs.
|
||||
- `tools.exec.safeBins`: stdin-only safe binaries that can run without explicit allowlist entries.
|
||||
- `tools.exec.pty` (default: false): enable PTY mode by default for exec commands. Useful when commands hang without a TTY. Ignored when sandboxed.
|
||||
|
||||
Example:
|
||||
```json5
|
||||
|
||||
@ -18,3 +18,28 @@ test("exec supports pty output", async () => {
|
||||
const text = result.content?.[0]?.text ?? "";
|
||||
expect(text).toContain("ok");
|
||||
});
|
||||
|
||||
test("exec uses pty when defaults.pty is true", async () => {
|
||||
const tool = createExecTool({ allowBackground: false, pty: true });
|
||||
// Note: pty is NOT passed in params - should use default
|
||||
const result = await tool.execute("toolcall", {
|
||||
command: 'node -e "process.stdout.write(String.fromCharCode(111,107))"',
|
||||
});
|
||||
|
||||
expect(result.details.status).toBe("completed");
|
||||
const text = result.content?.[0]?.text ?? "";
|
||||
expect(text).toContain("ok");
|
||||
});
|
||||
|
||||
test("exec params.pty overrides defaults.pty", async () => {
|
||||
const tool = createExecTool({ allowBackground: false, pty: true });
|
||||
// Explicitly set pty: false to override default
|
||||
const result = await tool.execute("toolcall", {
|
||||
command: "echo override",
|
||||
pty: false,
|
||||
});
|
||||
|
||||
expect(result.details.status).toBe("completed");
|
||||
const text = result.content?.[0]?.text ?? "";
|
||||
expect(text).toContain("override");
|
||||
});
|
||||
|
||||
@ -134,6 +134,7 @@ export type ExecToolDefaults = {
|
||||
messageProvider?: string;
|
||||
notifyOnExit?: boolean;
|
||||
cwd?: string;
|
||||
pty?: boolean;
|
||||
};
|
||||
|
||||
export type { BashSandboxConfig } from "./bash-tools.shared.js";
|
||||
@ -1295,7 +1296,7 @@ export function createExecTool(
|
||||
env,
|
||||
sandbox: undefined,
|
||||
containerWorkdir: null,
|
||||
usePty: params.pty === true && !sandbox,
|
||||
usePty: (params.pty ?? defaults?.pty) === true && !sandbox,
|
||||
warnings,
|
||||
maxOutput,
|
||||
pendingMaxOutput,
|
||||
@ -1381,7 +1382,7 @@ export function createExecTool(
|
||||
const effectiveTimeout =
|
||||
typeof params.timeout === "number" ? params.timeout : defaultTimeoutSec;
|
||||
const getWarningText = () => (warnings.length ? `${warnings.join("\n")}\n\n` : "");
|
||||
const usePty = params.pty === true && !sandbox;
|
||||
const usePty = (params.pty ?? defaults?.pty) === true && !sandbox;
|
||||
const run = await runExecProcess({
|
||||
command: params.command,
|
||||
workdir,
|
||||
|
||||
@ -92,6 +92,7 @@ function resolveExecConfig(cfg: OpenClawConfig | undefined) {
|
||||
approvalRunningNoticeMs: globalExec?.approvalRunningNoticeMs,
|
||||
cleanupMs: globalExec?.cleanupMs,
|
||||
notifyOnExit: globalExec?.notifyOnExit,
|
||||
pty: globalExec?.pty,
|
||||
applyPatch: globalExec?.applyPatch,
|
||||
};
|
||||
}
|
||||
@ -269,6 +270,7 @@ export function createOpenClawCodingTools(options?: {
|
||||
approvalRunningNoticeMs:
|
||||
options?.exec?.approvalRunningNoticeMs ?? execConfig.approvalRunningNoticeMs,
|
||||
notifyOnExit: options?.exec?.notifyOnExit ?? execConfig.notifyOnExit,
|
||||
pty: options?.exec?.pty ?? execConfig.pty,
|
||||
sandbox: sandbox
|
||||
? {
|
||||
containerName: sandbox.containerName,
|
||||
|
||||
@ -180,6 +180,7 @@ const FIELD_LABELS: Record<string, string> = {
|
||||
"tools.exec.node": "Exec Node Binding",
|
||||
"tools.exec.pathPrepend": "Exec PATH Prepend",
|
||||
"tools.exec.safeBins": "Exec Safe Bins",
|
||||
"tools.exec.pty": "Exec PTY Mode",
|
||||
"tools.message.allowCrossContextSend": "Allow Cross-Context Messaging",
|
||||
"tools.message.crossContext.allowWithinProvider": "Allow Cross-Context (Same Provider)",
|
||||
"tools.message.crossContext.allowAcrossProviders": "Allow Cross-Context (Across Providers)",
|
||||
@ -421,6 +422,8 @@ const FIELD_HELP: Record<string, string> = {
|
||||
"tools.exec.pathPrepend": "Directories to prepend to PATH for exec runs (gateway/sandbox).",
|
||||
"tools.exec.safeBins":
|
||||
"Allow stdin-only safe binaries to run without explicit allowlist entries.",
|
||||
"tools.exec.pty":
|
||||
"Enable PTY mode by default for exec commands. Ignored when sandboxed. (default: false).",
|
||||
"tools.message.allowCrossContextSend":
|
||||
"Legacy override: allow cross-context sends across all providers.",
|
||||
"tools.message.crossContext.allowWithinProvider":
|
||||
|
||||
@ -183,6 +183,8 @@ export type ExecToolConfig = {
|
||||
cleanupMs?: number;
|
||||
/** Emit a system event and heartbeat when a backgrounded exec exits. */
|
||||
notifyOnExit?: boolean;
|
||||
/** Enable PTY mode by default for exec commands (ignored when sandboxed). */
|
||||
pty?: boolean;
|
||||
/** apply_patch subtool configuration (experimental). */
|
||||
applyPatch?: {
|
||||
/** Enable apply_patch for OpenAI models (default: false). */
|
||||
|
||||
@ -271,6 +271,7 @@ export const AgentToolsSchema = z
|
||||
approvalRunningNoticeMs: z.number().int().nonnegative().optional(),
|
||||
cleanupMs: z.number().int().positive().optional(),
|
||||
notifyOnExit: z.boolean().optional(),
|
||||
pty: z.boolean().optional(),
|
||||
applyPatch: z
|
||||
.object({
|
||||
enabled: z.boolean().optional(),
|
||||
@ -512,6 +513,7 @@ export const ToolsSchema = z
|
||||
timeoutSec: z.number().int().positive().optional(),
|
||||
cleanupMs: z.number().int().positive().optional(),
|
||||
notifyOnExit: z.boolean().optional(),
|
||||
pty: z.boolean().optional(),
|
||||
applyPatch: z
|
||||
.object({
|
||||
enabled: z.boolean().optional(),
|
||||
|
||||
Loading…
Reference in New Issue
Block a user