File tree Expand file tree Collapse file tree 2 files changed +35
-4
lines changed
tui/internal/components/chat Expand file tree Collapse file tree 2 files changed +35
-4
lines changed Original file line number Diff line number Diff line change @@ -56,6 +56,7 @@ export namespace SessionPrompt {
5656 const log = Log . create ( { service : "session.prompt" } )
5757 export const OUTPUT_TOKEN_MAX = 32_000
5858 const MAX_RETRIES = 10
59+ const DOOM_LOOP_THRESHOLD = 3
5960
6061 export const Event = {
6162 Idle : Bus . event (
@@ -1068,6 +1069,32 @@ export namespace SessionPrompt {
10681069 metadata : value . providerMetadata ,
10691070 } )
10701071 toolcalls [ value . toolCallId ] = part as MessageV2 . ToolPart
1072+
1073+ const parts = await Session . getParts ( assistantMsg . id )
1074+ const lastThree = parts . slice ( - DOOM_LOOP_THRESHOLD )
1075+ if (
1076+ lastThree . length === DOOM_LOOP_THRESHOLD &&
1077+ lastThree . every (
1078+ ( p ) =>
1079+ p . type === "tool" &&
1080+ p . tool === value . toolName &&
1081+ p . state . status !== "pending" &&
1082+ JSON . stringify ( p . state . input ) === JSON . stringify ( value . input ) ,
1083+ )
1084+ ) {
1085+ await Permission . ask ( {
1086+ type : "doom-loop" ,
1087+ pattern : value . toolName ,
1088+ sessionID : assistantMsg . sessionID ,
1089+ messageID : assistantMsg . id ,
1090+ callID : value . toolCallId ,
1091+ title : `Possible doom loop: "${ value . toolName } " called ${ DOOM_LOOP_THRESHOLD } times with identical arguments` ,
1092+ metadata : {
1093+ tool : value . toolName ,
1094+ input : value . input ,
1095+ } ,
1096+ } )
1097+ }
10711098 }
10721099 break
10731100 }
Original file line number Diff line number Diff line change @@ -504,7 +504,11 @@ func renderToolDetails(
504504 base := styles .NewStyle ().Background (backgroundColor )
505505 text := base .Foreground (t .Text ()).Bold (true ).Render
506506 muted := base .Foreground (t .TextMuted ()).Render
507- permissionContent = "Permission required to run this tool:\n \n "
507+ if permission .Type == "doom-loop" {
508+ permissionContent = permission .Title + "\n \n "
509+ } else {
510+ permissionContent = "Permission required to run this tool:\n \n "
511+ }
508512 permissionContent += text (
509513 "enter " ,
510514 ) + muted (
@@ -642,9 +646,9 @@ func renderToolDetails(
642646 for _ , item := range todos .([]any ) {
643647 todo := item .(map [string ]any )
644648 content := todo ["content" ]
645- if content == nil {
646- continue
647- }
649+ if content == nil {
650+ continue
651+ }
648652 switch todo ["status" ] {
649653 case "completed" :
650654 body += fmt .Sprintf ("- [x] %s\n " , content )
You can’t perform that action at this time.
0 commit comments