Implement granular tool permissions (#82)
* Granular tool permissions * Fix build * Start on UI * Fixes * Fmt * Go ham on UI * Update migrations * Considate wiki files * Clean up * More tweaks. Docs. * Consolidate collab and noncollab * Fix build * Restrict for non-collaborators
This commit is contained in:
committed by
pullfrog[bot]
parent
4547b0032e
commit
97dce099c1
@@ -6,7 +6,7 @@ import type { Octokit } from "@octokit/rest";
|
||||
import { encode as toonEncode } from "@toon-format/toon";
|
||||
import { type } from "arktype";
|
||||
import { type Agent, agents } from "./agents/index.ts";
|
||||
import type { AgentResult } from "./agents/shared.ts";
|
||||
import type { AgentResult, ToolPermissions } from "./agents/shared.ts";
|
||||
import { AgentName, agentsManifest, Effort, type Payload } from "./external.ts";
|
||||
import { ensureProgressCommentUpdated, reportProgress } from "./mcp/comment.ts";
|
||||
import { createMcpConfigs } from "./mcp/config.ts";
|
||||
@@ -21,6 +21,10 @@ import { createOctokit, parseRepoContext, setupGitHubInstallationToken } from ".
|
||||
import { setupGitAuth, setupGitConfig } from "./utils/setup.ts";
|
||||
import { Timer } from "./utils/timer.ts";
|
||||
|
||||
// tool permission enum types for inputs
|
||||
const ToolPermissionInput = type.enumerated("disabled", "enabled");
|
||||
const BashPermissionInput = type.enumerated("disabled", "restricted", "enabled");
|
||||
|
||||
// inputs schema - mirrors Payload fields without the discriminated union for event
|
||||
export const Inputs = type({
|
||||
prompt: "string",
|
||||
@@ -28,7 +32,10 @@ export const Inputs = type({
|
||||
"agent?": AgentName.or("null"),
|
||||
"event?": "object",
|
||||
"modes?": ModeSchema.array(),
|
||||
"sandbox?": "boolean",
|
||||
"web?": ToolPermissionInput,
|
||||
"search?": ToolPermissionInput,
|
||||
"write?": ToolPermissionInput,
|
||||
"bash?": BashPermissionInput,
|
||||
"disableProgressComment?": "true",
|
||||
"comment_id?": "number|null",
|
||||
"issue_id?": "number|null",
|
||||
@@ -430,7 +437,6 @@ function parsePayload(inputs: Inputs): Payload {
|
||||
event: inputs.event as Payload["event"],
|
||||
modes: inputs.modes ?? modes,
|
||||
effort: inputs.effort ?? "auto",
|
||||
sandbox: inputs.sandbox,
|
||||
disableProgressComment: inputs.disableProgressComment,
|
||||
comment_id: inputs.comment_id,
|
||||
issue_id: inputs.issue_id,
|
||||
@@ -460,7 +466,6 @@ function parsePayload(inputs: Inputs): Payload {
|
||||
},
|
||||
modes: inputs.modes ?? modes,
|
||||
effort: inputs.effort ?? "auto",
|
||||
sandbox: inputs.sandbox,
|
||||
} as Payload;
|
||||
}
|
||||
}
|
||||
@@ -517,6 +522,22 @@ function validateApiKey(params: { agent: Agent; owner: string; name: string }):
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute tool permissions from inputs.
|
||||
* For run action, bash defaults to restricted for public repos when unset.
|
||||
*/
|
||||
function computeToolPermissions(params: {
|
||||
inputs: Inputs;
|
||||
isPublicRepo: boolean;
|
||||
}): ToolPermissions {
|
||||
return {
|
||||
web: params.inputs.web ?? "enabled",
|
||||
search: params.inputs.search ?? "enabled",
|
||||
write: params.inputs.write ?? "enabled",
|
||||
bash: params.inputs.bash ?? (params.isPublicRepo ? "restricted" : "enabled"),
|
||||
};
|
||||
}
|
||||
|
||||
async function runAgent(ctx: AgentContext): Promise<AgentResult> {
|
||||
const effort = ctx.payload.effort ?? "auto";
|
||||
log.info(`Running ${ctx.agent.name} with effort=${effort}...`);
|
||||
@@ -526,6 +547,11 @@ async function runAgent(ctx: AgentContext): Promise<AgentResult> {
|
||||
const promptContent = `${ctx.payload.prompt}\n\n${toonEncode(eventWithoutContext)}`;
|
||||
log.box(promptContent, { title: "Prompt" });
|
||||
|
||||
const tools = computeToolPermissions({ inputs: ctx.inputs, isPublicRepo: !ctx.repo.private });
|
||||
log.info(
|
||||
`Tool permissions: web=${tools.web}, search=${tools.search}, write=${tools.write}, bash=${tools.bash}`
|
||||
);
|
||||
|
||||
return ctx.agent.run({
|
||||
payload: ctx.payload,
|
||||
mcpServers: ctx.mcpServers,
|
||||
@@ -539,6 +565,7 @@ async function runAgent(ctx: AgentContext): Promise<AgentResult> {
|
||||
isPublic: !ctx.repo.private,
|
||||
},
|
||||
effort,
|
||||
tools,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user