@@ -17,6 +17,8 @@ interface PiResponse extends ToolResponse {
1717 diff ?: string
1818 prUrl ?: string
1919 branch ?: string
20+ reviewUrl ?: string
21+ commentsPosted ?: number
2022 tokens ?: {
2123 input ?: number
2224 output ?: number
@@ -36,7 +38,19 @@ interface PiResponse extends ToolResponse {
3638}
3739
3840const CLOUD : { field : 'mode' ; value : 'cloud' } = { field : 'mode' , value : 'cloud' }
41+ const CLOUD_REVIEW : { field : 'mode' ; value : 'cloud_review' } = {
42+ field : 'mode' ,
43+ value : 'cloud_review' ,
44+ }
45+ const CLOUD_ANY : { field : 'mode' ; value : Array < 'cloud' | 'cloud_review' > } = {
46+ field : 'mode' ,
47+ value : [ 'cloud' , 'cloud_review' ] ,
48+ }
3949const LOCAL : { field : 'mode' ; value : 'local' } = { field : 'mode' , value : 'local' }
50+ const AUTHORING_MODES : { field : 'mode' ; value : Array < 'cloud' | 'local' > } = {
51+ field : 'mode' ,
52+ value : [ 'cloud' , 'local' ] ,
53+ }
4054const MEMORY_TYPES = [ 'conversation' , 'sliding_window' , 'sliding_window_tokens' ]
4155
4256export const PiBlock : BlockConfig < PiResponse > = {
@@ -45,11 +59,12 @@ export const PiBlock: BlockConfig<PiResponse> = {
4559 description : 'Run an autonomous coding agent on a repo' ,
4660 authMode : AuthMode . ApiKey ,
4761 longDescription :
48- 'The Pi Coding Agent runs the Pi harness against a real repository. In Cloud mode it spins up an isolated sandbox, clones a connected GitHub repo, edits and tests with native shell + git, and opens a pull request. In Local mode it edits files on your own machine over SSH. Both modes stream progress and reuse your models, skills, and multi-turn memory.' ,
62+ 'The Pi Coding Agent runs the Pi harness against a real repository. Create PR spins up an isolated sandbox, clones a GitHub repo, edits with native shell + git, and opens a pull request. Review Code checks out a pinned PR snapshot with read-only tools and posts a structured review with optional inline comments. Local Dev edits files on your own machine over SSH. Create PR and Local Dev can reuse skills and multi-turn memory; Review Code runs without either because PR contents are untrusted .' ,
4963 bestPractices : `
50- - Use Cloud mode for hands-off changes against a GitHub repo where a reviewable PR is the deliverable.
51- - Use Local mode to edit a repo on your own machine; expose the machine on a public hostname/tunnel so Sim can reach it over SSH.
52- - Cloud mode requires your own provider API key (BYOK); the model key is never injected as a hosted key into the sandbox.
64+ - Use Create PR for hands-off changes against a GitHub repo where a reviewable PR is the deliverable.
65+ - Use Review Code to analyze an existing PR and leave summary + inline review comments.
66+ - Use Local Dev to edit a repo on your own machine; expose the machine on a public hostname/tunnel so Sim can reach it over SSH.
67+ - Create PR requires your own provider API key because the model runs in the sandbox. Review Code keeps the model key in Sim and can use either BYOK or a hosted key.
5368 ` ,
5469 category : 'blocks' ,
5570 integrationType : IntegrationType . AI ,
@@ -60,22 +75,29 @@ export const PiBlock: BlockConfig<PiResponse> = {
6075 id : 'mode' ,
6176 title : 'Mode' ,
6277 type : 'dropdown' ,
63- // Cloud mode runs in an E2B sandbox; only offer it where E2B is enabled.
78+ /** Create PR and Review Code require E2B and stay hidden when it is disabled. */
6479 value : ( ) => ( isTruthy ( getEnv ( 'NEXT_PUBLIC_E2B_ENABLED' ) ) ? 'cloud' : 'local' ) ,
6580 options : ( ) => {
6681 const options = [
6782 {
68- label : 'Local' ,
83+ label : 'Local Dev ' ,
6984 id : 'local' ,
7085 description : 'Edits files on your own machine over SSH' ,
7186 } ,
7287 ]
7388 if ( isTruthy ( getEnv ( 'NEXT_PUBLIC_E2B_ENABLED' ) ) ) {
74- options . unshift ( {
75- label : 'Cloud' ,
76- id : 'cloud' ,
77- description : 'Runs in an isolated sandbox, clones your repo, and opens a PR' ,
78- } )
89+ options . unshift (
90+ {
91+ label : 'Create PR' ,
92+ id : 'cloud' ,
93+ description : 'Runs in an isolated sandbox, clones your repo, and opens a PR' ,
94+ } ,
95+ {
96+ label : 'Review Code' ,
97+ id : 'cloud_review' ,
98+ description : 'Reviews an existing PR and posts GitHub review comments' ,
99+ }
100+ )
79101 }
80102 return options
81103 } ,
@@ -93,7 +115,7 @@ export const PiBlock: BlockConfig<PiResponse> = {
93115 type : 'combobox' ,
94116 placeholder : 'Type or select a model...' ,
95117 required : true ,
96- defaultValue : 'claude-sonnet-5 ' ,
118+ defaultValue : 'claude-sonnet-4-6 ' ,
97119 options : getPiModelOptions ,
98120 commandSearchable : true ,
99121 } ,
@@ -106,26 +128,27 @@ export const PiBlock: BlockConfig<PiResponse> = {
106128 type : 'short-input' ,
107129 placeholder : 'e.g., your-org' ,
108130 required : true ,
109- condition : CLOUD ,
131+ condition : CLOUD_ANY ,
110132 } ,
111133 {
112134 id : 'repo' ,
113135 title : 'Repository Name' ,
114136 type : 'short-input' ,
115137 placeholder : 'e.g., my-repo' ,
116138 required : true ,
117- condition : CLOUD ,
139+ condition : CLOUD_ANY ,
118140 } ,
119141 {
120142 id : 'githubToken' ,
121143 title : 'GitHub Token' ,
122144 type : 'short-input' ,
123145 password : true ,
124146 paramVisibility : 'user-only' ,
125- placeholder : 'GitHub personal access token (repo scope)' ,
126- tooltip : 'Personal access token with repo scope, used to clone, push, and open the PR.' ,
147+ placeholder : 'GitHub personal access token' ,
148+ tooltip :
149+ 'Personal access token used for GitHub access. Create PR needs clone/push/PR permissions; Review Code needs clone + review permissions.' ,
127150 required : true ,
128- condition : CLOUD ,
151+ condition : CLOUD_ANY ,
129152 } ,
130153 {
131154 id : 'baseBranch' ,
@@ -167,6 +190,27 @@ export const PiBlock: BlockConfig<PiResponse> = {
167190 mode : 'advanced' ,
168191 condition : CLOUD ,
169192 } ,
193+ {
194+ id : 'pullNumber' ,
195+ title : 'Pull Request Number' ,
196+ type : 'short-input' ,
197+ placeholder : 'e.g., 42' ,
198+ required : true ,
199+ condition : CLOUD_REVIEW ,
200+ } ,
201+ {
202+ id : 'reviewEvent' ,
203+ title : 'Review Outcome' ,
204+ type : 'dropdown' ,
205+ defaultValue : 'COMMENT' ,
206+ options : [
207+ { label : 'Comment' , id : 'COMMENT' } ,
208+ { label : 'Request changes' , id : 'REQUEST_CHANGES' } ,
209+ ] ,
210+ tooltip :
211+ 'How GitHub records the submitted review. Comment is neutral; Request changes marks the pull request as changes requested.' ,
212+ condition : CLOUD_REVIEW ,
213+ } ,
170214
171215 {
172216 id : 'host' ,
@@ -275,6 +319,7 @@ export const PiBlock: BlockConfig<PiResponse> = {
275319 type : 'skill-input' ,
276320 defaultValue : [ ] ,
277321 mode : 'advanced' ,
322+ condition : AUTHORING_MODES ,
278323 } ,
279324 {
280325 id : 'thinkingLevel' ,
@@ -288,6 +333,8 @@ export const PiBlock: BlockConfig<PiResponse> = {
288333 { label : 'high' , id : 'high' } ,
289334 { label : 'max' , id : 'max' } ,
290335 ] ,
336+ tooltip :
337+ "Requested reasoning effort for Pi. Pi clamps it to the selected model's supported levels; models without reasoning run with thinking off. Higher levels usually increase latency and token cost." ,
291338 mode : 'advanced' ,
292339 } ,
293340 {
@@ -302,15 +349,24 @@ export const PiBlock: BlockConfig<PiResponse> = {
302349 { label : 'Sliding window (tokens)' , id : 'sliding_window_tokens' } ,
303350 ] ,
304351 mode : 'advanced' ,
352+ condition : AUTHORING_MODES ,
305353 } ,
306354 {
307355 id : 'conversationId' ,
308356 title : 'Conversation ID' ,
309357 type : 'short-input' ,
310358 placeholder : 'e.g., user-123, session-abc' ,
311359 mode : 'advanced' ,
312- required : { field : 'memoryType' , value : MEMORY_TYPES } ,
313- condition : { field : 'memoryType' , value : MEMORY_TYPES } ,
360+ required : {
361+ field : 'mode' ,
362+ value : [ 'cloud' , 'local' ] ,
363+ and : { field : 'memoryType' , value : MEMORY_TYPES } ,
364+ } ,
365+ condition : {
366+ field : 'mode' ,
367+ value : [ 'cloud' , 'local' ] ,
368+ and : { field : 'memoryType' , value : MEMORY_TYPES } ,
369+ } ,
314370 dependsOn : [ 'memoryType' ] ,
315371 } ,
316372 {
@@ -319,7 +375,11 @@ export const PiBlock: BlockConfig<PiResponse> = {
319375 type : 'short-input' ,
320376 placeholder : 'Enter number of messages (e.g., 10)...' ,
321377 mode : 'advanced' ,
322- condition : { field : 'memoryType' , value : [ 'sliding_window' ] } ,
378+ condition : {
379+ field : 'mode' ,
380+ value : [ 'cloud' , 'local' ] ,
381+ and : { field : 'memoryType' , value : [ 'sliding_window' ] } ,
382+ } ,
323383 dependsOn : [ 'memoryType' ] ,
324384 } ,
325385 {
@@ -328,34 +388,46 @@ export const PiBlock: BlockConfig<PiResponse> = {
328388 type : 'short-input' ,
329389 placeholder : 'Enter max tokens (e.g., 4000)...' ,
330390 mode : 'advanced' ,
331- condition : { field : 'memoryType' , value : [ 'sliding_window_tokens' ] } ,
391+ condition : {
392+ field : 'mode' ,
393+ value : [ 'cloud' , 'local' ] ,
394+ and : { field : 'memoryType' , value : [ 'sliding_window_tokens' ] } ,
395+ } ,
332396 dependsOn : [ 'memoryType' ] ,
333397 } ,
334398 ] ,
335399 tools : {
336400 access : [ ] ,
337401 } ,
338402 inputs : {
339- mode : { type : 'string' , description : 'Execution mode: cloud or local' } ,
403+ mode : {
404+ type : 'string' ,
405+ description : 'Execution mode: Create PR, Review Code, or Local Dev' ,
406+ } ,
340407 task : { type : 'string' , description : 'Instruction for the coding agent' } ,
341408 model : { type : 'string' , description : 'AI model to use' } ,
342- owner : { type : 'string' , description : 'GitHub repository owner (cloud mode)' } ,
343- repo : { type : 'string' , description : 'GitHub repository name (cloud mode)' } ,
344- githubToken : { type : 'string' , description : 'GitHub token override (cloud mode)' } ,
345- baseBranch : { type : 'string' , description : 'Base branch for the PR (cloud mode)' } ,
346- branchName : { type : 'string' , description : 'Branch to create (cloud mode)' } ,
347- draft : { type : 'boolean' , description : 'Open the PR as a draft (cloud mode)' } ,
348- prTitle : { type : 'string' , description : 'Pull request title (cloud mode)' } ,
349- prBody : { type : 'string' , description : 'Pull request body (cloud mode)' } ,
350- host : { type : 'string' , description : 'SSH host (local mode)' } ,
351- port : { type : 'number' , description : 'SSH port (local mode)' } ,
352- username : { type : 'string' , description : 'SSH username (local mode)' } ,
353- authMethod : { type : 'string' , description : 'SSH authentication method (local mode)' } ,
354- password : { type : 'string' , description : 'SSH password (local mode)' } ,
355- privateKey : { type : 'string' , description : 'SSH private key (local mode)' } ,
356- passphrase : { type : 'string' , description : 'SSH key passphrase (local mode)' } ,
357- repoPath : { type : 'string' , description : 'Repository path on the target (local mode)' } ,
358- tools : { type : 'json' , description : 'Sim tools exposed to the agent (local mode)' } ,
409+ owner : { type : 'string' , description : 'GitHub repository owner (Create PR and Review Code)' } ,
410+ repo : { type : 'string' , description : 'GitHub repository name (Create PR and Review Code)' } ,
411+ githubToken : { type : 'string' , description : 'GitHub token (Create PR and Review Code)' } ,
412+ baseBranch : { type : 'string' , description : 'Base branch for the PR (Create PR)' } ,
413+ branchName : { type : 'string' , description : 'Branch to create (Create PR)' } ,
414+ draft : { type : 'boolean' , description : 'Open the PR as a draft (Create PR)' } ,
415+ prTitle : { type : 'string' , description : 'Pull request title (Create PR)' } ,
416+ prBody : { type : 'string' , description : 'Pull request body (Create PR)' } ,
417+ pullNumber : { type : 'number' , description : 'Pull request number (Review Code)' } ,
418+ reviewEvent : {
419+ type : 'string' ,
420+ description : 'GitHub review event: COMMENT or REQUEST_CHANGES' ,
421+ } ,
422+ host : { type : 'string' , description : 'SSH host (Local Dev)' } ,
423+ port : { type : 'number' , description : 'SSH port (Local Dev)' } ,
424+ username : { type : 'string' , description : 'SSH username (Local Dev)' } ,
425+ authMethod : { type : 'string' , description : 'SSH authentication method (Local Dev)' } ,
426+ password : { type : 'string' , description : 'SSH password (Local Dev)' } ,
427+ privateKey : { type : 'string' , description : 'SSH private key (Local Dev)' } ,
428+ passphrase : { type : 'string' , description : 'SSH key passphrase (Local Dev)' } ,
429+ repoPath : { type : 'string' , description : 'Repository path on the target (Local Dev)' } ,
430+ tools : { type : 'json' , description : 'Sim tools exposed to the agent (Local Dev)' } ,
359431 skills : { type : 'json' , description : 'Selected skills configuration' } ,
360432 thinkingLevel : { type : 'string' , description : 'Thinking level for the model' } ,
361433 memoryType : { type : 'string' , description : 'Memory type for multi-turn conversations' } ,
@@ -379,6 +451,16 @@ export const PiBlock: BlockConfig<PiResponse> = {
379451 description : 'Branch pushed with the changes' ,
380452 condition : CLOUD ,
381453 } ,
454+ reviewUrl : {
455+ type : 'string' ,
456+ description : 'URL of the submitted GitHub review' ,
457+ condition : CLOUD_REVIEW ,
458+ } ,
459+ commentsPosted : {
460+ type : 'number' ,
461+ description : 'Number of inline review comments posted' ,
462+ condition : CLOUD_REVIEW ,
463+ } ,
382464 tokens : { type : 'json' , description : 'Token usage statistics' } ,
383465 cost : { type : 'json' , description : 'Cost of the run' } ,
384466 providerTiming : { type : 'json' , description : 'Provider timing information' } ,
0 commit comments