summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorK Whiteside <[email protected]>2025-11-18 17:18:23 -0600
committerGitHub <[email protected]>2025-11-18 17:18:23 -0600
commit47bfae52c0d59e8b089d32a793b62531d5ce17f6 (patch)
tree517922643d4c07afbb7c830b59ec7968047fcf8c
parent52cf9e3423c21a5d54452cf3643a1d60dd0b4e19 (diff)
downloadopencode-47bfae52c0d59e8b089d32a793b62531d5ce17f6.tar.gz
opencode-47bfae52c0d59e8b089d32a793b62531d5ce17f6.zip
fix: permission checks for external_directory and doom_loop (#4433)
Co-authored-by: Aiden Cline <[email protected]> Co-authored-by: AerionDyseti <[email protected]>
-rw-r--r--packages/opencode/src/permission/index.ts7
-rw-r--r--packages/opencode/src/session/processor.ts12
-rw-r--r--packages/opencode/src/tool/edit.ts11
-rw-r--r--packages/opencode/src/tool/patch.ts11
-rw-r--r--packages/opencode/src/tool/read.ts11
-rw-r--r--packages/opencode/src/tool/write.ts11
6 files changed, 62 insertions, 1 deletions
diff --git a/packages/opencode/src/permission/index.ts b/packages/opencode/src/permission/index.ts
index 3a4a9901b..32dbd5a03 100644
--- a/packages/opencode/src/permission/index.ts
+++ b/packages/opencode/src/permission/index.ts
@@ -186,8 +186,13 @@ export namespace Permission {
public readonly permissionID: string,
public readonly toolCallID?: string,
public readonly metadata?: Record<string, any>,
+ public readonly reason?: string,
) {
- super(`The user rejected permission to use this specific tool call. You may try again with different parameters.`)
+ super(
+ reason !== undefined
+ ? reason
+ : `The user rejected permission to use this specific tool call. You may try again with different parameters.`,
+ )
}
}
}
diff --git a/packages/opencode/src/session/processor.ts b/packages/opencode/src/session/processor.ts
index 5c2005587..2af8e888e 100644
--- a/packages/opencode/src/session/processor.ts
+++ b/packages/opencode/src/session/processor.ts
@@ -136,6 +136,7 @@ export namespace SessionProcessor {
const parts = await MessageV2.parts(input.assistantMessage.id)
const lastThree = parts.slice(-DOOM_LOOP_THRESHOLD)
+
if (
lastThree.length === DOOM_LOOP_THRESHOLD &&
lastThree.every(
@@ -160,6 +161,17 @@ export namespace SessionProcessor {
input: value.input,
},
})
+ } else if (permission.doom_loop === "deny") {
+ throw new Permission.RejectedError(
+ input.assistantMessage.sessionID,
+ "doom_loop",
+ value.toolCallId,
+ {
+ tool: value.toolName,
+ input: value.input,
+ },
+ `You seem to be stuck in a doom loop, please stop repeating the same action`,
+ )
}
}
}
diff --git a/packages/opencode/src/tool/edit.ts b/packages/opencode/src/tool/edit.ts
index ca9859370..46627a3ed 100644
--- a/packages/opencode/src/tool/edit.ts
+++ b/packages/opencode/src/tool/edit.ts
@@ -57,6 +57,17 @@ export const EditTool = Tool.define("edit", {
parentDir,
},
})
+ } else if (agent.permission.external_directory === "deny") {
+ throw new Permission.RejectedError(
+ ctx.sessionID,
+ "external_directory",
+ ctx.callID,
+ {
+ filepath: filePath,
+ parentDir,
+ },
+ `File ${filePath} is not in the current working directory`,
+ )
}
}
diff --git a/packages/opencode/src/tool/patch.ts b/packages/opencode/src/tool/patch.ts
index 0571cd353..b8934f7c9 100644
--- a/packages/opencode/src/tool/patch.ts
+++ b/packages/opencode/src/tool/patch.ts
@@ -68,6 +68,17 @@ export const PatchTool = Tool.define("patch", {
parentDir,
},
})
+ } else if (agent.permission.external_directory === "deny") {
+ throw new Permission.RejectedError(
+ ctx.sessionID,
+ "external_directory",
+ ctx.callID,
+ {
+ filepath: filePath,
+ parentDir,
+ },
+ `File ${filePath} is not in the current working directory`,
+ )
}
}
diff --git a/packages/opencode/src/tool/read.ts b/packages/opencode/src/tool/read.ts
index ec97c8a6c..7e523496c 100644
--- a/packages/opencode/src/tool/read.ts
+++ b/packages/opencode/src/tool/read.ts
@@ -46,6 +46,17 @@ export const ReadTool = Tool.define("read", {
parentDir,
},
})
+ } else if (agent.permission.external_directory === "deny") {
+ throw new Permission.RejectedError(
+ ctx.sessionID,
+ "external_directory",
+ ctx.callID,
+ {
+ filepath: filepath,
+ parentDir,
+ },
+ `File ${filepath} is not in the current working directory`,
+ )
}
}
diff --git a/packages/opencode/src/tool/write.ts b/packages/opencode/src/tool/write.ts
index 58a0c177e..42bbe4690 100644
--- a/packages/opencode/src/tool/write.ts
+++ b/packages/opencode/src/tool/write.ts
@@ -36,6 +36,17 @@ export const WriteTool = Tool.define("write", {
parentDir,
},
})
+ } else if (agent.permission.external_directory === "deny") {
+ throw new Permission.RejectedError(
+ ctx.sessionID,
+ "external_directory",
+ ctx.callID,
+ {
+ filepath: filepath,
+ parentDir,
+ },
+ `File ${filepath} is not in the current working directory`,
+ )
}
}