@@ -5,6 +5,7 @@ import { Provider } from "../provider/provider"
55import { generateObject , type ModelMessage } from "ai"
66import PROMPT_GENERATE from "./generate.txt"
77import { SystemPrompt } from "../session/system"
8+ import { mergeDeep } from "remeda"
89
910export namespace Agent {
1011 export const Info = z
@@ -14,6 +15,11 @@ export namespace Agent {
1415 mode : z . union ( [ z . literal ( "subagent" ) , z . literal ( "primary" ) , z . literal ( "all" ) ] ) ,
1516 topP : z . number ( ) . optional ( ) ,
1617 temperature : z . number ( ) . optional ( ) ,
18+ permission : z . object ( {
19+ edit : Config . Permission ,
20+ bash : z . record ( z . string ( ) , Config . Permission ) ,
21+ webfetch : Config . Permission . optional ( ) ,
22+ } ) ,
1723 model : z
1824 . object ( {
1925 modelID : z . string ( ) ,
@@ -31,6 +37,13 @@ export namespace Agent {
3137
3238 const state = App . state ( "agent" , async ( ) => {
3339 const cfg = await Config . get ( )
40+ const defaultPermission : Info [ "permission" ] = {
41+ edit : "allow" ,
42+ bash : {
43+ "*" : "allow" ,
44+ } ,
45+ webfetch : "allow" ,
46+ }
3447 const result : Record < string , Info > = {
3548 general : {
3649 name : "general" ,
@@ -41,17 +54,20 @@ export namespace Agent {
4154 todowrite : false ,
4255 } ,
4356 options : { } ,
57+ permission : defaultPermission ,
4458 mode : "subagent" ,
4559 } ,
4660 build : {
4761 name : "build" ,
4862 tools : { } ,
4963 options : { } ,
64+ permission : defaultPermission ,
5065 mode : "primary" ,
5166 } ,
5267 plan : {
5368 name : "plan" ,
5469 options : { } ,
70+ permission : defaultPermission ,
5571 tools : {
5672 write : false ,
5773 edit : false ,
@@ -70,25 +86,48 @@ export namespace Agent {
7086 item = result [ key ] = {
7187 name : key ,
7288 mode : "all" ,
89+ permission : defaultPermission ,
7390 options : { } ,
7491 tools : { } ,
7592 }
76- const { model, prompt, tools, description, temperature, top_p, mode, ...extra } = value
93+ const { model, prompt, tools, description, temperature, top_p, mode, permission , ...extra } = value
7794 item . options = {
7895 ...item . options ,
7996 ...extra ,
8097 }
81- if ( value . model ) item . model = Provider . parseModel ( value . model )
82- if ( value . prompt ) item . prompt = value . prompt
83- if ( value . tools )
98+ if ( model ) item . model = Provider . parseModel ( model )
99+ if ( prompt ) item . prompt = prompt
100+ if ( tools )
84101 item . tools = {
85102 ...item . tools ,
86- ...value . tools ,
103+ ...tools ,
87104 }
88- if ( value . description ) item . description = value . description
89- if ( value . temperature != undefined ) item . temperature = value . temperature
90- if ( value . top_p != undefined ) item . topP = value . top_p
91- if ( value . mode ) item . mode = value . mode
105+ if ( description ) item . description = description
106+ if ( temperature != undefined ) item . temperature = temperature
107+ if ( top_p != undefined ) item . topP = top_p
108+ if ( mode ) item . mode = mode
109+
110+ if ( permission ?? cfg . permission ) {
111+ const merged = mergeDeep ( cfg . permission ?? { } , permission ?? { } )
112+ if ( merged . edit ) item . permission . edit = merged . edit
113+ if ( merged . webfetch ) item . permission . webfetch = merged . webfetch
114+ if ( merged . bash ) {
115+ if ( typeof merged . bash === "string" ) {
116+ item . permission . bash = {
117+ "*" : merged . bash ,
118+ }
119+ }
120+ // if granular permissions are provided, default to "ask"
121+ if ( typeof merged . bash === "object" ) {
122+ item . permission . bash = mergeDeep (
123+ {
124+ "*" : "ask" ,
125+ } ,
126+ merged . bash ,
127+ )
128+ }
129+ }
130+ }
92131 }
93132 return result
94133 } )
0 commit comments