返回 DeepSeek-Reasonix
executor.go
根目录 / internal / browser / executor.go
1 package browser
2
3 import (
4 "context"
5 "errors"
6 "time"
7 )
8
9 // Executor is the host-neutral browser contract. The local Electron shell and
10 // the remote SSH broker both implement it; the tools in this package are its
11 // only callers and never learn which host answers.
12 type Executor interface {
13 Tabs(ctx context.Context) ([]Tab, error)
14 Open(ctx context.Context, req OpenRequest) (Tab, error)
15 Navigate(ctx context.Context, req NavigateRequest) (Tab, error)
16 Snapshot(ctx context.Context, req SnapshotRequest) (Snapshot, error)
17 Screenshot(ctx context.Context, req ScreenshotRequest) (Screenshot, error)
18 Act(ctx context.Context, req ActRequest) (ActResult, error)
19 Downloads(ctx context.Context, req DownloadsRequest) ([]Download, error)
20 Close(ctx context.Context, req CloseRequest) error
21 }
22
23 // FilePreviewer is an optional desktop-only capability. It turns a file that
24 // the current task is already allowed to read into a task-owned browser tab.
25 // CLI/CDP executors intentionally need not implement it.
26 type FilePreviewer interface {
27 PreviewFile(ctx context.Context, req FilePreviewRequest) (Tab, error)
28 }
29
30 // Availability is an optional Executor capability: a host whose grant can
31 // lapse (session switch, connection generation change) reports it here so the
32 // tools fail closed before any call is dispatched.
33 type Availability interface {
34 Available(ctx context.Context) bool
35 }
36
37 var (
38 // ErrStaleReference means the ref or documentToken predates a navigation,
39 // page replacement, or take-over; the caller must snapshot again.
40 ErrStaleReference = errors.New("browser: stale reference")
41 // ErrTakenOver means the user is operating the tab; agent access resumes
42 // only after a fresh snapshot once the tab leaves human mode.
43 ErrTakenOver = errors.New("browser: tab taken over by the user")
44 // ErrNoGrant means no current browser grant covers this task or tab.
45 ErrNoGrant = errors.New("browser: no browser grant")
46 // ErrUnknownOutcome means a write's receipt was lost: the action may or
47 // may not have run and must never be replayed.
48 ErrUnknownOutcome = errors.New("browser: operation outcome unknown")
49 )
50
51 // Navigate actions.
52 const (
53 NavigateURL = "url"
54 NavigateBack = "back"
55 NavigateForward = "forward"
56 NavigateReload = "reload"
57 )
58
59 // Act actions.
60 const (
61 ActionClick = "click"
62 ActionType = "type"
63 ActionPress = "press"
64 ActionScroll = "scroll"
65 ActionSelect = "select"
66 ActionUpload = "upload"
67 )
68
69 // Act outcomes.
70 const (
71 OutcomeExecuted = "executed"
72 OutcomeNotExecuted = "not_executed"
73 OutcomeUnknown = "unknown"
74 )
75
76 // Tab is one browser tab owned by the current task.
77 type Tab struct {
78 ID string
79 URL string
80 Title string
81 Loading bool
82 Temporary bool
83 Error string
84 }
85
86 type OpenRequest struct {
87 OperationID string
88 URL string
89 Temporary bool
90 }
91
92 type FilePreviewRequest struct {
93 OperationID string
94 Source string
95 Path string
96 ToolCallID string
97 }
98
99 // NavigateRequest moves a bound tab; URL is consulted only for NavigateURL.
100 type NavigateRequest struct {
101 OperationID string
102 TabID string
103 URL string
104 Action string
105 }
106
107 type CloseRequest struct {
108 OperationID string
109 TabID string
110 }
111
112 type SnapshotRequest struct {
113 TabID string
114 Selector string
115 }
116
117 // Snapshot is the accessibility-style tree of one document version;
118 // DocumentToken binds every ref in Tree to that version.
119 type Snapshot struct {
120 DocumentToken string
121 URL string
122 Title string
123 Tree string
124 Refs int
125 Observation *Observation `json:"observation,omitempty"`
126 }
127
128 type Observation struct {
129 URL string `json:"url"`
130 TimeMS int64 `json:"timeMs"`
131 DocumentEpoch int64 `json:"documentEpoch"`
132 ViewportRevision int64 `json:"viewportRevision"`
133 CSSWidth int `json:"cssWidth"`
134 CSSHeight int `json:"cssHeight"`
135 }
136
137 type ScreenshotRequest struct {
138 TabID string
139 Ref string
140 FullPage bool
141 }
142
143 // Screenshot names the task-owned file the host wrote; image bytes never
144 // travel through control frames.
145 type Screenshot struct {
146 Observation *Observation `json:"observation,omitempty"`
147 Path string
148 MIME string
149 Width int
150 Height int
151 ObservationToken string `json:"observationToken,omitempty"`
152 CSSWidth int `json:"cssWidth,omitempty"`
153 CSSHeight int `json:"cssHeight,omitempty"`
154 }
155
156 // ActRequest is one reserved write. OperationID is minted by the model,
157 // unique per attempt, and rejected forever once used.
158 type ActRequest struct {
159 OperationID string
160 TabID string
161 DocumentToken string
162 Action string
163 Ref string
164 Text string
165 Keys string
166 Options []string
167 Files []string
168 Submit bool
169 DeltaX int
170 DeltaY int
171 }
172
173 // ActResult is the host's receipt; Reason explains a not_executed Outcome.
174 type ActResult struct {
175 Executed bool
176 Reason string
177 DocumentToken string
178 Outcome string
179 }
180
181 type DownloadsRequest struct {
182 TabID string
183 WaitFor time.Duration
184 }
185
186 type Download struct {
187 ID string
188 URL string
189 Path string
190 State string
191 Bytes int64
192 }
193
193 lines GO