Skip to content

Commit 3600882

Browse files
committed
single tool for web, fix widgetAccess, tsunami tools setup refactor
1 parent 1c4e7c4 commit 3600882

2 files changed

Lines changed: 98 additions & 57 deletions

File tree

pkg/aiusechat/tools.go

Lines changed: 36 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -126,10 +126,27 @@ func GenerateTabStateAndTools(ctx context.Context, tabid string, widgetAccess bo
126126
var tools []uctypes.ToolDefinition
127127
if widgetAccess {
128128
tools = append(tools, GetCaptureScreenshotToolDefinition(tabid))
129-
}
130-
for _, block := range blocks {
131-
blockTools := generateToolsForBlock(tabid, block)
132-
tools = append(tools, blockTools...)
129+
viewTypes := make(map[string]bool)
130+
for _, block := range blocks {
131+
if block.Meta == nil {
132+
continue
133+
}
134+
viewType, ok := block.Meta["view"].(string)
135+
if !ok {
136+
continue
137+
}
138+
viewTypes[viewType] = true
139+
if viewType == "tsunami" {
140+
blockTools := generateToolsForTsunamiBlock(block)
141+
tools = append(tools, blockTools...)
142+
}
143+
}
144+
if viewTypes["term"] {
145+
tools = append(tools, GetTermGetScrollbackToolDefinition(tabid))
146+
}
147+
if viewTypes["web"] {
148+
tools = append(tools, GetWebNavigateToolDefinition(tabid))
149+
}
133150
}
134151
return tabState, tools, nil
135152
}
@@ -164,37 +181,25 @@ func GenerateCurrentTabStatePrompt(blocks []*waveobj.Block, widgetAccess bool) s
164181
return prompt.String()
165182
}
166183

