fix: describe sandboxed elevated in prompt
This commit is contained in:
@@ -11,6 +11,7 @@
|
||||
- CLI: add `clawdbot update` (safe-ish git checkout update) + `--update` shorthand. (#673) — thanks @fm1randa.
|
||||
|
||||
### Fixes
|
||||
- Agents/System: clarify sandboxed runtime in system prompt and surface elevated availability when sandboxed.
|
||||
- Auto-reply: prefer `RawBody` for command/directive parsing (WhatsApp + Discord) and prevent fallback runs from clobbering concurrent session updates. (#643) — thanks @mcinteerj.
|
||||
- WhatsApp: fix group reactions by preserving message IDs and sender JIDs in history; normalize participant phone numbers to JIDs in outbound reactions. (#640) — thanks @mcinteerj.
|
||||
- WhatsApp: expose group participant IDs to the model so reactions can target the right sender.
|
||||
|
||||
@@ -19,6 +19,7 @@ The prompt is intentionally compact and uses fixed sections:
|
||||
- **Clawdbot Self-Update**: how to run `config.apply` and `update.run`.
|
||||
- **Workspace**: working directory (`agents.defaults.workspace`).
|
||||
- **Workspace Files (injected)**: indicates bootstrap files are included below.
|
||||
- **Sandbox** (when enabled): indicates sandboxed runtime, sandbox paths, and whether elevated bash is available.
|
||||
- **Time**: UTC default + the user’s local time (already converted).
|
||||
- **Reply Tags**: optional reply tag syntax for supported providers.
|
||||
- **Heartbeats**: heartbeat prompt and ack behavior.
|
||||
|
||||
@@ -61,6 +61,47 @@ describe("buildEmbeddedSandboxInfo", () => {
|
||||
browserNoVncUrl: "http://localhost:6080",
|
||||
});
|
||||
});
|
||||
|
||||
it("includes elevated info when allowed", () => {
|
||||
const sandbox = {
|
||||
enabled: true,
|
||||
sessionKey: "session:test",
|
||||
workspaceDir: "/tmp/clawdbot-sandbox",
|
||||
agentWorkspaceDir: "/tmp/clawdbot-workspace",
|
||||
workspaceAccess: "none",
|
||||
containerName: "clawdbot-sbx-test",
|
||||
containerWorkdir: "/workspace",
|
||||
docker: {
|
||||
image: "clawdbot-sandbox:bookworm-slim",
|
||||
containerPrefix: "clawdbot-sbx-",
|
||||
workdir: "/workspace",
|
||||
readOnlyRoot: true,
|
||||
tmpfs: ["/tmp"],
|
||||
network: "none",
|
||||
user: "1000:1000",
|
||||
capDrop: ["ALL"],
|
||||
env: { LANG: "C.UTF-8" },
|
||||
},
|
||||
tools: {
|
||||
allow: ["bash"],
|
||||
deny: ["browser"],
|
||||
},
|
||||
} satisfies SandboxContext;
|
||||
|
||||
expect(
|
||||
buildEmbeddedSandboxInfo(sandbox, {
|
||||
enabled: true,
|
||||
allowed: true,
|
||||
defaultLevel: "on",
|
||||
}),
|
||||
).toEqual({
|
||||
enabled: true,
|
||||
workspaceDir: "/tmp/clawdbot-sandbox",
|
||||
workspaceAccess: "none",
|
||||
agentWorkspaceMount: undefined,
|
||||
elevated: { allowed: true, defaultLevel: "on" },
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("resolveSessionAgentIds", () => {
|
||||
|
||||
@@ -479,6 +479,10 @@ type EmbeddedSandboxInfo = {
|
||||
agentWorkspaceMount?: string;
|
||||
browserControlUrl?: string;
|
||||
browserNoVncUrl?: string;
|
||||
elevated?: {
|
||||
allowed: boolean;
|
||||
defaultLevel: "on" | "off";
|
||||
};
|
||||
};
|
||||
|
||||
function resolveSessionLane(key: string) {
|
||||
@@ -552,8 +556,10 @@ function describeUnknownError(error: unknown): string {
|
||||
|
||||
export function buildEmbeddedSandboxInfo(
|
||||
sandbox?: Awaited<ReturnType<typeof resolveSandboxContext>>,
|
||||
bashElevated?: BashElevatedDefaults,
|
||||
): EmbeddedSandboxInfo | undefined {
|
||||
if (!sandbox?.enabled) return undefined;
|
||||
const elevatedAllowed = Boolean(bashElevated?.enabled && bashElevated.allowed);
|
||||
return {
|
||||
enabled: true,
|
||||
workspaceDir: sandbox.workspaceDir,
|
||||
@@ -562,6 +568,14 @@ export function buildEmbeddedSandboxInfo(
|
||||
sandbox.workspaceAccess === "ro" ? "/agent" : undefined,
|
||||
browserControlUrl: sandbox.browser?.controlUrl,
|
||||
browserNoVncUrl: sandbox.browser?.noVncUrl,
|
||||
...(elevatedAllowed
|
||||
? {
|
||||
elevated: {
|
||||
allowed: true,
|
||||
defaultLevel: bashElevated?.defaultLevel ?? "off",
|
||||
},
|
||||
}
|
||||
: {}),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -887,7 +901,10 @@ export async function compactEmbeddedPiSession(params: {
|
||||
provider: runtimeProvider,
|
||||
capabilities: runtimeCapabilities,
|
||||
};
|
||||
const sandboxInfo = buildEmbeddedSandboxInfo(sandbox);
|
||||
const sandboxInfo = buildEmbeddedSandboxInfo(
|
||||
sandbox,
|
||||
params.bashElevated,
|
||||
);
|
||||
const reasoningTagHint = provider === "ollama";
|
||||
const userTimezone = resolveUserTimezone(
|
||||
params.config?.agents?.defaults?.userTimezone,
|
||||
@@ -1264,7 +1281,10 @@ export async function runEmbeddedPiAgent(params: {
|
||||
node: process.version,
|
||||
model: `${provider}/${modelId}`,
|
||||
};
|
||||
const sandboxInfo = buildEmbeddedSandboxInfo(sandbox);
|
||||
const sandboxInfo = buildEmbeddedSandboxInfo(
|
||||
sandbox,
|
||||
params.bashElevated,
|
||||
);
|
||||
const reasoningTagHint = provider === "ollama";
|
||||
const userTimezone = resolveUserTimezone(
|
||||
params.config?.agents?.defaults?.userTimezone,
|
||||
|
||||
@@ -169,4 +169,21 @@ describe("buildAgentSystemPrompt", () => {
|
||||
expect(prompt).toContain("provider=telegram");
|
||||
expect(prompt).toContain("capabilities=inlineButtons");
|
||||
});
|
||||
|
||||
it("describes sandboxed runtime and elevated when allowed", () => {
|
||||
const prompt = buildAgentSystemPrompt({
|
||||
workspaceDir: "/tmp/clawd",
|
||||
sandboxInfo: {
|
||||
enabled: true,
|
||||
workspaceDir: "/tmp/sandbox",
|
||||
workspaceAccess: "ro",
|
||||
agentWorkspaceMount: "/agent",
|
||||
elevated: { allowed: true, defaultLevel: "on" },
|
||||
},
|
||||
});
|
||||
|
||||
expect(prompt).toContain("You are running in a sandboxed runtime");
|
||||
expect(prompt).toContain("User can toggle with /elevated on|off.");
|
||||
expect(prompt).toContain("Current elevated level: on");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -31,6 +31,10 @@ export function buildAgentSystemPrompt(params: {
|
||||
agentWorkspaceMount?: string;
|
||||
browserControlUrl?: string;
|
||||
browserNoVncUrl?: string;
|
||||
elevated?: {
|
||||
allowed: boolean;
|
||||
defaultLevel: "on" | "off";
|
||||
};
|
||||
};
|
||||
}) {
|
||||
const toolSummaries: Record<string, string> = {
|
||||
@@ -219,7 +223,7 @@ export function buildAgentSystemPrompt(params: {
|
||||
params.sandboxInfo?.enabled ? "## Sandbox" : "",
|
||||
params.sandboxInfo?.enabled
|
||||
? [
|
||||
"Tool execution is isolated in a Docker sandbox.",
|
||||
"You are running in a sandboxed runtime (tools execute in Docker).",
|
||||
"Some tools may be unavailable due to sandbox policy.",
|
||||
params.sandboxInfo.workspaceDir
|
||||
? `Sandbox workspace: ${params.sandboxInfo.workspaceDir}`
|
||||
@@ -237,6 +241,20 @@ export function buildAgentSystemPrompt(params: {
|
||||
params.sandboxInfo.browserNoVncUrl
|
||||
? `Sandbox browser observer (noVNC): ${params.sandboxInfo.browserNoVncUrl}`
|
||||
: "",
|
||||
params.sandboxInfo.elevated?.allowed
|
||||
? "Elevated bash is available for this session."
|
||||
: "",
|
||||
params.sandboxInfo.elevated?.allowed
|
||||
? "User can toggle with /elevated on|off."
|
||||
: "",
|
||||
params.sandboxInfo.elevated?.allowed
|
||||
? "You may also send /elevated on|off when needed."
|
||||
: "",
|
||||
params.sandboxInfo.elevated?.allowed
|
||||
? `Current elevated level: ${
|
||||
params.sandboxInfo.elevated.defaultLevel
|
||||
} (on runs bash on host; off runs in sandbox).`
|
||||
: "",
|
||||
]
|
||||
.filter(Boolean)
|
||||
.join("\n")
|
||||
|
||||
Reference in New Issue
Block a user