#ifndef CHROME_BROWSER_CONTEXTUAL_TASKS_CONTEXTUAL_TASKS_CONTEXT_SERVICE_H_
#define CHROME_BROWSER_CONTEXTUAL_TASKS_CONTEXTUAL_TASKS_CONTEXT_SERVICE_H_
#include <optional>
#include <string>
#include <vector>
#include "base/functional/callback.h"
#include "base/memory/raw_ptr.h"
#include "base/scoped_observation.h"
#include "base/time/tick_clock.h"
#include "base/time/time.h"
#include "chrome/browser/contextual_tasks/contextual_tasks_types.mojom.h"
#include "chrome/browser/passage_embeddings/page_embeddings_service.h"
#include "components/keyed_service/core/keyed_service.h"
#include "components/passage_embeddings/passage_embeddings_types.h"
class GURL;
class OptimizationGuideKeyedService;
class Profile;
namespace content {
class WebContents;
}
namespace optimization_guide::proto {
class ContextualTasksContextQuality;
}
namespace page_content_annotations {
class PageContentExtractionService;
}
namespace passage_embeddings {
class Embedder;
class EmbedderMetadataProvider;
class PageEmbeddingsService;
}
namespace contextual_tasks {
enum class ContextDeterminationStatus {
kSuccess = 0,
kEmbedderNotAvailable = 1,
kQueryEmbeddingFailed = 2,
kQueryEmbeddingOutputMalformed = 3,
kNoEligibleTabs = 4,
kMaxValue = kNoEligibleTabs,
};
struct TabSelectionOptions {
mojom::TabSelectionMode tab_selection_mode =
mojom::TabSelectionMode::kMultiSignalScoring;
std::optional<float> min_model_score;
};
class ContextualTasksContextService
: public KeyedService,
public passage_embeddings::EmbedderMetadataObserver,
public passage_embeddings::PageEmbeddingsService::Observer {
public:
ContextualTasksContextService(
Profile* profile,
passage_embeddings::PageEmbeddingsService* page_embeddings_service,
passage_embeddings::EmbedderMetadataProvider* embedder_metadata_provider,
passage_embeddings::Embedder* embedder,
OptimizationGuideKeyedService* optimization_guide_keyed_service,
page_content_annotations::PageContentExtractionService*
page_content_extraction_service);
ContextualTasksContextService(const ContextualTasksContextService&) = delete;
ContextualTasksContextService operator=(
const ContextualTasksContextService&) = delete;
~ContextualTasksContextService() override;
void GetRelevantTabsForQuery(
const TabSelectionOptions& options,
const std::string& query,
const std::vector<GURL>& explicit_urls,
base::OnceCallback<void(std::vector<content::WebContents*>)> callback);
void SetClockForTesting(const base::TickClock* tick_clock);
private:
void EmbedderMetadataUpdated(
passage_embeddings::EmbedderMetadata metadata) override;
passage_embeddings::PageEmbeddingsService::Priority GetDefaultPriority()
const override;
void OnQueryEmbeddingReady(
const std::string& query,
const TabSelectionOptions& options,
base::TimeTicks start_time,
const std::vector<GURL>& explicit_urls,
base::OnceCallback<void(std::vector<content::WebContents*>)> callback,
std::vector<std::string> passages,
std::vector<passage_embeddings::Embedding> embeddings,
passage_embeddings::Embedder::TaskId task_id,
passage_embeddings::ComputeEmbeddingsStatus status);
std::vector<content::WebContents*> GetAllEligibleTabs();
std::vector<content::WebContents*> SelectRelevantTabs(
const std::string& query,
const TabSelectionOptions& options,
const passage_embeddings::Embedding& query_embedding,
const std::vector<content::WebContents*>& all_tabs,
const std::vector<GURL>& explicit_urls,
optimization_guide::proto::ContextualTasksContextQuality* quality_log);
std::vector<content::WebContents*> SelectTabsByEmbeddingsMatch(
const std::string& query,
const TabSelectionOptions& options,
const passage_embeddings::Embedding& query_embedding,
const std::vector<content::WebContents*>& all_tabs);
std::vector<content::WebContents*> SelectTabsByMultiSignalScore(
const std::string& query,
const TabSelectionOptions& options,
const passage_embeddings::Embedding& query_embedding,
const std::vector<content::WebContents*>& all_tabs,
const std::vector<GURL>& explicit_urls,
optimization_guide::proto::ContextualTasksContextQuality* quality_log);
std::optional<base::TimeDelta> GetDurationSinceLastActive(
content::WebContents* web_contents);
bool ShouldAddTabToSelection(content::WebContents* web_contents);
std::optional<int64_t> embedder_model_version_;
raw_ptr<Profile> profile_;
raw_ptr<passage_embeddings::PageEmbeddingsService> page_embeddings_service_;
raw_ptr<passage_embeddings::EmbedderMetadataProvider>
embedder_metadata_provider_;
raw_ptr<passage_embeddings::Embedder> embedder_;
raw_ptr<OptimizationGuideKeyedService> optimization_guide_keyed_service_;
raw_ptr<page_content_annotations::PageContentExtractionService>
page_content_extraction_service_;
raw_ptr<const base::TickClock> tick_clock_;
base::ScopedObservation<passage_embeddings::EmbedderMetadataProvider,
passage_embeddings::EmbedderMetadataObserver>
scoped_embedder_metadata_provider_observation_{this};
base::ScopedObservation<passage_embeddings::PageEmbeddingsService,
passage_embeddings::PageEmbeddingsService::Observer>
scoped_page_embeddings_service_observation_{this};
base::WeakPtrFactory<ContextualTasksContextService> weak_ptr_factory_{this};
};
}
#endif