44package aiusechat
55
66import (
7+ "encoding/json"
78 "fmt"
89 "strings"
910 "time"
@@ -15,6 +16,60 @@ import (
1516 "github.com/wavetermdev/waveterm/pkg/wshutil"
1617)
1718
19+ type TermGetScrollbackToolInput struct {
20+ LineStart int `json:"line_start,omitempty"`
21+ Count int `json:"count,omitempty"`
22+ }
23+
24+ type TermGetScrollbackToolOutput struct {
25+ TotalLines int `json:"total_lines"`
26+ LineStart int `json:"line_start"`
27+ LineEnd int `json:"line_end"`
28+ ReturnedLines int `json:"returned_lines"`
29+ Content string `json:"content"`
30+ SinceLastOutputSec * int `json:"since_last_output_sec,omitempty"`
31+ HasMore bool `json:"has_more"`
32+ NextStart * int `json:"next_start"`
33+ }
34+
35+ func parseTermGetScrollbackInput (input any ) (* TermGetScrollbackToolInput , error ) {
36+ const (
37+ DefaultCount = 200
38+ MaxCount = 1000
39+ )
40+
41+ result := & TermGetScrollbackToolInput {
42+ LineStart : 0 ,
43+ Count : 0 ,
44+ }
45+
46+ if input == nil {
47+ result .Count = DefaultCount
48+ return result , nil
49+ }
50+
51+ inputBytes , err := json .Marshal (input )
52+ if err != nil {
53+ return nil , fmt .Errorf ("failed to marshal input: %w" , err )
54+ }
55+
56+ if err := json .Unmarshal (inputBytes , result ); err != nil {
57+ return nil , fmt .Errorf ("failed to unmarshal input: %w" , err )
58+ }
59+
60+ if result .Count == 0 {
61+ result .Count = DefaultCount
62+ }
63+
64+ if result .Count < 0 {
65+ return nil , fmt .Errorf ("count must be positive" )
66+ }
67+
68+ result .Count = min (result .Count , MaxCount )
69+
70+ return result , nil
71+ }
72+
1873func GetTermGetScrollbackToolDefinition (block * waveobj.Block ) uctypes.ToolDefinition {
1974 blockIdPrefix := block .OID [:8 ]
2075 toolName := fmt .Sprintf ("term_get_scrollback_%s" , blockIdPrefix )
@@ -27,90 +82,45 @@ func GetTermGetScrollbackToolDefinition(block *waveobj.Block) uctypes.ToolDefini
2782 InputSchema : map [string ]any {
2883 "type" : "object" ,
2984 "properties" : map [string ]any {
30- "linestart " : map [string ]any {
85+ "line_start " : map [string ]any {
3186 "type" : "integer" ,
3287 "minimum" : 0 ,
3388 "description" : "Logical start index where 0 = most recent line (default: 0)" ,
3489 },
35- "lineend" : map [string ]any {
36- "type" : "integer" ,
37- "minimum" : 0 ,
38- "description" : "Exclusive end index. Returns lines [linestart, lineend)" ,
39- },
4090 "count" : map [string ]any {
4191 "type" : "integer" ,
4292 "minimum" : 1 ,
43- "description" : "Alternative to lineend: number of lines to return from linestart (default: 200)" ,
93+ "description" : "Number of lines to return from line_start (default: 200)" ,
4494 },
4595 },
4696 "required" : []string {},
4797 "additionalProperties" : false ,
4898 },
4999 ToolInputDesc : func (input any ) string {
50- const DEFAULT_COUNT = 200
51- inputMap := make (map [string ]any )
52- if input != nil {
53- if m , ok := input .(map [string ]any ); ok {
54- inputMap = m
55- }
56- }
57-
58- lineStart := 0
59- if val , ok := inputMap ["linestart" ].(float64 ); ok {
60- lineStart = int (val )
61- }
62-
63- count := DEFAULT_COUNT
64- if val , ok := inputMap ["count" ].(float64 ); ok {
65- count = int (val )
66- } else if lineEndVal , ok := inputMap ["lineend" ].(float64 ); ok {
67- lineEnd := int (lineEndVal )
68- count = lineEnd - lineStart
100+ parsed , err := parseTermGetScrollbackInput (input )
101+ if err != nil {
102+ return fmt .Sprintf ("error parsing input: %v" , err )
69103 }
70104
71- if lineStart == 0 && count == DEFAULT_COUNT {
72- return fmt .Sprintf ("reading terminal output from %s (most recent %d lines)" , blockIdPrefix , count )
105+ if parsed . LineStart == 0 && parsed . Count == 200 {
106+ return fmt .Sprintf ("reading terminal output from %s (most recent %d lines)" , blockIdPrefix , parsed . Count )
73107 }
74- lineEnd := lineStart + count
75- return fmt .Sprintf ("reading terminal output from %s (lines %d-%d)" , blockIdPrefix , lineStart , lineEnd )
108+ lineEnd := parsed . LineStart + parsed . Count
109+ return fmt .Sprintf ("reading terminal output from %s (lines %d-%d)" , blockIdPrefix , parsed . LineStart , lineEnd )
76110 },
77111 ToolAnyCallback : func (input any ) (any , error ) {
78- const DEFAULT_COUNT = 200
79- const MAX_COUNT = 1000
80-
81- inputMap := make (map [string ]any )
82- if input != nil {
83- var ok bool
84- inputMap , ok = input .(map [string ]any )
85- if ! ok {
86- return nil , fmt .Errorf ("invalid input format" )
87- }
88- }
89-
90- lineStart := 0
91- if val , ok := inputMap ["linestart" ].(float64 ); ok {
92- lineStart = int (val )
93- }
94-
95- count := DEFAULT_COUNT
96- if val , ok := inputMap ["count" ].(float64 ); ok {
97- count = int (val )
98- } else if lineEndVal , ok := inputMap ["lineend" ].(float64 ); ok {
99- lineEnd := int (lineEndVal )
100- count = lineEnd - lineStart
112+ parsed , err := parseTermGetScrollbackInput (input )
113+ if err != nil {
114+ return nil , err
101115 }
102116
103- count = min (count , MAX_COUNT )
104- if count < 0 {
105- count = 0
106- }
107- lineEnd := lineStart + count
117+ lineEnd := parsed .LineStart + parsed .Count
108118
109119 rpcClient := wshclient .GetBareRpcClient ()
110120 result , err := wshclient .TermGetScrollbackLinesCommand (
111121 rpcClient ,
112122 wshrpc.CommandTermGetScrollbackLinesData {
113- LineStart : lineStart ,
123+ LineStart : parsed . LineStart ,
114124 LineEnd : lineEnd ,
115125 },
116126 & wshrpc.RpcOpts {Route : wshutil .MakeFeBlockRouteId (block .OID )},
@@ -120,20 +130,30 @@ func GetTermGetScrollbackToolDefinition(block *waveobj.Block) uctypes.ToolDefini
120130 }
121131
122132 content := strings .Join (result .Lines , "\n " )
123- sinceLastOutputSec := 0
133+ effectiveLineEnd := min (lineEnd , result .TotalLines )
134+ hasMore := effectiveLineEnd < result .TotalLines
135+
136+ var sinceLastOutputSec * int
124137 if result .LastUpdated > 0 {
125- sinceLastOutputSec = max (0 , int ((time .Now ().UnixMilli ()- result .LastUpdated )/ 1000 ))
138+ sec := max (0 , int ((time .Now ().UnixMilli ()- result .LastUpdated )/ 1000 ))
139+ sinceLastOutputSec = & sec
140+ }
141+
142+ var nextStart * int
143+ if hasMore {
144+ nextStart = & effectiveLineEnd
126145 }
127146
128- return map [string ]any {
129- "totallines" : result .TotalLines ,
130- "linestart" : result .LineStart ,
131- "lineend" : min (lineEnd , result .TotalLines ),
132- "returned_lines" : len (result .Lines ),
133- "content" : content ,
134- "since_last_output_sec" : sinceLastOutputSec ,
135- "has_more" : lineEnd < result .TotalLines ,
147+ return & TermGetScrollbackToolOutput {
148+ TotalLines : result .TotalLines ,
149+ LineStart : result .LineStart ,
150+ LineEnd : effectiveLineEnd ,
151+ ReturnedLines : len (result .Lines ),
152+ Content : content ,
153+ SinceLastOutputSec : sinceLastOutputSec ,
154+ HasMore : hasMore ,
155+ NextStart : nextStart ,
136156 }, nil
137157 },
138158 }
139- }
159+ }
0 commit comments