167-
func generateToolsForBlock(tabId string, block *waveobj.Block) []uctypes.ToolDefinition {
168-
if block.Meta == nil {
169-
return nil
170-
}
184+
func generateToolsForTsunamiBlock(block *waveobj.Block) []uctypes.ToolDefinition {
185+
var tools []uctypes.ToolDefinition
171186

172-
viewType, ok := block.Meta["view"].(string)
173-
if !ok {
187+
status := blockcontroller.GetBlockControllerRuntimeStatus(block.OID)
188+
if status == nil || status.ShellProcStatus != blockcontroller.Status_Running || status.TsunamiPort <= 0 {
174189
return nil
175190
}
176191

177-
var tools []uctypes.ToolDefinition
178-
switch viewType {
179-
case "term":
180-
tools = append(tools, GetTermGetScrollbackToolDefinition(tabId))
181-
case "web":
182-
tools = append(tools, GetWebNavigateToolDefinition(block))
183-
case "tsunami":
184-
status := blockcontroller.GetBlockControllerRuntimeStatus(block.OID)
185-
if status != nil && status.ShellProcStatus == blockcontroller.Status_Running && status.TsunamiPort > 0 {
186-
blockORef := waveobj.MakeORef(waveobj.OType_Block, block.OID)
187-
rtInfo := wstore.GetRTInfo(blockORef)
188-
if tool := GetTsunamiGetDataToolDefinition(block, rtInfo, status); tool != nil {
189-
tools = append(tools, *tool)
190-
}
191-
if tool := GetTsunamiGetConfigToolDefinition(block, rtInfo, status); tool != nil {
192-
tools = append(tools, *tool)
193-
}
194-
if tool := GetTsunamiSetConfigToolDefinition(block, rtInfo, status); tool != nil {
195-
tools = append(tools, *tool)
196-
}
197-
}
192+
blockORef := waveobj.MakeORef(waveobj.OType_Block, block.OID)
193+
rtInfo := wstore.GetRTInfo(blockORef)
194+
195+
if tool := GetTsunamiGetDataToolDefinition(block, rtInfo, status); tool != nil {
196+
tools = append(tools, *tool)
197+
}
198+
if tool := GetTsunamiGetConfigToolDefinition(block, rtInfo, status); tool != nil {
199+
tools = append(tools, *tool)
200+
}
201+
if tool := GetTsunamiSetConfigToolDefinition(block, rtInfo, status); tool != nil {
202+
tools = append(tools, *tool)
198203
}
199204

200205
return tools

pkg/aiusechat/tools_web.go

Lines changed: 62 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ package aiusechat
55

66
import (
77
"context"
8+
"encoding/json"
89
"fmt"
910
"time"
1011

@@ -14,58 +15,93 @@ import (
1415
"github.com/wavetermdev/waveterm/pkg/wstore"
1516
)
1617

17-
func GetWebNavigateToolDefinition(block *waveobj.Block) uctypes.ToolDefinition {
18-
blockIdPrefix := block.OID[:8]
19-
toolName := fmt.Sprintf("web_navigate_%s", blockIdPrefix)
18+
type WebNavigateToolInput struct {
19+
WidgetId string `json:"widget_id"`
20+
Url string `json:"url"`
21+
}
22+
23+
func parseWebNavigateInput(input any) (*WebNavigateToolInput, error) {
24+
result := &WebNavigateToolInput{}
25+
26+
if input == nil {
27+
return nil, fmt.Errorf("input is required")
28+
}
29+
30+
inputBytes, err := json.Marshal(input)
31+
if err != nil {
32+
return nil, fmt.Errorf("failed to marshal input: %w", err)
33+
}
34+
35+
if err := json.Unmarshal(inputBytes, result); err != nil {
36+
return nil, fmt.Errorf("failed to unmarshal input: %w", err)
37+
}
38+
39+
if result.WidgetId == "" {
40+
return nil, fmt.Errorf("widget_id is required")
41+
}
42+
43+
if result.Url == "" {
44+
return nil, fmt.Errorf("url is required")
45+
}
46+
47+
return result, nil
48+
}
49+
50+
func GetWebNavigateToolDefinition(tabId string) uctypes.ToolDefinition {
2051

2152
return uctypes.ToolDefinition{
22-
Name: toolName,
23-
DisplayName: fmt.Sprintf("Navigate Web Block %s", blockIdPrefix),
24-
Description: fmt.Sprintf("Navigate the web browser widget %s to a new URL", blockIdPrefix),
53+
Name: "web_navigate",
54+
DisplayName: "Navigate Web Widget",
55+
Description: "Navigate a web browser widget to a new URL",
2556
ToolLogName: "web:navigate",
2657
Strict: true,
2758
InputSchema: map[string]any{
2859
"type": "object",
2960
"properties": map[string]any{
61+
"widget_id": map[string]any{
62+
"type": "string",
63+
"description": "8-character widget ID of the web browser widget",
64+
},
3065
"url": map[string]any{
3166
"type": "string",
3267
"description": "URL to navigate to",
3368
},
3469
},
35-
"required": []string{"url"},
70+
"required": []string{"widget_id", "url"},
3671
"additionalProperties": false,
3772
},
3873
ToolInputDesc: func(input any) string {
39-
inputMap, ok := input.(map[string]any)
40-
if !ok {
41-
return fmt.Sprintf("navigating web widget %s", blockIdPrefix)
42-
}
43-
url, ok := inputMap["url"].(string)
44-
if !ok || url == "" {
45-
return fmt.Sprintf("navigating web widget %s", blockIdPrefix)
74+
parsed, err := parseWebNavigateInput(input)
75+
if err != nil {
76+
return fmt.Sprintf("error parsing input: %v", err)
4677
}
47-
return fmt.Sprintf("navigating web widget %s to %q", blockIdPrefix, url)
78+
return fmt.Sprintf("navigating web widget %s to %q", parsed.WidgetId, parsed.Url)
4879
},
4980
ToolAnyCallback: func(input any) (any, error) {
50-
inputMap, ok := input.(map[string]any)
51-
if !ok {
52-
return nil, fmt.Errorf("invalid input format")
53-
}
54-
55-
url, ok := inputMap["url"].(string)
56-
if !ok {
57-
return nil, fmt.Errorf("missing or invalid url parameter")
81+
parsed, err := parseWebNavigateInput(input)
82+
if err != nil {
83+
return nil, err
5884
}
5985

6086
ctx, cancelFn := context.WithTimeout(context.Background(), 5*time.Second)
6187
defer cancelFn()
6288

63-
blockORef := waveobj.MakeORef(waveobj.OType_Block, block.OID)
89+
tab, err := wstore.DBMustGet[*waveobj.Tab](ctx, tabId)
90+
if err != nil {
91+
return nil, fmt.Errorf("error getting tab: %w", err)
92+
}
93+
94+
fullBlockId, err := resolveBlockIdFromPrefix(tab, parsed.WidgetId)
95+
if err != nil {
96+
return nil, err
97+
}
98+
99+
blockORef := waveobj.MakeORef(waveobj.OType_Block, fullBlockId)
64100
meta := map[string]any{
65-
"url": url,
101+
"url": parsed.Url,
66102
}
67103

68-
err := wstore.UpdateObjectMeta(ctx, blockORef, meta, false)
104+
err = wstore.UpdateObjectMeta(ctx, blockORef, meta, false)
69105
if err != nil {
70106
return nil, fmt.Errorf("failed to update web block URL: %w", err)
71107
}

0 commit comments

Comments
 (0)