feat: add command-aware permission request system for granular tool approval
This commit is contained in:
parent
dccb8875ad
commit
f24683e661
44 changed files with 3176 additions and 1384 deletions
|
|
@ -55,6 +55,8 @@ import type {
|
|||
PartUpdateResponses,
|
||||
PathGetResponses,
|
||||
PermissionListResponses,
|
||||
PermissionReplyErrors,
|
||||
PermissionReplyResponses,
|
||||
PermissionRespondErrors,
|
||||
PermissionRespondResponses,
|
||||
ProjectCurrentResponses,
|
||||
|
|
@ -1626,6 +1628,43 @@ export class Permission extends HeyApiClient {
|
|||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Respond to permission request
|
||||
*
|
||||
* Approve or deny a permission request from the AI assistant.
|
||||
*/
|
||||
public reply<ThrowOnError extends boolean = false>(
|
||||
parameters: {
|
||||
requestID: string
|
||||
directory?: string
|
||||
reply?: "once" | "always" | "reject"
|
||||
},
|
||||
options?: Options<never, ThrowOnError>,
|
||||
) {
|
||||
const params = buildClientParams(
|
||||
[parameters],
|
||||
[
|
||||
{
|
||||
args: [
|
||||
{ in: "path", key: "requestID" },
|
||||
{ in: "query", key: "directory" },
|
||||
{ in: "body", key: "reply" },
|
||||
],
|
||||
},
|
||||
],
|
||||
)
|
||||
return (options?.client ?? this.client).post<PermissionReplyResponses, PermissionReplyErrors, ThrowOnError>({
|
||||
url: "/permission/{requestID}/reply",
|
||||
...options,
|
||||
...params,
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
...options?.headers,
|
||||
...params.headers,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* List pending permissions
|
||||
*
|
||||
|
|
|
|||
|
|
@ -451,6 +451,33 @@ export type EventMessagePartRemoved = {
|
|||
}
|
||||
}
|
||||
|
||||
export type PermissionRequest = {
|
||||
id: string
|
||||
callID?: string
|
||||
sessionID: string
|
||||
permission: string
|
||||
patterns: Array<string>
|
||||
message: string
|
||||
metadata: {
|
||||
[key: string]: unknown
|
||||
}
|
||||
always: Array<string>
|
||||
}
|
||||
|
||||
export type EventPermissionNextAsked = {
|
||||
type: "permission.next.asked"
|
||||
properties: PermissionRequest
|
||||
}
|
||||
|
||||
export type EventPermissionNextReplied = {
|
||||
type: "permission.next.replied"
|
||||
properties: {
|
||||
sessionID: string
|
||||
requestID: string
|
||||
reply: "once" | "always" | "reject"
|
||||
}
|
||||
}
|
||||
|
||||
export type Permission = {
|
||||
id: string
|
||||
type: string
|
||||
|
|
@ -458,7 +485,7 @@ export type Permission = {
|
|||
sessionID: string
|
||||
messageID: string
|
||||
callID?: string
|
||||
title: string
|
||||
message: string
|
||||
metadata: {
|
||||
[key: string]: unknown
|
||||
}
|
||||
|
|
@ -481,40 +508,6 @@ export type EventPermissionReplied = {
|
|||
}
|
||||
}
|
||||
|
||||
export type EventFileEdited = {
|
||||
type: "file.edited"
|
||||
properties: {
|
||||
file: string
|
||||
}
|
||||
}
|
||||
|
||||
export type Todo = {
|
||||
/**
|
||||
* Brief description of the task
|
||||
*/
|
||||
content: string
|
||||
/**
|
||||
* Current status of the task: pending, in_progress, completed, cancelled
|
||||
*/
|
||||
status: string
|
||||
/**
|
||||
* Priority level of the task: high, medium, low
|
||||
*/
|
||||
priority: string
|
||||
/**
|
||||
* Unique identifier for the todo item
|
||||
*/
|
||||
id: string
|
||||
}
|
||||
|
||||
export type EventTodoUpdated = {
|
||||
type: "todo.updated"
|
||||
properties: {
|
||||
sessionID: string
|
||||
todos: Array<Todo>
|
||||
}
|
||||
}
|
||||
|
||||
export type SessionStatus =
|
||||
| {
|
||||
type: "idle"
|
||||
|
|
@ -551,6 +544,40 @@ export type EventSessionCompacted = {
|
|||
}
|
||||
}
|
||||
|
||||
export type EventFileEdited = {
|
||||
type: "file.edited"
|
||||
properties: {
|
||||
file: string
|
||||
}
|
||||
}
|
||||
|
||||
export type Todo = {
|
||||
/**
|
||||
* Brief description of the task
|
||||
*/
|
||||
content: string
|
||||
/**
|
||||
* Current status of the task: pending, in_progress, completed, cancelled
|
||||
*/
|
||||
status: string
|
||||
/**
|
||||
* Priority level of the task: high, medium, low
|
||||
*/
|
||||
priority: string
|
||||
/**
|
||||
* Unique identifier for the todo item
|
||||
*/
|
||||
id: string
|
||||
}
|
||||
|
||||
export type EventTodoUpdated = {
|
||||
type: "todo.updated"
|
||||
properties: {
|
||||
sessionID: string
|
||||
todos: Array<Todo>
|
||||
}
|
||||
}
|
||||
|
||||
export type EventTuiPromptAppend = {
|
||||
type: "tui.prompt.append"
|
||||
properties: {
|
||||
|
|
@ -756,13 +783,15 @@ export type Event =
|
|||
| EventMessageRemoved
|
||||
| EventMessagePartUpdated
|
||||
| EventMessagePartRemoved
|
||||
| EventPermissionNextAsked
|
||||
| EventPermissionNextReplied
|
||||
| EventPermissionUpdated
|
||||
| EventPermissionReplied
|
||||
| EventFileEdited
|
||||
| EventTodoUpdated
|
||||
| EventSessionStatus
|
||||
| EventSessionIdle
|
||||
| EventSessionCompacted
|
||||
| EventFileEdited
|
||||
| EventTodoUpdated
|
||||
| EventTuiPromptAppend
|
||||
| EventTuiCommandExecute
|
||||
| EventTuiToastShow
|
||||
|
|
@ -1183,11 +1212,42 @@ export type ServerConfig = {
|
|||
cors?: Array<string>
|
||||
}
|
||||
|
||||
export type PermissionActionConfig = "ask" | "allow" | "deny"
|
||||
|
||||
export type PermissionObjectConfig = {
|
||||
[key: string]: PermissionActionConfig
|
||||
}
|
||||
|
||||
export type PermissionRuleConfig = PermissionActionConfig | PermissionObjectConfig
|
||||
|
||||
export type PermissionConfig =
|
||||
| {
|
||||
read?: PermissionRuleConfig
|
||||
edit?: PermissionRuleConfig
|
||||
glob?: PermissionRuleConfig
|
||||
grep?: PermissionRuleConfig
|
||||
list?: PermissionRuleConfig
|
||||
bash?: PermissionRuleConfig
|
||||
task?: PermissionRuleConfig
|
||||
external_directory?: PermissionRuleConfig
|
||||
todowrite?: PermissionActionConfig
|
||||
todoread?: PermissionActionConfig
|
||||
webfetch?: PermissionActionConfig
|
||||
websearch?: PermissionActionConfig
|
||||
codesearch?: PermissionActionConfig
|
||||
doom_loop?: PermissionActionConfig
|
||||
[key: string]: PermissionRuleConfig | PermissionActionConfig | undefined
|
||||
}
|
||||
| PermissionActionConfig
|
||||
|
||||
export type AgentConfig = {
|
||||
model?: string
|
||||
temperature?: number
|
||||
top_p?: number
|
||||
prompt?: string
|
||||
/**
|
||||
* @deprecated Use 'permission' field instead
|
||||
*/
|
||||
tools?: {
|
||||
[key: string]: boolean
|
||||
}
|
||||
|
|
@ -1197,6 +1257,9 @@ export type AgentConfig = {
|
|||
*/
|
||||
description?: string
|
||||
mode?: "subagent" | "primary" | "all"
|
||||
options?: {
|
||||
[key: string]: unknown
|
||||
}
|
||||
/**
|
||||
* Hex color code for the agent (e.g., #FF5733)
|
||||
*/
|
||||
|
|
@ -1204,27 +1267,12 @@ export type AgentConfig = {
|
|||
/**
|
||||
* Maximum number of agentic iterations before forcing text-only response
|
||||
*/
|
||||
steps?: number
|
||||
/**
|
||||
* @deprecated Use 'steps' field instead.
|
||||
*/
|
||||
maxSteps?: number
|
||||
permission?: {
|
||||
edit?: "ask" | "allow" | "deny"
|
||||
bash?:
|
||||
| "ask"
|
||||
| "allow"
|
||||
| "deny"
|
||||
| {
|
||||
[key: string]: "ask" | "allow" | "deny"
|
||||
}
|
||||
skill?:
|
||||
| "ask"
|
||||
| "allow"
|
||||
| "deny"
|
||||
| {
|
||||
[key: string]: "ask" | "allow" | "deny"
|
||||
}
|
||||
webfetch?: "ask" | "allow" | "deny"
|
||||
doom_loop?: "ask" | "allow" | "deny"
|
||||
external_directory?: "ask" | "allow" | "deny"
|
||||
}
|
||||
permission?: PermissionConfig
|
||||
[key: string]:
|
||||
| unknown
|
||||
| string
|
||||
|
|
@ -1236,28 +1284,12 @@ export type AgentConfig = {
|
|||
| "subagent"
|
||||
| "primary"
|
||||
| "all"
|
||||
| {
|
||||
[key: string]: unknown
|
||||
}
|
||||
| string
|
||||
| number
|
||||
| {
|
||||
edit?: "ask" | "allow" | "deny"
|
||||
bash?:
|
||||
| "ask"
|
||||
| "allow"
|
||||
| "deny"
|
||||
| {
|
||||
[key: string]: "ask" | "allow" | "deny"
|
||||
}
|
||||
skill?:
|
||||
| "ask"
|
||||
| "allow"
|
||||
| "deny"
|
||||
| {
|
||||
[key: string]: "ask" | "allow" | "deny"
|
||||
}
|
||||
webfetch?: "ask" | "allow" | "deny"
|
||||
doom_loop?: "ask" | "allow" | "deny"
|
||||
external_directory?: "ask" | "allow" | "deny"
|
||||
}
|
||||
| PermissionConfig
|
||||
| undefined
|
||||
}
|
||||
|
||||
|
|
@ -1578,26 +1610,7 @@ export type Config = {
|
|||
*/
|
||||
instructions?: Array<string>
|
||||
layout?: LayoutConfig
|
||||
permission?: {
|
||||
edit?: "ask" | "allow" | "deny"
|
||||
bash?:
|
||||
| "ask"
|
||||
| "allow"
|
||||
| "deny"
|
||||
| {
|
||||
[key: string]: "ask" | "allow" | "deny"
|
||||
}
|
||||
skill?:
|
||||
| "ask"
|
||||
| "allow"
|
||||
| "deny"
|
||||
| {
|
||||
[key: string]: "ask" | "allow" | "deny"
|
||||
}
|
||||
webfetch?: "ask" | "allow" | "deny"
|
||||
doom_loop?: "ask" | "allow" | "deny"
|
||||
external_directory?: "ask" | "allow" | "deny"
|
||||
}
|
||||
permission?: PermissionConfig
|
||||
tools?: {
|
||||
[key: string]: boolean
|
||||
}
|
||||
|
|
@ -1880,40 +1893,35 @@ export type File = {
|
|||
status: "added" | "deleted" | "modified"
|
||||
}
|
||||
|
||||
export type PermissionAction = "allow" | "deny" | "ask"
|
||||
|
||||
export type PermissionRule = {
|
||||
permission: string
|
||||
pattern: string
|
||||
action: PermissionAction
|
||||
}
|
||||
|
||||
export type PermissionRuleset = Array<PermissionRule>
|
||||
|
||||
export type Agent = {
|
||||
name: string
|
||||
description?: string
|
||||
mode: "subagent" | "primary" | "all"
|
||||
native?: boolean
|
||||
hidden?: boolean
|
||||
default?: boolean
|
||||
topP?: number
|
||||
temperature?: number
|
||||
color?: string
|
||||
permission: {
|
||||
edit: "ask" | "allow" | "deny"
|
||||
bash: {
|
||||
[key: string]: "ask" | "allow" | "deny"
|
||||
}
|
||||
skill: {
|
||||
[key: string]: "ask" | "allow" | "deny"
|
||||
}
|
||||
webfetch?: "ask" | "allow" | "deny"
|
||||
doom_loop?: "ask" | "allow" | "deny"
|
||||
external_directory?: "ask" | "allow" | "deny"
|
||||
}
|
||||
permission: PermissionRuleset
|
||||
model?: {
|
||||
modelID: string
|
||||
providerID: string
|
||||
}
|
||||
prompt?: string
|
||||
tools: {
|
||||
[key: string]: boolean
|
||||
}
|
||||
options: {
|
||||
[key: string]: unknown
|
||||
}
|
||||
maxSteps?: number
|
||||
steps?: number
|
||||
}
|
||||
|
||||
export type McpStatusConnected = {
|
||||
|
|
@ -3391,6 +3399,41 @@ export type PermissionRespondResponses = {
|
|||
|
||||
export type PermissionRespondResponse = PermissionRespondResponses[keyof PermissionRespondResponses]
|
||||
|
||||
export type PermissionReplyData = {
|
||||
body?: {
|
||||
reply: "once" | "always" | "reject"
|
||||
}
|
||||
path: {
|
||||
requestID: string
|
||||
}
|
||||
query?: {
|
||||
directory?: string
|
||||
}
|
||||
url: "/permission/{requestID}/reply"
|
||||
}
|
||||
|
||||
export type PermissionReplyErrors = {
|
||||
/**
|
||||
* Bad request
|
||||
*/
|
||||
400: BadRequestError
|
||||
/**
|
||||
* Not found
|
||||
*/
|
||||
404: NotFoundError
|
||||
}
|
||||
|
||||
export type PermissionReplyError = PermissionReplyErrors[keyof PermissionReplyErrors]
|
||||
|
||||
export type PermissionReplyResponses = {
|
||||
/**
|
||||
* Permission processed successfully
|
||||
*/
|
||||
200: boolean
|
||||
}
|
||||
|
||||
export type PermissionReplyResponse = PermissionReplyResponses[keyof PermissionReplyResponses]
|
||||
|
||||
export type PermissionListData = {
|
||||
body?: never
|
||||
path?: never
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
<<<<<<< HEAD
|
||||
{
|
||||
"openapi": "3.1.1",
|
||||
"info": {
|
||||
|
|
@ -9750,3 +9751,6 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
=======
|
||||
{}
|
||||
>>>>>>> 4f732c838 (feat: add command-aware permission request system for granular tool approval)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue