File: execution_engine.h

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (207 lines) | stat: -rw-r--r-- 7,221 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
// Copyright 2025 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROME_BROWSER_ACTOR_EXECUTION_ENGINE_H_
#define CHROME_BROWSER_ACTOR_EXECUTION_ENGINE_H_

#include <memory>
#include <optional>

#include "base/callback_list.h"
#include "base/functional/callback.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/safe_ref.h"
#include "base/memory/weak_ptr.h"
#include "base/sequence_checker.h"
#include "base/types/id_type.h"
#include "chrome/browser/actor/aggregated_journal.h"
#include "chrome/browser/actor/task_id.h"
#include "chrome/browser/actor/tools/tool_controller.h"
#include "chrome/common/actor.mojom-forward.h"
#include "components/optimization_guide/proto/features/actions_data.pb.h"
#include "components/tabs/public/tab_interface.h"
#include "content/public/browser/web_contents_observer.h"

class GURL;
class Profile;

namespace mojo_base {
class ProtoWrapper;
}

namespace content {
class WebContents;
}  // namespace content

namespace tabs {
class TabInterface;
}  // namespace tabs

namespace url {
class Origin;
}  // namespace url

namespace actor {

class ActorTask;
class ToolRequest;

// Coordinates the execution of a multi-step task.
class ExecutionEngine {
 public:
  using ActionResultCallback = base::OnceCallback<void(mojom::ActionResultPtr)>;
  using ActionsResultCallback =
      base::OnceCallback<void(optimization_guide::proto::ActionsResult)>;

  explicit ExecutionEngine(Profile* profile);

  // Old instances of ExecutionEngine assume that all actions are scoped to a
  // single tab. This constructor supports this use case, but this is
  // deprecated. Do not add new consumers
  ExecutionEngine(Profile* profile, tabs::TabInterface* tab);
  ExecutionEngine(const ExecutionEngine&) = delete;
  ExecutionEngine& operator=(const ExecutionEngine&) = delete;
  ~ExecutionEngine();

  // This cannot be in the constructor as we first construct the
  // ExecutionEngine, then the ActorTask.
  void SetOwner(ActorTask* task);

  static void RegisterWithProfile(Profile* profile);

  // Cancels any in-progress actions with the reason: "kTaskPaused".
  void CancelOngoingActions(mojom::ActionResultCode reason);

  // Returns the tab associated with the current task if it exists.
  tabs::TabInterface* GetTabOfCurrentTask() const;

  // Returns true if a task is currently active.
  bool HasTask() const;

  // Returns true if a task is currently active in `tab`.
  bool HasTaskForTab(const content::WebContents* tab) const;

  // Performs the next action in the current task.
  void Act(const optimization_guide::proto::BrowserAction& action,
           ActionResultCallback callback);

  // Performs the next action in the current task.
  void Act(const optimization_guide::proto::Actions& actions,
           ActionsResultCallback callback);

  // Gets called when a new observation is made for the actor task.
  void DidObserveContext(const mojo_base::ProtoWrapper&);

  // Returns last observed page content, nullptr if no observation has been
  // made.
  const optimization_guide::proto::AnnotatedPageContent*
  GetLastObservedPageContent();

  // Invalidated anytime `actions_` is reset.
  base::WeakPtr<ExecutionEngine> GetWeakPtr();

 private:
  class NewTabWebContentsObserver;

  // If there are no actions remaining, calls CompleteActions.
  // Otherwise, calls SafetyChecksForNextAction().
  void KickOffNextAction(mojom::ActionResultPtr previous_action_result);

  // Performs safety checks for next action. This is asynchronous.
  void SafetyChecksForNextAction();

  // Performs synchronous safety checks for the next action. If everything
  // passes calls tool_controller_.Invoke().
  void DidFinishAsyncSafetyChecks(const url::Origin& evaluated_origin,
                                  bool may_act);

  // Synchronously executes the next action. There are several types of actions,
  // including renderer-scoped actions, tab-scoped actions, and global actions.
  void ExecuteNextAction();

  // Called each time an action finishes.
  void FinishOneAction(mojom::ActionResultPtr result);

  // Calls out to CompleteActionsV1 or CompleteActionsV2.
  void CompleteActions(mojom::ActionResultPtr result);

  // Calls `callback` and clears `actions_v1_`.
  void CompleteActionsV1(mojom::ActionResultPtr result);

  // Calls `callback` and clears `actions_v2_`.
  void CompleteActionsV2(mojom::ActionResultPtr result);

  void OnTabWillDetach(tabs::TabInterface* tab,
                       tabs::TabInterface::DetachReason reason);

  const GURL& LastCommittedURLOfCurrentTask();

  const optimization_guide::proto::Action& GetNextAction();
  // Returns the tab associated with the action or nullptr.
  tabs::TabInterface* GetTab(const optimization_guide::proto::Action& action);

  static std::optional<base::TimeDelta> action_observation_delay_for_testing_;

  raw_ptr<Profile> profile_;
  base::SafeRef<AggregatedJournal> journal_;

  // Stores the last observed page content for TOCTOU check.
  std::unique_ptr<optimization_guide::proto::AnnotatedPageContent>
      last_observed_page_content_;

  template <typename ActionT, typename CallbackT>
  struct ActionWithCallback {
    ActionWithCallback(const ActionT& actions, CallbackT callback)
        : proto(actions), callback(std::move(callback)) {}
    ~ActionWithCallback() = default;
    ActionWithCallback(const ActionWithCallback&) = delete;
    ActionWithCallback& operator=(const ActionWithCallback&) = delete;

    ActionT proto;
    CallbackT callback;
  };

  // TODO(crbug.com/411462297): This assumes all tasks are scoped to a tab,
  // which is not true. This should eventually be removed.
  bool tab_scoped_actions_deprecated_ = false;
  raw_ptr<tabs::TabInterface> tab_;
  base::CallbackListSubscription tab_will_detach_subscription_;

  // Owns `this`.
  raw_ptr<ActorTask> task_;

  // Tool request currently being invoked.
  std::unique_ptr<ToolRequest> active_tool_request_;

  // Created when task_ is set. Handles execution details for an individual tool
  // request.
  std::unique_ptr<ToolController> tool_controller_;

  // A sequence of actions that the model has requested. When it is finished
  // being processed it is reset.
  // This is deprecated; do not add new use cases.
  std::optional<ActionWithCallback<optimization_guide::proto::BrowserAction,
                                   ActionResultCallback>>
      actions_v1_;

  // A sequence of actions that the model has requested. When it is finished
  // being processed it is reset.
  std::optional<ActionWithCallback<optimization_guide::proto::Actions,
                                   ActionsResultCallback>>
      actions_v2_;

  // The index of the in-progress action.
  int action_index_ = 0;

  SEQUENCE_CHECKER(sequence_checker_);

  // Normally, a WeakPtrFactory only invalidates its WeakPtrs when the object is
  // destroyed. However, this class invalidates WeakPtrs anytime a new set of
  // actions is passed in. This effectively cancels any ongoing async actions.
  base::WeakPtrFactory<ExecutionEngine> actions_weak_ptr_factory_{this};
};

}  // namespace actor

#endif  // CHROME_BROWSER_ACTOR_EXECUTION_ENGINE_H_