|
8609
|
167
|
13
|
2026-04-14T06:55:43.422806+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776149743422_m2.jpg...
|
Firefox
|
Jiminny — Work
|
True
|
app.staging.jiminny.com/ai-reports
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
JY-20543 add AJ reports User pilot tracking by Lak JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Jiminny
Jiminny
Close tab
New Tab
Customize sidebar
Close Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
AI Chat settings
Close
WORK, Google Account: [EMAIL]
Main menu
New Chat
Open menu for conversation actions.
Conversation with Gemini
Conversation with Gemini
Copy prompt
You said I’m on page “<tabTitle>Jy 19798 evaluation for ai activity types by nikol</tabTitle>” with “<selection>@@ -0,0 +1,330 @@1+#!/usr/bin/env python32+import asyncio3+import json4+import os5+from pathlib import Path6+from typing import Any, Dict, List7+8+import aiohttp9+10+from src.component.call_processing.schemes.ai_activity_type_request import AiActivityTypeRequest11+from src.component.call_processing.schemes.ai_activity_type_response import AiActivityTypeResponse12+from src.eval.abstract_evaluator import AbstractEvaluator13+from src.eval.collectors import collect_test_set as es_collect_test_set14+from src.eval.common_evaluator_runner import create_parser, run_evaluation15+from src.eval.endpoints import run_endpoint as run_endpoint_http16+from src.eval.models import EvaluationResult17+18+19+class AiActivityTypeEvaluator(AbstractEvaluator):20+ENDPOINT_PATH = "call/ai-activity-type"21+REQUEST_MODEL = AiActivityTypeRequest22+RESPONSE_MODEL = AiActivityTypeResponse23+OUTPUT_SUBFOLDER = "ai_activity_type"24+USES_LLM_EVALUATION = False25+26+READS_FROM_DATASET_FOLDER = True27+28+DATA_SET: str = "initial"29+30+MINIMUM_REQUEST_BODY_SIZE: int = 031+32+SKIP_UNREPLAYABLE_ON_COLLECT: bool = True33+REPLAYABILITY_CHECK_TIMEOUT_SECONDS: float = 20.034+35+POPULATE_GROUND_TRUTH_LLM: bool = False36+GROUND_TRUTH_LLM_ENDPOINT: str = "OPENAI:gpt-5_2"37+38+COMPARE_TO_GROUND_TRUTH: str = "es"39+40+def __init__(self, **kwargs: Any) -> None:41+super().__init__(**kwargs)42+_repo_root = Path(__file__).parents[2]43+_datasets_root = _repo_root / "eval_output" / self.OUTPUT_SUBFOLDER / "eval_datasets"44+_dataset_dir = _datasets_root / self.__class__.DATA_SET45+self._dataset_dir = _dataset_dir46+self._inputs_dir = _dataset_dir / "input"47+self._ground_truths_dir = _dataset_dir / "ground_truth"48+49+async def collect_test_set(self) -> List[Dict[str, Any]]:50+if self.es_host_name:51+return await self._collect_from_es()52+return await self._collect_from_files()53+54+async def _collect_from_es(self) -> List[Dict[str, Any]]:55+if self._inputs_dir.exists() or self._ground_truths_dir.exists():56+raise FileExistsError(57+f"Dataset folder already exists: {self._inputs_dir.parent}. "58+"Choose a different --data-set name or remove the folder manually."59+ )60+61+raw_samples = await es_collect_test_set(62+es_host_name=self.es_host_name,63+es_port=self.es_port,64+endpoint_path=self.ENDPOINT_PATH,65+limit=self.limit,66+language_filter=self.language_filter,67+min_prompt_length=self.min_prompt_length,68+is_json_response=self.IS_JSON_RESPONSE,69+exclude_languages=self.exclude_languages,70+ )71+72+self._inputs_dir.mkdir(parents=True, exist_ok=True)73+self._ground_truths_dir.mkdir(parents=True, exist_ok=True)74+75+min_size = self.MINIMUM_REQUEST_BODY_SIZE76+samples: List[Dict[str, Any]] = []77+skipped_no_response = 078+skipped_too_small = 079+skipped_unreplayable = 080+skipped_probe_errors = 081+82+endpoint_url = f"{self.api_host}/{self.ENDPOINT_PATH}"83+84+timeout = aiohttp.ClientTimeout(total=self.REPLAYABILITY_CHECK_TIMEOUT_SECONDS)85+async with aiohttp.ClientSession(timeout=timeout) as session:86+for sample in raw_samples:87+es_id = sample["id"]88+request_body = sample["request_body"]89+original_response = sample.get("original_response")90+91+if not original_response:92+skipped_no_response += 193+continue94+95+if min_size and len(json.dumps(request_body)) < min_size:96+skipped_too_small += 197+continue98+99+if self.SKIP_UNREPLAYABLE_ON_COLLECT:100+try:101+async with session.post(endpoint_url, json=request_body) as resp:102+if resp.status != 200:103+body_text = await resp.text()104+if "Cannot find activity" in body_text:105+skipped_unreplayable += 1106+continue107+except Exception:108+skipped_probe_errors += 1109+110+with open(self._inputs_dir / f"{es_id}.json", "w") as f:111+json.dump(request_body, f, indent=2)112+113+with open(self._ground_truths_dir / f"gt_{es_id}.json", "w") as f:114+json.dump(original_response, f, indent=2)115+116+samples.append(117+ {118+"id": es_id,119+"request_body": request_body,120+"original_response": original_response,121+"ground_truth": original_response,122+ }123+ )124+125+print(f"Wrote {len(samples)} samples to {self._inputs_dir.parent}")126+if skipped_no_response:127+print(f"Skipped {skipped_no_response} records with no response body")128+if skipped_too_small:129+print(130+f"Skipped {skipped_too_small} records whose request body was smaller "131+f"than {min_size} characters"132+ )133+if skipped_unreplayable:134+print(f"Skipped {skipped_unreplayable} records that are not replayable (missing activity in ES)")135+if skipped_probe_errors:136+print(f"Warning: replayability probe errored for {skipped_probe_errors} records (kept those records)")137+138+if self.__class__.POPULATE_GROUND_TRUTH_LLM:139+label_results = await run_endpoint_http(140+test_set=samples,141+endpoint_url=endpoint_url,142+request_model=self.REQUEST_MODEL,143+force_llm_endpoint=self.__class__.GROUND_TRUTH_LLM_ENDPOINT,144+is_streaming_response=self.IS_STREAMING_RESPONSE,145+timeout_seconds=300.0,146+parallel_requests=self.parallel_requests,147+return_prompt_in_run=self.RETURN_PROMPT_IN_RUN,148+ )149+150+for i, r in enumerate(label_results):151+forced = self.__class__.GROUND_TRUTH_LLM_ENDPOINT152+model = forced.split(":", 1)[1] if ":" in forced else forced153+samples[i]["ground_truth_llm_model"] = model154+155+if not r.get("success", True):156+samples[i]["ground_truth_llm"] = None157+samples[i]["ground_truth_llm_reasoning"] = None158+samples[i]["ground_truth_llm_error_type"] = r.get("error_type")159+samples[i]["ground_truth_llm_error_message"] = r.get("error_message")160+continue161+162+resp = r.get("new_response") or {}163+samples[i]["ground_truth_llm"] = resp.get("ai_activity_type")164+samples[i]["ground_truth_llm_reasoning"] = resp.get("ai_activity_type_reasoning")165+166+return samples167+168+async def _collect_from_files(self) -> List[Dict[str, Any]]:169+if not self._inputs_dir.exists():170+raise FileNotFoundError(171+f"Dataset folder not found: {self._inputs_dir}. "172+"Run --steps collect first or check your --data-set name."173+ )174+175+samples: List[Dict[str, Any]] = []176+for filename in sorted(os.listdir(self._inputs_dir)):177+input_path = self._inputs_dir / filename178+gt_path = self._ground_truths_dir / f"gt_{filename}"179+180+if not gt_path.exists():181+print(f"Warning: ground truth not found for {filename}, skipping")182+continue183+184+with open(input_path, "r") as f:185+request_body: Dict[str, Any] = json.load(f)186+187+with open(gt_path, "r") as f:188+ground_truth: Dict[str, Any] = json.load(f)189+190+samples.append(191+ {192+"id": Path(filename).stem,193+"request_body": request_body,194+"original_response": None,195+"ground_truth": ground_truth,196+ }197+ )198+199+print(f"Loaded {len(samples)} samples from {self._inputs_dir.parent}")200+return samples201+202+async def evaluate_against_ground_truth(self, results: List[Dict[str, Any]]) -> List[EvaluationResult]:203+evaluation_results: List[EvaluationResult] = []204+compare_to = self.__class__.COMPARE_TO_GROUND_TRUTH205+206+for res in results:207+req_id = res["request_id"]208+is_success = res.get("success", True)209+210+if not is_success:211+evaluation_results.append(212+EvaluationResult(213+request_id=req_id,214+request_body=res["request_body"],215+new_response=res.get("new_response"),216+valid_schema=False,217+quality_score=0.0,218+quality_feedback=f"Request failed: {res.get('error_type')} - {res.get('error_message')}",219+response_time=res.get("response_time"),220+success=False,221+error_type=res.get("error_type"),222+error_message=res.get("error_message"),223+ground_truth_match=False,224+ )225+ )226+continue227+228+pred = (res.get("new_response") or {}).get("ai_activity_type")229+230+if compare_to == "llm":231+if "ground_truth_llm" not in res:232+evaluation_results.append(233+EvaluationResult(234+request_id=req_id,235+request_body=res["request_body"],236+new_response=res.get("new_response"),237+valid_schema=res.get("valid_schema", True),238+quality_score=0.0,239+quality_feedback=(240+"Missing ground_truth_llm in run results. Ensure collect step populated it and "241+"endpoints.py passes it through."242+ ),243+response_time=res.get("response_time"),244+success=True,245+ground_truth_match=False,246+ )247+ )248+continue249+gt_label = res.get("ground_truth_llm")250+else:251+gt_path = self._ground_truths_dir / f"gt_{req_id}.json"252+if not gt_path.exists():253+evaluation_results.append(254+EvaluationResult(255+request_id=req_id,256+request_body=res["request_body"],257+new_response=res.get("new_response"),258+valid_schema=res.get("valid_schema", True),259+quality_score=0.0,260+quality_feedback=f"Ground truth file not found: {gt_path}",261+response_time=res.get("response_time"),262+success=True,263+ground_truth_match=False,264+ )265+ )266+continue267+268+with open(gt_path, "r") as f:269+ground_truth_dict: Dict[str, Any] = json.load(f)270+271+gt_label = (ground_truth_dict or {}).get("ai_activity_type")272+273+matched = pred == gt_label274+275+evaluation_results.append(276+EvaluationResult(277+request_id=req_id,278+request_body=res["request_body"],279+new_response=res.get("new_response"),280+valid_schema=res.get("valid_schema", True),281+quality_score=1.0 if matched else 0.0,282+quality_feedback="PASS" if matched else f"FAIL\nExpected: {gt_label}\nGot: {pred}",283+response_time=res.get("response_time"),284+success=True,285+ground_truth_match=matched,286+ )287+ )288+289+return evaluation_results290+291+292+if __name__ == "__main__":293+parser = create_parser(AiActivityTypeEvaluator)294+parser.add_argument(295+"--data-set",296+type=str,297+default="initial",298+dest="data_set",299+help="Dataset folder under eval_output/ai_activity_type/eval_datasets/ (default: initial)",300+ )301+302+parser.add_argument(303+"--populate-ground-truth-llm",304+action="store_true",305+dest="populate_ground_truth_llm",306+ )307+parser.add_argument(308+"--ground-truth-llm-endpoint",309+type=str,310+default="OPENAI:gpt-5_2",311+dest="ground_truth_llm_endpoint",312+ )313+314+parser.add_argument(315+"--compare-to-ground-truth",316+type=str,317+choices=["es", "llm"],318+default="es",319+dest="compare_to_ground_truth",320+ )321+322+args = parser.parse_args()323+AiActivityTypeEvaluator.DATA_SET = args.data_set324+325+AiActivityTypeEvaluator.POPULATE_GROUND_TRUTH_LLM = bool(args.populate_ground_truth_llm)326+AiActivityTypeEvaluator.GROUND_TRUTH_LLM_ENDPOINT = args.ground_truth_llm_endpoint327+328+AiActivityTypeEvaluator.COMPARE_TO_GROUND_TRUTH = args.compare_to_ground_truth329+330+asyncio.run(run_evaluation(AiActivityTypeEvaluator, args))</selection>” selected. Please summarize the selection using precise and concise language. Use headers and bulleted lists in the summary, to make it scannable. Maintain the meaning and factual accuracy.
You said
I’m on page “<tabTitle>Jy 19798 evaluation for ai activity types by nikol</tabTitle>” with “<selection>@@ -0,0 +1,330 @@1+#!/usr/bin/env python32+import asyncio3+import json4+import os5+from pathlib import Path6+from typing import Any, Dict, List7+8+import aiohttp9+10+from src.component.call_processing.schemes.ai_activity_type_request import AiActivityTypeRequest11+from src.component.call_processing.schemes.ai_activity_type_response import AiActivityTypeResponse12+from src.eval.abstract_evaluator import AbstractEvaluator13+from src.eval.collectors import collect_test_set as es_collect_test_set14+from src.eval.common_evaluator_runner import create_parser, run_evaluation15+from src.eval.endpoints import run_endpoint as run_endpoint_http16+from src.eval.models import EvaluationResult17+18+19+class AiActivityTypeEvaluator(AbstractEvaluator):20+ENDPOINT_PATH = "call/ai-activity-type"21+REQUEST_MODEL = AiActivityTypeRequest22+RESPONSE_MODEL = AiActivityTypeResponse23+OUTPUT_SUBFOLDER = "ai_activity_type"24+USES_LLM_EVALUATION = False25+26+READS_FROM_DATASET_FOLDER = True27+28+DATA_SET: str = "initial"29+30+MINIMUM_REQUEST_BODY_SIZE: int = 031+32+SKIP_UNREPLAYABLE_ON_COLLECT: bool = True33+REPLAYABILITY_CHECK_TIMEOUT_SECONDS: float = 20.034+35+POPULATE_GROUND_TRUTH_LLM: bool = False36+GROUND_TRUTH_LLM_ENDPOINT: str = "OPENAI:gpt-5_2"37+38+COMPARE_TO_GROUND_TRUTH: str = "es"39+40+def __init__(self, **kwargs: Any) -> None:41+super().__init__(**kwargs)42+_repo_root = Path(__file__).parents[2]43+_datasets_root = _repo_root / "eval_output" / self.OUTPUT_SUBFOLDER / "eval_datasets"44+_dataset_dir = _datasets_root / self.__class__.DATA_SET45+self._dataset_dir = _dataset_dir46+self._inputs_dir = _dataset_dir / "input"47+self._ground_truths_dir = _dataset_dir / "ground_truth"48+49+async def collect_test_set(self) -> List[Dict[str, Any]]:50+if self.es_host_name:51+return await self._collect_from_es()52+return await self._collect_from_files()53+54+async def _collect_from_es(self) -> List[Dict[str, Any]]:55+if self._inputs_dir.exists() or self._ground_truths_dir.exists():56+raise FileExistsError(57+f"Dataset folder already exists: {self._inputs_dir.parent}. "58+"Choose a different --data-set name or remove the folder manually."59+ )60+61+raw_samples = await es_collect_test_set(62+es_host_name=self.es_host_name,63+es_port=self.es_port,64+endpoint_path=self.ENDPOINT_PATH,65+limit=self.limit,66+language_filter=self.language_filter,67+min_prompt_length=self.min_prompt_length,68+is_json_response=self.IS_JSON_RESPONSE,69+exclude_languages=self.exclude_languages,70+ )71+72+self._inputs_dir.mkdir(parents=True, exist_ok=True)73+self._ground_truths_dir.mkdir(parents=True, exist_ok=True)74+75+min_size = self.MINIMUM_REQUEST_BODY_SIZE76+samples: List[Dict[str, Any]] = []77+skipped_no_response = 078+skipped_too_small = 079+skipped_unreplayable = 080+skipped_probe_errors = 081+82+endpoint_url = f"{self.api_host}/{self.ENDPOINT_PATH}"83+84+timeout = aiohttp.ClientTimeout(total=self.REPLAYABILITY_CHECK_TIMEOUT_SECONDS)85+async with aiohttp.ClientSession(timeout=timeout) as session:86+for sample in raw_samples:87+es_id = sample["id"]88+request_body = sample["request_body"]89+original_response = sample.get("original_response")90+91+if not original_response:92+skipped_no_response += 193+continue94+95+if min_size and len(json.dumps(request_body)) < min_size:96+skipped_too_small += 197+continue98+99+if self.SKIP_UNREPLAYABLE_ON_COLLECT:100+try:101+async with session.post(endpoint_url, json=request_body) as resp:102+if resp.status != 200:103+body_text = await resp.text()104+if "Cannot find activity" in body_text:105+skipped_unreplayable += 1106+continue107+except Exception:108+skipped_probe_errors += 1109+110+with open(self._inputs_dir / f"{es_id}.json", "w") as f:111+json.dump(request_body, f, indent=2)112+113+with open(self._ground_truths_dir / f"gt_{es_id}.json", "w") as f:114+json.dump(original_response, f, indent=2)115+116+samples.append(117+ {118+"id": es_id,119+"request_body": request_body,120+"original_response": original_response,121+"ground_truth": original_response,122+ }123+ )124+125+print(f"Wrote {len(samples)} samples to {self._inputs_dir.parent}")126+if skipped_no_response:127+print(f"Skipped {skipped_no_response} records with no response body")128+if skipped_too_small:129+print(130+f"Skipped {skipped_too_small} records whose request body was smaller "131+f"than {min_size} characters"132+ )133+if skipped_unreplayable:134+print(f"Skipped {skipped_unreplayable} records that are not replayable (missing activity in ES)")135+if skipped_probe_errors:136+print(f"Warning: replayability probe errored for {skipped_probe_errors} records (kept those records)")137+138+if self.__class__.POPULATE_GROUND_TRUTH_LLM:139+label_results = await run_endpoint_http(140+test_set=samples,141+endpoint_url=endpoint_url,142+request_model=self.REQUEST_MODEL,143+force_llm_endpoint=self.__class__.GROUND_TRUTH_LLM_ENDPOINT,144+is_streaming_response=self.IS_STREAMING_RESPONSE,145+timeout_seconds=300.0,146+parallel_requests=self.parallel_requests,147+return_prompt_in_run=self.RETURN_PROMPT_IN_RUN,148+ )149+150+for i, r in enumerate(label_results):151+forced = self.__class__.GROUND_TRUTH_LLM_ENDPOINT152+model = forced.split(":", 1)[1] if ":" in forced else forced153+samples[i]["ground_truth_llm_model"] = model154+155+if not r.get("success", True):156+samples[i]["ground_truth_llm"] = None157+samples[i]["ground_truth_llm_reasoning"] = None158+samples[i]["ground_truth_llm_error_type"] = r.get("error_type")159+samples[i]["ground_truth_llm_error_message"] = r.get("error_message")160+continue161+162+resp = r.get("new_response") or {}163+samples[i]["ground_truth_llm"] = resp.get("ai_activity_type")164+samples[i]["ground_truth_llm_reasoning"] = resp.get("ai_activity_type_reasoning")165+166+return samples167+168+async def _collect_from_files(self) -> List[Dict[str, Any]]:169+if not self._inputs_dir.exists():170+raise FileNotFoundError(171+f"Dataset folder not found: {self._inputs_dir}. "172+"Run --steps collect first or check your --data-set name."173+ )174+175+samples: List[Dict[str, Any]] = []176+for filename in sorted(os.listdir(self._inputs_dir)):177+input_path = self._inputs_dir / filename178+gt_path = self._ground_truths_dir / f"gt_{filename}"179+180+if not gt_path.exists():181+print(f"Warning: ground truth not found for {filename}, skipping")182+continue183+184+with open(input_path, "r") as f:185+request_body: Dict[str, Any] = json.load(f)186+187+with open(gt_path, "r") as f:188+ground_truth: Dict[str, Any] = json.load(f)189+190+samples.append(191+ {192+"id": Path(filename).stem,193+"request_body": request_body,194+"original_response": None,195+"ground_truth": ground_truth,196+ }197+ )198+199+print(f"Loaded {len(samples)} samples from {self._inputs_dir.parent}")200+return samples201+202+async def evaluate_against_ground_truth(self, results: List[Dict[str, Any]]) -> List[EvaluationResult]:203+evaluation_results: List[EvaluationResult] = []204+compare_to = self.__class__.COMPARE_TO_GROUND_TRUTH205+206+for res in results:207+req_id = res["request_id"]208+is_success = res.get("success", True)209+210+if not is_success:211+evaluation_results.append(212+EvaluationResult(213+request_id=req_id,214+request_body=res["request_body"],215+new_response=res.get("new_response"),216+valid_schema=False,217+quality_score=0.0,218+quality_feedback=f"Request failed: {res.get('error_type')} - {res.get('error_message')}",219+response_time=res.get("response_time"),220+success=False,221+error_type=res.get("error_type"),222+error_message=res.get("error_message"),223+ground_truth_match=False,224+ )225+ )226+continue227+228+pred = (res.get("new_response") or {}).get("ai_activity_type")229+230+if compare_to == "llm":231+if "ground_truth_llm" not in res:232+evaluation_results.append(233+EvaluationResult(234+request_id=req_id,235+request_body=res["request_body"],236+new_response=res.get("new_response"),237+valid_schema=res.get("valid_schema", True),238+quality_score=0.0,239+quality_feedback=(240+"Missing ground_truth_llm in run results. Ensure collect step populated it and "241+"endpoints.py passes it through."242+ ),243+response_time=res.get("response_time"),244+success=True,245+ground_truth_match=False,246+ )247+ )248+continue249+gt_label = res.get("ground_truth_llm")250+else:251+gt_path = self._ground_truths_dir / f"gt_{req_id}.json"252+if not gt_path.exists():253+evaluation_results.append(254+EvaluationResult(255+request_id=req_id,256+request_body=res["request_body"],257+new_response=res.get("new_response"),258+valid_schema=res.get("valid_schema", True),259+quality_score=0.0,260+quality_feedback=f"Ground truth file not found: {gt_path}",261+response_time=res.get("response_time"),262+success=True,263+ground_truth_match=False,264+ )265+ )266+continue267+268+with open(gt_path, "r") as f:269+ground_truth_dict: Dict[str, Any] = json.load(f)270+271+gt_label = (ground_truth_dict or {}).get("ai_activity_type")272+273+matched = pred == gt_label274+275+evaluation_results.append(276+EvaluationResult(277+request_id=req_id,278+request_body=res["request_body"],279+new_response=res.get("new_response"),280+valid_schema=res.get("valid_schema", True),281+quality_score=1.0 if matched else 0.0,282+quality_feedback="PASS" if matched else f"FAIL\nExpected: {gt_label}\nGot: {pred}",283+response_time=res.get("response_time"),284+success=True,285+ground_truth_match=matched,286+ )287+ )288+289+return evaluation_results290+291+292+if __name__ == "__main__":293+parser = create_parser(AiActivityTypeEvaluator)294+parser.add_argument(295+"--data-set",296+type=str,297+default="initial",298+dest="data_set",299+help="Dataset folder under eval_output/ai_activity_type/eval_datasets/ (default: initial)",300+ )301+302+parser.add_argument(303+"--populate-ground-truth-llm",304+action="store_true",305+dest="populate_ground_truth_llm",306+ )307+parser.add_argument(308+"--ground-truth-llm-endpoint",309+type=str,310+default="OPENAI:gpt-5_2",311+dest="ground_truth_llm_endpoint",312+ )313+314+parser.add_argument(315+"--compare-to-ground-truth",316+type=str,317+choices=["es", "llm"],318+default="es",319+dest="compare_to_ground_truth",320+ )321+322+args = parser.parse_args()323+AiActivityTypeEvaluator.DATA_SET = args.data_set324+325+AiActivityTypeEvaluator.POPULATE_GROUND_TRUTH_LLM = bool(args.populate_ground_truth_llm)326+AiActivityTypeEvaluator.GROUND_TRUTH_LLM_ENDPOINT = args.ground_truth_llm_endpoint327+328+AiActivityTypeEvaluator.COMPARE_TO_GROUND_TRUTH = args.compare_to_ground_truth329+330+asyncio.run(run_evaluation(AiActivityTypeEvaluator, args))</selection>” selected.
Please summarize the selection using precise and concise language. Use headers and bulleted lists in the summary, to make it scannable. Maintain the meaning and factual accuracy.
Expand
Listen
Show more options
Gemini said
Gemini said
This Python script defines the
AiActivityTypeEvaluator
class, a specialized tool for evaluating AI-driven activity type classification. It extends a base evaluation framework to handle data collection, ground-truth comparison, and performance scoring.
Core Functionality
Core Functionality
Data Collection (
collect_test_set
):
* Supports fetching raw samples from
Elasticsearch (ES)
or loading them from
local JSON files
.
Implements a
replayability check
: It probes the live API endpoint to ensure the activity exists before including it in the dataset.
Filters data based on request body size, language, and the presence of an original response.
Ground Truth Management:
Saves inputs and "gold standard" responses to a local directory structure (
eval_output/ai_activity_type/...
).
Features an optional mode to populate ground truth using a high-order LLM (e.g.,
gpt-5_2
) if the
POPULATE_GROUND_TRUTH_LLM
flag is set.
Evaluation Logic (
evaluate_against_ground_truth
):
Compares the model's predicted
ai_activity_type
against either the original ES response or the LLM-generated ground truth.
Assigns a
quality_score
of
1.0
for a match and
0.0
for a mismatch or request failure.
Key Configuration Constants
Key Configuration Constants
Constant
Purpose
ENDPOINT_PATH
The specific API route being tested:
call/ai-activity-type
.
COMPARE_TO_GROUND_TRUTH
Determines if the baseline is the original data (
es
) or an
llm
.
SKIP_UNREPLAYABLE_ON_COLLECT
If
True
, discards records where the API returns "Cannot find activity."
REPLAYABILITY_CHECK_TIMEOUT_SECONDS
Limits the probe request to 20 seconds.
Constant
ENDPOINT_PATH
COMPARE_TO_GROUND_TRUTH
SKIP_UNREPLAYABLE_ON_COLLECT
REPLAYABILITY_CHECK_TIMEOUT_SECONDS
Purpose
The specific API route being tested:
call/ai-activity-type
.
Determines if the baseline is the original data (
es
) or an
llm
.
If
True
, discards records where the API returns "Cannot find activity."
Limits the probe request to 20 seconds.
Copy table
Execution Workflow
Execution Workflow
Parsing:
The script uses
create_parser
to handle CLI arguments like
--data-set
,
--populate-ground-truth-llm
, and
--compare-to-ground-truth
.
Initialization:
Sets up directory paths for inputs and ground truths based on the selected dataset name.
Run:
Executes the evaluation via
asyncio.run(run_evaluation(...))
, which orchestrates the collection, endpoint calling, and result scoring phases.
Copy prompt
Edit
You said are there soem issues with this PR
You said
are there soem issues with this PR
Listen
Show more options
Show thinking
Gemini said
Gemini said
Yes, there are several issues and code smells in this Pull Request, ranging from performance bottlenecks to architectural anti-patterns.
Here is a breakdown of the most notable issues, categorized by impact:
Performance & Async Anti-Patterns
Performance & Async Anti-Patterns
Sequential Requests Defeating Async (Lines 86-106):
Inside
_collect_from_es
, the code loops through
raw_samples
and
await
s a
session.post
request for each sample one by one. This means the script waits for one HTTP request to finish before starting the next, completely defeating the purpose of using
aiohttp
for asynchronous concurrency.
Fix:
Collect these coroutines into a list and use
asyncio.gather()
(ideally wrapped in an
asyncio.Semaphore
to avoid overwhelming the endpoint) to run the replayability probes concurrently.
Blocking File I/O in Async Functions (Lines 110-114, 184-188, 268-269):
Standard synchronous file operations (
with open(...)
,
json.dump
,
json.load
) are used inside
async def
functions. In Python, this blocks the entire event loop while the disk is reading/writing.
Fix:
Use an asynchronous file I/O library like
aiofiles
, or run the blocking I/O operations in a separate thread using
asyncio.to_thread()
.
Architecture & State Management
Architecture & State Management
Mutating Class-Level Variables (Lines 323-328):
The script parses CLI arguments and directly mutates the class attributes (e.g.,
AiActivityTypeEvaluator.DATA_SET = args.data_set
). This is a major anti-pattern. If you ever try to run tests in parallel or create multiple instances of this evaluator in a single process, the state will bleed across them.
Fix:
Pass these arguments into the
__init__
constructor of the instance (
self.data_set = args.data_set
) rather than modifying the class definition globally.
Code Quality & Edge Cases
Code Quality & Edge Cases
Broad Exception Catching (Line 107):
Using a bare
except Exception:
during the replayability probe is dangerous. It will catch
aiohttp.ClientError
(which is intended), but it will also silently swallow
TimeoutError
or even memory errors, making debugging incredibly difficult if the endpoint goes down.
Fix:
Scope the exception to specific expected errors, like
except (aiohttp.ClientError, asyncio.TimeoutError):
.
Inefficient Size Calculation (Line 95):
len(json.dumps(request_body)) < min_size
requires serializing the entire dictionary to a string
just
to check its length. Since
min_size
defaults to
0
, the
if min_size
short-circuit saves it for now, but if anyone sets a minimum size, this will become an unnecessary CPU bottleneck on large datasets.
Potential Path Traversal Risk (Lines 110, 113, 251):
The script writes and reads files directly using
f"{es_id}.json"
and
f"gt_{req_id}.json"
. If
es_id
or
req_id
originate from a database and ever contain characters like
../
, it could result in files being read from or written to unintended directories.
Fix:
Sanitize the IDs or strictly enforce that they only contain alphanumeric characters.
Would you like me to rewrite the
_collect_from_es
method to show how to fix the sequential async loop and blocking file I/O?
Enter a prompt for Gemini
encrypted
Enter a prompt for Gemini
encrypted
Open upload file menu...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":4,"bounds":{"left":0.00234375,"top":0.045138888,"width":0.0890625,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira","depth":4,"bounds":{"left":0.0,"top":0.08263889,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira","depth":5,"bounds":{"left":0.015625,"top":0.09236111,"width":0.11796875,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet","depth":4,"bounds":{"left":0.0,"top":0.11111111,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet","depth":5,"bounds":{"left":0.015625,"top":0.12083333,"width":0.1984375,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jiminny","depth":4,"bounds":{"left":0.0,"top":0.13958333,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Jiminny","depth":5,"bounds":{"left":0.015625,"top":0.14930555,"width":0.015625,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.07890625,"top":0.14583333,"width":0.009375,"height":0.016666668},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Tab","depth":4,"bounds":{"left":0.003125,"top":0.16944444,"width":0.08710937,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.003125,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Close Google Gemini (⌃X)","depth":6,"bounds":{"left":0.01640625,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"bounds":{"left":0.029296875,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"bounds":{"left":0.0421875,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"bounds":{"left":0.05546875,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"AI Chat settings","depth":7,"bounds":{"left":0.2171875,"top":0.047916666,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Close","depth":7,"bounds":{"left":0.23125,"top":0.047916666,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"WORK, Google Account: lukas.kovalik@jiminny.com","depth":12,"bounds":{"left":0.228125,"top":0.090277776,"width":0.015625,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Main menu","depth":12,"bounds":{"left":0.0984375,"top":0.090277776,"width":0.015625,"height":0.027777778},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Chat","depth":12,"bounds":{"left":0.1953125,"top":0.090277776,"width":0.015625,"height":0.027777778},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Open menu for conversation actions.","depth":12,"bounds":{"left":0.2109375,"top":0.090277776,"width":0.015625,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXHeading","text":"Conversation with Gemini","depth":15,"bounds":{"left":0.09335937,"top":0.12847222,"width":0.000390625,"height":0.00069444446},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Conversation with Gemini","depth":16,"bounds":{"left":0.09335937,"top":0.13055556,"width":0.14101562,"height":0.022222223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Copy prompt","depth":21,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"You said I’m on page “<tabTitle>Jy 19798 evaluation for ai activity types by nikol</tabTitle>” with “<selection>@@ -0,0 +1,330 @@1+#!/usr/bin/env python32+import asyncio3+import json4+import os5+from pathlib import Path6+from typing import Any, Dict, List7+8+import aiohttp9+10+from src.component.call_processing.schemes.ai_activity_type_request import AiActivityTypeRequest11+from src.component.call_processing.schemes.ai_activity_type_response import AiActivityTypeResponse12+from src.eval.abstract_evaluator import AbstractEvaluator13+from src.eval.collectors import collect_test_set as es_collect_test_set14+from src.eval.common_evaluator_runner import create_parser, run_evaluation15+from src.eval.endpoints import run_endpoint as run_endpoint_http16+from src.eval.models import EvaluationResult17+18+19+class AiActivityTypeEvaluator(AbstractEvaluator):20+ENDPOINT_PATH = "call/ai-activity-type"21+REQUEST_MODEL = AiActivityTypeRequest22+RESPONSE_MODEL = AiActivityTypeResponse23+OUTPUT_SUBFOLDER = "ai_activity_type"24+USES_LLM_EVALUATION = False25+26+READS_FROM_DATASET_FOLDER = True27+28+DATA_SET: str = "initial"29+30+MINIMUM_REQUEST_BODY_SIZE: int = 031+32+SKIP_UNREPLAYABLE_ON_COLLECT: bool = True33+REPLAYABILITY_CHECK_TIMEOUT_SECONDS: float = 20.034+35+POPULATE_GROUND_TRUTH_LLM: bool = False36+GROUND_TRUTH_LLM_ENDPOINT: str = "OPENAI:gpt-5_2"37+38+COMPARE_TO_GROUND_TRUTH: str = "es"39+40+def __init__(self, **kwargs: Any) -> None:41+super().__init__(**kwargs)42+_repo_root = Path(__file__).parents[2]43+_datasets_root = _repo_root / "eval_output" / self.OUTPUT_SUBFOLDER / "eval_datasets"44+_dataset_dir = _datasets_root / self.__class__.DATA_SET45+self._dataset_dir = _dataset_dir46+self._inputs_dir = _dataset_dir / "input"47+self._ground_truths_dir = _dataset_dir / "ground_truth"48+49+async def collect_test_set(self) -> List[Dict[str, Any]]:50+if self.es_host_name:51+return await self._collect_from_es()52+return await self._collect_from_files()53+54+async def _collect_from_es(self) -> List[Dict[str, Any]]:55+if self._inputs_dir.exists() or self._ground_truths_dir.exists():56+raise FileExistsError(57+f"Dataset folder already exists: {self._inputs_dir.parent}. "58+"Choose a different --data-set name or remove the folder manually."59+ )60+61+raw_samples = await es_collect_test_set(62+es_host_name=self.es_host_name,63+es_port=self.es_port,64+endpoint_path=self.ENDPOINT_PATH,65+limit=self.limit,66+language_filter=self.language_filter,67+min_prompt_length=self.min_prompt_length,68+is_json_response=self.IS_JSON_RESPONSE,69+exclude_languages=self.exclude_languages,70+ )71+72+self._inputs_dir.mkdir(parents=True, exist_ok=True)73+self._ground_truths_dir.mkdir(parents=True, exist_ok=True)74+75+min_size = self.MINIMUM_REQUEST_BODY_SIZE76+samples: List[Dict[str, Any]] = []77+skipped_no_response = 078+skipped_too_small = 079+skipped_unreplayable = 080+skipped_probe_errors = 081+82+endpoint_url = f"{self.api_host}/{self.ENDPOINT_PATH}"83+84+timeout = aiohttp.ClientTimeout(total=self.REPLAYABILITY_CHECK_TIMEOUT_SECONDS)85+async with aiohttp.ClientSession(timeout=timeout) as session:86+for sample in raw_samples:87+es_id = sample["id"]88+request_body = sample["request_body"]89+original_response = sample.get("original_response")90+91+if not original_response:92+skipped_no_response += 193+continue94+95+if min_size and len(json.dumps(request_body)) < min_size:96+skipped_too_small += 197+continue98+99+if self.SKIP_UNREPLAYABLE_ON_COLLECT:100+try:101+async with session.post(endpoint_url, json=request_body) as resp:102+if resp.status != 200:103+body_text = await resp.text()104+if "Cannot find activity" in body_text:105+skipped_unreplayable += 1106+continue107+except Exception:108+skipped_probe_errors += 1109+110+with open(self._inputs_dir / f"{es_id}.json", "w") as f:111+json.dump(request_body, f, indent=2)112+113+with open(self._ground_truths_dir / f"gt_{es_id}.json", "w") as f:114+json.dump(original_response, f, indent=2)115+116+samples.append(117+ {118+"id": es_id,119+"request_body": request_body,120+"original_response": original_response,121+"ground_truth": original_response,122+ }123+ )124+125+print(f"Wrote {len(samples)} samples to {self._inputs_dir.parent}")126+if skipped_no_response:127+print(f"Skipped {skipped_no_response} records with no response body")128+if skipped_too_small:129+print(130+f"Skipped {skipped_too_small} records whose request body was smaller "131+f"than {min_size} characters"132+ )133+if skipped_unreplayable:134+print(f"Skipped {skipped_unreplayable} records that are not replayable (missing activity in ES)")135+if skipped_probe_errors:136+print(f"Warning: replayability probe errored for {skipped_probe_errors} records (kept those records)")137+138+if self.__class__.POPULATE_GROUND_TRUTH_LLM:139+label_results = await run_endpoint_http(140+test_set=samples,141+endpoint_url=endpoint_url,142+request_model=self.REQUEST_MODEL,143+force_llm_endpoint=self.__class__.GROUND_TRUTH_LLM_ENDPOINT,144+is_streaming_response=self.IS_STREAMING_RESPONSE,145+timeout_seconds=300.0,146+parallel_requests=self.parallel_requests,147+return_prompt_in_run=self.RETURN_PROMPT_IN_RUN,148+ )149+150+for i, r in enumerate(label_results):151+forced = self.__class__.GROUND_TRUTH_LLM_ENDPOINT152+model = forced.split(":", 1)[1] if ":" in forced else forced153+samples[i]["ground_truth_llm_model"] = model154+155+if not r.get("success", True):156+samples[i]["ground_truth_llm"] = None157+samples[i]["ground_truth_llm_reasoning"] = None158+samples[i]["ground_truth_llm_error_type"] = r.get("error_type")159+samples[i]["ground_truth_llm_error_message"] = r.get("error_message")160+continue161+162+resp = r.get("new_response") or {}163+samples[i]["ground_truth_llm"] = resp.get("ai_activity_type")164+samples[i]["ground_truth_llm_reasoning"] = resp.get("ai_activity_type_reasoning")165+166+return samples167+168+async def _collect_from_files(self) -> List[Dict[str, Any]]:169+if not self._inputs_dir.exists():170+raise FileNotFoundError(171+f"Dataset folder not found: {self._inputs_dir}. "172+"Run --steps collect first or check your --data-set name."173+ )174+175+samples: List[Dict[str, Any]] = []176+for filename in sorted(os.listdir(self._inputs_dir)):177+input_path = self._inputs_dir / filename178+gt_path = self._ground_truths_dir / f"gt_{filename}"179+180+if not gt_path.exists():181+print(f"Warning: ground truth not found for {filename}, skipping")182+continue183+184+with open(input_path, "r") as f:185+request_body: Dict[str, Any] = json.load(f)186+187+with open(gt_path, "r") as f:188+ground_truth: Dict[str, Any] = json.load(f)189+190+samples.append(191+ {192+"id": Path(filename).stem,193+"request_body": request_body,194+"original_response": None,195+"ground_truth": ground_truth,196+ }197+ )198+199+print(f"Loaded {len(samples)} samples from {self._inputs_dir.parent}")200+return samples201+202+async def evaluate_against_ground_truth(self, results: List[Dict[str, Any]]) -> List[EvaluationResult]:203+evaluation_results: List[EvaluationResult] = []204+compare_to = self.__class__.COMPARE_TO_GROUND_TRUTH205+206+for res in results:207+req_id = res["request_id"]208+is_success = res.get("success", True)209+210+if not is_success:211+evaluation_results.append(212+EvaluationResult(213+request_id=req_id,214+request_body=res["request_body"],215+new_response=res.get("new_response"),216+valid_schema=False,217+quality_score=0.0,218+quality_feedback=f"Request failed: {res.get('error_type')} - {res.get('error_message')}",219+response_time=res.get("response_time"),220+success=False,221+error_type=res.get("error_type"),222+error_message=res.get("error_message"),223+ground_truth_match=False,224+ )225+ )226+continue227+228+pred = (res.get("new_response") or {}).get("ai_activity_type")229+230+if compare_to == "llm":231+if "ground_truth_llm" not in res:232+evaluation_results.append(233+EvaluationResult(234+request_id=req_id,235+request_body=res["request_body"],236+new_response=res.get("new_response"),237+valid_schema=res.get("valid_schema", True),238+quality_score=0.0,239+quality_feedback=(240+"Missing ground_truth_llm in run results. Ensure collect step populated it and "241+"endpoints.py passes it through."242+ ),243+response_time=res.get("response_time"),244+success=True,245+ground_truth_match=False,246+ )247+ )248+continue249+gt_label = res.get("ground_truth_llm")250+else:251+gt_path = self._ground_truths_dir / f"gt_{req_id}.json"252+if not gt_path.exists():253+evaluation_results.append(254+EvaluationResult(255+request_id=req_id,256+request_body=res["request_body"],257+new_response=res.get("new_response"),258+valid_schema=res.get("valid_schema", True),259+quality_score=0.0,260+quality_feedback=f"Ground truth file not found: {gt_path}",261+response_time=res.get("response_time"),262+success=True,263+ground_truth_match=False,264+ )265+ )266+continue267+268+with open(gt_path, "r") as f:269+ground_truth_dict: Dict[str, Any] = json.load(f)270+271+gt_label = (ground_truth_dict or {}).get("ai_activity_type")272+273+matched = pred == gt_label274+275+evaluation_results.append(276+EvaluationResult(277+request_id=req_id,278+request_body=res["request_body"],279+new_response=res.get("new_response"),280+valid_schema=res.get("valid_schema", True),281+quality_score=1.0 if matched else 0.0,282+quality_feedback="PASS" if matched else f"FAIL\\nExpected: {gt_label}\\nGot: {pred}",283+response_time=res.get("response_time"),284+success=True,285+ground_truth_match=matched,286+ )287+ )288+289+return evaluation_results290+291+292+if __name__ == "__main__":293+parser = create_parser(AiActivityTypeEvaluator)294+parser.add_argument(295+"--data-set",296+type=str,297+default="initial",298+dest="data_set",299+help="Dataset folder under eval_output/ai_activity_type/eval_datasets/ (default: initial)",300+ )301+302+parser.add_argument(303+"--populate-ground-truth-llm",304+action="store_true",305+dest="populate_ground_truth_llm",306+ )307+parser.add_argument(308+"--ground-truth-llm-endpoint",309+type=str,310+default="OPENAI:gpt-5_2",311+dest="ground_truth_llm_endpoint",312+ )313+314+parser.add_argument(315+"--compare-to-ground-truth",316+type=str,317+choices=["es", "llm"],318+default="es",319+dest="compare_to_ground_truth",320+ )321+322+args = parser.parse_args()323+AiActivityTypeEvaluator.DATA_SET = args.data_set324+325+AiActivityTypeEvaluator.POPULATE_GROUND_TRUTH_LLM = bool(args.populate_ground_truth_llm)326+AiActivityTypeEvaluator.GROUND_TRUTH_LLM_ENDPOINT = args.ground_truth_llm_endpoint327+328+AiActivityTypeEvaluator.COMPARE_TO_GROUND_TRUTH = args.compare_to_ground_truth329+330+asyncio.run(run_evaluation(AiActivityTypeEvaluator, args))</selection>” selected. Please summarize the selection using precise and concise language. Use headers and bulleted lists in the summary, to make it scannable. Maintain the meaning and factual accuracy.","depth":21,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"You said","depth":23,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"I’m on page “<tabTitle>Jy 19798 evaluation for ai activity types by nikol</tabTitle>” with “<selection>@@ -0,0 +1,330 @@1+#!/usr/bin/env python32+import asyncio3+import json4+import os5+from pathlib import Path6+from typing import Any, Dict, List7+8+import aiohttp9+10+from src.component.call_processing.schemes.ai_activity_type_request import AiActivityTypeRequest11+from src.component.call_processing.schemes.ai_activity_type_response import AiActivityTypeResponse12+from src.eval.abstract_evaluator import AbstractEvaluator13+from src.eval.collectors import collect_test_set as es_collect_test_set14+from src.eval.common_evaluator_runner import create_parser, run_evaluation15+from src.eval.endpoints import run_endpoint as run_endpoint_http16+from src.eval.models import EvaluationResult17+18+19+class AiActivityTypeEvaluator(AbstractEvaluator):20+ENDPOINT_PATH = "call/ai-activity-type"21+REQUEST_MODEL = AiActivityTypeRequest22+RESPONSE_MODEL = AiActivityTypeResponse23+OUTPUT_SUBFOLDER = "ai_activity_type"24+USES_LLM_EVALUATION = False25+26+READS_FROM_DATASET_FOLDER = True27+28+DATA_SET: str = "initial"29+30+MINIMUM_REQUEST_BODY_SIZE: int = 031+32+SKIP_UNREPLAYABLE_ON_COLLECT: bool = True33+REPLAYABILITY_CHECK_TIMEOUT_SECONDS: float = 20.034+35+POPULATE_GROUND_TRUTH_LLM: bool = False36+GROUND_TRUTH_LLM_ENDPOINT: str = "OPENAI:gpt-5_2"37+38+COMPARE_TO_GROUND_TRUTH: str = "es"39+40+def __init__(self, **kwargs: Any) -> None:41+super().__init__(**kwargs)42+_repo_root = Path(__file__).parents[2]43+_datasets_root = _repo_root / "eval_output" / self.OUTPUT_SUBFOLDER / "eval_datasets"44+_dataset_dir = _datasets_root / self.__class__.DATA_SET45+self._dataset_dir = _dataset_dir46+self._inputs_dir = _dataset_dir / "input"47+self._ground_truths_dir = _dataset_dir / "ground_truth"48+49+async def collect_test_set(self) -> List[Dict[str, Any]]:50+if self.es_host_name:51+return await self._collect_from_es()52+return await self._collect_from_files()53+54+async def _collect_from_es(self) -> List[Dict[str, Any]]:55+if self._inputs_dir.exists() or self._ground_truths_dir.exists():56+raise FileExistsError(57+f"Dataset folder already exists: {self._inputs_dir.parent}. "58+"Choose a different --data-set name or remove the folder manually."59+ )60+61+raw_samples = await es_collect_test_set(62+es_host_name=self.es_host_name,63+es_port=self.es_port,64+endpoint_path=self.ENDPOINT_PATH,65+limit=self.limit,66+language_filter=self.language_filter,67+min_prompt_length=self.min_prompt_length,68+is_json_response=self.IS_JSON_RESPONSE,69+exclude_languages=self.exclude_languages,70+ )71+72+self._inputs_dir.mkdir(parents=True, exist_ok=True)73+self._ground_truths_dir.mkdir(parents=True, exist_ok=True)74+75+min_size = self.MINIMUM_REQUEST_BODY_SIZE76+samples: List[Dict[str, Any]] = []77+skipped_no_response = 078+skipped_too_small = 079+skipped_unreplayable = 080+skipped_probe_errors = 081+82+endpoint_url = f"{self.api_host}/{self.ENDPOINT_PATH}"83+84+timeout = aiohttp.ClientTimeout(total=self.REPLAYABILITY_CHECK_TIMEOUT_SECONDS)85+async with aiohttp.ClientSession(timeout=timeout) as session:86+for sample in raw_samples:87+es_id = sample["id"]88+request_body = sample["request_body"]89+original_response = sample.get("original_response")90+91+if not original_response:92+skipped_no_response += 193+continue94+95+if min_size and len(json.dumps(request_body)) < min_size:96+skipped_too_small += 197+continue98+99+if self.SKIP_UNREPLAYABLE_ON_COLLECT:100+try:101+async with session.post(endpoint_url, json=request_body) as resp:102+if resp.status != 200:103+body_text = await resp.text()104+if "Cannot find activity" in body_text:105+skipped_unreplayable += 1106+continue107+except Exception:108+skipped_probe_errors += 1109+110+with open(self._inputs_dir / f"{es_id}.json", "w") as f:111+json.dump(request_body, f, indent=2)112+113+with open(self._ground_truths_dir / f"gt_{es_id}.json", "w") as f:114+json.dump(original_response, f, indent=2)115+116+samples.append(117+ {118+"id": es_id,119+"request_body": request_body,120+"original_response": original_response,121+"ground_truth": original_response,122+ }123+ )124+125+print(f"Wrote {len(samples)} samples to {self._inputs_dir.parent}")126+if skipped_no_response:127+print(f"Skipped {skipped_no_response} records with no response body")128+if skipped_too_small:129+print(130+f"Skipped {skipped_too_small} records whose request body was smaller "131+f"than {min_size} characters"132+ )133+if skipped_unreplayable:134+print(f"Skipped {skipped_unreplayable} records that are not replayable (missing activity in ES)")135+if skipped_probe_errors:136+print(f"Warning: replayability probe errored for {skipped_probe_errors} records (kept those records)")137+138+if self.__class__.POPULATE_GROUND_TRUTH_LLM:139+label_results = await run_endpoint_http(140+test_set=samples,141+endpoint_url=endpoint_url,142+request_model=self.REQUEST_MODEL,143+force_llm_endpoint=self.__class__.GROUND_TRUTH_LLM_ENDPOINT,144+is_streaming_response=self.IS_STREAMING_RESPONSE,145+timeout_seconds=300.0,146+parallel_requests=self.parallel_requests,147+return_prompt_in_run=self.RETURN_PROMPT_IN_RUN,148+ )149+150+for i, r in enumerate(label_results):151+forced = self.__class__.GROUND_TRUTH_LLM_ENDPOINT152+model = forced.split(":", 1)[1] if ":" in forced else forced153+samples[i]["ground_truth_llm_model"] = model154+155+if not r.get("success", True):156+samples[i]["ground_truth_llm"] = None157+samples[i]["ground_truth_llm_reasoning"] = None158+samples[i]["ground_truth_llm_error_type"] = r.get("error_type")159+samples[i]["ground_truth_llm_error_message"] = r.get("error_message")160+continue161+162+resp = r.get("new_response") or {}163+samples[i]["ground_truth_llm"] = resp.get("ai_activity_type")164+samples[i]["ground_truth_llm_reasoning"] = resp.get("ai_activity_type_reasoning")165+166+return samples167+168+async def _collect_from_files(self) -> List[Dict[str, Any]]:169+if not self._inputs_dir.exists():170+raise FileNotFoundError(171+f"Dataset folder not found: {self._inputs_dir}. "172+"Run --steps collect first or check your --data-set name."173+ )174+175+samples: List[Dict[str, Any]] = []176+for filename in sorted(os.listdir(self._inputs_dir)):177+input_path = self._inputs_dir / filename178+gt_path = self._ground_truths_dir / f"gt_{filename}"179+180+if not gt_path.exists():181+print(f"Warning: ground truth not found for {filename}, skipping")182+continue183+184+with open(input_path, "r") as f:185+request_body: Dict[str, Any] = json.load(f)186+187+with open(gt_path, "r") as f:188+ground_truth: Dict[str, Any] = json.load(f)189+190+samples.append(191+ {192+"id": Path(filename).stem,193+"request_body": request_body,194+"original_response": None,195+"ground_truth": ground_truth,196+ }197+ )198+199+print(f"Loaded {len(samples)} samples from {self._inputs_dir.parent}")200+return samples201+202+async def evaluate_against_ground_truth(self, results: List[Dict[str, Any]]) -> List[EvaluationResult]:203+evaluation_results: List[EvaluationResult] = []204+compare_to = self.__class__.COMPARE_TO_GROUND_TRUTH205+206+for res in results:207+req_id = res["request_id"]208+is_success = res.get("success", True)209+210+if not is_success:211+evaluation_results.append(212+EvaluationResult(213+request_id=req_id,214+request_body=res["request_body"],215+new_response=res.get("new_response"),216+valid_schema=False,217+quality_score=0.0,218+quality_feedback=f"Request failed: {res.get('error_type')} - {res.get('error_message')}",219+response_time=res.get("response_time"),220+success=False,221+error_type=res.get("error_type"),222+error_message=res.get("error_message"),223+ground_truth_match=False,224+ )225+ )226+continue227+228+pred = (res.get("new_response") or {}).get("ai_activity_type")229+230+if compare_to == "llm":231+if "ground_truth_llm" not in res:232+evaluation_results.append(233+EvaluationResult(234+request_id=req_id,235+request_body=res["request_body"],236+new_response=res.get("new_response"),237+valid_schema=res.get("valid_schema", True),238+quality_score=0.0,239+quality_feedback=(240+"Missing ground_truth_llm in run results. Ensure collect step populated it and "241+"endpoints.py passes it through."242+ ),243+response_time=res.get("response_time"),244+success=True,245+ground_truth_match=False,246+ )247+ )248+continue249+gt_label = res.get("ground_truth_llm")250+else:251+gt_path = self._ground_truths_dir / f"gt_{req_id}.json"252+if not gt_path.exists():253+evaluation_results.append(254+EvaluationResult(255+request_id=req_id,256+request_body=res["request_body"],257+new_response=res.get("new_response"),258+valid_schema=res.get("valid_schema", True),259+quality_score=0.0,260+quality_feedback=f"Ground truth file not found: {gt_path}",261+response_time=res.get("response_time"),262+success=True,263+ground_truth_match=False,264+ )265+ )266+continue267+268+with open(gt_path, "r") as f:269+ground_truth_dict: Dict[str, Any] = json.load(f)270+271+gt_label = (ground_truth_dict or {}).get("ai_activity_type")272+273+matched = pred == gt_label274+275+evaluation_results.append(276+EvaluationResult(277+request_id=req_id,278+request_body=res["request_body"],279+new_response=res.get("new_response"),280+valid_schema=res.get("valid_schema", True),281+quality_score=1.0 if matched else 0.0,282+quality_feedback="PASS" if matched else f"FAIL\\nExpected: {gt_label}\\nGot: {pred}",283+response_time=res.get("response_time"),284+success=True,285+ground_truth_match=matched,286+ )287+ )288+289+return evaluation_results290+291+292+if __name__ == "__main__":293+parser = create_parser(AiActivityTypeEvaluator)294+parser.add_argument(295+"--data-set",296+type=str,297+default="initial",298+dest="data_set",299+help="Dataset folder under eval_output/ai_activity_type/eval_datasets/ (default: initial)",300+ )301+302+parser.add_argument(303+"--populate-ground-truth-llm",304+action="store_true",305+dest="populate_ground_truth_llm",306+ )307+parser.add_argument(308+"--ground-truth-llm-endpoint",309+type=str,310+default="OPENAI:gpt-5_2",311+dest="ground_truth_llm_endpoint",312+ )313+314+parser.add_argument(315+"--compare-to-ground-truth",316+type=str,317+choices=["es", "llm"],318+default="es",319+dest="compare_to_ground_truth",320+ )321+322+args = parser.parse_args()323+AiActivityTypeEvaluator.DATA_SET = args.data_set324+325+AiActivityTypeEvaluator.POPULATE_GROUND_TRUTH_LLM = bool(args.populate_ground_truth_llm)326+AiActivityTypeEvaluator.GROUND_TRUTH_LLM_ENDPOINT = args.ground_truth_llm_endpoint327+328+AiActivityTypeEvaluator.COMPARE_TO_GROUND_TRUTH = args.compare_to_ground_truth329+330+asyncio.run(run_evaluation(AiActivityTypeEvaluator, args))</selection>” selected.","depth":23,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Please summarize the selection using precise and concise language. Use headers and bulleted lists in the summary, to make it scannable. Maintain the meaning and factual accuracy.","depth":23,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Expand","depth":21,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Listen","depth":22,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Show more options","depth":20,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Gemini said","depth":20,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Gemini said","depth":21,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"This Python script defines the","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"AiActivityTypeEvaluator","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"class, a specialized tool for evaluating AI-driven activity type classification. It extends a base evaluation framework to handle data collection, ground-truth comparison, and performance scoring.","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Core Functionality","depth":23,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Core Functionality","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Data Collection (","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"collect_test_set","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"):","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"* Supports fetching raw samples from","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Elasticsearch (ES)","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"or loading them from","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"local JSON files","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Implements a","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"replayability check","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":": It probes the live API endpoint to ensure the activity exists before including it in the dataset.","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Filters data based on request body size, language, and the presence of an original response.","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Ground Truth Management:","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Saves inputs and \"gold standard\" responses to a local directory structure (","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"eval_output/ai_activity_type/...","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":").","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Features an optional mode to populate ground truth using a high-order LLM (e.g.,","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"gpt-5_2","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":") if the","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"POPULATE_GROUND_TRUTH_LLM","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"flag is set.","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Evaluation Logic (","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"evaluate_against_ground_truth","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"):","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Compares the model's predicted","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ai_activity_type","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"against either the original ES response or the LLM-generated ground truth.","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Assigns a","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"quality_score","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"of","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1.0","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"for a match and","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.0","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"for a mismatch or request failure.","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Key Configuration Constants","depth":23,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Key Configuration Constants","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Constant","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Purpose","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ENDPOINT_PATH","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"The specific API route being tested:","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"call/ai-activity-type","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"COMPARE_TO_GROUND_TRUTH","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Determines if the baseline is the original data (","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"es","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":") or an","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"llm","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"SKIP_UNREPLAYABLE_ON_COLLECT","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"If","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"True","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":", discards records where the API returns \"Cannot find activity.\"","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"REPLAYABILITY_CHECK_TIMEOUT_SECONDS","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Limits the probe request to 20 seconds.","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Constant","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ENDPOINT_PATH","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"COMPARE_TO_GROUND_TRUTH","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"SKIP_UNREPLAYABLE_ON_COLLECT","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"REPLAYABILITY_CHECK_TIMEOUT_SECONDS","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Purpose","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"The specific API route being tested:","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"call/ai-activity-type","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Determines if the baseline is the original data (","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"es","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":") or an","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"llm","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"If","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"True","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":", discards records where the API returns \"Cannot find activity.\"","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Limits the probe request to 20 seconds.","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Copy table","depth":24,"bounds":{"left":0.22070312,"top":0.0,"width":0.015625,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Execution Workflow","depth":23,"bounds":{"left":0.103125,"top":0.0,"width":0.13320312,"height":0.016666668},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Execution Workflow","depth":24,"bounds":{"left":0.103125,"top":0.0,"width":0.060546875,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Parsing:","depth":26,"bounds":{"left":0.1171875,"top":0.009027778,"width":0.024609376,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"The script uses","depth":26,"bounds":{"left":0.14179687,"top":0.009027778,"width":0.04609375,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"create_parser","depth":27,"bounds":{"left":0.19023438,"top":0.010416667,"width":0.042578124,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"to handle CLI arguments like","depth":26,"bounds":{"left":0.1171875,"top":0.009027778,"width":0.119140625,"height":0.03263889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"--data-set","depth":27,"bounds":{"left":0.1171875,"top":0.028472222,"width":0.107421875,"height":0.03125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":",","depth":26,"bounds":{"left":0.12929687,"top":0.045138888,"width":0.003125,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"--populate-ground-truth-llm","depth":27,"bounds":{"left":0.13476562,"top":0.046527777,"width":0.08867188,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":", and","depth":26,"bounds":{"left":0.1171875,"top":0.045138888,"width":0.11171875,"height":0.03263889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"--compare-to-ground-truth","depth":27,"bounds":{"left":0.13203125,"top":0.06458333,"width":0.08203125,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":26,"bounds":{"left":0.21640626,"top":0.063194446,"width":0.0015625,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Initialization:","depth":26,"bounds":{"left":0.1171875,"top":0.08680555,"width":0.039453126,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Sets up directory paths for inputs and ground truths based on the selected dataset name.","depth":26,"bounds":{"left":0.1171875,"top":0.08680555,"width":0.11875,"height":0.050694443},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Run:","depth":26,"bounds":{"left":0.1171875,"top":0.14652778,"width":0.013671875,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Executes the evaluation via","depth":26,"bounds":{"left":0.13085938,"top":0.14652778,"width":0.080078125,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"asyncio.run(run_evaluation(...))","depth":27,"bounds":{"left":0.11953125,"top":0.16597222,"width":0.10507812,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":", which orchestrates the collection, endpoint calling, and result scoring phases.","depth":26,"bounds":{"left":0.1171875,"top":0.16458334,"width":0.11289062,"height":0.06875},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Copy prompt","depth":21,"bounds":{"left":0.1203125,"top":0.28194445,"width":0.015625,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Edit","depth":21,"bounds":{"left":0.1375,"top":0.28194445,"width":0.015625,"height":0.027777778},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"You said are there soem issues with this PR","depth":21,"bounds":{"left":0.1609375,"top":0.29027778,"width":0.072265625,"height":0.03888889},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"You said","depth":23,"bounds":{"left":0.09335937,"top":0.2923611,"width":0.0234375,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"are there soem issues with this PR","depth":23,"bounds":{"left":0.1609375,"top":0.29305556,"width":0.062109374,"height":0.034027778},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Listen","depth":22,"bounds":{"left":0.22382812,"top":0.35694444,"width":0.015625,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Show more options","depth":20,"bounds":{"left":0.22382812,"top":0.35208333,"width":0.015625,"height":0.027777778},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Show thinking","depth":26,"bounds":{"left":0.11953125,"top":0.35902777,"width":0.036328126,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Gemini said","depth":20,"bounds":{"left":0.11679687,"top":0.3951389,"width":0.000390625,"height":0.00069444446},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Gemini said","depth":21,"bounds":{"left":0.11679687,"top":0.39652777,"width":0.048046876,"height":0.016666668},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Yes, there are several issues and code smells in this Pull Request, ranging from performance bottlenecks to architectural anti-patterns.","depth":24,"bounds":{"left":0.10390625,"top":0.40347221,"width":0.13242188,"height":0.050694443},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Here is a breakdown of the most notable issues, categorized by impact:","depth":24,"bounds":{"left":0.10390625,"top":0.46875,"width":0.11640625,"height":0.03263889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Performance & Async Anti-Patterns","depth":23,"bounds":{"left":0.10390625,"top":0.5222222,"width":0.13242188,"height":0.016666668},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Performance & Async Anti-Patterns","depth":24,"bounds":{"left":0.10390625,"top":0.5236111,"width":0.10859375,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Sequential Requests Defeating Async (Lines 86-106):","depth":26,"bounds":{"left":0.11757813,"top":0.5465278,"width":0.11601563,"height":0.03263889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Inside","depth":26,"bounds":{"left":0.16289063,"top":0.56458336,"width":0.019921875,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"_collect_from_es","depth":27,"bounds":{"left":0.11992188,"top":0.58402777,"width":0.05234375,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":", the code loops through","depth":26,"bounds":{"left":0.11757813,"top":0.58263886,"width":0.10429688,"height":0.03263889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"raw_samples","depth":27,"bounds":{"left":0.14414063,"top":0.6020833,"width":0.0359375,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"and","depth":26,"bounds":{"left":0.18242188,"top":0.6006944,"width":0.0140625,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"await","depth":27,"bounds":{"left":0.19882813,"top":0.6020833,"width":0.01640625,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"s a","depth":26,"bounds":{"left":0.21757813,"top":0.6006944,"width":0.009765625,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"session.post","depth":27,"bounds":{"left":0.11992188,"top":0.6201389,"width":0.039453126,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"request for each sample one by one. This means the script waits for one HTTP request to finish before starting the next, completely defeating the purpose of using","depth":26,"bounds":{"left":0.11757813,"top":0.61875,"width":0.11640625,"height":0.08680555},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"aiohttp","depth":27,"bounds":{"left":0.18046875,"top":0.6923611,"width":0.023046875,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"for asynchronous concurrency.","depth":26,"bounds":{"left":0.11757813,"top":0.6909722,"width":0.09921875,"height":0.03263889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Fix:","depth":28,"bounds":{"left":0.1296875,"top":0.7326389,"width":0.009765625,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Collect these coroutines into a list and use","depth":28,"bounds":{"left":0.1296875,"top":0.7326389,"width":0.09921875,"height":0.03263889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"asyncio.gather()","depth":29,"bounds":{"left":0.16601562,"top":0.75208336,"width":0.05234375,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(ideally wrapped in an","depth":28,"bounds":{"left":0.1296875,"top":0.75069445,"width":0.09257813,"height":0.03263889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"asyncio.Semaphore","depth":29,"bounds":{"left":0.13203125,"top":0.7881944,"width":0.055859376,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"to avoid overwhelming the endpoint) to run the replayability probes concurrently.","depth":28,"bounds":{"left":0.1296875,"top":0.78680557,"width":0.10546875,"height":0.050694443},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Blocking File I/O in Async Functions (Lines 110-114, 184-188, 268-269):","depth":26,"bounds":{"left":0.11757813,"top":0.84652776,"width":0.10976563,"height":0.03263889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Standard synchronous file operations (","depth":26,"bounds":{"left":0.11757813,"top":0.8645833,"width":0.107421875,"height":0.050694443},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"with open(...)","depth":27,"bounds":{"left":0.12226562,"top":0.90208334,"width":0.045703124,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":",","depth":26,"bounds":{"left":0.1703125,"top":0.90069443,"width":0.003515625,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"json.dump","depth":27,"bounds":{"left":0.17617187,"top":0.90208334,"width":0.029296875,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":",","depth":26,"bounds":{"left":0.2078125,"top":0.90069443,"width":0.003125,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"json.load","depth":27,"bounds":{"left":0.11992188,"top":0.9201389,"width":0.0296875,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":") are used inside","depth":26,"bounds":{"left":0.15195313,"top":0.91875,"width":0.048046876,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"async def","depth":27,"bounds":{"left":0.20234375,"top":0.9201389,"width":0.0296875,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"functions. In Python, this blocks the entire event loop while the disk is reading/writing.","depth":26,"bounds":{"left":0.11757813,"top":0.91875,"width":0.11875,"height":0.06875},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Fix:","depth":28,"bounds":{"left":0.1296875,"top":0.9965278,"width":0.009765625,"height":0.003472209},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Use an asynchronous file I/O library like","depth":28,"bounds":{"left":0.1296875,"top":0.9965278,"width":0.09335937,"height":0.003472209},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"aiofiles","depth":29,"bounds":{"left":0.1625,"top":1.0,"width":0.0265625,"height":-0.015972257},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":", or run the blocking I/O operations in a separate thread using","depth":28,"bounds":{"left":0.1296875,"top":1.0,"width":0.10585938,"height":-0.014583349},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"asyncio.to_thread()","depth":29,"bounds":{"left":0.16914062,"top":1.0,"width":0.0625,"height":-0.052083373},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":28,"bounds":{"left":0.23398438,"top":1.0,"width":0.0015625,"height":-0.050694466},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Architecture & State Management","depth":23,"bounds":{"left":0.10390625,"top":1.0,"width":0.13242188,"height":-0.08611107},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Architecture & State Management","depth":24,"bounds":{"left":0.10390625,"top":1.0,"width":0.103515625,"height":-0.087499976},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Mutating Class-Level Variables (Lines 323-328):","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"The script parses CLI arguments and directly mutates the class attributes (e.g.,","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"AiActivityTypeEvaluator.DATA_SET = args.data_set","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"). This is a major anti-pattern. If you ever try to run tests in parallel or create multiple instances of this evaluator in a single process, the state will bleed across them.","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Fix:","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Pass these arguments into the","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"__init__","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"constructor of the instance (","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"self.data_set = args.data_set","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":") rather than modifying the class definition globally.","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Code Quality & Edge Cases","depth":23,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Code Quality & Edge Cases","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Broad Exception Catching (Line 107):","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Using a bare","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"except Exception:","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"during the replayability probe is dangerous. It will catch","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"aiohttp.ClientError","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(which is intended), but it will also silently swallow","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"TimeoutError","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"or even memory errors, making debugging incredibly difficult if the endpoint goes down.","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Fix:","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Scope the exception to specific expected errors, like","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"except (aiohttp.ClientError, asyncio.TimeoutError):","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Inefficient Size Calculation (Line 95):","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"len(json.dumps(request_body)) < min_size","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"requires serializing the entire dictionary to a string","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"just","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"to check its length. Since","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"min_size","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"defaults to","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":", the","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"if min_size","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"short-circuit saves it for now, but if anyone sets a minimum size, this will become an unnecessary CPU bottleneck on large datasets.","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Potential Path Traversal Risk (Lines 110, 113, 251):","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"The script writes and reads files directly using","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"f\"{es_id}.json\"","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"and","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"f\"gt_{req_id}.json\"","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":". If","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"es_id","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"or","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"req_id","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"originate from a database and ever contain characters like","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"../","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":", it could result in files being read from or written to unintended directories.","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Fix:","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Sanitize the IDs or strictly enforce that they only contain alphanumeric characters.","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Would you like me to rewrite the","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"_collect_from_es","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"method to show how to fix the sequential async loop and blocking file I/O?","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextArea","text":"Enter a prompt for Gemini\nencrypted","depth":20,"bounds":{"left":0.109375,"top":0.8354167,"width":0.125,"height":0.016666668},"value":"Enter a prompt for Gemini\nencrypted","help_text":"","role_description":"text entry area","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Enter a prompt for Gemini","depth":21,"bounds":{"left":0.1171875,"top":0.8354167,"width":0.08203125,"height":0.016666668},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"encrypted","depth":21,"bounds":{"left":0.10820313,"top":0.8354167,"width":0.0078125,"height":0.016666668},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open upload file menu","depth":20,"bounds":{"left":0.1046875,"top":0.86527777,"width":0.015625,"height":0.027777778},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
-6264578760586490979
|
8732321574906802243
|
visual_change
|
accessibility
|
NULL
|
JY-20543 add AJ reports User pilot tracking by Lak JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Jiminny
Jiminny
Close tab
New Tab
Customize sidebar
Close Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
AI Chat settings
Close
WORK, Google Account: [EMAIL]
Main menu
New Chat
Open menu for conversation actions.
Conversation with Gemini
Conversation with Gemini
Copy prompt
You said I’m on page “<tabTitle>Jy 19798 evaluation for ai activity types by nikol</tabTitle>” with “<selection>@@ -0,0 +1,330 @@1+#!/usr/bin/env python32+import asyncio3+import json4+import os5+from pathlib import Path6+from typing import Any, Dict, List7+8+import aiohttp9+10+from src.component.call_processing.schemes.ai_activity_type_request import AiActivityTypeRequest11+from src.component.call_processing.schemes.ai_activity_type_response import AiActivityTypeResponse12+from src.eval.abstract_evaluator import AbstractEvaluator13+from src.eval.collectors import collect_test_set as es_collect_test_set14+from src.eval.common_evaluator_runner import create_parser, run_evaluation15+from src.eval.endpoints import run_endpoint as run_endpoint_http16+from src.eval.models import EvaluationResult17+18+19+class AiActivityTypeEvaluator(AbstractEvaluator):20+ENDPOINT_PATH = "call/ai-activity-type"21+REQUEST_MODEL = AiActivityTypeRequest22+RESPONSE_MODEL = AiActivityTypeResponse23+OUTPUT_SUBFOLDER = "ai_activity_type"24+USES_LLM_EVALUATION = False25+26+READS_FROM_DATASET_FOLDER = True27+28+DATA_SET: str = "initial"29+30+MINIMUM_REQUEST_BODY_SIZE: int = 031+32+SKIP_UNREPLAYABLE_ON_COLLECT: bool = True33+REPLAYABILITY_CHECK_TIMEOUT_SECONDS: float = 20.034+35+POPULATE_GROUND_TRUTH_LLM: bool = False36+GROUND_TRUTH_LLM_ENDPOINT: str = "OPENAI:gpt-5_2"37+38+COMPARE_TO_GROUND_TRUTH: str = "es"39+40+def __init__(self, **kwargs: Any) -> None:41+super().__init__(**kwargs)42+_repo_root = Path(__file__).parents[2]43+_datasets_root = _repo_root / "eval_output" / self.OUTPUT_SUBFOLDER / "eval_datasets"44+_dataset_dir = _datasets_root / self.__class__.DATA_SET45+self._dataset_dir = _dataset_dir46+self._inputs_dir = _dataset_dir / "input"47+self._ground_truths_dir = _dataset_dir / "ground_truth"48+49+async def collect_test_set(self) -> List[Dict[str, Any]]:50+if self.es_host_name:51+return await self._collect_from_es()52+return await self._collect_from_files()53+54+async def _collect_from_es(self) -> List[Dict[str, Any]]:55+if self._inputs_dir.exists() or self._ground_truths_dir.exists():56+raise FileExistsError(57+f"Dataset folder already exists: {self._inputs_dir.parent}. "58+"Choose a different --data-set name or remove the folder manually."59+ )60+61+raw_samples = await es_collect_test_set(62+es_host_name=self.es_host_name,63+es_port=self.es_port,64+endpoint_path=self.ENDPOINT_PATH,65+limit=self.limit,66+language_filter=self.language_filter,67+min_prompt_length=self.min_prompt_length,68+is_json_response=self.IS_JSON_RESPONSE,69+exclude_languages=self.exclude_languages,70+ )71+72+self._inputs_dir.mkdir(parents=True, exist_ok=True)73+self._ground_truths_dir.mkdir(parents=True, exist_ok=True)74+75+min_size = self.MINIMUM_REQUEST_BODY_SIZE76+samples: List[Dict[str, Any]] = []77+skipped_no_response = 078+skipped_too_small = 079+skipped_unreplayable = 080+skipped_probe_errors = 081+82+endpoint_url = f"{self.api_host}/{self.ENDPOINT_PATH}"83+84+timeout = aiohttp.ClientTimeout(total=self.REPLAYABILITY_CHECK_TIMEOUT_SECONDS)85+async with aiohttp.ClientSession(timeout=timeout) as session:86+for sample in raw_samples:87+es_id = sample["id"]88+request_body = sample["request_body"]89+original_response = sample.get("original_response")90+91+if not original_response:92+skipped_no_response += 193+continue94+95+if min_size and len(json.dumps(request_body)) < min_size:96+skipped_too_small += 197+continue98+99+if self.SKIP_UNREPLAYABLE_ON_COLLECT:100+try:101+async with session.post(endpoint_url, json=request_body) as resp:102+if resp.status != 200:103+body_text = await resp.text()104+if "Cannot find activity" in body_text:105+skipped_unreplayable += 1106+continue107+except Exception:108+skipped_probe_errors += 1109+110+with open(self._inputs_dir / f"{es_id}.json", "w") as f:111+json.dump(request_body, f, indent=2)112+113+with open(self._ground_truths_dir / f"gt_{es_id}.json", "w") as f:114+json.dump(original_response, f, indent=2)115+116+samples.append(117+ {118+"id": es_id,119+"request_body": request_body,120+"original_response": original_response,121+"ground_truth": original_response,122+ }123+ )124+125+print(f"Wrote {len(samples)} samples to {self._inputs_dir.parent}")126+if skipped_no_response:127+print(f"Skipped {skipped_no_response} records with no response body")128+if skipped_too_small:129+print(130+f"Skipped {skipped_too_small} records whose request body was smaller "131+f"than {min_size} characters"132+ )133+if skipped_unreplayable:134+print(f"Skipped {skipped_unreplayable} records that are not replayable (missing activity in ES)")135+if skipped_probe_errors:136+print(f"Warning: replayability probe errored for {skipped_probe_errors} records (kept those records)")137+138+if self.__class__.POPULATE_GROUND_TRUTH_LLM:139+label_results = await run_endpoint_http(140+test_set=samples,141+endpoint_url=endpoint_url,142+request_model=self.REQUEST_MODEL,143+force_llm_endpoint=self.__class__.GROUND_TRUTH_LLM_ENDPOINT,144+is_streaming_response=self.IS_STREAMING_RESPONSE,145+timeout_seconds=300.0,146+parallel_requests=self.parallel_requests,147+return_prompt_in_run=self.RETURN_PROMPT_IN_RUN,148+ )149+150+for i, r in enumerate(label_results):151+forced = self.__class__.GROUND_TRUTH_LLM_ENDPOINT152+model = forced.split(":", 1)[1] if ":" in forced else forced153+samples[i]["ground_truth_llm_model"] = model154+155+if not r.get("success", True):156+samples[i]["ground_truth_llm"] = None157+samples[i]["ground_truth_llm_reasoning"] = None158+samples[i]["ground_truth_llm_error_type"] = r.get("error_type")159+samples[i]["ground_truth_llm_error_message"] = r.get("error_message")160+continue161+162+resp = r.get("new_response") or {}163+samples[i]["ground_truth_llm"] = resp.get("ai_activity_type")164+samples[i]["ground_truth_llm_reasoning"] = resp.get("ai_activity_type_reasoning")165+166+return samples167+168+async def _collect_from_files(self) -> List[Dict[str, Any]]:169+if not self._inputs_dir.exists():170+raise FileNotFoundError(171+f"Dataset folder not found: {self._inputs_dir}. "172+"Run --steps collect first or check your --data-set name."173+ )174+175+samples: List[Dict[str, Any]] = []176+for filename in sorted(os.listdir(self._inputs_dir)):177+input_path = self._inputs_dir / filename178+gt_path = self._ground_truths_dir / f"gt_{filename}"179+180+if not gt_path.exists():181+print(f"Warning: ground truth not found for {filename}, skipping")182+continue183+184+with open(input_path, "r") as f:185+request_body: Dict[str, Any] = json.load(f)186+187+with open(gt_path, "r") as f:188+ground_truth: Dict[str, Any] = json.load(f)189+190+samples.append(191+ {192+"id": Path(filename).stem,193+"request_body": request_body,194+"original_response": None,195+"ground_truth": ground_truth,196+ }197+ )198+199+print(f"Loaded {len(samples)} samples from {self._inputs_dir.parent}")200+return samples201+202+async def evaluate_against_ground_truth(self, results: List[Dict[str, Any]]) -> List[EvaluationResult]:203+evaluation_results: List[EvaluationResult] = []204+compare_to = self.__class__.COMPARE_TO_GROUND_TRUTH205+206+for res in results:207+req_id = res["request_id"]208+is_success = res.get("success", True)209+210+if not is_success:211+evaluation_results.append(212+EvaluationResult(213+request_id=req_id,214+request_body=res["request_body"],215+new_response=res.get("new_response"),216+valid_schema=False,217+quality_score=0.0,218+quality_feedback=f"Request failed: {res.get('error_type')} - {res.get('error_message')}",219+response_time=res.get("response_time"),220+success=False,221+error_type=res.get("error_type"),222+error_message=res.get("error_message"),223+ground_truth_match=False,224+ )225+ )226+continue227+228+pred = (res.get("new_response") or {}).get("ai_activity_type")229+230+if compare_to == "llm":231+if "ground_truth_llm" not in res:232+evaluation_results.append(233+EvaluationResult(234+request_id=req_id,235+request_body=res["request_body"],236+new_response=res.get("new_response"),237+valid_schema=res.get("valid_schema", True),238+quality_score=0.0,239+quality_feedback=(240+"Missing ground_truth_llm in run results. Ensure collect step populated it and "241+"endpoints.py passes it through."242+ ),243+response_time=res.get("response_time"),244+success=True,245+ground_truth_match=False,246+ )247+ )248+continue249+gt_label = res.get("ground_truth_llm")250+else:251+gt_path = self._ground_truths_dir / f"gt_{req_id}.json"252+if not gt_path.exists():253+evaluation_results.append(254+EvaluationResult(255+request_id=req_id,256+request_body=res["request_body"],257+new_response=res.get("new_response"),258+valid_schema=res.get("valid_schema", True),259+quality_score=0.0,260+quality_feedback=f"Ground truth file not found: {gt_path}",261+response_time=res.get("response_time"),262+success=True,263+ground_truth_match=False,264+ )265+ )266+continue267+268+with open(gt_path, "r") as f:269+ground_truth_dict: Dict[str, Any] = json.load(f)270+271+gt_label = (ground_truth_dict or {}).get("ai_activity_type")272+273+matched = pred == gt_label274+275+evaluation_results.append(276+EvaluationResult(277+request_id=req_id,278+request_body=res["request_body"],279+new_response=res.get("new_response"),280+valid_schema=res.get("valid_schema", True),281+quality_score=1.0 if matched else 0.0,282+quality_feedback="PASS" if matched else f"FAIL\nExpected: {gt_label}\nGot: {pred}",283+response_time=res.get("response_time"),284+success=True,285+ground_truth_match=matched,286+ )287+ )288+289+return evaluation_results290+291+292+if __name__ == "__main__":293+parser = create_parser(AiActivityTypeEvaluator)294+parser.add_argument(295+"--data-set",296+type=str,297+default="initial",298+dest="data_set",299+help="Dataset folder under eval_output/ai_activity_type/eval_datasets/ (default: initial)",300+ )301+302+parser.add_argument(303+"--populate-ground-truth-llm",304+action="store_true",305+dest="populate_ground_truth_llm",306+ )307+parser.add_argument(308+"--ground-truth-llm-endpoint",309+type=str,310+default="OPENAI:gpt-5_2",311+dest="ground_truth_llm_endpoint",312+ )313+314+parser.add_argument(315+"--compare-to-ground-truth",316+type=str,317+choices=["es", "llm"],318+default="es",319+dest="compare_to_ground_truth",320+ )321+322+args = parser.parse_args()323+AiActivityTypeEvaluator.DATA_SET = args.data_set324+325+AiActivityTypeEvaluator.POPULATE_GROUND_TRUTH_LLM = bool(args.populate_ground_truth_llm)326+AiActivityTypeEvaluator.GROUND_TRUTH_LLM_ENDPOINT = args.ground_truth_llm_endpoint327+328+AiActivityTypeEvaluator.COMPARE_TO_GROUND_TRUTH = args.compare_to_ground_truth329+330+asyncio.run(run_evaluation(AiActivityTypeEvaluator, args))</selection>” selected. Please summarize the selection using precise and concise language. Use headers and bulleted lists in the summary, to make it scannable. Maintain the meaning and factual accuracy.
You said
I’m on page “<tabTitle>Jy 19798 evaluation for ai activity types by nikol</tabTitle>” with “<selection>@@ -0,0 +1,330 @@1+#!/usr/bin/env python32+import asyncio3+import json4+import os5+from pathlib import Path6+from typing import Any, Dict, List7+8+import aiohttp9+10+from src.component.call_processing.schemes.ai_activity_type_request import AiActivityTypeRequest11+from src.component.call_processing.schemes.ai_activity_type_response import AiActivityTypeResponse12+from src.eval.abstract_evaluator import AbstractEvaluator13+from src.eval.collectors import collect_test_set as es_collect_test_set14+from src.eval.common_evaluator_runner import create_parser, run_evaluation15+from src.eval.endpoints import run_endpoint as run_endpoint_http16+from src.eval.models import EvaluationResult17+18+19+class AiActivityTypeEvaluator(AbstractEvaluator):20+ENDPOINT_PATH = "call/ai-activity-type"21+REQUEST_MODEL = AiActivityTypeRequest22+RESPONSE_MODEL = AiActivityTypeResponse23+OUTPUT_SUBFOLDER = "ai_activity_type"24+USES_LLM_EVALUATION = False25+26+READS_FROM_DATASET_FOLDER = True27+28+DATA_SET: str = "initial"29+30+MINIMUM_REQUEST_BODY_SIZE: int = 031+32+SKIP_UNREPLAYABLE_ON_COLLECT: bool = True33+REPLAYABILITY_CHECK_TIMEOUT_SECONDS: float = 20.034+35+POPULATE_GROUND_TRUTH_LLM: bool = False36+GROUND_TRUTH_LLM_ENDPOINT: str = "OPENAI:gpt-5_2"37+38+COMPARE_TO_GROUND_TRUTH: str = "es"39+40+def __init__(self, **kwargs: Any) -> None:41+super().__init__(**kwargs)42+_repo_root = Path(__file__).parents[2]43+_datasets_root = _repo_root / "eval_output" / self.OUTPUT_SUBFOLDER / "eval_datasets"44+_dataset_dir = _datasets_root / self.__class__.DATA_SET45+self._dataset_dir = _dataset_dir46+self._inputs_dir = _dataset_dir / "input"47+self._ground_truths_dir = _dataset_dir / "ground_truth"48+49+async def collect_test_set(self) -> List[Dict[str, Any]]:50+if self.es_host_name:51+return await self._collect_from_es()52+return await self._collect_from_files()53+54+async def _collect_from_es(self) -> List[Dict[str, Any]]:55+if self._inputs_dir.exists() or self._ground_truths_dir.exists():56+raise FileExistsError(57+f"Dataset folder already exists: {self._inputs_dir.parent}. "58+"Choose a different --data-set name or remove the folder manually."59+ )60+61+raw_samples = await es_collect_test_set(62+es_host_name=self.es_host_name,63+es_port=self.es_port,64+endpoint_path=self.ENDPOINT_PATH,65+limit=self.limit,66+language_filter=self.language_filter,67+min_prompt_length=self.min_prompt_length,68+is_json_response=self.IS_JSON_RESPONSE,69+exclude_languages=self.exclude_languages,70+ )71+72+self._inputs_dir.mkdir(parents=True, exist_ok=True)73+self._ground_truths_dir.mkdir(parents=True, exist_ok=True)74+75+min_size = self.MINIMUM_REQUEST_BODY_SIZE76+samples: List[Dict[str, Any]] = []77+skipped_no_response = 078+skipped_too_small = 079+skipped_unreplayable = 080+skipped_probe_errors = 081+82+endpoint_url = f"{self.api_host}/{self.ENDPOINT_PATH}"83+84+timeout = aiohttp.ClientTimeout(total=self.REPLAYABILITY_CHECK_TIMEOUT_SECONDS)85+async with aiohttp.ClientSession(timeout=timeout) as session:86+for sample in raw_samples:87+es_id = sample["id"]88+request_body = sample["request_body"]89+original_response = sample.get("original_response")90+91+if not original_response:92+skipped_no_response += 193+continue94+95+if min_size and len(json.dumps(request_body)) < min_size:96+skipped_too_small += 197+continue98+99+if self.SKIP_UNREPLAYABLE_ON_COLLECT:100+try:101+async with session.post(endpoint_url, json=request_body) as resp:102+if resp.status != 200:103+body_text = await resp.text()104+if "Cannot find activity" in body_text:105+skipped_unreplayable += 1106+continue107+except Exception:108+skipped_probe_errors += 1109+110+with open(self._inputs_dir / f"{es_id}.json", "w") as f:111+json.dump(request_body, f, indent=2)112+113+with open(self._ground_truths_dir / f"gt_{es_id}.json", "w") as f:114+json.dump(original_response, f, indent=2)115+116+samples.append(117+ {118+"id": es_id,119+"request_body": request_body,120+"original_response": original_response,121+"ground_truth": original_response,122+ }123+ )124+125+print(f"Wrote {len(samples)} samples to {self._inputs_dir.parent}")126+if skipped_no_response:127+print(f"Skipped {skipped_no_response} records with no response body")128+if skipped_too_small:129+print(130+f"Skipped {skipped_too_small} records whose request body was smaller "131+f"than {min_size} characters"132+ )133+if skipped_unreplayable:134+print(f"Skipped {skipped_unreplayable} records that are not replayable (missing activity in ES)")135+if skipped_probe_errors:136+print(f"Warning: replayability probe errored for {skipped_probe_errors} records (kept those records)")137+138+if self.__class__.POPULATE_GROUND_TRUTH_LLM:139+label_results = await run_endpoint_http(140+test_set=samples,141+endpoint_url=endpoint_url,142+request_model=self.REQUEST_MODEL,143+force_llm_endpoint=self.__class__.GROUND_TRUTH_LLM_ENDPOINT,144+is_streaming_response=self.IS_STREAMING_RESPONSE,145+timeout_seconds=300.0,146+parallel_requests=self.parallel_requests,147+return_prompt_in_run=self.RETURN_PROMPT_IN_RUN,148+ )149+150+for i, r in enumerate(label_results):151+forced = self.__class__.GROUND_TRUTH_LLM_ENDPOINT152+model = forced.split(":", 1)[1] if ":" in forced else forced153+samples[i]["ground_truth_llm_model"] = model154+155+if not r.get("success", True):156+samples[i]["ground_truth_llm"] = None157+samples[i]["ground_truth_llm_reasoning"] = None158+samples[i]["ground_truth_llm_error_type"] = r.get("error_type")159+samples[i]["ground_truth_llm_error_message"] = r.get("error_message")160+continue161+162+resp = r.get("new_response") or {}163+samples[i]["ground_truth_llm"] = resp.get("ai_activity_type")164+samples[i]["ground_truth_llm_reasoning"] = resp.get("ai_activity_type_reasoning")165+166+return samples167+168+async def _collect_from_files(self) -> List[Dict[str, Any]]:169+if not self._inputs_dir.exists():170+raise FileNotFoundError(171+f"Dataset folder not found: {self._inputs_dir}. "172+"Run --steps collect first or check your --data-set name."173+ )174+175+samples: List[Dict[str, Any]] = []176+for filename in sorted(os.listdir(self._inputs_dir)):177+input_path = self._inputs_dir / filename178+gt_path = self._ground_truths_dir / f"gt_{filename}"179+180+if not gt_path.exists():181+print(f"Warning: ground truth not found for {filename}, skipping")182+continue183+184+with open(input_path, "r") as f:185+request_body: Dict[str, Any] = json.load(f)186+187+with open(gt_path, "r") as f:188+ground_truth: Dict[str, Any] = json.load(f)189+190+samples.append(191+ {192+"id": Path(filename).stem,193+"request_body": request_body,194+"original_response": None,195+"ground_truth": ground_truth,196+ }197+ )198+199+print(f"Loaded {len(samples)} samples from {self._inputs_dir.parent}")200+return samples201+202+async def evaluate_against_ground_truth(self, results: List[Dict[str, Any]]) -> List[EvaluationResult]:203+evaluation_results: List[EvaluationResult] = []204+compare_to = self.__class__.COMPARE_TO_GROUND_TRUTH205+206+for res in results:207+req_id = res["request_id"]208+is_success = res.get("success", True)209+210+if not is_success:211+evaluation_results.append(212+EvaluationResult(213+request_id=req_id,214+request_body=res["request_body"],215+new_response=res.get("new_response"),216+valid_schema=False,217+quality_score=0.0,218+quality_feedback=f"Request failed: {res.get('error_type')} - {res.get('error_message')}",219+response_time=res.get("response_time"),220+success=False,221+error_type=res.get("error_type"),222+error_message=res.get("error_message"),223+ground_truth_match=False,224+ )225+ )226+continue227+228+pred = (res.get("new_response") or {}).get("ai_activity_type")229+230+if compare_to == "llm":231+if "ground_truth_llm" not in res:232+evaluation_results.append(233+EvaluationResult(234+request_id=req_id,235+request_body=res["request_body"],236+new_response=res.get("new_response"),237+valid_schema=res.get("valid_schema", True),238+quality_score=0.0,239+quality_feedback=(240+"Missing ground_truth_llm in run results. Ensure collect step populated it and "241+"endpoints.py passes it through."242+ ),243+response_time=res.get("response_time"),244+success=True,245+ground_truth_match=False,246+ )247+ )248+continue249+gt_label = res.get("ground_truth_llm")250+else:251+gt_path = self._ground_truths_dir / f"gt_{req_id}.json"252+if not gt_path.exists():253+evaluation_results.append(254+EvaluationResult(255+request_id=req_id,256+request_body=res["request_body"],257+new_response=res.get("new_response"),258+valid_schema=res.get("valid_schema", True),259+quality_score=0.0,260+quality_feedback=f"Ground truth file not found: {gt_path}",261+response_time=res.get("response_time"),262+success=True,263+ground_truth_match=False,264+ )265+ )266+continue267+268+with open(gt_path, "r") as f:269+ground_truth_dict: Dict[str, Any] = json.load(f)270+271+gt_label = (ground_truth_dict or {}).get("ai_activity_type")272+273+matched = pred == gt_label274+275+evaluation_results.append(276+EvaluationResult(277+request_id=req_id,278+request_body=res["request_body"],279+new_response=res.get("new_response"),280+valid_schema=res.get("valid_schema", True),281+quality_score=1.0 if matched else 0.0,282+quality_feedback="PASS" if matched else f"FAIL\nExpected: {gt_label}\nGot: {pred}",283+response_time=res.get("response_time"),284+success=True,285+ground_truth_match=matched,286+ )287+ )288+289+return evaluation_results290+291+292+if __name__ == "__main__":293+parser = create_parser(AiActivityTypeEvaluator)294+parser.add_argument(295+"--data-set",296+type=str,297+default="initial",298+dest="data_set",299+help="Dataset folder under eval_output/ai_activity_type/eval_datasets/ (default: initial)",300+ )301+302+parser.add_argument(303+"--populate-ground-truth-llm",304+action="store_true",305+dest="populate_ground_truth_llm",306+ )307+parser.add_argument(308+"--ground-truth-llm-endpoint",309+type=str,310+default="OPENAI:gpt-5_2",311+dest="ground_truth_llm_endpoint",312+ )313+314+parser.add_argument(315+"--compare-to-ground-truth",316+type=str,317+choices=["es", "llm"],318+default="es",319+dest="compare_to_ground_truth",320+ )321+322+args = parser.parse_args()323+AiActivityTypeEvaluator.DATA_SET = args.data_set324+325+AiActivityTypeEvaluator.POPULATE_GROUND_TRUTH_LLM = bool(args.populate_ground_truth_llm)326+AiActivityTypeEvaluator.GROUND_TRUTH_LLM_ENDPOINT = args.ground_truth_llm_endpoint327+328+AiActivityTypeEvaluator.COMPARE_TO_GROUND_TRUTH = args.compare_to_ground_truth329+330+asyncio.run(run_evaluation(AiActivityTypeEvaluator, args))</selection>” selected.
Please summarize the selection using precise and concise language. Use headers and bulleted lists in the summary, to make it scannable. Maintain the meaning and factual accuracy.
Expand
Listen
Show more options
Gemini said
Gemini said
This Python script defines the
AiActivityTypeEvaluator
class, a specialized tool for evaluating AI-driven activity type classification. It extends a base evaluation framework to handle data collection, ground-truth comparison, and performance scoring.
Core Functionality
Core Functionality
Data Collection (
collect_test_set
):
* Supports fetching raw samples from
Elasticsearch (ES)
or loading them from
local JSON files
.
Implements a
replayability check
: It probes the live API endpoint to ensure the activity exists before including it in the dataset.
Filters data based on request body size, language, and the presence of an original response.
Ground Truth Management:
Saves inputs and "gold standard" responses to a local directory structure (
eval_output/ai_activity_type/...
).
Features an optional mode to populate ground truth using a high-order LLM (e.g.,
gpt-5_2
) if the
POPULATE_GROUND_TRUTH_LLM
flag is set.
Evaluation Logic (
evaluate_against_ground_truth
):
Compares the model's predicted
ai_activity_type
against either the original ES response or the LLM-generated ground truth.
Assigns a
quality_score
of
1.0
for a match and
0.0
for a mismatch or request failure.
Key Configuration Constants
Key Configuration Constants
Constant
Purpose
ENDPOINT_PATH
The specific API route being tested:
call/ai-activity-type
.
COMPARE_TO_GROUND_TRUTH
Determines if the baseline is the original data (
es
) or an
llm
.
SKIP_UNREPLAYABLE_ON_COLLECT
If
True
, discards records where the API returns "Cannot find activity."
REPLAYABILITY_CHECK_TIMEOUT_SECONDS
Limits the probe request to 20 seconds.
Constant
ENDPOINT_PATH
COMPARE_TO_GROUND_TRUTH
SKIP_UNREPLAYABLE_ON_COLLECT
REPLAYABILITY_CHECK_TIMEOUT_SECONDS
Purpose
The specific API route being tested:
call/ai-activity-type
.
Determines if the baseline is the original data (
es
) or an
llm
.
If
True
, discards records where the API returns "Cannot find activity."
Limits the probe request to 20 seconds.
Copy table
Execution Workflow
Execution Workflow
Parsing:
The script uses
create_parser
to handle CLI arguments like
--data-set
,
--populate-ground-truth-llm
, and
--compare-to-ground-truth
.
Initialization:
Sets up directory paths for inputs and ground truths based on the selected dataset name.
Run:
Executes the evaluation via
asyncio.run(run_evaluation(...))
, which orchestrates the collection, endpoint calling, and result scoring phases.
Copy prompt
Edit
You said are there soem issues with this PR
You said
are there soem issues with this PR
Listen
Show more options
Show thinking
Gemini said
Gemini said
Yes, there are several issues and code smells in this Pull Request, ranging from performance bottlenecks to architectural anti-patterns.
Here is a breakdown of the most notable issues, categorized by impact:
Performance & Async Anti-Patterns
Performance & Async Anti-Patterns
Sequential Requests Defeating Async (Lines 86-106):
Inside
_collect_from_es
, the code loops through
raw_samples
and
await
s a
session.post
request for each sample one by one. This means the script waits for one HTTP request to finish before starting the next, completely defeating the purpose of using
aiohttp
for asynchronous concurrency.
Fix:
Collect these coroutines into a list and use
asyncio.gather()
(ideally wrapped in an
asyncio.Semaphore
to avoid overwhelming the endpoint) to run the replayability probes concurrently.
Blocking File I/O in Async Functions (Lines 110-114, 184-188, 268-269):
Standard synchronous file operations (
with open(...)
,
json.dump
,
json.load
) are used inside
async def
functions. In Python, this blocks the entire event loop while the disk is reading/writing.
Fix:
Use an asynchronous file I/O library like
aiofiles
, or run the blocking I/O operations in a separate thread using
asyncio.to_thread()
.
Architecture & State Management
Architecture & State Management
Mutating Class-Level Variables (Lines 323-328):
The script parses CLI arguments and directly mutates the class attributes (e.g.,
AiActivityTypeEvaluator.DATA_SET = args.data_set
). This is a major anti-pattern. If you ever try to run tests in parallel or create multiple instances of this evaluator in a single process, the state will bleed across them.
Fix:
Pass these arguments into the
__init__
constructor of the instance (
self.data_set = args.data_set
) rather than modifying the class definition globally.
Code Quality & Edge Cases
Code Quality & Edge Cases
Broad Exception Catching (Line 107):
Using a bare
except Exception:
during the replayability probe is dangerous. It will catch
aiohttp.ClientError
(which is intended), but it will also silently swallow
TimeoutError
or even memory errors, making debugging incredibly difficult if the endpoint goes down.
Fix:
Scope the exception to specific expected errors, like
except (aiohttp.ClientError, asyncio.TimeoutError):
.
Inefficient Size Calculation (Line 95):
len(json.dumps(request_body)) < min_size
requires serializing the entire dictionary to a string
just
to check its length. Since
min_size
defaults to
0
, the
if min_size
short-circuit saves it for now, but if anyone sets a minimum size, this will become an unnecessary CPU bottleneck on large datasets.
Potential Path Traversal Risk (Lines 110, 113, 251):
The script writes and reads files directly using
f"{es_id}.json"
and
f"gt_{req_id}.json"
. If
es_id
or
req_id
originate from a database and ever contain characters like
../
, it could result in files being read from or written to unintended directories.
Fix:
Sanitize the IDs or strictly enforce that they only contain alphanumeric characters.
Would you like me to rewrite the
_collect_from_es
method to show how to fix the sequential async loop and blocking file I/O?
Enter a prompt for Gemini
encrypted
Enter a prompt for Gemini
encrypted
Open upload file menu...
|
8608
|
|
8542
|
165
|
11
|
2026-04-14T06:51:07.263345+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776149467263_m2.jpg...
|
Firefox
|
Jy 19798 evaluation for ai activity types by nikol Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet — Work...
|
True
|
github.com/jiminny/prophet/pull/468/changes#diff-d github.com/jiminny/prophet/pull/468/changes#diff-d2f9fea9bc428b119ae26a66453e8eab7dd0782d4a4d93075ca5ce05903d77e8...
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
JY-20543 add AJ reports User pilot tracking by Lak JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Close tab
New Tab
Customize sidebar
Close Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
AI Chat settings
Close
WORK, Google Account: [EMAIL]
Main menu
New Chat
Open menu for conversation actions.
Conversation with Gemini
Conversation with Gemini
Copy prompt
You said I’m on page “<tabTitle>Jy 19798 evaluation for ai activity types by nikol</tabTitle>” with “<selection>@@ -0,0 +1,330 @@1+#!/usr/bin/env python32+import asyncio3+import json4+import os5+from pathlib import Path6+from typing import Any, Dict, List7+8+import aiohttp9+10+from src.component.call_processing.schemes.ai_activity_type_request import AiActivityTypeRequest11+from src.component.call_processing.schemes.ai_activity_type_response import AiActivityTypeResponse12+from src.eval.abstract_evaluator import AbstractEvaluator13+from src.eval.collectors import collect_test_set as es_collect_test_set14+from src.eval.common_evaluator_runner import create_parser, run_evaluation15+from src.eval.endpoints import run_endpoint as run_endpoint_http16+from src.eval.models import EvaluationResult17+18+19+class AiActivityTypeEvaluator(AbstractEvaluator):20+ENDPOINT_PATH = "call/ai-activity-type"21+REQUEST_MODEL = AiActivityTypeRequest22+RESPONSE_MODEL = AiActivityTypeResponse23+OUTPUT_SUBFOLDER = "ai_activity_type"24+USES_LLM_EVALUATION = False25+26+READS_FROM_DATASET_FOLDER = True27+28+DATA_SET: str = "initial"29+30+MINIMUM_REQUEST_BODY_SIZE: int = 031+32+SKIP_UNREPLAYABLE_ON_COLLECT: bool = True33+REPLAYABILITY_CHECK_TIMEOUT_SECONDS: float = 20.034+35+POPULATE_GROUND_TRUTH_LLM: bool = False36+GROUND_TRUTH_LLM_ENDPOINT: str = "OPENAI:gpt-5_2"37+38+COMPARE_TO_GROUND_TRUTH: str = "es"39+40+def __init__(self, **kwargs: Any) -> None:41+super().__init__(**kwargs)42+_repo_root = Path(__file__).parents[2]43+_datasets_root = _repo_root / "eval_output" / self.OUTPUT_SUBFOLDER / "eval_datasets"44+_dataset_dir = _datasets_root / self.__class__.DATA_SET45+self._dataset_dir = _dataset_dir46+self._inputs_dir = _dataset_dir / "input"47+self._ground_truths_dir = _dataset_dir / "ground_truth"48+49+async def collect_test_set(self) -> List[Dict[str, Any]]:50+if self.es_host_name:51+return await self._collect_from_es()52+return await self._collect_from_files()53+54+async def _collect_from_es(self) -> List[Dict[str, Any]]:55+if self._inputs_dir.exists() or self._ground_truths_dir.exists():56+raise FileExistsError(57+f"Dataset folder already exists: {self._inputs_dir.parent}. "58+"Choose a different --data-set name or remove the folder manually."59+ )60+61+raw_samples = await es_collect_test_set(62+es_host_name=self.es_host_name,63+es_port=self.es_port,64+endpoint_path=self.ENDPOINT_PATH,65+limit=self.limit,66+language_filter=self.language_filter,67+min_prompt_length=self.min_prompt_length,68+is_json_response=self.IS_JSON_RESPONSE,69+exclude_languages=self.exclude_languages,70+ )71+72+self._inputs_dir.mkdir(parents=True, exist_ok=True)73+self._ground_truths_dir.mkdir(parents=True, exist_ok=True)74+75+min_size = self.MINIMUM_REQUEST_BODY_SIZE76+samples: List[Dict[str, Any]] = []77+skipped_no_response = 078+skipped_too_small = 079+skipped_unreplayable = 080+skipped_probe_errors = 081+82+endpoint_url = f"{self.api_host}/{self.ENDPOINT_PATH}"83+84+timeout = aiohttp.ClientTimeout(total=self.REPLAYABILITY_CHECK_TIMEOUT_SECONDS)85+async with aiohttp.ClientSession(timeout=timeout) as session:86+for sample in raw_samples:87+es_id = sample["id"]88+request_body = sample["request_body"]89+original_response = sample.get("original_response")90+91+if not original_response:92+skipped_no_response += 193+continue94+95+if min_size and len(json.dumps(request_body)) < min_size:96+skipped_too_small += 197+continue98+99+if self.SKIP_UNREPLAYABLE_ON_COLLECT:100+try:101+async with session.post(endpoint_url, json=request_body) as resp:102+if resp.status != 200:103+body_text = await resp.text()104+if "Cannot find activity" in body_text:105+skipped_unreplayable += 1106+continue107+except Exception:108+skipped_probe_errors += 1109+110+with open(self._inputs_dir / f"{es_id}.json", "w") as f:111+json.dump(request_body, f, indent=2)112+113+with open(self._ground_truths_dir / f"gt_{es_id}.json", "w") as f:114+json.dump(original_response, f, indent=2)115+116+samples.append(117+ {118+"id": es_id,119+"request_body": request_body,120+"original_response": original_response,121+"ground_truth": original_response,122+ }123+ )124+125+print(f"Wrote {len(samples)} samples to {self._inputs_dir.parent}")126+if skipped_no_response:127+print(f"Skipped {skipped_no_response} records with no response body")128+if skipped_too_small:129+print(130+f"Skipped {skipped_too_small} records whose request body was smaller "131+f"than {min_size} characters"132+ )133+if skipped_unreplayable:134+print(f"Skipped {skipped_unreplayable} records that are not replayable (missing activity in ES)")135+if skipped_probe_errors:136+print(f"Warning: replayability probe errored for {skipped_probe_errors} records (kept those records)")137+138+if self.__class__.POPULATE_GROUND_TRUTH_LLM:139+label_results = await run_endpoint_http(140+test_set=samples,141+endpoint_url=endpoint_url,142+request_model=self.REQUEST_MODEL,143+force_llm_endpoint=self.__class__.GROUND_TRUTH_LLM_ENDPOINT,144+is_streaming_response=self.IS_STREAMING_RESPONSE,145+timeout_seconds=300.0,146+parallel_requests=self.parallel_requests,147+return_prompt_in_run=self.RETURN_PROMPT_IN_RUN,148+ )149+150+for i, r in enumerate(label_results):151+forced = self.__class__.GROUND_TRUTH_LLM_ENDPOINT152+model = forced.split(":", 1)[1] if ":" in forced else forced153+samples[i]["ground_truth_llm_model"] = model154+155+if not r.get("success", True):156+samples[i]["ground_truth_llm"] = None157+samples[i]["ground_truth_llm_reasoning"] = None158+samples[i]["ground_truth_llm_error_type"] = r.get("error_type")159+samples[i]["ground_truth_llm_error_message"] = r.get("error_message")160+continue161+162+resp = r.get("new_response") or {}163+samples[i]["ground_truth_llm"] = resp.get("ai_activity_type")164+samples[i]["ground_truth_llm_reasoning"] = resp.get("ai_activity_type_reasoning")165+166+return samples167+168+async def _collect_from_files(self) -> List[Dict[str, Any]]:169+if not self._inputs_dir.exists():170+raise FileNotFoundError(171+f"Dataset folder not found: {self._inputs_dir}. "172+"Run --steps collect first or check your --data-set name."173+ )174+175+samples: List[Dict[str, Any]] = []176+for filename in sorted(os.listdir(self._inputs_dir)):177+input_path = self._inputs_dir / filename178+gt_path = self._ground_truths_dir / f"gt_{filename}"179+180+if not gt_path.exists():181+print(f"Warning: ground truth not found for {filename}, skipping")182+continue183+184+with open(input_path, "r") as f:185+request_body: Dict[str, Any] = json.load(f)186+187+with open(gt_path, "r") as f:188+ground_truth: Dict[str, Any] = json.load(f)189+190+samples.append(191+ {192+"id": Path(filename).stem,193+"request_body": request_body,194+"original_response": None,195+"ground_truth": ground_truth,196+ }197+ )198+199+print(f"Loaded {len(samples)} samples from {self._inputs_dir.parent}")200+return samples201+202+async def evaluate_against_ground_truth(self, results: List[Dict[str, Any]]) -> List[EvaluationResult]:203+evaluation_results: List[EvaluationResult] = []204+compare_to = self.__class__.COMPARE_TO_GROUND_TRUTH205+206+for res in results:207+req_id = res["request_id"]208+is_success = res.get("success", True)209+210+if not is_success:211+evaluation_results.append(212+EvaluationResult(213+request_id=req_id,214+request_body=res["request_body"],215+new_response=res.get("new_response"),216+valid_schema=False,217+quality_score=0.0,218+quality_feedback=f"Request failed: {res.get('error_type')} - {res.get('error_message')}",219+response_time=res.get("response_time"),220+success=False,221+error_type=res.get("error_type"),222+error_message=res.get("error_message"),223+ground_truth_match=False,224+ )225+ )226+continue227+228+pred = (res.get("new_response") or {}).get("ai_activity_type")229+230+if compare_to == "llm":231+if "ground_truth_llm" not in res:232+evaluation_results.append(233+EvaluationResult(234+request_id=req_id,235+request_body=res["request_body"],236+new_response=res.get("new_response"),237+valid_schema=res.get("valid_schema", True),238+quality_score=0.0,239+quality_feedback=(240+"Missing ground_truth_llm in run results. Ensure collect step populated it and "241+"endpoints.py passes it through."242+ ),243+response_time=res.get("response_time"),244+success=True,245+ground_truth_match=False,246+ )247+ )248+continue249+gt_label = res.get("ground_truth_llm")250+else:251+gt_path = self._ground_truths_dir / f"gt_{req_id}.json"252+if not gt_path.exists():253+evaluation_results.append(254+EvaluationResult(255+request_id=req_id,256+request_body=res["request_body"],257+new_response=res.get("new_response"),258+valid_schema=res.get("valid_schema", True),259+quality_score=0.0,260+quality_feedback=f"Ground truth file not found: {gt_path}",261+response_time=res.get("response_time"),262+success=True,263+ground_truth_match=False,264+ )265+ )266+continue267+268+with open(gt_path, "r") as f:269+ground_truth_dict: Dict[str, Any] = json.load(f)270+271+gt_label = (ground_truth_dict or {}).get("ai_activity_type")272+273+matched = pred == gt_label274+275+evaluation_results.append(276+EvaluationResult(277+request_id=req_id,278+request_body=res["request_body"],279+new_response=res.get("new_response"),280+valid_schema=res.get("valid_schema", True),281+quality_score=1.0 if matched else 0.0,282+quality_feedback="PASS" if matched else f"FAIL\nExpected: {gt_label}\nGot: {pred}",283+response_time=res.get("response_time"),284+success=True,285+ground_truth_match=matched,286+ )287+ )288+289+return evaluation_results290+291+292+if __name__ == "__main__":293+parser = create_parser(AiActivityTypeEvaluator)294+parser.add_argument(295+"--data-set",296+type=str,297+default="initial",298+dest="data_set",299+help="Dataset folder under eval_output/ai_activity_type/eval_datasets/ (default: initial)",300+ )301+302+parser.add_argument(303+"--populate-ground-truth-llm",304+action="store_true",305+dest="populate_ground_truth_llm",306+ )307+parser.add_argument(308+"--ground-truth-llm-endpoint",309+type=str,310+default="OPENAI:gpt-5_2",311+dest="ground_truth_llm_endpoint",312+ )313+314+parser.add_argument(315+"--compare-to-ground-truth",316+type=str,317+choices=["es", "llm"],318+default="es",319+dest="compare_to_ground_truth",320+ )321+322+args = parser.parse_args()323+AiActivityTypeEvaluator.DATA_SET = args.data_set324+325+AiActivityTypeEvaluator.POPULATE_GROUND_TRUTH_LLM = bool(args.populate_ground_truth_llm)326+AiActivityTypeEvaluator.GROUND_TRUTH_LLM_ENDPOINT = args.ground_truth_llm_endpoint327+328+AiActivityTypeEvaluator.COMPARE_TO_GROUND_TRUTH = args.compare_to_ground_truth329+330+asyncio.run(run_evaluation(AiActivityTypeEvaluator, args))</selection>” selected. Please summarize the selection using precise and concise language. Use headers and bulleted lists in the summary, to make it scannable. Maintain the meaning and factual accuracy.
You said
I’m on page “<tabTitle>Jy 19798 evaluation for ai activity types by nikol</tabTitle>” with “<selection>@@ -0,0 +1,330 @@1+#!/usr/bin/env python32+import asyncio3+import json4+import os5+from pathlib import Path6+from typing import Any, Dict, List7+8+import aiohttp9+10+from src.component.call_processing.schemes.ai_activity_type_request import AiActivityTypeRequest11+from src.component.call_processing.schemes.ai_activity_type_response import AiActivityTypeResponse12+from src.eval.abstract_evaluator import AbstractEvaluator13+from src.eval.collectors import collect_test_set as es_collect_test_set14+from src.eval.common_evaluator_runner import create_parser, run_evaluation15+from src.eval.endpoints import run_endpoint as run_endpoint_http16+from src.eval.models import EvaluationResult17+18+19+class AiActivityTypeEvaluator(AbstractEvaluator):20+ENDPOINT_PATH = "call/ai-activity-type"21+REQUEST_MODEL = AiActivityTypeRequest22+RESPONSE_MODEL = AiActivityTypeResponse23+OUTPUT_SUBFOLDER = "ai_activity_type"24+USES_LLM_EVALUATION = False25+26+READS_FROM_DATASET_FOLDER = True27+28+DATA_SET: str = "initial"29+30+MINIMUM_REQUEST_BODY_SIZE: int = 031+32+SKIP_UNREPLAYABLE_ON_COLLECT: bool = True33+REPLAYABILITY_CHECK_TIMEOUT_SECONDS: float = 20.034+35+POPULATE_GROUND_TRUTH_LLM: bool = False36+GROUND_TRUTH_LLM_ENDPOINT: str = "OPENAI:gpt-5_2"37+38+COMPARE_TO_GROUND_TRUTH: str = "es"39+40+def __init__(self, **kwargs: Any) -> None:41+super().__init__(**kwargs)42+_repo_root = Path(__file__).parents[2]43+_datasets_root = _repo_root / "eval_output" / self.OUTPUT_SUBFOLDER / "eval_datasets"44+_dataset_dir = _datasets_root / self.__class__.DATA_SET45+self._dataset_dir = _dataset_dir46+self._inputs_dir = _dataset_dir / "input"47+self._ground_truths_dir = _dataset_dir / "ground_truth"48+49+async def collect_test_set(self) -> List[Dict[str, Any]]:50+if self.es_host_name:51+return await self._collect_from_es()52+return await self._collect_from_files()53+54+async def _collect_from_es(self) -> List[Dict[str, Any]]:55+if self._inputs_dir.exists() or self._ground_truths_dir.exists():56+raise FileExistsError(57+f"Dataset folder already exists: {self._inputs_dir.parent}. "58+"Choose a different --data-set name or remove the folder manually."59+ )60+61+raw_samples = await es_collect_test_set(62+es_host_name=self.es_host_name,63+es_port=self.es_port,64+endpoint_path=self.ENDPOINT_PATH,65+limit=self.limit,66+language_filter=self.language_filter,67+min_prompt_length=self.min_prompt_length,68+is_json_response=self.IS_JSON_RESPONSE,69+exclude_languages=self.exclude_languages,70+ )71+72+self._inputs_dir.mkdir(parents=True, exist_ok=True)73+self._ground_truths_dir.mkdir(parents=True, exist_ok=True)74+75+min_size = self.MINIMUM_REQUEST_BODY_SIZE76+samples: List[Dict[str, Any]] = []77+skipped_no_response = 078+skipped_too_small = 079+skipped_unreplayable = 080+skipped_probe_errors = 081+82+endpoint_url = f"{self.api_host}/{self.ENDPOINT_PATH}"83+84+timeout = aiohttp.ClientTimeout(total=self.REPLAYABILITY_CHECK_TIMEOUT_SECONDS)85+async with aiohttp.ClientSession(timeout=timeout) as session:86+for sample in raw_samples:87+es_id = sample["id"]88+request_body = sample["request_body"]89+original_response = sample.get("original_response")90+91+if not original_response:92+skipped_no_response += 193+continue94+95+if min_size and len(json.dumps(request_body)) < min_size:96+skipped_too_small += 197+continue98+99+if self.SKIP_UNREPLAYABLE_ON_COLLECT:100+try:101+async with session.post(endpoint_url, json=request_body) as resp:102+if resp.status != 200:103+body_text = await resp.text()104+if "Cannot find activity" in body_text:105+skipped_unreplayable += 1106+continue107+except Exception:108+skipped_probe_errors += 1109+110+with open(self._inputs_dir / f"{es_id}.json", "w") as f:111+json.dump(request_body, f, indent=2)112+113+with open(self._ground_truths_dir / f"gt_{es_id}.json", "w") as f:114+json.dump(original_response, f, indent=2)115+116+samples.append(117+ {118+"id": es_id,119+"request_body": request_body,120+"original_response": original_response,121+"ground_truth": original_response,122+ }123+ )124+125+print(f"Wrote {len(samples)} samples to {self._inputs_dir.parent}")126+if skipped_no_response:127+print(f"Skipped {skipped_no_response} records with no response body")128+if skipped_too_small:129+print(130+f"Skipped {skipped_too_small} records whose request body was smaller "131+f"than {min_size} characters"132+ )133+if skipped_unreplayable:134+print(f"Skipped {skipped_unreplayable} records that are not replayable (missing activity in ES)")135+if skipped_probe_errors:136+print(f"Warning: replayability probe errored for {skipped_probe_errors} records (kept those records)")137+138+if self.__class__.POPULATE_GROUND_TRUTH_LLM:139+label_results = await run_endpoint_http(140+test_set=samples,141+endpoint_url=endpoint_url,142+request_model=self.REQUEST_MODEL,143+force_llm_endpoint=self.__class__.GROUND_TRUTH_LLM_ENDPOINT,144+is_streaming_response=self.IS_STREAMING_RESPONSE,145+timeout_seconds=300.0,146+parallel_requests=self.parallel_requests,147+return_prompt_in_run=self.RETURN_PROMPT_IN_RUN,148+ )149+150+for i, r in enumerate(label_results):151+forced = self.__class__.GROUND_TRUTH_LLM_ENDPOINT152+model = forced.split(":", 1)[1] if ":" in forced else forced153+samples[i]["ground_truth_llm_model"] = model154+155+if not r.get("success", True):156+samples[i]["ground_truth_llm"] = None157+samples[i]["ground_truth_llm_reasoning"] = None158+samples[i]["ground_truth_llm_error_type"] = r.get("error_type")159+samples[i]["ground_truth_llm_error_message"] = r.get("error_message")160+continue161+162+resp = r.get("new_response") or {}163+samples[i]["ground_truth_llm"] = resp.get("ai_activity_type")164+samples[i]["ground_truth_llm_reasoning"] = resp.get("ai_activity_type_reasoning")165+166+return samples167+168+async def _collect_from_files(self) -> List[Dict[str, Any]]:169+if not self._inputs_dir.exists():170+raise FileNotFoundError(171+f"Dataset folder not found: {self._inputs_dir}. "172+"Run --steps collect first or check your --data-set name."173+ )174+175+samples: List[Dict[str, Any]] = []176+for filename in sorted(os.listdir(self._inputs_dir)):177+input_path = self._inputs_dir / filename178+gt_path = self._ground_truths_dir / f"gt_{filename}"179+180+if not gt_path.exists():181+print(f"Warning: ground truth not found for {filename}, skipping")182+continue183+184+with open(input_path, "r") as f:185+request_body: Dict[str, Any] = json.load(f)186+187+with open(gt_path, "r") as f:188+ground_truth: Dict[str, Any] = json.load(f)189+190+samples.append(191+ {192+"id": Path(filename).stem,193+"request_body": request_body,194+"original_response": None,195+"ground_truth": ground_truth,196+ }197+ )198+199+print(f"Loaded {len(samples)} samples from {self._inputs_dir.parent}")200+return samples201+202+async def evaluate_against_ground_truth(self, results: List[Dict[str, Any]]) -> List[EvaluationResult]:203+evaluation_results: List[EvaluationResult] = []204+compare_to = self.__class__.COMPARE_TO_GROUND_TRUTH205+206+for res in results:207+req_id = res["request_id"]208+is_success = res.get("success", True)209+210+if not is_success:211+evaluation_results.append(212+EvaluationResult(213+request_id=req_id,214+request_body=res["request_body"],215+new_response=res.get("new_response"),216+valid_schema=False,217+quality_score=0.0,218+quality_feedback=f"Request failed: {res.get('error_type')} - {res.get('error_message')}",219+response_time=res.get("response_time"),220+success=False,221+error_type=res.get("error_type"),222+error_message=res.get("error_message"),223+ground_truth_match=False,224+ )225+ )226+continue227+228+pred = (res.get("new_response") or {}).get("ai_activity_type")229+230+if compare_to == "llm":231+if "ground_truth_llm" not in res:232+evaluation_results.append(233+EvaluationResult(234+request_id=req_id,235+request_body=res["request_body"],236+new_response=res.get("new_response"),237+valid_schema=res.get("valid_schema", True),238+quality_score=0.0,239+quality_feedback=(240+"Missing ground_truth_llm in run results. Ensure collect step populated it and "241+"endpoints.py passes it through."242+ ),243+response_time=res.get("response_time"),244+success=True,245+ground_truth_match=False,246+ )247+ )248+continue249+gt_label = res.get("ground_truth_llm")250+else:251+gt_path = self._ground_truths_dir / f"gt_{req_id}.json"252+if not gt_path.exists():253+evaluation_results.append(254+EvaluationResult(255+request_id=req_id,256+request_body=res["request_body"],257+new_response=res.get("new_response"),258+valid_schema=res.get("valid_schema", True),259+quality_score=0.0,260+quality_feedback=f"Ground truth file not found: {gt_path}",261+response_time=res.get("response_time"),262+success=True,263+ground_truth_match=False,264+ )265+ )266+continue267+268+with open(gt_path, "r") as f:269+ground_truth_dict: Dict[str, Any] = json.load(f)270+271+gt_label = (ground_truth_dict or {}).get("ai_activity_type")272+273+matched = pred == gt_label274+275+evaluation_results.append(276+EvaluationResult(277+request_id=req_id,278+request_body=res["request_body"],279+new_response=res.get("new_response"),280+valid_schema=res.get("valid_schema", True),281+quality_score=1.0 if matched else 0.0,282+quality_feedback="PASS" if matched else f"FAIL\nExpected: {gt_label}\nGot: {pred}",283+response_time=res.get("response_time"),284+success=True,285+ground_truth_match=matched,286+ )287+ )288+289+return evaluation_results290+291+292+if __name__ == "__main__":293+parser = create_parser(AiActivityTypeEvaluator)294+parser.add_argument(295+"--data-set",296+type=str,297+default="initial",298+dest="data_set",299+help="Dataset folder under eval_output/ai_activity_type/eval_datasets/ (default: initial)",300+ )301+302+parser.add_argument(303+"--populate-ground-truth-llm",304+action="store_true",305+dest="populate_ground_truth_llm",306+ )307+parser.add_argument(308+"--ground-truth-llm-endpoint",309+type=str,310+default="OPENAI:gpt-5_2",311+dest="ground_truth_llm_endpoint",312+ )313+314+parser.add_argument(315+"--compare-to-ground-truth",316+type=str,317+choices=["es", "llm"],318+default="es",319+dest="compare_to_ground_truth",320+ )321+322+args = parser.parse_args()323+AiActivityTypeEvaluator.DATA_SET = args.data_set324+325+AiActivityTypeEvaluator.POPULATE_GROUND_TRUTH_LLM = bool(args.populate_ground_truth_llm)326+AiActivityTypeEvaluator.GROUND_TRUTH_LLM_ENDPOINT = args.ground_truth_llm_endpoint327+328+AiActivityTypeEvaluator.COMPARE_TO_GROUND_TRUTH = args.compare_to_ground_truth329+330+asyncio.run(run_evaluation(AiActivityTypeEvaluator, args))</selection>” selected.
Please summarize the selection using precise and concise language. Use headers and bulleted lists in the summary, to make it scannable. Maintain the meaning and factual accuracy.
Expand
Listen
Show more options
Gemini said
Gemini said
This Python script defines the
AiActivityTypeEvaluator
class, a specialized tool for evaluating AI-driven activity type classification. It extends a base evaluation framework to handle data collection, ground-truth comparison, and performance scoring.
Core Functionality
Core Functionality
Data Collection (
collect_test_set
):
* Supports fetching raw samples from
Elasticsearch (ES)
or loading them from
local JSON files
.
Implements a
replayability check
: It probes the live API endpoint to ensure the activity exists before including it in the dataset.
Filters data based on request body size, language, and the presence of an original response.
Ground Truth Management:
Saves inputs and "gold standard" responses to a local directory structure (
eval_output/ai_activity_type/...
).
Features an optional mode to populate ground truth using a high-order LLM (e.g.,
gpt-5_2
) if the
POPULATE_GROUND_TRUTH_LLM
flag is set.
Evaluation Logic (
evaluate_against_ground_truth
):
Compares the model's predicted
ai_activity_type
against either the original ES response or the LLM-generated ground truth.
Assigns a
quality_score
of
1.0
for a match and
0.0
for a mismatch or request failure.
Key Configuration Constants
Key Configuration Constants
Constant
Purpose
ENDPOINT_PATH
The specific API route being tested:
call/ai-activity-type
.
COMPARE_TO_GROUND_TRUTH
Determines if the baseline is the original data (
es
) or an
llm
.
SKIP_UNREPLAYABLE_ON_COLLECT
If
True
, discards records where the API returns "Cannot find activity."
REPLAYABILITY_CHECK_TIMEOUT_SECONDS
Limits the probe request to 20 seconds.
Constant
ENDPOINT_PATH
COMPARE_TO_GROUND_TRUTH
SKIP_UNREPLAYABLE_ON_COLLECT
REPLAYABILITY_CHECK_TIMEOUT_SECONDS
Purpose
The specific API route being tested:
call/ai-activity-type
.
Determines if the baseline is the original data (
es
) or an
llm
.
If
True
, discards records where the API returns "Cannot find activity."
Limits the probe request to 20 seconds.
Copy table
Execution Workflow
Execution Workflow
Parsing:
The script uses
create_parser
to handle CLI arguments like
--data-set
,
--populate-ground-truth-llm
, and
--compare-to-ground-truth
.
Initialization:
Sets up directory paths for inputs and ground truths based on the selected dataset name.
Run:
Executes the evaluation via
asyncio.run(run_evaluation(...))
, which orchestrates the collection, endpoint calling, and result scoring phases.
Copy prompt
Edit
You said are there soem issues with this PR
You said
are there soem issues with this PR
Show more options
Analyzing Implementation
Gemini said
Gemini said
Enter a prompt for Gemini
encrypted
Enter a prompt for Gemini
encrypted
Open upload file menu
Tools
Open mode picker
Pro
Stop response
Your Jiminny chats aren’t used to improve our models. Gemini is AI and can make mistakes, including about people.
Your privacy & Gemini Opens in a new window
Your privacy & Gemini
Opens in a new window
Summarize page
Summarize page
Skip to content
Skip to content
Open menu
Homepage (g then d)
jiminny
jiminny
prophet
prophet
Search or jump to…
Type
/
to search
Chat with Copilot
Open Copilot…
Create new...
Issues
Pull requests
Repositories
You have unread notifications(g then n)
Open user navigation menu
Repository navigation
Repository navigation
Code
Code
Issues
Issues
Pull requests (6)
Pull requests
(
6
)
Agents...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":4,"bounds":{"left":0.00234375,"top":0.045138888,"width":0.0890625,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira","depth":4,"bounds":{"left":0.0,"top":0.08263889,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira","depth":5,"bounds":{"left":0.015625,"top":0.09236111,"width":0.11796875,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet","depth":4,"bounds":{"left":0.0,"top":0.11111111,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet","depth":5,"bounds":{"left":0.015625,"top":0.12083333,"width":0.1984375,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.07890625,"top":0.11736111,"width":0.009375,"height":0.016666668},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Tab","depth":4,"bounds":{"left":0.003125,"top":0.14097223,"width":0.08710937,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.003125,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Close Google Gemini (⌃X)","depth":6,"bounds":{"left":0.01640625,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"bounds":{"left":0.029296875,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"bounds":{"left":0.0421875,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"bounds":{"left":0.05546875,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"AI Chat settings","depth":7,"bounds":{"left":0.2171875,"top":0.047916666,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Close","depth":7,"bounds":{"left":0.23125,"top":0.047916666,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"WORK, Google Account: lukas.kovalik@jiminny.com","depth":12,"bounds":{"left":0.228125,"top":0.090277776,"width":0.015625,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Main menu","depth":12,"bounds":{"left":0.0984375,"top":0.090277776,"width":0.015625,"height":0.027777778},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Chat","depth":12,"bounds":{"left":0.1953125,"top":0.090277776,"width":0.015625,"height":0.027777778},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Open menu for conversation actions.","depth":12,"bounds":{"left":0.2109375,"top":0.090277776,"width":0.015625,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXHeading","text":"Conversation with Gemini","depth":15,"bounds":{"left":0.09335937,"top":0.12847222,"width":0.000390625,"height":0.00069444446},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Conversation with Gemini","depth":16,"bounds":{"left":0.09335937,"top":0.13055556,"width":0.14101562,"height":0.022222223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Copy prompt","depth":21,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"You said I’m on page “<tabTitle>Jy 19798 evaluation for ai activity types by nikol</tabTitle>” with “<selection>@@ -0,0 +1,330 @@1+#!/usr/bin/env python32+import asyncio3+import json4+import os5+from pathlib import Path6+from typing import Any, Dict, List7+8+import aiohttp9+10+from src.component.call_processing.schemes.ai_activity_type_request import AiActivityTypeRequest11+from src.component.call_processing.schemes.ai_activity_type_response import AiActivityTypeResponse12+from src.eval.abstract_evaluator import AbstractEvaluator13+from src.eval.collectors import collect_test_set as es_collect_test_set14+from src.eval.common_evaluator_runner import create_parser, run_evaluation15+from src.eval.endpoints import run_endpoint as run_endpoint_http16+from src.eval.models import EvaluationResult17+18+19+class AiActivityTypeEvaluator(AbstractEvaluator):20+ENDPOINT_PATH = "call/ai-activity-type"21+REQUEST_MODEL = AiActivityTypeRequest22+RESPONSE_MODEL = AiActivityTypeResponse23+OUTPUT_SUBFOLDER = "ai_activity_type"24+USES_LLM_EVALUATION = False25+26+READS_FROM_DATASET_FOLDER = True27+28+DATA_SET: str = "initial"29+30+MINIMUM_REQUEST_BODY_SIZE: int = 031+32+SKIP_UNREPLAYABLE_ON_COLLECT: bool = True33+REPLAYABILITY_CHECK_TIMEOUT_SECONDS: float = 20.034+35+POPULATE_GROUND_TRUTH_LLM: bool = False36+GROUND_TRUTH_LLM_ENDPOINT: str = "OPENAI:gpt-5_2"37+38+COMPARE_TO_GROUND_TRUTH: str = "es"39+40+def __init__(self, **kwargs: Any) -> None:41+super().__init__(**kwargs)42+_repo_root = Path(__file__).parents[2]43+_datasets_root = _repo_root / "eval_output" / self.OUTPUT_SUBFOLDER / "eval_datasets"44+_dataset_dir = _datasets_root / self.__class__.DATA_SET45+self._dataset_dir = _dataset_dir46+self._inputs_dir = _dataset_dir / "input"47+self._ground_truths_dir = _dataset_dir / "ground_truth"48+49+async def collect_test_set(self) -> List[Dict[str, Any]]:50+if self.es_host_name:51+return await self._collect_from_es()52+return await self._collect_from_files()53+54+async def _collect_from_es(self) -> List[Dict[str, Any]]:55+if self._inputs_dir.exists() or self._ground_truths_dir.exists():56+raise FileExistsError(57+f"Dataset folder already exists: {self._inputs_dir.parent}. "58+"Choose a different --data-set name or remove the folder manually."59+ )60+61+raw_samples = await es_collect_test_set(62+es_host_name=self.es_host_name,63+es_port=self.es_port,64+endpoint_path=self.ENDPOINT_PATH,65+limit=self.limit,66+language_filter=self.language_filter,67+min_prompt_length=self.min_prompt_length,68+is_json_response=self.IS_JSON_RESPONSE,69+exclude_languages=self.exclude_languages,70+ )71+72+self._inputs_dir.mkdir(parents=True, exist_ok=True)73+self._ground_truths_dir.mkdir(parents=True, exist_ok=True)74+75+min_size = self.MINIMUM_REQUEST_BODY_SIZE76+samples: List[Dict[str, Any]] = []77+skipped_no_response = 078+skipped_too_small = 079+skipped_unreplayable = 080+skipped_probe_errors = 081+82+endpoint_url = f"{self.api_host}/{self.ENDPOINT_PATH}"83+84+timeout = aiohttp.ClientTimeout(total=self.REPLAYABILITY_CHECK_TIMEOUT_SECONDS)85+async with aiohttp.ClientSession(timeout=timeout) as session:86+for sample in raw_samples:87+es_id = sample["id"]88+request_body = sample["request_body"]89+original_response = sample.get("original_response")90+91+if not original_response:92+skipped_no_response += 193+continue94+95+if min_size and len(json.dumps(request_body)) < min_size:96+skipped_too_small += 197+continue98+99+if self.SKIP_UNREPLAYABLE_ON_COLLECT:100+try:101+async with session.post(endpoint_url, json=request_body) as resp:102+if resp.status != 200:103+body_text = await resp.text()104+if "Cannot find activity" in body_text:105+skipped_unreplayable += 1106+continue107+except Exception:108+skipped_probe_errors += 1109+110+with open(self._inputs_dir / f"{es_id}.json", "w") as f:111+json.dump(request_body, f, indent=2)112+113+with open(self._ground_truths_dir / f"gt_{es_id}.json", "w") as f:114+json.dump(original_response, f, indent=2)115+116+samples.append(117+ {118+"id": es_id,119+"request_body": request_body,120+"original_response": original_response,121+"ground_truth": original_response,122+ }123+ )124+125+print(f"Wrote {len(samples)} samples to {self._inputs_dir.parent}")126+if skipped_no_response:127+print(f"Skipped {skipped_no_response} records with no response body")128+if skipped_too_small:129+print(130+f"Skipped {skipped_too_small} records whose request body was smaller "131+f"than {min_size} characters"132+ )133+if skipped_unreplayable:134+print(f"Skipped {skipped_unreplayable} records that are not replayable (missing activity in ES)")135+if skipped_probe_errors:136+print(f"Warning: replayability probe errored for {skipped_probe_errors} records (kept those records)")137+138+if self.__class__.POPULATE_GROUND_TRUTH_LLM:139+label_results = await run_endpoint_http(140+test_set=samples,141+endpoint_url=endpoint_url,142+request_model=self.REQUEST_MODEL,143+force_llm_endpoint=self.__class__.GROUND_TRUTH_LLM_ENDPOINT,144+is_streaming_response=self.IS_STREAMING_RESPONSE,145+timeout_seconds=300.0,146+parallel_requests=self.parallel_requests,147+return_prompt_in_run=self.RETURN_PROMPT_IN_RUN,148+ )149+150+for i, r in enumerate(label_results):151+forced = self.__class__.GROUND_TRUTH_LLM_ENDPOINT152+model = forced.split(":", 1)[1] if ":" in forced else forced153+samples[i]["ground_truth_llm_model"] = model154+155+if not r.get("success", True):156+samples[i]["ground_truth_llm"] = None157+samples[i]["ground_truth_llm_reasoning"] = None158+samples[i]["ground_truth_llm_error_type"] = r.get("error_type")159+samples[i]["ground_truth_llm_error_message"] = r.get("error_message")160+continue161+162+resp = r.get("new_response") or {}163+samples[i]["ground_truth_llm"] = resp.get("ai_activity_type")164+samples[i]["ground_truth_llm_reasoning"] = resp.get("ai_activity_type_reasoning")165+166+return samples167+168+async def _collect_from_files(self) -> List[Dict[str, Any]]:169+if not self._inputs_dir.exists():170+raise FileNotFoundError(171+f"Dataset folder not found: {self._inputs_dir}. "172+"Run --steps collect first or check your --data-set name."173+ )174+175+samples: List[Dict[str, Any]] = []176+for filename in sorted(os.listdir(self._inputs_dir)):177+input_path = self._inputs_dir / filename178+gt_path = self._ground_truths_dir / f"gt_{filename}"179+180+if not gt_path.exists():181+print(f"Warning: ground truth not found for {filename}, skipping")182+continue183+184+with open(input_path, "r") as f:185+request_body: Dict[str, Any] = json.load(f)186+187+with open(gt_path, "r") as f:188+ground_truth: Dict[str, Any] = json.load(f)189+190+samples.append(191+ {192+"id": Path(filename).stem,193+"request_body": request_body,194+"original_response": None,195+"ground_truth": ground_truth,196+ }197+ )198+199+print(f"Loaded {len(samples)} samples from {self._inputs_dir.parent}")200+return samples201+202+async def evaluate_against_ground_truth(self, results: List[Dict[str, Any]]) -> List[EvaluationResult]:203+evaluation_results: List[EvaluationResult] = []204+compare_to = self.__class__.COMPARE_TO_GROUND_TRUTH205+206+for res in results:207+req_id = res["request_id"]208+is_success = res.get("success", True)209+210+if not is_success:211+evaluation_results.append(212+EvaluationResult(213+request_id=req_id,214+request_body=res["request_body"],215+new_response=res.get("new_response"),216+valid_schema=False,217+quality_score=0.0,218+quality_feedback=f"Request failed: {res.get('error_type')} - {res.get('error_message')}",219+response_time=res.get("response_time"),220+success=False,221+error_type=res.get("error_type"),222+error_message=res.get("error_message"),223+ground_truth_match=False,224+ )225+ )226+continue227+228+pred = (res.get("new_response") or {}).get("ai_activity_type")229+230+if compare_to == "llm":231+if "ground_truth_llm" not in res:232+evaluation_results.append(233+EvaluationResult(234+request_id=req_id,235+request_body=res["request_body"],236+new_response=res.get("new_response"),237+valid_schema=res.get("valid_schema", True),238+quality_score=0.0,239+quality_feedback=(240+"Missing ground_truth_llm in run results. Ensure collect step populated it and "241+"endpoints.py passes it through."242+ ),243+response_time=res.get("response_time"),244+success=True,245+ground_truth_match=False,246+ )247+ )248+continue249+gt_label = res.get("ground_truth_llm")250+else:251+gt_path = self._ground_truths_dir / f"gt_{req_id}.json"252+if not gt_path.exists():253+evaluation_results.append(254+EvaluationResult(255+request_id=req_id,256+request_body=res["request_body"],257+new_response=res.get("new_response"),258+valid_schema=res.get("valid_schema", True),259+quality_score=0.0,260+quality_feedback=f"Ground truth file not found: {gt_path}",261+response_time=res.get("response_time"),262+success=True,263+ground_truth_match=False,264+ )265+ )266+continue267+268+with open(gt_path, "r") as f:269+ground_truth_dict: Dict[str, Any] = json.load(f)270+271+gt_label = (ground_truth_dict or {}).get("ai_activity_type")272+273+matched = pred == gt_label274+275+evaluation_results.append(276+EvaluationResult(277+request_id=req_id,278+request_body=res["request_body"],279+new_response=res.get("new_response"),280+valid_schema=res.get("valid_schema", True),281+quality_score=1.0 if matched else 0.0,282+quality_feedback="PASS" if matched else f"FAIL\\nExpected: {gt_label}\\nGot: {pred}",283+response_time=res.get("response_time"),284+success=True,285+ground_truth_match=matched,286+ )287+ )288+289+return evaluation_results290+291+292+if __name__ == "__main__":293+parser = create_parser(AiActivityTypeEvaluator)294+parser.add_argument(295+"--data-set",296+type=str,297+default="initial",298+dest="data_set",299+help="Dataset folder under eval_output/ai_activity_type/eval_datasets/ (default: initial)",300+ )301+302+parser.add_argument(303+"--populate-ground-truth-llm",304+action="store_true",305+dest="populate_ground_truth_llm",306+ )307+parser.add_argument(308+"--ground-truth-llm-endpoint",309+type=str,310+default="OPENAI:gpt-5_2",311+dest="ground_truth_llm_endpoint",312+ )313+314+parser.add_argument(315+"--compare-to-ground-truth",316+type=str,317+choices=["es", "llm"],318+default="es",319+dest="compare_to_ground_truth",320+ )321+322+args = parser.parse_args()323+AiActivityTypeEvaluator.DATA_SET = args.data_set324+325+AiActivityTypeEvaluator.POPULATE_GROUND_TRUTH_LLM = bool(args.populate_ground_truth_llm)326+AiActivityTypeEvaluator.GROUND_TRUTH_LLM_ENDPOINT = args.ground_truth_llm_endpoint327+328+AiActivityTypeEvaluator.COMPARE_TO_GROUND_TRUTH = args.compare_to_ground_truth329+330+asyncio.run(run_evaluation(AiActivityTypeEvaluator, args))</selection>” selected. Please summarize the selection using precise and concise language. Use headers and bulleted lists in the summary, to make it scannable. Maintain the meaning and factual accuracy.","depth":21,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"You said","depth":23,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"I’m on page “<tabTitle>Jy 19798 evaluation for ai activity types by nikol</tabTitle>” with “<selection>@@ -0,0 +1,330 @@1+#!/usr/bin/env python32+import asyncio3+import json4+import os5+from pathlib import Path6+from typing import Any, Dict, List7+8+import aiohttp9+10+from src.component.call_processing.schemes.ai_activity_type_request import AiActivityTypeRequest11+from src.component.call_processing.schemes.ai_activity_type_response import AiActivityTypeResponse12+from src.eval.abstract_evaluator import AbstractEvaluator13+from src.eval.collectors import collect_test_set as es_collect_test_set14+from src.eval.common_evaluator_runner import create_parser, run_evaluation15+from src.eval.endpoints import run_endpoint as run_endpoint_http16+from src.eval.models import EvaluationResult17+18+19+class AiActivityTypeEvaluator(AbstractEvaluator):20+ENDPOINT_PATH = "call/ai-activity-type"21+REQUEST_MODEL = AiActivityTypeRequest22+RESPONSE_MODEL = AiActivityTypeResponse23+OUTPUT_SUBFOLDER = "ai_activity_type"24+USES_LLM_EVALUATION = False25+26+READS_FROM_DATASET_FOLDER = True27+28+DATA_SET: str = "initial"29+30+MINIMUM_REQUEST_BODY_SIZE: int = 031+32+SKIP_UNREPLAYABLE_ON_COLLECT: bool = True33+REPLAYABILITY_CHECK_TIMEOUT_SECONDS: float = 20.034+35+POPULATE_GROUND_TRUTH_LLM: bool = False36+GROUND_TRUTH_LLM_ENDPOINT: str = "OPENAI:gpt-5_2"37+38+COMPARE_TO_GROUND_TRUTH: str = "es"39+40+def __init__(self, **kwargs: Any) -> None:41+super().__init__(**kwargs)42+_repo_root = Path(__file__).parents[2]43+_datasets_root = _repo_root / "eval_output" / self.OUTPUT_SUBFOLDER / "eval_datasets"44+_dataset_dir = _datasets_root / self.__class__.DATA_SET45+self._dataset_dir = _dataset_dir46+self._inputs_dir = _dataset_dir / "input"47+self._ground_truths_dir = _dataset_dir / "ground_truth"48+49+async def collect_test_set(self) -> List[Dict[str, Any]]:50+if self.es_host_name:51+return await self._collect_from_es()52+return await self._collect_from_files()53+54+async def _collect_from_es(self) -> List[Dict[str, Any]]:55+if self._inputs_dir.exists() or self._ground_truths_dir.exists():56+raise FileExistsError(57+f"Dataset folder already exists: {self._inputs_dir.parent}. "58+"Choose a different --data-set name or remove the folder manually."59+ )60+61+raw_samples = await es_collect_test_set(62+es_host_name=self.es_host_name,63+es_port=self.es_port,64+endpoint_path=self.ENDPOINT_PATH,65+limit=self.limit,66+language_filter=self.language_filter,67+min_prompt_length=self.min_prompt_length,68+is_json_response=self.IS_JSON_RESPONSE,69+exclude_languages=self.exclude_languages,70+ )71+72+self._inputs_dir.mkdir(parents=True, exist_ok=True)73+self._ground_truths_dir.mkdir(parents=True, exist_ok=True)74+75+min_size = self.MINIMUM_REQUEST_BODY_SIZE76+samples: List[Dict[str, Any]] = []77+skipped_no_response = 078+skipped_too_small = 079+skipped_unreplayable = 080+skipped_probe_errors = 081+82+endpoint_url = f"{self.api_host}/{self.ENDPOINT_PATH}"83+84+timeout = aiohttp.ClientTimeout(total=self.REPLAYABILITY_CHECK_TIMEOUT_SECONDS)85+async with aiohttp.ClientSession(timeout=timeout) as session:86+for sample in raw_samples:87+es_id = sample["id"]88+request_body = sample["request_body"]89+original_response = sample.get("original_response")90+91+if not original_response:92+skipped_no_response += 193+continue94+95+if min_size and len(json.dumps(request_body)) < min_size:96+skipped_too_small += 197+continue98+99+if self.SKIP_UNREPLAYABLE_ON_COLLECT:100+try:101+async with session.post(endpoint_url, json=request_body) as resp:102+if resp.status != 200:103+body_text = await resp.text()104+if "Cannot find activity" in body_text:105+skipped_unreplayable += 1106+continue107+except Exception:108+skipped_probe_errors += 1109+110+with open(self._inputs_dir / f"{es_id}.json", "w") as f:111+json.dump(request_body, f, indent=2)112+113+with open(self._ground_truths_dir / f"gt_{es_id}.json", "w") as f:114+json.dump(original_response, f, indent=2)115+116+samples.append(117+ {118+"id": es_id,119+"request_body": request_body,120+"original_response": original_response,121+"ground_truth": original_response,122+ }123+ )124+125+print(f"Wrote {len(samples)} samples to {self._inputs_dir.parent}")126+if skipped_no_response:127+print(f"Skipped {skipped_no_response} records with no response body")128+if skipped_too_small:129+print(130+f"Skipped {skipped_too_small} records whose request body was smaller "131+f"than {min_size} characters"132+ )133+if skipped_unreplayable:134+print(f"Skipped {skipped_unreplayable} records that are not replayable (missing activity in ES)")135+if skipped_probe_errors:136+print(f"Warning: replayability probe errored for {skipped_probe_errors} records (kept those records)")137+138+if self.__class__.POPULATE_GROUND_TRUTH_LLM:139+label_results = await run_endpoint_http(140+test_set=samples,141+endpoint_url=endpoint_url,142+request_model=self.REQUEST_MODEL,143+force_llm_endpoint=self.__class__.GROUND_TRUTH_LLM_ENDPOINT,144+is_streaming_response=self.IS_STREAMING_RESPONSE,145+timeout_seconds=300.0,146+parallel_requests=self.parallel_requests,147+return_prompt_in_run=self.RETURN_PROMPT_IN_RUN,148+ )149+150+for i, r in enumerate(label_results):151+forced = self.__class__.GROUND_TRUTH_LLM_ENDPOINT152+model = forced.split(":", 1)[1] if ":" in forced else forced153+samples[i]["ground_truth_llm_model"] = model154+155+if not r.get("success", True):156+samples[i]["ground_truth_llm"] = None157+samples[i]["ground_truth_llm_reasoning"] = None158+samples[i]["ground_truth_llm_error_type"] = r.get("error_type")159+samples[i]["ground_truth_llm_error_message"] = r.get("error_message")160+continue161+162+resp = r.get("new_response") or {}163+samples[i]["ground_truth_llm"] = resp.get("ai_activity_type")164+samples[i]["ground_truth_llm_reasoning"] = resp.get("ai_activity_type_reasoning")165+166+return samples167+168+async def _collect_from_files(self) -> List[Dict[str, Any]]:169+if not self._inputs_dir.exists():170+raise FileNotFoundError(171+f"Dataset folder not found: {self._inputs_dir}. "172+"Run --steps collect first or check your --data-set name."173+ )174+175+samples: List[Dict[str, Any]] = []176+for filename in sorted(os.listdir(self._inputs_dir)):177+input_path = self._inputs_dir / filename178+gt_path = self._ground_truths_dir / f"gt_{filename}"179+180+if not gt_path.exists():181+print(f"Warning: ground truth not found for {filename}, skipping")182+continue183+184+with open(input_path, "r") as f:185+request_body: Dict[str, Any] = json.load(f)186+187+with open(gt_path, "r") as f:188+ground_truth: Dict[str, Any] = json.load(f)189+190+samples.append(191+ {192+"id": Path(filename).stem,193+"request_body": request_body,194+"original_response": None,195+"ground_truth": ground_truth,196+ }197+ )198+199+print(f"Loaded {len(samples)} samples from {self._inputs_dir.parent}")200+return samples201+202+async def evaluate_against_ground_truth(self, results: List[Dict[str, Any]]) -> List[EvaluationResult]:203+evaluation_results: List[EvaluationResult] = []204+compare_to = self.__class__.COMPARE_TO_GROUND_TRUTH205+206+for res in results:207+req_id = res["request_id"]208+is_success = res.get("success", True)209+210+if not is_success:211+evaluation_results.append(212+EvaluationResult(213+request_id=req_id,214+request_body=res["request_body"],215+new_response=res.get("new_response"),216+valid_schema=False,217+quality_score=0.0,218+quality_feedback=f"Request failed: {res.get('error_type')} - {res.get('error_message')}",219+response_time=res.get("response_time"),220+success=False,221+error_type=res.get("error_type"),222+error_message=res.get("error_message"),223+ground_truth_match=False,224+ )225+ )226+continue227+228+pred = (res.get("new_response") or {}).get("ai_activity_type")229+230+if compare_to == "llm":231+if "ground_truth_llm" not in res:232+evaluation_results.append(233+EvaluationResult(234+request_id=req_id,235+request_body=res["request_body"],236+new_response=res.get("new_response"),237+valid_schema=res.get("valid_schema", True),238+quality_score=0.0,239+quality_feedback=(240+"Missing ground_truth_llm in run results. Ensure collect step populated it and "241+"endpoints.py passes it through."242+ ),243+response_time=res.get("response_time"),244+success=True,245+ground_truth_match=False,246+ )247+ )248+continue249+gt_label = res.get("ground_truth_llm")250+else:251+gt_path = self._ground_truths_dir / f"gt_{req_id}.json"252+if not gt_path.exists():253+evaluation_results.append(254+EvaluationResult(255+request_id=req_id,256+request_body=res["request_body"],257+new_response=res.get("new_response"),258+valid_schema=res.get("valid_schema", True),259+quality_score=0.0,260+quality_feedback=f"Ground truth file not found: {gt_path}",261+response_time=res.get("response_time"),262+success=True,263+ground_truth_match=False,264+ )265+ )266+continue267+268+with open(gt_path, "r") as f:269+ground_truth_dict: Dict[str, Any] = json.load(f)270+271+gt_label = (ground_truth_dict or {}).get("ai_activity_type")272+273+matched = pred == gt_label274+275+evaluation_results.append(276+EvaluationResult(277+request_id=req_id,278+request_body=res["request_body"],279+new_response=res.get("new_response"),280+valid_schema=res.get("valid_schema", True),281+quality_score=1.0 if matched else 0.0,282+quality_feedback="PASS" if matched else f"FAIL\\nExpected: {gt_label}\\nGot: {pred}",283+response_time=res.get("response_time"),284+success=True,285+ground_truth_match=matched,286+ )287+ )288+289+return evaluation_results290+291+292+if __name__ == "__main__":293+parser = create_parser(AiActivityTypeEvaluator)294+parser.add_argument(295+"--data-set",296+type=str,297+default="initial",298+dest="data_set",299+help="Dataset folder under eval_output/ai_activity_type/eval_datasets/ (default: initial)",300+ )301+302+parser.add_argument(303+"--populate-ground-truth-llm",304+action="store_true",305+dest="populate_ground_truth_llm",306+ )307+parser.add_argument(308+"--ground-truth-llm-endpoint",309+type=str,310+default="OPENAI:gpt-5_2",311+dest="ground_truth_llm_endpoint",312+ )313+314+parser.add_argument(315+"--compare-to-ground-truth",316+type=str,317+choices=["es", "llm"],318+default="es",319+dest="compare_to_ground_truth",320+ )321+322+args = parser.parse_args()323+AiActivityTypeEvaluator.DATA_SET = args.data_set324+325+AiActivityTypeEvaluator.POPULATE_GROUND_TRUTH_LLM = bool(args.populate_ground_truth_llm)326+AiActivityTypeEvaluator.GROUND_TRUTH_LLM_ENDPOINT = args.ground_truth_llm_endpoint327+328+AiActivityTypeEvaluator.COMPARE_TO_GROUND_TRUTH = args.compare_to_ground_truth329+330+asyncio.run(run_evaluation(AiActivityTypeEvaluator, args))</selection>” selected.","depth":23,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Please summarize the selection using precise and concise language. Use headers and bulleted lists in the summary, to make it scannable. Maintain the meaning and factual accuracy.","depth":23,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Expand","depth":21,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Listen","depth":22,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Show more options","depth":20,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Gemini said","depth":20,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Gemini said","depth":21,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"This Python script defines the","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"AiActivityTypeEvaluator","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"class, a specialized tool for evaluating AI-driven activity type classification. It extends a base evaluation framework to handle data collection, ground-truth comparison, and performance scoring.","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Core Functionality","depth":23,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Core Functionality","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Data Collection (","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"collect_test_set","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"):","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"* Supports fetching raw samples from","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Elasticsearch (ES)","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"or loading them from","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"local JSON files","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Implements a","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"replayability check","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":": It probes the live API endpoint to ensure the activity exists before including it in the dataset.","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Filters data based on request body size, language, and the presence of an original response.","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Ground Truth Management:","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Saves inputs and \"gold standard\" responses to a local directory structure (","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"eval_output/ai_activity_type/...","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":").","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Features an optional mode to populate ground truth using a high-order LLM (e.g.,","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"gpt-5_2","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":") if the","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"POPULATE_GROUND_TRUTH_LLM","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"flag is set.","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Evaluation Logic (","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"evaluate_against_ground_truth","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"):","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Compares the model's predicted","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ai_activity_type","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"against either the original ES response or the LLM-generated ground truth.","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Assigns a","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"quality_score","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"of","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1.0","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"for a match and","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.0","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"for a mismatch or request failure.","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Key Configuration Constants","depth":23,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Key Configuration Constants","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Constant","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Purpose","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ENDPOINT_PATH","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"The specific API route being tested:","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"call/ai-activity-type","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"COMPARE_TO_GROUND_TRUTH","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Determines if the baseline is the original data (","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"es","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":") or an","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"llm","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"SKIP_UNREPLAYABLE_ON_COLLECT","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"If","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"True","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":", discards records where the API returns \"Cannot find activity.\"","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"REPLAYABILITY_CHECK_TIMEOUT_SECONDS","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Limits the probe request to 20 seconds.","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Constant","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ENDPOINT_PATH","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"COMPARE_TO_GROUND_TRUTH","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"SKIP_UNREPLAYABLE_ON_COLLECT","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"REPLAYABILITY_CHECK_TIMEOUT_SECONDS","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Purpose","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"The specific API route being tested:","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"call/ai-activity-type","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Determines if the baseline is the original data (","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"es","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":") or an","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"llm","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"If","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"True","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":", discards records where the API returns \"Cannot find activity.\"","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Limits the probe request to 20 seconds.","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Copy table","depth":24,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Execution Workflow","depth":23,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Execution Workflow","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Parsing:","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"The script uses","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"create_parser","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"to handle CLI arguments like","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"--data-set","depth":27,"bounds":{"left":0.1171875,"top":0.0,"width":0.107421875,"height":0.03125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":",","depth":26,"bounds":{"left":0.12929687,"top":0.0,"width":0.003125,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"--populate-ground-truth-llm","depth":27,"bounds":{"left":0.13476562,"top":0.0,"width":0.08867188,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":", and","depth":26,"bounds":{"left":0.1171875,"top":0.0,"width":0.11171875,"height":0.03263889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"--compare-to-ground-truth","depth":27,"bounds":{"left":0.13203125,"top":0.0,"width":0.08203125,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":26,"bounds":{"left":0.21640626,"top":0.0,"width":0.0015625,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Initialization:","depth":26,"bounds":{"left":0.1171875,"top":0.0,"width":0.039453126,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Sets up directory paths for inputs and ground truths based on the selected dataset name.","depth":26,"bounds":{"left":0.1171875,"top":0.0,"width":0.11875,"height":0.050694443},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Run:","depth":26,"bounds":{"left":0.1171875,"top":0.024305556,"width":0.013671875,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Executes the evaluation via","depth":26,"bounds":{"left":0.13085938,"top":0.024305556,"width":0.080078125,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"asyncio.run(run_evaluation(...))","depth":27,"bounds":{"left":0.11953125,"top":0.04375,"width":0.10507812,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":", which orchestrates the collection, endpoint calling, and result scoring phases.","depth":26,"bounds":{"left":0.1171875,"top":0.04236111,"width":0.11289062,"height":0.06875},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Copy prompt","depth":21,"bounds":{"left":0.1203125,"top":0.15972222,"width":0.015625,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Edit","depth":21,"bounds":{"left":0.1375,"top":0.15972222,"width":0.015625,"height":0.027777778},"role_description":"button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"You said are there soem issues with this PR","depth":21,"bounds":{"left":0.1609375,"top":0.16805555,"width":0.072265625,"height":0.03888889},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"You said","depth":23,"bounds":{"left":0.09335937,"top":0.1701389,"width":0.0234375,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"are there soem issues with this PR","depth":23,"bounds":{"left":0.1609375,"top":0.17083333,"width":0.062109374,"height":0.034027778},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Show more options","depth":20,"bounds":{"left":0.22382812,"top":0.22986111,"width":0.015625,"height":0.027777778},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Analyzing Implementation","depth":26,"bounds":{"left":0.11953125,"top":0.23680556,"width":0.06679688,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Gemini said","depth":20,"bounds":{"left":0.11679687,"top":0.27291667,"width":0.000390625,"height":0.00069444446},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Gemini said","depth":21,"bounds":{"left":0.11679687,"top":0.27430555,"width":0.048046876,"height":0.016666668},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextArea","text":"Enter a prompt for Gemini\nencrypted","depth":20,"bounds":{"left":0.109375,"top":0.8354167,"width":0.125,"height":0.016666668},"value":"Enter a prompt for Gemini\nencrypted","help_text":"","role_description":"text entry area","subrole":"AXUnknown","is_enabled":true,"is_focused":true,"is_selected":false},{"role":"AXStaticText","text":"Enter a prompt for Gemini","depth":21,"bounds":{"left":0.1171875,"top":0.8354167,"width":0.08203125,"height":0.016666668},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"encrypted","depth":21,"bounds":{"left":0.10820313,"top":0.8354167,"width":0.0078125,"height":0.016666668},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open upload file menu","depth":20,"bounds":{"left":0.1046875,"top":0.86527777,"width":0.015625,"height":0.027777778},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Tools","depth":18,"bounds":{"left":0.1234375,"top":0.86527777,"width":0.015625,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Open mode picker","depth":20,"bounds":{"left":0.190625,"top":0.8645833,"width":0.03046875,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pro","depth":23,"bounds":{"left":0.196875,"top":0.87222224,"width":0.00859375,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Stop response","depth":19,"bounds":{"left":0.22265625,"top":0.86388886,"width":0.01640625,"height":0.029166667},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Your Jiminny chats aren’t used to improve our models. Gemini is AI and can make mistakes, including about people.","depth":17,"bounds":{"left":0.10039063,"top":0.9097222,"width":0.14296874,"height":0.022222223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Your privacy & Gemini Opens in a new window","depth":17,"bounds":{"left":0.1484375,"top":0.93194443,"width":0.046875,"height":0.011111111},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Your privacy & Gemini","depth":18,"bounds":{"left":0.1484375,"top":0.93194443,"width":0.046875,"height":0.011111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Opens in a new window","depth":19,"bounds":{"left":0.09335937,"top":0.93125,"width":0.05078125,"height":0.011111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Summarize page","depth":7,"bounds":{"left":0.1,"top":0.96319443,"width":0.06289063,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Summarize page","depth":9,"bounds":{"left":0.10664062,"top":0.9673611,"width":0.049609374,"height":0.013888889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Skip to content","depth":6,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip to content","depth":7,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open menu","depth":10,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Homepage (g then d)","depth":9,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"jiminny","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"jiminny","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"prophet","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"prophet","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Search or jump to…","depth":9,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Type","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"/","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"to search","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Chat with Copilot","depth":10,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXMenuButton","text":"Open Copilot…","depth":9,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXMenuButton","text":"Create new...","depth":9,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"Issues","depth":9,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Pull requests","depth":9,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Repositories","depth":9,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"You have unread notifications(g then n)","depth":9,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Open user navigation menu","depth":9,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Repository navigation","depth":9,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Repository navigation","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Code","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Code","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Issues","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Issues","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Pull requests (6)","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pull requests","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"6","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Agents","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false}]...
|
6142532471012435964
|
8731758629248348295
|
idle
|
accessibility
|
NULL
|
JY-20543 add AJ reports User pilot tracking by Lak JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Close tab
New Tab
Customize sidebar
Close Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
AI Chat settings
Close
WORK, Google Account: [EMAIL]
Main menu
New Chat
Open menu for conversation actions.
Conversation with Gemini
Conversation with Gemini
Copy prompt
You said I’m on page “<tabTitle>Jy 19798 evaluation for ai activity types by nikol</tabTitle>” with “<selection>@@ -0,0 +1,330 @@1+#!/usr/bin/env python32+import asyncio3+import json4+import os5+from pathlib import Path6+from typing import Any, Dict, List7+8+import aiohttp9+10+from src.component.call_processing.schemes.ai_activity_type_request import AiActivityTypeRequest11+from src.component.call_processing.schemes.ai_activity_type_response import AiActivityTypeResponse12+from src.eval.abstract_evaluator import AbstractEvaluator13+from src.eval.collectors import collect_test_set as es_collect_test_set14+from src.eval.common_evaluator_runner import create_parser, run_evaluation15+from src.eval.endpoints import run_endpoint as run_endpoint_http16+from src.eval.models import EvaluationResult17+18+19+class AiActivityTypeEvaluator(AbstractEvaluator):20+ENDPOINT_PATH = "call/ai-activity-type"21+REQUEST_MODEL = AiActivityTypeRequest22+RESPONSE_MODEL = AiActivityTypeResponse23+OUTPUT_SUBFOLDER = "ai_activity_type"24+USES_LLM_EVALUATION = False25+26+READS_FROM_DATASET_FOLDER = True27+28+DATA_SET: str = "initial"29+30+MINIMUM_REQUEST_BODY_SIZE: int = 031+32+SKIP_UNREPLAYABLE_ON_COLLECT: bool = True33+REPLAYABILITY_CHECK_TIMEOUT_SECONDS: float = 20.034+35+POPULATE_GROUND_TRUTH_LLM: bool = False36+GROUND_TRUTH_LLM_ENDPOINT: str = "OPENAI:gpt-5_2"37+38+COMPARE_TO_GROUND_TRUTH: str = "es"39+40+def __init__(self, **kwargs: Any) -> None:41+super().__init__(**kwargs)42+_repo_root = Path(__file__).parents[2]43+_datasets_root = _repo_root / "eval_output" / self.OUTPUT_SUBFOLDER / "eval_datasets"44+_dataset_dir = _datasets_root / self.__class__.DATA_SET45+self._dataset_dir = _dataset_dir46+self._inputs_dir = _dataset_dir / "input"47+self._ground_truths_dir = _dataset_dir / "ground_truth"48+49+async def collect_test_set(self) -> List[Dict[str, Any]]:50+if self.es_host_name:51+return await self._collect_from_es()52+return await self._collect_from_files()53+54+async def _collect_from_es(self) -> List[Dict[str, Any]]:55+if self._inputs_dir.exists() or self._ground_truths_dir.exists():56+raise FileExistsError(57+f"Dataset folder already exists: {self._inputs_dir.parent}. "58+"Choose a different --data-set name or remove the folder manually."59+ )60+61+raw_samples = await es_collect_test_set(62+es_host_name=self.es_host_name,63+es_port=self.es_port,64+endpoint_path=self.ENDPOINT_PATH,65+limit=self.limit,66+language_filter=self.language_filter,67+min_prompt_length=self.min_prompt_length,68+is_json_response=self.IS_JSON_RESPONSE,69+exclude_languages=self.exclude_languages,70+ )71+72+self._inputs_dir.mkdir(parents=True, exist_ok=True)73+self._ground_truths_dir.mkdir(parents=True, exist_ok=True)74+75+min_size = self.MINIMUM_REQUEST_BODY_SIZE76+samples: List[Dict[str, Any]] = []77+skipped_no_response = 078+skipped_too_small = 079+skipped_unreplayable = 080+skipped_probe_errors = 081+82+endpoint_url = f"{self.api_host}/{self.ENDPOINT_PATH}"83+84+timeout = aiohttp.ClientTimeout(total=self.REPLAYABILITY_CHECK_TIMEOUT_SECONDS)85+async with aiohttp.ClientSession(timeout=timeout) as session:86+for sample in raw_samples:87+es_id = sample["id"]88+request_body = sample["request_body"]89+original_response = sample.get("original_response")90+91+if not original_response:92+skipped_no_response += 193+continue94+95+if min_size and len(json.dumps(request_body)) < min_size:96+skipped_too_small += 197+continue98+99+if self.SKIP_UNREPLAYABLE_ON_COLLECT:100+try:101+async with session.post(endpoint_url, json=request_body) as resp:102+if resp.status != 200:103+body_text = await resp.text()104+if "Cannot find activity" in body_text:105+skipped_unreplayable += 1106+continue107+except Exception:108+skipped_probe_errors += 1109+110+with open(self._inputs_dir / f"{es_id}.json", "w") as f:111+json.dump(request_body, f, indent=2)112+113+with open(self._ground_truths_dir / f"gt_{es_id}.json", "w") as f:114+json.dump(original_response, f, indent=2)115+116+samples.append(117+ {118+"id": es_id,119+"request_body": request_body,120+"original_response": original_response,121+"ground_truth": original_response,122+ }123+ )124+125+print(f"Wrote {len(samples)} samples to {self._inputs_dir.parent}")126+if skipped_no_response:127+print(f"Skipped {skipped_no_response} records with no response body")128+if skipped_too_small:129+print(130+f"Skipped {skipped_too_small} records whose request body was smaller "131+f"than {min_size} characters"132+ )133+if skipped_unreplayable:134+print(f"Skipped {skipped_unreplayable} records that are not replayable (missing activity in ES)")135+if skipped_probe_errors:136+print(f"Warning: replayability probe errored for {skipped_probe_errors} records (kept those records)")137+138+if self.__class__.POPULATE_GROUND_TRUTH_LLM:139+label_results = await run_endpoint_http(140+test_set=samples,141+endpoint_url=endpoint_url,142+request_model=self.REQUEST_MODEL,143+force_llm_endpoint=self.__class__.GROUND_TRUTH_LLM_ENDPOINT,144+is_streaming_response=self.IS_STREAMING_RESPONSE,145+timeout_seconds=300.0,146+parallel_requests=self.parallel_requests,147+return_prompt_in_run=self.RETURN_PROMPT_IN_RUN,148+ )149+150+for i, r in enumerate(label_results):151+forced = self.__class__.GROUND_TRUTH_LLM_ENDPOINT152+model = forced.split(":", 1)[1] if ":" in forced else forced153+samples[i]["ground_truth_llm_model"] = model154+155+if not r.get("success", True):156+samples[i]["ground_truth_llm"] = None157+samples[i]["ground_truth_llm_reasoning"] = None158+samples[i]["ground_truth_llm_error_type"] = r.get("error_type")159+samples[i]["ground_truth_llm_error_message"] = r.get("error_message")160+continue161+162+resp = r.get("new_response") or {}163+samples[i]["ground_truth_llm"] = resp.get("ai_activity_type")164+samples[i]["ground_truth_llm_reasoning"] = resp.get("ai_activity_type_reasoning")165+166+return samples167+168+async def _collect_from_files(self) -> List[Dict[str, Any]]:169+if not self._inputs_dir.exists():170+raise FileNotFoundError(171+f"Dataset folder not found: {self._inputs_dir}. "172+"Run --steps collect first or check your --data-set name."173+ )174+175+samples: List[Dict[str, Any]] = []176+for filename in sorted(os.listdir(self._inputs_dir)):177+input_path = self._inputs_dir / filename178+gt_path = self._ground_truths_dir / f"gt_{filename}"179+180+if not gt_path.exists():181+print(f"Warning: ground truth not found for {filename}, skipping")182+continue183+184+with open(input_path, "r") as f:185+request_body: Dict[str, Any] = json.load(f)186+187+with open(gt_path, "r") as f:188+ground_truth: Dict[str, Any] = json.load(f)189+190+samples.append(191+ {192+"id": Path(filename).stem,193+"request_body": request_body,194+"original_response": None,195+"ground_truth": ground_truth,196+ }197+ )198+199+print(f"Loaded {len(samples)} samples from {self._inputs_dir.parent}")200+return samples201+202+async def evaluate_against_ground_truth(self, results: List[Dict[str, Any]]) -> List[EvaluationResult]:203+evaluation_results: List[EvaluationResult] = []204+compare_to = self.__class__.COMPARE_TO_GROUND_TRUTH205+206+for res in results:207+req_id = res["request_id"]208+is_success = res.get("success", True)209+210+if not is_success:211+evaluation_results.append(212+EvaluationResult(213+request_id=req_id,214+request_body=res["request_body"],215+new_response=res.get("new_response"),216+valid_schema=False,217+quality_score=0.0,218+quality_feedback=f"Request failed: {res.get('error_type')} - {res.get('error_message')}",219+response_time=res.get("response_time"),220+success=False,221+error_type=res.get("error_type"),222+error_message=res.get("error_message"),223+ground_truth_match=False,224+ )225+ )226+continue227+228+pred = (res.get("new_response") or {}).get("ai_activity_type")229+230+if compare_to == "llm":231+if "ground_truth_llm" not in res:232+evaluation_results.append(233+EvaluationResult(234+request_id=req_id,235+request_body=res["request_body"],236+new_response=res.get("new_response"),237+valid_schema=res.get("valid_schema", True),238+quality_score=0.0,239+quality_feedback=(240+"Missing ground_truth_llm in run results. Ensure collect step populated it and "241+"endpoints.py passes it through."242+ ),243+response_time=res.get("response_time"),244+success=True,245+ground_truth_match=False,246+ )247+ )248+continue249+gt_label = res.get("ground_truth_llm")250+else:251+gt_path = self._ground_truths_dir / f"gt_{req_id}.json"252+if not gt_path.exists():253+evaluation_results.append(254+EvaluationResult(255+request_id=req_id,256+request_body=res["request_body"],257+new_response=res.get("new_response"),258+valid_schema=res.get("valid_schema", True),259+quality_score=0.0,260+quality_feedback=f"Ground truth file not found: {gt_path}",261+response_time=res.get("response_time"),262+success=True,263+ground_truth_match=False,264+ )265+ )266+continue267+268+with open(gt_path, "r") as f:269+ground_truth_dict: Dict[str, Any] = json.load(f)270+271+gt_label = (ground_truth_dict or {}).get("ai_activity_type")272+273+matched = pred == gt_label274+275+evaluation_results.append(276+EvaluationResult(277+request_id=req_id,278+request_body=res["request_body"],279+new_response=res.get("new_response"),280+valid_schema=res.get("valid_schema", True),281+quality_score=1.0 if matched else 0.0,282+quality_feedback="PASS" if matched else f"FAIL\nExpected: {gt_label}\nGot: {pred}",283+response_time=res.get("response_time"),284+success=True,285+ground_truth_match=matched,286+ )287+ )288+289+return evaluation_results290+291+292+if __name__ == "__main__":293+parser = create_parser(AiActivityTypeEvaluator)294+parser.add_argument(295+"--data-set",296+type=str,297+default="initial",298+dest="data_set",299+help="Dataset folder under eval_output/ai_activity_type/eval_datasets/ (default: initial)",300+ )301+302+parser.add_argument(303+"--populate-ground-truth-llm",304+action="store_true",305+dest="populate_ground_truth_llm",306+ )307+parser.add_argument(308+"--ground-truth-llm-endpoint",309+type=str,310+default="OPENAI:gpt-5_2",311+dest="ground_truth_llm_endpoint",312+ )313+314+parser.add_argument(315+"--compare-to-ground-truth",316+type=str,317+choices=["es", "llm"],318+default="es",319+dest="compare_to_ground_truth",320+ )321+322+args = parser.parse_args()323+AiActivityTypeEvaluator.DATA_SET = args.data_set324+325+AiActivityTypeEvaluator.POPULATE_GROUND_TRUTH_LLM = bool(args.populate_ground_truth_llm)326+AiActivityTypeEvaluator.GROUND_TRUTH_LLM_ENDPOINT = args.ground_truth_llm_endpoint327+328+AiActivityTypeEvaluator.COMPARE_TO_GROUND_TRUTH = args.compare_to_ground_truth329+330+asyncio.run(run_evaluation(AiActivityTypeEvaluator, args))</selection>” selected. Please summarize the selection using precise and concise language. Use headers and bulleted lists in the summary, to make it scannable. Maintain the meaning and factual accuracy.
You said
I’m on page “<tabTitle>Jy 19798 evaluation for ai activity types by nikol</tabTitle>” with “<selection>@@ -0,0 +1,330 @@1+#!/usr/bin/env python32+import asyncio3+import json4+import os5+from pathlib import Path6+from typing import Any, Dict, List7+8+import aiohttp9+10+from src.component.call_processing.schemes.ai_activity_type_request import AiActivityTypeRequest11+from src.component.call_processing.schemes.ai_activity_type_response import AiActivityTypeResponse12+from src.eval.abstract_evaluator import AbstractEvaluator13+from src.eval.collectors import collect_test_set as es_collect_test_set14+from src.eval.common_evaluator_runner import create_parser, run_evaluation15+from src.eval.endpoints import run_endpoint as run_endpoint_http16+from src.eval.models import EvaluationResult17+18+19+class AiActivityTypeEvaluator(AbstractEvaluator):20+ENDPOINT_PATH = "call/ai-activity-type"21+REQUEST_MODEL = AiActivityTypeRequest22+RESPONSE_MODEL = AiActivityTypeResponse23+OUTPUT_SUBFOLDER = "ai_activity_type"24+USES_LLM_EVALUATION = False25+26+READS_FROM_DATASET_FOLDER = True27+28+DATA_SET: str = "initial"29+30+MINIMUM_REQUEST_BODY_SIZE: int = 031+32+SKIP_UNREPLAYABLE_ON_COLLECT: bool = True33+REPLAYABILITY_CHECK_TIMEOUT_SECONDS: float = 20.034+35+POPULATE_GROUND_TRUTH_LLM: bool = False36+GROUND_TRUTH_LLM_ENDPOINT: str = "OPENAI:gpt-5_2"37+38+COMPARE_TO_GROUND_TRUTH: str = "es"39+40+def __init__(self, **kwargs: Any) -> None:41+super().__init__(**kwargs)42+_repo_root = Path(__file__).parents[2]43+_datasets_root = _repo_root / "eval_output" / self.OUTPUT_SUBFOLDER / "eval_datasets"44+_dataset_dir = _datasets_root / self.__class__.DATA_SET45+self._dataset_dir = _dataset_dir46+self._inputs_dir = _dataset_dir / "input"47+self._ground_truths_dir = _dataset_dir / "ground_truth"48+49+async def collect_test_set(self) -> List[Dict[str, Any]]:50+if self.es_host_name:51+return await self._collect_from_es()52+return await self._collect_from_files()53+54+async def _collect_from_es(self) -> List[Dict[str, Any]]:55+if self._inputs_dir.exists() or self._ground_truths_dir.exists():56+raise FileExistsError(57+f"Dataset folder already exists: {self._inputs_dir.parent}. "58+"Choose a different --data-set name or remove the folder manually."59+ )60+61+raw_samples = await es_collect_test_set(62+es_host_name=self.es_host_name,63+es_port=self.es_port,64+endpoint_path=self.ENDPOINT_PATH,65+limit=self.limit,66+language_filter=self.language_filter,67+min_prompt_length=self.min_prompt_length,68+is_json_response=self.IS_JSON_RESPONSE,69+exclude_languages=self.exclude_languages,70+ )71+72+self._inputs_dir.mkdir(parents=True, exist_ok=True)73+self._ground_truths_dir.mkdir(parents=True, exist_ok=True)74+75+min_size = self.MINIMUM_REQUEST_BODY_SIZE76+samples: List[Dict[str, Any]] = []77+skipped_no_response = 078+skipped_too_small = 079+skipped_unreplayable = 080+skipped_probe_errors = 081+82+endpoint_url = f"{self.api_host}/{self.ENDPOINT_PATH}"83+84+timeout = aiohttp.ClientTimeout(total=self.REPLAYABILITY_CHECK_TIMEOUT_SECONDS)85+async with aiohttp.ClientSession(timeout=timeout) as session:86+for sample in raw_samples:87+es_id = sample["id"]88+request_body = sample["request_body"]89+original_response = sample.get("original_response")90+91+if not original_response:92+skipped_no_response += 193+continue94+95+if min_size and len(json.dumps(request_body)) < min_size:96+skipped_too_small += 197+continue98+99+if self.SKIP_UNREPLAYABLE_ON_COLLECT:100+try:101+async with session.post(endpoint_url, json=request_body) as resp:102+if resp.status != 200:103+body_text = await resp.text()104+if "Cannot find activity" in body_text:105+skipped_unreplayable += 1106+continue107+except Exception:108+skipped_probe_errors += 1109+110+with open(self._inputs_dir / f"{es_id}.json", "w") as f:111+json.dump(request_body, f, indent=2)112+113+with open(self._ground_truths_dir / f"gt_{es_id}.json", "w") as f:114+json.dump(original_response, f, indent=2)115+116+samples.append(117+ {118+"id": es_id,119+"request_body": request_body,120+"original_response": original_response,121+"ground_truth": original_response,122+ }123+ )124+125+print(f"Wrote {len(samples)} samples to {self._inputs_dir.parent}")126+if skipped_no_response:127+print(f"Skipped {skipped_no_response} records with no response body")128+if skipped_too_small:129+print(130+f"Skipped {skipped_too_small} records whose request body was smaller "131+f"than {min_size} characters"132+ )133+if skipped_unreplayable:134+print(f"Skipped {skipped_unreplayable} records that are not replayable (missing activity in ES)")135+if skipped_probe_errors:136+print(f"Warning: replayability probe errored for {skipped_probe_errors} records (kept those records)")137+138+if self.__class__.POPULATE_GROUND_TRUTH_LLM:139+label_results = await run_endpoint_http(140+test_set=samples,141+endpoint_url=endpoint_url,142+request_model=self.REQUEST_MODEL,143+force_llm_endpoint=self.__class__.GROUND_TRUTH_LLM_ENDPOINT,144+is_streaming_response=self.IS_STREAMING_RESPONSE,145+timeout_seconds=300.0,146+parallel_requests=self.parallel_requests,147+return_prompt_in_run=self.RETURN_PROMPT_IN_RUN,148+ )149+150+for i, r in enumerate(label_results):151+forced = self.__class__.GROUND_TRUTH_LLM_ENDPOINT152+model = forced.split(":", 1)[1] if ":" in forced else forced153+samples[i]["ground_truth_llm_model"] = model154+155+if not r.get("success", True):156+samples[i]["ground_truth_llm"] = None157+samples[i]["ground_truth_llm_reasoning"] = None158+samples[i]["ground_truth_llm_error_type"] = r.get("error_type")159+samples[i]["ground_truth_llm_error_message"] = r.get("error_message")160+continue161+162+resp = r.get("new_response") or {}163+samples[i]["ground_truth_llm"] = resp.get("ai_activity_type")164+samples[i]["ground_truth_llm_reasoning"] = resp.get("ai_activity_type_reasoning")165+166+return samples167+168+async def _collect_from_files(self) -> List[Dict[str, Any]]:169+if not self._inputs_dir.exists():170+raise FileNotFoundError(171+f"Dataset folder not found: {self._inputs_dir}. "172+"Run --steps collect first or check your --data-set name."173+ )174+175+samples: List[Dict[str, Any]] = []176+for filename in sorted(os.listdir(self._inputs_dir)):177+input_path = self._inputs_dir / filename178+gt_path = self._ground_truths_dir / f"gt_{filename}"179+180+if not gt_path.exists():181+print(f"Warning: ground truth not found for {filename}, skipping")182+continue183+184+with open(input_path, "r") as f:185+request_body: Dict[str, Any] = json.load(f)186+187+with open(gt_path, "r") as f:188+ground_truth: Dict[str, Any] = json.load(f)189+190+samples.append(191+ {192+"id": Path(filename).stem,193+"request_body": request_body,194+"original_response": None,195+"ground_truth": ground_truth,196+ }197+ )198+199+print(f"Loaded {len(samples)} samples from {self._inputs_dir.parent}")200+return samples201+202+async def evaluate_against_ground_truth(self, results: List[Dict[str, Any]]) -> List[EvaluationResult]:203+evaluation_results: List[EvaluationResult] = []204+compare_to = self.__class__.COMPARE_TO_GROUND_TRUTH205+206+for res in results:207+req_id = res["request_id"]208+is_success = res.get("success", True)209+210+if not is_success:211+evaluation_results.append(212+EvaluationResult(213+request_id=req_id,214+request_body=res["request_body"],215+new_response=res.get("new_response"),216+valid_schema=False,217+quality_score=0.0,218+quality_feedback=f"Request failed: {res.get('error_type')} - {res.get('error_message')}",219+response_time=res.get("response_time"),220+success=False,221+error_type=res.get("error_type"),222+error_message=res.get("error_message"),223+ground_truth_match=False,224+ )225+ )226+continue227+228+pred = (res.get("new_response") or {}).get("ai_activity_type")229+230+if compare_to == "llm":231+if "ground_truth_llm" not in res:232+evaluation_results.append(233+EvaluationResult(234+request_id=req_id,235+request_body=res["request_body"],236+new_response=res.get("new_response"),237+valid_schema=res.get("valid_schema", True),238+quality_score=0.0,239+quality_feedback=(240+"Missing ground_truth_llm in run results. Ensure collect step populated it and "241+"endpoints.py passes it through."242+ ),243+response_time=res.get("response_time"),244+success=True,245+ground_truth_match=False,246+ )247+ )248+continue249+gt_label = res.get("ground_truth_llm")250+else:251+gt_path = self._ground_truths_dir / f"gt_{req_id}.json"252+if not gt_path.exists():253+evaluation_results.append(254+EvaluationResult(255+request_id=req_id,256+request_body=res["request_body"],257+new_response=res.get("new_response"),258+valid_schema=res.get("valid_schema", True),259+quality_score=0.0,260+quality_feedback=f"Ground truth file not found: {gt_path}",261+response_time=res.get("response_time"),262+success=True,263+ground_truth_match=False,264+ )265+ )266+continue267+268+with open(gt_path, "r") as f:269+ground_truth_dict: Dict[str, Any] = json.load(f)270+271+gt_label = (ground_truth_dict or {}).get("ai_activity_type")272+273+matched = pred == gt_label274+275+evaluation_results.append(276+EvaluationResult(277+request_id=req_id,278+request_body=res["request_body"],279+new_response=res.get("new_response"),280+valid_schema=res.get("valid_schema", True),281+quality_score=1.0 if matched else 0.0,282+quality_feedback="PASS" if matched else f"FAIL\nExpected: {gt_label}\nGot: {pred}",283+response_time=res.get("response_time"),284+success=True,285+ground_truth_match=matched,286+ )287+ )288+289+return evaluation_results290+291+292+if __name__ == "__main__":293+parser = create_parser(AiActivityTypeEvaluator)294+parser.add_argument(295+"--data-set",296+type=str,297+default="initial",298+dest="data_set",299+help="Dataset folder under eval_output/ai_activity_type/eval_datasets/ (default: initial)",300+ )301+302+parser.add_argument(303+"--populate-ground-truth-llm",304+action="store_true",305+dest="populate_ground_truth_llm",306+ )307+parser.add_argument(308+"--ground-truth-llm-endpoint",309+type=str,310+default="OPENAI:gpt-5_2",311+dest="ground_truth_llm_endpoint",312+ )313+314+parser.add_argument(315+"--compare-to-ground-truth",316+type=str,317+choices=["es", "llm"],318+default="es",319+dest="compare_to_ground_truth",320+ )321+322+args = parser.parse_args()323+AiActivityTypeEvaluator.DATA_SET = args.data_set324+325+AiActivityTypeEvaluator.POPULATE_GROUND_TRUTH_LLM = bool(args.populate_ground_truth_llm)326+AiActivityTypeEvaluator.GROUND_TRUTH_LLM_ENDPOINT = args.ground_truth_llm_endpoint327+328+AiActivityTypeEvaluator.COMPARE_TO_GROUND_TRUTH = args.compare_to_ground_truth329+330+asyncio.run(run_evaluation(AiActivityTypeEvaluator, args))</selection>” selected.
Please summarize the selection using precise and concise language. Use headers and bulleted lists in the summary, to make it scannable. Maintain the meaning and factual accuracy.
Expand
Listen
Show more options
Gemini said
Gemini said
This Python script defines the
AiActivityTypeEvaluator
class, a specialized tool for evaluating AI-driven activity type classification. It extends a base evaluation framework to handle data collection, ground-truth comparison, and performance scoring.
Core Functionality
Core Functionality
Data Collection (
collect_test_set
):
* Supports fetching raw samples from
Elasticsearch (ES)
or loading them from
local JSON files
.
Implements a
replayability check
: It probes the live API endpoint to ensure the activity exists before including it in the dataset.
Filters data based on request body size, language, and the presence of an original response.
Ground Truth Management:
Saves inputs and "gold standard" responses to a local directory structure (
eval_output/ai_activity_type/...
).
Features an optional mode to populate ground truth using a high-order LLM (e.g.,
gpt-5_2
) if the
POPULATE_GROUND_TRUTH_LLM
flag is set.
Evaluation Logic (
evaluate_against_ground_truth
):
Compares the model's predicted
ai_activity_type
against either the original ES response or the LLM-generated ground truth.
Assigns a
quality_score
of
1.0
for a match and
0.0
for a mismatch or request failure.
Key Configuration Constants
Key Configuration Constants
Constant
Purpose
ENDPOINT_PATH
The specific API route being tested:
call/ai-activity-type
.
COMPARE_TO_GROUND_TRUTH
Determines if the baseline is the original data (
es
) or an
llm
.
SKIP_UNREPLAYABLE_ON_COLLECT
If
True
, discards records where the API returns "Cannot find activity."
REPLAYABILITY_CHECK_TIMEOUT_SECONDS
Limits the probe request to 20 seconds.
Constant
ENDPOINT_PATH
COMPARE_TO_GROUND_TRUTH
SKIP_UNREPLAYABLE_ON_COLLECT
REPLAYABILITY_CHECK_TIMEOUT_SECONDS
Purpose
The specific API route being tested:
call/ai-activity-type
.
Determines if the baseline is the original data (
es
) or an
llm
.
If
True
, discards records where the API returns "Cannot find activity."
Limits the probe request to 20 seconds.
Copy table
Execution Workflow
Execution Workflow
Parsing:
The script uses
create_parser
to handle CLI arguments like
--data-set
,
--populate-ground-truth-llm
, and
--compare-to-ground-truth
.
Initialization:
Sets up directory paths for inputs and ground truths based on the selected dataset name.
Run:
Executes the evaluation via
asyncio.run(run_evaluation(...))
, which orchestrates the collection, endpoint calling, and result scoring phases.
Copy prompt
Edit
You said are there soem issues with this PR
You said
are there soem issues with this PR
Show more options
Analyzing Implementation
Gemini said
Gemini said
Enter a prompt for Gemini
encrypted
Enter a prompt for Gemini
encrypted
Open upload file menu
Tools
Open mode picker
Pro
Stop response
Your Jiminny chats aren’t used to improve our models. Gemini is AI and can make mistakes, including about people.
Your privacy & Gemini Opens in a new window
Your privacy & Gemini
Opens in a new window
Summarize page
Summarize page
Skip to content
Skip to content
Open menu
Homepage (g then d)
jiminny
jiminny
prophet
prophet
Search or jump to…
Type
/
to search
Chat with Copilot
Open Copilot…
Create new...
Issues
Pull requests
Repositories
You have unread notifications(g then n)
Open user navigation menu
Repository navigation
Repository navigation
Code
Code
Issues
Issues
Pull requests (6)
Pull requests
(
6
)
Agents...
|
8539
|
|
8543
|
164
|
8
|
2026-04-14T06:51:18.848279+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776149478848_m1.jpg...
|
Firefox
|
Jy 19798 evaluation for ai activity types by nikol Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet — Work...
|
True
|
github.com/jiminny/prophet/pull/468/changes#diff-d github.com/jiminny/prophet/pull/468/changes#diff-d2f9fea9bc428b119ae26a66453e8eab7dd0782d4a4d93075ca5ce05903d77e8...
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
JY-20543 add AJ reports User pilot tracking by Lak JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Close tab
New Tab
Customize sidebar
Close Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
AI Chat settings
Close
WORK, Google Account: [EMAIL]
Main menu
New Chat
Open menu for conversation actions.
Conversation with Gemini
Conversation with Gemini
Copy prompt
You said I’m on page “<tabTitle>Jy 19798 evaluation for ai activity types by nikol</tabTitle>” with “<selection>@@ -0,0 +1,330 @@1+#!/usr/bin/env python32+import asyncio3+import json4+import os5+from pathlib import Path6+from typing import Any, Dict, List7+8+import aiohttp9+10+from src.component.call_processing.schemes.ai_activity_type_request import AiActivityTypeRequest11+from src.component.call_processing.schemes.ai_activity_type_response import AiActivityTypeResponse12+from src.eval.abstract_evaluator import AbstractEvaluator13+from src.eval.collectors import collect_test_set as es_collect_test_set14+from src.eval.common_evaluator_runner import create_parser, run_evaluation15+from src.eval.endpoints import run_endpoint as run_endpoint_http16+from src.eval.models import EvaluationResult17+18+19+class AiActivityTypeEvaluator(AbstractEvaluator):20+ENDPOINT_PATH = "call/ai-activity-type"21+REQUEST_MODEL = AiActivityTypeRequest22+RESPONSE_MODEL = AiActivityTypeResponse23+OUTPUT_SUBFOLDER = "ai_activity_type"24+USES_LLM_EVALUATION = False25+26+READS_FROM_DATASET_FOLDER = True27+28+DATA_SET: str = "initial"29+30+MINIMUM_REQUEST_BODY_SIZE: int = 031+32+SKIP_UNREPLAYABLE_ON_COLLECT: bool = True33+REPLAYABILITY_CHECK_TIMEOUT_SECONDS: float = 20.034+35+POPULATE_GROUND_TRUTH_LLM: bool = False36+GROUND_TRUTH_LLM_ENDPOINT: str = "OPENAI:gpt-5_2"37+38+COMPARE_TO_GROUND_TRUTH: str = "es"39+40+def __init__(self, **kwargs: Any) -> None:41+super().__init__(**kwargs)42+_repo_root = Path(__file__).parents[2]43+_datasets_root = _repo_root / "eval_output" / self.OUTPUT_SUBFOLDER / "eval_datasets"44+_dataset_dir = _datasets_root / self.__class__.DATA_SET45+self._dataset_dir = _dataset_dir46+self._inputs_dir = _dataset_dir / "input"47+self._ground_truths_dir = _dataset_dir / "ground_truth"48+49+async def collect_test_set(self) -> List[Dict[str, Any]]:50+if self.es_host_name:51+return await self._collect_from_es()52+return await self._collect_from_files()53+54+async def _collect_from_es(self) -> List[Dict[str, Any]]:55+if self._inputs_dir.exists() or self._ground_truths_dir.exists():56+raise FileExistsError(57+f"Dataset folder already exists: {self._inputs_dir.parent}. "58+"Choose a different --data-set name or remove the folder manually."59+ )60+61+raw_samples = await es_collect_test_set(62+es_host_name=self.es_host_name,63+es_port=self.es_port,64+endpoint_path=self.ENDPOINT_PATH,65+limit=self.limit,66+language_filter=self.language_filter,67+min_prompt_length=self.min_prompt_length,68+is_json_response=self.IS_JSON_RESPONSE,69+exclude_languages=self.exclude_languages,70+ )71+72+self._inputs_dir.mkdir(parents=True, exist_ok=True)73+self._ground_truths_dir.mkdir(parents=True, exist_ok=True)74+75+min_size = self.MINIMUM_REQUEST_BODY_SIZE76+samples: List[Dict[str, Any]] = []77+skipped_no_response = 078+skipped_too_small = 079+skipped_unreplayable = 080+skipped_probe_errors = 081+82+endpoint_url = f"{self.api_host}/{self.ENDPOINT_PATH}"83+84+timeout = aiohttp.ClientTimeout(total=self.REPLAYABILITY_CHECK_TIMEOUT_SECONDS)85+async with aiohttp.ClientSession(timeout=timeout) as session:86+for sample in raw_samples:87+es_id = sample["id"]88+request_body = sample["request_body"]89+original_response = sample.get("original_response")90+91+if not original_response:92+skipped_no_response += 193+continue94+95+if min_size and len(json.dumps(request_body)) < min_size:96+skipped_too_small += 197+continue98+99+if self.SKIP_UNREPLAYABLE_ON_COLLECT:100+try:101+async with session.post(endpoint_url, json=request_body) as resp:102+if resp.status != 200:103+body_text = await resp.text()104+if "Cannot find activity" in body_text:105+skipped_unreplayable += 1106+continue107+except Exception:108+skipped_probe_errors += 1109+110+with open(self._inputs_dir / f"{es_id}.json", "w") as f:111+json.dump(request_body, f, indent=2)112+113+with open(self._ground_truths_dir / f"gt_{es_id}.json", "w") as f:114+json.dump(original_response, f, indent=2)115+116+samples.append(117+ {118+"id": es_id,119+"request_body": request_body,120+"original_response": original_response,121+"ground_truth": original_response,122+ }123+ )124+125+print(f"Wrote {len(samples)} samples to {self._inputs_dir.parent}")126+if skipped_no_response:127+print(f"Skipped {skipped_no_response} records with no response body")128+if skipped_too_small:129+print(130+f"Skipped {skipped_too_small} records whose request body was smaller "131+f"than {min_size} characters"132+ )133+if skipped_unreplayable:134+print(f"Skipped {skipped_unreplayable} records that are not replayable (missing activity in ES)")135+if skipped_probe_errors:136+print(f"Warning: replayability probe errored for {skipped_probe_errors} records (kept those records)")137+138+if self.__class__.POPULATE_GROUND_TRUTH_LLM:139+label_results = await run_endpoint_http(140+test_set=samples,141+endpoint_url=endpoint_url,142+request_model=self.REQUEST_MODEL,143+force_llm_endpoint=self.__class__.GROUND_TRUTH_LLM_ENDPOINT,144+is_streaming_response=self.IS_STREAMING_RESPONSE,145+timeout_seconds=300.0,146+parallel_requests=self.parallel_requests,147+return_prompt_in_run=self.RETURN_PROMPT_IN_RUN,148+ )149+150+for i, r in enumerate(label_results):151+forced = self.__class__.GROUND_TRUTH_LLM_ENDPOINT152+model = forced.split(":", 1)[1] if ":" in forced else forced153+samples[i]["ground_truth_llm_model"] = model154+155+if not r.get("success", True):156+samples[i]["ground_truth_llm"] = None157+samples[i]["ground_truth_llm_reasoning"] = None158+samples[i]["ground_truth_llm_error_type"] = r.get("error_type")159+samples[i]["ground_truth_llm_error_message"] = r.get("error_message")160+continue161+162+resp = r.get("new_response") or {}163+samples[i]["ground_truth_llm"] = resp.get("ai_activity_type")164+samples[i]["ground_truth_llm_reasoning"] = resp.get("ai_activity_type_reasoning")165+166+return samples167+168+async def _collect_from_files(self) -> List[Dict[str, Any]]:169+if not self._inputs_dir.exists():170+raise FileNotFoundError(171+f"Dataset folder not found: {self._inputs_dir}. "172+"Run --steps collect first or check your --data-set name."173+ )174+175+samples: List[Dict[str, Any]] = []176+for filename in sorted(os.listdir(self._inputs_dir)):177+input_path = self._inputs_dir / filename178+gt_path = self._ground_truths_dir / f"gt_{filename}"179+180+if not gt_path.exists():181+print(f"Warning: ground truth not found for {filename}, skipping")182+continue183+184+with open(input_path, "r") as f:185+request_body: Dict[str, Any] = json.load(f)186+187+with open(gt_path, "r") as f:188+ground_truth: Dict[str, Any] = json.load(f)189+190+samples.append(191+ {192+"id": Path(filename).stem,193+"request_body": request_body,194+"original_response": None,195+"ground_truth": ground_truth,196+ }197+ )198+199+print(f"Loaded {len(samples)} samples from {self._inputs_dir.parent}")200+return samples201+202+async def evaluate_against_ground_truth(self, results: List[Dict[str, Any]]) -> List[EvaluationResult]:203+evaluation_results: List[EvaluationResult] = []204+compare_to = self.__class__.COMPARE_TO_GROUND_TRUTH205+206+for res in results:207+req_id = res["request_id"]208+is_success = res.get("success", True)209+210+if not is_success:211+evaluation_results.append(212+EvaluationResult(213+request_id=req_id,214+request_body=res["request_body"],215+new_response=res.get("new_response"),216+valid_schema=False,217+quality_score=0.0,218+quality_feedback=f"Request failed: {res.get('error_type')} - {res.get('error_message')}",219+response_time=res.get("response_time"),220+success=False,221+error_type=res.get("error_type"),222+error_message=res.get("error_message"),223+ground_truth_match=False,224+ )225+ )226+continue227+228+pred = (res.get("new_response") or {}).get("ai_activity_type")229+230+if compare_to == "llm":231+if "ground_truth_llm" not in res:232+evaluation_results.append(233+EvaluationResult(234+request_id=req_id,235+request_body=res["request_body"],236+new_response=res.get("new_response"),237+valid_schema=res.get("valid_schema", True),238+quality_score=0.0,239+quality_feedback=(240+"Missing ground_truth_llm in run results. Ensure collect step populated it and "241+"endpoints.py passes it through."242+ ),243+response_time=res.get("response_time"),244+success=True,245+ground_truth_match=False,246+ )247+ )248+continue249+gt_label = res.get("ground_truth_llm")250+else:251+gt_path = self._ground_truths_dir / f"gt_{req_id}.json"252+if not gt_path.exists():253+evaluation_results.append(254+EvaluationResult(255+request_id=req_id,256+request_body=res["request_body"],257+new_response=res.get("new_response"),258+valid_schema=res.get("valid_schema", True),259+quality_score=0.0,260+quality_feedback=f"Ground truth file not found: {gt_path}",261+response_time=res.get("response_time"),262+success=True,263+ground_truth_match=False,264+ )265+ )266+continue267+268+with open(gt_path, "r") as f:269+ground_truth_dict: Dict[str, Any] = json.load(f)270+271+gt_label = (ground_truth_dict or {}).get("ai_activity_type")272+273+matched = pred == gt_label274+275+evaluation_results.append(276+EvaluationResult(277+request_id=req_id,278+request_body=res["request_body"],279+new_response=res.get("new_response"),280+valid_schema=res.get("valid_schema", True),281+quality_score=1.0 if matched else 0.0,282+quality_feedback="PASS" if matched else f"FAIL\nExpected: {gt_label}\nGot: {pred}",283+response_time=res.get("response_time"),284+success=True,285+ground_truth_match=matched,286+ )287+ )288+289+return evaluation_results290+291+292+if __name__ == "__main__":293+parser = create_parser(AiActivityTypeEvaluator)294+parser.add_argument(295+"--data-set",296+type=str,297+default="initial",298+dest="data_set",299+help="Dataset folder under eval_output/ai_activity_type/eval_datasets/ (default: initial)",300+ )301+302+parser.add_argument(303+"--populate-ground-truth-llm",304+action="store_true",305+dest="populate_ground_truth_llm",306+ )307+parser.add_argument(308+"--ground-truth-llm-endpoint",309+type=str,310+default="OPENAI:gpt-5_2",311+dest="ground_truth_llm_endpoint",312+ )313+314+parser.add_argument(315+"--compare-to-ground-truth",316+type=str,317+choices=["es", "llm"],318+default="es",319+dest="compare_to_ground_truth",320+ )321+322+args = parser.parse_args()323+AiActivityTypeEvaluator.DATA_SET = args.data_set324+325+AiActivityTypeEvaluator.POPULATE_GROUND_TRUTH_LLM = bool(args.populate_ground_truth_llm)326+AiActivityTypeEvaluator.GROUND_TRUTH_LLM_ENDPOINT = args.ground_truth_llm_endpoint327+328+AiActivityTypeEvaluator.COMPARE_TO_GROUND_TRUTH = args.compare_to_ground_truth329+330+asyncio.run(run_evaluation(AiActivityTypeEvaluator, args))</selection>” selected. Please summarize the selection using precise and concise language. Use headers and bulleted lists in the summary, to make it scannable. Maintain the meaning and factual accuracy.
You said
I’m on page “<tabTitle>Jy 19798 evaluation for ai activity types by nikol</tabTitle>” with “<selection>@@ -0,0 +1,330 @@1+#!/usr/bin/env python32+import asyncio3+import json4+import os5+from pathlib import Path6+from typing import Any, Dict, List7+8+import aiohttp9+10+from src.component.call_processing.schemes.ai_activity_type_request import AiActivityTypeRequest11+from src.component.call_processing.schemes.ai_activity_type_response import AiActivityTypeResponse12+from src.eval.abstract_evaluator import AbstractEvaluator13+from src.eval.collectors import collect_test_set as es_collect_test_set14+from src.eval.common_evaluator_runner import create_parser, run_evaluation15+from src.eval.endpoints import run_endpoint as run_endpoint_http16+from src.eval.models import EvaluationResult17+18+19+class AiActivityTypeEvaluator(AbstractEvaluator):20+ENDPOINT_PATH = "call/ai-activity-type"21+REQUEST_MODEL = AiActivityTypeRequest22+RESPONSE_MODEL = AiActivityTypeResponse23+OUTPUT_SUBFOLDER = "ai_activity_type"24+USES_LLM_EVALUATION = False25+26+READS_FROM_DATASET_FOLDER = True27+28+DATA_SET: str = "initial"29+30+MINIMUM_REQUEST_BODY_SIZE: int = 031+32+SKIP_UNREPLAYABLE_ON_COLLECT: bool = True33+REPLAYABILITY_CHECK_TIMEOUT_SECONDS: float = 20.034+35+POPULATE_GROUND_TRUTH_LLM: bool = False36+GROUND_TRUTH_LLM_ENDPOINT: str = "OPENAI:gpt-5_2"37+38+COMPARE_TO_GROUND_TRUTH: str = "es"39+40+def __init__(self, **kwargs: Any) -> None:41+super().__init__(**kwargs)42+_repo_root = Path(__file__).parents[2]43+_datasets_root = _repo_root / "eval_output" / self.OUTPUT_SUBFOLDER / "eval_datasets"44+_dataset_dir = _datasets_root / self.__class__.DATA_SET45+self._dataset_dir = _dataset_dir46+self._inputs_dir = _dataset_dir / "input"47+self._ground_truths_dir = _dataset_dir / "ground_truth"48+49+async def collect_test_set(self) -> List[Dict[str, Any]]:50+if self.es_host_name:51+return await self._collect_from_es()52+return await self._collect_from_files()53+54+async def _collect_from_es(self) -> List[Dict[str, Any]]:55+if self._inputs_dir.exists() or self._ground_truths_dir.exists():56+raise FileExistsError(57+f"Dataset folder already exists: {self._inputs_dir.parent}. "58+"Choose a different --data-set name or remove the folder manually."59+ )60+61+raw_samples = await es_collect_test_set(62+es_host_name=self.es_host_name,63+es_port=self.es_port,64+endpoint_path=self.ENDPOINT_PATH,65+limit=self.limit,66+language_filter=self.language_filter,67+min_prompt_length=self.min_prompt_length,68+is_json_response=self.IS_JSON_RESPONSE,69+exclude_languages=self.exclude_languages,70+ )71+72+self._inputs_dir.mkdir(parents=True, exist_ok=True)73+self._ground_truths_dir.mkdir(parents=True, exist_ok=True)74+75+min_size = self.MINIMUM_REQUEST_BODY_SIZE76+samples: List[Dict[str, Any]] = []77+skipped_no_response = 078+skipped_too_small = 079+skipped_unreplayable = 080+skipped_probe_errors = 081+82+endpoint_url = f"{self.api_host}/{self.ENDPOINT_PATH}"83+84+timeout = aiohttp.ClientTimeout(total=self.REPLAYABILITY_CHECK_TIMEOUT_SECONDS)85+async with aiohttp.ClientSession(timeout=timeout) as session:86+for sample in raw_samples:87+es_id = sample["id"]88+request_body = sample["request_body"]89+original_response = sample.get("original_response")90+91+if not original_response:92+skipped_no_response += 193+continue94+95+if min_size and len(json.dumps(request_body)) < min_size:96+skipped_too_small += 197+continue98+99+if self.SKIP_UNREPLAYABLE_ON_COLLECT:100+try:101+async with session.post(endpoint_url, json=request_body) as resp:102+if resp.status != 200:103+body_text = await resp.text()104+if "Cannot find activity" in body_text:105+skipped_unreplayable += 1106+continue107+except Exception:108+skipped_probe_errors += 1109+110+with open(self._inputs_dir / f"{es_id}.json", "w") as f:111+json.dump(request_body, f, indent=2)112+113+with open(self._ground_truths_dir / f"gt_{es_id}.json", "w") as f:114+json.dump(original_response, f, indent=2)115+116+samples.append(117+ {118+"id": es_id,119+"request_body": request_body,120+"original_response": original_response,121+"ground_truth": original_response,122+ }123+ )124+125+print(f"Wrote {len(samples)} samples to {self._inputs_dir.parent}")126+if skipped_no_response:127+print(f"Skipped {skipped_no_response} records with no response body")128+if skipped_too_small:129+print(130+f"Skipped {skipped_too_small} records whose request body was smaller "131+f"than {min_size} characters"132+ )133+if skipped_unreplayable:134+print(f"Skipped {skipped_unreplayable} records that are not replayable (missing activity in ES)")135+if skipped_probe_errors:136+print(f"Warning: replayability probe errored for {skipped_probe_errors} records (kept those records)")137+138+if self.__class__.POPULATE_GROUND_TRUTH_LLM:139+label_results = await run_endpoint_http(140+test_set=samples,141+endpoint_url=endpoint_url,142+request_model=self.REQUEST_MODEL,143+force_llm_endpoint=self.__class__.GROUND_TRUTH_LLM_ENDPOINT,144+is_streaming_response=self.IS_STREAMING_RESPONSE,145+timeout_seconds=300.0,146+parallel_requests=self.parallel_requests,147+return_prompt_in_run=self.RETURN_PROMPT_IN_RUN,148+ )149+150+for i, r in enumerate(label_results):151+forced = self.__class__.GROUND_TRUTH_LLM_ENDPOINT152+model = forced.split(":", 1)[1] if ":" in forced else forced153+samples[i]["ground_truth_llm_model"] = model154+155+if not r.get("success", True):156+samples[i]["ground_truth_llm"] = None157+samples[i]["ground_truth_llm_reasoning"] = None158+samples[i]["ground_truth_llm_error_type"] = r.get("error_type")159+samples[i]["ground_truth_llm_error_message"] = r.get("error_message")160+continue161+162+resp = r.get("new_response") or {}163+samples[i]["ground_truth_llm"] = resp.get("ai_activity_type")164+samples[i]["ground_truth_llm_reasoning"] = resp.get("ai_activity_type_reasoning")165+166+return samples167+168+async def _collect_from_files(self) -> List[Dict[str, Any]]:169+if not self._inputs_dir.exists():170+raise FileNotFoundError(171+f"Dataset folder not found: {self._inputs_dir}. "172+"Run --steps collect first or check your --data-set name."173+ )174+175+samples: List[Dict[str, Any]] = []176+for filename in sorted(os.listdir(self._inputs_dir)):177+input_path = self._inputs_dir / filename178+gt_path = self._ground_truths_dir / f"gt_{filename}"179+180+if not gt_path.exists():181+print(f"Warning: ground truth not found for {filename}, skipping")182+continue183+184+with open(input_path, "r") as f:185+request_body: Dict[str, Any] = json.load(f)186+187+with open(gt_path, "r") as f:188+ground_truth: Dict[str, Any] = json.load(f)189+190+samples.append(191+ {192+"id": Path(filename).stem,193+"request_body": request_body,194+"original_response": None,195+"ground_truth": ground_truth,196+ }197+ )198+199+print(f"Loaded {len(samples)} samples from {self._inputs_dir.parent}")200+return samples201+202+async def evaluate_against_ground_truth(self, results: List[Dict[str, Any]]) -> List[EvaluationResult]:203+evaluation_results: List[EvaluationResult] = []204+compare_to = self.__class__.COMPARE_TO_GROUND_TRUTH205+206+for res in results:207+req_id = res["request_id"]208+is_success = res.get("success", True)209+210+if not is_success:211+evaluation_results.append(212+EvaluationResult(213+request_id=req_id,214+request_body=res["request_body"],215+new_response=res.get("new_response"),216+valid_schema=False,217+quality_score=0.0,218+quality_feedback=f"Request failed: {res.get('error_type')} - {res.get('error_message')}",219+response_time=res.get("response_time"),220+success=False,221+error_type=res.get("error_type"),222+error_message=res.get("error_message"),223+ground_truth_match=False,224+ )225+ )226+continue227+228+pred = (res.get("new_response") or {}).get("ai_activity_type")229+230+if compare_to == "llm":231+if "ground_truth_llm" not in res:232+evaluation_results.append(233+EvaluationResult(234+request_id=req_id,235+request_body=res["request_body"],236+new_response=res.get("new_response"),237+valid_schema=res.get("valid_schema", True),238+quality_score=0.0,239+quality_feedback=(240+"Missing ground_truth_llm in run results. Ensure collect step populated it and "241+"endpoints.py passes it through."242+ ),243+response_time=res.get("response_time"),244+success=True,245+ground_truth_match=False,246+ )247+ )248+continue249+gt_label = res.get("ground_truth_llm")250+else:251+gt_path = self._ground_truths_dir / f"gt_{req_id}.json"252+if not gt_path.exists():253+evaluation_results.append(254+EvaluationResult(255+request_id=req_id,256+request_body=res["request_body"],257+new_response=res.get("new_response"),258+valid_schema=res.get("valid_schema", True),259+quality_score=0.0,260+quality_feedback=f"Ground truth file not found: {gt_path}",261+response_time=res.get("response_time"),262+success=True,263+ground_truth_match=False,264+ )265+ )266+continue267+268+with open(gt_path, "r") as f:269+ground_truth_dict: Dict[str, Any] = json.load(f)270+271+gt_label = (ground_truth_dict or {}).get("ai_activity_type")272+273+matched = pred == gt_label274+275+evaluation_results.append(276+EvaluationResult(277+request_id=req_id,278+request_body=res["request_body"],279+new_response=res.get("new_response"),280+valid_schema=res.get("valid_schema", True),281+quality_score=1.0 if matched else 0.0,282+quality_feedback="PASS" if matched else f"FAIL\nExpected: {gt_label}\nGot: {pred}",283+response_time=res.get("response_time"),284+success=True,285+ground_truth_match=matched,286+ )287+ )288+289+return evaluation_results290+291+292+if __name__ == "__main__":293+parser = create_parser(AiActivityTypeEvaluator)294+parser.add_argument(295+"--data-set",296+type=str,297+default="initial",298+dest="data_set",299+help="Dataset folder under eval_output/ai_activity_type/eval_datasets/ (default: initial)",300+ )301+302+parser.add_argument(303+"--populate-ground-truth-llm",304+action="store_true",305+dest="populate_ground_truth_llm",306+ )307+parser.add_argument(308+"--ground-truth-llm-endpoint",309+type=str,310+default="OPENAI:gpt-5_2",311+dest="ground_truth_llm_endpoint",312+ )313+314+parser.add_argument(315+"--compare-to-ground-truth",316+type=str,317+choices=["es", "llm"],318+default="es",319+dest="compare_to_ground_truth",320+ )321+322+args = parser.parse_args()323+AiActivityTypeEvaluator.DATA_SET = args.data_set324+325+AiActivityTypeEvaluator.POPULATE_GROUND_TRUTH_LLM = bool(args.populate_ground_truth_llm)326+AiActivityTypeEvaluator.GROUND_TRUTH_LLM_ENDPOINT = args.ground_truth_llm_endpoint327+328+AiActivityTypeEvaluator.COMPARE_TO_GROUND_TRUTH = args.compare_to_ground_truth329+330+asyncio.run(run_evaluation(AiActivityTypeEvaluator, args))</selection>” selected.
Please summarize the selection using precise and concise language. Use headers and bulleted lists in the summary, to make it scannable. Maintain the meaning and factual accuracy.
Expand
Listen
Show more options
Gemini said
Gemini said
This Python script defines the
AiActivityTypeEvaluator
class, a specialized tool for evaluating AI-driven activity type classification. It extends a base evaluation framework to handle data collection, ground-truth comparison, and performance scoring.
Core Functionality
Core Functionality
Data Collection (
collect_test_set
):
* Supports fetching raw samples from
Elasticsearch (ES)
or loading them from
local JSON files
.
Implements a
replayability check
: It probes the live API endpoint to ensure the activity exists before including it in the dataset.
Filters data based on request body size, language, and the presence of an original response.
Ground Truth Management:
Saves inputs and "gold standard" responses to a local directory structure (
eval_output/ai_activity_type/...
).
Features an optional mode to populate ground truth using a high-order LLM (e.g.,
gpt-5_2
) if the
POPULATE_GROUND_TRUTH_LLM
flag is set.
Evaluation Logic (
evaluate_against_ground_truth
):
Compares the model's predicted
ai_activity_type
against either the original ES response or the LLM-generated ground truth.
Assigns a
quality_score
of
1.0
for a match and
0.0
for a mismatch or request failure.
Key Configuration Constants
Key Configuration Constants
Constant
Purpose
ENDPOINT_PATH
The specific API route being tested:
call/ai-activity-type
.
COMPARE_TO_GROUND_TRUTH
Determines if the baseline is the original data (
es
) or an
llm
.
SKIP_UNREPLAYABLE_ON_COLLECT
If
True
, discards records where the API returns "Cannot find activity."
REPLAYABILITY_CHECK_TIMEOUT_SECONDS
Limits the probe request to 20 seconds.
Constant
ENDPOINT_PATH
COMPARE_TO_GROUND_TRUTH
SKIP_UNREPLAYABLE_ON_COLLECT
REPLAYABILITY_CHECK_TIMEOUT_SECONDS
Purpose
The specific API route being tested:
call/ai-activity-type
.
Determines if the baseline is the original data (
es
) or an
llm
.
If
True
, discards records where the API returns "Cannot find activity."
Limits the probe request to 20 seconds.
Copy table
Execution Workflow
Execution Workflow
Parsing:
The script uses
create_parser
to handle CLI arguments like
--data-set
,
--populate-ground-truth-llm
, and
--compare-to-ground-truth
.
Initialization:
Sets up directory paths for inputs and ground truths based on the selected dataset name.
Run:
Executes the evaluation via
asyncio.run(run_evaluation(...))
, which orchestrates the collection, endpoint calling, and result scoring phases.
Copy prompt
Edit
You said are there soem issues with this PR
You said
are there soem issues with this PR
Show more options
Show thinking
Gemini said
Gemini said
Yes,
there are several issues and code smells in this Pull Request,
ranging from performance bottlenecks to architectural anti-patterns.
Here is a breakdown of the most notable issues,
categorized by impact:
Performance & Async Anti-Patterns
Performance & Async Anti-Patterns
Sequential Requests Defeating Async (Lines 86-106):
Inside
_collect_from_es
,
the code loops through
raw_samples
and
await
s a
session.post
request for each sample one by one.
This means the script waits for one HTTP request to finish before starting the next,
completely defeating the purpose of using
aiohttp
for asynchronous concurrency.
Fix:
Collect these coroutines into a list and use...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Tab","depth":4,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Close Google Gemini (⌃X)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"AI Chat settings","depth":7,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Close","depth":7,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"WORK, Google Account: lukas.kovalik@jiminny.com","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Main menu","depth":12,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Chat","depth":12,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Open menu for conversation actions.","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXHeading","text":"Conversation with Gemini","depth":15,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Conversation with Gemini","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Copy prompt","depth":21,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"You said I’m on page “<tabTitle>Jy 19798 evaluation for ai activity types by nikol</tabTitle>” with “<selection>@@ -0,0 +1,330 @@1+#!/usr/bin/env python32+import asyncio3+import json4+import os5+from pathlib import Path6+from typing import Any, Dict, List7+8+import aiohttp9+10+from src.component.call_processing.schemes.ai_activity_type_request import AiActivityTypeRequest11+from src.component.call_processing.schemes.ai_activity_type_response import AiActivityTypeResponse12+from src.eval.abstract_evaluator import AbstractEvaluator13+from src.eval.collectors import collect_test_set as es_collect_test_set14+from src.eval.common_evaluator_runner import create_parser, run_evaluation15+from src.eval.endpoints import run_endpoint as run_endpoint_http16+from src.eval.models import EvaluationResult17+18+19+class AiActivityTypeEvaluator(AbstractEvaluator):20+ENDPOINT_PATH = "call/ai-activity-type"21+REQUEST_MODEL = AiActivityTypeRequest22+RESPONSE_MODEL = AiActivityTypeResponse23+OUTPUT_SUBFOLDER = "ai_activity_type"24+USES_LLM_EVALUATION = False25+26+READS_FROM_DATASET_FOLDER = True27+28+DATA_SET: str = "initial"29+30+MINIMUM_REQUEST_BODY_SIZE: int = 031+32+SKIP_UNREPLAYABLE_ON_COLLECT: bool = True33+REPLAYABILITY_CHECK_TIMEOUT_SECONDS: float = 20.034+35+POPULATE_GROUND_TRUTH_LLM: bool = False36+GROUND_TRUTH_LLM_ENDPOINT: str = "OPENAI:gpt-5_2"37+38+COMPARE_TO_GROUND_TRUTH: str = "es"39+40+def __init__(self, **kwargs: Any) -> None:41+super().__init__(**kwargs)42+_repo_root = Path(__file__).parents[2]43+_datasets_root = _repo_root / "eval_output" / self.OUTPUT_SUBFOLDER / "eval_datasets"44+_dataset_dir = _datasets_root / self.__class__.DATA_SET45+self._dataset_dir = _dataset_dir46+self._inputs_dir = _dataset_dir / "input"47+self._ground_truths_dir = _dataset_dir / "ground_truth"48+49+async def collect_test_set(self) -> List[Dict[str, Any]]:50+if self.es_host_name:51+return await self._collect_from_es()52+return await self._collect_from_files()53+54+async def _collect_from_es(self) -> List[Dict[str, Any]]:55+if self._inputs_dir.exists() or self._ground_truths_dir.exists():56+raise FileExistsError(57+f"Dataset folder already exists: {self._inputs_dir.parent}. "58+"Choose a different --data-set name or remove the folder manually."59+ )60+61+raw_samples = await es_collect_test_set(62+es_host_name=self.es_host_name,63+es_port=self.es_port,64+endpoint_path=self.ENDPOINT_PATH,65+limit=self.limit,66+language_filter=self.language_filter,67+min_prompt_length=self.min_prompt_length,68+is_json_response=self.IS_JSON_RESPONSE,69+exclude_languages=self.exclude_languages,70+ )71+72+self._inputs_dir.mkdir(parents=True, exist_ok=True)73+self._ground_truths_dir.mkdir(parents=True, exist_ok=True)74+75+min_size = self.MINIMUM_REQUEST_BODY_SIZE76+samples: List[Dict[str, Any]] = []77+skipped_no_response = 078+skipped_too_small = 079+skipped_unreplayable = 080+skipped_probe_errors = 081+82+endpoint_url = f"{self.api_host}/{self.ENDPOINT_PATH}"83+84+timeout = aiohttp.ClientTimeout(total=self.REPLAYABILITY_CHECK_TIMEOUT_SECONDS)85+async with aiohttp.ClientSession(timeout=timeout) as session:86+for sample in raw_samples:87+es_id = sample["id"]88+request_body = sample["request_body"]89+original_response = sample.get("original_response")90+91+if not original_response:92+skipped_no_response += 193+continue94+95+if min_size and len(json.dumps(request_body)) < min_size:96+skipped_too_small += 197+continue98+99+if self.SKIP_UNREPLAYABLE_ON_COLLECT:100+try:101+async with session.post(endpoint_url, json=request_body) as resp:102+if resp.status != 200:103+body_text = await resp.text()104+if "Cannot find activity" in body_text:105+skipped_unreplayable += 1106+continue107+except Exception:108+skipped_probe_errors += 1109+110+with open(self._inputs_dir / f"{es_id}.json", "w") as f:111+json.dump(request_body, f, indent=2)112+113+with open(self._ground_truths_dir / f"gt_{es_id}.json", "w") as f:114+json.dump(original_response, f, indent=2)115+116+samples.append(117+ {118+"id": es_id,119+"request_body": request_body,120+"original_response": original_response,121+"ground_truth": original_response,122+ }123+ )124+125+print(f"Wrote {len(samples)} samples to {self._inputs_dir.parent}")126+if skipped_no_response:127+print(f"Skipped {skipped_no_response} records with no response body")128+if skipped_too_small:129+print(130+f"Skipped {skipped_too_small} records whose request body was smaller "131+f"than {min_size} characters"132+ )133+if skipped_unreplayable:134+print(f"Skipped {skipped_unreplayable} records that are not replayable (missing activity in ES)")135+if skipped_probe_errors:136+print(f"Warning: replayability probe errored for {skipped_probe_errors} records (kept those records)")137+138+if self.__class__.POPULATE_GROUND_TRUTH_LLM:139+label_results = await run_endpoint_http(140+test_set=samples,141+endpoint_url=endpoint_url,142+request_model=self.REQUEST_MODEL,143+force_llm_endpoint=self.__class__.GROUND_TRUTH_LLM_ENDPOINT,144+is_streaming_response=self.IS_STREAMING_RESPONSE,145+timeout_seconds=300.0,146+parallel_requests=self.parallel_requests,147+return_prompt_in_run=self.RETURN_PROMPT_IN_RUN,148+ )149+150+for i, r in enumerate(label_results):151+forced = self.__class__.GROUND_TRUTH_LLM_ENDPOINT152+model = forced.split(":", 1)[1] if ":" in forced else forced153+samples[i]["ground_truth_llm_model"] = model154+155+if not r.get("success", True):156+samples[i]["ground_truth_llm"] = None157+samples[i]["ground_truth_llm_reasoning"] = None158+samples[i]["ground_truth_llm_error_type"] = r.get("error_type")159+samples[i]["ground_truth_llm_error_message"] = r.get("error_message")160+continue161+162+resp = r.get("new_response") or {}163+samples[i]["ground_truth_llm"] = resp.get("ai_activity_type")164+samples[i]["ground_truth_llm_reasoning"] = resp.get("ai_activity_type_reasoning")165+166+return samples167+168+async def _collect_from_files(self) -> List[Dict[str, Any]]:169+if not self._inputs_dir.exists():170+raise FileNotFoundError(171+f"Dataset folder not found: {self._inputs_dir}. "172+"Run --steps collect first or check your --data-set name."173+ )174+175+samples: List[Dict[str, Any]] = []176+for filename in sorted(os.listdir(self._inputs_dir)):177+input_path = self._inputs_dir / filename178+gt_path = self._ground_truths_dir / f"gt_{filename}"179+180+if not gt_path.exists():181+print(f"Warning: ground truth not found for {filename}, skipping")182+continue183+184+with open(input_path, "r") as f:185+request_body: Dict[str, Any] = json.load(f)186+187+with open(gt_path, "r") as f:188+ground_truth: Dict[str, Any] = json.load(f)189+190+samples.append(191+ {192+"id": Path(filename).stem,193+"request_body": request_body,194+"original_response": None,195+"ground_truth": ground_truth,196+ }197+ )198+199+print(f"Loaded {len(samples)} samples from {self._inputs_dir.parent}")200+return samples201+202+async def evaluate_against_ground_truth(self, results: List[Dict[str, Any]]) -> List[EvaluationResult]:203+evaluation_results: List[EvaluationResult] = []204+compare_to = self.__class__.COMPARE_TO_GROUND_TRUTH205+206+for res in results:207+req_id = res["request_id"]208+is_success = res.get("success", True)209+210+if not is_success:211+evaluation_results.append(212+EvaluationResult(213+request_id=req_id,214+request_body=res["request_body"],215+new_response=res.get("new_response"),216+valid_schema=False,217+quality_score=0.0,218+quality_feedback=f"Request failed: {res.get('error_type')} - {res.get('error_message')}",219+response_time=res.get("response_time"),220+success=False,221+error_type=res.get("error_type"),222+error_message=res.get("error_message"),223+ground_truth_match=False,224+ )225+ )226+continue227+228+pred = (res.get("new_response") or {}).get("ai_activity_type")229+230+if compare_to == "llm":231+if "ground_truth_llm" not in res:232+evaluation_results.append(233+EvaluationResult(234+request_id=req_id,235+request_body=res["request_body"],236+new_response=res.get("new_response"),237+valid_schema=res.get("valid_schema", True),238+quality_score=0.0,239+quality_feedback=(240+"Missing ground_truth_llm in run results. Ensure collect step populated it and "241+"endpoints.py passes it through."242+ ),243+response_time=res.get("response_time"),244+success=True,245+ground_truth_match=False,246+ )247+ )248+continue249+gt_label = res.get("ground_truth_llm")250+else:251+gt_path = self._ground_truths_dir / f"gt_{req_id}.json"252+if not gt_path.exists():253+evaluation_results.append(254+EvaluationResult(255+request_id=req_id,256+request_body=res["request_body"],257+new_response=res.get("new_response"),258+valid_schema=res.get("valid_schema", True),259+quality_score=0.0,260+quality_feedback=f"Ground truth file not found: {gt_path}",261+response_time=res.get("response_time"),262+success=True,263+ground_truth_match=False,264+ )265+ )266+continue267+268+with open(gt_path, "r") as f:269+ground_truth_dict: Dict[str, Any] = json.load(f)270+271+gt_label = (ground_truth_dict or {}).get("ai_activity_type")272+273+matched = pred == gt_label274+275+evaluation_results.append(276+EvaluationResult(277+request_id=req_id,278+request_body=res["request_body"],279+new_response=res.get("new_response"),280+valid_schema=res.get("valid_schema", True),281+quality_score=1.0 if matched else 0.0,282+quality_feedback="PASS" if matched else f"FAIL\\nExpected: {gt_label}\\nGot: {pred}",283+response_time=res.get("response_time"),284+success=True,285+ground_truth_match=matched,286+ )287+ )288+289+return evaluation_results290+291+292+if __name__ == "__main__":293+parser = create_parser(AiActivityTypeEvaluator)294+parser.add_argument(295+"--data-set",296+type=str,297+default="initial",298+dest="data_set",299+help="Dataset folder under eval_output/ai_activity_type/eval_datasets/ (default: initial)",300+ )301+302+parser.add_argument(303+"--populate-ground-truth-llm",304+action="store_true",305+dest="populate_ground_truth_llm",306+ )307+parser.add_argument(308+"--ground-truth-llm-endpoint",309+type=str,310+default="OPENAI:gpt-5_2",311+dest="ground_truth_llm_endpoint",312+ )313+314+parser.add_argument(315+"--compare-to-ground-truth",316+type=str,317+choices=["es", "llm"],318+default="es",319+dest="compare_to_ground_truth",320+ )321+322+args = parser.parse_args()323+AiActivityTypeEvaluator.DATA_SET = args.data_set324+325+AiActivityTypeEvaluator.POPULATE_GROUND_TRUTH_LLM = bool(args.populate_ground_truth_llm)326+AiActivityTypeEvaluator.GROUND_TRUTH_LLM_ENDPOINT = args.ground_truth_llm_endpoint327+328+AiActivityTypeEvaluator.COMPARE_TO_GROUND_TRUTH = args.compare_to_ground_truth329+330+asyncio.run(run_evaluation(AiActivityTypeEvaluator, args))</selection>” selected. Please summarize the selection using precise and concise language. Use headers and bulleted lists in the summary, to make it scannable. Maintain the meaning and factual accuracy.","depth":21,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"You said","depth":23,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"I’m on page “<tabTitle>Jy 19798 evaluation for ai activity types by nikol</tabTitle>” with “<selection>@@ -0,0 +1,330 @@1+#!/usr/bin/env python32+import asyncio3+import json4+import os5+from pathlib import Path6+from typing import Any, Dict, List7+8+import aiohttp9+10+from src.component.call_processing.schemes.ai_activity_type_request import AiActivityTypeRequest11+from src.component.call_processing.schemes.ai_activity_type_response import AiActivityTypeResponse12+from src.eval.abstract_evaluator import AbstractEvaluator13+from src.eval.collectors import collect_test_set as es_collect_test_set14+from src.eval.common_evaluator_runner import create_parser, run_evaluation15+from src.eval.endpoints import run_endpoint as run_endpoint_http16+from src.eval.models import EvaluationResult17+18+19+class AiActivityTypeEvaluator(AbstractEvaluator):20+ENDPOINT_PATH = "call/ai-activity-type"21+REQUEST_MODEL = AiActivityTypeRequest22+RESPONSE_MODEL = AiActivityTypeResponse23+OUTPUT_SUBFOLDER = "ai_activity_type"24+USES_LLM_EVALUATION = False25+26+READS_FROM_DATASET_FOLDER = True27+28+DATA_SET: str = "initial"29+30+MINIMUM_REQUEST_BODY_SIZE: int = 031+32+SKIP_UNREPLAYABLE_ON_COLLECT: bool = True33+REPLAYABILITY_CHECK_TIMEOUT_SECONDS: float = 20.034+35+POPULATE_GROUND_TRUTH_LLM: bool = False36+GROUND_TRUTH_LLM_ENDPOINT: str = "OPENAI:gpt-5_2"37+38+COMPARE_TO_GROUND_TRUTH: str = "es"39+40+def __init__(self, **kwargs: Any) -> None:41+super().__init__(**kwargs)42+_repo_root = Path(__file__).parents[2]43+_datasets_root = _repo_root / "eval_output" / self.OUTPUT_SUBFOLDER / "eval_datasets"44+_dataset_dir = _datasets_root / self.__class__.DATA_SET45+self._dataset_dir = _dataset_dir46+self._inputs_dir = _dataset_dir / "input"47+self._ground_truths_dir = _dataset_dir / "ground_truth"48+49+async def collect_test_set(self) -> List[Dict[str, Any]]:50+if self.es_host_name:51+return await self._collect_from_es()52+return await self._collect_from_files()53+54+async def _collect_from_es(self) -> List[Dict[str, Any]]:55+if self._inputs_dir.exists() or self._ground_truths_dir.exists():56+raise FileExistsError(57+f"Dataset folder already exists: {self._inputs_dir.parent}. "58+"Choose a different --data-set name or remove the folder manually."59+ )60+61+raw_samples = await es_collect_test_set(62+es_host_name=self.es_host_name,63+es_port=self.es_port,64+endpoint_path=self.ENDPOINT_PATH,65+limit=self.limit,66+language_filter=self.language_filter,67+min_prompt_length=self.min_prompt_length,68+is_json_response=self.IS_JSON_RESPONSE,69+exclude_languages=self.exclude_languages,70+ )71+72+self._inputs_dir.mkdir(parents=True, exist_ok=True)73+self._ground_truths_dir.mkdir(parents=True, exist_ok=True)74+75+min_size = self.MINIMUM_REQUEST_BODY_SIZE76+samples: List[Dict[str, Any]] = []77+skipped_no_response = 078+skipped_too_small = 079+skipped_unreplayable = 080+skipped_probe_errors = 081+82+endpoint_url = f"{self.api_host}/{self.ENDPOINT_PATH}"83+84+timeout = aiohttp.ClientTimeout(total=self.REPLAYABILITY_CHECK_TIMEOUT_SECONDS)85+async with aiohttp.ClientSession(timeout=timeout) as session:86+for sample in raw_samples:87+es_id = sample["id"]88+request_body = sample["request_body"]89+original_response = sample.get("original_response")90+91+if not original_response:92+skipped_no_response += 193+continue94+95+if min_size and len(json.dumps(request_body)) < min_size:96+skipped_too_small += 197+continue98+99+if self.SKIP_UNREPLAYABLE_ON_COLLECT:100+try:101+async with session.post(endpoint_url, json=request_body) as resp:102+if resp.status != 200:103+body_text = await resp.text()104+if "Cannot find activity" in body_text:105+skipped_unreplayable += 1106+continue107+except Exception:108+skipped_probe_errors += 1109+110+with open(self._inputs_dir / f"{es_id}.json", "w") as f:111+json.dump(request_body, f, indent=2)112+113+with open(self._ground_truths_dir / f"gt_{es_id}.json", "w") as f:114+json.dump(original_response, f, indent=2)115+116+samples.append(117+ {118+"id": es_id,119+"request_body": request_body,120+"original_response": original_response,121+"ground_truth": original_response,122+ }123+ )124+125+print(f"Wrote {len(samples)} samples to {self._inputs_dir.parent}")126+if skipped_no_response:127+print(f"Skipped {skipped_no_response} records with no response body")128+if skipped_too_small:129+print(130+f"Skipped {skipped_too_small} records whose request body was smaller "131+f"than {min_size} characters"132+ )133+if skipped_unreplayable:134+print(f"Skipped {skipped_unreplayable} records that are not replayable (missing activity in ES)")135+if skipped_probe_errors:136+print(f"Warning: replayability probe errored for {skipped_probe_errors} records (kept those records)")137+138+if self.__class__.POPULATE_GROUND_TRUTH_LLM:139+label_results = await run_endpoint_http(140+test_set=samples,141+endpoint_url=endpoint_url,142+request_model=self.REQUEST_MODEL,143+force_llm_endpoint=self.__class__.GROUND_TRUTH_LLM_ENDPOINT,144+is_streaming_response=self.IS_STREAMING_RESPONSE,145+timeout_seconds=300.0,146+parallel_requests=self.parallel_requests,147+return_prompt_in_run=self.RETURN_PROMPT_IN_RUN,148+ )149+150+for i, r in enumerate(label_results):151+forced = self.__class__.GROUND_TRUTH_LLM_ENDPOINT152+model = forced.split(":", 1)[1] if ":" in forced else forced153+samples[i]["ground_truth_llm_model"] = model154+155+if not r.get("success", True):156+samples[i]["ground_truth_llm"] = None157+samples[i]["ground_truth_llm_reasoning"] = None158+samples[i]["ground_truth_llm_error_type"] = r.get("error_type")159+samples[i]["ground_truth_llm_error_message"] = r.get("error_message")160+continue161+162+resp = r.get("new_response") or {}163+samples[i]["ground_truth_llm"] = resp.get("ai_activity_type")164+samples[i]["ground_truth_llm_reasoning"] = resp.get("ai_activity_type_reasoning")165+166+return samples167+168+async def _collect_from_files(self) -> List[Dict[str, Any]]:169+if not self._inputs_dir.exists():170+raise FileNotFoundError(171+f"Dataset folder not found: {self._inputs_dir}. "172+"Run --steps collect first or check your --data-set name."173+ )174+175+samples: List[Dict[str, Any]] = []176+for filename in sorted(os.listdir(self._inputs_dir)):177+input_path = self._inputs_dir / filename178+gt_path = self._ground_truths_dir / f"gt_{filename}"179+180+if not gt_path.exists():181+print(f"Warning: ground truth not found for {filename}, skipping")182+continue183+184+with open(input_path, "r") as f:185+request_body: Dict[str, Any] = json.load(f)186+187+with open(gt_path, "r") as f:188+ground_truth: Dict[str, Any] = json.load(f)189+190+samples.append(191+ {192+"id": Path(filename).stem,193+"request_body": request_body,194+"original_response": None,195+"ground_truth": ground_truth,196+ }197+ )198+199+print(f"Loaded {len(samples)} samples from {self._inputs_dir.parent}")200+return samples201+202+async def evaluate_against_ground_truth(self, results: List[Dict[str, Any]]) -> List[EvaluationResult]:203+evaluation_results: List[EvaluationResult] = []204+compare_to = self.__class__.COMPARE_TO_GROUND_TRUTH205+206+for res in results:207+req_id = res["request_id"]208+is_success = res.get("success", True)209+210+if not is_success:211+evaluation_results.append(212+EvaluationResult(213+request_id=req_id,214+request_body=res["request_body"],215+new_response=res.get("new_response"),216+valid_schema=False,217+quality_score=0.0,218+quality_feedback=f"Request failed: {res.get('error_type')} - {res.get('error_message')}",219+response_time=res.get("response_time"),220+success=False,221+error_type=res.get("error_type"),222+error_message=res.get("error_message"),223+ground_truth_match=False,224+ )225+ )226+continue227+228+pred = (res.get("new_response") or {}).get("ai_activity_type")229+230+if compare_to == "llm":231+if "ground_truth_llm" not in res:232+evaluation_results.append(233+EvaluationResult(234+request_id=req_id,235+request_body=res["request_body"],236+new_response=res.get("new_response"),237+valid_schema=res.get("valid_schema", True),238+quality_score=0.0,239+quality_feedback=(240+"Missing ground_truth_llm in run results. Ensure collect step populated it and "241+"endpoints.py passes it through."242+ ),243+response_time=res.get("response_time"),244+success=True,245+ground_truth_match=False,246+ )247+ )248+continue249+gt_label = res.get("ground_truth_llm")250+else:251+gt_path = self._ground_truths_dir / f"gt_{req_id}.json"252+if not gt_path.exists():253+evaluation_results.append(254+EvaluationResult(255+request_id=req_id,256+request_body=res["request_body"],257+new_response=res.get("new_response"),258+valid_schema=res.get("valid_schema", True),259+quality_score=0.0,260+quality_feedback=f"Ground truth file not found: {gt_path}",261+response_time=res.get("response_time"),262+success=True,263+ground_truth_match=False,264+ )265+ )266+continue267+268+with open(gt_path, "r") as f:269+ground_truth_dict: Dict[str, Any] = json.load(f)270+271+gt_label = (ground_truth_dict or {}).get("ai_activity_type")272+273+matched = pred == gt_label274+275+evaluation_results.append(276+EvaluationResult(277+request_id=req_id,278+request_body=res["request_body"],279+new_response=res.get("new_response"),280+valid_schema=res.get("valid_schema", True),281+quality_score=1.0 if matched else 0.0,282+quality_feedback="PASS" if matched else f"FAIL\\nExpected: {gt_label}\\nGot: {pred}",283+response_time=res.get("response_time"),284+success=True,285+ground_truth_match=matched,286+ )287+ )288+289+return evaluation_results290+291+292+if __name__ == "__main__":293+parser = create_parser(AiActivityTypeEvaluator)294+parser.add_argument(295+"--data-set",296+type=str,297+default="initial",298+dest="data_set",299+help="Dataset folder under eval_output/ai_activity_type/eval_datasets/ (default: initial)",300+ )301+302+parser.add_argument(303+"--populate-ground-truth-llm",304+action="store_true",305+dest="populate_ground_truth_llm",306+ )307+parser.add_argument(308+"--ground-truth-llm-endpoint",309+type=str,310+default="OPENAI:gpt-5_2",311+dest="ground_truth_llm_endpoint",312+ )313+314+parser.add_argument(315+"--compare-to-ground-truth",316+type=str,317+choices=["es", "llm"],318+default="es",319+dest="compare_to_ground_truth",320+ )321+322+args = parser.parse_args()323+AiActivityTypeEvaluator.DATA_SET = args.data_set324+325+AiActivityTypeEvaluator.POPULATE_GROUND_TRUTH_LLM = bool(args.populate_ground_truth_llm)326+AiActivityTypeEvaluator.GROUND_TRUTH_LLM_ENDPOINT = args.ground_truth_llm_endpoint327+328+AiActivityTypeEvaluator.COMPARE_TO_GROUND_TRUTH = args.compare_to_ground_truth329+330+asyncio.run(run_evaluation(AiActivityTypeEvaluator, args))</selection>” selected.","depth":23,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Please summarize the selection using precise and concise language. Use headers and bulleted lists in the summary, to make it scannable. Maintain the meaning and factual accuracy.","depth":23,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Expand","depth":21,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Listen","depth":22,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Show more options","depth":20,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Gemini said","depth":20,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Gemini said","depth":21,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"This Python script defines the","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"AiActivityTypeEvaluator","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"class, a specialized tool for evaluating AI-driven activity type classification. It extends a base evaluation framework to handle data collection, ground-truth comparison, and performance scoring.","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Core Functionality","depth":23,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Core Functionality","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Data Collection (","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"collect_test_set","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"):","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"* Supports fetching raw samples from","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Elasticsearch (ES)","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"or loading them from","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"local JSON files","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Implements a","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"replayability check","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":": It probes the live API endpoint to ensure the activity exists before including it in the dataset.","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Filters data based on request body size, language, and the presence of an original response.","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Ground Truth Management:","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Saves inputs and \"gold standard\" responses to a local directory structure (","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"eval_output/ai_activity_type/...","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":").","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Features an optional mode to populate ground truth using a high-order LLM (e.g.,","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"gpt-5_2","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":") if the","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"POPULATE_GROUND_TRUTH_LLM","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"flag is set.","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Evaluation Logic (","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"evaluate_against_ground_truth","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"):","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Compares the model's predicted","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ai_activity_type","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"against either the original ES response or the LLM-generated ground truth.","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Assigns a","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"quality_score","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"of","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1.0","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"for a match and","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.0","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"for a mismatch or request failure.","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Key Configuration Constants","depth":23,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Key Configuration Constants","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Constant","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Purpose","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ENDPOINT_PATH","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"The specific API route being tested:","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"call/ai-activity-type","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"COMPARE_TO_GROUND_TRUTH","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Determines if the baseline is the original data (","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"es","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":") or an","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"llm","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"SKIP_UNREPLAYABLE_ON_COLLECT","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"If","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"True","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":", discards records where the API returns \"Cannot find activity.\"","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"REPLAYABILITY_CHECK_TIMEOUT_SECONDS","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Limits the probe request to 20 seconds.","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Constant","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ENDPOINT_PATH","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"COMPARE_TO_GROUND_TRUTH","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"SKIP_UNREPLAYABLE_ON_COLLECT","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"REPLAYABILITY_CHECK_TIMEOUT_SECONDS","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Purpose","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"The specific API route being tested:","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"call/ai-activity-type","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Determines if the baseline is the original data (","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"es","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":") or an","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"llm","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"If","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"True","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":", discards records where the API returns \"Cannot find activity.\"","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Limits the probe request to 20 seconds.","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Copy table","depth":24,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Execution Workflow","depth":23,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Execution Workflow","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Parsing:","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"The script uses","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"create_parser","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"to handle CLI arguments like","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"--data-set","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":",","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"--populate-ground-truth-llm","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":", and","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"--compare-to-ground-truth","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Initialization:","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Sets up directory paths for inputs and ground truths based on the selected dataset name.","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Run:","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Executes the evaluation via","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"asyncio.run(run_evaluation(...))","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":", which orchestrates the collection, endpoint calling, and result scoring phases.","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Copy prompt","depth":21,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Edit","depth":21,"role_description":"button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"You said are there soem issues with this PR","depth":21,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"You said","depth":23,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"are there soem issues with this PR","depth":23,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Show more options","depth":20,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Show thinking","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Gemini said","depth":20,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Gemini said","depth":21,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Yes,","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"there are several issues and code smells in this Pull Request,","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ranging from performance bottlenecks to architectural anti-patterns.","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Here is a breakdown of the most notable issues,","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"categorized by impact:","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Performance & Async Anti-Patterns","depth":23,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Performance & Async Anti-Patterns","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Sequential Requests Defeating Async (Lines 86-106):","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Inside","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"_collect_from_es","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":",","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"the code loops through","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"raw_samples","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"and","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"await","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"s a","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"session.post","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"request for each sample one by one.","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"This means the script waits for one HTTP request to finish before starting the next,","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"completely defeating the purpose of using","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"aiohttp","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"for asynchronous concurrency.","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Fix:","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Collect these coroutines into a list and use","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
4108366247784106262
|
8731758625087598999
|
idle
|
accessibility
|
NULL
|
JY-20543 add AJ reports User pilot tracking by Lak JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Close tab
New Tab
Customize sidebar
Close Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
AI Chat settings
Close
WORK, Google Account: [EMAIL]
Main menu
New Chat
Open menu for conversation actions.
Conversation with Gemini
Conversation with Gemini
Copy prompt
You said I’m on page “<tabTitle>Jy 19798 evaluation for ai activity types by nikol</tabTitle>” with “<selection>@@ -0,0 +1,330 @@1+#!/usr/bin/env python32+import asyncio3+import json4+import os5+from pathlib import Path6+from typing import Any, Dict, List7+8+import aiohttp9+10+from src.component.call_processing.schemes.ai_activity_type_request import AiActivityTypeRequest11+from src.component.call_processing.schemes.ai_activity_type_response import AiActivityTypeResponse12+from src.eval.abstract_evaluator import AbstractEvaluator13+from src.eval.collectors import collect_test_set as es_collect_test_set14+from src.eval.common_evaluator_runner import create_parser, run_evaluation15+from src.eval.endpoints import run_endpoint as run_endpoint_http16+from src.eval.models import EvaluationResult17+18+19+class AiActivityTypeEvaluator(AbstractEvaluator):20+ENDPOINT_PATH = "call/ai-activity-type"21+REQUEST_MODEL = AiActivityTypeRequest22+RESPONSE_MODEL = AiActivityTypeResponse23+OUTPUT_SUBFOLDER = "ai_activity_type"24+USES_LLM_EVALUATION = False25+26+READS_FROM_DATASET_FOLDER = True27+28+DATA_SET: str = "initial"29+30+MINIMUM_REQUEST_BODY_SIZE: int = 031+32+SKIP_UNREPLAYABLE_ON_COLLECT: bool = True33+REPLAYABILITY_CHECK_TIMEOUT_SECONDS: float = 20.034+35+POPULATE_GROUND_TRUTH_LLM: bool = False36+GROUND_TRUTH_LLM_ENDPOINT: str = "OPENAI:gpt-5_2"37+38+COMPARE_TO_GROUND_TRUTH: str = "es"39+40+def __init__(self, **kwargs: Any) -> None:41+super().__init__(**kwargs)42+_repo_root = Path(__file__).parents[2]43+_datasets_root = _repo_root / "eval_output" / self.OUTPUT_SUBFOLDER / "eval_datasets"44+_dataset_dir = _datasets_root / self.__class__.DATA_SET45+self._dataset_dir = _dataset_dir46+self._inputs_dir = _dataset_dir / "input"47+self._ground_truths_dir = _dataset_dir / "ground_truth"48+49+async def collect_test_set(self) -> List[Dict[str, Any]]:50+if self.es_host_name:51+return await self._collect_from_es()52+return await self._collect_from_files()53+54+async def _collect_from_es(self) -> List[Dict[str, Any]]:55+if self._inputs_dir.exists() or self._ground_truths_dir.exists():56+raise FileExistsError(57+f"Dataset folder already exists: {self._inputs_dir.parent}. "58+"Choose a different --data-set name or remove the folder manually."59+ )60+61+raw_samples = await es_collect_test_set(62+es_host_name=self.es_host_name,63+es_port=self.es_port,64+endpoint_path=self.ENDPOINT_PATH,65+limit=self.limit,66+language_filter=self.language_filter,67+min_prompt_length=self.min_prompt_length,68+is_json_response=self.IS_JSON_RESPONSE,69+exclude_languages=self.exclude_languages,70+ )71+72+self._inputs_dir.mkdir(parents=True, exist_ok=True)73+self._ground_truths_dir.mkdir(parents=True, exist_ok=True)74+75+min_size = self.MINIMUM_REQUEST_BODY_SIZE76+samples: List[Dict[str, Any]] = []77+skipped_no_response = 078+skipped_too_small = 079+skipped_unreplayable = 080+skipped_probe_errors = 081+82+endpoint_url = f"{self.api_host}/{self.ENDPOINT_PATH}"83+84+timeout = aiohttp.ClientTimeout(total=self.REPLAYABILITY_CHECK_TIMEOUT_SECONDS)85+async with aiohttp.ClientSession(timeout=timeout) as session:86+for sample in raw_samples:87+es_id = sample["id"]88+request_body = sample["request_body"]89+original_response = sample.get("original_response")90+91+if not original_response:92+skipped_no_response += 193+continue94+95+if min_size and len(json.dumps(request_body)) < min_size:96+skipped_too_small += 197+continue98+99+if self.SKIP_UNREPLAYABLE_ON_COLLECT:100+try:101+async with session.post(endpoint_url, json=request_body) as resp:102+if resp.status != 200:103+body_text = await resp.text()104+if "Cannot find activity" in body_text:105+skipped_unreplayable += 1106+continue107+except Exception:108+skipped_probe_errors += 1109+110+with open(self._inputs_dir / f"{es_id}.json", "w") as f:111+json.dump(request_body, f, indent=2)112+113+with open(self._ground_truths_dir / f"gt_{es_id}.json", "w") as f:114+json.dump(original_response, f, indent=2)115+116+samples.append(117+ {118+"id": es_id,119+"request_body": request_body,120+"original_response": original_response,121+"ground_truth": original_response,122+ }123+ )124+125+print(f"Wrote {len(samples)} samples to {self._inputs_dir.parent}")126+if skipped_no_response:127+print(f"Skipped {skipped_no_response} records with no response body")128+if skipped_too_small:129+print(130+f"Skipped {skipped_too_small} records whose request body was smaller "131+f"than {min_size} characters"132+ )133+if skipped_unreplayable:134+print(f"Skipped {skipped_unreplayable} records that are not replayable (missing activity in ES)")135+if skipped_probe_errors:136+print(f"Warning: replayability probe errored for {skipped_probe_errors} records (kept those records)")137+138+if self.__class__.POPULATE_GROUND_TRUTH_LLM:139+label_results = await run_endpoint_http(140+test_set=samples,141+endpoint_url=endpoint_url,142+request_model=self.REQUEST_MODEL,143+force_llm_endpoint=self.__class__.GROUND_TRUTH_LLM_ENDPOINT,144+is_streaming_response=self.IS_STREAMING_RESPONSE,145+timeout_seconds=300.0,146+parallel_requests=self.parallel_requests,147+return_prompt_in_run=self.RETURN_PROMPT_IN_RUN,148+ )149+150+for i, r in enumerate(label_results):151+forced = self.__class__.GROUND_TRUTH_LLM_ENDPOINT152+model = forced.split(":", 1)[1] if ":" in forced else forced153+samples[i]["ground_truth_llm_model"] = model154+155+if not r.get("success", True):156+samples[i]["ground_truth_llm"] = None157+samples[i]["ground_truth_llm_reasoning"] = None158+samples[i]["ground_truth_llm_error_type"] = r.get("error_type")159+samples[i]["ground_truth_llm_error_message"] = r.get("error_message")160+continue161+162+resp = r.get("new_response") or {}163+samples[i]["ground_truth_llm"] = resp.get("ai_activity_type")164+samples[i]["ground_truth_llm_reasoning"] = resp.get("ai_activity_type_reasoning")165+166+return samples167+168+async def _collect_from_files(self) -> List[Dict[str, Any]]:169+if not self._inputs_dir.exists():170+raise FileNotFoundError(171+f"Dataset folder not found: {self._inputs_dir}. "172+"Run --steps collect first or check your --data-set name."173+ )174+175+samples: List[Dict[str, Any]] = []176+for filename in sorted(os.listdir(self._inputs_dir)):177+input_path = self._inputs_dir / filename178+gt_path = self._ground_truths_dir / f"gt_{filename}"179+180+if not gt_path.exists():181+print(f"Warning: ground truth not found for {filename}, skipping")182+continue183+184+with open(input_path, "r") as f:185+request_body: Dict[str, Any] = json.load(f)186+187+with open(gt_path, "r") as f:188+ground_truth: Dict[str, Any] = json.load(f)189+190+samples.append(191+ {192+"id": Path(filename).stem,193+"request_body": request_body,194+"original_response": None,195+"ground_truth": ground_truth,196+ }197+ )198+199+print(f"Loaded {len(samples)} samples from {self._inputs_dir.parent}")200+return samples201+202+async def evaluate_against_ground_truth(self, results: List[Dict[str, Any]]) -> List[EvaluationResult]:203+evaluation_results: List[EvaluationResult] = []204+compare_to = self.__class__.COMPARE_TO_GROUND_TRUTH205+206+for res in results:207+req_id = res["request_id"]208+is_success = res.get("success", True)209+210+if not is_success:211+evaluation_results.append(212+EvaluationResult(213+request_id=req_id,214+request_body=res["request_body"],215+new_response=res.get("new_response"),216+valid_schema=False,217+quality_score=0.0,218+quality_feedback=f"Request failed: {res.get('error_type')} - {res.get('error_message')}",219+response_time=res.get("response_time"),220+success=False,221+error_type=res.get("error_type"),222+error_message=res.get("error_message"),223+ground_truth_match=False,224+ )225+ )226+continue227+228+pred = (res.get("new_response") or {}).get("ai_activity_type")229+230+if compare_to == "llm":231+if "ground_truth_llm" not in res:232+evaluation_results.append(233+EvaluationResult(234+request_id=req_id,235+request_body=res["request_body"],236+new_response=res.get("new_response"),237+valid_schema=res.get("valid_schema", True),238+quality_score=0.0,239+quality_feedback=(240+"Missing ground_truth_llm in run results. Ensure collect step populated it and "241+"endpoints.py passes it through."242+ ),243+response_time=res.get("response_time"),244+success=True,245+ground_truth_match=False,246+ )247+ )248+continue249+gt_label = res.get("ground_truth_llm")250+else:251+gt_path = self._ground_truths_dir / f"gt_{req_id}.json"252+if not gt_path.exists():253+evaluation_results.append(254+EvaluationResult(255+request_id=req_id,256+request_body=res["request_body"],257+new_response=res.get("new_response"),258+valid_schema=res.get("valid_schema", True),259+quality_score=0.0,260+quality_feedback=f"Ground truth file not found: {gt_path}",261+response_time=res.get("response_time"),262+success=True,263+ground_truth_match=False,264+ )265+ )266+continue267+268+with open(gt_path, "r") as f:269+ground_truth_dict: Dict[str, Any] = json.load(f)270+271+gt_label = (ground_truth_dict or {}).get("ai_activity_type")272+273+matched = pred == gt_label274+275+evaluation_results.append(276+EvaluationResult(277+request_id=req_id,278+request_body=res["request_body"],279+new_response=res.get("new_response"),280+valid_schema=res.get("valid_schema", True),281+quality_score=1.0 if matched else 0.0,282+quality_feedback="PASS" if matched else f"FAIL\nExpected: {gt_label}\nGot: {pred}",283+response_time=res.get("response_time"),284+success=True,285+ground_truth_match=matched,286+ )287+ )288+289+return evaluation_results290+291+292+if __name__ == "__main__":293+parser = create_parser(AiActivityTypeEvaluator)294+parser.add_argument(295+"--data-set",296+type=str,297+default="initial",298+dest="data_set",299+help="Dataset folder under eval_output/ai_activity_type/eval_datasets/ (default: initial)",300+ )301+302+parser.add_argument(303+"--populate-ground-truth-llm",304+action="store_true",305+dest="populate_ground_truth_llm",306+ )307+parser.add_argument(308+"--ground-truth-llm-endpoint",309+type=str,310+default="OPENAI:gpt-5_2",311+dest="ground_truth_llm_endpoint",312+ )313+314+parser.add_argument(315+"--compare-to-ground-truth",316+type=str,317+choices=["es", "llm"],318+default="es",319+dest="compare_to_ground_truth",320+ )321+322+args = parser.parse_args()323+AiActivityTypeEvaluator.DATA_SET = args.data_set324+325+AiActivityTypeEvaluator.POPULATE_GROUND_TRUTH_LLM = bool(args.populate_ground_truth_llm)326+AiActivityTypeEvaluator.GROUND_TRUTH_LLM_ENDPOINT = args.ground_truth_llm_endpoint327+328+AiActivityTypeEvaluator.COMPARE_TO_GROUND_TRUTH = args.compare_to_ground_truth329+330+asyncio.run(run_evaluation(AiActivityTypeEvaluator, args))</selection>” selected. Please summarize the selection using precise and concise language. Use headers and bulleted lists in the summary, to make it scannable. Maintain the meaning and factual accuracy.
You said
I’m on page “<tabTitle>Jy 19798 evaluation for ai activity types by nikol</tabTitle>” with “<selection>@@ -0,0 +1,330 @@1+#!/usr/bin/env python32+import asyncio3+import json4+import os5+from pathlib import Path6+from typing import Any, Dict, List7+8+import aiohttp9+10+from src.component.call_processing.schemes.ai_activity_type_request import AiActivityTypeRequest11+from src.component.call_processing.schemes.ai_activity_type_response import AiActivityTypeResponse12+from src.eval.abstract_evaluator import AbstractEvaluator13+from src.eval.collectors import collect_test_set as es_collect_test_set14+from src.eval.common_evaluator_runner import create_parser, run_evaluation15+from src.eval.endpoints import run_endpoint as run_endpoint_http16+from src.eval.models import EvaluationResult17+18+19+class AiActivityTypeEvaluator(AbstractEvaluator):20+ENDPOINT_PATH = "call/ai-activity-type"21+REQUEST_MODEL = AiActivityTypeRequest22+RESPONSE_MODEL = AiActivityTypeResponse23+OUTPUT_SUBFOLDER = "ai_activity_type"24+USES_LLM_EVALUATION = False25+26+READS_FROM_DATASET_FOLDER = True27+28+DATA_SET: str = "initial"29+30+MINIMUM_REQUEST_BODY_SIZE: int = 031+32+SKIP_UNREPLAYABLE_ON_COLLECT: bool = True33+REPLAYABILITY_CHECK_TIMEOUT_SECONDS: float = 20.034+35+POPULATE_GROUND_TRUTH_LLM: bool = False36+GROUND_TRUTH_LLM_ENDPOINT: str = "OPENAI:gpt-5_2"37+38+COMPARE_TO_GROUND_TRUTH: str = "es"39+40+def __init__(self, **kwargs: Any) -> None:41+super().__init__(**kwargs)42+_repo_root = Path(__file__).parents[2]43+_datasets_root = _repo_root / "eval_output" / self.OUTPUT_SUBFOLDER / "eval_datasets"44+_dataset_dir = _datasets_root / self.__class__.DATA_SET45+self._dataset_dir = _dataset_dir46+self._inputs_dir = _dataset_dir / "input"47+self._ground_truths_dir = _dataset_dir / "ground_truth"48+49+async def collect_test_set(self) -> List[Dict[str, Any]]:50+if self.es_host_name:51+return await self._collect_from_es()52+return await self._collect_from_files()53+54+async def _collect_from_es(self) -> List[Dict[str, Any]]:55+if self._inputs_dir.exists() or self._ground_truths_dir.exists():56+raise FileExistsError(57+f"Dataset folder already exists: {self._inputs_dir.parent}. "58+"Choose a different --data-set name or remove the folder manually."59+ )60+61+raw_samples = await es_collect_test_set(62+es_host_name=self.es_host_name,63+es_port=self.es_port,64+endpoint_path=self.ENDPOINT_PATH,65+limit=self.limit,66+language_filter=self.language_filter,67+min_prompt_length=self.min_prompt_length,68+is_json_response=self.IS_JSON_RESPONSE,69+exclude_languages=self.exclude_languages,70+ )71+72+self._inputs_dir.mkdir(parents=True, exist_ok=True)73+self._ground_truths_dir.mkdir(parents=True, exist_ok=True)74+75+min_size = self.MINIMUM_REQUEST_BODY_SIZE76+samples: List[Dict[str, Any]] = []77+skipped_no_response = 078+skipped_too_small = 079+skipped_unreplayable = 080+skipped_probe_errors = 081+82+endpoint_url = f"{self.api_host}/{self.ENDPOINT_PATH}"83+84+timeout = aiohttp.ClientTimeout(total=self.REPLAYABILITY_CHECK_TIMEOUT_SECONDS)85+async with aiohttp.ClientSession(timeout=timeout) as session:86+for sample in raw_samples:87+es_id = sample["id"]88+request_body = sample["request_body"]89+original_response = sample.get("original_response")90+91+if not original_response:92+skipped_no_response += 193+continue94+95+if min_size and len(json.dumps(request_body)) < min_size:96+skipped_too_small += 197+continue98+99+if self.SKIP_UNREPLAYABLE_ON_COLLECT:100+try:101+async with session.post(endpoint_url, json=request_body) as resp:102+if resp.status != 200:103+body_text = await resp.text()104+if "Cannot find activity" in body_text:105+skipped_unreplayable += 1106+continue107+except Exception:108+skipped_probe_errors += 1109+110+with open(self._inputs_dir / f"{es_id}.json", "w") as f:111+json.dump(request_body, f, indent=2)112+113+with open(self._ground_truths_dir / f"gt_{es_id}.json", "w") as f:114+json.dump(original_response, f, indent=2)115+116+samples.append(117+ {118+"id": es_id,119+"request_body": request_body,120+"original_response": original_response,121+"ground_truth": original_response,122+ }123+ )124+125+print(f"Wrote {len(samples)} samples to {self._inputs_dir.parent}")126+if skipped_no_response:127+print(f"Skipped {skipped_no_response} records with no response body")128+if skipped_too_small:129+print(130+f"Skipped {skipped_too_small} records whose request body was smaller "131+f"than {min_size} characters"132+ )133+if skipped_unreplayable:134+print(f"Skipped {skipped_unreplayable} records that are not replayable (missing activity in ES)")135+if skipped_probe_errors:136+print(f"Warning: replayability probe errored for {skipped_probe_errors} records (kept those records)")137+138+if self.__class__.POPULATE_GROUND_TRUTH_LLM:139+label_results = await run_endpoint_http(140+test_set=samples,141+endpoint_url=endpoint_url,142+request_model=self.REQUEST_MODEL,143+force_llm_endpoint=self.__class__.GROUND_TRUTH_LLM_ENDPOINT,144+is_streaming_response=self.IS_STREAMING_RESPONSE,145+timeout_seconds=300.0,146+parallel_requests=self.parallel_requests,147+return_prompt_in_run=self.RETURN_PROMPT_IN_RUN,148+ )149+150+for i, r in enumerate(label_results):151+forced = self.__class__.GROUND_TRUTH_LLM_ENDPOINT152+model = forced.split(":", 1)[1] if ":" in forced else forced153+samples[i]["ground_truth_llm_model"] = model154+155+if not r.get("success", True):156+samples[i]["ground_truth_llm"] = None157+samples[i]["ground_truth_llm_reasoning"] = None158+samples[i]["ground_truth_llm_error_type"] = r.get("error_type")159+samples[i]["ground_truth_llm_error_message"] = r.get("error_message")160+continue161+162+resp = r.get("new_response") or {}163+samples[i]["ground_truth_llm"] = resp.get("ai_activity_type")164+samples[i]["ground_truth_llm_reasoning"] = resp.get("ai_activity_type_reasoning")165+166+return samples167+168+async def _collect_from_files(self) -> List[Dict[str, Any]]:169+if not self._inputs_dir.exists():170+raise FileNotFoundError(171+f"Dataset folder not found: {self._inputs_dir}. "172+"Run --steps collect first or check your --data-set name."173+ )174+175+samples: List[Dict[str, Any]] = []176+for filename in sorted(os.listdir(self._inputs_dir)):177+input_path = self._inputs_dir / filename178+gt_path = self._ground_truths_dir / f"gt_{filename}"179+180+if not gt_path.exists():181+print(f"Warning: ground truth not found for {filename}, skipping")182+continue183+184+with open(input_path, "r") as f:185+request_body: Dict[str, Any] = json.load(f)186+187+with open(gt_path, "r") as f:188+ground_truth: Dict[str, Any] = json.load(f)189+190+samples.append(191+ {192+"id": Path(filename).stem,193+"request_body": request_body,194+"original_response": None,195+"ground_truth": ground_truth,196+ }197+ )198+199+print(f"Loaded {len(samples)} samples from {self._inputs_dir.parent}")200+return samples201+202+async def evaluate_against_ground_truth(self, results: List[Dict[str, Any]]) -> List[EvaluationResult]:203+evaluation_results: List[EvaluationResult] = []204+compare_to = self.__class__.COMPARE_TO_GROUND_TRUTH205+206+for res in results:207+req_id = res["request_id"]208+is_success = res.get("success", True)209+210+if not is_success:211+evaluation_results.append(212+EvaluationResult(213+request_id=req_id,214+request_body=res["request_body"],215+new_response=res.get("new_response"),216+valid_schema=False,217+quality_score=0.0,218+quality_feedback=f"Request failed: {res.get('error_type')} - {res.get('error_message')}",219+response_time=res.get("response_time"),220+success=False,221+error_type=res.get("error_type"),222+error_message=res.get("error_message"),223+ground_truth_match=False,224+ )225+ )226+continue227+228+pred = (res.get("new_response") or {}).get("ai_activity_type")229+230+if compare_to == "llm":231+if "ground_truth_llm" not in res:232+evaluation_results.append(233+EvaluationResult(234+request_id=req_id,235+request_body=res["request_body"],236+new_response=res.get("new_response"),237+valid_schema=res.get("valid_schema", True),238+quality_score=0.0,239+quality_feedback=(240+"Missing ground_truth_llm in run results. Ensure collect step populated it and "241+"endpoints.py passes it through."242+ ),243+response_time=res.get("response_time"),244+success=True,245+ground_truth_match=False,246+ )247+ )248+continue249+gt_label = res.get("ground_truth_llm")250+else:251+gt_path = self._ground_truths_dir / f"gt_{req_id}.json"252+if not gt_path.exists():253+evaluation_results.append(254+EvaluationResult(255+request_id=req_id,256+request_body=res["request_body"],257+new_response=res.get("new_response"),258+valid_schema=res.get("valid_schema", True),259+quality_score=0.0,260+quality_feedback=f"Ground truth file not found: {gt_path}",261+response_time=res.get("response_time"),262+success=True,263+ground_truth_match=False,264+ )265+ )266+continue267+268+with open(gt_path, "r") as f:269+ground_truth_dict: Dict[str, Any] = json.load(f)270+271+gt_label = (ground_truth_dict or {}).get("ai_activity_type")272+273+matched = pred == gt_label274+275+evaluation_results.append(276+EvaluationResult(277+request_id=req_id,278+request_body=res["request_body"],279+new_response=res.get("new_response"),280+valid_schema=res.get("valid_schema", True),281+quality_score=1.0 if matched else 0.0,282+quality_feedback="PASS" if matched else f"FAIL\nExpected: {gt_label}\nGot: {pred}",283+response_time=res.get("response_time"),284+success=True,285+ground_truth_match=matched,286+ )287+ )288+289+return evaluation_results290+291+292+if __name__ == "__main__":293+parser = create_parser(AiActivityTypeEvaluator)294+parser.add_argument(295+"--data-set",296+type=str,297+default="initial",298+dest="data_set",299+help="Dataset folder under eval_output/ai_activity_type/eval_datasets/ (default: initial)",300+ )301+302+parser.add_argument(303+"--populate-ground-truth-llm",304+action="store_true",305+dest="populate_ground_truth_llm",306+ )307+parser.add_argument(308+"--ground-truth-llm-endpoint",309+type=str,310+default="OPENAI:gpt-5_2",311+dest="ground_truth_llm_endpoint",312+ )313+314+parser.add_argument(315+"--compare-to-ground-truth",316+type=str,317+choices=["es", "llm"],318+default="es",319+dest="compare_to_ground_truth",320+ )321+322+args = parser.parse_args()323+AiActivityTypeEvaluator.DATA_SET = args.data_set324+325+AiActivityTypeEvaluator.POPULATE_GROUND_TRUTH_LLM = bool(args.populate_ground_truth_llm)326+AiActivityTypeEvaluator.GROUND_TRUTH_LLM_ENDPOINT = args.ground_truth_llm_endpoint327+328+AiActivityTypeEvaluator.COMPARE_TO_GROUND_TRUTH = args.compare_to_ground_truth329+330+asyncio.run(run_evaluation(AiActivityTypeEvaluator, args))</selection>” selected.
Please summarize the selection using precise and concise language. Use headers and bulleted lists in the summary, to make it scannable. Maintain the meaning and factual accuracy.
Expand
Listen
Show more options
Gemini said
Gemini said
This Python script defines the
AiActivityTypeEvaluator
class, a specialized tool for evaluating AI-driven activity type classification. It extends a base evaluation framework to handle data collection, ground-truth comparison, and performance scoring.
Core Functionality
Core Functionality
Data Collection (
collect_test_set
):
* Supports fetching raw samples from
Elasticsearch (ES)
or loading them from
local JSON files
.
Implements a
replayability check
: It probes the live API endpoint to ensure the activity exists before including it in the dataset.
Filters data based on request body size, language, and the presence of an original response.
Ground Truth Management:
Saves inputs and "gold standard" responses to a local directory structure (
eval_output/ai_activity_type/...
).
Features an optional mode to populate ground truth using a high-order LLM (e.g.,
gpt-5_2
) if the
POPULATE_GROUND_TRUTH_LLM
flag is set.
Evaluation Logic (
evaluate_against_ground_truth
):
Compares the model's predicted
ai_activity_type
against either the original ES response or the LLM-generated ground truth.
Assigns a
quality_score
of
1.0
for a match and
0.0
for a mismatch or request failure.
Key Configuration Constants
Key Configuration Constants
Constant
Purpose
ENDPOINT_PATH
The specific API route being tested:
call/ai-activity-type
.
COMPARE_TO_GROUND_TRUTH
Determines if the baseline is the original data (
es
) or an
llm
.
SKIP_UNREPLAYABLE_ON_COLLECT
If
True
, discards records where the API returns "Cannot find activity."
REPLAYABILITY_CHECK_TIMEOUT_SECONDS
Limits the probe request to 20 seconds.
Constant
ENDPOINT_PATH
COMPARE_TO_GROUND_TRUTH
SKIP_UNREPLAYABLE_ON_COLLECT
REPLAYABILITY_CHECK_TIMEOUT_SECONDS
Purpose
The specific API route being tested:
call/ai-activity-type
.
Determines if the baseline is the original data (
es
) or an
llm
.
If
True
, discards records where the API returns "Cannot find activity."
Limits the probe request to 20 seconds.
Copy table
Execution Workflow
Execution Workflow
Parsing:
The script uses
create_parser
to handle CLI arguments like
--data-set
,
--populate-ground-truth-llm
, and
--compare-to-ground-truth
.
Initialization:
Sets up directory paths for inputs and ground truths based on the selected dataset name.
Run:
Executes the evaluation via
asyncio.run(run_evaluation(...))
, which orchestrates the collection, endpoint calling, and result scoring phases.
Copy prompt
Edit
You said are there soem issues with this PR
You said
are there soem issues with this PR
Show more options
Show thinking
Gemini said
Gemini said
Yes,
there are several issues and code smells in this Pull Request,
ranging from performance bottlenecks to architectural anti-patterns.
Here is a breakdown of the most notable issues,
categorized by impact:
Performance & Async Anti-Patterns
Performance & Async Anti-Patterns
Sequential Requests Defeating Async (Lines 86-106):
Inside
_collect_from_es
,
the code loops through
raw_samples
and
await
s a
session.post
request for each sample one by one.
This means the script waits for one HTTP request to finish before starting the next,
completely defeating the purpose of using
aiohttp
for asynchronous concurrency.
Fix:
Collect these coroutines into a list and use...
|
NULL
|
|
8593
|
166
|
0
|
2026-04-14T06:55:10.956179+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776149710956_m1.jpg...
|
Firefox
|
Jiminny — Work
|
True
|
app.staging.jiminny.com
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
JY-20543 add AJ reports User pilot tracking by Lak JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Jiminny
Jiminny
Close tab
New Tab
Customize sidebar
Close Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
AI Chat settings
Close
WORK, Google Account: [EMAIL]
Main menu
New Chat
Open menu for conversation actions.
Conversation with Gemini
Conversation with Gemini
Copy prompt
You said I’m on page “<tabTitle>Jy 19798 evaluation for ai activity types by nikol</tabTitle>” with “<selection>@@ -0,0 +1,330 @@1+#!/usr/bin/env python32+import asyncio3+import json4+import os5+from pathlib import Path6+from typing import Any, Dict, List7+8+import aiohttp9+10+from src.component.call_processing.schemes.ai_activity_type_request import AiActivityTypeRequest11+from src.component.call_processing.schemes.ai_activity_type_response import AiActivityTypeResponse12+from src.eval.abstract_evaluator import AbstractEvaluator13+from src.eval.collectors import collect_test_set as es_collect_test_set14+from src.eval.common_evaluator_runner import create_parser, run_evaluation15+from src.eval.endpoints import run_endpoint as run_endpoint_http16+from src.eval.models import EvaluationResult17+18+19+class AiActivityTypeEvaluator(AbstractEvaluator):20+ENDPOINT_PATH = "call/ai-activity-type"21+REQUEST_MODEL = AiActivityTypeRequest22+RESPONSE_MODEL = AiActivityTypeResponse23+OUTPUT_SUBFOLDER = "ai_activity_type"24+USES_LLM_EVALUATION = False25+26+READS_FROM_DATASET_FOLDER = True27+28+DATA_SET: str = "initial"29+30+MINIMUM_REQUEST_BODY_SIZE: int = 031+32+SKIP_UNREPLAYABLE_ON_COLLECT: bool = True33+REPLAYABILITY_CHECK_TIMEOUT_SECONDS: float = 20.034+35+POPULATE_GROUND_TRUTH_LLM: bool = False36+GROUND_TRUTH_LLM_ENDPOINT: str = "OPENAI:gpt-5_2"37+38+COMPARE_TO_GROUND_TRUTH: str = "es"39+40+def __init__(self, **kwargs: Any) -> None:41+super().__init__(**kwargs)42+_repo_root = Path(__file__).parents[2]43+_datasets_root = _repo_root / "eval_output" / self.OUTPUT_SUBFOLDER / "eval_datasets"44+_dataset_dir = _datasets_root / self.__class__.DATA_SET45+self._dataset_dir = _dataset_dir46+self._inputs_dir = _dataset_dir / "input"47+self._ground_truths_dir = _dataset_dir / "ground_truth"48+49+async def collect_test_set(self) -> List[Dict[str, Any]]:50+if self.es_host_name:51+return await self._collect_from_es()52+return await self._collect_from_files()53+54+async def _collect_from_es(self) -> List[Dict[str, Any]]:55+if self._inputs_dir.exists() or self._ground_truths_dir.exists():56+raise FileExistsError(57+f"Dataset folder already exists: {self._inputs_dir.parent}. "58+"Choose a different --data-set name or remove the folder manually."59+ )60+61+raw_samples = await es_collect_test_set(62+es_host_name=self.es_host_name,63+es_port=self.es_port,64+endpoint_path=self.ENDPOINT_PATH,65+limit=self.limit,66+language_filter=self.language_filter,67+min_prompt_length=self.min_prompt_length,68+is_json_response=self.IS_JSON_RESPONSE,69+exclude_languages=self.exclude_languages,70+ )71+72+self._inputs_dir.mkdir(parents=True, exist_ok=True)73+self._ground_truths_dir.mkdir(parents=True, exist_ok=True)74+75+min_size = self.MINIMUM_REQUEST_BODY_SIZE76+samples: List[Dict[str, Any]] = []77+skipped_no_response = 078+skipped_too_small = 079+skipped_unreplayable = 080+skipped_probe_errors = 081+82+endpoint_url = f"{self.api_host}/{self.ENDPOINT_PATH}"83+84+timeout = aiohttp.ClientTimeout(total=self.REPLAYABILITY_CHECK_TIMEOUT_SECONDS)85+async with aiohttp.ClientSession(timeout=timeout) as session:86+for sample in raw_samples:87+es_id = sample["id"]88+request_body = sample["request_body"]89+original_response = sample.get("original_response")90+91+if not original_response:92+skipped_no_response += 193+continue94+95+if min_size and len(json.dumps(request_body)) < min_size:96+skipped_too_small += 197+continue98+99+if self.SKIP_UNREPLAYABLE_ON_COLLECT:100+try:101+async with session.post(endpoint_url, json=request_body) as resp:102+if resp.status != 200:103+body_text = await resp.text()104+if "Cannot find activity" in body_text:105+skipped_unreplayable += 1106+continue107+except Exception:108+skipped_probe_errors += 1109+110+with open(self._inputs_dir / f"{es_id}.json", "w") as f:111+json.dump(request_body, f, indent=2)112+113+with open(self._ground_truths_dir / f"gt_{es_id}.json", "w") as f:114+json.dump(original_response, f, indent=2)115+116+samples.append(117+ {118+"id": es_id,119+"request_body": request_body,120+"original_response": original_response,121+"ground_truth": original_response,122+ }123+ )124+125+print(f"Wrote {len(samples)} samples to {self._inputs_dir.parent}")126+if skipped_no_response:127+print(f"Skipped {skipped_no_response} records with no response body")128+if skipped_too_small:129+print(130+f"Skipped {skipped_too_small} records whose request body was smaller "131+f"than {min_size} characters"132+ )133+if skipped_unreplayable:134+print(f"Skipped {skipped_unreplayable} records that are not replayable (missing activity in ES)")135+if skipped_probe_errors:136+print(f"Warning: replayability probe errored for {skipped_probe_errors} records (kept those records)")137+138+if self.__class__.POPULATE_GROUND_TRUTH_LLM:139+label_results = await run_endpoint_http(140+test_set=samples,141+endpoint_url=endpoint_url,142+request_model=self.REQUEST_MODEL,143+force_llm_endpoint=self.__class__.GROUND_TRUTH_LLM_ENDPOINT,144+is_streaming_response=self.IS_STREAMING_RESPONSE,145+timeout_seconds=300.0,146+parallel_requests=self.parallel_requests,147+return_prompt_in_run=self.RETURN_PROMPT_IN_RUN,148+ )149+150+for i, r in enumerate(label_results):151+forced = self.__class__.GROUND_TRUTH_LLM_ENDPOINT152+model = forced.split(":", 1)[1] if ":" in forced else forced153+samples[i]["ground_truth_llm_model"] = model154+155+if not r.get("success", True):156+samples[i]["ground_truth_llm"] = None157+samples[i]["ground_truth_llm_reasoning"] = None158+samples[i]["ground_truth_llm_error_type"] = r.get("error_type")159+samples[i]["ground_truth_llm_error_message"] = r.get("error_message")160+continue161+162+resp = r.get("new_response") or {}163+samples[i]["ground_truth_llm"] = resp.get("ai_activity_type")164+samples[i]["ground_truth_llm_reasoning"] = resp.get("ai_activity_type_reasoning")165+166+return samples167+168+async def _collect_from_files(self) -> List[Dict[str, Any]]:169+if not self._inputs_dir.exists():170+raise FileNotFoundError(171+f"Dataset folder not found: {self._inputs_dir}. "172+"Run --steps collect first or check your --data-set name."173+ )174+175+samples: List[Dict[str, Any]] = []176+for filename in sorted(os.listdir(self._inputs_dir)):177+input_path = self._inputs_dir / filename178+gt_path = self._ground_truths_dir / f"gt_{filename}"179+180+if not gt_path.exists():181+print(f"Warning: ground truth not found for {filename}, skipping")182+continue183+184+with open(input_path, "r") as f:185+request_body: Dict[str, Any] = json.load(f)186+187+with open(gt_path, "r") as f:188+ground_truth: Dict[str, Any] = json.load(f)189+190+samples.append(191+ {192+"id": Path(filename).stem,193+"request_body": request_body,194+"original_response": None,195+"ground_truth": ground_truth,196+ }197+ )198+199+print(f"Loaded {len(samples)} samples from {self._inputs_dir.parent}")200+return samples201+202+async def evaluate_against_ground_truth(self, results: List[Dict[str, Any]]) -> List[EvaluationResult]:203+evaluation_results: List[EvaluationResult] = []204+compare_to = self.__class__.COMPARE_TO_GROUND_TRUTH205+206+for res in results:207+req_id = res["request_id"]208+is_success = res.get("success", True)209+210+if not is_success:211+evaluation_results.append(212+EvaluationResult(213+request_id=req_id,214+request_body=res["request_body"],215+new_response=res.get("new_response"),216+valid_schema=False,217+quality_score=0.0,218+quality_feedback=f"Request failed: {res.get('error_type')} - {res.get('error_message')}",219+response_time=res.get("response_time"),220+success=False,221+error_type=res.get("error_type"),222+error_message=res.get("error_message"),223+ground_truth_match=False,224+ )225+ )226+continue227+228+pred = (res.get("new_response") or {}).get("ai_activity_type")229+230+if compare_to == "llm":231+if "ground_truth_llm" not in res:232+evaluation_results.append(233+EvaluationResult(234+request_id=req_id,235+request_body=res["request_body"],236+new_response=res.get("new_response"),237+valid_schema=res.get("valid_schema", True),238+quality_score=0.0,239+quality_feedback=(240+"Missing ground_truth_llm in run results. Ensure collect step populated it and "241+"endpoints.py passes it through."242+ ),243+response_time=res.get("response_time"),244+success=True,245+ground_truth_match=False,246+ )247+ )248+continue249+gt_label = res.get("ground_truth_llm")250+else:251+gt_path = self._ground_truths_dir / f"gt_{req_id}.json"252+if not gt_path.exists():253+evaluation_results.append(254+EvaluationResult(255+request_id=req_id,256+request_body=res["request_body"],257+new_response=res.get("new_response"),258+valid_schema=res.get("valid_schema", True),259+quality_score=0.0,260+quality_feedback=f"Ground truth file not found: {gt_path}",261+response_time=res.get("response_time"),262+success=True,263+ground_truth_match=False,264+ )265+ )266+continue267+268+with open(gt_path, "r") as f:269+ground_truth_dict: Dict[str, Any] = json.load(f)270+271+gt_label = (ground_truth_dict or {}).get("ai_activity_type")272+273+matched = pred == gt_label274+275+evaluation_results.append(276+EvaluationResult(277+request_id=req_id,278+request_body=res["request_body"],279+new_response=res.get("new_response"),280+valid_schema=res.get("valid_schema", True),281+quality_score=1.0 if matched else 0.0,282+quality_feedback="PASS" if matched else f"FAIL\nExpected: {gt_label}\nGot: {pred}",283+response_time=res.get("response_time"),284+success=True,285+ground_truth_match=matched,286+ )287+ )288+289+return evaluation_results290+291+292+if __name__ == "__main__":293+parser = create_parser(AiActivityTypeEvaluator)294+parser.add_argument(295+"--data-set",296+type=str,297+default="initial",298+dest="data_set",299+help="Dataset folder under eval_output/ai_activity_type/eval_datasets/ (default: initial)",300+ )301+302+parser.add_argument(303+"--populate-ground-truth-llm",304+action="store_true",305+dest="populate_ground_truth_llm",306+ )307+parser.add_argument(308+"--ground-truth-llm-endpoint",309+type=str,310+default="OPENAI:gpt-5_2",311+dest="ground_truth_llm_endpoint",312+ )313+314+parser.add_argument(315+"--compare-to-ground-truth",316+type=str,317+choices=["es", "llm"],318+default="es",319+dest="compare_to_ground_truth",320+ )321+322+args = parser.parse_args()323+AiActivityTypeEvaluator.DATA_SET = args.data_set324+325+AiActivityTypeEvaluator.POPULATE_GROUND_TRUTH_LLM = bool(args.populate_ground_truth_llm)326+AiActivityTypeEvaluator.GROUND_TRUTH_LLM_ENDPOINT = args.ground_truth_llm_endpoint327+328+AiActivityTypeEvaluator.COMPARE_TO_GROUND_TRUTH = args.compare_to_ground_truth329+330+asyncio.run(run_evaluation(AiActivityTypeEvaluator, args))</selection>” selected. Please summarize the selection using precise and concise language. Use headers and bulleted lists in the summary, to make it scannable. Maintain the meaning and factual accuracy.
You said
I’m on page “<tabTitle>Jy 19798 evaluation for ai activity types by nikol</tabTitle>” with “<selection>@@ -0,0 +1,330 @@1+#!/usr/bin/env python32+import asyncio3+import json4+import os5+from pathlib import Path6+from typing import Any, Dict, List7+8+import aiohttp9+10+from src.component.call_processing.schemes.ai_activity_type_request import AiActivityTypeRequest11+from src.component.call_processing.schemes.ai_activity_type_response import AiActivityTypeResponse12+from src.eval.abstract_evaluator import AbstractEvaluator13+from src.eval.collectors import collect_test_set as es_collect_test_set14+from src.eval.common_evaluator_runner import create_parser, run_evaluation15+from src.eval.endpoints import run_endpoint as run_endpoint_http16+from src.eval.models import EvaluationResult17+18+19+class AiActivityTypeEvaluator(AbstractEvaluator):20+ENDPOINT_PATH = "call/ai-activity-type"21+REQUEST_MODEL = AiActivityTypeRequest22+RESPONSE_MODEL = AiActivityTypeResponse23+OUTPUT_SUBFOLDER = "ai_activity_type"24+USES_LLM_EVALUATION = False25+26+READS_FROM_DATASET_FOLDER = True27+28+DATA_SET: str = "initial"29+30+MINIMUM_REQUEST_BODY_SIZE: int = 031+32+SKIP_UNREPLAYABLE_ON_COLLECT: bool = True33+REPLAYABILITY_CHECK_TIMEOUT_SECONDS: float = 20.034+35+POPULATE_GROUND_TRUTH_LLM: bool = False36+GROUND_TRUTH_LLM_ENDPOINT: str = "OPENAI:gpt-5_2"37+38+COMPARE_TO_GROUND_TRUTH: str = "es"39+40+def __init__(self, **kwargs: Any) -> None:41+super().__init__(**kwargs)42+_repo_root = Path(__file__).parents[2]43+_datasets_root = _repo_root / "eval_output" / self.OUTPUT_SUBFOLDER / "eval_datasets"44+_dataset_dir = _datasets_root / self.__class__.DATA_SET45+self._dataset_dir = _dataset_dir46+self._inputs_dir = _dataset_dir / "input"47+self._ground_truths_dir = _dataset_dir / "ground_truth"48+49+async def collect_test_set(self) -> List[Dict[str, Any]]:50+if self.es_host_name:51+return await self._collect_from_es()52+return await self._collect_from_files()53+54+async def _collect_from_es(self) -> List[Dict[str, Any]]:55+if self._inputs_dir.exists() or self._ground_truths_dir.exists():56+raise FileExistsError(57+f"Dataset folder already exists: {self._inputs_dir.parent}. "58+"Choose a different --data-set name or remove the folder manually."59+ )60+61+raw_samples = await es_collect_test_set(62+es_host_name=self.es_host_name,63+es_port=self.es_port,64+endpoint_path=self.ENDPOINT_PATH,65+limit=self.limit,66+language_filter=self.language_filter,67+min_prompt_length=self.min_prompt_length,68+is_json_response=self.IS_JSON_RESPONSE,69+exclude_languages=self.exclude_languages,70+ )71+72+self._inputs_dir.mkdir(parents=True, exist_ok=True)73+self._ground_truths_dir.mkdir(parents=True, exist_ok=True)74+75+min_size = self.MINIMUM_REQUEST_BODY_SIZE76+samples: List[Dict[str, Any]] = []77+skipped_no_response = 078+skipped_too_small = 079+skipped_unreplayable = 080+skipped_probe_errors = 081+82+endpoint_url = f"{self.api_host}/{self.ENDPOINT_PATH}"83+84+timeout = aiohttp.ClientTimeout(total=self.REPLAYABILITY_CHECK_TIMEOUT_SECONDS)85+async with aiohttp.ClientSession(timeout=timeout) as session:86+for sample in raw_samples:87+es_id = sample["id"]88+request_body = sample["request_body"]89+original_response = sample.get("original_response")90+91+if not original_response:92+skipped_no_response += 193+continue94+95+if min_size and len(json.dumps(request_body)) < min_size:96+skipped_too_small += 197+continue98+99+if self.SKIP_UNREPLAYABLE_ON_COLLECT:100+try:101+async with session.post(endpoint_url, json=request_body) as resp:102+if resp.status != 200:103+body_text = await resp.text()104+if "Cannot find activity" in body_text:105+skipped_unreplayable += 1106+continue107+except Exception:108+skipped_probe_errors += 1109+110+with open(self._inputs_dir / f"{es_id}.json", "w") as f:111+json.dump(request_body, f, indent=2)112+113+with open(self._ground_truths_dir / f"gt_{es_id}.json", "w") as f:114+json.dump(original_response, f, indent=2)115+116+samples.append(117+ {118+"id": es_id,119+"request_body": request_body,120+"original_response": original_response,121+"ground_truth": original_response,122+ }123+ )124+125+print(f"Wrote {len(samples)} samples to {self._inputs_dir.parent}")126+if skipped_no_response:127+print(f"Skipped {skipped_no_response} records with no response body")128+if skipped_too_small:129+print(130+f"Skipped {skipped_too_small} records whose request body was smaller "131+f"than {min_size} characters"132+ )133+if skipped_unreplayable:134+print(f"Skipped {skipped_unreplayable} records that are not replayable (missing activity in ES)")135+if skipped_probe_errors:136+print(f"Warning: replayability probe errored for {skipped_probe_errors} records (kept those records)")137+138+if self.__class__.POPULATE_GROUND_TRUTH_LLM:139+label_results = await run_endpoint_http(140+test_set=samples,141+endpoint_url=endpoint_url,142+request_model=self.REQUEST_MODEL,143+force_llm_endpoint=self.__class__.GROUND_TRUTH_LLM_ENDPOINT,144+is_streaming_response=self.IS_STREAMING_RESPONSE,145+timeout_seconds=300.0,146+parallel_requests=self.parallel_requests,147+return_prompt_in_run=self.RETURN_PROMPT_IN_RUN,148+ )149+150+for i, r in enumerate(label_results):151+forced = self.__class__.GROUND_TRUTH_LLM_ENDPOINT152+model = forced.split(":", 1)[1] if ":" in forced else forced153+samples[i]["ground_truth_llm_model"] = model154+155+if not r.get("success", True):156+samples[i]["ground_truth_llm"] = None157+samples[i]["ground_truth_llm_reasoning"] = None158+samples[i]["ground_truth_llm_error_type"] = r.get("error_type")159+samples[i]["ground_truth_llm_error_message"] = r.get("error_message")160+continue161+162+resp = r.get("new_response") or {}163+samples[i]["ground_truth_llm"] = resp.get("ai_activity_type")164+samples[i]["ground_truth_llm_reasoning"] = resp.get("ai_activity_type_reasoning")165+166+return samples167+168+async def _collect_from_files(self) -> List[Dict[str, Any]]:169+if not self._inputs_dir.exists():170+raise FileNotFoundError(171+f"Dataset folder not found: {self._inputs_dir}. "172+"Run --steps collect first or check your --data-set name."173+ )174+175+samples: List[Dict[str, Any]] = []176+for filename in sorted(os.listdir(self._inputs_dir)):177+input_path = self._inputs_dir / filename178+gt_path = self._ground_truths_dir / f"gt_{filename}"179+180+if not gt_path.exists():181+print(f"Warning: ground truth not found for {filename}, skipping")182+continue183+184+with open(input_path, "r") as f:185+request_body: Dict[str, Any] = json.load(f)186+187+with open(gt_path, "r") as f:188+ground_truth: Dict[str, Any] = json.load(f)189+190+samples.append(191+ {192+"id": Path(filename).stem,193+"request_body": request_body,194+"original_response": None,195+"ground_truth": ground_truth,196+ }197+ )198+199+print(f"Loaded {len(samples)} samples from {self._inputs_dir.parent}")200+return samples201+202+async def evaluate_against_ground_truth(self, results: List[Dict[str, Any]]) -> List[EvaluationResult]:203+evaluation_results: List[EvaluationResult] = []204+compare_to = self.__class__.COMPARE_TO_GROUND_TRUTH205+206+for res in results:207+req_id = res["request_id"]208+is_success = res.get("success", True)209+210+if not is_success:211+evaluation_results.append(212+EvaluationResult(213+request_id=req_id,214+request_body=res["request_body"],215+new_response=res.get("new_response"),216+valid_schema=False,217+quality_score=0.0,218+quality_feedback=f"Request failed: {res.get('error_type')} - {res.get('error_message')}",219+response_time=res.get("response_time"),220+success=False,221+error_type=res.get("error_type"),222+error_message=res.get("error_message"),223+ground_truth_match=False,224+ )225+ )226+continue227+228+pred = (res.get("new_response") or {}).get("ai_activity_type")229+230+if compare_to == "llm":231+if "ground_truth_llm" not in res:232+evaluation_results.append(233+EvaluationResult(234+request_id=req_id,235+request_body=res["request_body"],236+new_response=res.get("new_response"),237+valid_schema=res.get("valid_schema", True),238+quality_score=0.0,239+quality_feedback=(240+"Missing ground_truth_llm in run results. Ensure collect step populated it and "241+"endpoints.py passes it through."242+ ),243+response_time=res.get("response_time"),244+success=True,245+ground_truth_match=False,246+ )247+ )248+continue249+gt_label = res.get("ground_truth_llm")250+else:251+gt_path = self._ground_truths_dir / f"gt_{req_id}.json"252+if not gt_path.exists():253+evaluation_results.append(254+EvaluationResult(255+request_id=req_id,256+request_body=res["request_body"],257+new_response=res.get("new_response"),258+valid_schema=res.get("valid_schema", True),259+quality_score=0.0,260+quality_feedback=f"Ground truth file not found: {gt_path}",261+response_time=res.get("response_time"),262+success=True,263+ground_truth_match=False,264+ )265+ )266+continue267+268+with open(gt_path, "r") as f:269+ground_truth_dict: Dict[str, Any] = json.load(f)270+271+gt_label = (ground_truth_dict or {}).get("ai_activity_type")272+273+matched = pred == gt_label274+275+evaluation_results.append(276+EvaluationResult(277+request_id=req_id,278+request_body=res["request_body"],279+new_response=res.get("new_response"),280+valid_schema=res.get("valid_schema", True),281+quality_score=1.0 if matched else 0.0,282+quality_feedback="PASS" if matched else f"FAIL\nExpected: {gt_label}\nGot: {pred}",283+response_time=res.get("response_time"),284+success=True,285+ground_truth_match=matched,286+ )287+ )288+289+return evaluation_results290+291+292+if __name__ == "__main__":293+parser = create_parser(AiActivityTypeEvaluator)294+parser.add_argument(295+"--data-set",296+type=str,297+default="initial",298+dest="data_set",299+help="Dataset folder under eval_output/ai_activity_type/eval_datasets/ (default: initial)",300+ )301+302+parser.add_argument(303+"--populate-ground-truth-llm",304+action="store_true",305+dest="populate_ground_truth_llm",306+ )307+parser.add_argument(308+"--ground-truth-llm-endpoint",309+type=str,310+default="OPENAI:gpt-5_2",311+dest="ground_truth_llm_endpoint",312+ )313+314+parser.add_argument(315+"--compare-to-ground-truth",316+type=str,317+choices=["es", "llm"],318+default="es",319+dest="compare_to_ground_truth",320+ )321+322+args = parser.parse_args()323+AiActivityTypeEvaluator.DATA_SET = args.data_set324+325+AiActivityTypeEvaluator.POPULATE_GROUND_TRUTH_LLM = bool(args.populate_ground_truth_llm)326+AiActivityTypeEvaluator.GROUND_TRUTH_LLM_ENDPOINT = args.ground_truth_llm_endpoint327+328+AiActivityTypeEvaluator.COMPARE_TO_GROUND_TRUTH = args.compare_to_ground_truth329+330+asyncio.run(run_evaluation(AiActivityTypeEvaluator, args))</selection>” selected.
Please summarize the selection using precise and concise language. Use headers and bulleted lists in the summary, to make it scannable. Maintain the meaning and factual accuracy.
Expand
Listen
Show more options
Gemini said
Gemini said
This Python script defines the
AiActivityTypeEvaluator
class, a specialized tool for evaluating AI-driven activity type classification. It extends a base evaluation framework to handle data collection, ground-truth comparison, and performance scoring.
Core Functionality
Core Functionality
Data Collection (
collect_test_set
):
* Supports fetching raw samples from
Elasticsearch (ES)
or loading them from
local JSON files
.
Implements a
replayability check
: It probes the live API endpoint to ensure the activity exists before including it in the dataset.
Filters data based on request body size, language, and the presence of an original response.
Ground Truth Management:
Saves inputs and "gold standard" responses to a local directory structure (
eval_output/ai_activity_type/...
).
Features an optional mode to populate ground truth using a high-order LLM (e.g.,
gpt-5_2
) if the
POPULATE_GROUND_TRUTH_LLM
flag is set.
Evaluation Logic (
evaluate_against_ground_truth
):
Compares the model's predicted
ai_activity_type
against either the original ES response or the LLM-generated ground truth.
Assigns a
quality_score
of
1.0
for a match and
0.0
for a mismatch or request failure.
Key Configuration Constants
Key Configuration Constants
Constant
Purpose
ENDPOINT_PATH
The specific API route being tested:
call/ai-activity-type
.
COMPARE_TO_GROUND_TRUTH
Determines if the baseline is the original data (
es
) or an
llm
.
SKIP_UNREPLAYABLE_ON_COLLECT
If
True
, discards records where the API returns "Cannot find activity."
REPLAYABILITY_CHECK_TIMEOUT_SECONDS
Limits the probe request to 20 seconds.
Constant
ENDPOINT_PATH
COMPARE_TO_GROUND_TRUTH
SKIP_UNREPLAYABLE_ON_COLLECT
REPLAYABILITY_CHECK_TIMEOUT_SECONDS
Purpose
The specific API route being tested:
call/ai-activity-type
.
Determines if the baseline is the original data (
es
) or an
llm
.
If
True
, discards records where the API returns "Cannot find activity."
Limits the probe request to 20 seconds.
Copy table
Execution Workflow
Execution Workflow
Parsing:
The script uses
create_parser
to handle CLI arguments like
--data-set
,
--populate-ground-truth-llm
, and
--compare-to-ground-truth
.
Initialization:
Sets up directory paths for inputs and ground truths based on the selected dataset name.
Run:
Executes the evaluation via
asyncio.run(run_evaluation(...))
, which orchestrates the collection, endpoint calling, and result scoring phases.
Copy prompt
Edit
You said are there soem issues with this PR
You said
are there soem issues with this PR
Listen
Show more options
Show thinking
Gemini said
Gemini said
Yes, there are several issues and code smells in this Pull Request, ranging from performance bottlenecks to architectural anti-patterns.
Here is a breakdown of the most notable issues, categorized by impact:
Performance & Async Anti-Patterns
Performance & Async Anti-Patterns
Sequential Requests Defeating Async (Lines 86-106):
Inside
_collect_from_es
, the code loops through
raw_samples
and
await
s a
session.post
request for each sample one by one. This means the script waits for one HTTP request to finish before starting the next, completely defeating the purpose of using
aiohttp
for asynchronous concurrency.
Fix:...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jiminny","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Jiminny","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Tab","depth":4,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Close Google Gemini (⌃X)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"AI Chat settings","depth":7,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Close","depth":7,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"WORK, Google Account: lukas.kovalik@jiminny.com","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Main menu","depth":12,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Chat","depth":12,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Open menu for conversation actions.","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXHeading","text":"Conversation with Gemini","depth":15,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Conversation with Gemini","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Copy prompt","depth":21,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"You said I’m on page “<tabTitle>Jy 19798 evaluation for ai activity types by nikol</tabTitle>” with “<selection>@@ -0,0 +1,330 @@1+#!/usr/bin/env python32+import asyncio3+import json4+import os5+from pathlib import Path6+from typing import Any, Dict, List7+8+import aiohttp9+10+from src.component.call_processing.schemes.ai_activity_type_request import AiActivityTypeRequest11+from src.component.call_processing.schemes.ai_activity_type_response import AiActivityTypeResponse12+from src.eval.abstract_evaluator import AbstractEvaluator13+from src.eval.collectors import collect_test_set as es_collect_test_set14+from src.eval.common_evaluator_runner import create_parser, run_evaluation15+from src.eval.endpoints import run_endpoint as run_endpoint_http16+from src.eval.models import EvaluationResult17+18+19+class AiActivityTypeEvaluator(AbstractEvaluator):20+ENDPOINT_PATH = "call/ai-activity-type"21+REQUEST_MODEL = AiActivityTypeRequest22+RESPONSE_MODEL = AiActivityTypeResponse23+OUTPUT_SUBFOLDER = "ai_activity_type"24+USES_LLM_EVALUATION = False25+26+READS_FROM_DATASET_FOLDER = True27+28+DATA_SET: str = "initial"29+30+MINIMUM_REQUEST_BODY_SIZE: int = 031+32+SKIP_UNREPLAYABLE_ON_COLLECT: bool = True33+REPLAYABILITY_CHECK_TIMEOUT_SECONDS: float = 20.034+35+POPULATE_GROUND_TRUTH_LLM: bool = False36+GROUND_TRUTH_LLM_ENDPOINT: str = "OPENAI:gpt-5_2"37+38+COMPARE_TO_GROUND_TRUTH: str = "es"39+40+def __init__(self, **kwargs: Any) -> None:41+super().__init__(**kwargs)42+_repo_root = Path(__file__).parents[2]43+_datasets_root = _repo_root / "eval_output" / self.OUTPUT_SUBFOLDER / "eval_datasets"44+_dataset_dir = _datasets_root / self.__class__.DATA_SET45+self._dataset_dir = _dataset_dir46+self._inputs_dir = _dataset_dir / "input"47+self._ground_truths_dir = _dataset_dir / "ground_truth"48+49+async def collect_test_set(self) -> List[Dict[str, Any]]:50+if self.es_host_name:51+return await self._collect_from_es()52+return await self._collect_from_files()53+54+async def _collect_from_es(self) -> List[Dict[str, Any]]:55+if self._inputs_dir.exists() or self._ground_truths_dir.exists():56+raise FileExistsError(57+f"Dataset folder already exists: {self._inputs_dir.parent}. "58+"Choose a different --data-set name or remove the folder manually."59+ )60+61+raw_samples = await es_collect_test_set(62+es_host_name=self.es_host_name,63+es_port=self.es_port,64+endpoint_path=self.ENDPOINT_PATH,65+limit=self.limit,66+language_filter=self.language_filter,67+min_prompt_length=self.min_prompt_length,68+is_json_response=self.IS_JSON_RESPONSE,69+exclude_languages=self.exclude_languages,70+ )71+72+self._inputs_dir.mkdir(parents=True, exist_ok=True)73+self._ground_truths_dir.mkdir(parents=True, exist_ok=True)74+75+min_size = self.MINIMUM_REQUEST_BODY_SIZE76+samples: List[Dict[str, Any]] = []77+skipped_no_response = 078+skipped_too_small = 079+skipped_unreplayable = 080+skipped_probe_errors = 081+82+endpoint_url = f"{self.api_host}/{self.ENDPOINT_PATH}"83+84+timeout = aiohttp.ClientTimeout(total=self.REPLAYABILITY_CHECK_TIMEOUT_SECONDS)85+async with aiohttp.ClientSession(timeout=timeout) as session:86+for sample in raw_samples:87+es_id = sample["id"]88+request_body = sample["request_body"]89+original_response = sample.get("original_response")90+91+if not original_response:92+skipped_no_response += 193+continue94+95+if min_size and len(json.dumps(request_body)) < min_size:96+skipped_too_small += 197+continue98+99+if self.SKIP_UNREPLAYABLE_ON_COLLECT:100+try:101+async with session.post(endpoint_url, json=request_body) as resp:102+if resp.status != 200:103+body_text = await resp.text()104+if "Cannot find activity" in body_text:105+skipped_unreplayable += 1106+continue107+except Exception:108+skipped_probe_errors += 1109+110+with open(self._inputs_dir / f"{es_id}.json", "w") as f:111+json.dump(request_body, f, indent=2)112+113+with open(self._ground_truths_dir / f"gt_{es_id}.json", "w") as f:114+json.dump(original_response, f, indent=2)115+116+samples.append(117+ {118+"id": es_id,119+"request_body": request_body,120+"original_response": original_response,121+"ground_truth": original_response,122+ }123+ )124+125+print(f"Wrote {len(samples)} samples to {self._inputs_dir.parent}")126+if skipped_no_response:127+print(f"Skipped {skipped_no_response} records with no response body")128+if skipped_too_small:129+print(130+f"Skipped {skipped_too_small} records whose request body was smaller "131+f"than {min_size} characters"132+ )133+if skipped_unreplayable:134+print(f"Skipped {skipped_unreplayable} records that are not replayable (missing activity in ES)")135+if skipped_probe_errors:136+print(f"Warning: replayability probe errored for {skipped_probe_errors} records (kept those records)")137+138+if self.__class__.POPULATE_GROUND_TRUTH_LLM:139+label_results = await run_endpoint_http(140+test_set=samples,141+endpoint_url=endpoint_url,142+request_model=self.REQUEST_MODEL,143+force_llm_endpoint=self.__class__.GROUND_TRUTH_LLM_ENDPOINT,144+is_streaming_response=self.IS_STREAMING_RESPONSE,145+timeout_seconds=300.0,146+parallel_requests=self.parallel_requests,147+return_prompt_in_run=self.RETURN_PROMPT_IN_RUN,148+ )149+150+for i, r in enumerate(label_results):151+forced = self.__class__.GROUND_TRUTH_LLM_ENDPOINT152+model = forced.split(":", 1)[1] if ":" in forced else forced153+samples[i]["ground_truth_llm_model"] = model154+155+if not r.get("success", True):156+samples[i]["ground_truth_llm"] = None157+samples[i]["ground_truth_llm_reasoning"] = None158+samples[i]["ground_truth_llm_error_type"] = r.get("error_type")159+samples[i]["ground_truth_llm_error_message"] = r.get("error_message")160+continue161+162+resp = r.get("new_response") or {}163+samples[i]["ground_truth_llm"] = resp.get("ai_activity_type")164+samples[i]["ground_truth_llm_reasoning"] = resp.get("ai_activity_type_reasoning")165+166+return samples167+168+async def _collect_from_files(self) -> List[Dict[str, Any]]:169+if not self._inputs_dir.exists():170+raise FileNotFoundError(171+f"Dataset folder not found: {self._inputs_dir}. "172+"Run --steps collect first or check your --data-set name."173+ )174+175+samples: List[Dict[str, Any]] = []176+for filename in sorted(os.listdir(self._inputs_dir)):177+input_path = self._inputs_dir / filename178+gt_path = self._ground_truths_dir / f"gt_{filename}"179+180+if not gt_path.exists():181+print(f"Warning: ground truth not found for {filename}, skipping")182+continue183+184+with open(input_path, "r") as f:185+request_body: Dict[str, Any] = json.load(f)186+187+with open(gt_path, "r") as f:188+ground_truth: Dict[str, Any] = json.load(f)189+190+samples.append(191+ {192+"id": Path(filename).stem,193+"request_body": request_body,194+"original_response": None,195+"ground_truth": ground_truth,196+ }197+ )198+199+print(f"Loaded {len(samples)} samples from {self._inputs_dir.parent}")200+return samples201+202+async def evaluate_against_ground_truth(self, results: List[Dict[str, Any]]) -> List[EvaluationResult]:203+evaluation_results: List[EvaluationResult] = []204+compare_to = self.__class__.COMPARE_TO_GROUND_TRUTH205+206+for res in results:207+req_id = res["request_id"]208+is_success = res.get("success", True)209+210+if not is_success:211+evaluation_results.append(212+EvaluationResult(213+request_id=req_id,214+request_body=res["request_body"],215+new_response=res.get("new_response"),216+valid_schema=False,217+quality_score=0.0,218+quality_feedback=f"Request failed: {res.get('error_type')} - {res.get('error_message')}",219+response_time=res.get("response_time"),220+success=False,221+error_type=res.get("error_type"),222+error_message=res.get("error_message"),223+ground_truth_match=False,224+ )225+ )226+continue227+228+pred = (res.get("new_response") or {}).get("ai_activity_type")229+230+if compare_to == "llm":231+if "ground_truth_llm" not in res:232+evaluation_results.append(233+EvaluationResult(234+request_id=req_id,235+request_body=res["request_body"],236+new_response=res.get("new_response"),237+valid_schema=res.get("valid_schema", True),238+quality_score=0.0,239+quality_feedback=(240+"Missing ground_truth_llm in run results. Ensure collect step populated it and "241+"endpoints.py passes it through."242+ ),243+response_time=res.get("response_time"),244+success=True,245+ground_truth_match=False,246+ )247+ )248+continue249+gt_label = res.get("ground_truth_llm")250+else:251+gt_path = self._ground_truths_dir / f"gt_{req_id}.json"252+if not gt_path.exists():253+evaluation_results.append(254+EvaluationResult(255+request_id=req_id,256+request_body=res["request_body"],257+new_response=res.get("new_response"),258+valid_schema=res.get("valid_schema", True),259+quality_score=0.0,260+quality_feedback=f"Ground truth file not found: {gt_path}",261+response_time=res.get("response_time"),262+success=True,263+ground_truth_match=False,264+ )265+ )266+continue267+268+with open(gt_path, "r") as f:269+ground_truth_dict: Dict[str, Any] = json.load(f)270+271+gt_label = (ground_truth_dict or {}).get("ai_activity_type")272+273+matched = pred == gt_label274+275+evaluation_results.append(276+EvaluationResult(277+request_id=req_id,278+request_body=res["request_body"],279+new_response=res.get("new_response"),280+valid_schema=res.get("valid_schema", True),281+quality_score=1.0 if matched else 0.0,282+quality_feedback="PASS" if matched else f"FAIL\\nExpected: {gt_label}\\nGot: {pred}",283+response_time=res.get("response_time"),284+success=True,285+ground_truth_match=matched,286+ )287+ )288+289+return evaluation_results290+291+292+if __name__ == "__main__":293+parser = create_parser(AiActivityTypeEvaluator)294+parser.add_argument(295+"--data-set",296+type=str,297+default="initial",298+dest="data_set",299+help="Dataset folder under eval_output/ai_activity_type/eval_datasets/ (default: initial)",300+ )301+302+parser.add_argument(303+"--populate-ground-truth-llm",304+action="store_true",305+dest="populate_ground_truth_llm",306+ )307+parser.add_argument(308+"--ground-truth-llm-endpoint",309+type=str,310+default="OPENAI:gpt-5_2",311+dest="ground_truth_llm_endpoint",312+ )313+314+parser.add_argument(315+"--compare-to-ground-truth",316+type=str,317+choices=["es", "llm"],318+default="es",319+dest="compare_to_ground_truth",320+ )321+322+args = parser.parse_args()323+AiActivityTypeEvaluator.DATA_SET = args.data_set324+325+AiActivityTypeEvaluator.POPULATE_GROUND_TRUTH_LLM = bool(args.populate_ground_truth_llm)326+AiActivityTypeEvaluator.GROUND_TRUTH_LLM_ENDPOINT = args.ground_truth_llm_endpoint327+328+AiActivityTypeEvaluator.COMPARE_TO_GROUND_TRUTH = args.compare_to_ground_truth329+330+asyncio.run(run_evaluation(AiActivityTypeEvaluator, args))</selection>” selected. Please summarize the selection using precise and concise language. Use headers and bulleted lists in the summary, to make it scannable. Maintain the meaning and factual accuracy.","depth":21,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"You said","depth":23,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"I’m on page “<tabTitle>Jy 19798 evaluation for ai activity types by nikol</tabTitle>” with “<selection>@@ -0,0 +1,330 @@1+#!/usr/bin/env python32+import asyncio3+import json4+import os5+from pathlib import Path6+from typing import Any, Dict, List7+8+import aiohttp9+10+from src.component.call_processing.schemes.ai_activity_type_request import AiActivityTypeRequest11+from src.component.call_processing.schemes.ai_activity_type_response import AiActivityTypeResponse12+from src.eval.abstract_evaluator import AbstractEvaluator13+from src.eval.collectors import collect_test_set as es_collect_test_set14+from src.eval.common_evaluator_runner import create_parser, run_evaluation15+from src.eval.endpoints import run_endpoint as run_endpoint_http16+from src.eval.models import EvaluationResult17+18+19+class AiActivityTypeEvaluator(AbstractEvaluator):20+ENDPOINT_PATH = "call/ai-activity-type"21+REQUEST_MODEL = AiActivityTypeRequest22+RESPONSE_MODEL = AiActivityTypeResponse23+OUTPUT_SUBFOLDER = "ai_activity_type"24+USES_LLM_EVALUATION = False25+26+READS_FROM_DATASET_FOLDER = True27+28+DATA_SET: str = "initial"29+30+MINIMUM_REQUEST_BODY_SIZE: int = 031+32+SKIP_UNREPLAYABLE_ON_COLLECT: bool = True33+REPLAYABILITY_CHECK_TIMEOUT_SECONDS: float = 20.034+35+POPULATE_GROUND_TRUTH_LLM: bool = False36+GROUND_TRUTH_LLM_ENDPOINT: str = "OPENAI:gpt-5_2"37+38+COMPARE_TO_GROUND_TRUTH: str = "es"39+40+def __init__(self, **kwargs: Any) -> None:41+super().__init__(**kwargs)42+_repo_root = Path(__file__).parents[2]43+_datasets_root = _repo_root / "eval_output" / self.OUTPUT_SUBFOLDER / "eval_datasets"44+_dataset_dir = _datasets_root / self.__class__.DATA_SET45+self._dataset_dir = _dataset_dir46+self._inputs_dir = _dataset_dir / "input"47+self._ground_truths_dir = _dataset_dir / "ground_truth"48+49+async def collect_test_set(self) -> List[Dict[str, Any]]:50+if self.es_host_name:51+return await self._collect_from_es()52+return await self._collect_from_files()53+54+async def _collect_from_es(self) -> List[Dict[str, Any]]:55+if self._inputs_dir.exists() or self._ground_truths_dir.exists():56+raise FileExistsError(57+f"Dataset folder already exists: {self._inputs_dir.parent}. "58+"Choose a different --data-set name or remove the folder manually."59+ )60+61+raw_samples = await es_collect_test_set(62+es_host_name=self.es_host_name,63+es_port=self.es_port,64+endpoint_path=self.ENDPOINT_PATH,65+limit=self.limit,66+language_filter=self.language_filter,67+min_prompt_length=self.min_prompt_length,68+is_json_response=self.IS_JSON_RESPONSE,69+exclude_languages=self.exclude_languages,70+ )71+72+self._inputs_dir.mkdir(parents=True, exist_ok=True)73+self._ground_truths_dir.mkdir(parents=True, exist_ok=True)74+75+min_size = self.MINIMUM_REQUEST_BODY_SIZE76+samples: List[Dict[str, Any]] = []77+skipped_no_response = 078+skipped_too_small = 079+skipped_unreplayable = 080+skipped_probe_errors = 081+82+endpoint_url = f"{self.api_host}/{self.ENDPOINT_PATH}"83+84+timeout = aiohttp.ClientTimeout(total=self.REPLAYABILITY_CHECK_TIMEOUT_SECONDS)85+async with aiohttp.ClientSession(timeout=timeout) as session:86+for sample in raw_samples:87+es_id = sample["id"]88+request_body = sample["request_body"]89+original_response = sample.get("original_response")90+91+if not original_response:92+skipped_no_response += 193+continue94+95+if min_size and len(json.dumps(request_body)) < min_size:96+skipped_too_small += 197+continue98+99+if self.SKIP_UNREPLAYABLE_ON_COLLECT:100+try:101+async with session.post(endpoint_url, json=request_body) as resp:102+if resp.status != 200:103+body_text = await resp.text()104+if "Cannot find activity" in body_text:105+skipped_unreplayable += 1106+continue107+except Exception:108+skipped_probe_errors += 1109+110+with open(self._inputs_dir / f"{es_id}.json", "w") as f:111+json.dump(request_body, f, indent=2)112+113+with open(self._ground_truths_dir / f"gt_{es_id}.json", "w") as f:114+json.dump(original_response, f, indent=2)115+116+samples.append(117+ {118+"id": es_id,119+"request_body": request_body,120+"original_response": original_response,121+"ground_truth": original_response,122+ }123+ )124+125+print(f"Wrote {len(samples)} samples to {self._inputs_dir.parent}")126+if skipped_no_response:127+print(f"Skipped {skipped_no_response} records with no response body")128+if skipped_too_small:129+print(130+f"Skipped {skipped_too_small} records whose request body was smaller "131+f"than {min_size} characters"132+ )133+if skipped_unreplayable:134+print(f"Skipped {skipped_unreplayable} records that are not replayable (missing activity in ES)")135+if skipped_probe_errors:136+print(f"Warning: replayability probe errored for {skipped_probe_errors} records (kept those records)")137+138+if self.__class__.POPULATE_GROUND_TRUTH_LLM:139+label_results = await run_endpoint_http(140+test_set=samples,141+endpoint_url=endpoint_url,142+request_model=self.REQUEST_MODEL,143+force_llm_endpoint=self.__class__.GROUND_TRUTH_LLM_ENDPOINT,144+is_streaming_response=self.IS_STREAMING_RESPONSE,145+timeout_seconds=300.0,146+parallel_requests=self.parallel_requests,147+return_prompt_in_run=self.RETURN_PROMPT_IN_RUN,148+ )149+150+for i, r in enumerate(label_results):151+forced = self.__class__.GROUND_TRUTH_LLM_ENDPOINT152+model = forced.split(":", 1)[1] if ":" in forced else forced153+samples[i]["ground_truth_llm_model"] = model154+155+if not r.get("success", True):156+samples[i]["ground_truth_llm"] = None157+samples[i]["ground_truth_llm_reasoning"] = None158+samples[i]["ground_truth_llm_error_type"] = r.get("error_type")159+samples[i]["ground_truth_llm_error_message"] = r.get("error_message")160+continue161+162+resp = r.get("new_response") or {}163+samples[i]["ground_truth_llm"] = resp.get("ai_activity_type")164+samples[i]["ground_truth_llm_reasoning"] = resp.get("ai_activity_type_reasoning")165+166+return samples167+168+async def _collect_from_files(self) -> List[Dict[str, Any]]:169+if not self._inputs_dir.exists():170+raise FileNotFoundError(171+f"Dataset folder not found: {self._inputs_dir}. "172+"Run --steps collect first or check your --data-set name."173+ )174+175+samples: List[Dict[str, Any]] = []176+for filename in sorted(os.listdir(self._inputs_dir)):177+input_path = self._inputs_dir / filename178+gt_path = self._ground_truths_dir / f"gt_{filename}"179+180+if not gt_path.exists():181+print(f"Warning: ground truth not found for {filename}, skipping")182+continue183+184+with open(input_path, "r") as f:185+request_body: Dict[str, Any] = json.load(f)186+187+with open(gt_path, "r") as f:188+ground_truth: Dict[str, Any] = json.load(f)189+190+samples.append(191+ {192+"id": Path(filename).stem,193+"request_body": request_body,194+"original_response": None,195+"ground_truth": ground_truth,196+ }197+ )198+199+print(f"Loaded {len(samples)} samples from {self._inputs_dir.parent}")200+return samples201+202+async def evaluate_against_ground_truth(self, results: List[Dict[str, Any]]) -> List[EvaluationResult]:203+evaluation_results: List[EvaluationResult] = []204+compare_to = self.__class__.COMPARE_TO_GROUND_TRUTH205+206+for res in results:207+req_id = res["request_id"]208+is_success = res.get("success", True)209+210+if not is_success:211+evaluation_results.append(212+EvaluationResult(213+request_id=req_id,214+request_body=res["request_body"],215+new_response=res.get("new_response"),216+valid_schema=False,217+quality_score=0.0,218+quality_feedback=f"Request failed: {res.get('error_type')} - {res.get('error_message')}",219+response_time=res.get("response_time"),220+success=False,221+error_type=res.get("error_type"),222+error_message=res.get("error_message"),223+ground_truth_match=False,224+ )225+ )226+continue227+228+pred = (res.get("new_response") or {}).get("ai_activity_type")229+230+if compare_to == "llm":231+if "ground_truth_llm" not in res:232+evaluation_results.append(233+EvaluationResult(234+request_id=req_id,235+request_body=res["request_body"],236+new_response=res.get("new_response"),237+valid_schema=res.get("valid_schema", True),238+quality_score=0.0,239+quality_feedback=(240+"Missing ground_truth_llm in run results. Ensure collect step populated it and "241+"endpoints.py passes it through."242+ ),243+response_time=res.get("response_time"),244+success=True,245+ground_truth_match=False,246+ )247+ )248+continue249+gt_label = res.get("ground_truth_llm")250+else:251+gt_path = self._ground_truths_dir / f"gt_{req_id}.json"252+if not gt_path.exists():253+evaluation_results.append(254+EvaluationResult(255+request_id=req_id,256+request_body=res["request_body"],257+new_response=res.get("new_response"),258+valid_schema=res.get("valid_schema", True),259+quality_score=0.0,260+quality_feedback=f"Ground truth file not found: {gt_path}",261+response_time=res.get("response_time"),262+success=True,263+ground_truth_match=False,264+ )265+ )266+continue267+268+with open(gt_path, "r") as f:269+ground_truth_dict: Dict[str, Any] = json.load(f)270+271+gt_label = (ground_truth_dict or {}).get("ai_activity_type")272+273+matched = pred == gt_label274+275+evaluation_results.append(276+EvaluationResult(277+request_id=req_id,278+request_body=res["request_body"],279+new_response=res.get("new_response"),280+valid_schema=res.get("valid_schema", True),281+quality_score=1.0 if matched else 0.0,282+quality_feedback="PASS" if matched else f"FAIL\\nExpected: {gt_label}\\nGot: {pred}",283+response_time=res.get("response_time"),284+success=True,285+ground_truth_match=matched,286+ )287+ )288+289+return evaluation_results290+291+292+if __name__ == "__main__":293+parser = create_parser(AiActivityTypeEvaluator)294+parser.add_argument(295+"--data-set",296+type=str,297+default="initial",298+dest="data_set",299+help="Dataset folder under eval_output/ai_activity_type/eval_datasets/ (default: initial)",300+ )301+302+parser.add_argument(303+"--populate-ground-truth-llm",304+action="store_true",305+dest="populate_ground_truth_llm",306+ )307+parser.add_argument(308+"--ground-truth-llm-endpoint",309+type=str,310+default="OPENAI:gpt-5_2",311+dest="ground_truth_llm_endpoint",312+ )313+314+parser.add_argument(315+"--compare-to-ground-truth",316+type=str,317+choices=["es", "llm"],318+default="es",319+dest="compare_to_ground_truth",320+ )321+322+args = parser.parse_args()323+AiActivityTypeEvaluator.DATA_SET = args.data_set324+325+AiActivityTypeEvaluator.POPULATE_GROUND_TRUTH_LLM = bool(args.populate_ground_truth_llm)326+AiActivityTypeEvaluator.GROUND_TRUTH_LLM_ENDPOINT = args.ground_truth_llm_endpoint327+328+AiActivityTypeEvaluator.COMPARE_TO_GROUND_TRUTH = args.compare_to_ground_truth329+330+asyncio.run(run_evaluation(AiActivityTypeEvaluator, args))</selection>” selected.","depth":23,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Please summarize the selection using precise and concise language. Use headers and bulleted lists in the summary, to make it scannable. Maintain the meaning and factual accuracy.","depth":23,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Expand","depth":21,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Listen","depth":22,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Show more options","depth":20,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Gemini said","depth":20,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Gemini said","depth":21,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"This Python script defines the","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"AiActivityTypeEvaluator","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"class, a specialized tool for evaluating AI-driven activity type classification. It extends a base evaluation framework to handle data collection, ground-truth comparison, and performance scoring.","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Core Functionality","depth":23,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Core Functionality","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Data Collection (","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"collect_test_set","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"):","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"* Supports fetching raw samples from","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Elasticsearch (ES)","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"or loading them from","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"local JSON files","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Implements a","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"replayability check","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":": It probes the live API endpoint to ensure the activity exists before including it in the dataset.","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Filters data based on request body size, language, and the presence of an original response.","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Ground Truth Management:","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Saves inputs and \"gold standard\" responses to a local directory structure (","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"eval_output/ai_activity_type/...","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":").","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Features an optional mode to populate ground truth using a high-order LLM (e.g.,","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"gpt-5_2","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":") if the","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"POPULATE_GROUND_TRUTH_LLM","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"flag is set.","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Evaluation Logic (","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"evaluate_against_ground_truth","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"):","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Compares the model's predicted","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ai_activity_type","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"against either the original ES response or the LLM-generated ground truth.","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Assigns a","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"quality_score","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"of","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1.0","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"for a match and","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.0","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"for a mismatch or request failure.","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Key Configuration Constants","depth":23,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Key Configuration Constants","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Constant","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Purpose","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ENDPOINT_PATH","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"The specific API route being tested:","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"call/ai-activity-type","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"COMPARE_TO_GROUND_TRUTH","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Determines if the baseline is the original data (","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"es","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":") or an","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"llm","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"SKIP_UNREPLAYABLE_ON_COLLECT","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"If","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"True","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":", discards records where the API returns \"Cannot find activity.\"","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"REPLAYABILITY_CHECK_TIMEOUT_SECONDS","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Limits the probe request to 20 seconds.","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Constant","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ENDPOINT_PATH","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"COMPARE_TO_GROUND_TRUTH","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"SKIP_UNREPLAYABLE_ON_COLLECT","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"REPLAYABILITY_CHECK_TIMEOUT_SECONDS","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Purpose","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"The specific API route being tested:","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"call/ai-activity-type","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Determines if the baseline is the original data (","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"es","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":") or an","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"llm","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"If","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"True","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":", discards records where the API returns \"Cannot find activity.\"","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Limits the probe request to 20 seconds.","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Copy table","depth":24,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Execution Workflow","depth":23,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Execution Workflow","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Parsing:","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"The script uses","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"create_parser","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"to handle CLI arguments like","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"--data-set","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":",","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"--populate-ground-truth-llm","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":", and","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"--compare-to-ground-truth","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Initialization:","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Sets up directory paths for inputs and ground truths based on the selected dataset name.","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Run:","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Executes the evaluation via","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"asyncio.run(run_evaluation(...))","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":", which orchestrates the collection, endpoint calling, and result scoring phases.","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Copy prompt","depth":21,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Edit","depth":21,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"You said are there soem issues with this PR","depth":21,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"You said","depth":23,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"are there soem issues with this PR","depth":23,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Listen","depth":22,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Show more options","depth":20,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Show thinking","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Gemini said","depth":20,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Gemini said","depth":21,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Yes, there are several issues and code smells in this Pull Request, ranging from performance bottlenecks to architectural anti-patterns.","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Here is a breakdown of the most notable issues, categorized by impact:","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Performance & Async Anti-Patterns","depth":23,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Performance & Async Anti-Patterns","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Sequential Requests Defeating Async (Lines 86-106):","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Inside","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"_collect_from_es","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":", the code loops through","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"raw_samples","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"and","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"await","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"s a","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"session.post","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"request for each sample one by one. This means the script waits for one HTTP request to finish before starting the next, completely defeating the purpose of using","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"aiohttp","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"for asynchronous concurrency.","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Fix:","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
5074366443921049573
|
8731758625087598999
|
click
|
accessibility
|
NULL
|
JY-20543 add AJ reports User pilot tracking by Lak JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Jiminny
Jiminny
Close tab
New Tab
Customize sidebar
Close Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
AI Chat settings
Close
WORK, Google Account: [EMAIL]
Main menu
New Chat
Open menu for conversation actions.
Conversation with Gemini
Conversation with Gemini
Copy prompt
You said I’m on page “<tabTitle>Jy 19798 evaluation for ai activity types by nikol</tabTitle>” with “<selection>@@ -0,0 +1,330 @@1+#!/usr/bin/env python32+import asyncio3+import json4+import os5+from pathlib import Path6+from typing import Any, Dict, List7+8+import aiohttp9+10+from src.component.call_processing.schemes.ai_activity_type_request import AiActivityTypeRequest11+from src.component.call_processing.schemes.ai_activity_type_response import AiActivityTypeResponse12+from src.eval.abstract_evaluator import AbstractEvaluator13+from src.eval.collectors import collect_test_set as es_collect_test_set14+from src.eval.common_evaluator_runner import create_parser, run_evaluation15+from src.eval.endpoints import run_endpoint as run_endpoint_http16+from src.eval.models import EvaluationResult17+18+19+class AiActivityTypeEvaluator(AbstractEvaluator):20+ENDPOINT_PATH = "call/ai-activity-type"21+REQUEST_MODEL = AiActivityTypeRequest22+RESPONSE_MODEL = AiActivityTypeResponse23+OUTPUT_SUBFOLDER = "ai_activity_type"24+USES_LLM_EVALUATION = False25+26+READS_FROM_DATASET_FOLDER = True27+28+DATA_SET: str = "initial"29+30+MINIMUM_REQUEST_BODY_SIZE: int = 031+32+SKIP_UNREPLAYABLE_ON_COLLECT: bool = True33+REPLAYABILITY_CHECK_TIMEOUT_SECONDS: float = 20.034+35+POPULATE_GROUND_TRUTH_LLM: bool = False36+GROUND_TRUTH_LLM_ENDPOINT: str = "OPENAI:gpt-5_2"37+38+COMPARE_TO_GROUND_TRUTH: str = "es"39+40+def __init__(self, **kwargs: Any) -> None:41+super().__init__(**kwargs)42+_repo_root = Path(__file__).parents[2]43+_datasets_root = _repo_root / "eval_output" / self.OUTPUT_SUBFOLDER / "eval_datasets"44+_dataset_dir = _datasets_root / self.__class__.DATA_SET45+self._dataset_dir = _dataset_dir46+self._inputs_dir = _dataset_dir / "input"47+self._ground_truths_dir = _dataset_dir / "ground_truth"48+49+async def collect_test_set(self) -> List[Dict[str, Any]]:50+if self.es_host_name:51+return await self._collect_from_es()52+return await self._collect_from_files()53+54+async def _collect_from_es(self) -> List[Dict[str, Any]]:55+if self._inputs_dir.exists() or self._ground_truths_dir.exists():56+raise FileExistsError(57+f"Dataset folder already exists: {self._inputs_dir.parent}. "58+"Choose a different --data-set name or remove the folder manually."59+ )60+61+raw_samples = await es_collect_test_set(62+es_host_name=self.es_host_name,63+es_port=self.es_port,64+endpoint_path=self.ENDPOINT_PATH,65+limit=self.limit,66+language_filter=self.language_filter,67+min_prompt_length=self.min_prompt_length,68+is_json_response=self.IS_JSON_RESPONSE,69+exclude_languages=self.exclude_languages,70+ )71+72+self._inputs_dir.mkdir(parents=True, exist_ok=True)73+self._ground_truths_dir.mkdir(parents=True, exist_ok=True)74+75+min_size = self.MINIMUM_REQUEST_BODY_SIZE76+samples: List[Dict[str, Any]] = []77+skipped_no_response = 078+skipped_too_small = 079+skipped_unreplayable = 080+skipped_probe_errors = 081+82+endpoint_url = f"{self.api_host}/{self.ENDPOINT_PATH}"83+84+timeout = aiohttp.ClientTimeout(total=self.REPLAYABILITY_CHECK_TIMEOUT_SECONDS)85+async with aiohttp.ClientSession(timeout=timeout) as session:86+for sample in raw_samples:87+es_id = sample["id"]88+request_body = sample["request_body"]89+original_response = sample.get("original_response")90+91+if not original_response:92+skipped_no_response += 193+continue94+95+if min_size and len(json.dumps(request_body)) < min_size:96+skipped_too_small += 197+continue98+99+if self.SKIP_UNREPLAYABLE_ON_COLLECT:100+try:101+async with session.post(endpoint_url, json=request_body) as resp:102+if resp.status != 200:103+body_text = await resp.text()104+if "Cannot find activity" in body_text:105+skipped_unreplayable += 1106+continue107+except Exception:108+skipped_probe_errors += 1109+110+with open(self._inputs_dir / f"{es_id}.json", "w") as f:111+json.dump(request_body, f, indent=2)112+113+with open(self._ground_truths_dir / f"gt_{es_id}.json", "w") as f:114+json.dump(original_response, f, indent=2)115+116+samples.append(117+ {118+"id": es_id,119+"request_body": request_body,120+"original_response": original_response,121+"ground_truth": original_response,122+ }123+ )124+125+print(f"Wrote {len(samples)} samples to {self._inputs_dir.parent}")126+if skipped_no_response:127+print(f"Skipped {skipped_no_response} records with no response body")128+if skipped_too_small:129+print(130+f"Skipped {skipped_too_small} records whose request body was smaller "131+f"than {min_size} characters"132+ )133+if skipped_unreplayable:134+print(f"Skipped {skipped_unreplayable} records that are not replayable (missing activity in ES)")135+if skipped_probe_errors:136+print(f"Warning: replayability probe errored for {skipped_probe_errors} records (kept those records)")137+138+if self.__class__.POPULATE_GROUND_TRUTH_LLM:139+label_results = await run_endpoint_http(140+test_set=samples,141+endpoint_url=endpoint_url,142+request_model=self.REQUEST_MODEL,143+force_llm_endpoint=self.__class__.GROUND_TRUTH_LLM_ENDPOINT,144+is_streaming_response=self.IS_STREAMING_RESPONSE,145+timeout_seconds=300.0,146+parallel_requests=self.parallel_requests,147+return_prompt_in_run=self.RETURN_PROMPT_IN_RUN,148+ )149+150+for i, r in enumerate(label_results):151+forced = self.__class__.GROUND_TRUTH_LLM_ENDPOINT152+model = forced.split(":", 1)[1] if ":" in forced else forced153+samples[i]["ground_truth_llm_model"] = model154+155+if not r.get("success", True):156+samples[i]["ground_truth_llm"] = None157+samples[i]["ground_truth_llm_reasoning"] = None158+samples[i]["ground_truth_llm_error_type"] = r.get("error_type")159+samples[i]["ground_truth_llm_error_message"] = r.get("error_message")160+continue161+162+resp = r.get("new_response") or {}163+samples[i]["ground_truth_llm"] = resp.get("ai_activity_type")164+samples[i]["ground_truth_llm_reasoning"] = resp.get("ai_activity_type_reasoning")165+166+return samples167+168+async def _collect_from_files(self) -> List[Dict[str, Any]]:169+if not self._inputs_dir.exists():170+raise FileNotFoundError(171+f"Dataset folder not found: {self._inputs_dir}. "172+"Run --steps collect first or check your --data-set name."173+ )174+175+samples: List[Dict[str, Any]] = []176+for filename in sorted(os.listdir(self._inputs_dir)):177+input_path = self._inputs_dir / filename178+gt_path = self._ground_truths_dir / f"gt_{filename}"179+180+if not gt_path.exists():181+print(f"Warning: ground truth not found for {filename}, skipping")182+continue183+184+with open(input_path, "r") as f:185+request_body: Dict[str, Any] = json.load(f)186+187+with open(gt_path, "r") as f:188+ground_truth: Dict[str, Any] = json.load(f)189+190+samples.append(191+ {192+"id": Path(filename).stem,193+"request_body": request_body,194+"original_response": None,195+"ground_truth": ground_truth,196+ }197+ )198+199+print(f"Loaded {len(samples)} samples from {self._inputs_dir.parent}")200+return samples201+202+async def evaluate_against_ground_truth(self, results: List[Dict[str, Any]]) -> List[EvaluationResult]:203+evaluation_results: List[EvaluationResult] = []204+compare_to = self.__class__.COMPARE_TO_GROUND_TRUTH205+206+for res in results:207+req_id = res["request_id"]208+is_success = res.get("success", True)209+210+if not is_success:211+evaluation_results.append(212+EvaluationResult(213+request_id=req_id,214+request_body=res["request_body"],215+new_response=res.get("new_response"),216+valid_schema=False,217+quality_score=0.0,218+quality_feedback=f"Request failed: {res.get('error_type')} - {res.get('error_message')}",219+response_time=res.get("response_time"),220+success=False,221+error_type=res.get("error_type"),222+error_message=res.get("error_message"),223+ground_truth_match=False,224+ )225+ )226+continue227+228+pred = (res.get("new_response") or {}).get("ai_activity_type")229+230+if compare_to == "llm":231+if "ground_truth_llm" not in res:232+evaluation_results.append(233+EvaluationResult(234+request_id=req_id,235+request_body=res["request_body"],236+new_response=res.get("new_response"),237+valid_schema=res.get("valid_schema", True),238+quality_score=0.0,239+quality_feedback=(240+"Missing ground_truth_llm in run results. Ensure collect step populated it and "241+"endpoints.py passes it through."242+ ),243+response_time=res.get("response_time"),244+success=True,245+ground_truth_match=False,246+ )247+ )248+continue249+gt_label = res.get("ground_truth_llm")250+else:251+gt_path = self._ground_truths_dir / f"gt_{req_id}.json"252+if not gt_path.exists():253+evaluation_results.append(254+EvaluationResult(255+request_id=req_id,256+request_body=res["request_body"],257+new_response=res.get("new_response"),258+valid_schema=res.get("valid_schema", True),259+quality_score=0.0,260+quality_feedback=f"Ground truth file not found: {gt_path}",261+response_time=res.get("response_time"),262+success=True,263+ground_truth_match=False,264+ )265+ )266+continue267+268+with open(gt_path, "r") as f:269+ground_truth_dict: Dict[str, Any] = json.load(f)270+271+gt_label = (ground_truth_dict or {}).get("ai_activity_type")272+273+matched = pred == gt_label274+275+evaluation_results.append(276+EvaluationResult(277+request_id=req_id,278+request_body=res["request_body"],279+new_response=res.get("new_response"),280+valid_schema=res.get("valid_schema", True),281+quality_score=1.0 if matched else 0.0,282+quality_feedback="PASS" if matched else f"FAIL\nExpected: {gt_label}\nGot: {pred}",283+response_time=res.get("response_time"),284+success=True,285+ground_truth_match=matched,286+ )287+ )288+289+return evaluation_results290+291+292+if __name__ == "__main__":293+parser = create_parser(AiActivityTypeEvaluator)294+parser.add_argument(295+"--data-set",296+type=str,297+default="initial",298+dest="data_set",299+help="Dataset folder under eval_output/ai_activity_type/eval_datasets/ (default: initial)",300+ )301+302+parser.add_argument(303+"--populate-ground-truth-llm",304+action="store_true",305+dest="populate_ground_truth_llm",306+ )307+parser.add_argument(308+"--ground-truth-llm-endpoint",309+type=str,310+default="OPENAI:gpt-5_2",311+dest="ground_truth_llm_endpoint",312+ )313+314+parser.add_argument(315+"--compare-to-ground-truth",316+type=str,317+choices=["es", "llm"],318+default="es",319+dest="compare_to_ground_truth",320+ )321+322+args = parser.parse_args()323+AiActivityTypeEvaluator.DATA_SET = args.data_set324+325+AiActivityTypeEvaluator.POPULATE_GROUND_TRUTH_LLM = bool(args.populate_ground_truth_llm)326+AiActivityTypeEvaluator.GROUND_TRUTH_LLM_ENDPOINT = args.ground_truth_llm_endpoint327+328+AiActivityTypeEvaluator.COMPARE_TO_GROUND_TRUTH = args.compare_to_ground_truth329+330+asyncio.run(run_evaluation(AiActivityTypeEvaluator, args))</selection>” selected. Please summarize the selection using precise and concise language. Use headers and bulleted lists in the summary, to make it scannable. Maintain the meaning and factual accuracy.
You said
I’m on page “<tabTitle>Jy 19798 evaluation for ai activity types by nikol</tabTitle>” with “<selection>@@ -0,0 +1,330 @@1+#!/usr/bin/env python32+import asyncio3+import json4+import os5+from pathlib import Path6+from typing import Any, Dict, List7+8+import aiohttp9+10+from src.component.call_processing.schemes.ai_activity_type_request import AiActivityTypeRequest11+from src.component.call_processing.schemes.ai_activity_type_response import AiActivityTypeResponse12+from src.eval.abstract_evaluator import AbstractEvaluator13+from src.eval.collectors import collect_test_set as es_collect_test_set14+from src.eval.common_evaluator_runner import create_parser, run_evaluation15+from src.eval.endpoints import run_endpoint as run_endpoint_http16+from src.eval.models import EvaluationResult17+18+19+class AiActivityTypeEvaluator(AbstractEvaluator):20+ENDPOINT_PATH = "call/ai-activity-type"21+REQUEST_MODEL = AiActivityTypeRequest22+RESPONSE_MODEL = AiActivityTypeResponse23+OUTPUT_SUBFOLDER = "ai_activity_type"24+USES_LLM_EVALUATION = False25+26+READS_FROM_DATASET_FOLDER = True27+28+DATA_SET: str = "initial"29+30+MINIMUM_REQUEST_BODY_SIZE: int = 031+32+SKIP_UNREPLAYABLE_ON_COLLECT: bool = True33+REPLAYABILITY_CHECK_TIMEOUT_SECONDS: float = 20.034+35+POPULATE_GROUND_TRUTH_LLM: bool = False36+GROUND_TRUTH_LLM_ENDPOINT: str = "OPENAI:gpt-5_2"37+38+COMPARE_TO_GROUND_TRUTH: str = "es"39+40+def __init__(self, **kwargs: Any) -> None:41+super().__init__(**kwargs)42+_repo_root = Path(__file__).parents[2]43+_datasets_root = _repo_root / "eval_output" / self.OUTPUT_SUBFOLDER / "eval_datasets"44+_dataset_dir = _datasets_root / self.__class__.DATA_SET45+self._dataset_dir = _dataset_dir46+self._inputs_dir = _dataset_dir / "input"47+self._ground_truths_dir = _dataset_dir / "ground_truth"48+49+async def collect_test_set(self) -> List[Dict[str, Any]]:50+if self.es_host_name:51+return await self._collect_from_es()52+return await self._collect_from_files()53+54+async def _collect_from_es(self) -> List[Dict[str, Any]]:55+if self._inputs_dir.exists() or self._ground_truths_dir.exists():56+raise FileExistsError(57+f"Dataset folder already exists: {self._inputs_dir.parent}. "58+"Choose a different --data-set name or remove the folder manually."59+ )60+61+raw_samples = await es_collect_test_set(62+es_host_name=self.es_host_name,63+es_port=self.es_port,64+endpoint_path=self.ENDPOINT_PATH,65+limit=self.limit,66+language_filter=self.language_filter,67+min_prompt_length=self.min_prompt_length,68+is_json_response=self.IS_JSON_RESPONSE,69+exclude_languages=self.exclude_languages,70+ )71+72+self._inputs_dir.mkdir(parents=True, exist_ok=True)73+self._ground_truths_dir.mkdir(parents=True, exist_ok=True)74+75+min_size = self.MINIMUM_REQUEST_BODY_SIZE76+samples: List[Dict[str, Any]] = []77+skipped_no_response = 078+skipped_too_small = 079+skipped_unreplayable = 080+skipped_probe_errors = 081+82+endpoint_url = f"{self.api_host}/{self.ENDPOINT_PATH}"83+84+timeout = aiohttp.ClientTimeout(total=self.REPLAYABILITY_CHECK_TIMEOUT_SECONDS)85+async with aiohttp.ClientSession(timeout=timeout) as session:86+for sample in raw_samples:87+es_id = sample["id"]88+request_body = sample["request_body"]89+original_response = sample.get("original_response")90+91+if not original_response:92+skipped_no_response += 193+continue94+95+if min_size and len(json.dumps(request_body)) < min_size:96+skipped_too_small += 197+continue98+99+if self.SKIP_UNREPLAYABLE_ON_COLLECT:100+try:101+async with session.post(endpoint_url, json=request_body) as resp:102+if resp.status != 200:103+body_text = await resp.text()104+if "Cannot find activity" in body_text:105+skipped_unreplayable += 1106+continue107+except Exception:108+skipped_probe_errors += 1109+110+with open(self._inputs_dir / f"{es_id}.json", "w") as f:111+json.dump(request_body, f, indent=2)112+113+with open(self._ground_truths_dir / f"gt_{es_id}.json", "w") as f:114+json.dump(original_response, f, indent=2)115+116+samples.append(117+ {118+"id": es_id,119+"request_body": request_body,120+"original_response": original_response,121+"ground_truth": original_response,122+ }123+ )124+125+print(f"Wrote {len(samples)} samples to {self._inputs_dir.parent}")126+if skipped_no_response:127+print(f"Skipped {skipped_no_response} records with no response body")128+if skipped_too_small:129+print(130+f"Skipped {skipped_too_small} records whose request body was smaller "131+f"than {min_size} characters"132+ )133+if skipped_unreplayable:134+print(f"Skipped {skipped_unreplayable} records that are not replayable (missing activity in ES)")135+if skipped_probe_errors:136+print(f"Warning: replayability probe errored for {skipped_probe_errors} records (kept those records)")137+138+if self.__class__.POPULATE_GROUND_TRUTH_LLM:139+label_results = await run_endpoint_http(140+test_set=samples,141+endpoint_url=endpoint_url,142+request_model=self.REQUEST_MODEL,143+force_llm_endpoint=self.__class__.GROUND_TRUTH_LLM_ENDPOINT,144+is_streaming_response=self.IS_STREAMING_RESPONSE,145+timeout_seconds=300.0,146+parallel_requests=self.parallel_requests,147+return_prompt_in_run=self.RETURN_PROMPT_IN_RUN,148+ )149+150+for i, r in enumerate(label_results):151+forced = self.__class__.GROUND_TRUTH_LLM_ENDPOINT152+model = forced.split(":", 1)[1] if ":" in forced else forced153+samples[i]["ground_truth_llm_model"] = model154+155+if not r.get("success", True):156+samples[i]["ground_truth_llm"] = None157+samples[i]["ground_truth_llm_reasoning"] = None158+samples[i]["ground_truth_llm_error_type"] = r.get("error_type")159+samples[i]["ground_truth_llm_error_message"] = r.get("error_message")160+continue161+162+resp = r.get("new_response") or {}163+samples[i]["ground_truth_llm"] = resp.get("ai_activity_type")164+samples[i]["ground_truth_llm_reasoning"] = resp.get("ai_activity_type_reasoning")165+166+return samples167+168+async def _collect_from_files(self) -> List[Dict[str, Any]]:169+if not self._inputs_dir.exists():170+raise FileNotFoundError(171+f"Dataset folder not found: {self._inputs_dir}. "172+"Run --steps collect first or check your --data-set name."173+ )174+175+samples: List[Dict[str, Any]] = []176+for filename in sorted(os.listdir(self._inputs_dir)):177+input_path = self._inputs_dir / filename178+gt_path = self._ground_truths_dir / f"gt_{filename}"179+180+if not gt_path.exists():181+print(f"Warning: ground truth not found for {filename}, skipping")182+continue183+184+with open(input_path, "r") as f:185+request_body: Dict[str, Any] = json.load(f)186+187+with open(gt_path, "r") as f:188+ground_truth: Dict[str, Any] = json.load(f)189+190+samples.append(191+ {192+"id": Path(filename).stem,193+"request_body": request_body,194+"original_response": None,195+"ground_truth": ground_truth,196+ }197+ )198+199+print(f"Loaded {len(samples)} samples from {self._inputs_dir.parent}")200+return samples201+202+async def evaluate_against_ground_truth(self, results: List[Dict[str, Any]]) -> List[EvaluationResult]:203+evaluation_results: List[EvaluationResult] = []204+compare_to = self.__class__.COMPARE_TO_GROUND_TRUTH205+206+for res in results:207+req_id = res["request_id"]208+is_success = res.get("success", True)209+210+if not is_success:211+evaluation_results.append(212+EvaluationResult(213+request_id=req_id,214+request_body=res["request_body"],215+new_response=res.get("new_response"),216+valid_schema=False,217+quality_score=0.0,218+quality_feedback=f"Request failed: {res.get('error_type')} - {res.get('error_message')}",219+response_time=res.get("response_time"),220+success=False,221+error_type=res.get("error_type"),222+error_message=res.get("error_message"),223+ground_truth_match=False,224+ )225+ )226+continue227+228+pred = (res.get("new_response") or {}).get("ai_activity_type")229+230+if compare_to == "llm":231+if "ground_truth_llm" not in res:232+evaluation_results.append(233+EvaluationResult(234+request_id=req_id,235+request_body=res["request_body"],236+new_response=res.get("new_response"),237+valid_schema=res.get("valid_schema", True),238+quality_score=0.0,239+quality_feedback=(240+"Missing ground_truth_llm in run results. Ensure collect step populated it and "241+"endpoints.py passes it through."242+ ),243+response_time=res.get("response_time"),244+success=True,245+ground_truth_match=False,246+ )247+ )248+continue249+gt_label = res.get("ground_truth_llm")250+else:251+gt_path = self._ground_truths_dir / f"gt_{req_id}.json"252+if not gt_path.exists():253+evaluation_results.append(254+EvaluationResult(255+request_id=req_id,256+request_body=res["request_body"],257+new_response=res.get("new_response"),258+valid_schema=res.get("valid_schema", True),259+quality_score=0.0,260+quality_feedback=f"Ground truth file not found: {gt_path}",261+response_time=res.get("response_time"),262+success=True,263+ground_truth_match=False,264+ )265+ )266+continue267+268+with open(gt_path, "r") as f:269+ground_truth_dict: Dict[str, Any] = json.load(f)270+271+gt_label = (ground_truth_dict or {}).get("ai_activity_type")272+273+matched = pred == gt_label274+275+evaluation_results.append(276+EvaluationResult(277+request_id=req_id,278+request_body=res["request_body"],279+new_response=res.get("new_response"),280+valid_schema=res.get("valid_schema", True),281+quality_score=1.0 if matched else 0.0,282+quality_feedback="PASS" if matched else f"FAIL\nExpected: {gt_label}\nGot: {pred}",283+response_time=res.get("response_time"),284+success=True,285+ground_truth_match=matched,286+ )287+ )288+289+return evaluation_results290+291+292+if __name__ == "__main__":293+parser = create_parser(AiActivityTypeEvaluator)294+parser.add_argument(295+"--data-set",296+type=str,297+default="initial",298+dest="data_set",299+help="Dataset folder under eval_output/ai_activity_type/eval_datasets/ (default: initial)",300+ )301+302+parser.add_argument(303+"--populate-ground-truth-llm",304+action="store_true",305+dest="populate_ground_truth_llm",306+ )307+parser.add_argument(308+"--ground-truth-llm-endpoint",309+type=str,310+default="OPENAI:gpt-5_2",311+dest="ground_truth_llm_endpoint",312+ )313+314+parser.add_argument(315+"--compare-to-ground-truth",316+type=str,317+choices=["es", "llm"],318+default="es",319+dest="compare_to_ground_truth",320+ )321+322+args = parser.parse_args()323+AiActivityTypeEvaluator.DATA_SET = args.data_set324+325+AiActivityTypeEvaluator.POPULATE_GROUND_TRUTH_LLM = bool(args.populate_ground_truth_llm)326+AiActivityTypeEvaluator.GROUND_TRUTH_LLM_ENDPOINT = args.ground_truth_llm_endpoint327+328+AiActivityTypeEvaluator.COMPARE_TO_GROUND_TRUTH = args.compare_to_ground_truth329+330+asyncio.run(run_evaluation(AiActivityTypeEvaluator, args))</selection>” selected.
Please summarize the selection using precise and concise language. Use headers and bulleted lists in the summary, to make it scannable. Maintain the meaning and factual accuracy.
Expand
Listen
Show more options
Gemini said
Gemini said
This Python script defines the
AiActivityTypeEvaluator
class, a specialized tool for evaluating AI-driven activity type classification. It extends a base evaluation framework to handle data collection, ground-truth comparison, and performance scoring.
Core Functionality
Core Functionality
Data Collection (
collect_test_set
):
* Supports fetching raw samples from
Elasticsearch (ES)
or loading them from
local JSON files
.
Implements a
replayability check
: It probes the live API endpoint to ensure the activity exists before including it in the dataset.
Filters data based on request body size, language, and the presence of an original response.
Ground Truth Management:
Saves inputs and "gold standard" responses to a local directory structure (
eval_output/ai_activity_type/...
).
Features an optional mode to populate ground truth using a high-order LLM (e.g.,
gpt-5_2
) if the
POPULATE_GROUND_TRUTH_LLM
flag is set.
Evaluation Logic (
evaluate_against_ground_truth
):
Compares the model's predicted
ai_activity_type
against either the original ES response or the LLM-generated ground truth.
Assigns a
quality_score
of
1.0
for a match and
0.0
for a mismatch or request failure.
Key Configuration Constants
Key Configuration Constants
Constant
Purpose
ENDPOINT_PATH
The specific API route being tested:
call/ai-activity-type
.
COMPARE_TO_GROUND_TRUTH
Determines if the baseline is the original data (
es
) or an
llm
.
SKIP_UNREPLAYABLE_ON_COLLECT
If
True
, discards records where the API returns "Cannot find activity."
REPLAYABILITY_CHECK_TIMEOUT_SECONDS
Limits the probe request to 20 seconds.
Constant
ENDPOINT_PATH
COMPARE_TO_GROUND_TRUTH
SKIP_UNREPLAYABLE_ON_COLLECT
REPLAYABILITY_CHECK_TIMEOUT_SECONDS
Purpose
The specific API route being tested:
call/ai-activity-type
.
Determines if the baseline is the original data (
es
) or an
llm
.
If
True
, discards records where the API returns "Cannot find activity."
Limits the probe request to 20 seconds.
Copy table
Execution Workflow
Execution Workflow
Parsing:
The script uses
create_parser
to handle CLI arguments like
--data-set
,
--populate-ground-truth-llm
, and
--compare-to-ground-truth
.
Initialization:
Sets up directory paths for inputs and ground truths based on the selected dataset name.
Run:
Executes the evaluation via
asyncio.run(run_evaluation(...))
, which orchestrates the collection, endpoint calling, and result scoring phases.
Copy prompt
Edit
You said are there soem issues with this PR
You said
are there soem issues with this PR
Listen
Show more options
Show thinking
Gemini said
Gemini said
Yes, there are several issues and code smells in this Pull Request, ranging from performance bottlenecks to architectural anti-patterns.
Here is a breakdown of the most notable issues, categorized by impact:
Performance & Async Anti-Patterns
Performance & Async Anti-Patterns
Sequential Requests Defeating Async (Lines 86-106):
Inside
_collect_from_es
, the code loops through
raw_samples
and
await
s a
session.post
request for each sample one by one. This means the script waits for one HTTP request to finish before starting the next, completely defeating the purpose of using
aiohttp
for asynchronous concurrency.
Fix:...
|
8588
|
|
10062
|
195
|
33
|
2026-04-14T08:10:00.248331+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776154200248_m2.jpg...
|
Firefox
|
Meet - Daily - Platform — Work
|
True
|
meet.google.com/mie-gawc-dsi
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
JY-20543 add AJ reports User pilot tracking by Lak JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
Console Home | Console Home | us-east-2
Console Home | Console Home | us-east-2
SecurityGroup | EC2 | us-east-2
SecurityGroup | EC2 | us-east-2
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app
SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Jiminny
Jiminny
Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf
Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf
Service-Desk - Queues - Platform team - Service space - Jira
Service-Desk - Queues - Platform team - Service space - Jira
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
CloudWatch | us-east-2
CloudWatch | us-east-2
Meet - Daily - Platform
Meet - Daily - Platform
Close tab
Settings
Settings
New Tab
Customize sidebar
Close Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
AI Chat settings
Close
WORK, Google Account: [EMAIL]
Main menu
New Chat
Open menu for conversation actions.
Conversation with Gemini
Conversation with Gemini
Copy prompt
Edit
You said why I can't see speaker data on meemt in firefox. ho wto set it up
You said
why I can't see speaker data on meemt in firefox. ho wto set it up
Listen
Show more options
Show thinking
Gemini said
Gemini said
Dealing with missing features right when you need them is incredibly frustrating. Assuming "meemt" means Google Meet, the reason you can't see your speaker data comes down to how Firefox interacts with Google's platform compared to Chrome.
Since "speaker data" can mean a couple of different things in a meeting, here are the two most likely causes for your issue and exactly how to get things working.
1. You Need "Speaker Notes" for Google Slides
1. You Need "Speaker Notes" for Google Slides
The Reality:
Google Meet has a native feature that lets you see your presentation's speaker notes right inside the video call interface.
However, this relies on a specific "Present a Tab" technology built exclusively for Google Chrome. Firefox handles screen sharing differently, so that native integration simply won't load.
View source details for citation from Google Workspace Updates. Opens side panel.
How to set it up (The Firefox Workaround):
You can still present and read your notes in Firefox by manually managing your windows.
Open your Google Slides presentation in a standard Firefox window.
Click the dropdown arrow next to the
Slideshow
button in the top right corner.
Select
Presenter view
to pop your speaker notes out into a separate, smaller window.
View source details for citation from Skywork. Opens side panel.
Join your Google Meet in a different Firefox window.
Click
Present now
and choose the
Window
option.
Select the window displaying your main slides (do not select your separate speaker notes window).
Resize your windows on your monitor so you can comfortably read the notes window while keeping an eye on the Meet window.
2. You Need "Speaker Labels" or Transcripts
2. You Need "Speaker Labels" or Transcripts
The Reality:
If you are trying to use a third-party AI note-taker (like Otter.ai, Tactiq, or tl;dv) to capture transcriptions and see who is speaking, Firefox is likely the roadblock. Firefox has strict privacy guardrails that prevent extensions from capturing internal browser audio easily, so most developers only build these tools for Chrome.
How to set it up:
Turn on built-in captions:
Google Meet has its own live captions that natively identify who is speaking, even in Firefox. Click the
CC
button at the bottom of your Meet screen to toggle them on.
Search for a Firefox add-on:
Check the Mozilla Add-ons store to see if your preferred tool actually has a supported Firefox version (for example, Fellow.ai offers one).
View source details for citation from Fellow.ai. Opens side panel.
Switch browsers temporarily:
If your specific transcription tool is explicitly Chrome-only, you will unfortunately need to join that specific meeting using a Chromium-based browser like Chrome, Edge, or Brave to capture the data.
Using Meet's built-in closed captions or the manual Presenter view workaround will get your speaker data back on track without forcing you to completely abandon Firefox.
Sources
Sources
I men in dia (arc) I can see my headphones in both microphone and speakers
I men in dia (arc) I can see my headphones in both microphone and speakers
Open upload file menu
Tools
Open mode picker
Pro
Send message
Your Jiminny chats aren’t used to improve our models. Gemini is AI and can make mistakes, including about people.
Your privacy & Gemini Opens in a new window
Your privacy & Gemini
Opens in a new window
Summarize page
Summarize page
Backgrounds and effects
Backgrounds and effects
Turn off visual effects
Back
Generate a background
No scene
No scene
Describe your idea
Create samples
Create samples
Learn more about generating backgrounds
Learn more about generating backgrounds
Close...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":4,"bounds":{"left":0.00234375,"top":0.045138888,"width":0.0890625,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira","depth":4,"bounds":{"left":0.0,"top":0.08263889,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira","depth":5,"bounds":{"left":0.015625,"top":0.09236111,"width":0.11796875,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":4,"bounds":{"left":0.0,"top":0.11111111,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":5,"bounds":{"left":0.015625,"top":0.12083333,"width":0.1515625,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Console Home | Console Home | us-east-2","depth":4,"bounds":{"left":0.0,"top":0.13958333,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Console Home | Console Home | us-east-2","depth":5,"bounds":{"left":0.015625,"top":0.14930555,"width":0.08671875,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"SecurityGroup | EC2 | us-east-2","depth":4,"bounds":{"left":0.0,"top":0.16805555,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"SecurityGroup | EC2 | us-east-2","depth":5,"bounds":{"left":0.015625,"top":0.17777778,"width":0.06484375,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.19652778,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":5,"bounds":{"left":0.015625,"top":0.20625,"width":0.18710938,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.225,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app","depth":5,"bounds":{"left":0.015625,"top":0.23472223,"width":0.23476562,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet","depth":4,"bounds":{"left":0.0,"top":0.2534722,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet","depth":5,"bounds":{"left":0.015625,"top":0.26319444,"width":0.1984375,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jiminny","depth":4,"bounds":{"left":0.0,"top":0.28194445,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny","depth":5,"bounds":{"left":0.015625,"top":0.29166666,"width":0.015625,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf","depth":4,"bounds":{"left":0.0,"top":0.31041667,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf","depth":5,"bounds":{"left":0.015625,"top":0.3201389,"width":0.1640625,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Service-Desk - Queues - Platform team - Service space - Jira","depth":4,"bounds":{"left":0.0,"top":0.33888888,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Service-Desk - Queues - Platform team - Service space - Jira","depth":5,"bounds":{"left":0.015625,"top":0.34861112,"width":0.12617187,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.3673611,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":5,"bounds":{"left":0.015625,"top":0.37708333,"width":0.18710938,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":4,"bounds":{"left":0.0,"top":0.39583334,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":5,"bounds":{"left":0.015625,"top":0.40555555,"width":0.1515625,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"CloudWatch | us-east-2","depth":4,"bounds":{"left":0.0,"top":0.42430556,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"CloudWatch | us-east-2","depth":5,"bounds":{"left":0.015625,"top":0.4340278,"width":0.0484375,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Meet - Daily - Platform","depth":4,"bounds":{"left":0.0,"top":0.45277777,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Meet - Daily - Platform","depth":5,"bounds":{"left":0.015625,"top":0.4625,"width":0.046484374,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.07890625,"top":0.45902777,"width":0.009375,"height":0.016666668},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Settings","depth":4,"bounds":{"left":0.0,"top":0.48125,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Settings","depth":5,"bounds":{"left":0.015625,"top":0.49097222,"width":0.016796876,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"New Tab","depth":4,"bounds":{"left":0.003125,"top":0.51111114,"width":0.08710937,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.003125,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Close Google Gemini (⌃X)","depth":6,"bounds":{"left":0.01640625,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"bounds":{"left":0.029296875,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"bounds":{"left":0.0421875,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"bounds":{"left":0.05546875,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"AI Chat settings","depth":7,"bounds":{"left":0.2171875,"top":0.047916666,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Close","depth":7,"bounds":{"left":0.23125,"top":0.047916666,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"WORK, Google Account: lukas.kovalik@jiminny.com","depth":12,"bounds":{"left":0.228125,"top":0.090277776,"width":0.015625,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Main menu","depth":12,"bounds":{"left":0.0984375,"top":0.090277776,"width":0.015625,"height":0.027777778},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Chat","depth":12,"bounds":{"left":0.1953125,"top":0.090277776,"width":0.015625,"height":0.027777778},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Open menu for conversation actions.","depth":12,"bounds":{"left":0.2109375,"top":0.090277776,"width":0.015625,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXHeading","text":"Conversation with Gemini","depth":15,"bounds":{"left":0.09335937,"top":0.12847222,"width":0.000390625,"height":0.00069444446},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Conversation with Gemini","depth":16,"bounds":{"left":0.09335937,"top":0.13055556,"width":0.14101562,"height":0.022222223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Copy prompt","depth":21,"bounds":{"left":0.1203125,"top":0.15972222,"width":0.015625,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Edit","depth":21,"bounds":{"left":0.1375,"top":0.15972222,"width":0.015625,"height":0.027777778},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"You said why I can't see speaker data on meemt in firefox. ho wto set it up","depth":21,"bounds":{"left":0.1609375,"top":0.16805555,"width":0.072265625,"height":0.058333334},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"You said","depth":23,"bounds":{"left":0.09335937,"top":0.1701389,"width":0.0234375,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"why I can't see speaker data on meemt in firefox. ho wto set it up","depth":23,"bounds":{"left":0.1609375,"top":0.17083333,"width":0.07070313,"height":0.05347222},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Listen","depth":22,"bounds":{"left":0.22382812,"top":0.25416666,"width":0.015625,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Show more options","depth":20,"bounds":{"left":0.22382812,"top":0.24930556,"width":0.015625,"height":0.027777778},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Show thinking","depth":26,"bounds":{"left":0.11953125,"top":0.25625,"width":0.036328126,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Gemini said","depth":20,"bounds":{"left":0.11679687,"top":0.2923611,"width":0.000390625,"height":0.00069444446},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Gemini said","depth":21,"bounds":{"left":0.11679687,"top":0.29375,"width":0.048046876,"height":0.016666668},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Dealing with missing features right when you need them is incredibly frustrating. Assuming \"meemt\" means Google Meet, the reason you can't see your speaker data comes down to how Firefox interacts with Google's platform compared to Chrome.","depth":24,"bounds":{"left":0.10390625,"top":0.30069444,"width":0.13046876,"height":0.10486111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Since \"speaker data\" can mean a couple of different things in a meeting, here are the two most likely causes for your issue and exactly how to get things working.","depth":24,"bounds":{"left":0.10390625,"top":0.4201389,"width":0.13125,"height":0.06875},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"1. You Need \"Speaker Notes\" for Google Slides","depth":23,"bounds":{"left":0.10390625,"top":0.52152777,"width":0.13242188,"height":0.033333335},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1. You Need \"Speaker Notes\" for Google Slides","depth":24,"bounds":{"left":0.10390625,"top":0.5229167,"width":0.12070312,"height":0.03125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"The Reality:","depth":24,"bounds":{"left":0.10390625,"top":0.5625,"width":0.036328126,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Google Meet has a native feature that lets you see your presentation's speaker notes right inside the video call interface.","depth":24,"bounds":{"left":0.10390625,"top":0.5625,"width":0.13242188,"height":0.050694443},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"However, this relies on a specific \"Present a Tab\" technology built exclusively for Google Chrome. Firefox handles screen sharing differently, so that native integration simply won't load.","depth":24,"bounds":{"left":0.10390625,"top":0.5986111,"width":0.12539062,"height":0.10486111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"View source details for citation from Google Workspace Updates. Opens side panel.","depth":24,"bounds":{"left":0.13710937,"top":0.68958336,"width":0.01015625,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"How to set it up (The Firefox Workaround):","depth":24,"bounds":{"left":0.10390625,"top":0.71805555,"width":0.12851563,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"You can still present and read your notes in Firefox by manually managing your windows.","depth":24,"bounds":{"left":0.10390625,"top":0.7361111,"width":0.12617187,"height":0.03263889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Open your Google Slides presentation in a standard Firefox window.","depth":26,"bounds":{"left":0.11796875,"top":0.7777778,"width":0.115625,"height":0.03263889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Click the dropdown arrow next to the","depth":26,"bounds":{"left":0.11796875,"top":0.8194444,"width":0.10703125,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Slideshow","depth":26,"bounds":{"left":0.11796875,"top":0.8375,"width":0.03125,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"button in the top right corner.","depth":26,"bounds":{"left":0.14921875,"top":0.8375,"width":0.08515625,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Select","depth":26,"bounds":{"left":0.11796875,"top":0.8611111,"width":0.01953125,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Presenter view","depth":26,"bounds":{"left":0.1375,"top":0.8611111,"width":0.0453125,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"to pop your speaker notes out into a separate, smaller window.","depth":26,"bounds":{"left":0.11796875,"top":0.8611111,"width":0.10078125,"height":0.050694443},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"View source details for citation from Skywork. Opens side panel.","depth":26,"bounds":{"left":0.16523437,"top":0.8979167,"width":0.01015625,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Join your Google Meet in a different Firefox window.","depth":26,"bounds":{"left":0.11796875,"top":0.92083335,"width":0.103125,"height":0.03263889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Click","depth":26,"bounds":{"left":0.11796875,"top":0.9625,"width":0.015234375,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Present now","depth":26,"bounds":{"left":0.13320312,"top":0.9625,"width":0.037890624,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"and choose the","depth":26,"bounds":{"left":0.17109375,"top":0.9625,"width":0.047265626,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Window","depth":26,"bounds":{"left":0.11796875,"top":0.98055553,"width":0.02421875,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"option.","depth":26,"bounds":{"left":0.1421875,"top":0.98055553,"width":0.02109375,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Select the window displaying your main slides (do not select your separate speaker notes window).","depth":26,"bounds":{"left":0.11796875,"top":1.0,"width":0.11328125,"height":-0.0041667223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Resize your windows on your monitor so you can comfortably read the notes window while keeping an eye on the Meet window.","depth":26,"bounds":{"left":0.11796875,"top":1.0,"width":0.11835937,"height":-0.06388891},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"2. You Need \"Speaker Labels\" or Transcripts","depth":23,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2. You Need \"Speaker Labels\" or Transcripts","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"The Reality:","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"If you are trying to use a third-party AI note-taker (like Otter.ai, Tactiq, or tl;dv) to capture transcriptions and see who is speaking, Firefox is likely the roadblock. Firefox has strict privacy guardrails that prevent extensions from capturing internal browser audio easily, so most developers only build these tools for Chrome.","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"How to set it up:","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Turn on built-in captions:","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Google Meet has its own live captions that natively identify who is speaking, even in Firefox. Click the","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"CC","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"button at the bottom of your Meet screen to toggle them on.","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Search for a Firefox add-on:","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Check the Mozilla Add-ons store to see if your preferred tool actually has a supported Firefox version (for example, Fellow.ai offers one).","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"View source details for citation from Fellow.ai. Opens side panel.","depth":26,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Switch browsers temporarily:","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"If your specific transcription tool is explicitly Chrome-only, you will unfortunately need to join that specific meeting using a Chromium-based browser like Chrome, Edge, or Brave to capture the data.","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Using Meet's built-in closed captions or the manual Presenter view workaround will get your speaker data back on track without forcing you to completely abandon Firefox.","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Sources","depth":23,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Sources","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextArea","text":"I men in dia (arc) I can see my headphones in both microphone and speakers","depth":20,"bounds":{"left":0.109375,"top":0.8020833,"width":0.125,"height":0.05},"value":"I men in dia (arc) I can see my headphones in both microphone and speakers","help_text":"","role_description":"text entry area","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"I men in dia (arc) I can see my headphones in both microphone and speakers","depth":22,"bounds":{"left":0.109375,"top":0.8034722,"width":0.10625,"height":0.047916666},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open upload file menu","depth":20,"bounds":{"left":0.1046875,"top":0.86527777,"width":0.015625,"height":0.027777778},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Tools","depth":18,"bounds":{"left":0.1234375,"top":0.86527777,"width":0.015625,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Open mode picker","depth":20,"bounds":{"left":0.190625,"top":0.8645833,"width":0.03046875,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pro","depth":23,"bounds":{"left":0.196875,"top":0.87222224,"width":0.00859375,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Send message","depth":19,"bounds":{"left":0.22265625,"top":0.86388886,"width":0.01640625,"height":0.029166667},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Your Jiminny chats aren’t used to improve our models. Gemini is AI and can make mistakes, including about people.","depth":17,"bounds":{"left":0.10039063,"top":0.9097222,"width":0.14296874,"height":0.022222223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Your privacy & Gemini Opens in a new window","depth":17,"bounds":{"left":0.1484375,"top":0.93194443,"width":0.046875,"height":0.011111111},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Your privacy & Gemini","depth":18,"bounds":{"left":0.1484375,"top":0.93194443,"width":0.046875,"height":0.011111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Opens in a new window","depth":19,"bounds":{"left":0.09335937,"top":0.93125,"width":0.05078125,"height":0.011111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Summarize page","depth":7,"bounds":{"left":0.1,"top":0.96319443,"width":0.06289063,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Summarize page","depth":9,"bounds":{"left":0.10664062,"top":0.9673611,"width":0.049609374,"height":0.013888889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Backgrounds and effects","depth":11,"bounds":{"left":0.3921875,"top":0.28958333,"width":0.46289062,"height":0.055555556},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Backgrounds and effects","depth":12,"bounds":{"left":0.4015625,"top":0.30694443,"width":0.10546875,"height":0.021527778},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Turn off visual effects","depth":14,"bounds":{"left":0.675,"top":0.59652776,"width":0.021875,"height":0.03888889},"role_description":"button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Back","depth":15,"bounds":{"left":0.7109375,"top":0.34513888,"width":0.015625,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":true,"is_selected":false},{"role":"AXStaticText","text":"Generate a background","depth":14,"bounds":{"left":0.7265625,"top":0.35,"width":0.08710937,"height":0.018055556},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXComboBox","text":"No scene","depth":15,"bounds":{"left":0.715625,"top":0.38125,"width":0.13125,"height":0.03888889},"value":"No scene","help_text":"","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"No scene","depth":17,"bounds":{"left":0.740625,"top":0.39375,"width":0.0265625,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextArea","text":"Describe your idea","depth":16,"bounds":{"left":0.715625,"top":0.44236112,"width":0.13125,"height":0.06666667},"help_text":"","placeholder":"Jungle patio at sunset","role_description":"text entry area","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Create samples","depth":16,"bounds":{"left":0.7515625,"top":0.53402776,"width":0.059375,"height":0.025},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Create samples","depth":18,"bounds":{"left":0.7609375,"top":0.5402778,"width":0.040625,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Learn more about generating backgrounds","depth":16,"bounds":{"left":0.73398435,"top":0.5715278,"width":0.09453125,"height":0.011111111},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Learn more about generating backgrounds","depth":17,"bounds":{"left":0.73398435,"top":0.5715278,"width":0.09453125,"height":0.011111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close","depth":11,"bounds":{"left":0.83320314,"top":0.30069444,"width":0.01875,"height":0.033333335},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false}]...
|
-7263733678066306169
|
8731697523133232206
|
visual_change
|
accessibility
|
NULL
|
JY-20543 add AJ reports User pilot tracking by Lak JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
Console Home | Console Home | us-east-2
Console Home | Console Home | us-east-2
SecurityGroup | EC2 | us-east-2
SecurityGroup | EC2 | us-east-2
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app
SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Jiminny
Jiminny
Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf
Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf
Service-Desk - Queues - Platform team - Service space - Jira
Service-Desk - Queues - Platform team - Service space - Jira
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
CloudWatch | us-east-2
CloudWatch | us-east-2
Meet - Daily - Platform
Meet - Daily - Platform
Close tab
Settings
Settings
New Tab
Customize sidebar
Close Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
AI Chat settings
Close
WORK, Google Account: [EMAIL]
Main menu
New Chat
Open menu for conversation actions.
Conversation with Gemini
Conversation with Gemini
Copy prompt
Edit
You said why I can't see speaker data on meemt in firefox. ho wto set it up
You said
why I can't see speaker data on meemt in firefox. ho wto set it up
Listen
Show more options
Show thinking
Gemini said
Gemini said
Dealing with missing features right when you need them is incredibly frustrating. Assuming "meemt" means Google Meet, the reason you can't see your speaker data comes down to how Firefox interacts with Google's platform compared to Chrome.
Since "speaker data" can mean a couple of different things in a meeting, here are the two most likely causes for your issue and exactly how to get things working.
1. You Need "Speaker Notes" for Google Slides
1. You Need "Speaker Notes" for Google Slides
The Reality:
Google Meet has a native feature that lets you see your presentation's speaker notes right inside the video call interface.
However, this relies on a specific "Present a Tab" technology built exclusively for Google Chrome. Firefox handles screen sharing differently, so that native integration simply won't load.
View source details for citation from Google Workspace Updates. Opens side panel.
How to set it up (The Firefox Workaround):
You can still present and read your notes in Firefox by manually managing your windows.
Open your Google Slides presentation in a standard Firefox window.
Click the dropdown arrow next to the
Slideshow
button in the top right corner.
Select
Presenter view
to pop your speaker notes out into a separate, smaller window.
View source details for citation from Skywork. Opens side panel.
Join your Google Meet in a different Firefox window.
Click
Present now
and choose the
Window
option.
Select the window displaying your main slides (do not select your separate speaker notes window).
Resize your windows on your monitor so you can comfortably read the notes window while keeping an eye on the Meet window.
2. You Need "Speaker Labels" or Transcripts
2. You Need "Speaker Labels" or Transcripts
The Reality:
If you are trying to use a third-party AI note-taker (like Otter.ai, Tactiq, or tl;dv) to capture transcriptions and see who is speaking, Firefox is likely the roadblock. Firefox has strict privacy guardrails that prevent extensions from capturing internal browser audio easily, so most developers only build these tools for Chrome.
How to set it up:
Turn on built-in captions:
Google Meet has its own live captions that natively identify who is speaking, even in Firefox. Click the
CC
button at the bottom of your Meet screen to toggle them on.
Search for a Firefox add-on:
Check the Mozilla Add-ons store to see if your preferred tool actually has a supported Firefox version (for example, Fellow.ai offers one).
View source details for citation from Fellow.ai. Opens side panel.
Switch browsers temporarily:
If your specific transcription tool is explicitly Chrome-only, you will unfortunately need to join that specific meeting using a Chromium-based browser like Chrome, Edge, or Brave to capture the data.
Using Meet's built-in closed captions or the manual Presenter view workaround will get your speaker data back on track without forcing you to completely abandon Firefox.
Sources
Sources
I men in dia (arc) I can see my headphones in both microphone and speakers
I men in dia (arc) I can see my headphones in both microphone and speakers
Open upload file menu
Tools
Open mode picker
Pro
Send message
Your Jiminny chats aren’t used to improve our models. Gemini is AI and can make mistakes, including about people.
Your privacy & Gemini Opens in a new window
Your privacy & Gemini
Opens in a new window
Summarize page
Summarize page
Backgrounds and effects
Backgrounds and effects
Turn off visual effects
Back
Generate a background
No scene
No scene
Describe your idea
Create samples
Create samples
Learn more about generating backgrounds
Learn more about generating backgrounds
Close...
|
10061
|
|
10066
|
195
|
35
|
2026-04-14T08:10:03.883667+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776154203883_m2.jpg...
|
Firefox
|
Meet - Daily - Platform — Work
|
True
|
meet.google.com/mie-gawc-dsi
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
JY-20543 add AJ reports User pilot tracking by Lak JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
Console Home | Console Home | us-east-2
Console Home | Console Home | us-east-2
SecurityGroup | EC2 | us-east-2
SecurityGroup | EC2 | us-east-2
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app
SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Jiminny
Jiminny
Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf
Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf
Service-Desk - Queues - Platform team - Service space - Jira
Service-Desk - Queues - Platform team - Service space - Jira
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
CloudWatch | us-east-2
CloudWatch | us-east-2
Meet - Daily - Platform
Meet - Daily - Platform
Close tab
Settings
Settings
New Tab
Customize sidebar
Close Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
AI Chat settings
Close
WORK, Google Account: [EMAIL]
Main menu
New Chat
Open menu for conversation actions.
Conversation with Gemini
Conversation with Gemini
Copy prompt
Edit
You said why I can't see speaker data on meemt in firefox. ho wto set it up
You said
why I can't see speaker data on meemt in firefox. ho wto set it up
Listen
Show more options
Show thinking
Gemini said
Gemini said
Dealing with missing features right when you need them is incredibly frustrating. Assuming "meemt" means Google Meet, the reason you can't see your speaker data comes down to how Firefox interacts with Google's platform compared to Chrome.
Since "speaker data" can mean a couple of different things in a meeting, here are the two most likely causes for your issue and exactly how to get things working.
1. You Need "Speaker Notes" for Google Slides
1. You Need "Speaker Notes" for Google Slides
The Reality:
Google Meet has a native feature that lets you see your presentation's speaker notes right inside the video call interface.
However, this relies on a specific "Present a Tab" technology built exclusively for Google Chrome. Firefox handles screen sharing differently, so that native integration simply won't load.
View source details for citation from Google Workspace Updates. Opens side panel.
How to set it up (The Firefox Workaround):
You can still present and read your notes in Firefox by manually managing your windows.
Open your Google Slides presentation in a standard Firefox window.
Click the dropdown arrow next to the
Slideshow
button in the top right corner.
Select
Presenter view
to pop your speaker notes out into a separate, smaller window.
View source details for citation from Skywork. Opens side panel.
Join your Google Meet in a different Firefox window.
Click
Present now
and choose the
Window
option.
Select the window displaying your main slides (do not select your separate speaker notes window).
Resize your windows on your monitor so you can comfortably read the notes window while keeping an eye on the Meet window.
2. You Need "Speaker Labels" or Transcripts
2. You Need "Speaker Labels" or Transcripts
The Reality:
If you are trying to use a third-party AI note-taker (like Otter.ai, Tactiq, or tl;dv) to capture transcriptions and see who is speaking, Firefox is likely the roadblock. Firefox has strict privacy guardrails that prevent extensions from capturing internal browser audio easily, so most developers only build these tools for Chrome.
How to set it up:
Turn on built-in captions:
Google Meet has its own live captions that natively identify who is speaking, even in Firefox. Click the
CC
button at the bottom of your Meet screen to toggle them on.
Search for a Firefox add-on:
Check the Mozilla Add-ons store to see if your preferred tool actually has a supported Firefox version (for example, Fellow.ai offers one).
View source details for citation from Fellow.ai. Opens side panel.
Switch browsers temporarily:
If your specific transcription tool is explicitly Chrome-only, you will unfortunately need to join that specific meeting using a Chromium-based browser like Chrome, Edge, or Brave to capture the data.
Using Meet's built-in closed captions or the manual Presenter view workaround will get your speaker data back on track without forcing you to completely abandon Firefox.
Sources
Sources
I men in dia (arc) I can see my headphones in both microphone and speakers
I men in dia (arc) I can see my headphones in both microphone and speakers
Open upload file menu
Tools
Open mode picker
Pro
Send message
Your Jiminny chats aren’t used to improve our models. Gemini is AI and can make mistakes, including about people.
Your privacy & Gemini Opens in a new window
Your privacy & Gemini
Opens in a new window
Summarize page
Summarize page
Backgrounds and effects
Backgrounds and effects
Turn off visual effects
Back
Generate a background
No scene
No scene
Describe your idea
Create samples
Create samples
Learn more about generating backgrounds
Learn more about generating backgrounds
Close...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":4,"bounds":{"left":0.00234375,"top":0.045138888,"width":0.0890625,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira","depth":4,"bounds":{"left":0.0,"top":0.08263889,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira","depth":5,"bounds":{"left":0.015625,"top":0.09236111,"width":0.11796875,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":4,"bounds":{"left":0.0,"top":0.11111111,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":5,"bounds":{"left":0.015625,"top":0.12083333,"width":0.1515625,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Console Home | Console Home | us-east-2","depth":4,"bounds":{"left":0.0,"top":0.13958333,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Console Home | Console Home | us-east-2","depth":5,"bounds":{"left":0.015625,"top":0.14930555,"width":0.08671875,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"SecurityGroup | EC2 | us-east-2","depth":4,"bounds":{"left":0.0,"top":0.16805555,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"SecurityGroup | EC2 | us-east-2","depth":5,"bounds":{"left":0.015625,"top":0.17777778,"width":0.06484375,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.19652778,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":5,"bounds":{"left":0.015625,"top":0.20625,"width":0.18710938,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.225,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app","depth":5,"bounds":{"left":0.015625,"top":0.23472223,"width":0.23476562,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet","depth":4,"bounds":{"left":0.0,"top":0.2534722,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet","depth":5,"bounds":{"left":0.015625,"top":0.26319444,"width":0.1984375,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jiminny","depth":4,"bounds":{"left":0.0,"top":0.28194445,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny","depth":5,"bounds":{"left":0.015625,"top":0.29166666,"width":0.015625,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf","depth":4,"bounds":{"left":0.0,"top":0.31041667,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf","depth":5,"bounds":{"left":0.015625,"top":0.3201389,"width":0.1640625,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Service-Desk - Queues - Platform team - Service space - Jira","depth":4,"bounds":{"left":0.0,"top":0.33888888,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Service-Desk - Queues - Platform team - Service space - Jira","depth":5,"bounds":{"left":0.015625,"top":0.34861112,"width":0.12617187,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.3673611,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":5,"bounds":{"left":0.015625,"top":0.37708333,"width":0.18710938,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":4,"bounds":{"left":0.0,"top":0.39583334,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":5,"bounds":{"left":0.015625,"top":0.40555555,"width":0.1515625,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"CloudWatch | us-east-2","depth":4,"bounds":{"left":0.0,"top":0.42430556,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"CloudWatch | us-east-2","depth":5,"bounds":{"left":0.015625,"top":0.4340278,"width":0.0484375,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Meet - Daily - Platform","depth":4,"bounds":{"left":0.0,"top":0.45277777,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Meet - Daily - Platform","depth":5,"bounds":{"left":0.015625,"top":0.4625,"width":0.046484374,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.07890625,"top":0.45902777,"width":0.009375,"height":0.016666668},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Settings","depth":4,"bounds":{"left":0.0,"top":0.48125,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Settings","depth":5,"bounds":{"left":0.015625,"top":0.49097222,"width":0.016796876,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"New Tab","depth":4,"bounds":{"left":0.003125,"top":0.51111114,"width":0.08710937,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.003125,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Close Google Gemini (⌃X)","depth":6,"bounds":{"left":0.01640625,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"bounds":{"left":0.029296875,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"bounds":{"left":0.0421875,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"bounds":{"left":0.05546875,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"AI Chat settings","depth":7,"bounds":{"left":0.2171875,"top":0.047916666,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Close","depth":7,"bounds":{"left":0.23125,"top":0.047916666,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"WORK, Google Account: lukas.kovalik@jiminny.com","depth":12,"bounds":{"left":0.228125,"top":0.090277776,"width":0.015625,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Main menu","depth":12,"bounds":{"left":0.0984375,"top":0.090277776,"width":0.015625,"height":0.027777778},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Chat","depth":12,"bounds":{"left":0.1953125,"top":0.090277776,"width":0.015625,"height":0.027777778},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Open menu for conversation actions.","depth":12,"bounds":{"left":0.2109375,"top":0.090277776,"width":0.015625,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXHeading","text":"Conversation with Gemini","depth":15,"bounds":{"left":0.09335937,"top":0.12847222,"width":0.000390625,"height":0.00069444446},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Conversation with Gemini","depth":16,"bounds":{"left":0.09335937,"top":0.13055556,"width":0.14101562,"height":0.022222223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Copy prompt","depth":21,"bounds":{"left":0.1203125,"top":0.15972222,"width":0.015625,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Edit","depth":21,"bounds":{"left":0.1375,"top":0.15972222,"width":0.015625,"height":0.027777778},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"You said why I can't see speaker data on meemt in firefox. ho wto set it up","depth":21,"bounds":{"left":0.1609375,"top":0.16805555,"width":0.072265625,"height":0.058333334},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"You said","depth":23,"bounds":{"left":0.09335937,"top":0.1701389,"width":0.0234375,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"why I can't see speaker data on meemt in firefox. ho wto set it up","depth":23,"bounds":{"left":0.1609375,"top":0.17083333,"width":0.07070313,"height":0.05347222},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Listen","depth":22,"bounds":{"left":0.22382812,"top":0.25416666,"width":0.015625,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Show more options","depth":20,"bounds":{"left":0.22382812,"top":0.24930556,"width":0.015625,"height":0.027777778},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Show thinking","depth":26,"bounds":{"left":0.11953125,"top":0.25625,"width":0.036328126,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Gemini said","depth":20,"bounds":{"left":0.11679687,"top":0.2923611,"width":0.000390625,"height":0.00069444446},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Gemini said","depth":21,"bounds":{"left":0.11679687,"top":0.29375,"width":0.048046876,"height":0.016666668},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Dealing with missing features right when you need them is incredibly frustrating. Assuming \"meemt\" means Google Meet, the reason you can't see your speaker data comes down to how Firefox interacts with Google's platform compared to Chrome.","depth":24,"bounds":{"left":0.10390625,"top":0.30069444,"width":0.13046876,"height":0.10486111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Since \"speaker data\" can mean a couple of different things in a meeting, here are the two most likely causes for your issue and exactly how to get things working.","depth":24,"bounds":{"left":0.10390625,"top":0.4201389,"width":0.13125,"height":0.06875},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"1. You Need \"Speaker Notes\" for Google Slides","depth":23,"bounds":{"left":0.10390625,"top":0.52152777,"width":0.13242188,"height":0.033333335},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1. You Need \"Speaker Notes\" for Google Slides","depth":24,"bounds":{"left":0.10390625,"top":0.5229167,"width":0.12070312,"height":0.03125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"The Reality:","depth":24,"bounds":{"left":0.10390625,"top":0.5625,"width":0.036328126,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Google Meet has a native feature that lets you see your presentation's speaker notes right inside the video call interface.","depth":24,"bounds":{"left":0.10390625,"top":0.5625,"width":0.13242188,"height":0.050694443},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"However, this relies on a specific \"Present a Tab\" technology built exclusively for Google Chrome. Firefox handles screen sharing differently, so that native integration simply won't load.","depth":24,"bounds":{"left":0.10390625,"top":0.5986111,"width":0.12539062,"height":0.10486111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"View source details for citation from Google Workspace Updates. Opens side panel.","depth":24,"bounds":{"left":0.13710937,"top":0.68958336,"width":0.01015625,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"How to set it up (The Firefox Workaround):","depth":24,"bounds":{"left":0.10390625,"top":0.71805555,"width":0.12851563,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"You can still present and read your notes in Firefox by manually managing your windows.","depth":24,"bounds":{"left":0.10390625,"top":0.7361111,"width":0.12617187,"height":0.03263889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Open your Google Slides presentation in a standard Firefox window.","depth":26,"bounds":{"left":0.11796875,"top":0.7777778,"width":0.115625,"height":0.03263889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Click the dropdown arrow next to the","depth":26,"bounds":{"left":0.11796875,"top":0.8194444,"width":0.10703125,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Slideshow","depth":26,"bounds":{"left":0.11796875,"top":0.8375,"width":0.03125,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"button in the top right corner.","depth":26,"bounds":{"left":0.14921875,"top":0.8375,"width":0.08515625,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Select","depth":26,"bounds":{"left":0.11796875,"top":0.8611111,"width":0.01953125,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Presenter view","depth":26,"bounds":{"left":0.1375,"top":0.8611111,"width":0.0453125,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"to pop your speaker notes out into a separate, smaller window.","depth":26,"bounds":{"left":0.11796875,"top":0.8611111,"width":0.10078125,"height":0.050694443},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"View source details for citation from Skywork. Opens side panel.","depth":26,"bounds":{"left":0.16523437,"top":0.8979167,"width":0.01015625,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Join your Google Meet in a different Firefox window.","depth":26,"bounds":{"left":0.11796875,"top":0.92083335,"width":0.103125,"height":0.03263889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Click","depth":26,"bounds":{"left":0.11796875,"top":0.9625,"width":0.015234375,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Present now","depth":26,"bounds":{"left":0.13320312,"top":0.9625,"width":0.037890624,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"and choose the","depth":26,"bounds":{"left":0.17109375,"top":0.9625,"width":0.047265626,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Window","depth":26,"bounds":{"left":0.11796875,"top":0.98055553,"width":0.02421875,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"option.","depth":26,"bounds":{"left":0.1421875,"top":0.98055553,"width":0.02109375,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Select the window displaying your main slides (do not select your separate speaker notes window).","depth":26,"bounds":{"left":0.11796875,"top":1.0,"width":0.11328125,"height":-0.0041667223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Resize your windows on your monitor so you can comfortably read the notes window while keeping an eye on the Meet window.","depth":26,"bounds":{"left":0.11796875,"top":1.0,"width":0.11835937,"height":-0.06388891},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"2. You Need \"Speaker Labels\" or Transcripts","depth":23,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2. You Need \"Speaker Labels\" or Transcripts","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"The Reality:","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"If you are trying to use a third-party AI note-taker (like Otter.ai, Tactiq, or tl;dv) to capture transcriptions and see who is speaking, Firefox is likely the roadblock. Firefox has strict privacy guardrails that prevent extensions from capturing internal browser audio easily, so most developers only build these tools for Chrome.","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"How to set it up:","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Turn on built-in captions:","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Google Meet has its own live captions that natively identify who is speaking, even in Firefox. Click the","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"CC","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"button at the bottom of your Meet screen to toggle them on.","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Search for a Firefox add-on:","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Check the Mozilla Add-ons store to see if your preferred tool actually has a supported Firefox version (for example, Fellow.ai offers one).","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"View source details for citation from Fellow.ai. Opens side panel.","depth":26,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Switch browsers temporarily:","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"If your specific transcription tool is explicitly Chrome-only, you will unfortunately need to join that specific meeting using a Chromium-based browser like Chrome, Edge, or Brave to capture the data.","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Using Meet's built-in closed captions or the manual Presenter view workaround will get your speaker data back on track without forcing you to completely abandon Firefox.","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Sources","depth":23,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Sources","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextArea","text":"I men in dia (arc) I can see my headphones in both microphone and speakers","depth":20,"bounds":{"left":0.109375,"top":0.8020833,"width":0.125,"height":0.05},"value":"I men in dia (arc) I can see my headphones in both microphone and speakers","help_text":"","role_description":"text entry area","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"I men in dia (arc) I can see my headphones in both microphone and speakers","depth":22,"bounds":{"left":0.109375,"top":0.8034722,"width":0.10625,"height":0.047916666},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open upload file menu","depth":20,"bounds":{"left":0.1046875,"top":0.86527777,"width":0.015625,"height":0.027777778},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Tools","depth":18,"bounds":{"left":0.1234375,"top":0.86527777,"width":0.015625,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Open mode picker","depth":20,"bounds":{"left":0.190625,"top":0.8645833,"width":0.03046875,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pro","depth":23,"bounds":{"left":0.196875,"top":0.87222224,"width":0.00859375,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Send message","depth":19,"bounds":{"left":0.22265625,"top":0.86388886,"width":0.01640625,"height":0.029166667},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Your Jiminny chats aren’t used to improve our models. Gemini is AI and can make mistakes, including about people.","depth":17,"bounds":{"left":0.10039063,"top":0.9097222,"width":0.14296874,"height":0.022222223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Your privacy & Gemini Opens in a new window","depth":17,"bounds":{"left":0.1484375,"top":0.93194443,"width":0.046875,"height":0.011111111},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Your privacy & Gemini","depth":18,"bounds":{"left":0.1484375,"top":0.93194443,"width":0.046875,"height":0.011111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Opens in a new window","depth":19,"bounds":{"left":0.09335937,"top":0.93125,"width":0.05078125,"height":0.011111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Summarize page","depth":7,"bounds":{"left":0.1,"top":0.96319443,"width":0.06289063,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Summarize page","depth":9,"bounds":{"left":0.10664062,"top":0.9673611,"width":0.049609374,"height":0.013888889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Backgrounds and effects","depth":11,"bounds":{"left":0.3921875,"top":0.28958333,"width":0.46289062,"height":0.055555556},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Backgrounds and effects","depth":12,"bounds":{"left":0.4015625,"top":0.30694443,"width":0.10546875,"height":0.021527778},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Turn off visual effects","depth":14,"bounds":{"left":0.675,"top":0.59652776,"width":0.021875,"height":0.03888889},"role_description":"button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Back","depth":15,"bounds":{"left":0.7109375,"top":0.34513888,"width":0.015625,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Generate a background","depth":14,"bounds":{"left":0.7265625,"top":0.35,"width":0.08710937,"height":0.018055556},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXComboBox","text":"No scene","depth":15,"bounds":{"left":0.715625,"top":0.38125,"width":0.13125,"height":0.03888889},"value":"No scene","help_text":"","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"No scene","depth":17,"bounds":{"left":0.740625,"top":0.39375,"width":0.0265625,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextArea","text":"Describe your idea","depth":16,"bounds":{"left":0.715625,"top":0.44236112,"width":0.13125,"height":0.06666667},"help_text":"","placeholder":"Jungle patio at sunset","role_description":"text entry area","subrole":"AXUnknown","is_enabled":true,"is_focused":true,"is_selected":false},{"role":"AXButton","text":"Create samples","depth":16,"bounds":{"left":0.7515625,"top":0.53402776,"width":0.059375,"height":0.025},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Create samples","depth":18,"bounds":{"left":0.7609375,"top":0.5402778,"width":0.040625,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Learn more about generating backgrounds","depth":16,"bounds":{"left":0.73398435,"top":0.5715278,"width":0.09453125,"height":0.011111111},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Learn more about generating backgrounds","depth":17,"bounds":{"left":0.73398435,"top":0.5715278,"width":0.09453125,"height":0.011111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close","depth":11,"bounds":{"left":0.83320314,"top":0.30069444,"width":0.01875,"height":0.033333335},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false}]...
|
-7263733678066306169
|
8731697523133232206
|
click
|
accessibility
|
NULL
|
JY-20543 add AJ reports User pilot tracking by Lak JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
Console Home | Console Home | us-east-2
Console Home | Console Home | us-east-2
SecurityGroup | EC2 | us-east-2
SecurityGroup | EC2 | us-east-2
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app
SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Jiminny
Jiminny
Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf
Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf
Service-Desk - Queues - Platform team - Service space - Jira
Service-Desk - Queues - Platform team - Service space - Jira
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
CloudWatch | us-east-2
CloudWatch | us-east-2
Meet - Daily - Platform
Meet - Daily - Platform
Close tab
Settings
Settings
New Tab
Customize sidebar
Close Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
AI Chat settings
Close
WORK, Google Account: [EMAIL]
Main menu
New Chat
Open menu for conversation actions.
Conversation with Gemini
Conversation with Gemini
Copy prompt
Edit
You said why I can't see speaker data on meemt in firefox. ho wto set it up
You said
why I can't see speaker data on meemt in firefox. ho wto set it up
Listen
Show more options
Show thinking
Gemini said
Gemini said
Dealing with missing features right when you need them is incredibly frustrating. Assuming "meemt" means Google Meet, the reason you can't see your speaker data comes down to how Firefox interacts with Google's platform compared to Chrome.
Since "speaker data" can mean a couple of different things in a meeting, here are the two most likely causes for your issue and exactly how to get things working.
1. You Need "Speaker Notes" for Google Slides
1. You Need "Speaker Notes" for Google Slides
The Reality:
Google Meet has a native feature that lets you see your presentation's speaker notes right inside the video call interface.
However, this relies on a specific "Present a Tab" technology built exclusively for Google Chrome. Firefox handles screen sharing differently, so that native integration simply won't load.
View source details for citation from Google Workspace Updates. Opens side panel.
How to set it up (The Firefox Workaround):
You can still present and read your notes in Firefox by manually managing your windows.
Open your Google Slides presentation in a standard Firefox window.
Click the dropdown arrow next to the
Slideshow
button in the top right corner.
Select
Presenter view
to pop your speaker notes out into a separate, smaller window.
View source details for citation from Skywork. Opens side panel.
Join your Google Meet in a different Firefox window.
Click
Present now
and choose the
Window
option.
Select the window displaying your main slides (do not select your separate speaker notes window).
Resize your windows on your monitor so you can comfortably read the notes window while keeping an eye on the Meet window.
2. You Need "Speaker Labels" or Transcripts
2. You Need "Speaker Labels" or Transcripts
The Reality:
If you are trying to use a third-party AI note-taker (like Otter.ai, Tactiq, or tl;dv) to capture transcriptions and see who is speaking, Firefox is likely the roadblock. Firefox has strict privacy guardrails that prevent extensions from capturing internal browser audio easily, so most developers only build these tools for Chrome.
How to set it up:
Turn on built-in captions:
Google Meet has its own live captions that natively identify who is speaking, even in Firefox. Click the
CC
button at the bottom of your Meet screen to toggle them on.
Search for a Firefox add-on:
Check the Mozilla Add-ons store to see if your preferred tool actually has a supported Firefox version (for example, Fellow.ai offers one).
View source details for citation from Fellow.ai. Opens side panel.
Switch browsers temporarily:
If your specific transcription tool is explicitly Chrome-only, you will unfortunately need to join that specific meeting using a Chromium-based browser like Chrome, Edge, or Brave to capture the data.
Using Meet's built-in closed captions or the manual Presenter view workaround will get your speaker data back on track without forcing you to completely abandon Firefox.
Sources
Sources
I men in dia (arc) I can see my headphones in both microphone and speakers
I men in dia (arc) I can see my headphones in both microphone and speakers
Open upload file menu
Tools
Open mode picker
Pro
Send message
Your Jiminny chats aren’t used to improve our models. Gemini is AI and can make mistakes, including about people.
Your privacy & Gemini Opens in a new window
Your privacy & Gemini
Opens in a new window
Summarize page
Summarize page
Backgrounds and effects
Backgrounds and effects
Turn off visual effects
Back
Generate a background
No scene
No scene
Describe your idea
Create samples
Create samples
Learn more about generating backgrounds
Learn more about generating backgrounds
Close...
|
10064
|
|
10040
|
194
|
13
|
2026-04-14T08:08:51.229530+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776154131229_m1.jpg...
|
Firefox
|
Meet - Daily - Platform — Work
|
True
|
meet.google.com/mie-gawc-dsi
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
JY-20543 add AJ reports User pilot tracking by Lak JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
Console Home | Console Home | us-east-2
Console Home | Console Home | us-east-2
SecurityGroup | EC2 | us-east-2
SecurityGroup | EC2 | us-east-2
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app
SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Jiminny
Jiminny
Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf
Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf
Service-Desk - Queues - Platform team - Service space - Jira
Service-Desk - Queues - Platform team - Service space - Jira
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
CloudWatch | us-east-2
CloudWatch | us-east-2
Meet - Daily - Platform
Meet - Daily - Platform
Close tab
Settings
Settings
New Tab
Customize sidebar
Close Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
AI Chat settings
Close
WORK, Google Account: [EMAIL]
Main menu
New Chat
Open menu for conversation actions.
Conversation with Gemini
Conversation with Gemini
Copy prompt
Edit
You said why I can't see speaker data on meemt in firefox. ho wto set it up
You said
why I can't see speaker data on meemt in firefox. ho wto set it up
Listen
Show more options
Show thinking
Gemini said
Gemini said
Dealing with missing features right when you need them is incredibly frustrating. Assuming "meemt" means Google Meet, the reason you can't see your speaker data comes down to how Firefox interacts with Google's platform compared to Chrome.
Since "speaker data" can mean a couple of different things in a meeting, here are the two most likely causes for your issue and exactly how to get things working.
1. You Need "Speaker Notes" for Google Slides
1. You Need "Speaker Notes" for Google Slides
The Reality:
Google Meet has a native feature that lets you see your presentation's speaker notes right inside the video call interface.
However, this relies on a specific "Present a Tab" technology built exclusively for Google Chrome. Firefox handles screen sharing differently, so that native integration simply won't load.
View source details for citation from Google Workspace Updates. Opens side panel.
How to set it up (The Firefox Workaround):
You can still present and read your notes in Firefox by manually managing your windows.
Open your Google Slides presentation in a standard Firefox window.
Click the dropdown arrow next to the
Slideshow
button in the top right corner.
Select
Presenter view
to pop your speaker notes out into a separate, smaller window.
View source details for citation from Skywork. Opens side panel.
Join your Google Meet in a different Firefox window.
Click
Present now
and choose the
Window
option.
Select the window displaying your main slides (do not select your separate speaker notes window).
Resize your windows on your monitor so you can comfortably read the notes window while keeping an eye on the Meet window.
2. You Need "Speaker Labels" or Transcripts
2. You Need "Speaker Labels" or Transcripts
The Reality:
If you are trying to use a third-party AI note-taker (like Otter.ai, Tactiq, or tl;dv) to capture transcriptions and see who is speaking, Firefox is likely the roadblock. Firefox has strict privacy guardrails that prevent extensions from capturing internal browser audio easily, so most developers only build these tools for Chrome.
How to set it up:
Turn on built-in captions:
Google Meet has its own live captions that natively identify who is speaking, even in Firefox. Click the
CC
button at the bottom of your Meet screen to toggle them on.
Search for a Firefox add-on:
Check the Mozilla Add-ons store to see if your preferred tool actually has a supported Firefox version (for example, Fellow.ai offers one).
View source details for citation from Fellow.ai. Opens side panel.
Switch browsers temporarily:
If your specific transcription tool is explicitly Chrome-only, you will unfortunately need to join that specific meeting using a Chromium-based browser like Chrome, Edge, or Brave to capture the data.
Using Meet's built-in closed captions or the manual Presenter view workaround will get your speaker data back on track without forcing you to completely abandon Firefox.
Sources
Sources
Enter a prompt for Gemini
encrypted
Enter a prompt for Gemini
encrypted
Open upload file menu
Tools
Open mode picker
Pro
Microphone
Your Jiminny chats aren’t used to improve our models. Gemini is AI and can make mistakes, including about people.
Your privacy & Gemini Opens in a new window
Your privacy & Gemini
Opens in a new window
Summarize page
Summarize page
Return to home screen
[EMAIL]
Switch account
Switch account
Lukas Kovalik
More options
Turn off microphone
Turn off camera...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Console Home | Console Home | us-east-2","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Console Home | Console Home | us-east-2","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"SecurityGroup | EC2 | us-east-2","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"SecurityGroup | EC2 | us-east-2","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jiminny","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Service-Desk - Queues - Platform team - Service space - Jira","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Service-Desk - Queues - Platform team - Service space - Jira","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"CloudWatch | us-east-2","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"CloudWatch | us-east-2","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Meet - Daily - Platform","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Meet - Daily - Platform","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Settings","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Settings","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"New Tab","depth":4,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Close Google Gemini (⌃X)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"AI Chat settings","depth":7,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Close","depth":7,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"WORK, Google Account: lukas.kovalik@jiminny.com","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Main menu","depth":12,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Chat","depth":12,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Open menu for conversation actions.","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXHeading","text":"Conversation with Gemini","depth":15,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Conversation with Gemini","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Copy prompt","depth":21,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Edit","depth":21,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"You said why I can't see speaker data on meemt in firefox. ho wto set it up","depth":21,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"You said","depth":23,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"why I can't see speaker data on meemt in firefox. ho wto set it up","depth":23,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Listen","depth":22,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Show more options","depth":20,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Show thinking","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Gemini said","depth":20,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Gemini said","depth":21,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Dealing with missing features right when you need them is incredibly frustrating. Assuming \"meemt\" means Google Meet, the reason you can't see your speaker data comes down to how Firefox interacts with Google's platform compared to Chrome.","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Since \"speaker data\" can mean a couple of different things in a meeting, here are the two most likely causes for your issue and exactly how to get things working.","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"1. You Need \"Speaker Notes\" for Google Slides","depth":23,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1. You Need \"Speaker Notes\" for Google Slides","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"The Reality:","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Google Meet has a native feature that lets you see your presentation's speaker notes right inside the video call interface.","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"However, this relies on a specific \"Present a Tab\" technology built exclusively for Google Chrome. Firefox handles screen sharing differently, so that native integration simply won't load.","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"View source details for citation from Google Workspace Updates. Opens side panel.","depth":24,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"How to set it up (The Firefox Workaround):","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"You can still present and read your notes in Firefox by manually managing your windows.","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Open your Google Slides presentation in a standard Firefox window.","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Click the dropdown arrow next to the","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Slideshow","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"button in the top right corner.","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Select","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Presenter view","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"to pop your speaker notes out into a separate, smaller window.","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"View source details for citation from Skywork. Opens side panel.","depth":26,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Join your Google Meet in a different Firefox window.","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Click","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Present now","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"and choose the","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Window","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"option.","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Select the window displaying your main slides (do not select your separate speaker notes window).","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Resize your windows on your monitor so you can comfortably read the notes window while keeping an eye on the Meet window.","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"2. You Need \"Speaker Labels\" or Transcripts","depth":23,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2. You Need \"Speaker Labels\" or Transcripts","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"The Reality:","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"If you are trying to use a third-party AI note-taker (like Otter.ai, Tactiq, or tl;dv) to capture transcriptions and see who is speaking, Firefox is likely the roadblock. Firefox has strict privacy guardrails that prevent extensions from capturing internal browser audio easily, so most developers only build these tools for Chrome.","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"How to set it up:","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Turn on built-in captions:","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Google Meet has its own live captions that natively identify who is speaking, even in Firefox. Click the","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"CC","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"button at the bottom of your Meet screen to toggle them on.","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Search for a Firefox add-on:","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Check the Mozilla Add-ons store to see if your preferred tool actually has a supported Firefox version (for example, Fellow.ai offers one).","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"View source details for citation from Fellow.ai. Opens side panel.","depth":26,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Switch browsers temporarily:","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"If your specific transcription tool is explicitly Chrome-only, you will unfortunately need to join that specific meeting using a Chromium-based browser like Chrome, Edge, or Brave to capture the data.","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Using Meet's built-in closed captions or the manual Presenter view workaround will get your speaker data back on track without forcing you to completely abandon Firefox.","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Sources","depth":23,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Sources","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextArea","text":"Enter a prompt for Gemini\nencrypted","depth":20,"value":"Enter a prompt for Gemini\nencrypted","help_text":"","role_description":"text entry area","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Enter a prompt for Gemini","depth":21,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"encrypted","depth":21,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open upload file menu","depth":20,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Tools","depth":18,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Open mode picker","depth":20,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pro","depth":23,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Microphone","depth":19,"role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Your Jiminny chats aren’t used to improve our models. Gemini is AI and can make mistakes, including about people.","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Your privacy & Gemini Opens in a new window","depth":17,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Your privacy & Gemini","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Opens in a new window","depth":19,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Summarize page","depth":7,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Summarize page","depth":9,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Return to home screen","depth":10,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"lukas.kovalik@jiminny.com","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Switch account","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Switch account","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Lukas Kovalik","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"More options","depth":13,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Turn off microphone","depth":14,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Turn off camera","depth":14,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false}]...
|
1413830423386179030
|
8731688727032609870
|
click
|
accessibility
|
NULL
|
JY-20543 add AJ reports User pilot tracking by Lak JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
Console Home | Console Home | us-east-2
Console Home | Console Home | us-east-2
SecurityGroup | EC2 | us-east-2
SecurityGroup | EC2 | us-east-2
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app
SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Jiminny
Jiminny
Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf
Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf
Service-Desk - Queues - Platform team - Service space - Jira
Service-Desk - Queues - Platform team - Service space - Jira
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
CloudWatch | us-east-2
CloudWatch | us-east-2
Meet - Daily - Platform
Meet - Daily - Platform
Close tab
Settings
Settings
New Tab
Customize sidebar
Close Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
AI Chat settings
Close
WORK, Google Account: [EMAIL]
Main menu
New Chat
Open menu for conversation actions.
Conversation with Gemini
Conversation with Gemini
Copy prompt
Edit
You said why I can't see speaker data on meemt in firefox. ho wto set it up
You said
why I can't see speaker data on meemt in firefox. ho wto set it up
Listen
Show more options
Show thinking
Gemini said
Gemini said
Dealing with missing features right when you need them is incredibly frustrating. Assuming "meemt" means Google Meet, the reason you can't see your speaker data comes down to how Firefox interacts with Google's platform compared to Chrome.
Since "speaker data" can mean a couple of different things in a meeting, here are the two most likely causes for your issue and exactly how to get things working.
1. You Need "Speaker Notes" for Google Slides
1. You Need "Speaker Notes" for Google Slides
The Reality:
Google Meet has a native feature that lets you see your presentation's speaker notes right inside the video call interface.
However, this relies on a specific "Present a Tab" technology built exclusively for Google Chrome. Firefox handles screen sharing differently, so that native integration simply won't load.
View source details for citation from Google Workspace Updates. Opens side panel.
How to set it up (The Firefox Workaround):
You can still present and read your notes in Firefox by manually managing your windows.
Open your Google Slides presentation in a standard Firefox window.
Click the dropdown arrow next to the
Slideshow
button in the top right corner.
Select
Presenter view
to pop your speaker notes out into a separate, smaller window.
View source details for citation from Skywork. Opens side panel.
Join your Google Meet in a different Firefox window.
Click
Present now
and choose the
Window
option.
Select the window displaying your main slides (do not select your separate speaker notes window).
Resize your windows on your monitor so you can comfortably read the notes window while keeping an eye on the Meet window.
2. You Need "Speaker Labels" or Transcripts
2. You Need "Speaker Labels" or Transcripts
The Reality:
If you are trying to use a third-party AI note-taker (like Otter.ai, Tactiq, or tl;dv) to capture transcriptions and see who is speaking, Firefox is likely the roadblock. Firefox has strict privacy guardrails that prevent extensions from capturing internal browser audio easily, so most developers only build these tools for Chrome.
How to set it up:
Turn on built-in captions:
Google Meet has its own live captions that natively identify who is speaking, even in Firefox. Click the
CC
button at the bottom of your Meet screen to toggle them on.
Search for a Firefox add-on:
Check the Mozilla Add-ons store to see if your preferred tool actually has a supported Firefox version (for example, Fellow.ai offers one).
View source details for citation from Fellow.ai. Opens side panel.
Switch browsers temporarily:
If your specific transcription tool is explicitly Chrome-only, you will unfortunately need to join that specific meeting using a Chromium-based browser like Chrome, Edge, or Brave to capture the data.
Using Meet's built-in closed captions or the manual Presenter view workaround will get your speaker data back on track without forcing you to completely abandon Firefox.
Sources
Sources
Enter a prompt for Gemini
encrypted
Enter a prompt for Gemini
encrypted
Open upload file menu
Tools
Open mode picker
Pro
Microphone
Your Jiminny chats aren’t used to improve our models. Gemini is AI and can make mistakes, including about people.
Your privacy & Gemini Opens in a new window
Your privacy & Gemini
Opens in a new window
Summarize page
Summarize page
Return to home screen
[EMAIL]
Switch account
Switch account
Lukas Kovalik
More options
Turn off microphone
Turn off camera...
|
10034
|
|
10056
|
195
|
29
|
2026-04-14T08:09:50.269486+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776154190269_m2.jpg...
|
Firefox
|
Meet - Daily - Platform — Work
|
True
|
meet.google.com/mie-gawc-dsi
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
JY-20543 add AJ reports User pilot tracking by Lak JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
Console Home | Console Home | us-east-2
Console Home | Console Home | us-east-2
SecurityGroup | EC2 | us-east-2
SecurityGroup | EC2 | us-east-2
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app
SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Jiminny
Jiminny
Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf
Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf
Service-Desk - Queues - Platform team - Service space - Jira
Service-Desk - Queues - Platform team - Service space - Jira
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
CloudWatch | us-east-2
CloudWatch | us-east-2
Meet - Daily - Platform
Mute tab
Meet - Daily - Platform
Close tab
Settings
Settings
New Tab
Customize sidebar
Close Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
AI Chat settings
Close
WORK, Google Account: [EMAIL]
Main menu
New Chat
Open menu for conversation actions.
Conversation with Gemini
Conversation with Gemini
Copy prompt
Edit
You said why I can't see speaker data on meemt in firefox. ho wto set it up
You said
why I can't see speaker data on meemt in firefox. ho wto set it up
Listen
Show more options
Show thinking
Gemini said
Gemini said
Dealing with missing features right when you need them is incredibly frustrating. Assuming "meemt" means Google Meet, the reason you can't see your speaker data comes down to how Firefox interacts with Google's platform compared to Chrome.
Since "speaker data" can mean a couple of different things in a meeting, here are the two most likely causes for your issue and exactly how to get things working.
1. You Need "Speaker Notes" for Google Slides
1. You Need "Speaker Notes" for Google Slides
The Reality:
Google Meet has a native feature that lets you see your presentation's speaker notes right inside the video call interface.
However, this relies on a specific "Present a Tab" technology built exclusively for Google Chrome. Firefox handles screen sharing differently, so that native integration simply won't load.
View source details for citation from Google Workspace Updates. Opens side panel.
How to set it up (The Firefox Workaround):
You can still present and read your notes in Firefox by manually managing your windows.
Open your Google Slides presentation in a standard Firefox window.
Click the dropdown arrow next to the
Slideshow
button in the top right corner.
Select
Presenter view
to pop your speaker notes out into a separate, smaller window.
View source details for citation from Skywork. Opens side panel.
Join your Google Meet in a different Firefox window.
Click
Present now
and choose the
Window
option.
Select the window displaying your main slides (do not select your separate speaker notes window).
Resize your windows on your monitor so you can comfortably read the notes window while keeping an eye on the Meet window.
2. You Need "Speaker Labels" or Transcripts
2. You Need "Speaker Labels" or Transcripts
The Reality:
If you are trying to use a third-party AI note-taker (like Otter.ai, Tactiq, or tl;dv) to capture transcriptions and see who is speaking, Firefox is likely the roadblock. Firefox has strict privacy guardrails that prevent extensions from capturing internal browser audio easily, so most developers only build these tools for Chrome.
How to set it up:
Turn on built-in captions:
Google Meet has its own live captions that natively identify who is speaking, even in Firefox. Click the
CC
button at the bottom of your Meet screen to toggle them on.
Search for a Firefox add-on:
Check the Mozilla Add-ons store to see if your preferred tool actually has a supported Firefox version (for example, Fellow.ai offers one).
View source details for citation from Fellow.ai. Opens side panel.
Switch browsers temporarily:
If your specific transcription tool is explicitly Chrome-only, you will unfortunately need to join that specific meeting using a Chromium-based browser like Chrome, Edge, or Brave to capture the data.
Using Meet's built-in closed captions or the manual Presenter view workaround will get your speaker data back on track without forcing you to completely abandon Firefox.
Sources
Sources
I men in dia (arc) I can see my headphones in both microphone and speakers
I men in dia (arc) I can see my headphones in both microphone and speakers
Open upload file menu
Tools
Open mode picker
Pro
Send message
Your Jiminny chats aren’t used to improve our models. Gemini is AI and can make mistakes, including about people.
Your privacy & Gemini Opens in a new window
Your privacy & Gemini
Opens in a new window
Summarize page
Summarize page
Return to home screen
[EMAIL]
Switch account
Switch account
Lukas Kovalik
More options
Turn off microphone
Turn off camera
Turn on background blur
Microphone: soundcore AeroClip
Speaker: Playing…
Camera: FaceTime HD Camera
Backgrounds and effects
Enhance your appearance
Enhance your appearance
Meet can adjust your image sharpness and lighting so others can see you better. To change how you look, use the Appearance tab.
Not now
Try now
Try now
Daily - Platform
Daily - Platform
Scheduled for
Thu, Apr 16
9:45 AM
Use Gemini to take notes Share notes and transcript
Use Gemini to take notes
Share notes and transcript
Start
Start
Join anyway
Join anyway
Other ways to join
Gemini is available in Meet as your personal in-meeting assistant. It can analyze conversation via temporary access to meeting captions. Using Ask Gemini won't create a recording or store meeting data. The meeting host can turn it off.
Learn more
Learn more...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":4,"bounds":{"left":0.00234375,"top":0.045138888,"width":0.0890625,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira","depth":4,"bounds":{"left":0.0,"top":0.08263889,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira","depth":5,"bounds":{"left":0.015625,"top":0.09236111,"width":0.11796875,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":4,"bounds":{"left":0.0,"top":0.11111111,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":5,"bounds":{"left":0.015625,"top":0.12083333,"width":0.1515625,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Console Home | Console Home | us-east-2","depth":4,"bounds":{"left":0.0,"top":0.13958333,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Console Home | Console Home | us-east-2","depth":5,"bounds":{"left":0.015625,"top":0.14930555,"width":0.08671875,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"SecurityGroup | EC2 | us-east-2","depth":4,"bounds":{"left":0.0,"top":0.16805555,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"SecurityGroup | EC2 | us-east-2","depth":5,"bounds":{"left":0.015625,"top":0.17777778,"width":0.06484375,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.19652778,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":5,"bounds":{"left":0.015625,"top":0.20625,"width":0.18710938,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.225,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app","depth":5,"bounds":{"left":0.015625,"top":0.23472223,"width":0.23476562,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet","depth":4,"bounds":{"left":0.0,"top":0.2534722,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet","depth":5,"bounds":{"left":0.015625,"top":0.26319444,"width":0.1984375,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jiminny","depth":4,"bounds":{"left":0.0,"top":0.28194445,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny","depth":5,"bounds":{"left":0.015625,"top":0.29166666,"width":0.015625,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf","depth":4,"bounds":{"left":0.0,"top":0.31041667,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf","depth":5,"bounds":{"left":0.015625,"top":0.3201389,"width":0.1640625,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Service-Desk - Queues - Platform team - Service space - Jira","depth":4,"bounds":{"left":0.0,"top":0.33888888,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Service-Desk - Queues - Platform team - Service space - Jira","depth":5,"bounds":{"left":0.015625,"top":0.34861112,"width":0.12617187,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.3673611,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":5,"bounds":{"left":0.015625,"top":0.37708333,"width":0.18710938,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":4,"bounds":{"left":0.0,"top":0.39583334,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":5,"bounds":{"left":0.015625,"top":0.40555555,"width":0.1515625,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"CloudWatch | us-east-2","depth":4,"bounds":{"left":0.0,"top":0.42430556,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"CloudWatch | us-east-2","depth":5,"bounds":{"left":0.015625,"top":0.4340278,"width":0.0484375,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Meet - Daily - Platform","depth":4,"bounds":{"left":0.0,"top":0.45277777,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXButton","text":"Mute tab","depth":5,"bounds":{"left":0.01328125,"top":0.45902777,"width":0.009375,"height":0.016666668},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Meet - Daily - Platform","depth":5,"bounds":{"left":0.0234375,"top":0.4625,"width":0.046875,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.07890625,"top":0.45902777,"width":0.009375,"height":0.016666668},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Settings","depth":4,"bounds":{"left":0.0,"top":0.48125,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Settings","depth":5,"bounds":{"left":0.015625,"top":0.49097222,"width":0.016796876,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"New Tab","depth":4,"bounds":{"left":0.003125,"top":0.51111114,"width":0.08710937,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.003125,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Close Google Gemini (⌃X)","depth":6,"bounds":{"left":0.01640625,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"bounds":{"left":0.029296875,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"bounds":{"left":0.0421875,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"bounds":{"left":0.05546875,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"AI Chat settings","depth":7,"bounds":{"left":0.2171875,"top":0.047916666,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Close","depth":7,"bounds":{"left":0.23125,"top":0.047916666,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"WORK, Google Account: lukas.kovalik@jiminny.com","depth":12,"bounds":{"left":0.228125,"top":0.090277776,"width":0.015625,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Main menu","depth":12,"bounds":{"left":0.0984375,"top":0.090277776,"width":0.015625,"height":0.027777778},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Chat","depth":12,"bounds":{"left":0.1953125,"top":0.090277776,"width":0.015625,"height":0.027777778},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Open menu for conversation actions.","depth":12,"bounds":{"left":0.2109375,"top":0.090277776,"width":0.015625,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXHeading","text":"Conversation with Gemini","depth":15,"bounds":{"left":0.09335937,"top":0.12847222,"width":0.000390625,"height":0.00069444446},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Conversation with Gemini","depth":16,"bounds":{"left":0.09335937,"top":0.13055556,"width":0.14101562,"height":0.022222223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Copy prompt","depth":21,"bounds":{"left":0.1203125,"top":0.15972222,"width":0.015625,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Edit","depth":21,"bounds":{"left":0.1375,"top":0.15972222,"width":0.015625,"height":0.027777778},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"You said why I can't see speaker data on meemt in firefox. ho wto set it up","depth":21,"bounds":{"left":0.1609375,"top":0.16805555,"width":0.072265625,"height":0.058333334},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"You said","depth":23,"bounds":{"left":0.09335937,"top":0.1701389,"width":0.0234375,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"why I can't see speaker data on meemt in firefox. ho wto set it up","depth":23,"bounds":{"left":0.1609375,"top":0.17083333,"width":0.07070313,"height":0.05347222},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Listen","depth":22,"bounds":{"left":0.22382812,"top":0.25416666,"width":0.015625,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Show more options","depth":20,"bounds":{"left":0.22382812,"top":0.24930556,"width":0.015625,"height":0.027777778},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Show thinking","depth":26,"bounds":{"left":0.11953125,"top":0.25625,"width":0.036328126,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Gemini said","depth":20,"bounds":{"left":0.11679687,"top":0.2923611,"width":0.000390625,"height":0.00069444446},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Gemini said","depth":21,"bounds":{"left":0.11679687,"top":0.29375,"width":0.048046876,"height":0.016666668},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Dealing with missing features right when you need them is incredibly frustrating. Assuming \"meemt\" means Google Meet, the reason you can't see your speaker data comes down to how Firefox interacts with Google's platform compared to Chrome.","depth":24,"bounds":{"left":0.10390625,"top":0.30069444,"width":0.13046876,"height":0.10486111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Since \"speaker data\" can mean a couple of different things in a meeting, here are the two most likely causes for your issue and exactly how to get things working.","depth":24,"bounds":{"left":0.10390625,"top":0.4201389,"width":0.13125,"height":0.06875},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"1. You Need \"Speaker Notes\" for Google Slides","depth":23,"bounds":{"left":0.10390625,"top":0.52152777,"width":0.13242188,"height":0.033333335},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1. You Need \"Speaker Notes\" for Google Slides","depth":24,"bounds":{"left":0.10390625,"top":0.5229167,"width":0.12070312,"height":0.03125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"The Reality:","depth":24,"bounds":{"left":0.10390625,"top":0.5625,"width":0.036328126,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Google Meet has a native feature that lets you see your presentation's speaker notes right inside the video call interface.","depth":24,"bounds":{"left":0.10390625,"top":0.5625,"width":0.13242188,"height":0.050694443},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"However, this relies on a specific \"Present a Tab\" technology built exclusively for Google Chrome. Firefox handles screen sharing differently, so that native integration simply won't load.","depth":24,"bounds":{"left":0.10390625,"top":0.5986111,"width":0.12539062,"height":0.10486111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"View source details for citation from Google Workspace Updates. Opens side panel.","depth":24,"bounds":{"left":0.13710937,"top":0.68958336,"width":0.01015625,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"How to set it up (The Firefox Workaround):","depth":24,"bounds":{"left":0.10390625,"top":0.71805555,"width":0.12851563,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"You can still present and read your notes in Firefox by manually managing your windows.","depth":24,"bounds":{"left":0.10390625,"top":0.7361111,"width":0.12617187,"height":0.03263889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Open your Google Slides presentation in a standard Firefox window.","depth":26,"bounds":{"left":0.11796875,"top":0.7777778,"width":0.115625,"height":0.03263889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Click the dropdown arrow next to the","depth":26,"bounds":{"left":0.11796875,"top":0.8194444,"width":0.10703125,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Slideshow","depth":26,"bounds":{"left":0.11796875,"top":0.8375,"width":0.03125,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"button in the top right corner.","depth":26,"bounds":{"left":0.14921875,"top":0.8375,"width":0.08515625,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Select","depth":26,"bounds":{"left":0.11796875,"top":0.8611111,"width":0.01953125,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Presenter view","depth":26,"bounds":{"left":0.1375,"top":0.8611111,"width":0.0453125,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"to pop your speaker notes out into a separate, smaller window.","depth":26,"bounds":{"left":0.11796875,"top":0.8611111,"width":0.10078125,"height":0.050694443},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"View source details for citation from Skywork. Opens side panel.","depth":26,"bounds":{"left":0.16523437,"top":0.8979167,"width":0.01015625,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Join your Google Meet in a different Firefox window.","depth":26,"bounds":{"left":0.11796875,"top":0.92083335,"width":0.103125,"height":0.03263889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Click","depth":26,"bounds":{"left":0.11796875,"top":0.9625,"width":0.015234375,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Present now","depth":26,"bounds":{"left":0.13320312,"top":0.9625,"width":0.037890624,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"and choose the","depth":26,"bounds":{"left":0.17109375,"top":0.9625,"width":0.047265626,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Window","depth":26,"bounds":{"left":0.11796875,"top":0.98055553,"width":0.02421875,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"option.","depth":26,"bounds":{"left":0.1421875,"top":0.98055553,"width":0.02109375,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Select the window displaying your main slides (do not select your separate speaker notes window).","depth":26,"bounds":{"left":0.11796875,"top":1.0,"width":0.11328125,"height":-0.0041667223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Resize your windows on your monitor so you can comfortably read the notes window while keeping an eye on the Meet window.","depth":26,"bounds":{"left":0.11796875,"top":1.0,"width":0.11835937,"height":-0.06388891},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"2. You Need \"Speaker Labels\" or Transcripts","depth":23,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2. You Need \"Speaker Labels\" or Transcripts","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"The Reality:","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"If you are trying to use a third-party AI note-taker (like Otter.ai, Tactiq, or tl;dv) to capture transcriptions and see who is speaking, Firefox is likely the roadblock. Firefox has strict privacy guardrails that prevent extensions from capturing internal browser audio easily, so most developers only build these tools for Chrome.","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"How to set it up:","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Turn on built-in captions:","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Google Meet has its own live captions that natively identify who is speaking, even in Firefox. Click the","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"CC","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"button at the bottom of your Meet screen to toggle them on.","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Search for a Firefox add-on:","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Check the Mozilla Add-ons store to see if your preferred tool actually has a supported Firefox version (for example, Fellow.ai offers one).","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"View source details for citation from Fellow.ai. Opens side panel.","depth":26,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Switch browsers temporarily:","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"If your specific transcription tool is explicitly Chrome-only, you will unfortunately need to join that specific meeting using a Chromium-based browser like Chrome, Edge, or Brave to capture the data.","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Using Meet's built-in closed captions or the manual Presenter view workaround will get your speaker data back on track without forcing you to completely abandon Firefox.","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Sources","depth":23,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Sources","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextArea","text":"I men in dia (arc) I can see my headphones in both microphone and speakers","depth":20,"bounds":{"left":0.109375,"top":0.8020833,"width":0.125,"height":0.05},"value":"I men in dia (arc) I can see my headphones in both microphone and speakers","help_text":"","role_description":"text entry area","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"I men in dia (arc) I can see my headphones in both microphone and speakers","depth":22,"bounds":{"left":0.109375,"top":0.8034722,"width":0.10625,"height":0.047916666},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open upload file menu","depth":20,"bounds":{"left":0.1046875,"top":0.86527777,"width":0.015625,"height":0.027777778},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Tools","depth":18,"bounds":{"left":0.1234375,"top":0.86527777,"width":0.015625,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Open mode picker","depth":20,"bounds":{"left":0.190625,"top":0.8645833,"width":0.03046875,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pro","depth":23,"bounds":{"left":0.196875,"top":0.87222224,"width":0.00859375,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Send message","depth":19,"bounds":{"left":0.22265625,"top":0.86388886,"width":0.01640625,"height":0.029166667},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Your Jiminny chats aren’t used to improve our models. Gemini is AI and can make mistakes, including about people.","depth":17,"bounds":{"left":0.10039063,"top":0.9097222,"width":0.14296874,"height":0.022222223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Your privacy & Gemini Opens in a new window","depth":17,"bounds":{"left":0.1484375,"top":0.93194443,"width":0.046875,"height":0.011111111},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Your privacy & Gemini","depth":18,"bounds":{"left":0.1484375,"top":0.93194443,"width":0.046875,"height":0.011111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Opens in a new window","depth":19,"bounds":{"left":0.09335937,"top":0.93125,"width":0.05078125,"height":0.011111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Summarize page","depth":7,"bounds":{"left":0.1,"top":0.96319443,"width":0.06289063,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Summarize page","depth":9,"bounds":{"left":0.10664062,"top":0.9673611,"width":0.049609374,"height":0.013888889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Return to home screen","depth":10,"bounds":{"left":0.259375,"top":0.05625,"width":0.041015625,"height":0.027777778},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"lukas.kovalik@jiminny.com","depth":12,"bounds":{"left":0.9097656,"top":0.057638887,"width":0.06523438,"height":0.011805556},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Switch account","depth":11,"bounds":{"left":0.94023436,"top":0.06875,"width":0.034765624,"height":0.011805556},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Switch account","depth":12,"bounds":{"left":0.94023436,"top":0.06875,"width":0.034765624,"height":0.011805556},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Lukas Kovalik","depth":14,"bounds":{"left":0.39765626,"top":0.36319444,"width":0.03515625,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"More options","depth":13,"bounds":{"left":0.6578125,"top":0.35277778,"width":0.01875,"height":0.033333335},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Turn off microphone","depth":14,"bounds":{"left":0.496875,"top":0.59097224,"width":0.021875,"height":0.033333335},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Turn off camera","depth":14,"bounds":{"left":0.525,"top":0.59097224,"width":0.021875,"height":0.033333335},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Turn on background blur","depth":13,"bounds":{"left":0.553125,"top":0.59097224,"width":0.021875,"height":0.033333335},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Microphone: soundcore AeroClip","depth":12,"bounds":{"left":0.39140624,"top":0.6493056,"width":0.06992187,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Speaker: Playing…","depth":13,"bounds":{"left":0.46445313,"top":0.6493056,"width":0.06992187,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Camera: FaceTime HD Camera","depth":13,"bounds":{"left":0.5375,"top":0.6493056,"width":0.06992187,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Backgrounds and effects","depth":12,"bounds":{"left":0.6105469,"top":0.6493056,"width":0.06992187,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXHeading","text":"Enhance your appearance","depth":14,"bounds":{"left":0.5679687,"top":0.5138889,"width":0.07539062,"height":0.016666668},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Enhance your appearance","depth":15,"bounds":{"left":0.5679687,"top":0.51458335,"width":0.07539062,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Meet can adjust your image sharpness and lighting so others can see you better. To change how you look, use the Appearance tab.","depth":15,"bounds":{"left":0.55546874,"top":0.53333336,"width":0.10507812,"height":0.05486111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Not now","depth":15,"bounds":{"left":0.590625,"top":0.6,"width":0.03046875,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Try now","depth":15,"bounds":{"left":0.62578124,"top":0.6,"width":0.0390625,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":true,"is_selected":false},{"role":"AXStaticText","text":"Try now","depth":17,"bounds":{"left":0.6351563,"top":0.60694444,"width":0.0203125,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Daily - Platform","depth":11,"bounds":{"left":0.68671876,"top":0.3888889,"width":0.175,"height":0.025},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Daily - Platform","depth":14,"bounds":{"left":0.7363281,"top":0.38819444,"width":0.07578125,"height":0.025694445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Scheduled for","depth":12,"bounds":{"left":0.7601563,"top":0.425,"width":0.035546876,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Thu, Apr 16","depth":12,"bounds":{"left":0.73164064,"top":0.43888888,"width":0.046484374,"height":0.021527778},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"9:45 AM","depth":12,"bounds":{"left":0.7828125,"top":0.43888888,"width":0.033984374,"height":0.021527778},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Use Gemini to take notes Share notes and transcript","depth":11,"bounds":{"left":0.71132815,"top":0.4722222,"width":0.12578125,"height":0.044444446},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Use Gemini to take notes","depth":12,"bounds":{"left":0.73476565,"top":0.48194444,"width":0.06328125,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Share notes and transcript","depth":12,"bounds":{"left":0.73476565,"top":0.49583334,"width":0.056640625,"height":0.011111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Start","depth":12,"bounds":{"left":0.8011719,"top":0.48055556,"width":0.03125,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Start","depth":14,"bounds":{"left":0.8105469,"top":0.4875,"width":0.0125,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Join anyway","depth":12,"bounds":{"left":0.72734374,"top":0.5277778,"width":0.09375,"height":0.03888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Join anyway","depth":14,"bounds":{"left":0.75859374,"top":0.5402778,"width":0.03125,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Other ways to join","depth":12,"bounds":{"left":0.7378906,"top":0.5861111,"width":0.07265625,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Gemini is available in Meet as your personal in-meeting assistant. It can analyze conversation via temporary access to meeting captions. Using Ask Gemini won't create a recording or store meeting data. The meeting host can turn it off.","depth":12,"bounds":{"left":0.50273436,"top":0.9375,"width":0.26328126,"height":0.035416666},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Learn more","depth":12,"bounds":{"left":0.64453125,"top":0.9611111,"width":0.027734375,"height":0.011805556},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Learn more","depth":13,"bounds":{"left":0.64453125,"top":0.9611111,"width":0.027734375,"height":0.011805556},"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
-2250905463257490131
|
8731661789005347918
|
visual_change
|
accessibility
|
NULL
|
JY-20543 add AJ reports User pilot tracking by Lak JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
Console Home | Console Home | us-east-2
Console Home | Console Home | us-east-2
SecurityGroup | EC2 | us-east-2
SecurityGroup | EC2 | us-east-2
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app
SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Jiminny
Jiminny
Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf
Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf
Service-Desk - Queues - Platform team - Service space - Jira
Service-Desk - Queues - Platform team - Service space - Jira
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
CloudWatch | us-east-2
CloudWatch | us-east-2
Meet - Daily - Platform
Mute tab
Meet - Daily - Platform
Close tab
Settings
Settings
New Tab
Customize sidebar
Close Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
AI Chat settings
Close
WORK, Google Account: [EMAIL]
Main menu
New Chat
Open menu for conversation actions.
Conversation with Gemini
Conversation with Gemini
Copy prompt
Edit
You said why I can't see speaker data on meemt in firefox. ho wto set it up
You said
why I can't see speaker data on meemt in firefox. ho wto set it up
Listen
Show more options
Show thinking
Gemini said
Gemini said
Dealing with missing features right when you need them is incredibly frustrating. Assuming "meemt" means Google Meet, the reason you can't see your speaker data comes down to how Firefox interacts with Google's platform compared to Chrome.
Since "speaker data" can mean a couple of different things in a meeting, here are the two most likely causes for your issue and exactly how to get things working.
1. You Need "Speaker Notes" for Google Slides
1. You Need "Speaker Notes" for Google Slides
The Reality:
Google Meet has a native feature that lets you see your presentation's speaker notes right inside the video call interface.
However, this relies on a specific "Present a Tab" technology built exclusively for Google Chrome. Firefox handles screen sharing differently, so that native integration simply won't load.
View source details for citation from Google Workspace Updates. Opens side panel.
How to set it up (The Firefox Workaround):
You can still present and read your notes in Firefox by manually managing your windows.
Open your Google Slides presentation in a standard Firefox window.
Click the dropdown arrow next to the
Slideshow
button in the top right corner.
Select
Presenter view
to pop your speaker notes out into a separate, smaller window.
View source details for citation from Skywork. Opens side panel.
Join your Google Meet in a different Firefox window.
Click
Present now
and choose the
Window
option.
Select the window displaying your main slides (do not select your separate speaker notes window).
Resize your windows on your monitor so you can comfortably read the notes window while keeping an eye on the Meet window.
2. You Need "Speaker Labels" or Transcripts
2. You Need "Speaker Labels" or Transcripts
The Reality:
If you are trying to use a third-party AI note-taker (like Otter.ai, Tactiq, or tl;dv) to capture transcriptions and see who is speaking, Firefox is likely the roadblock. Firefox has strict privacy guardrails that prevent extensions from capturing internal browser audio easily, so most developers only build these tools for Chrome.
How to set it up:
Turn on built-in captions:
Google Meet has its own live captions that natively identify who is speaking, even in Firefox. Click the
CC
button at the bottom of your Meet screen to toggle them on.
Search for a Firefox add-on:
Check the Mozilla Add-ons store to see if your preferred tool actually has a supported Firefox version (for example, Fellow.ai offers one).
View source details for citation from Fellow.ai. Opens side panel.
Switch browsers temporarily:
If your specific transcription tool is explicitly Chrome-only, you will unfortunately need to join that specific meeting using a Chromium-based browser like Chrome, Edge, or Brave to capture the data.
Using Meet's built-in closed captions or the manual Presenter view workaround will get your speaker data back on track without forcing you to completely abandon Firefox.
Sources
Sources
I men in dia (arc) I can see my headphones in both microphone and speakers
I men in dia (arc) I can see my headphones in both microphone and speakers
Open upload file menu
Tools
Open mode picker
Pro
Send message
Your Jiminny chats aren’t used to improve our models. Gemini is AI and can make mistakes, including about people.
Your privacy & Gemini Opens in a new window
Your privacy & Gemini
Opens in a new window
Summarize page
Summarize page
Return to home screen
[EMAIL]
Switch account
Switch account
Lukas Kovalik
More options
Turn off microphone
Turn off camera
Turn on background blur
Microphone: soundcore AeroClip
Speaker: Playing…
Camera: FaceTime HD Camera
Backgrounds and effects
Enhance your appearance
Enhance your appearance
Meet can adjust your image sharpness and lighting so others can see you better. To change how you look, use the Appearance tab.
Not now
Try now
Try now
Daily - Platform
Daily - Platform
Scheduled for
Thu, Apr 16
9:45 AM
Use Gemini to take notes Share notes and transcript
Use Gemini to take notes
Share notes and transcript
Start
Start
Join anyway
Join anyway
Other ways to join
Gemini is available in Meet as your personal in-meeting assistant. It can analyze conversation via temporary access to meeting captions. Using Ask Gemini won't create a recording or store meeting data. The meeting host can turn it off.
Learn more
Learn more...
|
10055
|
|
10522
|
208
|
38
|
2026-04-14T08:46:35.135112+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776156395135_m1.jpg...
|
Firefox
|
Jiminny — Work
|
True
|
app.staging.jiminny.com/ondemand?topic_id[]=e02f09 app.staging.jiminny.com/ondemand?topic_id[]=e02f0932-cb76-41b6-ac4f-6b8db1392146&include_internal_conversations=1&sequence_number=3...
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
JY-20543 add AJ reports User pilot tracking by Lak JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
Console Home | Console Home | us-east-2
Console Home | Console Home | us-east-2
SecurityGroup | EC2 | us-east-2
SecurityGroup | EC2 | us-east-2
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app
SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Jiminny
Jiminny
Close tab
Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf
Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf
Service-Desk - Queues - Platform team - Service space - Jira
Service-Desk - Queues - Platform team - Service space - Jira
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
CloudWatch | us-east-2
CloudWatch | us-east-2
New Tab
Customize sidebar
Close Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
AI Chat settings
Close
WORK, Google Account: [EMAIL]
Main menu
New Chat
Open menu for conversation actions.
Conversation with Gemini
Conversation with Gemini
Copy prompt
Edit
You said why I can't see speaker data on meemt in firefox. ho wto set it up
You said
why I can't see speaker data on meemt in firefox. ho wto set it up
Listen
Show more options
Show thinking
Gemini said
Gemini said
Dealing with missing features right when you need them is incredibly frustrating. Assuming "meemt" means Google Meet, the reason you can't see your speaker data comes down to how Firefox interacts with Google's platform compared to Chrome.
Since "speaker data" can mean a couple of different things in a meeting, here are the two most likely causes for your issue and exactly how to get things working.
1. You Need "Speaker Notes" for Google Slides
1. You Need "Speaker Notes" for Google Slides
The Reality:
Google Meet has a native feature that lets you see your presentation's speaker notes right inside the video call interface.
However, this relies on a specific "Present a Tab" technology built exclusively for Google Chrome. Firefox handles screen sharing differently, so that native integration simply won't load.
View source details for citation from Google Workspace Updates. Opens side panel.
How to set it up (The Firefox Workaround):
You can still present and read your notes in Firefox by manually managing your windows.
Open your Google Slides presentation in a standard Firefox window.
Click the dropdown arrow next to the
Slideshow
button in the top right corner.
Select
Presenter view
to pop your speaker notes out into a separate, smaller window.
View source details for citation from Skywork. Opens side panel.
Join your Google Meet in a different Firefox window.
Click
Present now
and choose the
Window
option.
Select the window displaying your main slides (do not select your separate speaker notes window).
Resize your windows on your monitor so you can comfortably read the notes window while keeping an eye on the Meet window.
2. You Need "Speaker Labels" or Transcripts
2. You Need "Speaker Labels" or Transcripts
The Reality:
If you are trying to use a third-party AI note-taker (like Otter.ai, Tactiq, or tl;dv) to capture transcriptions and see who is speaking, Firefox is likely the roadblock. Firefox has strict privacy guardrails that prevent extensions from capturing internal browser audio easily, so most developers only build these tools for Chrome.
How to set it up:
Turn on built-in captions:
Google Meet has its own live captions that natively identify who is speaking, even in Firefox. Click the
CC
button at the bottom of your Meet screen to toggle them on.
Search for a Firefox add-on:
Check the Mozilla Add-ons store to see if your preferred tool actually has a supported Firefox version (for example, Fellow.ai offers one).
View source details for citation from Fellow.ai. Opens side panel.
Switch browsers temporarily:
If your specific transcription tool is explicitly Chrome-only, you will unfortunately need to join that specific meeting using a Chromium-based browser like Chrome, Edge, or Brave to capture the data.
Using Meet's built-in closed captions or the manual Presenter view workaround will get your speaker data back on track without forcing you to completely abandon Firefox.
Sources
Sources
I men in dia (arc) I can see my headphones in both microphone and speakers
I men in dia (arc) I can see my headphones in both microphone and speakers
Open upload file menu
Tools
Open mode picker
Pro
Send message
Your Jiminny chats aren’t used to improve our models. Gemini is AI and can make mistakes, including about people.
Your privacy & Gemini Opens in a new window
Your privacy & Gemini
Opens in a new window
Summarize page
Summarize page
JY-18909-automated-reports-ask-jiminny ■ 869720
28
28
14
activities
Get Notified
Sort by Sort by: Most recent
Sort by
Sort by:
Most recent
Add Recording
common.ai-icon-alt
Topics:
Competitors
Show internal and external activities:
Show internal only
Save Search
Clear all
Saved searches Competitive Pitches
Saved searches
Competitive Pitches
Team
Search teams Search teams
Search teams
Search teams
Host
Search team members Search team members
Search team members
Search team members
Also search as participant
Participant
Search team members Search team members
Search team members
Search team members
Customer
Customer
Transcript
Search transcript
Select option Said by
Select option
Said by
Select option Anyone
Select option...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Console Home | Console Home | us-east-2","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Console Home | Console Home | us-east-2","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"SecurityGroup | EC2 | us-east-2","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"SecurityGroup | EC2 | us-east-2","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jiminny","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Jiminny","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Service-Desk - Queues - Platform team - Service space - Jira","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Service-Desk - Queues - Platform team - Service space - Jira","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"CloudWatch | us-east-2","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"CloudWatch | us-east-2","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"New Tab","depth":4,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Close Google Gemini (⌃X)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"AI Chat settings","depth":7,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Close","depth":7,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"WORK, Google Account: lukas.kovalik@jiminny.com","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Main menu","depth":12,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Chat","depth":12,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Open menu for conversation actions.","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXHeading","text":"Conversation with Gemini","depth":15,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Conversation with Gemini","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Copy prompt","depth":21,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Edit","depth":21,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"You said why I can't see speaker data on meemt in firefox. ho wto set it up","depth":21,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"You said","depth":23,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"why I can't see speaker data on meemt in firefox. ho wto set it up","depth":23,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Listen","depth":22,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Show more options","depth":20,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Show thinking","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Gemini said","depth":20,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Gemini said","depth":21,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Dealing with missing features right when you need them is incredibly frustrating. Assuming \"meemt\" means Google Meet, the reason you can't see your speaker data comes down to how Firefox interacts with Google's platform compared to Chrome.","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Since \"speaker data\" can mean a couple of different things in a meeting, here are the two most likely causes for your issue and exactly how to get things working.","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"1. You Need \"Speaker Notes\" for Google Slides","depth":23,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1. You Need \"Speaker Notes\" for Google Slides","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"The Reality:","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Google Meet has a native feature that lets you see your presentation's speaker notes right inside the video call interface.","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"However, this relies on a specific \"Present a Tab\" technology built exclusively for Google Chrome. Firefox handles screen sharing differently, so that native integration simply won't load.","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"View source details for citation from Google Workspace Updates. Opens side panel.","depth":24,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"How to set it up (The Firefox Workaround):","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"You can still present and read your notes in Firefox by manually managing your windows.","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Open your Google Slides presentation in a standard Firefox window.","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Click the dropdown arrow next to the","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Slideshow","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"button in the top right corner.","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Select","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Presenter view","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"to pop your speaker notes out into a separate, smaller window.","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"View source details for citation from Skywork. Opens side panel.","depth":26,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Join your Google Meet in a different Firefox window.","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Click","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Present now","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"and choose the","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Window","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"option.","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Select the window displaying your main slides (do not select your separate speaker notes window).","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Resize your windows on your monitor so you can comfortably read the notes window while keeping an eye on the Meet window.","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"2. You Need \"Speaker Labels\" or Transcripts","depth":23,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2. You Need \"Speaker Labels\" or Transcripts","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"The Reality:","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"If you are trying to use a third-party AI note-taker (like Otter.ai, Tactiq, or tl;dv) to capture transcriptions and see who is speaking, Firefox is likely the roadblock. Firefox has strict privacy guardrails that prevent extensions from capturing internal browser audio easily, so most developers only build these tools for Chrome.","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"How to set it up:","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Turn on built-in captions:","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Google Meet has its own live captions that natively identify who is speaking, even in Firefox. Click the","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"CC","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"button at the bottom of your Meet screen to toggle them on.","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Search for a Firefox add-on:","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Check the Mozilla Add-ons store to see if your preferred tool actually has a supported Firefox version (for example, Fellow.ai offers one).","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"View source details for citation from Fellow.ai. Opens side panel.","depth":26,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Switch browsers temporarily:","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"If your specific transcription tool is explicitly Chrome-only, you will unfortunately need to join that specific meeting using a Chromium-based browser like Chrome, Edge, or Brave to capture the data.","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Using Meet's built-in closed captions or the manual Presenter view workaround will get your speaker data back on track without forcing you to completely abandon Firefox.","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Sources","depth":23,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Sources","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextArea","text":"I men in dia (arc) I can see my headphones in both microphone and speakers","depth":20,"value":"I men in dia (arc) I can see my headphones in both microphone and speakers","help_text":"","role_description":"text entry area","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"I men in dia (arc) I can see my headphones in both microphone and speakers","depth":22,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open upload file menu","depth":20,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Tools","depth":18,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Open mode picker","depth":20,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pro","depth":23,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Send message","depth":19,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Your Jiminny chats aren’t used to improve our models. Gemini is AI and can make mistakes, including about people.","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Your privacy & Gemini Opens in a new window","depth":17,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Your privacy & Gemini","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Opens in a new window","depth":19,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Summarize page","depth":7,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Summarize page","depth":9,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"JY-18909-automated-reports-ask-jiminny ■ 869720","depth":9,"bounds":{"left":0.036805555,"top":0.0,"width":0.20972222,"height":0.017777778},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"28","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"28","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"14","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"activities","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Get Notified","depth":13,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXComboBox","text":"Sort by Sort by: Most recent","depth":13,"value":"Sort by Sort by: Most recent","help_text":"","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextField","text":"Sort by","depth":14,"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Sort by:","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Most recent","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Add Recording","depth":13,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"common.ai-icon-alt","depth":14,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Topics:","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Competitors","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Show internal and external activities:","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Show internal only","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Save Search","depth":14,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Clear all","depth":14,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXComboBox","text":"Saved searches Competitive Pitches","depth":13,"value":"Saved searches Competitive Pitches","help_text":"","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextField","text":"Saved searches","depth":15,"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Competitive Pitches","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Team","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXComboBox","text":"Search teams Search teams","depth":12,"value":"Search teams Search teams","help_text":"","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextField","text":"Search teams","depth":13,"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Search teams","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Host","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXComboBox","text":"Search team members Search team members","depth":12,"value":"Search team members Search team members","help_text":"","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextField","text":"Search team members","depth":13,"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Search team members","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Also search as participant","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Participant","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXComboBox","text":"Search team members Search team members","depth":12,"value":"Search team members Search team members","help_text":"","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextField","text":"Search team members","depth":13,"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Search team members","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Customer","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"Customer","depth":12,"help_text":"","placeholder":"Customer or Subject","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Transcript","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"Search transcript","depth":12,"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXComboBox","text":"Select option Said by","depth":12,"value":"Select option Said by","help_text":"","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextField","text":"Select option","depth":13,"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Said by","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXComboBox","text":"Select option Anyone","depth":12,"value":"Select option Anyone","help_text":"","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextField","text":"Select option","depth":13,"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false}]...
|
4064876673524165384
|
8731658490462076494
|
click
|
accessibility
|
NULL
|
JY-20543 add AJ reports User pilot tracking by Lak JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
Console Home | Console Home | us-east-2
Console Home | Console Home | us-east-2
SecurityGroup | EC2 | us-east-2
SecurityGroup | EC2 | us-east-2
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app
SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Jiminny
Jiminny
Close tab
Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf
Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf
Service-Desk - Queues - Platform team - Service space - Jira
Service-Desk - Queues - Platform team - Service space - Jira
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
CloudWatch | us-east-2
CloudWatch | us-east-2
New Tab
Customize sidebar
Close Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
AI Chat settings
Close
WORK, Google Account: [EMAIL]
Main menu
New Chat
Open menu for conversation actions.
Conversation with Gemini
Conversation with Gemini
Copy prompt
Edit
You said why I can't see speaker data on meemt in firefox. ho wto set it up
You said
why I can't see speaker data on meemt in firefox. ho wto set it up
Listen
Show more options
Show thinking
Gemini said
Gemini said
Dealing with missing features right when you need them is incredibly frustrating. Assuming "meemt" means Google Meet, the reason you can't see your speaker data comes down to how Firefox interacts with Google's platform compared to Chrome.
Since "speaker data" can mean a couple of different things in a meeting, here are the two most likely causes for your issue and exactly how to get things working.
1. You Need "Speaker Notes" for Google Slides
1. You Need "Speaker Notes" for Google Slides
The Reality:
Google Meet has a native feature that lets you see your presentation's speaker notes right inside the video call interface.
However, this relies on a specific "Present a Tab" technology built exclusively for Google Chrome. Firefox handles screen sharing differently, so that native integration simply won't load.
View source details for citation from Google Workspace Updates. Opens side panel.
How to set it up (The Firefox Workaround):
You can still present and read your notes in Firefox by manually managing your windows.
Open your Google Slides presentation in a standard Firefox window.
Click the dropdown arrow next to the
Slideshow
button in the top right corner.
Select
Presenter view
to pop your speaker notes out into a separate, smaller window.
View source details for citation from Skywork. Opens side panel.
Join your Google Meet in a different Firefox window.
Click
Present now
and choose the
Window
option.
Select the window displaying your main slides (do not select your separate speaker notes window).
Resize your windows on your monitor so you can comfortably read the notes window while keeping an eye on the Meet window.
2. You Need "Speaker Labels" or Transcripts
2. You Need "Speaker Labels" or Transcripts
The Reality:
If you are trying to use a third-party AI note-taker (like Otter.ai, Tactiq, or tl;dv) to capture transcriptions and see who is speaking, Firefox is likely the roadblock. Firefox has strict privacy guardrails that prevent extensions from capturing internal browser audio easily, so most developers only build these tools for Chrome.
How to set it up:
Turn on built-in captions:
Google Meet has its own live captions that natively identify who is speaking, even in Firefox. Click the
CC
button at the bottom of your Meet screen to toggle them on.
Search for a Firefox add-on:
Check the Mozilla Add-ons store to see if your preferred tool actually has a supported Firefox version (for example, Fellow.ai offers one).
View source details for citation from Fellow.ai. Opens side panel.
Switch browsers temporarily:
If your specific transcription tool is explicitly Chrome-only, you will unfortunately need to join that specific meeting using a Chromium-based browser like Chrome, Edge, or Brave to capture the data.
Using Meet's built-in closed captions or the manual Presenter view workaround will get your speaker data back on track without forcing you to completely abandon Firefox.
Sources
Sources
I men in dia (arc) I can see my headphones in both microphone and speakers
I men in dia (arc) I can see my headphones in both microphone and speakers
Open upload file menu
Tools
Open mode picker
Pro
Send message
Your Jiminny chats aren’t used to improve our models. Gemini is AI and can make mistakes, including about people.
Your privacy & Gemini Opens in a new window
Your privacy & Gemini
Opens in a new window
Summarize page
Summarize page
JY-18909-automated-reports-ask-jiminny ■ 869720
28
28
14
activities
Get Notified
Sort by Sort by: Most recent
Sort by
Sort by:
Most recent
Add Recording
common.ai-icon-alt
Topics:
Competitors
Show internal and external activities:
Show internal only
Save Search
Clear all
Saved searches Competitive Pitches
Saved searches
Competitive Pitches
Team
Search teams Search teams
Search teams
Search teams
Host
Search team members Search team members
Search team members
Search team members
Also search as participant
Participant
Search team members Search team members
Search team members
Search team members
Customer
Customer
Transcript
Search transcript
Select option Said by
Select option
Said by
Select option Anyone
Select option...
|
10520
|
|
10709
|
213
|
22
|
2026-04-14T08:54:35.667922+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776156875667_m2.jpg...
|
Firefox
|
CloudWatch | us-east-2 — Work
|
True
|
us-east-2.console.aws.amazon.com/cloudwatch/home?r us-east-2.console.aws.amazon.com/cloudwatch/home?region=us-east-2#logsV2:logs-insights$3FqueryDetail$3D~(end~0~start~-3600~timeType~'RELATIVE~tz~'UTC~unit~'seconds~editorString~'fields*20*40timestamp*2c*20*40message*2c*20*40logStream*2c*20*40log*0a*7c*20filter*20*40message*20like*20*22*5bAskJiminnyReport*3aGenerate*5d*22*20*0a*7c*20filter*20*40message*20not*20like*20*2fAnalytic*2f*20*7c*20filter*20*40message*20not*20like*20*2fTranscript*2f*0a*7c*20filter*20*40message*20not*20like*20*2fWebhook*2f*20*7c*20filter*20*40message*20not*20like*20*2fMeetingBot*2f*20*0a*7c*20limit*2010000~queryId~'0551e814-f51a-4339-8372-80d7ba4cef27~source~(~'*2a)~lang~'CWLI~logClass~'STANDARD~accountIDs~(~'All)~queryBy~'allLogGroups)...
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
JY-20543 add AJ reports User pilot tracking by Lak JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
Console Home | Console Home | us-east-2
Console Home | Console Home | us-east-2
SecurityGroup | EC2 | us-east-2
SecurityGroup | EC2 | us-east-2
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app
SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Jiminny
Jiminny
Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf
Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf
Service-Desk - Queues - Platform team - Service space - Jira
Service-Desk - Queues - Platform team - Service space - Jira
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
CloudWatch | us-east-2
CloudWatch | us-east-2
New Tab
New Tab
CloudWatch | us-east-2
CloudWatch | us-east-2
Close tab
New Tab
Customize sidebar
Close Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
AI Chat settings
Close
WORK, Google Account: [EMAIL]
Main menu
New Chat
Open menu for conversation actions.
Conversation with Gemini
Conversation with Gemini
Copy prompt
Edit
You said why I can't see speaker data on meemt in firefox. ho wto set it up
You said
why I can't see speaker data on meemt in firefox. ho wto set it up
Listen
Show more options
Show thinking
Gemini said
Gemini said
Dealing with missing features right when you need them is incredibly frustrating. Assuming "meemt" means Google Meet, the reason you can't see your speaker data comes down to how Firefox interacts with Google's platform compared to Chrome.
Since "speaker data" can mean a couple of different things in a meeting, here are the two most likely causes for your issue and exactly how to get things working.
1. You Need "Speaker Notes" for Google Slides
1. You Need "Speaker Notes" for Google Slides
The Reality:
Google Meet has a native feature that lets you see your presentation's speaker notes right inside the video call interface.
However, this relies on a specific "Present a Tab" technology built exclusively for Google Chrome. Firefox handles screen sharing differently, so that native integration simply won't load.
View source details for citation from Google Workspace Updates. Opens side panel.
How to set it up (The Firefox Workaround):
You can still present and read your notes in Firefox by manually managing your windows.
Open your Google Slides presentation in a standard Firefox window.
Click the dropdown arrow next to the
Slideshow
button in the top right corner.
Select
Presenter view
to pop your speaker notes out into a separate, smaller window.
View source details for citation from Skywork. Opens side panel.
Join your Google Meet in a different Firefox window.
Click
Present now
and choose the
Window
option.
Select the window displaying your main slides (do not select your separate speaker notes window).
Resize your windows on your monitor so you can comfortably read the notes window while keeping an eye on the Meet window.
2. You Need "Speaker Labels" or Transcripts
2. You Need "Speaker Labels" or Transcripts
The Reality:
If you are trying to use a third-party AI note-taker (like Otter.ai, Tactiq, or tl;dv) to capture transcriptions and see who is speaking, Firefox is likely the roadblock. Firefox has strict privacy guardrails that prevent extensions from capturing internal browser audio easily, so most developers only build these tools for Chrome.
How to set it up:
Turn on built-in captions:
Google Meet has its own live captions that natively identify who is speaking, even in Firefox. Click the
CC
button at the bottom of your Meet screen to toggle them on.
Search for a Firefox add-on:
Check the Mozilla Add-ons store to see if your preferred tool actually has a supported Firefox version (for example, Fellow.ai offers one).
View source details for citation from Fellow.ai. Opens side panel.
Switch browsers temporarily:
If your specific transcription tool is explicitly Chrome-only, you will unfortunately need to join that specific meeting using a Chromium-based browser like Chrome, Edge, or Brave to capture the data.
Using Meet's built-in closed captions or the manual Presenter view workaround will get your speaker data back on track without forcing you to completely abandon Firefox.
Sources
Sources
I men in dia (arc) I can see my headphones in both microphone and speakers
I men in dia (arc) I can see my headphones in both microphone and speakers
Open upload file menu
Tools
Open mode picker
Pro
Send message
Your Jiminny chats aren’t used to improve our models. Gemini is AI and can make mistakes, including about people.
Your privacy & Gemini Opens in a new window
Your privacy & Gemini
Opens in a new window
Summarize page
Summarize page
AWS Console Home
Skip to Main Content
Skip to Main Content
Amazon Q
Services
Search
Ask Amazon Q
[Option+S]
CloudShell
Notifications (none available)
Help & support
Settings
United States (Ohio)
United States (Ohio)
STAGE
Account ID: 4387-4037-0364
STAGE
EC2 EC2
EC2
Elastic Container Service Elastic Container Service
Elastic Container Service
S3 S3
S3
CodeDeploy CodeDeploy
CodeDeploy
CloudWatch CloudWatch
CloudWatch
ElastiCache ElastiCache
ElastiCache
Aurora and RDS Aurora and RDS
Aurora and RDS
Amazon OpenSearch Service Amazon OpenSearch Service
Amazon OpenSearch Service
CloudFront CloudFront
CloudFront
MediaLive MediaLive
MediaLive
Open side navigation...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":4,"bounds":{"left":0.00234375,"top":0.045138888,"width":0.0890625,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira","depth":4,"bounds":{"left":0.0,"top":0.08263889,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira","depth":5,"bounds":{"left":0.015625,"top":0.09236111,"width":0.11796875,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.11111111,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":5,"bounds":{"left":0.015625,"top":0.12083333,"width":0.18710938,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":4,"bounds":{"left":0.0,"top":0.13958333,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":5,"bounds":{"left":0.015625,"top":0.14930555,"width":0.1515625,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Console Home | Console Home | us-east-2","depth":4,"bounds":{"left":0.0,"top":0.16805555,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Console Home | Console Home | us-east-2","depth":5,"bounds":{"left":0.015625,"top":0.17777778,"width":0.08671875,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"SecurityGroup | EC2 | us-east-2","depth":4,"bounds":{"left":0.0,"top":0.19652778,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"SecurityGroup | EC2 | us-east-2","depth":5,"bounds":{"left":0.015625,"top":0.20625,"width":0.06484375,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.225,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":5,"bounds":{"left":0.015625,"top":0.23472223,"width":0.18710938,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.2534722,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app","depth":5,"bounds":{"left":0.015625,"top":0.26319444,"width":0.23476562,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet","depth":4,"bounds":{"left":0.0,"top":0.28194445,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet","depth":5,"bounds":{"left":0.015625,"top":0.29166666,"width":0.1984375,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jiminny","depth":4,"bounds":{"left":0.0,"top":0.31041667,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny","depth":5,"bounds":{"left":0.015625,"top":0.3201389,"width":0.015625,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf","depth":4,"bounds":{"left":0.0,"top":0.33888888,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf","depth":5,"bounds":{"left":0.015625,"top":0.34861112,"width":0.1640625,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Service-Desk - Queues - Platform team - Service space - Jira","depth":4,"bounds":{"left":0.0,"top":0.3673611,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Service-Desk - Queues - Platform team - Service space - Jira","depth":5,"bounds":{"left":0.015625,"top":0.37708333,"width":0.12617187,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.39583334,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":5,"bounds":{"left":0.015625,"top":0.40555555,"width":0.18710938,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":4,"bounds":{"left":0.0,"top":0.42430556,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":5,"bounds":{"left":0.015625,"top":0.4340278,"width":0.1515625,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"CloudWatch | us-east-2","depth":4,"bounds":{"left":0.0,"top":0.45277777,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"CloudWatch | us-east-2","depth":5,"bounds":{"left":0.015625,"top":0.4625,"width":0.0484375,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"New Tab","depth":4,"bounds":{"left":0.0,"top":0.48125,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"New Tab","depth":5,"bounds":{"left":0.015625,"top":0.49097222,"width":0.017578125,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"CloudWatch | us-east-2","depth":4,"bounds":{"left":0.0,"top":0.50972223,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"CloudWatch | us-east-2","depth":5,"bounds":{"left":0.015625,"top":0.51944447,"width":0.0484375,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.07890625,"top":0.5159722,"width":0.009375,"height":0.016666668},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Tab","depth":4,"bounds":{"left":0.003125,"top":0.5395833,"width":0.08710937,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.003125,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Close Google Gemini (⌃X)","depth":6,"bounds":{"left":0.01640625,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"bounds":{"left":0.029296875,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"bounds":{"left":0.0421875,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"bounds":{"left":0.05546875,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"AI Chat settings","depth":7,"bounds":{"left":0.2171875,"top":0.047916666,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Close","depth":7,"bounds":{"left":0.23125,"top":0.047916666,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"WORK, Google Account: lukas.kovalik@jiminny.com","depth":12,"bounds":{"left":0.228125,"top":0.090277776,"width":0.015625,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Main menu","depth":12,"bounds":{"left":0.0984375,"top":0.090277776,"width":0.015625,"height":0.027777778},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Chat","depth":12,"bounds":{"left":0.1953125,"top":0.090277776,"width":0.015625,"height":0.027777778},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Open menu for conversation actions.","depth":12,"bounds":{"left":0.2109375,"top":0.090277776,"width":0.015625,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXHeading","text":"Conversation with Gemini","depth":15,"bounds":{"left":0.09335937,"top":0.12847222,"width":0.000390625,"height":0.00069444446},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Conversation with Gemini","depth":16,"bounds":{"left":0.09335937,"top":0.13055556,"width":0.14101562,"height":0.022222223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Copy prompt","depth":21,"bounds":{"left":0.1203125,"top":0.15972222,"width":0.015625,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Edit","depth":21,"bounds":{"left":0.1375,"top":0.15972222,"width":0.015625,"height":0.027777778},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"You said why I can't see speaker data on meemt in firefox. ho wto set it up","depth":21,"bounds":{"left":0.1609375,"top":0.16805555,"width":0.072265625,"height":0.058333334},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"You said","depth":23,"bounds":{"left":0.09335937,"top":0.1701389,"width":0.0234375,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"why I can't see speaker data on meemt in firefox. ho wto set it up","depth":23,"bounds":{"left":0.1609375,"top":0.17083333,"width":0.07070313,"height":0.05347222},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Listen","depth":22,"bounds":{"left":0.22382812,"top":0.25416666,"width":0.015625,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Show more options","depth":20,"bounds":{"left":0.22382812,"top":0.24930556,"width":0.015625,"height":0.027777778},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Show thinking","depth":26,"bounds":{"left":0.11953125,"top":0.25625,"width":0.036328126,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Gemini said","depth":20,"bounds":{"left":0.11679687,"top":0.2923611,"width":0.000390625,"height":0.00069444446},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Gemini said","depth":21,"bounds":{"left":0.11679687,"top":0.29375,"width":0.048046876,"height":0.016666668},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Dealing with missing features right when you need them is incredibly frustrating. Assuming \"meemt\" means Google Meet, the reason you can't see your speaker data comes down to how Firefox interacts with Google's platform compared to Chrome.","depth":24,"bounds":{"left":0.10390625,"top":0.30069444,"width":0.13046876,"height":0.10486111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Since \"speaker data\" can mean a couple of different things in a meeting, here are the two most likely causes for your issue and exactly how to get things working.","depth":24,"bounds":{"left":0.10390625,"top":0.4201389,"width":0.13125,"height":0.06875},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"1. You Need \"Speaker Notes\" for Google Slides","depth":23,"bounds":{"left":0.10390625,"top":0.52152777,"width":0.13242188,"height":0.033333335},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1. You Need \"Speaker Notes\" for Google Slides","depth":24,"bounds":{"left":0.10390625,"top":0.5229167,"width":0.12070312,"height":0.03125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"The Reality:","depth":24,"bounds":{"left":0.10390625,"top":0.5625,"width":0.036328126,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Google Meet has a native feature that lets you see your presentation's speaker notes right inside the video call interface.","depth":24,"bounds":{"left":0.10390625,"top":0.5625,"width":0.13242188,"height":0.050694443},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"However, this relies on a specific \"Present a Tab\" technology built exclusively for Google Chrome. Firefox handles screen sharing differently, so that native integration simply won't load.","depth":24,"bounds":{"left":0.10390625,"top":0.5986111,"width":0.12539062,"height":0.10486111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"View source details for citation from Google Workspace Updates. Opens side panel.","depth":24,"bounds":{"left":0.13710937,"top":0.68958336,"width":0.01015625,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"How to set it up (The Firefox Workaround):","depth":24,"bounds":{"left":0.10390625,"top":0.71805555,"width":0.12851563,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"You can still present and read your notes in Firefox by manually managing your windows.","depth":24,"bounds":{"left":0.10390625,"top":0.7361111,"width":0.12617187,"height":0.03263889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Open your Google Slides presentation in a standard Firefox window.","depth":26,"bounds":{"left":0.11796875,"top":0.7777778,"width":0.115625,"height":0.03263889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Click the dropdown arrow next to the","depth":26,"bounds":{"left":0.11796875,"top":0.8194444,"width":0.10703125,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Slideshow","depth":26,"bounds":{"left":0.11796875,"top":0.8375,"width":0.03125,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"button in the top right corner.","depth":26,"bounds":{"left":0.14921875,"top":0.8375,"width":0.08515625,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Select","depth":26,"bounds":{"left":0.11796875,"top":0.8611111,"width":0.01953125,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Presenter view","depth":26,"bounds":{"left":0.1375,"top":0.8611111,"width":0.0453125,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"to pop your speaker notes out into a separate, smaller window.","depth":26,"bounds":{"left":0.11796875,"top":0.8611111,"width":0.10078125,"height":0.050694443},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"View source details for citation from Skywork. Opens side panel.","depth":26,"bounds":{"left":0.16523437,"top":0.8979167,"width":0.01015625,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Join your Google Meet in a different Firefox window.","depth":26,"bounds":{"left":0.11796875,"top":0.92083335,"width":0.103125,"height":0.03263889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Click","depth":26,"bounds":{"left":0.11796875,"top":0.9625,"width":0.015234375,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Present now","depth":26,"bounds":{"left":0.13320312,"top":0.9625,"width":0.037890624,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"and choose the","depth":26,"bounds":{"left":0.17109375,"top":0.9625,"width":0.047265626,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Window","depth":26,"bounds":{"left":0.11796875,"top":0.98055553,"width":0.02421875,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"option.","depth":26,"bounds":{"left":0.1421875,"top":0.98055553,"width":0.02109375,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Select the window displaying your main slides (do not select your separate speaker notes window).","depth":26,"bounds":{"left":0.11796875,"top":1.0,"width":0.11328125,"height":-0.0041667223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Resize your windows on your monitor so you can comfortably read the notes window while keeping an eye on the Meet window.","depth":26,"bounds":{"left":0.11796875,"top":1.0,"width":0.11835937,"height":-0.06388891},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"2. You Need \"Speaker Labels\" or Transcripts","depth":23,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2. You Need \"Speaker Labels\" or Transcripts","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"The Reality:","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"If you are trying to use a third-party AI note-taker (like Otter.ai, Tactiq, or tl;dv) to capture transcriptions and see who is speaking, Firefox is likely the roadblock. Firefox has strict privacy guardrails that prevent extensions from capturing internal browser audio easily, so most developers only build these tools for Chrome.","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"How to set it up:","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Turn on built-in captions:","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Google Meet has its own live captions that natively identify who is speaking, even in Firefox. Click the","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"CC","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"button at the bottom of your Meet screen to toggle them on.","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Search for a Firefox add-on:","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Check the Mozilla Add-ons store to see if your preferred tool actually has a supported Firefox version (for example, Fellow.ai offers one).","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"View source details for citation from Fellow.ai. Opens side panel.","depth":26,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Switch browsers temporarily:","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"If your specific transcription tool is explicitly Chrome-only, you will unfortunately need to join that specific meeting using a Chromium-based browser like Chrome, Edge, or Brave to capture the data.","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Using Meet's built-in closed captions or the manual Presenter view workaround will get your speaker data back on track without forcing you to completely abandon Firefox.","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Sources","depth":23,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Sources","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextArea","text":"I men in dia (arc) I can see my headphones in both microphone and speakers","depth":20,"bounds":{"left":0.109375,"top":0.8020833,"width":0.125,"height":0.05},"value":"I men in dia (arc) I can see my headphones in both microphone and speakers","help_text":"","role_description":"text entry area","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"I men in dia (arc) I can see my headphones in both microphone and speakers","depth":22,"bounds":{"left":0.109375,"top":0.8034722,"width":0.10625,"height":0.047916666},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open upload file menu","depth":20,"bounds":{"left":0.1046875,"top":0.86527777,"width":0.015625,"height":0.027777778},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Tools","depth":18,"bounds":{"left":0.1234375,"top":0.86527777,"width":0.015625,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Open mode picker","depth":20,"bounds":{"left":0.190625,"top":0.8645833,"width":0.03046875,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pro","depth":23,"bounds":{"left":0.196875,"top":0.87222224,"width":0.00859375,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Send message","depth":19,"bounds":{"left":0.22265625,"top":0.86388886,"width":0.01640625,"height":0.029166667},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Your Jiminny chats aren’t used to improve our models. Gemini is AI and can make mistakes, including about people.","depth":17,"bounds":{"left":0.10039063,"top":0.9097222,"width":0.14296874,"height":0.022222223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Your privacy & Gemini Opens in a new window","depth":17,"bounds":{"left":0.1484375,"top":0.93194443,"width":0.046875,"height":0.011111111},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Your privacy & Gemini","depth":18,"bounds":{"left":0.1484375,"top":0.93194443,"width":0.046875,"height":0.011111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Opens in a new window","depth":19,"bounds":{"left":0.09335937,"top":0.93125,"width":0.05078125,"height":0.011111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Summarize page","depth":7,"bounds":{"left":0.1,"top":0.96319443,"width":0.06289063,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Summarize page","depth":9,"bounds":{"left":0.10664062,"top":0.9673611,"width":0.049609374,"height":0.013888889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"AWS Console Home","depth":13,"bounds":{"left":0.253125,"top":0.047916666,"width":0.025390625,"height":0.033333335},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Skip to Main Content","depth":13,"bounds":{"left":0.25273436,"top":0.047222223,"width":0.0015625,"height":0.0013888889},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip to Main Content","depth":14,"bounds":{"left":0.25351563,"top":0.047916666,"width":0.01953125,"height":0.045138888},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Amazon Q","depth":14,"bounds":{"left":0.27890626,"top":0.047916666,"width":0.01953125,"height":0.033333335},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Services","depth":13,"bounds":{"left":0.2984375,"top":0.047916666,"width":0.01953125,"height":0.033333335},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXComboBox","text":"Search","depth":16,"bounds":{"left":0.31796876,"top":0.054166667,"width":0.2109375,"height":0.020833334},"role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Ask Amazon Q","depth":15,"bounds":{"left":0.5132812,"top":0.05625,"width":0.01171875,"height":0.016666668},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[Option+S]","depth":16,"bounds":{"left":0.48789063,"top":0.058333334,"width":0.02734375,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"CloudShell","depth":14,"bounds":{"left":0.7800781,"top":0.047916666,"width":0.01875,"height":0.033333335},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Notifications (none available)","depth":15,"bounds":{"left":0.7988281,"top":0.050694443,"width":0.01953125,"height":0.027777778},"help_text":"Notifications","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Help & support","depth":15,"bounds":{"left":0.8183594,"top":0.047916666,"width":0.01953125,"height":0.033333335},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Settings","depth":15,"bounds":{"left":0.8378906,"top":0.047916666,"width":0.01953125,"height":0.033333335},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXComboBox","text":"United States (Ohio)","depth":15,"bounds":{"left":0.8574219,"top":0.047916666,"width":0.06328125,"height":0.033333335},"value":"United States (Ohio)","help_text":"United States (Ohio)","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"United States (Ohio)","depth":17,"bounds":{"left":0.8640625,"top":0.059722222,"width":0.04375,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"STAGE","depth":15,"bounds":{"left":0.9207031,"top":0.047916666,"width":0.07929687,"height":0.033333335},"help_text":"Staging_View_Only @ jmny","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Account ID: 4387-4037-0364","depth":19,"bounds":{"left":0.9242188,"top":0.05,"width":0.06367187,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"STAGE","depth":18,"bounds":{"left":0.97734374,"top":0.065972224,"width":0.0140625,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"EC2 EC2","depth":16,"bounds":{"left":0.25625,"top":0.083333336,"width":0.023828125,"height":0.019444445},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"EC2","depth":18,"bounds":{"left":0.26875,"top":0.088194445,"width":0.008203125,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Elastic Container Service Elastic Container Service","depth":16,"bounds":{"left":0.2800781,"top":0.083333336,"width":0.06757812,"height":0.019444445},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Elastic Container Service","depth":18,"bounds":{"left":0.29257813,"top":0.088194445,"width":0.051953126,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"S3 S3","depth":16,"bounds":{"left":0.34765625,"top":0.083333336,"width":0.02109375,"height":0.019444445},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"S3","depth":18,"bounds":{"left":0.36015624,"top":0.088194445,"width":0.00546875,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"CodeDeploy CodeDeploy","depth":16,"bounds":{"left":0.36875,"top":0.083333336,"width":0.04140625,"height":0.019444445},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"CodeDeploy","depth":18,"bounds":{"left":0.38125,"top":0.088194445,"width":0.02578125,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"CloudWatch CloudWatch","depth":16,"bounds":{"left":0.41015625,"top":0.083333336,"width":0.04140625,"height":0.019444445},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"CloudWatch","depth":18,"bounds":{"left":0.42265624,"top":0.088194445,"width":0.02578125,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"ElastiCache ElastiCache","depth":16,"bounds":{"left":0.4515625,"top":0.083333336,"width":0.03984375,"height":0.019444445},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"ElastiCache","depth":18,"bounds":{"left":0.4640625,"top":0.088194445,"width":0.02421875,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Aurora and RDS Aurora and RDS","depth":16,"bounds":{"left":0.49140626,"top":0.083333336,"width":0.048828125,"height":0.019444445},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Aurora and RDS","depth":18,"bounds":{"left":0.50390625,"top":0.088194445,"width":0.033203125,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Amazon OpenSearch Service Amazon OpenSearch Service","depth":16,"bounds":{"left":0.5402344,"top":0.083333336,"width":0.07421875,"height":0.019444445},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Amazon OpenSearch Service","depth":18,"bounds":{"left":0.5527344,"top":0.088194445,"width":0.0609375,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"CloudFront CloudFront","depth":16,"bounds":{"left":0.61445314,"top":0.083333336,"width":0.039453126,"height":0.019444445},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"CloudFront","depth":18,"bounds":{"left":0.6269531,"top":0.088194445,"width":0.023828125,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"MediaLive MediaLive","depth":16,"bounds":{"left":0.6539062,"top":0.083333336,"width":0.037109375,"height":0.019444445},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"MediaLive","depth":18,"bounds":{"left":0.6664063,"top":0.088194445,"width":0.021484375,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Open side navigation","depth":13,"bounds":{"left":0.259375,"top":0.108333334,"width":0.01171875,"height":0.020833334},"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
-4238386251763441733
|
8731653534069814510
|
visual_change
|
accessibility
|
NULL
|
JY-20543 add AJ reports User pilot tracking by Lak JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
Console Home | Console Home | us-east-2
Console Home | Console Home | us-east-2
SecurityGroup | EC2 | us-east-2
SecurityGroup | EC2 | us-east-2
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app
SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Jiminny
Jiminny
Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf
Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf
Service-Desk - Queues - Platform team - Service space - Jira
Service-Desk - Queues - Platform team - Service space - Jira
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
CloudWatch | us-east-2
CloudWatch | us-east-2
New Tab
New Tab
CloudWatch | us-east-2
CloudWatch | us-east-2
Close tab
New Tab
Customize sidebar
Close Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
AI Chat settings
Close
WORK, Google Account: [EMAIL]
Main menu
New Chat
Open menu for conversation actions.
Conversation with Gemini
Conversation with Gemini
Copy prompt
Edit
You said why I can't see speaker data on meemt in firefox. ho wto set it up
You said
why I can't see speaker data on meemt in firefox. ho wto set it up
Listen
Show more options
Show thinking
Gemini said
Gemini said
Dealing with missing features right when you need them is incredibly frustrating. Assuming "meemt" means Google Meet, the reason you can't see your speaker data comes down to how Firefox interacts with Google's platform compared to Chrome.
Since "speaker data" can mean a couple of different things in a meeting, here are the two most likely causes for your issue and exactly how to get things working.
1. You Need "Speaker Notes" for Google Slides
1. You Need "Speaker Notes" for Google Slides
The Reality:
Google Meet has a native feature that lets you see your presentation's speaker notes right inside the video call interface.
However, this relies on a specific "Present a Tab" technology built exclusively for Google Chrome. Firefox handles screen sharing differently, so that native integration simply won't load.
View source details for citation from Google Workspace Updates. Opens side panel.
How to set it up (The Firefox Workaround):
You can still present and read your notes in Firefox by manually managing your windows.
Open your Google Slides presentation in a standard Firefox window.
Click the dropdown arrow next to the
Slideshow
button in the top right corner.
Select
Presenter view
to pop your speaker notes out into a separate, smaller window.
View source details for citation from Skywork. Opens side panel.
Join your Google Meet in a different Firefox window.
Click
Present now
and choose the
Window
option.
Select the window displaying your main slides (do not select your separate speaker notes window).
Resize your windows on your monitor so you can comfortably read the notes window while keeping an eye on the Meet window.
2. You Need "Speaker Labels" or Transcripts
2. You Need "Speaker Labels" or Transcripts
The Reality:
If you are trying to use a third-party AI note-taker (like Otter.ai, Tactiq, or tl;dv) to capture transcriptions and see who is speaking, Firefox is likely the roadblock. Firefox has strict privacy guardrails that prevent extensions from capturing internal browser audio easily, so most developers only build these tools for Chrome.
How to set it up:
Turn on built-in captions:
Google Meet has its own live captions that natively identify who is speaking, even in Firefox. Click the
CC
button at the bottom of your Meet screen to toggle them on.
Search for a Firefox add-on:
Check the Mozilla Add-ons store to see if your preferred tool actually has a supported Firefox version (for example, Fellow.ai offers one).
View source details for citation from Fellow.ai. Opens side panel.
Switch browsers temporarily:
If your specific transcription tool is explicitly Chrome-only, you will unfortunately need to join that specific meeting using a Chromium-based browser like Chrome, Edge, or Brave to capture the data.
Using Meet's built-in closed captions or the manual Presenter view workaround will get your speaker data back on track without forcing you to completely abandon Firefox.
Sources
Sources
I men in dia (arc) I can see my headphones in both microphone and speakers
I men in dia (arc) I can see my headphones in both microphone and speakers
Open upload file menu
Tools
Open mode picker
Pro
Send message
Your Jiminny chats aren’t used to improve our models. Gemini is AI and can make mistakes, including about people.
Your privacy & Gemini Opens in a new window
Your privacy & Gemini
Opens in a new window
Summarize page
Summarize page
AWS Console Home
Skip to Main Content
Skip to Main Content
Amazon Q
Services
Search
Ask Amazon Q
[Option+S]
CloudShell
Notifications (none available)
Help & support
Settings
United States (Ohio)
United States (Ohio)
STAGE
Account ID: 4387-4037-0364
STAGE
EC2 EC2
EC2
Elastic Container Service Elastic Container Service
Elastic Container Service
S3 S3
S3
CodeDeploy CodeDeploy
CodeDeploy
CloudWatch CloudWatch
CloudWatch
ElastiCache ElastiCache
ElastiCache
Aurora and RDS Aurora and RDS
Aurora and RDS
Amazon OpenSearch Service Amazon OpenSearch Service
Amazon OpenSearch Service
CloudFront CloudFront
CloudFront
MediaLive MediaLive
MediaLive
Open side navigation...
|
NULL
|
|
10093
|
197
|
6
|
2026-04-14T08:12:45.872468+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776154365872_m2.jpg...
|
Firefox
|
Settings — Work
|
True
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
JY-20543 add AJ reports User pilot tracking by Lak JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
Console Home | Console Home | us-east-2
Console Home | Console Home | us-east-2
SecurityGroup | EC2 | us-east-2
SecurityGroup | EC2 | us-east-2
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app
SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Jiminny
Jiminny
Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf
Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf
Service-Desk - Queues - Platform team - Service space - Jira
Service-Desk - Queues - Platform team - Service space - Jira
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
CloudWatch | us-east-2
CloudWatch | us-east-2
Settings
Settings
Close tab
New Tab
Customize sidebar
Close Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
AI Chat settings
Close
WORK, Google Account: [EMAIL]
Main menu
New Chat
Open menu for conversation actions.
Conversation with Gemini
Conversation with Gemini
Copy prompt
Edit
You said why I can't see speaker data on meemt in firefox. ho wto set it up
You said
why I can't see speaker data on meemt in firefox. ho wto set it up
Listen
Show more options
Show thinking
Gemini said
Gemini said
Dealing with missing features right when you need them is incredibly frustrating. Assuming "meemt" means Google Meet, the reason you can't see your speaker data comes down to how Firefox interacts with Google's platform compared to Chrome.
Since "speaker data" can mean a couple of different things in a meeting, here are the two most likely causes for your issue and exactly how to get things working.
1. You Need "Speaker Notes" for Google Slides
1. You Need "Speaker Notes" for Google Slides
The Reality:
Google Meet has a native feature that lets you see your presentation's speaker notes right inside the video call interface.
However, this relies on a specific "Present a Tab" technology built exclusively for Google Chrome. Firefox handles screen sharing differently, so that native integration simply won't load.
View source details for citation from Google Workspace Updates. Opens side panel.
How to set it up (The Firefox Workaround):
You can still present and read your notes in Firefox by manually managing your windows.
Open your Google Slides presentation in a standard Firefox window.
Click the dropdown arrow next to the
Slideshow
button in the top right corner.
Select
Presenter view
to pop your speaker notes out into a separate, smaller window.
View source details for citation from Skywork. Opens side panel.
Join your Google Meet in a different Firefox window.
Click
Present now
and choose the
Window
option.
Select the window displaying your main slides (do not select your separate speaker notes window).
Resize your windows on your monitor so you can comfortably read the notes window while keeping an eye on the Meet window.
2. You Need "Speaker Labels" or Transcripts
2. You Need "Speaker Labels" or Transcripts
The Reality:
If you are trying to use a third-party AI note-taker (like Otter.ai, Tactiq, or tl;dv) to capture transcriptions and see who is speaking, Firefox is likely the roadblock. Firefox has strict privacy guardrails that prevent extensions from capturing internal browser audio easily, so most developers only build these tools for Chrome.
How to set it up:
Turn on built-in captions:
Google Meet has its own live captions that natively identify who is speaking, even in Firefox. Click the
CC
button at the bottom of your Meet screen to toggle them on.
Search for a Firefox add-on:
Check the Mozilla Add-ons store to see if your preferred tool actually has a supported Firefox version (for example, Fellow.ai offers one).
View source details for citation from Fellow.ai. Opens side panel.
Switch browsers temporarily:
If your specific transcription tool is explicitly Chrome-only, you will unfortunately need to join that specific meeting using a Chromium-based browser like Chrome, Edge, or Brave to capture the data.
Using Meet's built-in closed captions or the manual Presenter view workaround will get your speaker data back on track without forcing you to completely abandon Firefox.
Sources
Sources
I men in dia (arc) I can see my headphones in both microphone and speakers
I men in dia (arc) I can see my headphones in both microphone and speakers
Open upload file menu
Tools
Open mode picker
Pro
Send message
Your Jiminny chats aren’t used to improve our models. Gemini is AI and can make mistakes, including about people.
Your privacy & Gemini Opens in a new window
Your privacy & Gemini
Opens in a new window
Summarize page
Summarize page
General
Home
Search
Privacy & Security
Sync
AI Controls
Firefox Labs
More from Mozilla
Extensions & Themes
Extensions & Themes
Firefox Support
Firefox Support
Your browser is being managed by your organization.
Your browser is being managed by your organization.
Find in Settings
General
General
Default browser
Default browser
Psst, Firefox isn’t your default.
Make default
Make default
Startup
Startup
Open previous windows and tabs
Open previous windows and tabs
Always check if Firefox is your default browser
Always check if Firefox is your default browser
Import browser data
Import browser data
Bring your bookmarks, passwords, history, extensions, and autofill data from another browser.
Import data
Import data
Profiles
Profiles...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":4,"bounds":{"left":0.00234375,"top":0.045138888,"width":0.0890625,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira","depth":4,"bounds":{"left":0.0,"top":0.08263889,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira","depth":5,"bounds":{"left":0.015625,"top":0.09236111,"width":0.11796875,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":4,"bounds":{"left":0.0,"top":0.11111111,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":5,"bounds":{"left":0.015625,"top":0.12083333,"width":0.1515625,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Console Home | Console Home | us-east-2","depth":4,"bounds":{"left":0.0,"top":0.13958333,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Console Home | Console Home | us-east-2","depth":5,"bounds":{"left":0.015625,"top":0.14930555,"width":0.08671875,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"SecurityGroup | EC2 | us-east-2","depth":4,"bounds":{"left":0.0,"top":0.16805555,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"SecurityGroup | EC2 | us-east-2","depth":5,"bounds":{"left":0.015625,"top":0.17777778,"width":0.06484375,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.19652778,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":5,"bounds":{"left":0.015625,"top":0.20625,"width":0.18710938,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.225,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app","depth":5,"bounds":{"left":0.015625,"top":0.23472223,"width":0.23476562,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet","depth":4,"bounds":{"left":0.0,"top":0.2534722,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet","depth":5,"bounds":{"left":0.015625,"top":0.26319444,"width":0.1984375,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jiminny","depth":4,"bounds":{"left":0.0,"top":0.28194445,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny","depth":5,"bounds":{"left":0.015625,"top":0.29166666,"width":0.015625,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf","depth":4,"bounds":{"left":0.0,"top":0.31041667,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf","depth":5,"bounds":{"left":0.015625,"top":0.3201389,"width":0.1640625,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Service-Desk - Queues - Platform team - Service space - Jira","depth":4,"bounds":{"left":0.0,"top":0.33888888,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Service-Desk - Queues - Platform team - Service space - Jira","depth":5,"bounds":{"left":0.015625,"top":0.34861112,"width":0.12617187,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.3673611,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":5,"bounds":{"left":0.015625,"top":0.37708333,"width":0.18710938,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":4,"bounds":{"left":0.0,"top":0.39583334,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":5,"bounds":{"left":0.015625,"top":0.40555555,"width":0.1515625,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"CloudWatch | us-east-2","depth":4,"bounds":{"left":0.0,"top":0.42430556,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"CloudWatch | us-east-2","depth":5,"bounds":{"left":0.015625,"top":0.4340278,"width":0.0484375,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Settings","depth":4,"bounds":{"left":0.0,"top":0.45277777,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Settings","depth":5,"bounds":{"left":0.015625,"top":0.4625,"width":0.016796876,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.07890625,"top":0.45902777,"width":0.009375,"height":0.016666668},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Tab","depth":4,"bounds":{"left":0.003125,"top":0.4826389,"width":0.08710937,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.003125,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Close Google Gemini (⌃X)","depth":6,"bounds":{"left":0.01640625,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"bounds":{"left":0.029296875,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"bounds":{"left":0.0421875,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"bounds":{"left":0.05546875,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"AI Chat settings","depth":7,"bounds":{"left":0.2171875,"top":0.047916666,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Close","depth":7,"bounds":{"left":0.23125,"top":0.047916666,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"WORK, Google Account: lukas.kovalik@jiminny.com","depth":12,"bounds":{"left":0.228125,"top":0.090277776,"width":0.015625,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Main menu","depth":12,"bounds":{"left":0.0984375,"top":0.090277776,"width":0.015625,"height":0.027777778},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Chat","depth":12,"bounds":{"left":0.1953125,"top":0.090277776,"width":0.015625,"height":0.027777778},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Open menu for conversation actions.","depth":12,"bounds":{"left":0.2109375,"top":0.090277776,"width":0.015625,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXHeading","text":"Conversation with Gemini","depth":15,"bounds":{"left":0.09335937,"top":0.12847222,"width":0.000390625,"height":0.00069444446},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Conversation with Gemini","depth":16,"bounds":{"left":0.09335937,"top":0.13055556,"width":0.14101562,"height":0.022222223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Copy prompt","depth":21,"bounds":{"left":0.1203125,"top":0.15972222,"width":0.015625,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Edit","depth":21,"bounds":{"left":0.1375,"top":0.15972222,"width":0.015625,"height":0.027777778},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"You said why I can't see speaker data on meemt in firefox. ho wto set it up","depth":21,"bounds":{"left":0.1609375,"top":0.16805555,"width":0.072265625,"height":0.058333334},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"You said","depth":23,"bounds":{"left":0.09335937,"top":0.1701389,"width":0.0234375,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"why I can't see speaker data on meemt in firefox. ho wto set it up","depth":23,"bounds":{"left":0.1609375,"top":0.17083333,"width":0.07070313,"height":0.05347222},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Listen","depth":22,"bounds":{"left":0.22382812,"top":0.25416666,"width":0.015625,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Show more options","depth":20,"bounds":{"left":0.22382812,"top":0.24930556,"width":0.015625,"height":0.027777778},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Show thinking","depth":26,"bounds":{"left":0.11953125,"top":0.25625,"width":0.036328126,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Gemini said","depth":20,"bounds":{"left":0.11679687,"top":0.2923611,"width":0.000390625,"height":0.00069444446},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Gemini said","depth":21,"bounds":{"left":0.11679687,"top":0.29375,"width":0.048046876,"height":0.016666668},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Dealing with missing features right when you need them is incredibly frustrating. Assuming \"meemt\" means Google Meet, the reason you can't see your speaker data comes down to how Firefox interacts with Google's platform compared to Chrome.","depth":24,"bounds":{"left":0.10390625,"top":0.30069444,"width":0.13046876,"height":0.10486111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Since \"speaker data\" can mean a couple of different things in a meeting, here are the two most likely causes for your issue and exactly how to get things working.","depth":24,"bounds":{"left":0.10390625,"top":0.4201389,"width":0.13125,"height":0.06875},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"1. You Need \"Speaker Notes\" for Google Slides","depth":23,"bounds":{"left":0.10390625,"top":0.52152777,"width":0.13242188,"height":0.033333335},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1. You Need \"Speaker Notes\" for Google Slides","depth":24,"bounds":{"left":0.10390625,"top":0.5229167,"width":0.12070312,"height":0.03125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"The Reality:","depth":24,"bounds":{"left":0.10390625,"top":0.5625,"width":0.036328126,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Google Meet has a native feature that lets you see your presentation's speaker notes right inside the video call interface.","depth":24,"bounds":{"left":0.10390625,"top":0.5625,"width":0.13242188,"height":0.050694443},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"However, this relies on a specific \"Present a Tab\" technology built exclusively for Google Chrome. Firefox handles screen sharing differently, so that native integration simply won't load.","depth":24,"bounds":{"left":0.10390625,"top":0.5986111,"width":0.12539062,"height":0.10486111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"View source details for citation from Google Workspace Updates. Opens side panel.","depth":24,"bounds":{"left":0.13710937,"top":0.68958336,"width":0.01015625,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"How to set it up (The Firefox Workaround):","depth":24,"bounds":{"left":0.10390625,"top":0.71805555,"width":0.12851563,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"You can still present and read your notes in Firefox by manually managing your windows.","depth":24,"bounds":{"left":0.10390625,"top":0.7361111,"width":0.12617187,"height":0.03263889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Open your Google Slides presentation in a standard Firefox window.","depth":26,"bounds":{"left":0.11796875,"top":0.7777778,"width":0.115625,"height":0.03263889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Click the dropdown arrow next to the","depth":26,"bounds":{"left":0.11796875,"top":0.8194444,"width":0.10703125,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Slideshow","depth":26,"bounds":{"left":0.11796875,"top":0.8375,"width":0.03125,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"button in the top right corner.","depth":26,"bounds":{"left":0.14921875,"top":0.8375,"width":0.08515625,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Select","depth":26,"bounds":{"left":0.11796875,"top":0.8611111,"width":0.01953125,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Presenter view","depth":26,"bounds":{"left":0.1375,"top":0.8611111,"width":0.0453125,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"to pop your speaker notes out into a separate, smaller window.","depth":26,"bounds":{"left":0.11796875,"top":0.8611111,"width":0.10078125,"height":0.050694443},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"View source details for citation from Skywork. Opens side panel.","depth":26,"bounds":{"left":0.16523437,"top":0.8979167,"width":0.01015625,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Join your Google Meet in a different Firefox window.","depth":26,"bounds":{"left":0.11796875,"top":0.92083335,"width":0.103125,"height":0.03263889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Click","depth":26,"bounds":{"left":0.11796875,"top":0.9625,"width":0.015234375,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Present now","depth":26,"bounds":{"left":0.13320312,"top":0.9625,"width":0.037890624,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"and choose the","depth":26,"bounds":{"left":0.17109375,"top":0.9625,"width":0.047265626,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Window","depth":26,"bounds":{"left":0.11796875,"top":0.98055553,"width":0.02421875,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"option.","depth":26,"bounds":{"left":0.1421875,"top":0.98055553,"width":0.02109375,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Select the window displaying your main slides (do not select your separate speaker notes window).","depth":26,"bounds":{"left":0.11796875,"top":1.0,"width":0.11328125,"height":-0.0041667223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Resize your windows on your monitor so you can comfortably read the notes window while keeping an eye on the Meet window.","depth":26,"bounds":{"left":0.11796875,"top":1.0,"width":0.11835937,"height":-0.06388891},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"2. You Need \"Speaker Labels\" or Transcripts","depth":23,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2. You Need \"Speaker Labels\" or Transcripts","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"The Reality:","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"If you are trying to use a third-party AI note-taker (like Otter.ai, Tactiq, or tl;dv) to capture transcriptions and see who is speaking, Firefox is likely the roadblock. Firefox has strict privacy guardrails that prevent extensions from capturing internal browser audio easily, so most developers only build these tools for Chrome.","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"How to set it up:","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Turn on built-in captions:","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Google Meet has its own live captions that natively identify who is speaking, even in Firefox. Click the","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"CC","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"button at the bottom of your Meet screen to toggle them on.","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Search for a Firefox add-on:","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Check the Mozilla Add-ons store to see if your preferred tool actually has a supported Firefox version (for example, Fellow.ai offers one).","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"View source details for citation from Fellow.ai. Opens side panel.","depth":26,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Switch browsers temporarily:","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"If your specific transcription tool is explicitly Chrome-only, you will unfortunately need to join that specific meeting using a Chromium-based browser like Chrome, Edge, or Brave to capture the data.","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Using Meet's built-in closed captions or the manual Presenter view workaround will get your speaker data back on track without forcing you to completely abandon Firefox.","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Sources","depth":23,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Sources","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextArea","text":"I men in dia (arc) I can see my headphones in both microphone and speakers","depth":20,"bounds":{"left":0.109375,"top":0.8020833,"width":0.125,"height":0.05},"value":"I men in dia (arc) I can see my headphones in both microphone and speakers","help_text":"","role_description":"text entry area","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"I men in dia (arc) I can see my headphones in both microphone and speakers","depth":22,"bounds":{"left":0.109375,"top":0.8034722,"width":0.10625,"height":0.047916666},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open upload file menu","depth":20,"bounds":{"left":0.1046875,"top":0.86527777,"width":0.015625,"height":0.027777778},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Tools","depth":18,"bounds":{"left":0.1234375,"top":0.86527777,"width":0.015625,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Open mode picker","depth":20,"bounds":{"left":0.190625,"top":0.8645833,"width":0.03046875,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pro","depth":23,"bounds":{"left":0.196875,"top":0.87222224,"width":0.00859375,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Send message","depth":19,"bounds":{"left":0.22265625,"top":0.86388886,"width":0.01640625,"height":0.029166667},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Your Jiminny chats aren’t used to improve our models. Gemini is AI and can make mistakes, including about people.","depth":17,"bounds":{"left":0.10039063,"top":0.9097222,"width":0.14296874,"height":0.022222223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Your privacy & Gemini Opens in a new window","depth":17,"bounds":{"left":0.1484375,"top":0.93194443,"width":0.046875,"height":0.011111111},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Your privacy & Gemini","depth":18,"bounds":{"left":0.1484375,"top":0.93194443,"width":0.046875,"height":0.011111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Opens in a new window","depth":19,"bounds":{"left":0.09335937,"top":0.93125,"width":0.05078125,"height":0.011111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Summarize page","depth":7,"bounds":{"left":0.1,"top":0.96319443,"width":0.06289063,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Summarize page","depth":9,"bounds":{"left":0.10664062,"top":0.9673611,"width":0.049609374,"height":0.013888889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"General","depth":10,"bounds":{"left":0.28398436,"top":0.104166664,"width":0.021875,"height":0.013888889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Home","depth":10,"bounds":{"left":0.28398436,"top":0.1375,"width":0.016796876,"height":0.013888889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Search","depth":10,"bounds":{"left":0.28398436,"top":0.17083333,"width":0.01953125,"height":0.013888889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Privacy & Security","depth":10,"bounds":{"left":0.28398436,"top":0.20416667,"width":0.051953126,"height":0.013888889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Sync","depth":10,"bounds":{"left":0.28398436,"top":0.2375,"width":0.0140625,"height":0.013888889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"AI Controls","depth":10,"bounds":{"left":0.28398436,"top":0.27083334,"width":0.03125,"height":0.013888889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Firefox Labs","depth":10,"bounds":{"left":0.28398436,"top":0.30416667,"width":0.034375,"height":0.013888889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"More from Mozilla","depth":10,"bounds":{"left":0.28398436,"top":0.3375,"width":0.051171876,"height":0.013888889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Extensions & Themes","depth":7,"bounds":{"left":0.26640624,"top":0.9222222,"width":0.09609375,"height":0.02638889},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Extensions & Themes","depth":9,"bounds":{"left":0.28359374,"top":0.9298611,"width":0.052734375,"height":0.011805556},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Firefox Support","depth":7,"bounds":{"left":0.26640624,"top":0.94861114,"width":0.09609375,"height":0.02638889},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Firefox Support","depth":9,"bounds":{"left":0.28359374,"top":0.95625,"width":0.0375,"height":0.011805556},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Your browser is being managed by your organization.","depth":7,"bounds":{"left":0.3859375,"top":0.06458333,"width":0.1234375,"height":0.011111111},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Your browser is being managed by your organization.","depth":8,"bounds":{"left":0.3859375,"top":0.06458333,"width":0.1234375,"height":0.011111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"Find in Settings","depth":9,"bounds":{"left":0.5425781,"top":0.059027776,"width":0.09023438,"height":0.022222223},"help_text":"","role_description":"search text field","subrole":"AXSearchField","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"General","depth":7,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"General","depth":8,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Default browser","depth":10,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Default browser","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Psst, Firefox isn’t your default.","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Make default","depth":13,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Make default","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Startup","depth":10,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Startup","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Open previous windows and tabs","depth":15,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Open previous windows and tabs","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Always check if Firefox is your default browser","depth":15,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Always check if Firefox is your default browser","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Import browser data","depth":10,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Import browser data","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Bring your bookmarks, passwords, history, extensions, and autofill data from another browser.","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Import data","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Import data","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Profiles","depth":10,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Profiles","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
-1456274009075115407
|
8731416039566603342
|
click
|
accessibility
|
NULL
|
JY-20543 add AJ reports User pilot tracking by Lak JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
Console Home | Console Home | us-east-2
Console Home | Console Home | us-east-2
SecurityGroup | EC2 | us-east-2
SecurityGroup | EC2 | us-east-2
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app
SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Jiminny
Jiminny
Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf
Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf
Service-Desk - Queues - Platform team - Service space - Jira
Service-Desk - Queues - Platform team - Service space - Jira
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
CloudWatch | us-east-2
CloudWatch | us-east-2
Settings
Settings
Close tab
New Tab
Customize sidebar
Close Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
AI Chat settings
Close
WORK, Google Account: [EMAIL]
Main menu
New Chat
Open menu for conversation actions.
Conversation with Gemini
Conversation with Gemini
Copy prompt
Edit
You said why I can't see speaker data on meemt in firefox. ho wto set it up
You said
why I can't see speaker data on meemt in firefox. ho wto set it up
Listen
Show more options
Show thinking
Gemini said
Gemini said
Dealing with missing features right when you need them is incredibly frustrating. Assuming "meemt" means Google Meet, the reason you can't see your speaker data comes down to how Firefox interacts with Google's platform compared to Chrome.
Since "speaker data" can mean a couple of different things in a meeting, here are the two most likely causes for your issue and exactly how to get things working.
1. You Need "Speaker Notes" for Google Slides
1. You Need "Speaker Notes" for Google Slides
The Reality:
Google Meet has a native feature that lets you see your presentation's speaker notes right inside the video call interface.
However, this relies on a specific "Present a Tab" technology built exclusively for Google Chrome. Firefox handles screen sharing differently, so that native integration simply won't load.
View source details for citation from Google Workspace Updates. Opens side panel.
How to set it up (The Firefox Workaround):
You can still present and read your notes in Firefox by manually managing your windows.
Open your Google Slides presentation in a standard Firefox window.
Click the dropdown arrow next to the
Slideshow
button in the top right corner.
Select
Presenter view
to pop your speaker notes out into a separate, smaller window.
View source details for citation from Skywork. Opens side panel.
Join your Google Meet in a different Firefox window.
Click
Present now
and choose the
Window
option.
Select the window displaying your main slides (do not select your separate speaker notes window).
Resize your windows on your monitor so you can comfortably read the notes window while keeping an eye on the Meet window.
2. You Need "Speaker Labels" or Transcripts
2. You Need "Speaker Labels" or Transcripts
The Reality:
If you are trying to use a third-party AI note-taker (like Otter.ai, Tactiq, or tl;dv) to capture transcriptions and see who is speaking, Firefox is likely the roadblock. Firefox has strict privacy guardrails that prevent extensions from capturing internal browser audio easily, so most developers only build these tools for Chrome.
How to set it up:
Turn on built-in captions:
Google Meet has its own live captions that natively identify who is speaking, even in Firefox. Click the
CC
button at the bottom of your Meet screen to toggle them on.
Search for a Firefox add-on:
Check the Mozilla Add-ons store to see if your preferred tool actually has a supported Firefox version (for example, Fellow.ai offers one).
View source details for citation from Fellow.ai. Opens side panel.
Switch browsers temporarily:
If your specific transcription tool is explicitly Chrome-only, you will unfortunately need to join that specific meeting using a Chromium-based browser like Chrome, Edge, or Brave to capture the data.
Using Meet's built-in closed captions or the manual Presenter view workaround will get your speaker data back on track without forcing you to completely abandon Firefox.
Sources
Sources
I men in dia (arc) I can see my headphones in both microphone and speakers
I men in dia (arc) I can see my headphones in both microphone and speakers
Open upload file menu
Tools
Open mode picker
Pro
Send message
Your Jiminny chats aren’t used to improve our models. Gemini is AI and can make mistakes, including about people.
Your privacy & Gemini Opens in a new window
Your privacy & Gemini
Opens in a new window
Summarize page
Summarize page
General
Home
Search
Privacy & Security
Sync
AI Controls
Firefox Labs
More from Mozilla
Extensions & Themes
Extensions & Themes
Firefox Support
Firefox Support
Your browser is being managed by your organization.
Your browser is being managed by your organization.
Find in Settings
General
General
Default browser
Default browser
Psst, Firefox isn’t your default.
Make default
Make default
Startup
Startup
Open previous windows and tabs
Open previous windows and tabs
Always check if Firefox is your default browser
Always check if Firefox is your default browser
Import browser data
Import browser data
Bring your bookmarks, passwords, history, extensions, and autofill data from another browser.
Import data
Import data
Profiles
Profiles...
|
NULL
|
|
10092
|
196
|
4
|
2026-04-14T08:12:45.906711+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776154365906_m1.jpg...
|
Firefox
|
Settings — Work
|
True
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
JY-20543 add AJ reports User pilot tracking by Lak JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
Console Home | Console Home | us-east-2
Console Home | Console Home | us-east-2
SecurityGroup | EC2 | us-east-2
SecurityGroup | EC2 | us-east-2
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app
SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Jiminny
Jiminny
Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf
Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf
Service-Desk - Queues - Platform team - Service space - Jira
Service-Desk - Queues - Platform team - Service space - Jira
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
CloudWatch | us-east-2
CloudWatch | us-east-2
Settings
Settings
Close tab
New Tab
Customize sidebar
Close Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
AI Chat settings
Close
WORK, Google Account: [EMAIL]
Main menu
New Chat
Open menu for conversation actions.
Conversation with Gemini
Conversation with Gemini
Copy prompt
Edit
You said why I can't see speaker data on meemt in firefox. ho wto set it up
You said
why I can't see speaker data on meemt in firefox. ho wto set it up
Listen
Show more options
Show thinking
Gemini said
Gemini said
Dealing with missing features right when you need them is incredibly frustrating. Assuming "meemt" means Google Meet, the reason you can't see your speaker data comes down to how Firefox interacts with Google's platform compared to Chrome.
Since "speaker data" can mean a couple of different things in a meeting, here are the two most likely causes for your issue and exactly how to get things working.
1. You Need "Speaker Notes" for Google Slides
1. You Need "Speaker Notes" for Google Slides
The Reality:
Google Meet has a native feature that lets you see your presentation's speaker notes right inside the video call interface.
However, this relies on a specific "Present a Tab" technology built exclusively for Google Chrome. Firefox handles screen sharing differently, so that native integration simply won't load.
View source details for citation from Google Workspace Updates. Opens side panel.
How to set it up (The Firefox Workaround):
You can still present and read your notes in Firefox by manually managing your windows.
Open your Google Slides presentation in a standard Firefox window.
Click the dropdown arrow next to the
Slideshow
button in the top right corner.
Select
Presenter view
to pop your speaker notes out into a separate, smaller window.
View source details for citation from Skywork. Opens side panel.
Join your Google Meet in a different Firefox window.
Click
Present now
and choose the
Window
option.
Select the window displaying your main slides (do not select your separate speaker notes window).
Resize your windows on your monitor so you can comfortably read the notes window while keeping an eye on the Meet window.
2. You Need "Speaker Labels" or Transcripts
2. You Need "Speaker Labels" or Transcripts
The Reality:
If you are trying to use a third-party AI note-taker (like Otter.ai, Tactiq, or tl;dv) to capture transcriptions and see who is speaking, Firefox is likely the roadblock. Firefox has strict privacy guardrails that prevent extensions from capturing internal browser audio easily, so most developers only build these tools for Chrome.
How to set it up:
Turn on built-in captions:
Google Meet has its own live captions that natively identify who is speaking, even in Firefox. Click the
CC
button at the bottom of your Meet screen to toggle them on.
Search for a Firefox add-on:
Check the Mozilla Add-ons store to see if your preferred tool actually has a supported Firefox version (for example, Fellow.ai offers one).
View source details for citation from Fellow.ai. Opens side panel.
Switch browsers temporarily:
If your specific transcription tool is explicitly Chrome-only, you will unfortunately need to join that specific meeting using a Chromium-based browser like Chrome, Edge, or Brave to capture the data.
Using Meet's built-in closed captions or the manual Presenter view workaround will get your speaker data back on track without forcing you to completely abandon Firefox.
Sources
Sources
I men in dia (arc) I can see my headphones in both microphone and speakers
I men in dia (arc) I can see my headphones in both microphone and speakers
Open upload file menu
Tools
Open mode picker
Pro
Send message
Your Jiminny chats aren’t used to improve our models. Gemini is AI and can make mistakes, including about people.
Your privacy & Gemini Opens in a new window
Your privacy & Gemini
Opens in a new window
Summarize page
Summarize page
General
Home
Search
Privacy & Security
Sync
AI Controls
Firefox Labs
More from Mozilla
Extensions & Themes
Extensions & Themes
Firefox Support
Firefox Support
Your browser is being managed by your organization.
Your browser is being managed by your organization.
Find in Settings
General
General
Default browser
Default browser
Psst, Firefox isn’t your default.
Make default
Make default
Startup
Startup
Open previous windows and tabs
Open previous windows and tabs
Always check if Firefox is your default browser
Always check if Firefox is your default browser
Import browser data
Import browser data
Bring your bookmarks, passwords, history, extensions, and autofill data from another browser.
Import data
Import data
Profiles
Profiles
Each profile has separate browsing data and settings, including history, passwords, and more.
Learn more
Learn more
Settings
Settings
Tabs
Tabs
Opening
Open links in tabs instead of new windows
Open links in tabs instead of new windows
When you open a link, image or media in a new tab, switch to it immediately
When you open a link, image or media in a new tab, switch to it immediately
Open links from apps next to your active tab
Open links from apps next to your active tab
Interaction
Ctrl+Tab cycles through tabs in recently used order
Ctrl+Tab cycles through tabs in recently used order...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Console Home | Console Home | us-east-2","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Console Home | Console Home | us-east-2","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"SecurityGroup | EC2 | us-east-2","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"SecurityGroup | EC2 | us-east-2","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jiminny","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Service-Desk - Queues - Platform team - Service space - Jira","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Service-Desk - Queues - Platform team - Service space - Jira","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"CloudWatch | us-east-2","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"CloudWatch | us-east-2","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Settings","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Settings","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Tab","depth":4,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Close Google Gemini (⌃X)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"AI Chat settings","depth":7,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Close","depth":7,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"WORK, Google Account: lukas.kovalik@jiminny.com","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Main menu","depth":12,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Chat","depth":12,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Open menu for conversation actions.","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXHeading","text":"Conversation with Gemini","depth":15,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Conversation with Gemini","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Copy prompt","depth":21,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Edit","depth":21,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"You said why I can't see speaker data on meemt in firefox. ho wto set it up","depth":21,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"You said","depth":23,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"why I can't see speaker data on meemt in firefox. ho wto set it up","depth":23,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Listen","depth":22,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Show more options","depth":20,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Show thinking","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Gemini said","depth":20,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Gemini said","depth":21,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Dealing with missing features right when you need them is incredibly frustrating. Assuming \"meemt\" means Google Meet, the reason you can't see your speaker data comes down to how Firefox interacts with Google's platform compared to Chrome.","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Since \"speaker data\" can mean a couple of different things in a meeting, here are the two most likely causes for your issue and exactly how to get things working.","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"1. You Need \"Speaker Notes\" for Google Slides","depth":23,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1. You Need \"Speaker Notes\" for Google Slides","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"The Reality:","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Google Meet has a native feature that lets you see your presentation's speaker notes right inside the video call interface.","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"However, this relies on a specific \"Present a Tab\" technology built exclusively for Google Chrome. Firefox handles screen sharing differently, so that native integration simply won't load.","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"View source details for citation from Google Workspace Updates. Opens side panel.","depth":24,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"How to set it up (The Firefox Workaround):","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"You can still present and read your notes in Firefox by manually managing your windows.","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Open your Google Slides presentation in a standard Firefox window.","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Click the dropdown arrow next to the","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Slideshow","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"button in the top right corner.","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Select","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Presenter view","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"to pop your speaker notes out into a separate, smaller window.","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"View source details for citation from Skywork. Opens side panel.","depth":26,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Join your Google Meet in a different Firefox window.","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Click","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Present now","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"and choose the","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Window","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"option.","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Select the window displaying your main slides (do not select your separate speaker notes window).","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Resize your windows on your monitor so you can comfortably read the notes window while keeping an eye on the Meet window.","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"2. You Need \"Speaker Labels\" or Transcripts","depth":23,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2. You Need \"Speaker Labels\" or Transcripts","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"The Reality:","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"If you are trying to use a third-party AI note-taker (like Otter.ai, Tactiq, or tl;dv) to capture transcriptions and see who is speaking, Firefox is likely the roadblock. Firefox has strict privacy guardrails that prevent extensions from capturing internal browser audio easily, so most developers only build these tools for Chrome.","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"How to set it up:","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Turn on built-in captions:","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Google Meet has its own live captions that natively identify who is speaking, even in Firefox. Click the","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"CC","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"button at the bottom of your Meet screen to toggle them on.","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Search for a Firefox add-on:","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Check the Mozilla Add-ons store to see if your preferred tool actually has a supported Firefox version (for example, Fellow.ai offers one).","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"View source details for citation from Fellow.ai. Opens side panel.","depth":26,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Switch browsers temporarily:","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"If your specific transcription tool is explicitly Chrome-only, you will unfortunately need to join that specific meeting using a Chromium-based browser like Chrome, Edge, or Brave to capture the data.","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Using Meet's built-in closed captions or the manual Presenter view workaround will get your speaker data back on track without forcing you to completely abandon Firefox.","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Sources","depth":23,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Sources","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextArea","text":"I men in dia (arc) I can see my headphones in both microphone and speakers","depth":20,"value":"I men in dia (arc) I can see my headphones in both microphone and speakers","help_text":"","role_description":"text entry area","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"I men in dia (arc) I can see my headphones in both microphone and speakers","depth":22,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open upload file menu","depth":20,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Tools","depth":18,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Open mode picker","depth":20,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pro","depth":23,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Send message","depth":19,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Your Jiminny chats aren’t used to improve our models. Gemini is AI and can make mistakes, including about people.","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Your privacy & Gemini Opens in a new window","depth":17,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Your privacy & Gemini","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Opens in a new window","depth":19,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Summarize page","depth":7,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Summarize page","depth":9,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"General","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Home","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Search","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Privacy & Security","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Sync","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"AI Controls","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Firefox Labs","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"More from Mozilla","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Extensions & Themes","depth":7,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Extensions & Themes","depth":9,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Firefox Support","depth":7,"bounds":{"left":0.059027776,"top":0.0,"width":0.17083333,"height":0.04222222},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Firefox Support","depth":9,"bounds":{"left":0.08958333,"top":0.0,"width":0.06666667,"height":0.018888889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Your browser is being managed by your organization.","depth":7,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Your browser is being managed by your organization.","depth":8,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"Find in Settings","depth":9,"help_text":"","role_description":"search text field","subrole":"AXSearchField","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"General","depth":7,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"General","depth":8,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Default browser","depth":10,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Default browser","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Psst, Firefox isn’t your default.","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Make default","depth":13,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Make default","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Startup","depth":10,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Startup","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Open previous windows and tabs","depth":15,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Open previous windows and tabs","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Always check if Firefox is your default browser","depth":15,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Always check if Firefox is your default browser","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Import browser data","depth":10,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Import browser data","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Bring your bookmarks, passwords, history, extensions, and autofill data from another browser.","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Import data","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Import data","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Profiles","depth":10,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Profiles","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Each profile has separate browsing data and settings, including history, passwords, and more.","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Learn more","depth":10,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Learn more","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Settings","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Settings","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Tabs","depth":10,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Tabs","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Opening","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Open links in tabs instead of new windows","depth":19,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Open links in tabs instead of new windows","depth":19,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"When you open a link, image or media in a new tab, switch to it immediately","depth":19,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"When you open a link, image or media in a new tab, switch to it immediately","depth":19,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Open links from apps next to your active tab","depth":19,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Open links from apps next to your active tab","depth":19,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Interaction","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Ctrl+Tab cycles through tabs in recently used order","depth":19,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Ctrl+Tab cycles through tabs in recently used order","depth":19,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
8646856968713714492
|
8731409451086771230
|
click
|
accessibility
|
NULL
|
JY-20543 add AJ reports User pilot tracking by Lak JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
Console Home | Console Home | us-east-2
Console Home | Console Home | us-east-2
SecurityGroup | EC2 | us-east-2
SecurityGroup | EC2 | us-east-2
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app
SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Jiminny
Jiminny
Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf
Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf
Service-Desk - Queues - Platform team - Service space - Jira
Service-Desk - Queues - Platform team - Service space - Jira
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
CloudWatch | us-east-2
CloudWatch | us-east-2
Settings
Settings
Close tab
New Tab
Customize sidebar
Close Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
AI Chat settings
Close
WORK, Google Account: [EMAIL]
Main menu
New Chat
Open menu for conversation actions.
Conversation with Gemini
Conversation with Gemini
Copy prompt
Edit
You said why I can't see speaker data on meemt in firefox. ho wto set it up
You said
why I can't see speaker data on meemt in firefox. ho wto set it up
Listen
Show more options
Show thinking
Gemini said
Gemini said
Dealing with missing features right when you need them is incredibly frustrating. Assuming "meemt" means Google Meet, the reason you can't see your speaker data comes down to how Firefox interacts with Google's platform compared to Chrome.
Since "speaker data" can mean a couple of different things in a meeting, here are the two most likely causes for your issue and exactly how to get things working.
1. You Need "Speaker Notes" for Google Slides
1. You Need "Speaker Notes" for Google Slides
The Reality:
Google Meet has a native feature that lets you see your presentation's speaker notes right inside the video call interface.
However, this relies on a specific "Present a Tab" technology built exclusively for Google Chrome. Firefox handles screen sharing differently, so that native integration simply won't load.
View source details for citation from Google Workspace Updates. Opens side panel.
How to set it up (The Firefox Workaround):
You can still present and read your notes in Firefox by manually managing your windows.
Open your Google Slides presentation in a standard Firefox window.
Click the dropdown arrow next to the
Slideshow
button in the top right corner.
Select
Presenter view
to pop your speaker notes out into a separate, smaller window.
View source details for citation from Skywork. Opens side panel.
Join your Google Meet in a different Firefox window.
Click
Present now
and choose the
Window
option.
Select the window displaying your main slides (do not select your separate speaker notes window).
Resize your windows on your monitor so you can comfortably read the notes window while keeping an eye on the Meet window.
2. You Need "Speaker Labels" or Transcripts
2. You Need "Speaker Labels" or Transcripts
The Reality:
If you are trying to use a third-party AI note-taker (like Otter.ai, Tactiq, or tl;dv) to capture transcriptions and see who is speaking, Firefox is likely the roadblock. Firefox has strict privacy guardrails that prevent extensions from capturing internal browser audio easily, so most developers only build these tools for Chrome.
How to set it up:
Turn on built-in captions:
Google Meet has its own live captions that natively identify who is speaking, even in Firefox. Click the
CC
button at the bottom of your Meet screen to toggle them on.
Search for a Firefox add-on:
Check the Mozilla Add-ons store to see if your preferred tool actually has a supported Firefox version (for example, Fellow.ai offers one).
View source details for citation from Fellow.ai. Opens side panel.
Switch browsers temporarily:
If your specific transcription tool is explicitly Chrome-only, you will unfortunately need to join that specific meeting using a Chromium-based browser like Chrome, Edge, or Brave to capture the data.
Using Meet's built-in closed captions or the manual Presenter view workaround will get your speaker data back on track without forcing you to completely abandon Firefox.
Sources
Sources
I men in dia (arc) I can see my headphones in both microphone and speakers
I men in dia (arc) I can see my headphones in both microphone and speakers
Open upload file menu
Tools
Open mode picker
Pro
Send message
Your Jiminny chats aren’t used to improve our models. Gemini is AI and can make mistakes, including about people.
Your privacy & Gemini Opens in a new window
Your privacy & Gemini
Opens in a new window
Summarize page
Summarize page
General
Home
Search
Privacy & Security
Sync
AI Controls
Firefox Labs
More from Mozilla
Extensions & Themes
Extensions & Themes
Firefox Support
Firefox Support
Your browser is being managed by your organization.
Your browser is being managed by your organization.
Find in Settings
General
General
Default browser
Default browser
Psst, Firefox isn’t your default.
Make default
Make default
Startup
Startup
Open previous windows and tabs
Open previous windows and tabs
Always check if Firefox is your default browser
Always check if Firefox is your default browser
Import browser data
Import browser data
Bring your bookmarks, passwords, history, extensions, and autofill data from another browser.
Import data
Import data
Profiles
Profiles
Each profile has separate browsing data and settings, including history, passwords, and more.
Learn more
Learn more
Settings
Settings
Tabs
Tabs
Opening
Open links in tabs instead of new windows
Open links in tabs instead of new windows
When you open a link, image or media in a new tab, switch to it immediately
When you open a link, image or media in a new tab, switch to it immediately
Open links from apps next to your active tab
Open links from apps next to your active tab
Interaction
Ctrl+Tab cycles through tabs in recently used order
Ctrl+Tab cycles through tabs in recently used order...
|
NULL
|
|
10041
|
195
|
20
|
2026-04-14T08:08:51.249845+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776154131249_m2.jpg...
|
Firefox
|
Meet - Daily - Platform — Work
|
True
|
meet.google.com/mie-gawc-dsi
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
JY-20543 add AJ reports User pilot tracking by Lak JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
Console Home | Console Home | us-east-2
Console Home | Console Home | us-east-2
SecurityGroup | EC2 | us-east-2
SecurityGroup | EC2 | us-east-2
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app
SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Jiminny
Jiminny
Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf
Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf
Service-Desk - Queues - Platform team - Service space - Jira
Service-Desk - Queues - Platform team - Service space - Jira
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
CloudWatch | us-east-2
CloudWatch | us-east-2
Meet - Daily - Platform
Meet - Daily - Platform
Close tab
Settings
Settings
New Tab
Customize sidebar
Close Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
AI Chat settings
Close
WORK, Google Account: [EMAIL]
Main menu
New Chat
Open menu for conversation actions.
Conversation with Gemini
Conversation with Gemini
Copy prompt
Edit
You said why I can't see speaker data on meemt in firefox. ho wto set it up
You said
why I can't see speaker data on meemt in firefox. ho wto set it up
Listen
Show more options
Show thinking
Gemini said
Gemini said
Dealing with missing features right when you need them is incredibly frustrating. Assuming "meemt" means Google Meet, the reason you can't see your speaker data comes down to how Firefox interacts with Google's platform compared to Chrome.
Since "speaker data" can mean a couple of different things in a meeting, here are the two most likely causes for your issue and exactly how to get things working.
1. You Need "Speaker Notes" for Google Slides
1. You Need "Speaker Notes" for Google Slides
The Reality:
Google Meet has a native feature that lets you see your presentation's speaker notes right inside the video call interface.
However, this relies on a specific "Present a Tab" technology built exclusively for Google Chrome. Firefox handles screen sharing differently, so that native integration simply won't load.
View source details for citation from Google Workspace Updates. Opens side panel.
How to set it up (The Firefox Workaround):
You can still present and read your notes in Firefox by manually managing your windows.
Open your Google Slides presentation in a standard Firefox window.
Click the dropdown arrow next to the
Slideshow
button in the top right corner.
Select
Presenter view
to pop your speaker notes out into a separate, smaller window.
View source details for citation from Skywork. Opens side panel.
Join your Google Meet in a different Firefox window.
Click
Present now
and choose the
Window
option.
Select the window displaying your main slides (do not select your separate speaker notes window).
Resize your windows on your monitor so you can comfortably read the notes window while keeping an eye on the Meet window.
2. You Need "Speaker Labels" or Transcripts
2. You Need "Speaker Labels" or Transcripts
The Reality:
If you are trying to use a third-party AI note-taker (like Otter.ai, Tactiq, or tl;dv) to capture transcriptions and see who is speaking, Firefox is likely the roadblock. Firefox has strict privacy guardrails that prevent extensions from capturing internal browser audio easily, so most developers only build these tools for Chrome.
How to set it up:
Turn on built-in captions:
Google Meet has its own live captions that natively identify who is speaking, even in Firefox. Click the
CC
button at the bottom of your Meet screen to toggle them on.
Search for a Firefox add-on:
Check the Mozilla Add-ons store to see if your preferred tool actually has a supported Firefox version (for example, Fellow.ai offers one).
View source details for citation from Fellow.ai. Opens side panel.
Switch browsers temporarily:
If your specific transcription tool is explicitly Chrome-only, you will unfortunately need to join that specific meeting using a Chromium-based browser like Chrome, Edge, or Brave to capture the data.
Using Meet's built-in closed captions or the manual Presenter view workaround will get your speaker data back on track without forcing you to completely abandon Firefox.
Sources
Sources
Enter a prompt for Gemini
encrypted
Enter a prompt for Gemini
encrypted
Open upload file menu
Tools
Open mode picker
Pro
Microphone
Your Jiminny chats aren’t used to improve our models. Gemini is AI and can make mistakes, including about people.
Your privacy & Gemini Opens in a new window
Your privacy & Gemini
Opens in a new window
Summarize page
Summarize page
Return to home screen
[EMAIL]
Switch account
Switch account
Lukas Kovalik
More options
Turn off microphone
Turn off camera
Turn on background blur
Microphone: soundcore AeroClip
Speaker: System Default Speaker Device
Camera: FaceTime HD Camera
Backgrounds and effects
Enhance your appearance
Enhance your appearance
Meet can adjust your image sharpness and lighting so others can see you better. To change how you look, use the Appearance tab.
Not now
Try now
Try now
Daily - Platform
Daily - Platform
Scheduled for
Thu, Apr 16
9:45 AM
Use Gemini to take notes Share notes and transcript
Use Gemini to take notes
Share notes and transcript
Start
Start
Join anyway
Join anyway
Other ways to join
Gemini is available in Meet as your personal in-meeting assistant. It can analyze conversation via temporary access to meeting captions. Using Ask Gemini won't create a recording or store meeting data. The meeting host can turn it off.
Learn more
Learn more...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":4,"bounds":{"left":0.00234375,"top":0.045138888,"width":0.0890625,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira","depth":4,"bounds":{"left":0.0,"top":0.08263889,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira","depth":5,"bounds":{"left":0.015625,"top":0.09236111,"width":0.11796875,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":4,"bounds":{"left":0.0,"top":0.11111111,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":5,"bounds":{"left":0.015625,"top":0.12083333,"width":0.1515625,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Console Home | Console Home | us-east-2","depth":4,"bounds":{"left":0.0,"top":0.13958333,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Console Home | Console Home | us-east-2","depth":5,"bounds":{"left":0.015625,"top":0.14930555,"width":0.08671875,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"SecurityGroup | EC2 | us-east-2","depth":4,"bounds":{"left":0.0,"top":0.16805555,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"SecurityGroup | EC2 | us-east-2","depth":5,"bounds":{"left":0.015625,"top":0.17777778,"width":0.06484375,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.19652778,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":5,"bounds":{"left":0.015625,"top":0.20625,"width":0.18710938,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.225,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app","depth":5,"bounds":{"left":0.015625,"top":0.23472223,"width":0.23476562,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet","depth":4,"bounds":{"left":0.0,"top":0.2534722,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet","depth":5,"bounds":{"left":0.015625,"top":0.26319444,"width":0.1984375,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jiminny","depth":4,"bounds":{"left":0.0,"top":0.28194445,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny","depth":5,"bounds":{"left":0.015625,"top":0.29166666,"width":0.015625,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf","depth":4,"bounds":{"left":0.0,"top":0.31041667,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf","depth":5,"bounds":{"left":0.015625,"top":0.3201389,"width":0.1640625,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Service-Desk - Queues - Platform team - Service space - Jira","depth":4,"bounds":{"left":0.0,"top":0.33888888,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Service-Desk - Queues - Platform team - Service space - Jira","depth":5,"bounds":{"left":0.015625,"top":0.34861112,"width":0.12617187,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.3673611,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":5,"bounds":{"left":0.015625,"top":0.37708333,"width":0.18710938,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":4,"bounds":{"left":0.0,"top":0.39583334,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":5,"bounds":{"left":0.015625,"top":0.40555555,"width":0.1515625,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"CloudWatch | us-east-2","depth":4,"bounds":{"left":0.0,"top":0.42430556,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"CloudWatch | us-east-2","depth":5,"bounds":{"left":0.015625,"top":0.4340278,"width":0.0484375,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Meet - Daily - Platform","depth":4,"bounds":{"left":0.0,"top":0.45277777,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Meet - Daily - Platform","depth":5,"bounds":{"left":0.015625,"top":0.4625,"width":0.046484374,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.07890625,"top":0.45902777,"width":0.009375,"height":0.016666668},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Settings","depth":4,"bounds":{"left":0.0,"top":0.48125,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Settings","depth":5,"bounds":{"left":0.015625,"top":0.49097222,"width":0.016796876,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"New Tab","depth":4,"bounds":{"left":0.003125,"top":0.51111114,"width":0.08710937,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.003125,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Close Google Gemini (⌃X)","depth":6,"bounds":{"left":0.01640625,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"bounds":{"left":0.029296875,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"bounds":{"left":0.0421875,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"bounds":{"left":0.05546875,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"AI Chat settings","depth":7,"bounds":{"left":0.2171875,"top":0.047916666,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Close","depth":7,"bounds":{"left":0.23125,"top":0.047916666,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"WORK, Google Account: lukas.kovalik@jiminny.com","depth":12,"bounds":{"left":0.228125,"top":0.090277776,"width":0.015625,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Main menu","depth":12,"bounds":{"left":0.0984375,"top":0.090277776,"width":0.015625,"height":0.027777778},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Chat","depth":12,"bounds":{"left":0.1953125,"top":0.090277776,"width":0.015625,"height":0.027777778},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Open menu for conversation actions.","depth":12,"bounds":{"left":0.2109375,"top":0.090277776,"width":0.015625,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXHeading","text":"Conversation with Gemini","depth":15,"bounds":{"left":0.09335937,"top":0.12847222,"width":0.000390625,"height":0.00069444446},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Conversation with Gemini","depth":16,"bounds":{"left":0.09335937,"top":0.13055556,"width":0.14101562,"height":0.022222223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Copy prompt","depth":21,"bounds":{"left":0.1203125,"top":0.15972222,"width":0.015625,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Edit","depth":21,"bounds":{"left":0.1375,"top":0.15972222,"width":0.015625,"height":0.027777778},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"You said why I can't see speaker data on meemt in firefox. ho wto set it up","depth":21,"bounds":{"left":0.1609375,"top":0.16805555,"width":0.072265625,"height":0.058333334},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"You said","depth":23,"bounds":{"left":0.09335937,"top":0.1701389,"width":0.0234375,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"why I can't see speaker data on meemt in firefox. ho wto set it up","depth":23,"bounds":{"left":0.1609375,"top":0.17083333,"width":0.07070313,"height":0.05347222},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Listen","depth":22,"bounds":{"left":0.22382812,"top":0.25416666,"width":0.015625,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Show more options","depth":20,"bounds":{"left":0.22382812,"top":0.24930556,"width":0.015625,"height":0.027777778},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Show thinking","depth":26,"bounds":{"left":0.11953125,"top":0.25625,"width":0.036328126,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Gemini said","depth":20,"bounds":{"left":0.11679687,"top":0.2923611,"width":0.000390625,"height":0.00069444446},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Gemini said","depth":21,"bounds":{"left":0.11679687,"top":0.29375,"width":0.048046876,"height":0.016666668},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Dealing with missing features right when you need them is incredibly frustrating. Assuming \"meemt\" means Google Meet, the reason you can't see your speaker data comes down to how Firefox interacts with Google's platform compared to Chrome.","depth":24,"bounds":{"left":0.10390625,"top":0.30069444,"width":0.13046876,"height":0.10486111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Since \"speaker data\" can mean a couple of different things in a meeting, here are the two most likely causes for your issue and exactly how to get things working.","depth":24,"bounds":{"left":0.10390625,"top":0.4201389,"width":0.13125,"height":0.06875},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"1. You Need \"Speaker Notes\" for Google Slides","depth":23,"bounds":{"left":0.10390625,"top":0.52152777,"width":0.13242188,"height":0.033333335},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1. You Need \"Speaker Notes\" for Google Slides","depth":24,"bounds":{"left":0.10390625,"top":0.5229167,"width":0.12070312,"height":0.03125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"The Reality:","depth":24,"bounds":{"left":0.10390625,"top":0.5625,"width":0.036328126,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Google Meet has a native feature that lets you see your presentation's speaker notes right inside the video call interface.","depth":24,"bounds":{"left":0.10390625,"top":0.5625,"width":0.13242188,"height":0.050694443},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"However, this relies on a specific \"Present a Tab\" technology built exclusively for Google Chrome. Firefox handles screen sharing differently, so that native integration simply won't load.","depth":24,"bounds":{"left":0.10390625,"top":0.5986111,"width":0.12539062,"height":0.10486111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"View source details for citation from Google Workspace Updates. Opens side panel.","depth":24,"bounds":{"left":0.13710937,"top":0.68958336,"width":0.01015625,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"How to set it up (The Firefox Workaround):","depth":24,"bounds":{"left":0.10390625,"top":0.71805555,"width":0.12851563,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"You can still present and read your notes in Firefox by manually managing your windows.","depth":24,"bounds":{"left":0.10390625,"top":0.7361111,"width":0.12617187,"height":0.03263889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Open your Google Slides presentation in a standard Firefox window.","depth":26,"bounds":{"left":0.11796875,"top":0.7777778,"width":0.115625,"height":0.03263889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Click the dropdown arrow next to the","depth":26,"bounds":{"left":0.11796875,"top":0.8194444,"width":0.10703125,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Slideshow","depth":26,"bounds":{"left":0.11796875,"top":0.8375,"width":0.03125,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"button in the top right corner.","depth":26,"bounds":{"left":0.14921875,"top":0.8375,"width":0.08515625,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Select","depth":26,"bounds":{"left":0.11796875,"top":0.8611111,"width":0.01953125,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Presenter view","depth":26,"bounds":{"left":0.1375,"top":0.8611111,"width":0.0453125,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"to pop your speaker notes out into a separate, smaller window.","depth":26,"bounds":{"left":0.11796875,"top":0.8611111,"width":0.10078125,"height":0.050694443},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"View source details for citation from Skywork. Opens side panel.","depth":26,"bounds":{"left":0.16523437,"top":0.8979167,"width":0.01015625,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Join your Google Meet in a different Firefox window.","depth":26,"bounds":{"left":0.11796875,"top":0.92083335,"width":0.103125,"height":0.03263889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Click","depth":26,"bounds":{"left":0.11796875,"top":0.9625,"width":0.015234375,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Present now","depth":26,"bounds":{"left":0.13320312,"top":0.9625,"width":0.037890624,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"and choose the","depth":26,"bounds":{"left":0.17109375,"top":0.9625,"width":0.047265626,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Window","depth":26,"bounds":{"left":0.11796875,"top":0.98055553,"width":0.02421875,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"option.","depth":26,"bounds":{"left":0.1421875,"top":0.98055553,"width":0.02109375,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Select the window displaying your main slides (do not select your separate speaker notes window).","depth":26,"bounds":{"left":0.11796875,"top":1.0,"width":0.11328125,"height":-0.0041667223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Resize your windows on your monitor so you can comfortably read the notes window while keeping an eye on the Meet window.","depth":26,"bounds":{"left":0.11796875,"top":1.0,"width":0.11835937,"height":-0.06388891},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"2. You Need \"Speaker Labels\" or Transcripts","depth":23,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2. You Need \"Speaker Labels\" or Transcripts","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"The Reality:","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"If you are trying to use a third-party AI note-taker (like Otter.ai, Tactiq, or tl;dv) to capture transcriptions and see who is speaking, Firefox is likely the roadblock. Firefox has strict privacy guardrails that prevent extensions from capturing internal browser audio easily, so most developers only build these tools for Chrome.","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"How to set it up:","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Turn on built-in captions:","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Google Meet has its own live captions that natively identify who is speaking, even in Firefox. Click the","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"CC","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"button at the bottom of your Meet screen to toggle them on.","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Search for a Firefox add-on:","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Check the Mozilla Add-ons store to see if your preferred tool actually has a supported Firefox version (for example, Fellow.ai offers one).","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"View source details for citation from Fellow.ai. Opens side panel.","depth":26,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Switch browsers temporarily:","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"If your specific transcription tool is explicitly Chrome-only, you will unfortunately need to join that specific meeting using a Chromium-based browser like Chrome, Edge, or Brave to capture the data.","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Using Meet's built-in closed captions or the manual Presenter view workaround will get your speaker data back on track without forcing you to completely abandon Firefox.","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Sources","depth":23,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Sources","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextArea","text":"Enter a prompt for Gemini\nencrypted","depth":20,"bounds":{"left":0.109375,"top":0.8354167,"width":0.125,"height":0.016666668},"value":"Enter a prompt for Gemini\nencrypted","help_text":"","role_description":"text entry area","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Enter a prompt for Gemini","depth":21,"bounds":{"left":0.1171875,"top":0.8354167,"width":0.08203125,"height":0.016666668},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"encrypted","depth":21,"bounds":{"left":0.10820313,"top":0.8354167,"width":0.0078125,"height":0.016666668},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open upload file menu","depth":20,"bounds":{"left":0.1046875,"top":0.86527777,"width":0.015625,"height":0.027777778},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Tools","depth":18,"bounds":{"left":0.1234375,"top":0.86527777,"width":0.015625,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Open mode picker","depth":20,"bounds":{"left":0.190625,"top":0.8645833,"width":0.03046875,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pro","depth":23,"bounds":{"left":0.196875,"top":0.87222224,"width":0.00859375,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Microphone","depth":19,"bounds":{"left":0.2234375,"top":0.8645833,"width":0.015625,"height":0.027777778},"role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Your Jiminny chats aren’t used to improve our models. Gemini is AI and can make mistakes, including about people.","depth":17,"bounds":{"left":0.10039063,"top":0.9097222,"width":0.14296874,"height":0.022222223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Your privacy & Gemini Opens in a new window","depth":17,"bounds":{"left":0.1484375,"top":0.93194443,"width":0.046875,"height":0.011111111},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Your privacy & Gemini","depth":18,"bounds":{"left":0.1484375,"top":0.93194443,"width":0.046875,"height":0.011111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Opens in a new window","depth":19,"bounds":{"left":0.09335937,"top":0.93125,"width":0.05078125,"height":0.011111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Summarize page","depth":7,"bounds":{"left":0.1,"top":0.96319443,"width":0.06289063,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Summarize page","depth":9,"bounds":{"left":0.10664062,"top":0.9673611,"width":0.049609374,"height":0.013888889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Return to home screen","depth":10,"bounds":{"left":0.259375,"top":0.05625,"width":0.041015625,"height":0.027777778},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"lukas.kovalik@jiminny.com","depth":12,"bounds":{"left":0.9097656,"top":0.057638887,"width":0.06523438,"height":0.011805556},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Switch account","depth":11,"bounds":{"left":0.94023436,"top":0.06875,"width":0.034765624,"height":0.011805556},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Switch account","depth":12,"bounds":{"left":0.94023436,"top":0.06875,"width":0.034765624,"height":0.011805556},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Lukas Kovalik","depth":14,"bounds":{"left":0.39765626,"top":0.36319444,"width":0.03515625,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"More options","depth":13,"bounds":{"left":0.6578125,"top":0.35277778,"width":0.01875,"height":0.033333335},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Turn off microphone","depth":14,"bounds":{"left":0.496875,"top":0.59097224,"width":0.021875,"height":0.033333335},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Turn off camera","depth":14,"bounds":{"left":0.525,"top":0.59097224,"width":0.021875,"height":0.033333335},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Turn on background blur","depth":13,"bounds":{"left":0.553125,"top":0.59097224,"width":0.021875,"height":0.033333335},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Microphone: soundcore AeroClip","depth":12,"bounds":{"left":0.39140624,"top":0.6493056,"width":0.06992187,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Speaker: System Default Speaker Device","depth":13,"bounds":{"left":0.46445313,"top":0.6493056,"width":0.06992187,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Camera: FaceTime HD Camera","depth":13,"bounds":{"left":0.5375,"top":0.6493056,"width":0.06992187,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Backgrounds and effects","depth":12,"bounds":{"left":0.6105469,"top":0.6493056,"width":0.06992187,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXHeading","text":"Enhance your appearance","depth":14,"bounds":{"left":0.5679687,"top":0.5138889,"width":0.07539062,"height":0.016666668},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Enhance your appearance","depth":15,"bounds":{"left":0.5679687,"top":0.51458335,"width":0.07539062,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Meet can adjust your image sharpness and lighting so others can see you better. To change how you look, use the Appearance tab.","depth":15,"bounds":{"left":0.55546874,"top":0.53333336,"width":0.10507812,"height":0.05486111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Not now","depth":15,"bounds":{"left":0.590625,"top":0.6,"width":0.03046875,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Try now","depth":15,"bounds":{"left":0.62578124,"top":0.6,"width":0.0390625,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":true,"is_selected":false},{"role":"AXStaticText","text":"Try now","depth":17,"bounds":{"left":0.6351563,"top":0.60694444,"width":0.0203125,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Daily - Platform","depth":11,"bounds":{"left":0.68671876,"top":0.3888889,"width":0.175,"height":0.025},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Daily - Platform","depth":14,"bounds":{"left":0.7363281,"top":0.38819444,"width":0.07578125,"height":0.025694445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Scheduled for","depth":12,"bounds":{"left":0.7601563,"top":0.425,"width":0.035546876,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Thu, Apr 16","depth":12,"bounds":{"left":0.73164064,"top":0.43888888,"width":0.046484374,"height":0.021527778},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"9:45 AM","depth":12,"bounds":{"left":0.7828125,"top":0.43888888,"width":0.033984374,"height":0.021527778},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Use Gemini to take notes Share notes and transcript","depth":11,"bounds":{"left":0.71132815,"top":0.4722222,"width":0.12578125,"height":0.044444446},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Use Gemini to take notes","depth":12,"bounds":{"left":0.73476565,"top":0.48194444,"width":0.06328125,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Share notes and transcript","depth":12,"bounds":{"left":0.73476565,"top":0.49583334,"width":0.056640625,"height":0.011111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Start","depth":12,"bounds":{"left":0.8011719,"top":0.48055556,"width":0.03125,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Start","depth":14,"bounds":{"left":0.8105469,"top":0.4875,"width":0.0125,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Join anyway","depth":12,"bounds":{"left":0.72734374,"top":0.5277778,"width":0.09375,"height":0.03888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Join anyway","depth":14,"bounds":{"left":0.75859374,"top":0.5402778,"width":0.03125,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Other ways to join","depth":12,"bounds":{"left":0.7378906,"top":0.5861111,"width":0.07265625,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Gemini is available in Meet as your personal in-meeting assistant. It can analyze conversation via temporary access to meeting captions. Using Ask Gemini won't create a recording or store meeting data. The meeting host can turn it off.","depth":12,"bounds":{"left":0.50273436,"top":0.9375,"width":0.26328126,"height":0.035416666},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Learn more","depth":12,"bounds":{"left":0.64453125,"top":0.9611111,"width":0.027734375,"height":0.011805556},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Learn more","depth":13,"bounds":{"left":0.64453125,"top":0.9611111,"width":0.027734375,"height":0.011805556},"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
-5166859552799166284
|
8730315986773212238
|
click
|
accessibility
|
NULL
|
JY-20543 add AJ reports User pilot tracking by Lak JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
Console Home | Console Home | us-east-2
Console Home | Console Home | us-east-2
SecurityGroup | EC2 | us-east-2
SecurityGroup | EC2 | us-east-2
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app
SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Jiminny
Jiminny
Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf
Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf
Service-Desk - Queues - Platform team - Service space - Jira
Service-Desk - Queues - Platform team - Service space - Jira
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
CloudWatch | us-east-2
CloudWatch | us-east-2
Meet - Daily - Platform
Meet - Daily - Platform
Close tab
Settings
Settings
New Tab
Customize sidebar
Close Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
AI Chat settings
Close
WORK, Google Account: [EMAIL]
Main menu
New Chat
Open menu for conversation actions.
Conversation with Gemini
Conversation with Gemini
Copy prompt
Edit
You said why I can't see speaker data on meemt in firefox. ho wto set it up
You said
why I can't see speaker data on meemt in firefox. ho wto set it up
Listen
Show more options
Show thinking
Gemini said
Gemini said
Dealing with missing features right when you need them is incredibly frustrating. Assuming "meemt" means Google Meet, the reason you can't see your speaker data comes down to how Firefox interacts with Google's platform compared to Chrome.
Since "speaker data" can mean a couple of different things in a meeting, here are the two most likely causes for your issue and exactly how to get things working.
1. You Need "Speaker Notes" for Google Slides
1. You Need "Speaker Notes" for Google Slides
The Reality:
Google Meet has a native feature that lets you see your presentation's speaker notes right inside the video call interface.
However, this relies on a specific "Present a Tab" technology built exclusively for Google Chrome. Firefox handles screen sharing differently, so that native integration simply won't load.
View source details for citation from Google Workspace Updates. Opens side panel.
How to set it up (The Firefox Workaround):
You can still present and read your notes in Firefox by manually managing your windows.
Open your Google Slides presentation in a standard Firefox window.
Click the dropdown arrow next to the
Slideshow
button in the top right corner.
Select
Presenter view
to pop your speaker notes out into a separate, smaller window.
View source details for citation from Skywork. Opens side panel.
Join your Google Meet in a different Firefox window.
Click
Present now
and choose the
Window
option.
Select the window displaying your main slides (do not select your separate speaker notes window).
Resize your windows on your monitor so you can comfortably read the notes window while keeping an eye on the Meet window.
2. You Need "Speaker Labels" or Transcripts
2. You Need "Speaker Labels" or Transcripts
The Reality:
If you are trying to use a third-party AI note-taker (like Otter.ai, Tactiq, or tl;dv) to capture transcriptions and see who is speaking, Firefox is likely the roadblock. Firefox has strict privacy guardrails that prevent extensions from capturing internal browser audio easily, so most developers only build these tools for Chrome.
How to set it up:
Turn on built-in captions:
Google Meet has its own live captions that natively identify who is speaking, even in Firefox. Click the
CC
button at the bottom of your Meet screen to toggle them on.
Search for a Firefox add-on:
Check the Mozilla Add-ons store to see if your preferred tool actually has a supported Firefox version (for example, Fellow.ai offers one).
View source details for citation from Fellow.ai. Opens side panel.
Switch browsers temporarily:
If your specific transcription tool is explicitly Chrome-only, you will unfortunately need to join that specific meeting using a Chromium-based browser like Chrome, Edge, or Brave to capture the data.
Using Meet's built-in closed captions or the manual Presenter view workaround will get your speaker data back on track without forcing you to completely abandon Firefox.
Sources
Sources
Enter a prompt for Gemini
encrypted
Enter a prompt for Gemini
encrypted
Open upload file menu
Tools
Open mode picker
Pro
Microphone
Your Jiminny chats aren’t used to improve our models. Gemini is AI and can make mistakes, including about people.
Your privacy & Gemini Opens in a new window
Your privacy & Gemini
Opens in a new window
Summarize page
Summarize page
Return to home screen
[EMAIL]
Switch account
Switch account
Lukas Kovalik
More options
Turn off microphone
Turn off camera
Turn on background blur
Microphone: soundcore AeroClip
Speaker: System Default Speaker Device
Camera: FaceTime HD Camera
Backgrounds and effects
Enhance your appearance
Enhance your appearance
Meet can adjust your image sharpness and lighting so others can see you better. To change how you look, use the Appearance tab.
Not now
Try now
Try now
Daily - Platform
Daily - Platform
Scheduled for
Thu, Apr 16
9:45 AM
Use Gemini to take notes Share notes and transcript
Use Gemini to take notes
Share notes and transcript
Start
Start
Join anyway
Join anyway
Other ways to join
Gemini is available in Meet as your personal in-meeting assistant. It can analyze conversation via temporary access to meeting captions. Using Ask Gemini won't create a recording or store meeting data. The meeting host can turn it off.
Learn more
Learn more...
|
NULL
|
|
10077
|
195
|
42
|
2026-04-14T08:10:50.109010+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776154250109_m2.jpg...
|
Firefox
|
Meet - Daily - Platform — Work
|
True
|
meet.google.com/mie-gawc-dsi
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
JY-20543 add AJ reports User pilot tracking by Lak JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
Console Home | Console Home | us-east-2
Console Home | Console Home | us-east-2
SecurityGroup | EC2 | us-east-2
SecurityGroup | EC2 | us-east-2
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app
SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Jiminny
Jiminny
Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf
Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf
Service-Desk - Queues - Platform team - Service space - Jira
Service-Desk - Queues - Platform team - Service space - Jira
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
CloudWatch | us-east-2
CloudWatch | us-east-2
Meet - Daily - Platform
Meet - Daily - Platform
Close tab
Settings
Settings
New Tab
Customize sidebar
Close Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
AI Chat settings
Close
WORK, Google Account: [EMAIL]
Main menu
New Chat
Open menu for conversation actions.
Conversation with Gemini
Conversation with Gemini
Copy prompt
Edit
You said why I can't see speaker data on meemt in firefox. ho wto set it up
You said
why I can't see speaker data on meemt in firefox. ho wto set it up
Listen
Show more options
Show thinking
Gemini said
Gemini said
Dealing with missing features right when you need them is incredibly frustrating. Assuming "meemt" means Google Meet, the reason you can't see your speaker data comes down to how Firefox interacts with Google's platform compared to Chrome.
Since "speaker data" can mean a couple of different things in a meeting, here are the two most likely causes for your issue and exactly how to get things working.
1. You Need "Speaker Notes" for Google Slides
1. You Need "Speaker Notes" for Google Slides
The Reality:
Google Meet has a native feature that lets you see your presentation's speaker notes right inside the video call interface.
However, this relies on a specific "Present a Tab" technology built exclusively for Google Chrome. Firefox handles screen sharing differently, so that native integration simply won't load.
View source details for citation from Google Workspace Updates. Opens side panel.
How to set it up (The Firefox Workaround):
You can still present and read your notes in Firefox by manually managing your windows.
Open your Google Slides presentation in a standard Firefox window.
Click the dropdown arrow next to the
Slideshow
button in the top right corner.
Select
Presenter view
to pop your speaker notes out into a separate, smaller window.
View source details for citation from Skywork. Opens side panel.
Join your Google Meet in a different Firefox window.
Click
Present now
and choose the
Window
option.
Select the window displaying your main slides (do not select your separate speaker notes window).
Resize your windows on your monitor so you can comfortably read the notes window while keeping an eye on the Meet window.
2. You Need "Speaker Labels" or Transcripts
2. You Need "Speaker Labels" or Transcripts
The Reality:
If you are trying to use a third-party AI note-taker (like Otter.ai, Tactiq, or tl;dv) to capture transcriptions and see who is speaking, Firefox is likely the roadblock. Firefox has strict privacy guardrails that prevent extensions from capturing internal browser audio easily, so most developers only build these tools for Chrome.
How to set it up:
Turn on built-in captions:
Google Meet has its own live captions that natively identify who is speaking, even in Firefox. Click the
CC
button at the bottom of your Meet screen to toggle them on.
Search for a Firefox add-on:
Check the Mozilla Add-ons store to see if your preferred tool actually has a supported Firefox version (for example, Fellow.ai offers one).
View source details for citation from Fellow.ai. Opens side panel.
Switch browsers temporarily:
If your specific transcription tool is explicitly Chrome-only, you will unfortunately need to join that specific meeting using a Chromium-based browser like Chrome, Edge, or Brave to capture the data.
Using Meet's built-in closed captions or the manual Presenter view workaround will get your speaker data back on track without forcing you to completely abandon Firefox.
Sources
Sources
I men in dia (arc) I can see my headphones in both microphone and speakers
I men in dia (arc) I can see my headphones in both microphone and speakers
Open upload file menu
Tools
Open mode picker
Pro
Send message
Your Jiminny chats aren’t used to improve our models. Gemini is AI and can make mistakes, including about people.
Your privacy & Gemini Opens in a new window
Your privacy & Gemini
Opens in a new window
Summarize page
Summarize page
Backgrounds and effects
Backgrounds and effects
Turn off visual effects
Back
Generate a background
No scene
No scene
Acropolic propylaea
Create other samples
Create other samples
You can generate more results or change your description to get different results
Learn more about generating backgrounds
Learn more about generating backgrounds
Use this background
Like
Dislike
Report a legal issue
Report a legal issue
Close
Generated background has been applied
Background is now replaced...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":4,"bounds":{"left":0.00234375,"top":0.045138888,"width":0.0890625,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira","depth":4,"bounds":{"left":0.0,"top":0.08263889,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira","depth":5,"bounds":{"left":0.015625,"top":0.09236111,"width":0.11796875,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":4,"bounds":{"left":0.0,"top":0.11111111,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":5,"bounds":{"left":0.015625,"top":0.12083333,"width":0.1515625,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Console Home | Console Home | us-east-2","depth":4,"bounds":{"left":0.0,"top":0.13958333,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Console Home | Console Home | us-east-2","depth":5,"bounds":{"left":0.015625,"top":0.14930555,"width":0.08671875,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"SecurityGroup | EC2 | us-east-2","depth":4,"bounds":{"left":0.0,"top":0.16805555,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"SecurityGroup | EC2 | us-east-2","depth":5,"bounds":{"left":0.015625,"top":0.17777778,"width":0.06484375,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.19652778,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":5,"bounds":{"left":0.015625,"top":0.20625,"width":0.18710938,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.225,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app","depth":5,"bounds":{"left":0.015625,"top":0.23472223,"width":0.23476562,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet","depth":4,"bounds":{"left":0.0,"top":0.2534722,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet","depth":5,"bounds":{"left":0.015625,"top":0.26319444,"width":0.1984375,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jiminny","depth":4,"bounds":{"left":0.0,"top":0.28194445,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny","depth":5,"bounds":{"left":0.015625,"top":0.29166666,"width":0.015625,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf","depth":4,"bounds":{"left":0.0,"top":0.31041667,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf","depth":5,"bounds":{"left":0.015625,"top":0.3201389,"width":0.1640625,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Service-Desk - Queues - Platform team - Service space - Jira","depth":4,"bounds":{"left":0.0,"top":0.33888888,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Service-Desk - Queues - Platform team - Service space - Jira","depth":5,"bounds":{"left":0.015625,"top":0.34861112,"width":0.12617187,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.3673611,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":5,"bounds":{"left":0.015625,"top":0.37708333,"width":0.18710938,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":4,"bounds":{"left":0.0,"top":0.39583334,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":5,"bounds":{"left":0.015625,"top":0.40555555,"width":0.1515625,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"CloudWatch | us-east-2","depth":4,"bounds":{"left":0.0,"top":0.42430556,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"CloudWatch | us-east-2","depth":5,"bounds":{"left":0.015625,"top":0.4340278,"width":0.0484375,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Meet - Daily - Platform","depth":4,"bounds":{"left":0.0,"top":0.45277777,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Meet - Daily - Platform","depth":5,"bounds":{"left":0.015625,"top":0.4625,"width":0.046484374,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.07890625,"top":0.45902777,"width":0.009375,"height":0.016666668},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Settings","depth":4,"bounds":{"left":0.0,"top":0.48125,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Settings","depth":5,"bounds":{"left":0.015625,"top":0.49097222,"width":0.016796876,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"New Tab","depth":4,"bounds":{"left":0.003125,"top":0.51111114,"width":0.08710937,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.003125,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Close Google Gemini (⌃X)","depth":6,"bounds":{"left":0.01640625,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"bounds":{"left":0.029296875,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"bounds":{"left":0.0421875,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"bounds":{"left":0.05546875,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"AI Chat settings","depth":7,"bounds":{"left":0.2171875,"top":0.047916666,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Close","depth":7,"bounds":{"left":0.23125,"top":0.047916666,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"WORK, Google Account: lukas.kovalik@jiminny.com","depth":12,"bounds":{"left":0.228125,"top":0.090277776,"width":0.015625,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Main menu","depth":12,"bounds":{"left":0.0984375,"top":0.090277776,"width":0.015625,"height":0.027777778},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Chat","depth":12,"bounds":{"left":0.1953125,"top":0.090277776,"width":0.015625,"height":0.027777778},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Open menu for conversation actions.","depth":12,"bounds":{"left":0.2109375,"top":0.090277776,"width":0.015625,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXHeading","text":"Conversation with Gemini","depth":15,"bounds":{"left":0.09335937,"top":0.12847222,"width":0.000390625,"height":0.00069444446},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Conversation with Gemini","depth":16,"bounds":{"left":0.09335937,"top":0.13055556,"width":0.14101562,"height":0.022222223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Copy prompt","depth":21,"bounds":{"left":0.1203125,"top":0.15972222,"width":0.015625,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Edit","depth":21,"bounds":{"left":0.1375,"top":0.15972222,"width":0.015625,"height":0.027777778},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"You said why I can't see speaker data on meemt in firefox. ho wto set it up","depth":21,"bounds":{"left":0.1609375,"top":0.16805555,"width":0.072265625,"height":0.058333334},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"You said","depth":23,"bounds":{"left":0.09335937,"top":0.1701389,"width":0.0234375,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"why I can't see speaker data on meemt in firefox. ho wto set it up","depth":23,"bounds":{"left":0.1609375,"top":0.17083333,"width":0.07070313,"height":0.05347222},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Listen","depth":22,"bounds":{"left":0.22382812,"top":0.25416666,"width":0.015625,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Show more options","depth":20,"bounds":{"left":0.22382812,"top":0.24930556,"width":0.015625,"height":0.027777778},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Show thinking","depth":26,"bounds":{"left":0.11953125,"top":0.25625,"width":0.036328126,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Gemini said","depth":20,"bounds":{"left":0.11679687,"top":0.2923611,"width":0.000390625,"height":0.00069444446},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Gemini said","depth":21,"bounds":{"left":0.11679687,"top":0.29375,"width":0.048046876,"height":0.016666668},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Dealing with missing features right when you need them is incredibly frustrating. Assuming \"meemt\" means Google Meet, the reason you can't see your speaker data comes down to how Firefox interacts with Google's platform compared to Chrome.","depth":24,"bounds":{"left":0.10390625,"top":0.30069444,"width":0.13046876,"height":0.10486111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Since \"speaker data\" can mean a couple of different things in a meeting, here are the two most likely causes for your issue and exactly how to get things working.","depth":24,"bounds":{"left":0.10390625,"top":0.4201389,"width":0.13125,"height":0.06875},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"1. You Need \"Speaker Notes\" for Google Slides","depth":23,"bounds":{"left":0.10390625,"top":0.52152777,"width":0.13242188,"height":0.033333335},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1. You Need \"Speaker Notes\" for Google Slides","depth":24,"bounds":{"left":0.10390625,"top":0.5229167,"width":0.12070312,"height":0.03125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"The Reality:","depth":24,"bounds":{"left":0.10390625,"top":0.5625,"width":0.036328126,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Google Meet has a native feature that lets you see your presentation's speaker notes right inside the video call interface.","depth":24,"bounds":{"left":0.10390625,"top":0.5625,"width":0.13242188,"height":0.050694443},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"However, this relies on a specific \"Present a Tab\" technology built exclusively for Google Chrome. Firefox handles screen sharing differently, so that native integration simply won't load.","depth":24,"bounds":{"left":0.10390625,"top":0.5986111,"width":0.12539062,"height":0.10486111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"View source details for citation from Google Workspace Updates. Opens side panel.","depth":24,"bounds":{"left":0.13710937,"top":0.68958336,"width":0.01015625,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"How to set it up (The Firefox Workaround):","depth":24,"bounds":{"left":0.10390625,"top":0.71805555,"width":0.12851563,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"You can still present and read your notes in Firefox by manually managing your windows.","depth":24,"bounds":{"left":0.10390625,"top":0.7361111,"width":0.12617187,"height":0.03263889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Open your Google Slides presentation in a standard Firefox window.","depth":26,"bounds":{"left":0.11796875,"top":0.7777778,"width":0.115625,"height":0.03263889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Click the dropdown arrow next to the","depth":26,"bounds":{"left":0.11796875,"top":0.8194444,"width":0.10703125,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Slideshow","depth":26,"bounds":{"left":0.11796875,"top":0.8375,"width":0.03125,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"button in the top right corner.","depth":26,"bounds":{"left":0.14921875,"top":0.8375,"width":0.08515625,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Select","depth":26,"bounds":{"left":0.11796875,"top":0.8611111,"width":0.01953125,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Presenter view","depth":26,"bounds":{"left":0.1375,"top":0.8611111,"width":0.0453125,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"to pop your speaker notes out into a separate, smaller window.","depth":26,"bounds":{"left":0.11796875,"top":0.8611111,"width":0.10078125,"height":0.050694443},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"View source details for citation from Skywork. Opens side panel.","depth":26,"bounds":{"left":0.16523437,"top":0.8979167,"width":0.01015625,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Join your Google Meet in a different Firefox window.","depth":26,"bounds":{"left":0.11796875,"top":0.92083335,"width":0.103125,"height":0.03263889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Click","depth":26,"bounds":{"left":0.11796875,"top":0.9625,"width":0.015234375,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Present now","depth":26,"bounds":{"left":0.13320312,"top":0.9625,"width":0.037890624,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"and choose the","depth":26,"bounds":{"left":0.17109375,"top":0.9625,"width":0.047265626,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Window","depth":26,"bounds":{"left":0.11796875,"top":0.98055553,"width":0.02421875,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"option.","depth":26,"bounds":{"left":0.1421875,"top":0.98055553,"width":0.02109375,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Select the window displaying your main slides (do not select your separate speaker notes window).","depth":26,"bounds":{"left":0.11796875,"top":1.0,"width":0.11328125,"height":-0.0041667223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Resize your windows on your monitor so you can comfortably read the notes window while keeping an eye on the Meet window.","depth":26,"bounds":{"left":0.11796875,"top":1.0,"width":0.11835937,"height":-0.06388891},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"2. You Need \"Speaker Labels\" or Transcripts","depth":23,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2. You Need \"Speaker Labels\" or Transcripts","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"The Reality:","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"If you are trying to use a third-party AI note-taker (like Otter.ai, Tactiq, or tl;dv) to capture transcriptions and see who is speaking, Firefox is likely the roadblock. Firefox has strict privacy guardrails that prevent extensions from capturing internal browser audio easily, so most developers only build these tools for Chrome.","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"How to set it up:","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Turn on built-in captions:","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Google Meet has its own live captions that natively identify who is speaking, even in Firefox. Click the","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"CC","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"button at the bottom of your Meet screen to toggle them on.","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Search for a Firefox add-on:","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Check the Mozilla Add-ons store to see if your preferred tool actually has a supported Firefox version (for example, Fellow.ai offers one).","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"View source details for citation from Fellow.ai. Opens side panel.","depth":26,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Switch browsers temporarily:","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"If your specific transcription tool is explicitly Chrome-only, you will unfortunately need to join that specific meeting using a Chromium-based browser like Chrome, Edge, or Brave to capture the data.","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Using Meet's built-in closed captions or the manual Presenter view workaround will get your speaker data back on track without forcing you to completely abandon Firefox.","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Sources","depth":23,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Sources","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextArea","text":"I men in dia (arc) I can see my headphones in both microphone and speakers","depth":20,"bounds":{"left":0.109375,"top":0.8020833,"width":0.125,"height":0.05},"value":"I men in dia (arc) I can see my headphones in both microphone and speakers","help_text":"","role_description":"text entry area","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"I men in dia (arc) I can see my headphones in both microphone and speakers","depth":22,"bounds":{"left":0.109375,"top":0.8034722,"width":0.10625,"height":0.047916666},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open upload file menu","depth":20,"bounds":{"left":0.1046875,"top":0.86527777,"width":0.015625,"height":0.027777778},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Tools","depth":18,"bounds":{"left":0.1234375,"top":0.86527777,"width":0.015625,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Open mode picker","depth":20,"bounds":{"left":0.190625,"top":0.8645833,"width":0.03046875,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pro","depth":23,"bounds":{"left":0.196875,"top":0.87222224,"width":0.00859375,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Send message","depth":19,"bounds":{"left":0.22265625,"top":0.86388886,"width":0.01640625,"height":0.029166667},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Your Jiminny chats aren’t used to improve our models. Gemini is AI and can make mistakes, including about people.","depth":17,"bounds":{"left":0.10039063,"top":0.9097222,"width":0.14296874,"height":0.022222223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Your privacy & Gemini Opens in a new window","depth":17,"bounds":{"left":0.1484375,"top":0.93194443,"width":0.046875,"height":0.011111111},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Your privacy & Gemini","depth":18,"bounds":{"left":0.1484375,"top":0.93194443,"width":0.046875,"height":0.011111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Opens in a new window","depth":19,"bounds":{"left":0.09335937,"top":0.93125,"width":0.05078125,"height":0.011111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Summarize page","depth":7,"bounds":{"left":0.1,"top":0.96319443,"width":0.06289063,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Summarize page","depth":9,"bounds":{"left":0.10664062,"top":0.9673611,"width":0.049609374,"height":0.013888889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Backgrounds and effects","depth":11,"bounds":{"left":0.3921875,"top":0.28958333,"width":0.46289062,"height":0.055555556},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Backgrounds and effects","depth":12,"bounds":{"left":0.4015625,"top":0.30694443,"width":0.10546875,"height":0.021527778},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Turn off visual effects","depth":14,"bounds":{"left":0.675,"top":0.59652776,"width":0.021875,"height":0.03888889},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Back","depth":15,"bounds":{"left":0.7109375,"top":0.34513888,"width":0.015625,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Generate a background","depth":14,"bounds":{"left":0.7265625,"top":0.35,"width":0.08710937,"height":0.018055556},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXComboBox","text":"No scene","depth":15,"bounds":{"left":0.715625,"top":0.38125,"width":0.12539062,"height":0.03888889},"value":"No scene","help_text":"","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"No scene","depth":17,"bounds":{"left":0.740625,"top":0.39375,"width":0.0265625,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextArea","text":"Acropolic propylaea","depth":16,"bounds":{"left":0.715625,"top":0.44236112,"width":0.12539062,"height":0.06666667},"value":"Acropolic propylaea","help_text":"","placeholder":"Jungle patio at sunset","role_description":"text entry area","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Create other samples","depth":16,"bounds":{"left":0.7410156,"top":0.53402776,"width":0.07460938,"height":0.025},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Create other samples","depth":18,"bounds":{"left":0.75039065,"top":0.5402778,"width":0.055859376,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"You can generate more results or change your description to get different results","depth":16,"bounds":{"left":0.72734374,"top":0.5715278,"width":0.10195313,"height":0.022222223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Learn more about generating backgrounds","depth":16,"bounds":{"left":0.7308594,"top":0.59375,"width":0.09492187,"height":0.011111111},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Learn more about generating backgrounds","depth":17,"bounds":{"left":0.7308594,"top":0.59375,"width":0.09492187,"height":0.011111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Use this background","depth":16,"bounds":{"left":0.72148436,"top":0.61319447,"width":0.1140625,"height":0.12638889},"role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":true,"is_selected":false},{"role":"AXButton","text":"Like","depth":17,"bounds":{"left":0.809375,"top":0.71458334,"width":0.0109375,"height":0.019444445},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Dislike","depth":17,"bounds":{"left":0.821875,"top":0.71458334,"width":0.0109375,"height":0.019444445},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Report a legal issue","depth":16,"bounds":{"left":0.72148436,"top":0.75069445,"width":0.04296875,"height":0.011111111},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Report a legal issue","depth":17,"bounds":{"left":0.72148436,"top":0.75069445,"width":0.04296875,"height":0.011111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close","depth":11,"bounds":{"left":0.83320314,"top":0.30069444,"width":0.01875,"height":0.033333335},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Generated background has been applied","depth":8,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Background is now replaced","depth":8,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
-443061304843876557
|
8729445723311160398
|
visual_change
|
accessibility
|
NULL
|
JY-20543 add AJ reports User pilot tracking by Lak JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
Console Home | Console Home | us-east-2
Console Home | Console Home | us-east-2
SecurityGroup | EC2 | us-east-2
SecurityGroup | EC2 | us-east-2
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app
SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Jiminny
Jiminny
Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf
Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf
Service-Desk - Queues - Platform team - Service space - Jira
Service-Desk - Queues - Platform team - Service space - Jira
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
CloudWatch | us-east-2
CloudWatch | us-east-2
Meet - Daily - Platform
Meet - Daily - Platform
Close tab
Settings
Settings
New Tab
Customize sidebar
Close Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
AI Chat settings
Close
WORK, Google Account: [EMAIL]
Main menu
New Chat
Open menu for conversation actions.
Conversation with Gemini
Conversation with Gemini
Copy prompt
Edit
You said why I can't see speaker data on meemt in firefox. ho wto set it up
You said
why I can't see speaker data on meemt in firefox. ho wto set it up
Listen
Show more options
Show thinking
Gemini said
Gemini said
Dealing with missing features right when you need them is incredibly frustrating. Assuming "meemt" means Google Meet, the reason you can't see your speaker data comes down to how Firefox interacts with Google's platform compared to Chrome.
Since "speaker data" can mean a couple of different things in a meeting, here are the two most likely causes for your issue and exactly how to get things working.
1. You Need "Speaker Notes" for Google Slides
1. You Need "Speaker Notes" for Google Slides
The Reality:
Google Meet has a native feature that lets you see your presentation's speaker notes right inside the video call interface.
However, this relies on a specific "Present a Tab" technology built exclusively for Google Chrome. Firefox handles screen sharing differently, so that native integration simply won't load.
View source details for citation from Google Workspace Updates. Opens side panel.
How to set it up (The Firefox Workaround):
You can still present and read your notes in Firefox by manually managing your windows.
Open your Google Slides presentation in a standard Firefox window.
Click the dropdown arrow next to the
Slideshow
button in the top right corner.
Select
Presenter view
to pop your speaker notes out into a separate, smaller window.
View source details for citation from Skywork. Opens side panel.
Join your Google Meet in a different Firefox window.
Click
Present now
and choose the
Window
option.
Select the window displaying your main slides (do not select your separate speaker notes window).
Resize your windows on your monitor so you can comfortably read the notes window while keeping an eye on the Meet window.
2. You Need "Speaker Labels" or Transcripts
2. You Need "Speaker Labels" or Transcripts
The Reality:
If you are trying to use a third-party AI note-taker (like Otter.ai, Tactiq, or tl;dv) to capture transcriptions and see who is speaking, Firefox is likely the roadblock. Firefox has strict privacy guardrails that prevent extensions from capturing internal browser audio easily, so most developers only build these tools for Chrome.
How to set it up:
Turn on built-in captions:
Google Meet has its own live captions that natively identify who is speaking, even in Firefox. Click the
CC
button at the bottom of your Meet screen to toggle them on.
Search for a Firefox add-on:
Check the Mozilla Add-ons store to see if your preferred tool actually has a supported Firefox version (for example, Fellow.ai offers one).
View source details for citation from Fellow.ai. Opens side panel.
Switch browsers temporarily:
If your specific transcription tool is explicitly Chrome-only, you will unfortunately need to join that specific meeting using a Chromium-based browser like Chrome, Edge, or Brave to capture the data.
Using Meet's built-in closed captions or the manual Presenter view workaround will get your speaker data back on track without forcing you to completely abandon Firefox.
Sources
Sources
I men in dia (arc) I can see my headphones in both microphone and speakers
I men in dia (arc) I can see my headphones in both microphone and speakers
Open upload file menu
Tools
Open mode picker
Pro
Send message
Your Jiminny chats aren’t used to improve our models. Gemini is AI and can make mistakes, including about people.
Your privacy & Gemini Opens in a new window
Your privacy & Gemini
Opens in a new window
Summarize page
Summarize page
Backgrounds and effects
Backgrounds and effects
Turn off visual effects
Back
Generate a background
No scene
No scene
Acropolic propylaea
Create other samples
Create other samples
You can generate more results or change your description to get different results
Learn more about generating backgrounds
Learn more about generating backgrounds
Use this background
Like
Dislike
Report a legal issue
Report a legal issue
Close
Generated background has been applied
Background is now replaced...
|
NULL
|
|
10078
|
194
|
28
|
2026-04-14T08:11:15.071559+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776154275071_m1.jpg...
|
Firefox
|
Meet - Daily - Platform — Work
|
True
|
meet.google.com/mie-gawc-dsi
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
JY-20543 add AJ reports User pilot tracking by Lak JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
Console Home | Console Home | us-east-2
Console Home | Console Home | us-east-2
SecurityGroup | EC2 | us-east-2
SecurityGroup | EC2 | us-east-2
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app
SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Jiminny
Jiminny
Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf
Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf
Service-Desk - Queues - Platform team - Service space - Jira
Service-Desk - Queues - Platform team - Service space - Jira
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
CloudWatch | us-east-2
CloudWatch | us-east-2
Meet - Daily - Platform
Meet - Daily - Platform
Close tab
Settings
Settings
New Tab
Customize sidebar
Close Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
AI Chat settings
Close
WORK, Google Account: [EMAIL]
Main menu
New Chat
Open menu for conversation actions.
Conversation with Gemini
Conversation with Gemini
Copy prompt
Edit
You said why I can't see speaker data on meemt in firefox. ho wto set it up
You said
why I can't see speaker data on meemt in firefox. ho wto set it up
Listen
Show more options
Show thinking
Gemini said
Gemini said
Dealing with missing features right when you need them is incredibly frustrating. Assuming "meemt" means Google Meet, the reason you can't see your speaker data comes down to how Firefox interacts with Google's platform compared to Chrome.
Since "speaker data" can mean a couple of different things in a meeting, here are the two most likely causes for your issue and exactly how to get things working.
1. You Need "Speaker Notes" for Google Slides
1. You Need "Speaker Notes" for Google Slides
The Reality:
Google Meet has a native feature that lets you see your presentation's speaker notes right inside the video call interface.
However, this relies on a specific "Present a Tab" technology built exclusively for Google Chrome. Firefox handles screen sharing differently, so that native integration simply won't load.
View source details for citation from Google Workspace Updates. Opens side panel.
How to set it up (The Firefox Workaround):
You can still present and read your notes in Firefox by manually managing your windows.
Open your Google Slides presentation in a standard Firefox window.
Click the dropdown arrow next to the
Slideshow
button in the top right corner.
Select
Presenter view
to pop your speaker notes out into a separate, smaller window.
View source details for citation from Skywork. Opens side panel.
Join your Google Meet in a different Firefox window.
Click
Present now
and choose the
Window
option.
Select the window displaying your main slides (do not select your separate speaker notes window).
Resize your windows on your monitor so you can comfortably read the notes window while keeping an eye on the Meet window.
2. You Need "Speaker Labels" or Transcripts
2. You Need "Speaker Labels" or Transcripts
The Reality:
If you are trying to use a third-party AI note-taker (like Otter.ai, Tactiq, or tl;dv) to capture transcriptions and see who is speaking, Firefox is likely the roadblock. Firefox has strict privacy guardrails that prevent extensions from capturing internal browser audio easily, so most developers only build these tools for Chrome.
How to set it up:
Turn on built-in captions:
Google Meet has its own live captions that natively identify who is speaking, even in Firefox. Click the
CC
button at the bottom of your Meet screen to toggle them on.
Search for a Firefox add-on:
Check the Mozilla Add-ons store to see if your preferred tool actually has a supported Firefox version (for example, Fellow.ai offers one).
View source details for citation from Fellow.ai. Opens side panel.
Switch browsers temporarily:
If your specific transcription tool is explicitly Chrome-only, you will unfortunately need to join that specific meeting using a Chromium-based browser like Chrome, Edge, or Brave to capture the data.
Using Meet's built-in closed captions or the manual Presenter view workaround will get your speaker data back on track without forcing you to completely abandon Firefox.
Sources
Sources
I men in dia (arc) I can see my headphones in both microphone and speakers
I men in dia (arc) I can see my headphones in both microphone and speakers
Open upload file menu
Tools
Open mode picker
Pro
Send message
Your Jiminny chats aren’t used to improve our models. Gemini is AI and can make mistakes, including about people.
Your privacy & Gemini Opens in a new window
Your privacy & Gemini
Opens in a new window
Summarize page
Summarize page
Backgrounds and effects
Backgrounds and effects
Turn off visual effects
Back
Generate a background
No scene
No scene
Acropolic propylaea
Create other samples
Create other samples
You can generate more results or change your description to get different results
Learn more about generating backgrounds
Learn more about generating backgrounds
Use this background
Like
Dislike
Report a legal issue
Report a legal issue
Close
Generated background has been applied
Background is now replaced...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Console Home | Console Home | us-east-2","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Console Home | Console Home | us-east-2","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"SecurityGroup | EC2 | us-east-2","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"SecurityGroup | EC2 | us-east-2","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jiminny","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Service-Desk - Queues - Platform team - Service space - Jira","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Service-Desk - Queues - Platform team - Service space - Jira","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"CloudWatch | us-east-2","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"CloudWatch | us-east-2","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Meet - Daily - Platform","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Meet - Daily - Platform","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Settings","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Settings","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"New Tab","depth":4,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Close Google Gemini (⌃X)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"AI Chat settings","depth":7,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Close","depth":7,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"WORK, Google Account: lukas.kovalik@jiminny.com","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Main menu","depth":12,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Chat","depth":12,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Open menu for conversation actions.","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXHeading","text":"Conversation with Gemini","depth":15,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Conversation with Gemini","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Copy prompt","depth":21,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Edit","depth":21,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"You said why I can't see speaker data on meemt in firefox. ho wto set it up","depth":21,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"You said","depth":23,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"why I can't see speaker data on meemt in firefox. ho wto set it up","depth":23,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Listen","depth":22,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Show more options","depth":20,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Show thinking","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Gemini said","depth":20,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Gemini said","depth":21,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Dealing with missing features right when you need them is incredibly frustrating. Assuming \"meemt\" means Google Meet, the reason you can't see your speaker data comes down to how Firefox interacts with Google's platform compared to Chrome.","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Since \"speaker data\" can mean a couple of different things in a meeting, here are the two most likely causes for your issue and exactly how to get things working.","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"1. You Need \"Speaker Notes\" for Google Slides","depth":23,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1. You Need \"Speaker Notes\" for Google Slides","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"The Reality:","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Google Meet has a native feature that lets you see your presentation's speaker notes right inside the video call interface.","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"However, this relies on a specific \"Present a Tab\" technology built exclusively for Google Chrome. Firefox handles screen sharing differently, so that native integration simply won't load.","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"View source details for citation from Google Workspace Updates. Opens side panel.","depth":24,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"How to set it up (The Firefox Workaround):","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"You can still present and read your notes in Firefox by manually managing your windows.","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Open your Google Slides presentation in a standard Firefox window.","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Click the dropdown arrow next to the","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Slideshow","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"button in the top right corner.","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Select","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Presenter view","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"to pop your speaker notes out into a separate, smaller window.","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"View source details for citation from Skywork. Opens side panel.","depth":26,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Join your Google Meet in a different Firefox window.","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Click","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Present now","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"and choose the","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Window","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"option.","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Select the window displaying your main slides (do not select your separate speaker notes window).","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Resize your windows on your monitor so you can comfortably read the notes window while keeping an eye on the Meet window.","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"2. You Need \"Speaker Labels\" or Transcripts","depth":23,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2. You Need \"Speaker Labels\" or Transcripts","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"The Reality:","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"If you are trying to use a third-party AI note-taker (like Otter.ai, Tactiq, or tl;dv) to capture transcriptions and see who is speaking, Firefox is likely the roadblock. Firefox has strict privacy guardrails that prevent extensions from capturing internal browser audio easily, so most developers only build these tools for Chrome.","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"How to set it up:","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Turn on built-in captions:","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Google Meet has its own live captions that natively identify who is speaking, even in Firefox. Click the","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"CC","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"button at the bottom of your Meet screen to toggle them on.","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Search for a Firefox add-on:","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Check the Mozilla Add-ons store to see if your preferred tool actually has a supported Firefox version (for example, Fellow.ai offers one).","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"View source details for citation from Fellow.ai. Opens side panel.","depth":26,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Switch browsers temporarily:","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"If your specific transcription tool is explicitly Chrome-only, you will unfortunately need to join that specific meeting using a Chromium-based browser like Chrome, Edge, or Brave to capture the data.","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Using Meet's built-in closed captions or the manual Presenter view workaround will get your speaker data back on track without forcing you to completely abandon Firefox.","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Sources","depth":23,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Sources","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextArea","text":"I men in dia (arc) I can see my headphones in both microphone and speakers","depth":20,"value":"I men in dia (arc) I can see my headphones in both microphone and speakers","help_text":"","role_description":"text entry area","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"I men in dia (arc) I can see my headphones in both microphone and speakers","depth":22,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open upload file menu","depth":20,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Tools","depth":18,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Open mode picker","depth":20,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pro","depth":23,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Send message","depth":19,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Your Jiminny chats aren’t used to improve our models. Gemini is AI and can make mistakes, including about people.","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Your privacy & Gemini Opens in a new window","depth":17,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Your privacy & Gemini","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Opens in a new window","depth":19,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Summarize page","depth":7,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Summarize page","depth":9,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Backgrounds and effects","depth":11,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Backgrounds and effects","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Turn off visual effects","depth":14,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Back","depth":15,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Generate a background","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXComboBox","text":"No scene","depth":15,"value":"No scene","help_text":"","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"No scene","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextArea","text":"Acropolic propylaea","depth":16,"value":"Acropolic propylaea","help_text":"","placeholder":"Jungle patio at sunset","role_description":"text entry area","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Create other samples","depth":16,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Create other samples","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"You can generate more results or change your description to get different results","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Learn more about generating backgrounds","depth":16,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Learn more about generating backgrounds","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Use this background","depth":16,"role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":true,"is_selected":false},{"role":"AXButton","text":"Like","depth":17,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Dislike","depth":17,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Report a legal issue","depth":16,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Report a legal issue","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close","depth":11,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Generated background has been applied","depth":8,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Background is now replaced","depth":8,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
-443061304843876557
|
8729445723311160398
|
idle
|
accessibility
|
NULL
|
JY-20543 add AJ reports User pilot tracking by Lak JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
Console Home | Console Home | us-east-2
Console Home | Console Home | us-east-2
SecurityGroup | EC2 | us-east-2
SecurityGroup | EC2 | us-east-2
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app
SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Jiminny
Jiminny
Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf
Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf
Service-Desk - Queues - Platform team - Service space - Jira
Service-Desk - Queues - Platform team - Service space - Jira
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
CloudWatch | us-east-2
CloudWatch | us-east-2
Meet - Daily - Platform
Meet - Daily - Platform
Close tab
Settings
Settings
New Tab
Customize sidebar
Close Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
AI Chat settings
Close
WORK, Google Account: [EMAIL]
Main menu
New Chat
Open menu for conversation actions.
Conversation with Gemini
Conversation with Gemini
Copy prompt
Edit
You said why I can't see speaker data on meemt in firefox. ho wto set it up
You said
why I can't see speaker data on meemt in firefox. ho wto set it up
Listen
Show more options
Show thinking
Gemini said
Gemini said
Dealing with missing features right when you need them is incredibly frustrating. Assuming "meemt" means Google Meet, the reason you can't see your speaker data comes down to how Firefox interacts with Google's platform compared to Chrome.
Since "speaker data" can mean a couple of different things in a meeting, here are the two most likely causes for your issue and exactly how to get things working.
1. You Need "Speaker Notes" for Google Slides
1. You Need "Speaker Notes" for Google Slides
The Reality:
Google Meet has a native feature that lets you see your presentation's speaker notes right inside the video call interface.
However, this relies on a specific "Present a Tab" technology built exclusively for Google Chrome. Firefox handles screen sharing differently, so that native integration simply won't load.
View source details for citation from Google Workspace Updates. Opens side panel.
How to set it up (The Firefox Workaround):
You can still present and read your notes in Firefox by manually managing your windows.
Open your Google Slides presentation in a standard Firefox window.
Click the dropdown arrow next to the
Slideshow
button in the top right corner.
Select
Presenter view
to pop your speaker notes out into a separate, smaller window.
View source details for citation from Skywork. Opens side panel.
Join your Google Meet in a different Firefox window.
Click
Present now
and choose the
Window
option.
Select the window displaying your main slides (do not select your separate speaker notes window).
Resize your windows on your monitor so you can comfortably read the notes window while keeping an eye on the Meet window.
2. You Need "Speaker Labels" or Transcripts
2. You Need "Speaker Labels" or Transcripts
The Reality:
If you are trying to use a third-party AI note-taker (like Otter.ai, Tactiq, or tl;dv) to capture transcriptions and see who is speaking, Firefox is likely the roadblock. Firefox has strict privacy guardrails that prevent extensions from capturing internal browser audio easily, so most developers only build these tools for Chrome.
How to set it up:
Turn on built-in captions:
Google Meet has its own live captions that natively identify who is speaking, even in Firefox. Click the
CC
button at the bottom of your Meet screen to toggle them on.
Search for a Firefox add-on:
Check the Mozilla Add-ons store to see if your preferred tool actually has a supported Firefox version (for example, Fellow.ai offers one).
View source details for citation from Fellow.ai. Opens side panel.
Switch browsers temporarily:
If your specific transcription tool is explicitly Chrome-only, you will unfortunately need to join that specific meeting using a Chromium-based browser like Chrome, Edge, or Brave to capture the data.
Using Meet's built-in closed captions or the manual Presenter view workaround will get your speaker data back on track without forcing you to completely abandon Firefox.
Sources
Sources
I men in dia (arc) I can see my headphones in both microphone and speakers
I men in dia (arc) I can see my headphones in both microphone and speakers
Open upload file menu
Tools
Open mode picker
Pro
Send message
Your Jiminny chats aren’t used to improve our models. Gemini is AI and can make mistakes, including about people.
Your privacy & Gemini Opens in a new window
Your privacy & Gemini
Opens in a new window
Summarize page
Summarize page
Backgrounds and effects
Backgrounds and effects
Turn off visual effects
Back
Generate a background
No scene
No scene
Acropolic propylaea
Create other samples
Create other samples
You can generate more results or change your description to get different results
Learn more about generating backgrounds
Learn more about generating backgrounds
Use this background
Like
Dislike
Report a legal issue
Report a legal issue
Close
Generated background has been applied
Background is now replaced...
|
NULL
|
|
10079
|
195
|
43
|
2026-04-14T08:11:20.412941+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776154280412_m2.jpg...
|
Firefox
|
Meet - Daily - Platform — Work
|
True
|
meet.google.com/mie-gawc-dsi
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
JY-20543 add AJ reports User pilot tracking by Lak JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
Console Home | Console Home | us-east-2
Console Home | Console Home | us-east-2
SecurityGroup | EC2 | us-east-2
SecurityGroup | EC2 | us-east-2
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app
SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Jiminny
Jiminny
Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf
Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf
Service-Desk - Queues - Platform team - Service space - Jira
Service-Desk - Queues - Platform team - Service space - Jira
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
CloudWatch | us-east-2
CloudWatch | us-east-2
Meet - Daily - Platform
Meet - Daily - Platform
Close tab
Settings
Settings
New Tab
Customize sidebar
Close Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
AI Chat settings
Close
WORK, Google Account: [EMAIL]
Main menu
New Chat
Open menu for conversation actions.
Conversation with Gemini
Conversation with Gemini
Copy prompt
Edit
You said why I can't see speaker data on meemt in firefox. ho wto set it up
You said
why I can't see speaker data on meemt in firefox. ho wto set it up
Listen
Show more options
Show thinking
Gemini said
Gemini said
Dealing with missing features right when you need them is incredibly frustrating. Assuming "meemt" means Google Meet, the reason you can't see your speaker data comes down to how Firefox interacts with Google's platform compared to Chrome.
Since "speaker data" can mean a couple of different things in a meeting, here are the two most likely causes for your issue and exactly how to get things working.
1. You Need "Speaker Notes" for Google Slides
1. You Need "Speaker Notes" for Google Slides
The Reality:
Google Meet has a native feature that lets you see your presentation's speaker notes right inside the video call interface.
However, this relies on a specific "Present a Tab" technology built exclusively for Google Chrome. Firefox handles screen sharing differently, so that native integration simply won't load.
View source details for citation from Google Workspace Updates. Opens side panel.
How to set it up (The Firefox Workaround):
You can still present and read your notes in Firefox by manually managing your windows.
Open your Google Slides presentation in a standard Firefox window.
Click the dropdown arrow next to the
Slideshow
button in the top right corner.
Select
Presenter view
to pop your speaker notes out into a separate, smaller window.
View source details for citation from Skywork. Opens side panel.
Join your Google Meet in a different Firefox window.
Click
Present now
and choose the
Window
option.
Select the window displaying your main slides (do not select your separate speaker notes window).
Resize your windows on your monitor so you can comfortably read the notes window while keeping an eye on the Meet window.
2. You Need "Speaker Labels" or Transcripts
2. You Need "Speaker Labels" or Transcripts
The Reality:
If you are trying to use a third-party AI note-taker (like Otter.ai, Tactiq, or tl;dv) to capture transcriptions and see who is speaking, Firefox is likely the roadblock. Firefox has strict privacy guardrails that prevent extensions from capturing internal browser audio easily, so most developers only build these tools for Chrome.
How to set it up:
Turn on built-in captions:
Google Meet has its own live captions that natively identify who is speaking, even in Firefox. Click the
CC
button at the bottom of your Meet screen to toggle them on.
Search for a Firefox add-on:
Check the Mozilla Add-ons store to see if your preferred tool actually has a supported Firefox version (for example, Fellow.ai offers one).
View source details for citation from Fellow.ai. Opens side panel.
Switch browsers temporarily:
If your specific transcription tool is explicitly Chrome-only, you will unfortunately need to join that specific meeting using a Chromium-based browser like Chrome, Edge, or Brave to capture the data.
Using Meet's built-in closed captions or the manual Presenter view workaround will get your speaker data back on track without forcing you to completely abandon Firefox.
Sources
Sources
I men in dia (arc) I can see my headphones in both microphone and speakers
I men in dia (arc) I can see my headphones in both microphone and speakers
Open upload file menu
Tools
Open mode picker
Pro
Send message
Your Jiminny chats aren’t used to improve our models. Gemini is AI and can make mistakes, including about people.
Your privacy & Gemini Opens in a new window
Your privacy & Gemini
Opens in a new window
Summarize page
Summarize page
Backgrounds and effects
Backgrounds and effects
Turn off visual effects
Back
Generate a background
No scene
No scene
Acropolic propylaea
Create other samples
Create other samples
You can generate more results or change your description to get different results
Learn more about generating backgrounds
Learn more about generating backgrounds
Use this background
Like
Dislike
Report a legal issue
Report a legal issue
Close
Generated background has been applied
Background is now replaced...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":4,"bounds":{"left":0.00234375,"top":0.045138888,"width":0.0890625,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira","depth":4,"bounds":{"left":0.0,"top":0.08263889,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira","depth":5,"bounds":{"left":0.015625,"top":0.09236111,"width":0.11796875,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":4,"bounds":{"left":0.0,"top":0.11111111,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":5,"bounds":{"left":0.015625,"top":0.12083333,"width":0.1515625,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Console Home | Console Home | us-east-2","depth":4,"bounds":{"left":0.0,"top":0.13958333,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Console Home | Console Home | us-east-2","depth":5,"bounds":{"left":0.015625,"top":0.14930555,"width":0.08671875,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"SecurityGroup | EC2 | us-east-2","depth":4,"bounds":{"left":0.0,"top":0.16805555,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"SecurityGroup | EC2 | us-east-2","depth":5,"bounds":{"left":0.015625,"top":0.17777778,"width":0.06484375,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.19652778,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":5,"bounds":{"left":0.015625,"top":0.20625,"width":0.18710938,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.225,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app","depth":5,"bounds":{"left":0.015625,"top":0.23472223,"width":0.23476562,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet","depth":4,"bounds":{"left":0.0,"top":0.2534722,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet","depth":5,"bounds":{"left":0.015625,"top":0.26319444,"width":0.1984375,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jiminny","depth":4,"bounds":{"left":0.0,"top":0.28194445,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny","depth":5,"bounds":{"left":0.015625,"top":0.29166666,"width":0.015625,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf","depth":4,"bounds":{"left":0.0,"top":0.31041667,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf","depth":5,"bounds":{"left":0.015625,"top":0.3201389,"width":0.1640625,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Service-Desk - Queues - Platform team - Service space - Jira","depth":4,"bounds":{"left":0.0,"top":0.33888888,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Service-Desk - Queues - Platform team - Service space - Jira","depth":5,"bounds":{"left":0.015625,"top":0.34861112,"width":0.12617187,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.3673611,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":5,"bounds":{"left":0.015625,"top":0.37708333,"width":0.18710938,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":4,"bounds":{"left":0.0,"top":0.39583334,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":5,"bounds":{"left":0.015625,"top":0.40555555,"width":0.1515625,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"CloudWatch | us-east-2","depth":4,"bounds":{"left":0.0,"top":0.42430556,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"CloudWatch | us-east-2","depth":5,"bounds":{"left":0.015625,"top":0.4340278,"width":0.0484375,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Meet - Daily - Platform","depth":4,"bounds":{"left":0.0,"top":0.45277777,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Meet - Daily - Platform","depth":5,"bounds":{"left":0.015625,"top":0.4625,"width":0.046484374,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.07890625,"top":0.45902777,"width":0.009375,"height":0.016666668},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Settings","depth":4,"bounds":{"left":0.0,"top":0.48125,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Settings","depth":5,"bounds":{"left":0.015625,"top":0.49097222,"width":0.016796876,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"New Tab","depth":4,"bounds":{"left":0.003125,"top":0.51111114,"width":0.08710937,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.003125,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Close Google Gemini (⌃X)","depth":6,"bounds":{"left":0.01640625,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"bounds":{"left":0.029296875,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"bounds":{"left":0.0421875,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"bounds":{"left":0.05546875,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"AI Chat settings","depth":7,"bounds":{"left":0.2171875,"top":0.047916666,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Close","depth":7,"bounds":{"left":0.23125,"top":0.047916666,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"WORK, Google Account: lukas.kovalik@jiminny.com","depth":12,"bounds":{"left":0.228125,"top":0.090277776,"width":0.015625,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Main menu","depth":12,"bounds":{"left":0.0984375,"top":0.090277776,"width":0.015625,"height":0.027777778},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Chat","depth":12,"bounds":{"left":0.1953125,"top":0.090277776,"width":0.015625,"height":0.027777778},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Open menu for conversation actions.","depth":12,"bounds":{"left":0.2109375,"top":0.090277776,"width":0.015625,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXHeading","text":"Conversation with Gemini","depth":15,"bounds":{"left":0.09335937,"top":0.12847222,"width":0.000390625,"height":0.00069444446},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Conversation with Gemini","depth":16,"bounds":{"left":0.09335937,"top":0.13055556,"width":0.14101562,"height":0.022222223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Copy prompt","depth":21,"bounds":{"left":0.1203125,"top":0.15972222,"width":0.015625,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Edit","depth":21,"bounds":{"left":0.1375,"top":0.15972222,"width":0.015625,"height":0.027777778},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"You said why I can't see speaker data on meemt in firefox. ho wto set it up","depth":21,"bounds":{"left":0.1609375,"top":0.16805555,"width":0.072265625,"height":0.058333334},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"You said","depth":23,"bounds":{"left":0.09335937,"top":0.1701389,"width":0.0234375,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"why I can't see speaker data on meemt in firefox. ho wto set it up","depth":23,"bounds":{"left":0.1609375,"top":0.17083333,"width":0.07070313,"height":0.05347222},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Listen","depth":22,"bounds":{"left":0.22382812,"top":0.25416666,"width":0.015625,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Show more options","depth":20,"bounds":{"left":0.22382812,"top":0.24930556,"width":0.015625,"height":0.027777778},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Show thinking","depth":26,"bounds":{"left":0.11953125,"top":0.25625,"width":0.036328126,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Gemini said","depth":20,"bounds":{"left":0.11679687,"top":0.2923611,"width":0.000390625,"height":0.00069444446},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Gemini said","depth":21,"bounds":{"left":0.11679687,"top":0.29375,"width":0.048046876,"height":0.016666668},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Dealing with missing features right when you need them is incredibly frustrating. Assuming \"meemt\" means Google Meet, the reason you can't see your speaker data comes down to how Firefox interacts with Google's platform compared to Chrome.","depth":24,"bounds":{"left":0.10390625,"top":0.30069444,"width":0.13046876,"height":0.10486111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Since \"speaker data\" can mean a couple of different things in a meeting, here are the two most likely causes for your issue and exactly how to get things working.","depth":24,"bounds":{"left":0.10390625,"top":0.4201389,"width":0.13125,"height":0.06875},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"1. You Need \"Speaker Notes\" for Google Slides","depth":23,"bounds":{"left":0.10390625,"top":0.52152777,"width":0.13242188,"height":0.033333335},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1. You Need \"Speaker Notes\" for Google Slides","depth":24,"bounds":{"left":0.10390625,"top":0.5229167,"width":0.12070312,"height":0.03125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"The Reality:","depth":24,"bounds":{"left":0.10390625,"top":0.5625,"width":0.036328126,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Google Meet has a native feature that lets you see your presentation's speaker notes right inside the video call interface.","depth":24,"bounds":{"left":0.10390625,"top":0.5625,"width":0.13242188,"height":0.050694443},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"However, this relies on a specific \"Present a Tab\" technology built exclusively for Google Chrome. Firefox handles screen sharing differently, so that native integration simply won't load.","depth":24,"bounds":{"left":0.10390625,"top":0.5986111,"width":0.12539062,"height":0.10486111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"View source details for citation from Google Workspace Updates. Opens side panel.","depth":24,"bounds":{"left":0.13710937,"top":0.68958336,"width":0.01015625,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"How to set it up (The Firefox Workaround):","depth":24,"bounds":{"left":0.10390625,"top":0.71805555,"width":0.12851563,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"You can still present and read your notes in Firefox by manually managing your windows.","depth":24,"bounds":{"left":0.10390625,"top":0.7361111,"width":0.12617187,"height":0.03263889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Open your Google Slides presentation in a standard Firefox window.","depth":26,"bounds":{"left":0.11796875,"top":0.7777778,"width":0.115625,"height":0.03263889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Click the dropdown arrow next to the","depth":26,"bounds":{"left":0.11796875,"top":0.8194444,"width":0.10703125,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Slideshow","depth":26,"bounds":{"left":0.11796875,"top":0.8375,"width":0.03125,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"button in the top right corner.","depth":26,"bounds":{"left":0.14921875,"top":0.8375,"width":0.08515625,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Select","depth":26,"bounds":{"left":0.11796875,"top":0.8611111,"width":0.01953125,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Presenter view","depth":26,"bounds":{"left":0.1375,"top":0.8611111,"width":0.0453125,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"to pop your speaker notes out into a separate, smaller window.","depth":26,"bounds":{"left":0.11796875,"top":0.8611111,"width":0.10078125,"height":0.050694443},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"View source details for citation from Skywork. Opens side panel.","depth":26,"bounds":{"left":0.16523437,"top":0.8979167,"width":0.01015625,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Join your Google Meet in a different Firefox window.","depth":26,"bounds":{"left":0.11796875,"top":0.92083335,"width":0.103125,"height":0.03263889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Click","depth":26,"bounds":{"left":0.11796875,"top":0.9625,"width":0.015234375,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Present now","depth":26,"bounds":{"left":0.13320312,"top":0.9625,"width":0.037890624,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"and choose the","depth":26,"bounds":{"left":0.17109375,"top":0.9625,"width":0.047265626,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Window","depth":26,"bounds":{"left":0.11796875,"top":0.98055553,"width":0.02421875,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"option.","depth":26,"bounds":{"left":0.1421875,"top":0.98055553,"width":0.02109375,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Select the window displaying your main slides (do not select your separate speaker notes window).","depth":26,"bounds":{"left":0.11796875,"top":1.0,"width":0.11328125,"height":-0.0041667223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Resize your windows on your monitor so you can comfortably read the notes window while keeping an eye on the Meet window.","depth":26,"bounds":{"left":0.11796875,"top":1.0,"width":0.11835937,"height":-0.06388891},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"2. You Need \"Speaker Labels\" or Transcripts","depth":23,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2. You Need \"Speaker Labels\" or Transcripts","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"The Reality:","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"If you are trying to use a third-party AI note-taker (like Otter.ai, Tactiq, or tl;dv) to capture transcriptions and see who is speaking, Firefox is likely the roadblock. Firefox has strict privacy guardrails that prevent extensions from capturing internal browser audio easily, so most developers only build these tools for Chrome.","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"How to set it up:","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Turn on built-in captions:","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Google Meet has its own live captions that natively identify who is speaking, even in Firefox. Click the","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"CC","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"button at the bottom of your Meet screen to toggle them on.","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Search for a Firefox add-on:","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Check the Mozilla Add-ons store to see if your preferred tool actually has a supported Firefox version (for example, Fellow.ai offers one).","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"View source details for citation from Fellow.ai. Opens side panel.","depth":26,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Switch browsers temporarily:","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"If your specific transcription tool is explicitly Chrome-only, you will unfortunately need to join that specific meeting using a Chromium-based browser like Chrome, Edge, or Brave to capture the data.","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Using Meet's built-in closed captions or the manual Presenter view workaround will get your speaker data back on track without forcing you to completely abandon Firefox.","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Sources","depth":23,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Sources","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextArea","text":"I men in dia (arc) I can see my headphones in both microphone and speakers","depth":20,"bounds":{"left":0.109375,"top":0.8020833,"width":0.125,"height":0.05},"value":"I men in dia (arc) I can see my headphones in both microphone and speakers","help_text":"","role_description":"text entry area","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"I men in dia (arc) I can see my headphones in both microphone and speakers","depth":22,"bounds":{"left":0.109375,"top":0.8034722,"width":0.10625,"height":0.047916666},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open upload file menu","depth":20,"bounds":{"left":0.1046875,"top":0.86527777,"width":0.015625,"height":0.027777778},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Tools","depth":18,"bounds":{"left":0.1234375,"top":0.86527777,"width":0.015625,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Open mode picker","depth":20,"bounds":{"left":0.190625,"top":0.8645833,"width":0.03046875,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pro","depth":23,"bounds":{"left":0.196875,"top":0.87222224,"width":0.00859375,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Send message","depth":19,"bounds":{"left":0.22265625,"top":0.86388886,"width":0.01640625,"height":0.029166667},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Your Jiminny chats aren’t used to improve our models. Gemini is AI and can make mistakes, including about people.","depth":17,"bounds":{"left":0.10039063,"top":0.9097222,"width":0.14296874,"height":0.022222223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Your privacy & Gemini Opens in a new window","depth":17,"bounds":{"left":0.1484375,"top":0.93194443,"width":0.046875,"height":0.011111111},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Your privacy & Gemini","depth":18,"bounds":{"left":0.1484375,"top":0.93194443,"width":0.046875,"height":0.011111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Opens in a new window","depth":19,"bounds":{"left":0.09335937,"top":0.93125,"width":0.05078125,"height":0.011111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Summarize page","depth":7,"bounds":{"left":0.1,"top":0.96319443,"width":0.06289063,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Summarize page","depth":9,"bounds":{"left":0.10664062,"top":0.9673611,"width":0.049609374,"height":0.013888889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Backgrounds and effects","depth":11,"bounds":{"left":0.3921875,"top":0.28958333,"width":0.46289062,"height":0.055555556},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Backgrounds and effects","depth":12,"bounds":{"left":0.4015625,"top":0.30694443,"width":0.10546875,"height":0.021527778},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Turn off visual effects","depth":14,"bounds":{"left":0.675,"top":0.59652776,"width":0.021875,"height":0.03888889},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Back","depth":15,"bounds":{"left":0.7109375,"top":0.34513888,"width":0.015625,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Generate a background","depth":14,"bounds":{"left":0.7265625,"top":0.35,"width":0.08710937,"height":0.018055556},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXComboBox","text":"No scene","depth":15,"bounds":{"left":0.715625,"top":0.38125,"width":0.12539062,"height":0.03888889},"value":"No scene","help_text":"","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"No scene","depth":17,"bounds":{"left":0.740625,"top":0.39375,"width":0.0265625,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextArea","text":"Acropolic propylaea","depth":16,"bounds":{"left":0.715625,"top":0.44236112,"width":0.12539062,"height":0.06666667},"value":"Acropolic propylaea","help_text":"","placeholder":"Jungle patio at sunset","role_description":"text entry area","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Create other samples","depth":16,"bounds":{"left":0.7410156,"top":0.53402776,"width":0.07460938,"height":0.025},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Create other samples","depth":18,"bounds":{"left":0.75039065,"top":0.5402778,"width":0.055859376,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"You can generate more results or change your description to get different results","depth":16,"bounds":{"left":0.72734374,"top":0.5715278,"width":0.10195313,"height":0.022222223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Learn more about generating backgrounds","depth":16,"bounds":{"left":0.7308594,"top":0.59375,"width":0.09492187,"height":0.011111111},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Learn more about generating backgrounds","depth":17,"bounds":{"left":0.7308594,"top":0.59375,"width":0.09492187,"height":0.011111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Use this background","depth":16,"bounds":{"left":0.72148436,"top":0.61319447,"width":0.1140625,"height":0.12638889},"role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":true,"is_selected":false},{"role":"AXButton","text":"Like","depth":17,"bounds":{"left":0.809375,"top":0.71458334,"width":0.0109375,"height":0.019444445},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Dislike","depth":17,"bounds":{"left":0.821875,"top":0.71458334,"width":0.0109375,"height":0.019444445},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Report a legal issue","depth":16,"bounds":{"left":0.72148436,"top":0.75069445,"width":0.04296875,"height":0.011111111},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Report a legal issue","depth":17,"bounds":{"left":0.72148436,"top":0.75069445,"width":0.04296875,"height":0.011111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close","depth":11,"bounds":{"left":0.83320314,"top":0.30069444,"width":0.01875,"height":0.033333335},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Generated background has been applied","depth":8,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Background is now replaced","depth":8,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
-443061304843876557
|
8729445723311160398
|
idle
|
accessibility
|
NULL
|
JY-20543 add AJ reports User pilot tracking by Lak JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
Console Home | Console Home | us-east-2
Console Home | Console Home | us-east-2
SecurityGroup | EC2 | us-east-2
SecurityGroup | EC2 | us-east-2
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app
SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Jiminny
Jiminny
Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf
Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf
Service-Desk - Queues - Platform team - Service space - Jira
Service-Desk - Queues - Platform team - Service space - Jira
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
CloudWatch | us-east-2
CloudWatch | us-east-2
Meet - Daily - Platform
Meet - Daily - Platform
Close tab
Settings
Settings
New Tab
Customize sidebar
Close Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
AI Chat settings
Close
WORK, Google Account: [EMAIL]
Main menu
New Chat
Open menu for conversation actions.
Conversation with Gemini
Conversation with Gemini
Copy prompt
Edit
You said why I can't see speaker data on meemt in firefox. ho wto set it up
You said
why I can't see speaker data on meemt in firefox. ho wto set it up
Listen
Show more options
Show thinking
Gemini said
Gemini said
Dealing with missing features right when you need them is incredibly frustrating. Assuming "meemt" means Google Meet, the reason you can't see your speaker data comes down to how Firefox interacts with Google's platform compared to Chrome.
Since "speaker data" can mean a couple of different things in a meeting, here are the two most likely causes for your issue and exactly how to get things working.
1. You Need "Speaker Notes" for Google Slides
1. You Need "Speaker Notes" for Google Slides
The Reality:
Google Meet has a native feature that lets you see your presentation's speaker notes right inside the video call interface.
However, this relies on a specific "Present a Tab" technology built exclusively for Google Chrome. Firefox handles screen sharing differently, so that native integration simply won't load.
View source details for citation from Google Workspace Updates. Opens side panel.
How to set it up (The Firefox Workaround):
You can still present and read your notes in Firefox by manually managing your windows.
Open your Google Slides presentation in a standard Firefox window.
Click the dropdown arrow next to the
Slideshow
button in the top right corner.
Select
Presenter view
to pop your speaker notes out into a separate, smaller window.
View source details for citation from Skywork. Opens side panel.
Join your Google Meet in a different Firefox window.
Click
Present now
and choose the
Window
option.
Select the window displaying your main slides (do not select your separate speaker notes window).
Resize your windows on your monitor so you can comfortably read the notes window while keeping an eye on the Meet window.
2. You Need "Speaker Labels" or Transcripts
2. You Need "Speaker Labels" or Transcripts
The Reality:
If you are trying to use a third-party AI note-taker (like Otter.ai, Tactiq, or tl;dv) to capture transcriptions and see who is speaking, Firefox is likely the roadblock. Firefox has strict privacy guardrails that prevent extensions from capturing internal browser audio easily, so most developers only build these tools for Chrome.
How to set it up:
Turn on built-in captions:
Google Meet has its own live captions that natively identify who is speaking, even in Firefox. Click the
CC
button at the bottom of your Meet screen to toggle them on.
Search for a Firefox add-on:
Check the Mozilla Add-ons store to see if your preferred tool actually has a supported Firefox version (for example, Fellow.ai offers one).
View source details for citation from Fellow.ai. Opens side panel.
Switch browsers temporarily:
If your specific transcription tool is explicitly Chrome-only, you will unfortunately need to join that specific meeting using a Chromium-based browser like Chrome, Edge, or Brave to capture the data.
Using Meet's built-in closed captions or the manual Presenter view workaround will get your speaker data back on track without forcing you to completely abandon Firefox.
Sources
Sources
I men in dia (arc) I can see my headphones in both microphone and speakers
I men in dia (arc) I can see my headphones in both microphone and speakers
Open upload file menu
Tools
Open mode picker
Pro
Send message
Your Jiminny chats aren’t used to improve our models. Gemini is AI and can make mistakes, including about people.
Your privacy & Gemini Opens in a new window
Your privacy & Gemini
Opens in a new window
Summarize page
Summarize page
Backgrounds and effects
Backgrounds and effects
Turn off visual effects
Back
Generate a background
No scene
No scene
Acropolic propylaea
Create other samples
Create other samples
You can generate more results or change your description to get different results
Learn more about generating backgrounds
Learn more about generating backgrounds
Use this background
Like
Dislike
Report a legal issue
Report a legal issue
Close
Generated background has been applied
Background is now replaced...
|
10077
|
|
10080
|
NULL
|
0
|
2026-04-14T08:11:45.311918+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776154305311_m1.jpg...
|
Firefox
|
Meet - Daily - Platform — Work
|
True
|
meet.google.com/mie-gawc-dsi
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
JY-20543 add AJ reports User pilot tracking by Lak JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
Console Home | Console Home | us-east-2
Console Home | Console Home | us-east-2
SecurityGroup | EC2 | us-east-2
SecurityGroup | EC2 | us-east-2
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app
SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Jiminny
Jiminny
Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf
Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf
Service-Desk - Queues - Platform team - Service space - Jira
Service-Desk - Queues - Platform team - Service space - Jira
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
CloudWatch | us-east-2
CloudWatch | us-east-2
Meet - Daily - Platform
Meet - Daily - Platform
Close tab
Settings
Settings
New Tab
Customize sidebar
Close Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
AI Chat settings
Close
WORK, Google Account: [EMAIL]
Main menu
New Chat
Open menu for conversation actions.
Conversation with Gemini
Conversation with Gemini
Copy prompt
Edit
You said why I can't see speaker data on meemt in firefox. ho wto set it up
You said
why I can't see speaker data on meemt in firefox. ho wto set it up
Listen
Show more options
Show thinking
Gemini said
Gemini said
Dealing with missing features right when you need them is incredibly frustrating. Assuming "meemt" means Google Meet, the reason you can't see your speaker data comes down to how Firefox interacts with Google's platform compared to Chrome.
Since "speaker data" can mean a couple of different things in a meeting, here are the two most likely causes for your issue and exactly how to get things working.
1. You Need "Speaker Notes" for Google Slides
1. You Need "Speaker Notes" for Google Slides
The Reality:
Google Meet has a native feature that lets you see your presentation's speaker notes right inside the video call interface.
However, this relies on a specific "Present a Tab" technology built exclusively for Google Chrome. Firefox handles screen sharing differently, so that native integration simply won't load.
View source details for citation from Google Workspace Updates. Opens side panel.
How to set it up (The Firefox Workaround):
You can still present and read your notes in Firefox by manually managing your windows.
Open your Google Slides presentation in a standard Firefox window.
Click the dropdown arrow next to the
Slideshow
button in the top right corner.
Select
Presenter view
to pop your speaker notes out into a separate, smaller window.
View source details for citation from Skywork. Opens side panel.
Join your Google Meet in a different Firefox window.
Click
Present now
and choose the
Window
option.
Select the window displaying your main slides (do not select your separate speaker notes window).
Resize your windows on your monitor so you can comfortably read the notes window while keeping an eye on the Meet window.
2. You Need "Speaker Labels" or Transcripts
2. You Need "Speaker Labels" or Transcripts
The Reality:
If you are trying to use a third-party AI note-taker (like Otter.ai, Tactiq, or tl;dv) to capture transcriptions and see who is speaking, Firefox is likely the roadblock. Firefox has strict privacy guardrails that prevent extensions from capturing internal browser audio easily, so most developers only build these tools for Chrome.
How to set it up:
Turn on built-in captions:
Google Meet has its own live captions that natively identify who is speaking, even in Firefox. Click the
CC
button at the bottom of your Meet screen to toggle them on.
Search for a Firefox add-on:
Check the Mozilla Add-ons store to see if your preferred tool actually has a supported Firefox version (for example, Fellow.ai offers one).
View source details for citation from Fellow.ai. Opens side panel.
Switch browsers temporarily:
If your specific transcription tool is explicitly Chrome-only, you will unfortunately need to join that specific meeting using a Chromium-based browser like Chrome, Edge, or Brave to capture the data.
Using Meet's built-in closed captions or the manual Presenter view workaround will get your speaker data back on track without forcing you to completely abandon Firefox.
Sources
Sources
I men in dia (arc) I can see my headphones in both microphone and speakers
I men in dia (arc) I can see my headphones in both microphone and speakers
Open upload file menu
Tools
Open mode picker
Pro
Send message
Your Jiminny chats aren’t used to improve our models. Gemini is AI and can make mistakes, including about people.
Your privacy & Gemini Opens in a new window
Your privacy & Gemini
Opens in a new window
Summarize page
Summarize page
Backgrounds and effects
Backgrounds and effects
Turn off visual effects
Back
Generate a background
No scene
No scene
Acropolic propylaea
Create other samples
Create other samples
You can generate more results or change your description to get different results
Learn more about generating backgrounds
Learn more about generating backgrounds
Use this background
Like
Dislike
Report a legal issue
Report a legal issue
Close
Generated background has been applied
Background is now replaced...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Console Home | Console Home | us-east-2","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Console Home | Console Home | us-east-2","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"SecurityGroup | EC2 | us-east-2","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"SecurityGroup | EC2 | us-east-2","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jiminny","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Service-Desk - Queues - Platform team - Service space - Jira","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Service-Desk - Queues - Platform team - Service space - Jira","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"CloudWatch | us-east-2","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"CloudWatch | us-east-2","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Meet - Daily - Platform","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Meet - Daily - Platform","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Settings","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Settings","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"New Tab","depth":4,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Close Google Gemini (⌃X)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"AI Chat settings","depth":7,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Close","depth":7,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"WORK, Google Account: lukas.kovalik@jiminny.com","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Main menu","depth":12,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Chat","depth":12,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Open menu for conversation actions.","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXHeading","text":"Conversation with Gemini","depth":15,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Conversation with Gemini","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Copy prompt","depth":21,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Edit","depth":21,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"You said why I can't see speaker data on meemt in firefox. ho wto set it up","depth":21,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"You said","depth":23,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"why I can't see speaker data on meemt in firefox. ho wto set it up","depth":23,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Listen","depth":22,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Show more options","depth":20,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Show thinking","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Gemini said","depth":20,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Gemini said","depth":21,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Dealing with missing features right when you need them is incredibly frustrating. Assuming \"meemt\" means Google Meet, the reason you can't see your speaker data comes down to how Firefox interacts with Google's platform compared to Chrome.","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Since \"speaker data\" can mean a couple of different things in a meeting, here are the two most likely causes for your issue and exactly how to get things working.","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"1. You Need \"Speaker Notes\" for Google Slides","depth":23,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1. You Need \"Speaker Notes\" for Google Slides","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"The Reality:","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Google Meet has a native feature that lets you see your presentation's speaker notes right inside the video call interface.","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"However, this relies on a specific \"Present a Tab\" technology built exclusively for Google Chrome. Firefox handles screen sharing differently, so that native integration simply won't load.","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"View source details for citation from Google Workspace Updates. Opens side panel.","depth":24,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"How to set it up (The Firefox Workaround):","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"You can still present and read your notes in Firefox by manually managing your windows.","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Open your Google Slides presentation in a standard Firefox window.","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Click the dropdown arrow next to the","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Slideshow","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"button in the top right corner.","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Select","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Presenter view","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"to pop your speaker notes out into a separate, smaller window.","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"View source details for citation from Skywork. Opens side panel.","depth":26,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Join your Google Meet in a different Firefox window.","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Click","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Present now","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"and choose the","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Window","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"option.","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Select the window displaying your main slides (do not select your separate speaker notes window).","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Resize your windows on your monitor so you can comfortably read the notes window while keeping an eye on the Meet window.","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"2. You Need \"Speaker Labels\" or Transcripts","depth":23,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2. You Need \"Speaker Labels\" or Transcripts","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"The Reality:","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"If you are trying to use a third-party AI note-taker (like Otter.ai, Tactiq, or tl;dv) to capture transcriptions and see who is speaking, Firefox is likely the roadblock. Firefox has strict privacy guardrails that prevent extensions from capturing internal browser audio easily, so most developers only build these tools for Chrome.","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"How to set it up:","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Turn on built-in captions:","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Google Meet has its own live captions that natively identify who is speaking, even in Firefox. Click the","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"CC","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"button at the bottom of your Meet screen to toggle them on.","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Search for a Firefox add-on:","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Check the Mozilla Add-ons store to see if your preferred tool actually has a supported Firefox version (for example, Fellow.ai offers one).","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"View source details for citation from Fellow.ai. Opens side panel.","depth":26,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Switch browsers temporarily:","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"If your specific transcription tool is explicitly Chrome-only, you will unfortunately need to join that specific meeting using a Chromium-based browser like Chrome, Edge, or Brave to capture the data.","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Using Meet's built-in closed captions or the manual Presenter view workaround will get your speaker data back on track without forcing you to completely abandon Firefox.","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Sources","depth":23,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Sources","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextArea","text":"I men in dia (arc) I can see my headphones in both microphone and speakers","depth":20,"value":"I men in dia (arc) I can see my headphones in both microphone and speakers","help_text":"","role_description":"text entry area","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"I men in dia (arc) I can see my headphones in both microphone and speakers","depth":22,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open upload file menu","depth":20,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Tools","depth":18,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Open mode picker","depth":20,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pro","depth":23,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Send message","depth":19,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Your Jiminny chats aren’t used to improve our models. Gemini is AI and can make mistakes, including about people.","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Your privacy & Gemini Opens in a new window","depth":17,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Your privacy & Gemini","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Opens in a new window","depth":19,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Summarize page","depth":7,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Summarize page","depth":9,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Backgrounds and effects","depth":11,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Backgrounds and effects","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Turn off visual effects","depth":14,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Back","depth":15,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Generate a background","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXComboBox","text":"No scene","depth":15,"value":"No scene","help_text":"","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"No scene","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextArea","text":"Acropolic propylaea","depth":16,"value":"Acropolic propylaea","help_text":"","placeholder":"Jungle patio at sunset","role_description":"text entry area","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Create other samples","depth":16,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Create other samples","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"You can generate more results or change your description to get different results","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Learn more about generating backgrounds","depth":16,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Learn more about generating backgrounds","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Use this background","depth":16,"role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":true,"is_selected":false},{"role":"AXButton","text":"Like","depth":17,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Dislike","depth":17,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Report a legal issue","depth":16,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Report a legal issue","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close","depth":11,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Generated background has been applied","depth":8,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Background is now replaced","depth":8,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
-443061304843876557
|
8729445723311160398
|
idle
|
accessibility
|
NULL
|
JY-20543 add AJ reports User pilot tracking by Lak JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
Console Home | Console Home | us-east-2
Console Home | Console Home | us-east-2
SecurityGroup | EC2 | us-east-2
SecurityGroup | EC2 | us-east-2
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app
SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Jiminny
Jiminny
Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf
Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf
Service-Desk - Queues - Platform team - Service space - Jira
Service-Desk - Queues - Platform team - Service space - Jira
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
CloudWatch | us-east-2
CloudWatch | us-east-2
Meet - Daily - Platform
Meet - Daily - Platform
Close tab
Settings
Settings
New Tab
Customize sidebar
Close Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
AI Chat settings
Close
WORK, Google Account: [EMAIL]
Main menu
New Chat
Open menu for conversation actions.
Conversation with Gemini
Conversation with Gemini
Copy prompt
Edit
You said why I can't see speaker data on meemt in firefox. ho wto set it up
You said
why I can't see speaker data on meemt in firefox. ho wto set it up
Listen
Show more options
Show thinking
Gemini said
Gemini said
Dealing with missing features right when you need them is incredibly frustrating. Assuming "meemt" means Google Meet, the reason you can't see your speaker data comes down to how Firefox interacts with Google's platform compared to Chrome.
Since "speaker data" can mean a couple of different things in a meeting, here are the two most likely causes for your issue and exactly how to get things working.
1. You Need "Speaker Notes" for Google Slides
1. You Need "Speaker Notes" for Google Slides
The Reality:
Google Meet has a native feature that lets you see your presentation's speaker notes right inside the video call interface.
However, this relies on a specific "Present a Tab" technology built exclusively for Google Chrome. Firefox handles screen sharing differently, so that native integration simply won't load.
View source details for citation from Google Workspace Updates. Opens side panel.
How to set it up (The Firefox Workaround):
You can still present and read your notes in Firefox by manually managing your windows.
Open your Google Slides presentation in a standard Firefox window.
Click the dropdown arrow next to the
Slideshow
button in the top right corner.
Select
Presenter view
to pop your speaker notes out into a separate, smaller window.
View source details for citation from Skywork. Opens side panel.
Join your Google Meet in a different Firefox window.
Click
Present now
and choose the
Window
option.
Select the window displaying your main slides (do not select your separate speaker notes window).
Resize your windows on your monitor so you can comfortably read the notes window while keeping an eye on the Meet window.
2. You Need "Speaker Labels" or Transcripts
2. You Need "Speaker Labels" or Transcripts
The Reality:
If you are trying to use a third-party AI note-taker (like Otter.ai, Tactiq, or tl;dv) to capture transcriptions and see who is speaking, Firefox is likely the roadblock. Firefox has strict privacy guardrails that prevent extensions from capturing internal browser audio easily, so most developers only build these tools for Chrome.
How to set it up:
Turn on built-in captions:
Google Meet has its own live captions that natively identify who is speaking, even in Firefox. Click the
CC
button at the bottom of your Meet screen to toggle them on.
Search for a Firefox add-on:
Check the Mozilla Add-ons store to see if your preferred tool actually has a supported Firefox version (for example, Fellow.ai offers one).
View source details for citation from Fellow.ai. Opens side panel.
Switch browsers temporarily:
If your specific transcription tool is explicitly Chrome-only, you will unfortunately need to join that specific meeting using a Chromium-based browser like Chrome, Edge, or Brave to capture the data.
Using Meet's built-in closed captions or the manual Presenter view workaround will get your speaker data back on track without forcing you to completely abandon Firefox.
Sources
Sources
I men in dia (arc) I can see my headphones in both microphone and speakers
I men in dia (arc) I can see my headphones in both microphone and speakers
Open upload file menu
Tools
Open mode picker
Pro
Send message
Your Jiminny chats aren’t used to improve our models. Gemini is AI and can make mistakes, including about people.
Your privacy & Gemini Opens in a new window
Your privacy & Gemini
Opens in a new window
Summarize page
Summarize page
Backgrounds and effects
Backgrounds and effects
Turn off visual effects
Back
Generate a background
No scene
No scene
Acropolic propylaea
Create other samples
Create other samples
You can generate more results or change your description to get different results
Learn more about generating backgrounds
Learn more about generating backgrounds
Use this background
Like
Dislike
Report a legal issue
Report a legal issue
Close
Generated background has been applied
Background is now replaced...
|
10078
|
|
10081
|
NULL
|
0
|
2026-04-14T08:11:50.711380+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776154310711_m2.jpg...
|
Firefox
|
Meet - Daily - Platform — Work
|
True
|
meet.google.com/mie-gawc-dsi
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
JY-20543 add AJ reports User pilot tracking by Lak JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
Console Home | Console Home | us-east-2
Console Home | Console Home | us-east-2
SecurityGroup | EC2 | us-east-2
SecurityGroup | EC2 | us-east-2
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app
SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Jiminny
Jiminny
Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf
Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf
Service-Desk - Queues - Platform team - Service space - Jira
Service-Desk - Queues - Platform team - Service space - Jira
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
CloudWatch | us-east-2
CloudWatch | us-east-2
Meet - Daily - Platform
Meet - Daily - Platform
Close tab
Settings
Settings
New Tab
Customize sidebar
Close Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
AI Chat settings
Close
WORK, Google Account: [EMAIL]
Main menu
New Chat
Open menu for conversation actions.
Conversation with Gemini
Conversation with Gemini
Copy prompt
Edit
You said why I can't see speaker data on meemt in firefox. ho wto set it up
You said
why I can't see speaker data on meemt in firefox. ho wto set it up
Listen
Show more options
Show thinking
Gemini said
Gemini said
Dealing with missing features right when you need them is incredibly frustrating. Assuming "meemt" means Google Meet, the reason you can't see your speaker data comes down to how Firefox interacts with Google's platform compared to Chrome.
Since "speaker data" can mean a couple of different things in a meeting, here are the two most likely causes for your issue and exactly how to get things working.
1. You Need "Speaker Notes" for Google Slides
1. You Need "Speaker Notes" for Google Slides
The Reality:
Google Meet has a native feature that lets you see your presentation's speaker notes right inside the video call interface.
However, this relies on a specific "Present a Tab" technology built exclusively for Google Chrome. Firefox handles screen sharing differently, so that native integration simply won't load.
View source details for citation from Google Workspace Updates. Opens side panel.
How to set it up (The Firefox Workaround):
You can still present and read your notes in Firefox by manually managing your windows.
Open your Google Slides presentation in a standard Firefox window.
Click the dropdown arrow next to the
Slideshow
button in the top right corner.
Select
Presenter view
to pop your speaker notes out into a separate, smaller window.
View source details for citation from Skywork. Opens side panel.
Join your Google Meet in a different Firefox window.
Click
Present now
and choose the
Window
option.
Select the window displaying your main slides (do not select your separate speaker notes window).
Resize your windows on your monitor so you can comfortably read the notes window while keeping an eye on the Meet window.
2. You Need "Speaker Labels" or Transcripts
2. You Need "Speaker Labels" or Transcripts
The Reality:
If you are trying to use a third-party AI note-taker (like Otter.ai, Tactiq, or tl;dv) to capture transcriptions and see who is speaking, Firefox is likely the roadblock. Firefox has strict privacy guardrails that prevent extensions from capturing internal browser audio easily, so most developers only build these tools for Chrome.
How to set it up:
Turn on built-in captions:
Google Meet has its own live captions that natively identify who is speaking, even in Firefox. Click the
CC
button at the bottom of your Meet screen to toggle them on.
Search for a Firefox add-on:
Check the Mozilla Add-ons store to see if your preferred tool actually has a supported Firefox version (for example, Fellow.ai offers one).
View source details for citation from Fellow.ai. Opens side panel.
Switch browsers temporarily:
If your specific transcription tool is explicitly Chrome-only, you will unfortunately need to join that specific meeting using a Chromium-based browser like Chrome, Edge, or Brave to capture the data.
Using Meet's built-in closed captions or the manual Presenter view workaround will get your speaker data back on track without forcing you to completely abandon Firefox.
Sources
Sources
I men in dia (arc) I can see my headphones in both microphone and speakers
I men in dia (arc) I can see my headphones in both microphone and speakers
Open upload file menu
Tools
Open mode picker
Pro
Send message
Your Jiminny chats aren’t used to improve our models. Gemini is AI and can make mistakes, including about people.
Your privacy & Gemini Opens in a new window
Your privacy & Gemini
Opens in a new window
Summarize page
Summarize page
Backgrounds and effects
Backgrounds and effects
Turn off visual effects
Back
Generate a background
No scene
No scene
Acropolic propylaea
Create other samples
Create other samples
You can generate more results or change your description to get different results
Learn more about generating backgrounds
Learn more about generating backgrounds
Use this background
Like
Dislike
Report a legal issue
Report a legal issue
Close
Generated background has been applied
Background is now replaced...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":4,"bounds":{"left":0.00234375,"top":0.045138888,"width":0.0890625,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira","depth":4,"bounds":{"left":0.0,"top":0.08263889,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira","depth":5,"bounds":{"left":0.015625,"top":0.09236111,"width":0.11796875,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":4,"bounds":{"left":0.0,"top":0.11111111,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":5,"bounds":{"left":0.015625,"top":0.12083333,"width":0.1515625,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Console Home | Console Home | us-east-2","depth":4,"bounds":{"left":0.0,"top":0.13958333,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Console Home | Console Home | us-east-2","depth":5,"bounds":{"left":0.015625,"top":0.14930555,"width":0.08671875,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"SecurityGroup | EC2 | us-east-2","depth":4,"bounds":{"left":0.0,"top":0.16805555,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"SecurityGroup | EC2 | us-east-2","depth":5,"bounds":{"left":0.015625,"top":0.17777778,"width":0.06484375,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.19652778,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":5,"bounds":{"left":0.015625,"top":0.20625,"width":0.18710938,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.225,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app","depth":5,"bounds":{"left":0.015625,"top":0.23472223,"width":0.23476562,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet","depth":4,"bounds":{"left":0.0,"top":0.2534722,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet","depth":5,"bounds":{"left":0.015625,"top":0.26319444,"width":0.1984375,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jiminny","depth":4,"bounds":{"left":0.0,"top":0.28194445,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny","depth":5,"bounds":{"left":0.015625,"top":0.29166666,"width":0.015625,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf","depth":4,"bounds":{"left":0.0,"top":0.31041667,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf","depth":5,"bounds":{"left":0.015625,"top":0.3201389,"width":0.1640625,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Service-Desk - Queues - Platform team - Service space - Jira","depth":4,"bounds":{"left":0.0,"top":0.33888888,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Service-Desk - Queues - Platform team - Service space - Jira","depth":5,"bounds":{"left":0.015625,"top":0.34861112,"width":0.12617187,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.3673611,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":5,"bounds":{"left":0.015625,"top":0.37708333,"width":0.18710938,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":4,"bounds":{"left":0.0,"top":0.39583334,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":5,"bounds":{"left":0.015625,"top":0.40555555,"width":0.1515625,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"CloudWatch | us-east-2","depth":4,"bounds":{"left":0.0,"top":0.42430556,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"CloudWatch | us-east-2","depth":5,"bounds":{"left":0.015625,"top":0.4340278,"width":0.0484375,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Meet - Daily - Platform","depth":4,"bounds":{"left":0.0,"top":0.45277777,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Meet - Daily - Platform","depth":5,"bounds":{"left":0.015625,"top":0.4625,"width":0.046484374,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.07890625,"top":0.45902777,"width":0.009375,"height":0.016666668},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Settings","depth":4,"bounds":{"left":0.0,"top":0.48125,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Settings","depth":5,"bounds":{"left":0.015625,"top":0.49097222,"width":0.016796876,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"New Tab","depth":4,"bounds":{"left":0.003125,"top":0.51111114,"width":0.08710937,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.003125,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Close Google Gemini (⌃X)","depth":6,"bounds":{"left":0.01640625,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"bounds":{"left":0.029296875,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"bounds":{"left":0.0421875,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"bounds":{"left":0.05546875,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"AI Chat settings","depth":7,"bounds":{"left":0.2171875,"top":0.047916666,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Close","depth":7,"bounds":{"left":0.23125,"top":0.047916666,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"WORK, Google Account: lukas.kovalik@jiminny.com","depth":12,"bounds":{"left":0.228125,"top":0.090277776,"width":0.015625,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Main menu","depth":12,"bounds":{"left":0.0984375,"top":0.090277776,"width":0.015625,"height":0.027777778},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Chat","depth":12,"bounds":{"left":0.1953125,"top":0.090277776,"width":0.015625,"height":0.027777778},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Open menu for conversation actions.","depth":12,"bounds":{"left":0.2109375,"top":0.090277776,"width":0.015625,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXHeading","text":"Conversation with Gemini","depth":15,"bounds":{"left":0.09335937,"top":0.12847222,"width":0.000390625,"height":0.00069444446},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Conversation with Gemini","depth":16,"bounds":{"left":0.09335937,"top":0.13055556,"width":0.14101562,"height":0.022222223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Copy prompt","depth":21,"bounds":{"left":0.1203125,"top":0.15972222,"width":0.015625,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Edit","depth":21,"bounds":{"left":0.1375,"top":0.15972222,"width":0.015625,"height":0.027777778},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"You said why I can't see speaker data on meemt in firefox. ho wto set it up","depth":21,"bounds":{"left":0.1609375,"top":0.16805555,"width":0.072265625,"height":0.058333334},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"You said","depth":23,"bounds":{"left":0.09335937,"top":0.1701389,"width":0.0234375,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"why I can't see speaker data on meemt in firefox. ho wto set it up","depth":23,"bounds":{"left":0.1609375,"top":0.17083333,"width":0.07070313,"height":0.05347222},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Listen","depth":22,"bounds":{"left":0.22382812,"top":0.25416666,"width":0.015625,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Show more options","depth":20,"bounds":{"left":0.22382812,"top":0.24930556,"width":0.015625,"height":0.027777778},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Show thinking","depth":26,"bounds":{"left":0.11953125,"top":0.25625,"width":0.036328126,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Gemini said","depth":20,"bounds":{"left":0.11679687,"top":0.2923611,"width":0.000390625,"height":0.00069444446},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Gemini said","depth":21,"bounds":{"left":0.11679687,"top":0.29375,"width":0.048046876,"height":0.016666668},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Dealing with missing features right when you need them is incredibly frustrating. Assuming \"meemt\" means Google Meet, the reason you can't see your speaker data comes down to how Firefox interacts with Google's platform compared to Chrome.","depth":24,"bounds":{"left":0.10390625,"top":0.30069444,"width":0.13046876,"height":0.10486111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Since \"speaker data\" can mean a couple of different things in a meeting, here are the two most likely causes for your issue and exactly how to get things working.","depth":24,"bounds":{"left":0.10390625,"top":0.4201389,"width":0.13125,"height":0.06875},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"1. You Need \"Speaker Notes\" for Google Slides","depth":23,"bounds":{"left":0.10390625,"top":0.52152777,"width":0.13242188,"height":0.033333335},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1. You Need \"Speaker Notes\" for Google Slides","depth":24,"bounds":{"left":0.10390625,"top":0.5229167,"width":0.12070312,"height":0.03125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"The Reality:","depth":24,"bounds":{"left":0.10390625,"top":0.5625,"width":0.036328126,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Google Meet has a native feature that lets you see your presentation's speaker notes right inside the video call interface.","depth":24,"bounds":{"left":0.10390625,"top":0.5625,"width":0.13242188,"height":0.050694443},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"However, this relies on a specific \"Present a Tab\" technology built exclusively for Google Chrome. Firefox handles screen sharing differently, so that native integration simply won't load.","depth":24,"bounds":{"left":0.10390625,"top":0.5986111,"width":0.12539062,"height":0.10486111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"View source details for citation from Google Workspace Updates. Opens side panel.","depth":24,"bounds":{"left":0.13710937,"top":0.68958336,"width":0.01015625,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"How to set it up (The Firefox Workaround):","depth":24,"bounds":{"left":0.10390625,"top":0.71805555,"width":0.12851563,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"You can still present and read your notes in Firefox by manually managing your windows.","depth":24,"bounds":{"left":0.10390625,"top":0.7361111,"width":0.12617187,"height":0.03263889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Open your Google Slides presentation in a standard Firefox window.","depth":26,"bounds":{"left":0.11796875,"top":0.7777778,"width":0.115625,"height":0.03263889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Click the dropdown arrow next to the","depth":26,"bounds":{"left":0.11796875,"top":0.8194444,"width":0.10703125,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Slideshow","depth":26,"bounds":{"left":0.11796875,"top":0.8375,"width":0.03125,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"button in the top right corner.","depth":26,"bounds":{"left":0.14921875,"top":0.8375,"width":0.08515625,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Select","depth":26,"bounds":{"left":0.11796875,"top":0.8611111,"width":0.01953125,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Presenter view","depth":26,"bounds":{"left":0.1375,"top":0.8611111,"width":0.0453125,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"to pop your speaker notes out into a separate, smaller window.","depth":26,"bounds":{"left":0.11796875,"top":0.8611111,"width":0.10078125,"height":0.050694443},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"View source details for citation from Skywork. Opens side panel.","depth":26,"bounds":{"left":0.16523437,"top":0.8979167,"width":0.01015625,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Join your Google Meet in a different Firefox window.","depth":26,"bounds":{"left":0.11796875,"top":0.92083335,"width":0.103125,"height":0.03263889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Click","depth":26,"bounds":{"left":0.11796875,"top":0.9625,"width":0.015234375,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Present now","depth":26,"bounds":{"left":0.13320312,"top":0.9625,"width":0.037890624,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"and choose the","depth":26,"bounds":{"left":0.17109375,"top":0.9625,"width":0.047265626,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Window","depth":26,"bounds":{"left":0.11796875,"top":0.98055553,"width":0.02421875,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"option.","depth":26,"bounds":{"left":0.1421875,"top":0.98055553,"width":0.02109375,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Select the window displaying your main slides (do not select your separate speaker notes window).","depth":26,"bounds":{"left":0.11796875,"top":1.0,"width":0.11328125,"height":-0.0041667223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Resize your windows on your monitor so you can comfortably read the notes window while keeping an eye on the Meet window.","depth":26,"bounds":{"left":0.11796875,"top":1.0,"width":0.11835937,"height":-0.06388891},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"2. You Need \"Speaker Labels\" or Transcripts","depth":23,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2. You Need \"Speaker Labels\" or Transcripts","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"The Reality:","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"If you are trying to use a third-party AI note-taker (like Otter.ai, Tactiq, or tl;dv) to capture transcriptions and see who is speaking, Firefox is likely the roadblock. Firefox has strict privacy guardrails that prevent extensions from capturing internal browser audio easily, so most developers only build these tools for Chrome.","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"How to set it up:","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Turn on built-in captions:","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Google Meet has its own live captions that natively identify who is speaking, even in Firefox. Click the","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"CC","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"button at the bottom of your Meet screen to toggle them on.","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Search for a Firefox add-on:","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Check the Mozilla Add-ons store to see if your preferred tool actually has a supported Firefox version (for example, Fellow.ai offers one).","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"View source details for citation from Fellow.ai. Opens side panel.","depth":26,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Switch browsers temporarily:","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"If your specific transcription tool is explicitly Chrome-only, you will unfortunately need to join that specific meeting using a Chromium-based browser like Chrome, Edge, or Brave to capture the data.","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Using Meet's built-in closed captions or the manual Presenter view workaround will get your speaker data back on track without forcing you to completely abandon Firefox.","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Sources","depth":23,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Sources","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextArea","text":"I men in dia (arc) I can see my headphones in both microphone and speakers","depth":20,"bounds":{"left":0.109375,"top":0.8020833,"width":0.125,"height":0.05},"value":"I men in dia (arc) I can see my headphones in both microphone and speakers","help_text":"","role_description":"text entry area","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"I men in dia (arc) I can see my headphones in both microphone and speakers","depth":22,"bounds":{"left":0.109375,"top":0.8034722,"width":0.10625,"height":0.047916666},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open upload file menu","depth":20,"bounds":{"left":0.1046875,"top":0.86527777,"width":0.015625,"height":0.027777778},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Tools","depth":18,"bounds":{"left":0.1234375,"top":0.86527777,"width":0.015625,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Open mode picker","depth":20,"bounds":{"left":0.190625,"top":0.8645833,"width":0.03046875,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pro","depth":23,"bounds":{"left":0.196875,"top":0.87222224,"width":0.00859375,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Send message","depth":19,"bounds":{"left":0.22265625,"top":0.86388886,"width":0.01640625,"height":0.029166667},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Your Jiminny chats aren’t used to improve our models. Gemini is AI and can make mistakes, including about people.","depth":17,"bounds":{"left":0.10039063,"top":0.9097222,"width":0.14296874,"height":0.022222223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Your privacy & Gemini Opens in a new window","depth":17,"bounds":{"left":0.1484375,"top":0.93194443,"width":0.046875,"height":0.011111111},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Your privacy & Gemini","depth":18,"bounds":{"left":0.1484375,"top":0.93194443,"width":0.046875,"height":0.011111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Opens in a new window","depth":19,"bounds":{"left":0.09335937,"top":0.93125,"width":0.05078125,"height":0.011111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Summarize page","depth":7,"bounds":{"left":0.1,"top":0.96319443,"width":0.06289063,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Summarize page","depth":9,"bounds":{"left":0.10664062,"top":0.9673611,"width":0.049609374,"height":0.013888889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Backgrounds and effects","depth":11,"bounds":{"left":0.3921875,"top":0.28958333,"width":0.46289062,"height":0.055555556},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Backgrounds and effects","depth":12,"bounds":{"left":0.4015625,"top":0.30694443,"width":0.10546875,"height":0.021527778},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Turn off visual effects","depth":14,"bounds":{"left":0.675,"top":0.59652776,"width":0.021875,"height":0.03888889},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Back","depth":15,"bounds":{"left":0.7109375,"top":0.34513888,"width":0.015625,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Generate a background","depth":14,"bounds":{"left":0.7265625,"top":0.35,"width":0.08710937,"height":0.018055556},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXComboBox","text":"No scene","depth":15,"bounds":{"left":0.715625,"top":0.38125,"width":0.12539062,"height":0.03888889},"value":"No scene","help_text":"","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"No scene","depth":17,"bounds":{"left":0.740625,"top":0.39375,"width":0.0265625,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextArea","text":"Acropolic propylaea","depth":16,"bounds":{"left":0.715625,"top":0.44236112,"width":0.12539062,"height":0.06666667},"value":"Acropolic propylaea","help_text":"","placeholder":"Jungle patio at sunset","role_description":"text entry area","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Create other samples","depth":16,"bounds":{"left":0.7410156,"top":0.53402776,"width":0.07460938,"height":0.025},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Create other samples","depth":18,"bounds":{"left":0.75039065,"top":0.5402778,"width":0.055859376,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"You can generate more results or change your description to get different results","depth":16,"bounds":{"left":0.72734374,"top":0.5715278,"width":0.10195313,"height":0.022222223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Learn more about generating backgrounds","depth":16,"bounds":{"left":0.7308594,"top":0.59375,"width":0.09492187,"height":0.011111111},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Learn more about generating backgrounds","depth":17,"bounds":{"left":0.7308594,"top":0.59375,"width":0.09492187,"height":0.011111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Use this background","depth":16,"bounds":{"left":0.72148436,"top":0.61319447,"width":0.1140625,"height":0.12638889},"role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":true,"is_selected":false},{"role":"AXButton","text":"Like","depth":17,"bounds":{"left":0.809375,"top":0.71458334,"width":0.0109375,"height":0.019444445},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Dislike","depth":17,"bounds":{"left":0.821875,"top":0.71458334,"width":0.0109375,"height":0.019444445},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Report a legal issue","depth":16,"bounds":{"left":0.72148436,"top":0.75069445,"width":0.04296875,"height":0.011111111},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Report a legal issue","depth":17,"bounds":{"left":0.72148436,"top":0.75069445,"width":0.04296875,"height":0.011111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close","depth":11,"bounds":{"left":0.83320314,"top":0.30069444,"width":0.01875,"height":0.033333335},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Generated background has been applied","depth":8,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Background is now replaced","depth":8,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
-443061304843876557
|
8729445723311160398
|
idle
|
accessibility
|
NULL
|
JY-20543 add AJ reports User pilot tracking by Lak JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
Console Home | Console Home | us-east-2
Console Home | Console Home | us-east-2
SecurityGroup | EC2 | us-east-2
SecurityGroup | EC2 | us-east-2
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app
SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Jiminny
Jiminny
Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf
Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf
Service-Desk - Queues - Platform team - Service space - Jira
Service-Desk - Queues - Platform team - Service space - Jira
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
CloudWatch | us-east-2
CloudWatch | us-east-2
Meet - Daily - Platform
Meet - Daily - Platform
Close tab
Settings
Settings
New Tab
Customize sidebar
Close Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
AI Chat settings
Close
WORK, Google Account: [EMAIL]
Main menu
New Chat
Open menu for conversation actions.
Conversation with Gemini
Conversation with Gemini
Copy prompt
Edit
You said why I can't see speaker data on meemt in firefox. ho wto set it up
You said
why I can't see speaker data on meemt in firefox. ho wto set it up
Listen
Show more options
Show thinking
Gemini said
Gemini said
Dealing with missing features right when you need them is incredibly frustrating. Assuming "meemt" means Google Meet, the reason you can't see your speaker data comes down to how Firefox interacts with Google's platform compared to Chrome.
Since "speaker data" can mean a couple of different things in a meeting, here are the two most likely causes for your issue and exactly how to get things working.
1. You Need "Speaker Notes" for Google Slides
1. You Need "Speaker Notes" for Google Slides
The Reality:
Google Meet has a native feature that lets you see your presentation's speaker notes right inside the video call interface.
However, this relies on a specific "Present a Tab" technology built exclusively for Google Chrome. Firefox handles screen sharing differently, so that native integration simply won't load.
View source details for citation from Google Workspace Updates. Opens side panel.
How to set it up (The Firefox Workaround):
You can still present and read your notes in Firefox by manually managing your windows.
Open your Google Slides presentation in a standard Firefox window.
Click the dropdown arrow next to the
Slideshow
button in the top right corner.
Select
Presenter view
to pop your speaker notes out into a separate, smaller window.
View source details for citation from Skywork. Opens side panel.
Join your Google Meet in a different Firefox window.
Click
Present now
and choose the
Window
option.
Select the window displaying your main slides (do not select your separate speaker notes window).
Resize your windows on your monitor so you can comfortably read the notes window while keeping an eye on the Meet window.
2. You Need "Speaker Labels" or Transcripts
2. You Need "Speaker Labels" or Transcripts
The Reality:
If you are trying to use a third-party AI note-taker (like Otter.ai, Tactiq, or tl;dv) to capture transcriptions and see who is speaking, Firefox is likely the roadblock. Firefox has strict privacy guardrails that prevent extensions from capturing internal browser audio easily, so most developers only build these tools for Chrome.
How to set it up:
Turn on built-in captions:
Google Meet has its own live captions that natively identify who is speaking, even in Firefox. Click the
CC
button at the bottom of your Meet screen to toggle them on.
Search for a Firefox add-on:
Check the Mozilla Add-ons store to see if your preferred tool actually has a supported Firefox version (for example, Fellow.ai offers one).
View source details for citation from Fellow.ai. Opens side panel.
Switch browsers temporarily:
If your specific transcription tool is explicitly Chrome-only, you will unfortunately need to join that specific meeting using a Chromium-based browser like Chrome, Edge, or Brave to capture the data.
Using Meet's built-in closed captions or the manual Presenter view workaround will get your speaker data back on track without forcing you to completely abandon Firefox.
Sources
Sources
I men in dia (arc) I can see my headphones in both microphone and speakers
I men in dia (arc) I can see my headphones in both microphone and speakers
Open upload file menu
Tools
Open mode picker
Pro
Send message
Your Jiminny chats aren’t used to improve our models. Gemini is AI and can make mistakes, including about people.
Your privacy & Gemini Opens in a new window
Your privacy & Gemini
Opens in a new window
Summarize page
Summarize page
Backgrounds and effects
Backgrounds and effects
Turn off visual effects
Back
Generate a background
No scene
No scene
Acropolic propylaea
Create other samples
Create other samples
You can generate more results or change your description to get different results
Learn more about generating backgrounds
Learn more about generating backgrounds
Use this background
Like
Dislike
Report a legal issue
Report a legal issue
Close
Generated background has been applied
Background is now replaced...
|
10077
|
|
10082
|
196
|
0
|
2026-04-14T08:12:15.542943+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776154335542_m1.jpg...
|
Firefox
|
Meet - Daily - Platform — Work
|
True
|
meet.google.com/mie-gawc-dsi
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
JY-20543 add AJ reports User pilot tracking by Lak JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
Console Home | Console Home | us-east-2
Console Home | Console Home | us-east-2
SecurityGroup | EC2 | us-east-2
SecurityGroup | EC2 | us-east-2
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app
SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Jiminny
Jiminny
Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf
Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf
Service-Desk - Queues - Platform team - Service space - Jira
Service-Desk - Queues - Platform team - Service space - Jira
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
CloudWatch | us-east-2
CloudWatch | us-east-2
Meet - Daily - Platform
Meet - Daily - Platform
Close tab
Settings
Settings
New Tab
Customize sidebar
Close Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
AI Chat settings
Close
WORK, Google Account: [EMAIL]
Main menu
New Chat
Open menu for conversation actions.
Conversation with Gemini
Conversation with Gemini
Copy prompt
Edit
You said why I can't see speaker data on meemt in firefox. ho wto set it up
You said
why I can't see speaker data on meemt in firefox. ho wto set it up
Listen
Show more options
Show thinking
Gemini said
Gemini said
Dealing with missing features right when you need them is incredibly frustrating. Assuming "meemt" means Google Meet, the reason you can't see your speaker data comes down to how Firefox interacts with Google's platform compared to Chrome.
Since "speaker data" can mean a couple of different things in a meeting, here are the two most likely causes for your issue and exactly how to get things working.
1. You Need "Speaker Notes" for Google Slides
1. You Need "Speaker Notes" for Google Slides
The Reality:
Google Meet has a native feature that lets you see your presentation's speaker notes right inside the video call interface.
However, this relies on a specific "Present a Tab" technology built exclusively for Google Chrome. Firefox handles screen sharing differently, so that native integration simply won't load.
View source details for citation from Google Workspace Updates. Opens side panel.
How to set it up (The Firefox Workaround):
You can still present and read your notes in Firefox by manually managing your windows.
Open your Google Slides presentation in a standard Firefox window.
Click the dropdown arrow next to the
Slideshow
button in the top right corner.
Select
Presenter view
to pop your speaker notes out into a separate, smaller window.
View source details for citation from Skywork. Opens side panel.
Join your Google Meet in a different Firefox window.
Click
Present now
and choose the
Window
option.
Select the window displaying your main slides (do not select your separate speaker notes window).
Resize your windows on your monitor so you can comfortably read the notes window while keeping an eye on the Meet window.
2. You Need "Speaker Labels" or Transcripts
2. You Need "Speaker Labels" or Transcripts
The Reality:
If you are trying to use a third-party AI note-taker (like Otter.ai, Tactiq, or tl;dv) to capture transcriptions and see who is speaking, Firefox is likely the roadblock. Firefox has strict privacy guardrails that prevent extensions from capturing internal browser audio easily, so most developers only build these tools for Chrome.
How to set it up:
Turn on built-in captions:
Google Meet has its own live captions that natively identify who is speaking, even in Firefox. Click the
CC
button at the bottom of your Meet screen to toggle them on.
Search for a Firefox add-on:
Check the Mozilla Add-ons store to see if your preferred tool actually has a supported Firefox version (for example, Fellow.ai offers one).
View source details for citation from Fellow.ai. Opens side panel.
Switch browsers temporarily:
If your specific transcription tool is explicitly Chrome-only, you will unfortunately need to join that specific meeting using a Chromium-based browser like Chrome, Edge, or Brave to capture the data.
Using Meet's built-in closed captions or the manual Presenter view workaround will get your speaker data back on track without forcing you to completely abandon Firefox.
Sources
Sources
I men in dia (arc) I can see my headphones in both microphone and speakers
I men in dia (arc) I can see my headphones in both microphone and speakers
Open upload file menu
Tools
Open mode picker
Pro
Send message
Your Jiminny chats aren’t used to improve our models. Gemini is AI and can make mistakes, including about people.
Your privacy & Gemini Opens in a new window
Your privacy & Gemini
Opens in a new window
Summarize page
Summarize page
Backgrounds and effects
Backgrounds and effects
Turn off visual effects
Back
Generate a background
No scene
No scene
Acropolic propylaea
Create other samples
Create other samples
You can generate more results or change your description to get different results
Learn more about generating backgrounds
Learn more about generating backgrounds
Use this background
Like
Dislike
Report a legal issue
Report a legal issue
Close
Generated background has been applied
Background is now replaced...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Console Home | Console Home | us-east-2","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Console Home | Console Home | us-east-2","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"SecurityGroup | EC2 | us-east-2","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"SecurityGroup | EC2 | us-east-2","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jiminny","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Service-Desk - Queues - Platform team - Service space - Jira","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Service-Desk - Queues - Platform team - Service space - Jira","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"CloudWatch | us-east-2","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"CloudWatch | us-east-2","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Meet - Daily - Platform","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Meet - Daily - Platform","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Settings","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Settings","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"New Tab","depth":4,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Close Google Gemini (⌃X)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"AI Chat settings","depth":7,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Close","depth":7,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"WORK, Google Account: lukas.kovalik@jiminny.com","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Main menu","depth":12,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Chat","depth":12,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Open menu for conversation actions.","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXHeading","text":"Conversation with Gemini","depth":15,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Conversation with Gemini","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Copy prompt","depth":21,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Edit","depth":21,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"You said why I can't see speaker data on meemt in firefox. ho wto set it up","depth":21,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"You said","depth":23,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"why I can't see speaker data on meemt in firefox. ho wto set it up","depth":23,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Listen","depth":22,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Show more options","depth":20,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Show thinking","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Gemini said","depth":20,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Gemini said","depth":21,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Dealing with missing features right when you need them is incredibly frustrating. Assuming \"meemt\" means Google Meet, the reason you can't see your speaker data comes down to how Firefox interacts with Google's platform compared to Chrome.","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Since \"speaker data\" can mean a couple of different things in a meeting, here are the two most likely causes for your issue and exactly how to get things working.","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"1. You Need \"Speaker Notes\" for Google Slides","depth":23,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1. You Need \"Speaker Notes\" for Google Slides","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"The Reality:","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Google Meet has a native feature that lets you see your presentation's speaker notes right inside the video call interface.","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"However, this relies on a specific \"Present a Tab\" technology built exclusively for Google Chrome. Firefox handles screen sharing differently, so that native integration simply won't load.","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"View source details for citation from Google Workspace Updates. Opens side panel.","depth":24,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"How to set it up (The Firefox Workaround):","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"You can still present and read your notes in Firefox by manually managing your windows.","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Open your Google Slides presentation in a standard Firefox window.","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Click the dropdown arrow next to the","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Slideshow","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"button in the top right corner.","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Select","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Presenter view","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"to pop your speaker notes out into a separate, smaller window.","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"View source details for citation from Skywork. Opens side panel.","depth":26,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Join your Google Meet in a different Firefox window.","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Click","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Present now","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"and choose the","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Window","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"option.","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Select the window displaying your main slides (do not select your separate speaker notes window).","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Resize your windows on your monitor so you can comfortably read the notes window while keeping an eye on the Meet window.","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"2. You Need \"Speaker Labels\" or Transcripts","depth":23,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2. You Need \"Speaker Labels\" or Transcripts","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"The Reality:","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"If you are trying to use a third-party AI note-taker (like Otter.ai, Tactiq, or tl;dv) to capture transcriptions and see who is speaking, Firefox is likely the roadblock. Firefox has strict privacy guardrails that prevent extensions from capturing internal browser audio easily, so most developers only build these tools for Chrome.","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"How to set it up:","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Turn on built-in captions:","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Google Meet has its own live captions that natively identify who is speaking, even in Firefox. Click the","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"CC","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"button at the bottom of your Meet screen to toggle them on.","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Search for a Firefox add-on:","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Check the Mozilla Add-ons store to see if your preferred tool actually has a supported Firefox version (for example, Fellow.ai offers one).","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"View source details for citation from Fellow.ai. Opens side panel.","depth":26,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Switch browsers temporarily:","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"If your specific transcription tool is explicitly Chrome-only, you will unfortunately need to join that specific meeting using a Chromium-based browser like Chrome, Edge, or Brave to capture the data.","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Using Meet's built-in closed captions or the manual Presenter view workaround will get your speaker data back on track without forcing you to completely abandon Firefox.","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Sources","depth":23,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Sources","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextArea","text":"I men in dia (arc) I can see my headphones in both microphone and speakers","depth":20,"value":"I men in dia (arc) I can see my headphones in both microphone and speakers","help_text":"","role_description":"text entry area","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"I men in dia (arc) I can see my headphones in both microphone and speakers","depth":22,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open upload file menu","depth":20,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Tools","depth":18,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Open mode picker","depth":20,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pro","depth":23,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Send message","depth":19,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Your Jiminny chats aren’t used to improve our models. Gemini is AI and can make mistakes, including about people.","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Your privacy & Gemini Opens in a new window","depth":17,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Your privacy & Gemini","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Opens in a new window","depth":19,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Summarize page","depth":7,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Summarize page","depth":9,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Backgrounds and effects","depth":11,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Backgrounds and effects","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Turn off visual effects","depth":14,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Back","depth":15,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Generate a background","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXComboBox","text":"No scene","depth":15,"value":"No scene","help_text":"","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"No scene","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextArea","text":"Acropolic propylaea","depth":16,"value":"Acropolic propylaea","help_text":"","placeholder":"Jungle patio at sunset","role_description":"text entry area","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Create other samples","depth":16,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Create other samples","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"You can generate more results or change your description to get different results","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Learn more about generating backgrounds","depth":16,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Learn more about generating backgrounds","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Use this background","depth":16,"role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":true,"is_selected":false},{"role":"AXButton","text":"Like","depth":17,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Dislike","depth":17,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Report a legal issue","depth":16,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Report a legal issue","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close","depth":11,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Generated background has been applied","depth":8,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Background is now replaced","depth":8,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
-443061304843876557
|
8729445723311160398
|
idle
|
accessibility
|
NULL
|
JY-20543 add AJ reports User pilot tracking by Lak JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
Console Home | Console Home | us-east-2
Console Home | Console Home | us-east-2
SecurityGroup | EC2 | us-east-2
SecurityGroup | EC2 | us-east-2
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app
SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Jiminny
Jiminny
Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf
Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf
Service-Desk - Queues - Platform team - Service space - Jira
Service-Desk - Queues - Platform team - Service space - Jira
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
CloudWatch | us-east-2
CloudWatch | us-east-2
Meet - Daily - Platform
Meet - Daily - Platform
Close tab
Settings
Settings
New Tab
Customize sidebar
Close Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
AI Chat settings
Close
WORK, Google Account: [EMAIL]
Main menu
New Chat
Open menu for conversation actions.
Conversation with Gemini
Conversation with Gemini
Copy prompt
Edit
You said why I can't see speaker data on meemt in firefox. ho wto set it up
You said
why I can't see speaker data on meemt in firefox. ho wto set it up
Listen
Show more options
Show thinking
Gemini said
Gemini said
Dealing with missing features right when you need them is incredibly frustrating. Assuming "meemt" means Google Meet, the reason you can't see your speaker data comes down to how Firefox interacts with Google's platform compared to Chrome.
Since "speaker data" can mean a couple of different things in a meeting, here are the two most likely causes for your issue and exactly how to get things working.
1. You Need "Speaker Notes" for Google Slides
1. You Need "Speaker Notes" for Google Slides
The Reality:
Google Meet has a native feature that lets you see your presentation's speaker notes right inside the video call interface.
However, this relies on a specific "Present a Tab" technology built exclusively for Google Chrome. Firefox handles screen sharing differently, so that native integration simply won't load.
View source details for citation from Google Workspace Updates. Opens side panel.
How to set it up (The Firefox Workaround):
You can still present and read your notes in Firefox by manually managing your windows.
Open your Google Slides presentation in a standard Firefox window.
Click the dropdown arrow next to the
Slideshow
button in the top right corner.
Select
Presenter view
to pop your speaker notes out into a separate, smaller window.
View source details for citation from Skywork. Opens side panel.
Join your Google Meet in a different Firefox window.
Click
Present now
and choose the
Window
option.
Select the window displaying your main slides (do not select your separate speaker notes window).
Resize your windows on your monitor so you can comfortably read the notes window while keeping an eye on the Meet window.
2. You Need "Speaker Labels" or Transcripts
2. You Need "Speaker Labels" or Transcripts
The Reality:
If you are trying to use a third-party AI note-taker (like Otter.ai, Tactiq, or tl;dv) to capture transcriptions and see who is speaking, Firefox is likely the roadblock. Firefox has strict privacy guardrails that prevent extensions from capturing internal browser audio easily, so most developers only build these tools for Chrome.
How to set it up:
Turn on built-in captions:
Google Meet has its own live captions that natively identify who is speaking, even in Firefox. Click the
CC
button at the bottom of your Meet screen to toggle them on.
Search for a Firefox add-on:
Check the Mozilla Add-ons store to see if your preferred tool actually has a supported Firefox version (for example, Fellow.ai offers one).
View source details for citation from Fellow.ai. Opens side panel.
Switch browsers temporarily:
If your specific transcription tool is explicitly Chrome-only, you will unfortunately need to join that specific meeting using a Chromium-based browser like Chrome, Edge, or Brave to capture the data.
Using Meet's built-in closed captions or the manual Presenter view workaround will get your speaker data back on track without forcing you to completely abandon Firefox.
Sources
Sources
I men in dia (arc) I can see my headphones in both microphone and speakers
I men in dia (arc) I can see my headphones in both microphone and speakers
Open upload file menu
Tools
Open mode picker
Pro
Send message
Your Jiminny chats aren’t used to improve our models. Gemini is AI and can make mistakes, including about people.
Your privacy & Gemini Opens in a new window
Your privacy & Gemini
Opens in a new window
Summarize page
Summarize page
Backgrounds and effects
Backgrounds and effects
Turn off visual effects
Back
Generate a background
No scene
No scene
Acropolic propylaea
Create other samples
Create other samples
You can generate more results or change your description to get different results
Learn more about generating backgrounds
Learn more about generating backgrounds
Use this background
Like
Dislike
Report a legal issue
Report a legal issue
Close
Generated background has been applied
Background is now replaced...
|
10078
|
|
10083
|
197
|
0
|
2026-04-14T08:12:21.018340+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776154341018_m2.jpg...
|
Firefox
|
Meet - Daily - Platform — Work
|
True
|
meet.google.com/mie-gawc-dsi
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
JY-20543 add AJ reports User pilot tracking by Lak JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
Console Home | Console Home | us-east-2
Console Home | Console Home | us-east-2
SecurityGroup | EC2 | us-east-2
SecurityGroup | EC2 | us-east-2
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app
SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Jiminny
Jiminny
Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf
Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf
Service-Desk - Queues - Platform team - Service space - Jira
Service-Desk - Queues - Platform team - Service space - Jira
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
CloudWatch | us-east-2
CloudWatch | us-east-2
Meet - Daily - Platform
Meet - Daily - Platform
Close tab
Settings
Settings
New Tab
Customize sidebar
Close Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
AI Chat settings
Close
WORK, Google Account: [EMAIL]
Main menu
New Chat
Open menu for conversation actions.
Conversation with Gemini
Conversation with Gemini
Copy prompt
Edit
You said why I can't see speaker data on meemt in firefox. ho wto set it up
You said
why I can't see speaker data on meemt in firefox. ho wto set it up
Listen
Show more options
Show thinking
Gemini said
Gemini said
Dealing with missing features right when you need them is incredibly frustrating. Assuming "meemt" means Google Meet, the reason you can't see your speaker data comes down to how Firefox interacts with Google's platform compared to Chrome.
Since "speaker data" can mean a couple of different things in a meeting, here are the two most likely causes for your issue and exactly how to get things working.
1. You Need "Speaker Notes" for Google Slides
1. You Need "Speaker Notes" for Google Slides
The Reality:
Google Meet has a native feature that lets you see your presentation's speaker notes right inside the video call interface.
However, this relies on a specific "Present a Tab" technology built exclusively for Google Chrome. Firefox handles screen sharing differently, so that native integration simply won't load.
View source details for citation from Google Workspace Updates. Opens side panel.
How to set it up (The Firefox Workaround):
You can still present and read your notes in Firefox by manually managing your windows.
Open your Google Slides presentation in a standard Firefox window.
Click the dropdown arrow next to the
Slideshow
button in the top right corner.
Select
Presenter view
to pop your speaker notes out into a separate, smaller window.
View source details for citation from Skywork. Opens side panel.
Join your Google Meet in a different Firefox window.
Click
Present now
and choose the
Window
option.
Select the window displaying your main slides (do not select your separate speaker notes window).
Resize your windows on your monitor so you can comfortably read the notes window while keeping an eye on the Meet window.
2. You Need "Speaker Labels" or Transcripts
2. You Need "Speaker Labels" or Transcripts
The Reality:
If you are trying to use a third-party AI note-taker (like Otter.ai, Tactiq, or tl;dv) to capture transcriptions and see who is speaking, Firefox is likely the roadblock. Firefox has strict privacy guardrails that prevent extensions from capturing internal browser audio easily, so most developers only build these tools for Chrome.
How to set it up:
Turn on built-in captions:
Google Meet has its own live captions that natively identify who is speaking, even in Firefox. Click the
CC
button at the bottom of your Meet screen to toggle them on.
Search for a Firefox add-on:
Check the Mozilla Add-ons store to see if your preferred tool actually has a supported Firefox version (for example, Fellow.ai offers one).
View source details for citation from Fellow.ai. Opens side panel.
Switch browsers temporarily:
If your specific transcription tool is explicitly Chrome-only, you will unfortunately need to join that specific meeting using a Chromium-based browser like Chrome, Edge, or Brave to capture the data.
Using Meet's built-in closed captions or the manual Presenter view workaround will get your speaker data back on track without forcing you to completely abandon Firefox.
Sources
Sources
I men in dia (arc) I can see my headphones in both microphone and speakers
I men in dia (arc) I can see my headphones in both microphone and speakers
Open upload file menu
Tools
Open mode picker
Pro
Send message
Your Jiminny chats aren’t used to improve our models. Gemini is AI and can make mistakes, including about people.
Your privacy & Gemini Opens in a new window
Your privacy & Gemini
Opens in a new window
Summarize page
Summarize page
Backgrounds and effects
Backgrounds and effects
Turn off visual effects
Back
Generate a background
No scene
No scene
Acropolic propylaea
Create other samples
Create other samples
You can generate more results or change your description to get different results
Learn more about generating backgrounds
Learn more about generating backgrounds
Use this background
Like
Dislike
Report a legal issue
Report a legal issue
Close
Generated background has been applied
Background is now replaced...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":4,"bounds":{"left":0.00234375,"top":0.045138888,"width":0.0890625,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira","depth":4,"bounds":{"left":0.0,"top":0.08263889,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira","depth":5,"bounds":{"left":0.015625,"top":0.09236111,"width":0.11796875,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":4,"bounds":{"left":0.0,"top":0.11111111,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":5,"bounds":{"left":0.015625,"top":0.12083333,"width":0.1515625,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Console Home | Console Home | us-east-2","depth":4,"bounds":{"left":0.0,"top":0.13958333,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Console Home | Console Home | us-east-2","depth":5,"bounds":{"left":0.015625,"top":0.14930555,"width":0.08671875,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"SecurityGroup | EC2 | us-east-2","depth":4,"bounds":{"left":0.0,"top":0.16805555,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"SecurityGroup | EC2 | us-east-2","depth":5,"bounds":{"left":0.015625,"top":0.17777778,"width":0.06484375,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.19652778,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":5,"bounds":{"left":0.015625,"top":0.20625,"width":0.18710938,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.225,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app","depth":5,"bounds":{"left":0.015625,"top":0.23472223,"width":0.23476562,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet","depth":4,"bounds":{"left":0.0,"top":0.2534722,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet","depth":5,"bounds":{"left":0.015625,"top":0.26319444,"width":0.1984375,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jiminny","depth":4,"bounds":{"left":0.0,"top":0.28194445,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny","depth":5,"bounds":{"left":0.015625,"top":0.29166666,"width":0.015625,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf","depth":4,"bounds":{"left":0.0,"top":0.31041667,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf","depth":5,"bounds":{"left":0.015625,"top":0.3201389,"width":0.1640625,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Service-Desk - Queues - Platform team - Service space - Jira","depth":4,"bounds":{"left":0.0,"top":0.33888888,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Service-Desk - Queues - Platform team - Service space - Jira","depth":5,"bounds":{"left":0.015625,"top":0.34861112,"width":0.12617187,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.3673611,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":5,"bounds":{"left":0.015625,"top":0.37708333,"width":0.18710938,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":4,"bounds":{"left":0.0,"top":0.39583334,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":5,"bounds":{"left":0.015625,"top":0.40555555,"width":0.1515625,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"CloudWatch | us-east-2","depth":4,"bounds":{"left":0.0,"top":0.42430556,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"CloudWatch | us-east-2","depth":5,"bounds":{"left":0.015625,"top":0.4340278,"width":0.0484375,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Meet - Daily - Platform","depth":4,"bounds":{"left":0.0,"top":0.45277777,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Meet - Daily - Platform","depth":5,"bounds":{"left":0.015625,"top":0.4625,"width":0.046484374,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.07890625,"top":0.45902777,"width":0.009375,"height":0.016666668},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Settings","depth":4,"bounds":{"left":0.0,"top":0.48125,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Settings","depth":5,"bounds":{"left":0.015625,"top":0.49097222,"width":0.016796876,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"New Tab","depth":4,"bounds":{"left":0.003125,"top":0.51111114,"width":0.08710937,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.003125,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Close Google Gemini (⌃X)","depth":6,"bounds":{"left":0.01640625,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"bounds":{"left":0.029296875,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"bounds":{"left":0.0421875,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"bounds":{"left":0.05546875,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"AI Chat settings","depth":7,"bounds":{"left":0.2171875,"top":0.047916666,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Close","depth":7,"bounds":{"left":0.23125,"top":0.047916666,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"WORK, Google Account: lukas.kovalik@jiminny.com","depth":12,"bounds":{"left":0.228125,"top":0.090277776,"width":0.015625,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Main menu","depth":12,"bounds":{"left":0.0984375,"top":0.090277776,"width":0.015625,"height":0.027777778},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Chat","depth":12,"bounds":{"left":0.1953125,"top":0.090277776,"width":0.015625,"height":0.027777778},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Open menu for conversation actions.","depth":12,"bounds":{"left":0.2109375,"top":0.090277776,"width":0.015625,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXHeading","text":"Conversation with Gemini","depth":15,"bounds":{"left":0.09335937,"top":0.12847222,"width":0.000390625,"height":0.00069444446},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Conversation with Gemini","depth":16,"bounds":{"left":0.09335937,"top":0.13055556,"width":0.14101562,"height":0.022222223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Copy prompt","depth":21,"bounds":{"left":0.1203125,"top":0.15972222,"width":0.015625,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Edit","depth":21,"bounds":{"left":0.1375,"top":0.15972222,"width":0.015625,"height":0.027777778},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"You said why I can't see speaker data on meemt in firefox. ho wto set it up","depth":21,"bounds":{"left":0.1609375,"top":0.16805555,"width":0.072265625,"height":0.058333334},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"You said","depth":23,"bounds":{"left":0.09335937,"top":0.1701389,"width":0.0234375,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"why I can't see speaker data on meemt in firefox. ho wto set it up","depth":23,"bounds":{"left":0.1609375,"top":0.17083333,"width":0.07070313,"height":0.05347222},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Listen","depth":22,"bounds":{"left":0.22382812,"top":0.25416666,"width":0.015625,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Show more options","depth":20,"bounds":{"left":0.22382812,"top":0.24930556,"width":0.015625,"height":0.027777778},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Show thinking","depth":26,"bounds":{"left":0.11953125,"top":0.25625,"width":0.036328126,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Gemini said","depth":20,"bounds":{"left":0.11679687,"top":0.2923611,"width":0.000390625,"height":0.00069444446},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Gemini said","depth":21,"bounds":{"left":0.11679687,"top":0.29375,"width":0.048046876,"height":0.016666668},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Dealing with missing features right when you need them is incredibly frustrating. Assuming \"meemt\" means Google Meet, the reason you can't see your speaker data comes down to how Firefox interacts with Google's platform compared to Chrome.","depth":24,"bounds":{"left":0.10390625,"top":0.30069444,"width":0.13046876,"height":0.10486111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Since \"speaker data\" can mean a couple of different things in a meeting, here are the two most likely causes for your issue and exactly how to get things working.","depth":24,"bounds":{"left":0.10390625,"top":0.4201389,"width":0.13125,"height":0.06875},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"1. You Need \"Speaker Notes\" for Google Slides","depth":23,"bounds":{"left":0.10390625,"top":0.52152777,"width":0.13242188,"height":0.033333335},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1. You Need \"Speaker Notes\" for Google Slides","depth":24,"bounds":{"left":0.10390625,"top":0.5229167,"width":0.12070312,"height":0.03125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"The Reality:","depth":24,"bounds":{"left":0.10390625,"top":0.5625,"width":0.036328126,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Google Meet has a native feature that lets you see your presentation's speaker notes right inside the video call interface.","depth":24,"bounds":{"left":0.10390625,"top":0.5625,"width":0.13242188,"height":0.050694443},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"However, this relies on a specific \"Present a Tab\" technology built exclusively for Google Chrome. Firefox handles screen sharing differently, so that native integration simply won't load.","depth":24,"bounds":{"left":0.10390625,"top":0.5986111,"width":0.12539062,"height":0.10486111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"View source details for citation from Google Workspace Updates. Opens side panel.","depth":24,"bounds":{"left":0.13710937,"top":0.68958336,"width":0.01015625,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"How to set it up (The Firefox Workaround):","depth":24,"bounds":{"left":0.10390625,"top":0.71805555,"width":0.12851563,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"You can still present and read your notes in Firefox by manually managing your windows.","depth":24,"bounds":{"left":0.10390625,"top":0.7361111,"width":0.12617187,"height":0.03263889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Open your Google Slides presentation in a standard Firefox window.","depth":26,"bounds":{"left":0.11796875,"top":0.7777778,"width":0.115625,"height":0.03263889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Click the dropdown arrow next to the","depth":26,"bounds":{"left":0.11796875,"top":0.8194444,"width":0.10703125,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Slideshow","depth":26,"bounds":{"left":0.11796875,"top":0.8375,"width":0.03125,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"button in the top right corner.","depth":26,"bounds":{"left":0.14921875,"top":0.8375,"width":0.08515625,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Select","depth":26,"bounds":{"left":0.11796875,"top":0.8611111,"width":0.01953125,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Presenter view","depth":26,"bounds":{"left":0.1375,"top":0.8611111,"width":0.0453125,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"to pop your speaker notes out into a separate, smaller window.","depth":26,"bounds":{"left":0.11796875,"top":0.8611111,"width":0.10078125,"height":0.050694443},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"View source details for citation from Skywork. Opens side panel.","depth":26,"bounds":{"left":0.16523437,"top":0.8979167,"width":0.01015625,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Join your Google Meet in a different Firefox window.","depth":26,"bounds":{"left":0.11796875,"top":0.92083335,"width":0.103125,"height":0.03263889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Click","depth":26,"bounds":{"left":0.11796875,"top":0.9625,"width":0.015234375,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Present now","depth":26,"bounds":{"left":0.13320312,"top":0.9625,"width":0.037890624,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"and choose the","depth":26,"bounds":{"left":0.17109375,"top":0.9625,"width":0.047265626,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Window","depth":26,"bounds":{"left":0.11796875,"top":0.98055553,"width":0.02421875,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"option.","depth":26,"bounds":{"left":0.1421875,"top":0.98055553,"width":0.02109375,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Select the window displaying your main slides (do not select your separate speaker notes window).","depth":26,"bounds":{"left":0.11796875,"top":1.0,"width":0.11328125,"height":-0.0041667223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Resize your windows on your monitor so you can comfortably read the notes window while keeping an eye on the Meet window.","depth":26,"bounds":{"left":0.11796875,"top":1.0,"width":0.11835937,"height":-0.06388891},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"2. You Need \"Speaker Labels\" or Transcripts","depth":23,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2. You Need \"Speaker Labels\" or Transcripts","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"The Reality:","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"If you are trying to use a third-party AI note-taker (like Otter.ai, Tactiq, or tl;dv) to capture transcriptions and see who is speaking, Firefox is likely the roadblock. Firefox has strict privacy guardrails that prevent extensions from capturing internal browser audio easily, so most developers only build these tools for Chrome.","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"How to set it up:","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Turn on built-in captions:","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Google Meet has its own live captions that natively identify who is speaking, even in Firefox. Click the","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"CC","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"button at the bottom of your Meet screen to toggle them on.","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Search for a Firefox add-on:","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Check the Mozilla Add-ons store to see if your preferred tool actually has a supported Firefox version (for example, Fellow.ai offers one).","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"View source details for citation from Fellow.ai. Opens side panel.","depth":26,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Switch browsers temporarily:","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"If your specific transcription tool is explicitly Chrome-only, you will unfortunately need to join that specific meeting using a Chromium-based browser like Chrome, Edge, or Brave to capture the data.","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Using Meet's built-in closed captions or the manual Presenter view workaround will get your speaker data back on track without forcing you to completely abandon Firefox.","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Sources","depth":23,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Sources","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextArea","text":"I men in dia (arc) I can see my headphones in both microphone and speakers","depth":20,"bounds":{"left":0.109375,"top":0.8020833,"width":0.125,"height":0.05},"value":"I men in dia (arc) I can see my headphones in both microphone and speakers","help_text":"","role_description":"text entry area","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"I men in dia (arc) I can see my headphones in both microphone and speakers","depth":22,"bounds":{"left":0.109375,"top":0.8034722,"width":0.10625,"height":0.047916666},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open upload file menu","depth":20,"bounds":{"left":0.1046875,"top":0.86527777,"width":0.015625,"height":0.027777778},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Tools","depth":18,"bounds":{"left":0.1234375,"top":0.86527777,"width":0.015625,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Open mode picker","depth":20,"bounds":{"left":0.190625,"top":0.8645833,"width":0.03046875,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pro","depth":23,"bounds":{"left":0.196875,"top":0.87222224,"width":0.00859375,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Send message","depth":19,"bounds":{"left":0.22265625,"top":0.86388886,"width":0.01640625,"height":0.029166667},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Your Jiminny chats aren’t used to improve our models. Gemini is AI and can make mistakes, including about people.","depth":17,"bounds":{"left":0.10039063,"top":0.9097222,"width":0.14296874,"height":0.022222223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Your privacy & Gemini Opens in a new window","depth":17,"bounds":{"left":0.1484375,"top":0.93194443,"width":0.046875,"height":0.011111111},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Your privacy & Gemini","depth":18,"bounds":{"left":0.1484375,"top":0.93194443,"width":0.046875,"height":0.011111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Opens in a new window","depth":19,"bounds":{"left":0.09335937,"top":0.93125,"width":0.05078125,"height":0.011111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Summarize page","depth":7,"bounds":{"left":0.1,"top":0.96319443,"width":0.06289063,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Summarize page","depth":9,"bounds":{"left":0.10664062,"top":0.9673611,"width":0.049609374,"height":0.013888889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Backgrounds and effects","depth":11,"bounds":{"left":0.3921875,"top":0.28958333,"width":0.46289062,"height":0.055555556},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Backgrounds and effects","depth":12,"bounds":{"left":0.4015625,"top":0.30694443,"width":0.10546875,"height":0.021527778},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Turn off visual effects","depth":14,"bounds":{"left":0.675,"top":0.59652776,"width":0.021875,"height":0.03888889},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Back","depth":15,"bounds":{"left":0.7109375,"top":0.34513888,"width":0.015625,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Generate a background","depth":14,"bounds":{"left":0.7265625,"top":0.35,"width":0.08710937,"height":0.018055556},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXComboBox","text":"No scene","depth":15,"bounds":{"left":0.715625,"top":0.38125,"width":0.12539062,"height":0.03888889},"value":"No scene","help_text":"","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"No scene","depth":17,"bounds":{"left":0.740625,"top":0.39375,"width":0.0265625,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextArea","text":"Acropolic propylaea","depth":16,"bounds":{"left":0.715625,"top":0.44236112,"width":0.12539062,"height":0.06666667},"value":"Acropolic propylaea","help_text":"","placeholder":"Jungle patio at sunset","role_description":"text entry area","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Create other samples","depth":16,"bounds":{"left":0.7410156,"top":0.53402776,"width":0.07460938,"height":0.025},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Create other samples","depth":18,"bounds":{"left":0.75039065,"top":0.5402778,"width":0.055859376,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"You can generate more results or change your description to get different results","depth":16,"bounds":{"left":0.72734374,"top":0.5715278,"width":0.10195313,"height":0.022222223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Learn more about generating backgrounds","depth":16,"bounds":{"left":0.7308594,"top":0.59375,"width":0.09492187,"height":0.011111111},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Learn more about generating backgrounds","depth":17,"bounds":{"left":0.7308594,"top":0.59375,"width":0.09492187,"height":0.011111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Use this background","depth":16,"bounds":{"left":0.72148436,"top":0.61319447,"width":0.1140625,"height":0.12638889},"role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":true,"is_selected":false},{"role":"AXButton","text":"Like","depth":17,"bounds":{"left":0.809375,"top":0.71458334,"width":0.0109375,"height":0.019444445},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Dislike","depth":17,"bounds":{"left":0.821875,"top":0.71458334,"width":0.0109375,"height":0.019444445},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Report a legal issue","depth":16,"bounds":{"left":0.72148436,"top":0.75069445,"width":0.04296875,"height":0.011111111},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Report a legal issue","depth":17,"bounds":{"left":0.72148436,"top":0.75069445,"width":0.04296875,"height":0.011111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close","depth":11,"bounds":{"left":0.83320314,"top":0.30069444,"width":0.01875,"height":0.033333335},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Generated background has been applied","depth":8,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Background is now replaced","depth":8,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
-443061304843876557
|
8729445723311160398
|
idle
|
accessibility
|
NULL
|
JY-20543 add AJ reports User pilot tracking by Lak JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
Console Home | Console Home | us-east-2
Console Home | Console Home | us-east-2
SecurityGroup | EC2 | us-east-2
SecurityGroup | EC2 | us-east-2
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app
SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Jiminny
Jiminny
Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf
Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf
Service-Desk - Queues - Platform team - Service space - Jira
Service-Desk - Queues - Platform team - Service space - Jira
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
CloudWatch | us-east-2
CloudWatch | us-east-2
Meet - Daily - Platform
Meet - Daily - Platform
Close tab
Settings
Settings
New Tab
Customize sidebar
Close Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
AI Chat settings
Close
WORK, Google Account: [EMAIL]
Main menu
New Chat
Open menu for conversation actions.
Conversation with Gemini
Conversation with Gemini
Copy prompt
Edit
You said why I can't see speaker data on meemt in firefox. ho wto set it up
You said
why I can't see speaker data on meemt in firefox. ho wto set it up
Listen
Show more options
Show thinking
Gemini said
Gemini said
Dealing with missing features right when you need them is incredibly frustrating. Assuming "meemt" means Google Meet, the reason you can't see your speaker data comes down to how Firefox interacts with Google's platform compared to Chrome.
Since "speaker data" can mean a couple of different things in a meeting, here are the two most likely causes for your issue and exactly how to get things working.
1. You Need "Speaker Notes" for Google Slides
1. You Need "Speaker Notes" for Google Slides
The Reality:
Google Meet has a native feature that lets you see your presentation's speaker notes right inside the video call interface.
However, this relies on a specific "Present a Tab" technology built exclusively for Google Chrome. Firefox handles screen sharing differently, so that native integration simply won't load.
View source details for citation from Google Workspace Updates. Opens side panel.
How to set it up (The Firefox Workaround):
You can still present and read your notes in Firefox by manually managing your windows.
Open your Google Slides presentation in a standard Firefox window.
Click the dropdown arrow next to the
Slideshow
button in the top right corner.
Select
Presenter view
to pop your speaker notes out into a separate, smaller window.
View source details for citation from Skywork. Opens side panel.
Join your Google Meet in a different Firefox window.
Click
Present now
and choose the
Window
option.
Select the window displaying your main slides (do not select your separate speaker notes window).
Resize your windows on your monitor so you can comfortably read the notes window while keeping an eye on the Meet window.
2. You Need "Speaker Labels" or Transcripts
2. You Need "Speaker Labels" or Transcripts
The Reality:
If you are trying to use a third-party AI note-taker (like Otter.ai, Tactiq, or tl;dv) to capture transcriptions and see who is speaking, Firefox is likely the roadblock. Firefox has strict privacy guardrails that prevent extensions from capturing internal browser audio easily, so most developers only build these tools for Chrome.
How to set it up:
Turn on built-in captions:
Google Meet has its own live captions that natively identify who is speaking, even in Firefox. Click the
CC
button at the bottom of your Meet screen to toggle them on.
Search for a Firefox add-on:
Check the Mozilla Add-ons store to see if your preferred tool actually has a supported Firefox version (for example, Fellow.ai offers one).
View source details for citation from Fellow.ai. Opens side panel.
Switch browsers temporarily:
If your specific transcription tool is explicitly Chrome-only, you will unfortunately need to join that specific meeting using a Chromium-based browser like Chrome, Edge, or Brave to capture the data.
Using Meet's built-in closed captions or the manual Presenter view workaround will get your speaker data back on track without forcing you to completely abandon Firefox.
Sources
Sources
I men in dia (arc) I can see my headphones in both microphone and speakers
I men in dia (arc) I can see my headphones in both microphone and speakers
Open upload file menu
Tools
Open mode picker
Pro
Send message
Your Jiminny chats aren’t used to improve our models. Gemini is AI and can make mistakes, including about people.
Your privacy & Gemini Opens in a new window
Your privacy & Gemini
Opens in a new window
Summarize page
Summarize page
Backgrounds and effects
Backgrounds and effects
Turn off visual effects
Back
Generate a background
No scene
No scene
Acropolic propylaea
Create other samples
Create other samples
You can generate more results or change your description to get different results
Learn more about generating backgrounds
Learn more about generating backgrounds
Use this background
Like
Dislike
Report a legal issue
Report a legal issue
Close
Generated background has been applied
Background is now replaced...
|
10077
|
|
10074
|
195
|
40
|
2026-04-14T08:10:40.992409+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776154240992_m2.jpg...
|
Firefox
|
Meet - Daily - Platform — Work
|
True
|
meet.google.com/mie-gawc-dsi
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
JY-20543 add AJ reports User pilot tracking by Lak JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
Console Home | Console Home | us-east-2
Console Home | Console Home | us-east-2
SecurityGroup | EC2 | us-east-2
SecurityGroup | EC2 | us-east-2
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app
SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Jiminny
Jiminny
Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf
Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf
Service-Desk - Queues - Platform team - Service space - Jira
Service-Desk - Queues - Platform team - Service space - Jira
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
CloudWatch | us-east-2
CloudWatch | us-east-2
Meet - Daily - Platform
Meet - Daily - Platform
Close tab
Settings
Settings
New Tab
Customize sidebar
Close Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
AI Chat settings
Close
WORK, Google Account: [EMAIL]
Main menu
New Chat
Open menu for conversation actions.
Conversation with Gemini
Conversation with Gemini
Copy prompt
Edit
You said why I can't see speaker data on meemt in firefox. ho wto set it up
You said
why I can't see speaker data on meemt in firefox. ho wto set it up
Listen
Show more options
Show thinking
Gemini said
Gemini said
Dealing with missing features right when you need them is incredibly frustrating. Assuming "meemt" means Google Meet, the reason you can't see your speaker data comes down to how Firefox interacts with Google's platform compared to Chrome.
Since "speaker data" can mean a couple of different things in a meeting, here are the two most likely causes for your issue and exactly how to get things working.
1. You Need "Speaker Notes" for Google Slides
1. You Need "Speaker Notes" for Google Slides
The Reality:
Google Meet has a native feature that lets you see your presentation's speaker notes right inside the video call interface.
However, this relies on a specific "Present a Tab" technology built exclusively for Google Chrome. Firefox handles screen sharing differently, so that native integration simply won't load.
View source details for citation from Google Workspace Updates. Opens side panel.
How to set it up (The Firefox Workaround):
You can still present and read your notes in Firefox by manually managing your windows.
Open your Google Slides presentation in a standard Firefox window.
Click the dropdown arrow next to the
Slideshow
button in the top right corner.
Select
Presenter view
to pop your speaker notes out into a separate, smaller window.
View source details for citation from Skywork. Opens side panel.
Join your Google Meet in a different Firefox window.
Click
Present now
and choose the
Window
option.
Select the window displaying your main slides (do not select your separate speaker notes window).
Resize your windows on your monitor so you can comfortably read the notes window while keeping an eye on the Meet window.
2. You Need "Speaker Labels" or Transcripts
2. You Need "Speaker Labels" or Transcripts
The Reality:
If you are trying to use a third-party AI note-taker (like Otter.ai, Tactiq, or tl;dv) to capture transcriptions and see who is speaking, Firefox is likely the roadblock. Firefox has strict privacy guardrails that prevent extensions from capturing internal browser audio easily, so most developers only build these tools for Chrome.
How to set it up:
Turn on built-in captions:
Google Meet has its own live captions that natively identify who is speaking, even in Firefox. Click the
CC
button at the bottom of your Meet screen to toggle them on.
Search for a Firefox add-on:
Check the Mozilla Add-ons store to see if your preferred tool actually has a supported Firefox version (for example, Fellow.ai offers one).
View source details for citation from Fellow.ai. Opens side panel.
Switch browsers temporarily:
If your specific transcription tool is explicitly Chrome-only, you will unfortunately need to join that specific meeting using a Chromium-based browser like Chrome, Edge, or Brave to capture the data.
Using Meet's built-in closed captions or the manual Presenter view workaround will get your speaker data back on track without forcing you to completely abandon Firefox.
Sources
Sources
I men in dia (arc) I can see my headphones in both microphone and speakers
I men in dia (arc) I can see my headphones in both microphone and speakers
Open upload file menu
Tools
Open mode picker
Pro
Send message
Your Jiminny chats aren’t used to improve our models. Gemini is AI and can make mistakes, including about people.
Your privacy & Gemini Opens in a new window
Your privacy & Gemini
Opens in a new window
Summarize page
Summarize page
Backgrounds and effects
Backgrounds and effects
Turn off visual effects
Back
Generate a background
No scene
No scene
Acropolic propylaea
Create other samples
Create other samples
You can generate more results or change your description to get different results
Learn more about generating backgrounds
Learn more about generating backgrounds
Use this background
Report a legal issue
Report a legal issue
Close
Samples have been created...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":4,"bounds":{"left":0.00234375,"top":0.045138888,"width":0.0890625,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira","depth":4,"bounds":{"left":0.0,"top":0.08263889,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira","depth":5,"bounds":{"left":0.015625,"top":0.09236111,"width":0.11796875,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":4,"bounds":{"left":0.0,"top":0.11111111,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":5,"bounds":{"left":0.015625,"top":0.12083333,"width":0.1515625,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Console Home | Console Home | us-east-2","depth":4,"bounds":{"left":0.0,"top":0.13958333,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Console Home | Console Home | us-east-2","depth":5,"bounds":{"left":0.015625,"top":0.14930555,"width":0.08671875,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"SecurityGroup | EC2 | us-east-2","depth":4,"bounds":{"left":0.0,"top":0.16805555,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"SecurityGroup | EC2 | us-east-2","depth":5,"bounds":{"left":0.015625,"top":0.17777778,"width":0.06484375,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.19652778,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":5,"bounds":{"left":0.015625,"top":0.20625,"width":0.18710938,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.225,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app","depth":5,"bounds":{"left":0.015625,"top":0.23472223,"width":0.23476562,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet","depth":4,"bounds":{"left":0.0,"top":0.2534722,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet","depth":5,"bounds":{"left":0.015625,"top":0.26319444,"width":0.1984375,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jiminny","depth":4,"bounds":{"left":0.0,"top":0.28194445,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny","depth":5,"bounds":{"left":0.015625,"top":0.29166666,"width":0.015625,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf","depth":4,"bounds":{"left":0.0,"top":0.31041667,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf","depth":5,"bounds":{"left":0.015625,"top":0.3201389,"width":0.1640625,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Service-Desk - Queues - Platform team - Service space - Jira","depth":4,"bounds":{"left":0.0,"top":0.33888888,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Service-Desk - Queues - Platform team - Service space - Jira","depth":5,"bounds":{"left":0.015625,"top":0.34861112,"width":0.12617187,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.3673611,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app","depth":5,"bounds":{"left":0.015625,"top":0.37708333,"width":0.18710938,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":4,"bounds":{"left":0.0,"top":0.39583334,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":5,"bounds":{"left":0.015625,"top":0.40555555,"width":0.1515625,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"CloudWatch | us-east-2","depth":4,"bounds":{"left":0.0,"top":0.42430556,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"CloudWatch | us-east-2","depth":5,"bounds":{"left":0.015625,"top":0.4340278,"width":0.0484375,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Meet - Daily - Platform","depth":4,"bounds":{"left":0.0,"top":0.45277777,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Meet - Daily - Platform","depth":5,"bounds":{"left":0.015625,"top":0.4625,"width":0.046484374,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.07890625,"top":0.45902777,"width":0.009375,"height":0.016666668},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Settings","depth":4,"bounds":{"left":0.0,"top":0.48125,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Settings","depth":5,"bounds":{"left":0.015625,"top":0.49097222,"width":0.016796876,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"New Tab","depth":4,"bounds":{"left":0.003125,"top":0.51111114,"width":0.08710937,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.003125,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Close Google Gemini (⌃X)","depth":6,"bounds":{"left":0.01640625,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"bounds":{"left":0.029296875,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"bounds":{"left":0.0421875,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"bounds":{"left":0.05546875,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"AI Chat settings","depth":7,"bounds":{"left":0.2171875,"top":0.047916666,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Close","depth":7,"bounds":{"left":0.23125,"top":0.047916666,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"WORK, Google Account: lukas.kovalik@jiminny.com","depth":12,"bounds":{"left":0.228125,"top":0.090277776,"width":0.015625,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Main menu","depth":12,"bounds":{"left":0.0984375,"top":0.090277776,"width":0.015625,"height":0.027777778},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Chat","depth":12,"bounds":{"left":0.1953125,"top":0.090277776,"width":0.015625,"height":0.027777778},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Open menu for conversation actions.","depth":12,"bounds":{"left":0.2109375,"top":0.090277776,"width":0.015625,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXHeading","text":"Conversation with Gemini","depth":15,"bounds":{"left":0.09335937,"top":0.12847222,"width":0.000390625,"height":0.00069444446},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Conversation with Gemini","depth":16,"bounds":{"left":0.09335937,"top":0.13055556,"width":0.14101562,"height":0.022222223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Copy prompt","depth":21,"bounds":{"left":0.1203125,"top":0.15972222,"width":0.015625,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Edit","depth":21,"bounds":{"left":0.1375,"top":0.15972222,"width":0.015625,"height":0.027777778},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"You said why I can't see speaker data on meemt in firefox. ho wto set it up","depth":21,"bounds":{"left":0.1609375,"top":0.16805555,"width":0.072265625,"height":0.058333334},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"You said","depth":23,"bounds":{"left":0.09335937,"top":0.1701389,"width":0.0234375,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"why I can't see speaker data on meemt in firefox. ho wto set it up","depth":23,"bounds":{"left":0.1609375,"top":0.17083333,"width":0.07070313,"height":0.05347222},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Listen","depth":22,"bounds":{"left":0.22382812,"top":0.25416666,"width":0.015625,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Show more options","depth":20,"bounds":{"left":0.22382812,"top":0.24930556,"width":0.015625,"height":0.027777778},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Show thinking","depth":26,"bounds":{"left":0.11953125,"top":0.25625,"width":0.036328126,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Gemini said","depth":20,"bounds":{"left":0.11679687,"top":0.2923611,"width":0.000390625,"height":0.00069444446},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Gemini said","depth":21,"bounds":{"left":0.11679687,"top":0.29375,"width":0.048046876,"height":0.016666668},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Dealing with missing features right when you need them is incredibly frustrating. Assuming \"meemt\" means Google Meet, the reason you can't see your speaker data comes down to how Firefox interacts with Google's platform compared to Chrome.","depth":24,"bounds":{"left":0.10390625,"top":0.30069444,"width":0.13046876,"height":0.10486111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Since \"speaker data\" can mean a couple of different things in a meeting, here are the two most likely causes for your issue and exactly how to get things working.","depth":24,"bounds":{"left":0.10390625,"top":0.4201389,"width":0.13125,"height":0.06875},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"1. You Need \"Speaker Notes\" for Google Slides","depth":23,"bounds":{"left":0.10390625,"top":0.52152777,"width":0.13242188,"height":0.033333335},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1. You Need \"Speaker Notes\" for Google Slides","depth":24,"bounds":{"left":0.10390625,"top":0.5229167,"width":0.12070312,"height":0.03125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"The Reality:","depth":24,"bounds":{"left":0.10390625,"top":0.5625,"width":0.036328126,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Google Meet has a native feature that lets you see your presentation's speaker notes right inside the video call interface.","depth":24,"bounds":{"left":0.10390625,"top":0.5625,"width":0.13242188,"height":0.050694443},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"However, this relies on a specific \"Present a Tab\" technology built exclusively for Google Chrome. Firefox handles screen sharing differently, so that native integration simply won't load.","depth":24,"bounds":{"left":0.10390625,"top":0.5986111,"width":0.12539062,"height":0.10486111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"View source details for citation from Google Workspace Updates. Opens side panel.","depth":24,"bounds":{"left":0.13710937,"top":0.68958336,"width":0.01015625,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"How to set it up (The Firefox Workaround):","depth":24,"bounds":{"left":0.10390625,"top":0.71805555,"width":0.12851563,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"You can still present and read your notes in Firefox by manually managing your windows.","depth":24,"bounds":{"left":0.10390625,"top":0.7361111,"width":0.12617187,"height":0.03263889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Open your Google Slides presentation in a standard Firefox window.","depth":26,"bounds":{"left":0.11796875,"top":0.7777778,"width":0.115625,"height":0.03263889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Click the dropdown arrow next to the","depth":26,"bounds":{"left":0.11796875,"top":0.8194444,"width":0.10703125,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Slideshow","depth":26,"bounds":{"left":0.11796875,"top":0.8375,"width":0.03125,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"button in the top right corner.","depth":26,"bounds":{"left":0.14921875,"top":0.8375,"width":0.08515625,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Select","depth":26,"bounds":{"left":0.11796875,"top":0.8611111,"width":0.01953125,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Presenter view","depth":26,"bounds":{"left":0.1375,"top":0.8611111,"width":0.0453125,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"to pop your speaker notes out into a separate, smaller window.","depth":26,"bounds":{"left":0.11796875,"top":0.8611111,"width":0.10078125,"height":0.050694443},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"View source details for citation from Skywork. Opens side panel.","depth":26,"bounds":{"left":0.16523437,"top":0.8979167,"width":0.01015625,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Join your Google Meet in a different Firefox window.","depth":26,"bounds":{"left":0.11796875,"top":0.92083335,"width":0.103125,"height":0.03263889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Click","depth":26,"bounds":{"left":0.11796875,"top":0.9625,"width":0.015234375,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Present now","depth":26,"bounds":{"left":0.13320312,"top":0.9625,"width":0.037890624,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"and choose the","depth":26,"bounds":{"left":0.17109375,"top":0.9625,"width":0.047265626,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Window","depth":26,"bounds":{"left":0.11796875,"top":0.98055553,"width":0.02421875,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"option.","depth":26,"bounds":{"left":0.1421875,"top":0.98055553,"width":0.02109375,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Select the window displaying your main slides (do not select your separate speaker notes window).","depth":26,"bounds":{"left":0.11796875,"top":1.0,"width":0.11328125,"height":-0.0041667223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Resize your windows on your monitor so you can comfortably read the notes window while keeping an eye on the Meet window.","depth":26,"bounds":{"left":0.11796875,"top":1.0,"width":0.11835937,"height":-0.06388891},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"2. You Need \"Speaker Labels\" or Transcripts","depth":23,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2. You Need \"Speaker Labels\" or Transcripts","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"The Reality:","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"If you are trying to use a third-party AI note-taker (like Otter.ai, Tactiq, or tl;dv) to capture transcriptions and see who is speaking, Firefox is likely the roadblock. Firefox has strict privacy guardrails that prevent extensions from capturing internal browser audio easily, so most developers only build these tools for Chrome.","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"How to set it up:","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Turn on built-in captions:","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Google Meet has its own live captions that natively identify who is speaking, even in Firefox. Click the","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"CC","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"button at the bottom of your Meet screen to toggle them on.","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Search for a Firefox add-on:","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Check the Mozilla Add-ons store to see if your preferred tool actually has a supported Firefox version (for example, Fellow.ai offers one).","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"View source details for citation from Fellow.ai. Opens side panel.","depth":26,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Switch browsers temporarily:","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"If your specific transcription tool is explicitly Chrome-only, you will unfortunately need to join that specific meeting using a Chromium-based browser like Chrome, Edge, or Brave to capture the data.","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Using Meet's built-in closed captions or the manual Presenter view workaround will get your speaker data back on track without forcing you to completely abandon Firefox.","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Sources","depth":23,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Sources","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextArea","text":"I men in dia (arc) I can see my headphones in both microphone and speakers","depth":20,"bounds":{"left":0.109375,"top":0.8020833,"width":0.125,"height":0.05},"value":"I men in dia (arc) I can see my headphones in both microphone and speakers","help_text":"","role_description":"text entry area","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"I men in dia (arc) I can see my headphones in both microphone and speakers","depth":22,"bounds":{"left":0.109375,"top":0.8034722,"width":0.10625,"height":0.047916666},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open upload file menu","depth":20,"bounds":{"left":0.1046875,"top":0.86527777,"width":0.015625,"height":0.027777778},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Tools","depth":18,"bounds":{"left":0.1234375,"top":0.86527777,"width":0.015625,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Open mode picker","depth":20,"bounds":{"left":0.190625,"top":0.8645833,"width":0.03046875,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pro","depth":23,"bounds":{"left":0.196875,"top":0.87222224,"width":0.00859375,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Send message","depth":19,"bounds":{"left":0.22265625,"top":0.86388886,"width":0.01640625,"height":0.029166667},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Your Jiminny chats aren’t used to improve our models. Gemini is AI and can make mistakes, including about people.","depth":17,"bounds":{"left":0.10039063,"top":0.9097222,"width":0.14296874,"height":0.022222223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Your privacy & Gemini Opens in a new window","depth":17,"bounds":{"left":0.1484375,"top":0.93194443,"width":0.046875,"height":0.011111111},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Your privacy & Gemini","depth":18,"bounds":{"left":0.1484375,"top":0.93194443,"width":0.046875,"height":0.011111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Opens in a new window","depth":19,"bounds":{"left":0.09335937,"top":0.93125,"width":0.05078125,"height":0.011111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Summarize page","depth":7,"bounds":{"left":0.1,"top":0.96319443,"width":0.06289063,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Summarize page","depth":9,"bounds":{"left":0.10664062,"top":0.9673611,"width":0.049609374,"height":0.013888889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Backgrounds and effects","depth":11,"bounds":{"left":0.3921875,"top":0.28958333,"width":0.46289062,"height":0.055555556},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Backgrounds and effects","depth":12,"bounds":{"left":0.4015625,"top":0.30694443,"width":0.10546875,"height":0.021527778},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Turn off visual effects","depth":14,"bounds":{"left":0.675,"top":0.59652776,"width":0.021875,"height":0.03888889},"role_description":"button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Back","depth":15,"bounds":{"left":0.7109375,"top":0.34513888,"width":0.015625,"height":0.027777778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Generate a background","depth":14,"bounds":{"left":0.7265625,"top":0.35,"width":0.08710937,"height":0.018055556},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXComboBox","text":"No scene","depth":15,"bounds":{"left":0.715625,"top":0.38125,"width":0.12539062,"height":0.03888889},"value":"No scene","help_text":"","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"No scene","depth":17,"bounds":{"left":0.740625,"top":0.39375,"width":0.0265625,"height":0.014583333},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextArea","text":"Acropolic propylaea","depth":16,"bounds":{"left":0.715625,"top":0.44236112,"width":0.12539062,"height":0.06666667},"value":"Acropolic propylaea","help_text":"","placeholder":"Jungle patio at sunset","role_description":"text entry area","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Create other samples","depth":16,"bounds":{"left":0.7410156,"top":0.53402776,"width":0.07460938,"height":0.025},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":true,"is_selected":false},{"role":"AXStaticText","text":"Create other samples","depth":18,"bounds":{"left":0.75039065,"top":0.5402778,"width":0.055859376,"height":0.013194445},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"You can generate more results or change your description to get different results","depth":16,"bounds":{"left":0.72734374,"top":0.5715278,"width":0.10195313,"height":0.022222223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Learn more about generating backgrounds","depth":16,"bounds":{"left":0.7308594,"top":0.59375,"width":0.09492187,"height":0.011111111},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Learn more about generating backgrounds","depth":17,"bounds":{"left":0.7308594,"top":0.59375,"width":0.09492187,"height":0.011111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Use this background","depth":16,"bounds":{"left":0.72148436,"top":0.61319447,"width":0.1140625,"height":0.12638889},"role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Report a legal issue","depth":16,"bounds":{"left":0.72148436,"top":0.75069445,"width":0.04296875,"height":0.011111111},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Report a legal issue","depth":17,"bounds":{"left":0.72148436,"top":0.75069445,"width":0.04296875,"height":0.011111111},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close","depth":11,"bounds":{"left":0.83320314,"top":0.30069444,"width":0.01875,"height":0.033333335},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Samples have been created","depth":8,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
-6705365528007953525
|
8729401742846049358
|
visual_change
|
accessibility
|
NULL
|
JY-20543 add AJ reports User pilot tracking by Lak JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 1 Q2 - Platform Team - Scrum Board - Jira
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
Console Home | Console Home | us-east-2
Console Home | Console Home | us-east-2
SecurityGroup | EC2 | us-east-2
SecurityGroup | EC2 | us-east-2
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app
SRD-6779 | JY-20632 | Unable to log in to Sidekick with SSO by yalokin-jiminny · Pull Request #11935 · jiminny/app
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Jy 19798 evaluation for ai activity types by nikolaybiaivanov · Pull Request #468 · jiminny/prophet
Jiminny
Jiminny
Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf
Ask Jiminny test report - 8 Apr 2026 - Ask Jiminny test report - 13 Apr 2026.pdf
Service-Desk - Queues - Platform team - Service space - Jira
Service-Desk - Queues - Platform team - Service space - Jira
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
JY-20543 add AJ reports User pilot tracking by LakyLak · Pull Request #11932 · jiminny/app
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
CloudWatch | us-east-2
CloudWatch | us-east-2
Meet - Daily - Platform
Meet - Daily - Platform
Close tab
Settings
Settings
New Tab
Customize sidebar
Close Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
AI Chat settings
Close
WORK, Google Account: [EMAIL]
Main menu
New Chat
Open menu for conversation actions.
Conversation with Gemini
Conversation with Gemini
Copy prompt
Edit
You said why I can't see speaker data on meemt in firefox. ho wto set it up
You said
why I can't see speaker data on meemt in firefox. ho wto set it up
Listen
Show more options
Show thinking
Gemini said
Gemini said
Dealing with missing features right when you need them is incredibly frustrating. Assuming "meemt" means Google Meet, the reason you can't see your speaker data comes down to how Firefox interacts with Google's platform compared to Chrome.
Since "speaker data" can mean a couple of different things in a meeting, here are the two most likely causes for your issue and exactly how to get things working.
1. You Need "Speaker Notes" for Google Slides
1. You Need "Speaker Notes" for Google Slides
The Reality:
Google Meet has a native feature that lets you see your presentation's speaker notes right inside the video call interface.
However, this relies on a specific "Present a Tab" technology built exclusively for Google Chrome. Firefox handles screen sharing differently, so that native integration simply won't load.
View source details for citation from Google Workspace Updates. Opens side panel.
How to set it up (The Firefox Workaround):
You can still present and read your notes in Firefox by manually managing your windows.
Open your Google Slides presentation in a standard Firefox window.
Click the dropdown arrow next to the
Slideshow
button in the top right corner.
Select
Presenter view
to pop your speaker notes out into a separate, smaller window.
View source details for citation from Skywork. Opens side panel.
Join your Google Meet in a different Firefox window.
Click
Present now
and choose the
Window
option.
Select the window displaying your main slides (do not select your separate speaker notes window).
Resize your windows on your monitor so you can comfortably read the notes window while keeping an eye on the Meet window.
2. You Need "Speaker Labels" or Transcripts
2. You Need "Speaker Labels" or Transcripts
The Reality:
If you are trying to use a third-party AI note-taker (like Otter.ai, Tactiq, or tl;dv) to capture transcriptions and see who is speaking, Firefox is likely the roadblock. Firefox has strict privacy guardrails that prevent extensions from capturing internal browser audio easily, so most developers only build these tools for Chrome.
How to set it up:
Turn on built-in captions:
Google Meet has its own live captions that natively identify who is speaking, even in Firefox. Click the
CC
button at the bottom of your Meet screen to toggle them on.
Search for a Firefox add-on:
Check the Mozilla Add-ons store to see if your preferred tool actually has a supported Firefox version (for example, Fellow.ai offers one).
View source details for citation from Fellow.ai. Opens side panel.
Switch browsers temporarily:
If your specific transcription tool is explicitly Chrome-only, you will unfortunately need to join that specific meeting using a Chromium-based browser like Chrome, Edge, or Brave to capture the data.
Using Meet's built-in closed captions or the manual Presenter view workaround will get your speaker data back on track without forcing you to completely abandon Firefox.
Sources
Sources
I men in dia (arc) I can see my headphones in both microphone and speakers
I men in dia (arc) I can see my headphones in both microphone and speakers
Open upload file menu
Tools
Open mode picker
Pro
Send message
Your Jiminny chats aren’t used to improve our models. Gemini is AI and can make mistakes, including about people.
Your privacy & Gemini Opens in a new window
Your privacy & Gemini
Opens in a new window
Summarize page
Summarize page
Backgrounds and effects
Backgrounds and effects
Turn off visual effects
Back
Generate a background
No scene
No scene
Acropolic propylaea
Create other samples
Create other samples
You can generate more results or change your description to get different results
Learn more about generating backgrounds
Learn more about generating backgrounds
Use this background
Report a legal issue
Report a legal issue
Close
Samples have been created...
|
NULL
|
|
9467
|
183
|
17
|
2026-04-14T07:39:49.479483+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776152389479_m2.jpg...
|
PhpStorm
|
faVsco.js – AutomatedReportsCommand.php
|
True
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
#11894 on JY-18909-automa Project: faVsco.js, menu
#11894 on JY-18909-automated-reports-ask-jiminny, menu
Start Listening for PHP Debug Connections
RequestGenerateAskJiminnyReportJobTest
Run 'RequestGenerateAskJiminnyReportJobTest'
Debug 'RequestGenerateAskJiminnyReportJobTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Console\Commands\Reports;
use Carbon\Carbon;
use Illuminate\Console\Command;
use Illuminate\Contracts\Bus\Dispatcher as BusDispatcher;
use Jiminny\Jobs\AutomatedReports\RequestGenerateAskJiminnyReportJob;
use Jiminny\Jobs\AutomatedReports\RequestGenerateReportJob;
use Jiminny\Models\AutomatedReport;
use Jiminny\Repositories\AutomatedReportsRepository;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Psr\Log\LoggerInterface;
class AutomatedReportsCommand extends Command
{
/**
* Log prefix for all log messages
*/
private const string LOG_PREFIX = '[automated-reports]';
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'automated-reports';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Process automated reports based on their frequency (weekly, monthly, quarterly)';
public function __construct(
private readonly LoggerInterface $logger,
private readonly BusDispatcher $dispatcher,
private readonly AutomatedReportsRepository $reportRepository
) {
parent::__construct();
}
/**
* Execute the console command.
*
* @return int
*/
public function handle(): int
{
$this->logger->info(self::LOG_PREFIX . ' Started');
$now = Carbon::now();
$isMonday = $now->isMonday();
$isFirstDayOfMonth = $now->day === 1;
$currentMonth = $now->month;
// Check if the current month is a quarterly month (January, April, July, October)
$isQuarterlyMonth = in_array($currentMonth, [1, 4, 7, 10], true);
$this->logger->info(self::LOG_PREFIX . ' Checking conditions', [
'isMonday' => $isMonday,
'isFirstDayOfMonth' => $isFirstDayOfMonth,
'currentMonth' => $currentMonth,
'isQuarterlyMonth' => $isQuarterlyMonth,
]);
// Process daily reports
$this->processReports(AutomatedReportsService::FREQUENCY_DAILY);
// Process weekly reports on Mondays
if ($isMonday) {
$this->processReports(AutomatedReportsService::FREQUENCY_WEEKLY);
}
// Process monthly reports on the first day of the month
if ($isFirstDayOfMonth) {
$this->processReports(AutomatedReportsService::FREQUENCY_MONTHLY);
}
// Process quarterly reports on the first day of January, April, July, and October
if ($isFirstDayOfMonth && $isQuarterlyMonth) {
$this->processReports(AutomatedReportsService::FREQUENCY_QUARTERLY);
}
$this->logger->info(self::LOG_PREFIX . ' Completed');
return 0;
}
/**
* Process reports for a specific frequency.
*
* @param string $frequency
*
* @return void
*/
private function processReports(string $frequency): void
{
$this->logger->info(self::LOG_PREFIX . " Processing $frequency reports");
// Get all enabled, not deleted reports with active teams for the specified frequency
$reports = $this->reportRepository->getActiveReportsByFrequency($frequency);
// $reports = collect([AutomatedReport::find(68)]);
$this->logger->info(self::LOG_PREFIX . " Found {$reports->count()} $frequency reports to process");
/** @var AutomatedReport $report */
foreach ($reports as $report) {
$this->logger->info(self::LOG_PREFIX . ' Dispatching Generate Report job for report', [
'reportUuid' => $report->getUuid(),
'teamId' => $report->getTeamId(),
'frequency' => $report->getFrequency(),
'type' => $report->getType(),
]);
$job = $report->isAskJiminnyReport()
? new RequestGenerateAskJiminnyReportJob($report->getUuid())
: new RequestGenerateReportJob($report->getUuid());
// $this->dispatcher->dispatch($job);
$this->dispatcher->dispatchSync($job);
}
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
1
14
4
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Tests\Unit\Jobs\AutomatedReports;
use Carbon\Carbon;
use Jiminny\Component\ProphetAi\Exceptions\ProphetException;
use Jiminny\Component\ProphetAi\ProphetClient;
use Jiminny\Jobs\AutomatedReports\RequestGenerateAskJiminnyReportJob;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\AutomatedReportResult;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityService;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
use Psr\Log\LoggerInterface;
class RequestGenerateAskJiminnyReportJobTest extends TestCase
{
private AutomatedReportsService&MockObject $reportService;
private AskJiminnyReportActivityService&MockObject $activityService;
private ProphetClient&MockObject $prophetClient;
private LoggerInterface&MockObject $logger;
protected function setUp(): void
{
$this->reportService = $this->createMock(AutomatedReportsService::class);
$this->activityService = $this->createMock(AskJiminnyReportActivityService::class);
$this->prophetClient = $this->createMock(ProphetClient::class);
$this->logger = $this->createMock(LoggerInterface::class);
}
private function makeJob(string $uuid = 'report-uuid'): RequestGenerateAskJiminnyReportJob
{
return new RequestGenerateAskJiminnyReportJob($uuid);
}
private function makeActiveReport(
string $type = AutomatedReportsService::TYPE_ASK_JIMINNY,
bool $status = true,
string $teamStatus = Team::STATUS_ACTIVE,
): AutomatedReport&MockObject { // @phpstan-ignore-line
$team = $this->createMock(Team::class);
$team->method('getStatus')->willReturn($teamStatus);
$report = $this->createMock(AutomatedReport::class);
$report->method('getType')->willReturn($type);
$report->method('getStatus')->willReturn($status);
$report->method('getTeam')->willReturn($team);
return $report;
}
public function testUniqueIdReturnsReportUuid(): void
{
$job = $this->makeJob('my-unique-uuid');
$this->assertEquals('my-unique-uuid', $job->uniqueId());
}
public function testHandleSkipsWhenReportTypeIsNotAskJiminny(): void
{
$report = $this->makeActiveReport(type: 'exec_summary');
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->logger->expects($this->once())
->method('info')
->with($this->stringContains('Started'));
$this->logger->expects($this->once())
->method('warning')
->with($this->stringContains('not an ask_jiminny report'));
$this->reportService->expects($this->never())->method('createReportResult');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleSkipsWhenReportIsInactive(): void
{
$report = $this->makeActiveReport(status: false);
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->logger->expects($this->exactly(2))
->method('info');
$this->reportService->expects($this->never())->method('createReportResult');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleSkipsWhenTeamIsInactive(): void
{
$report = $this->makeActiveReport(teamStatus: Team::STATUS_DEACTIVATED);
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->logger->expects($this->exactly(2))
->method('info');
$this->reportService->expects($this->never())->method('createReportResult');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleSkipsWhenCreatorIsNull(): void
{
$report = $this->makeActiveReport();
$report->method('getCreator')->willReturn(null);
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->logger->expects($this->once())
->method('warning')
->with($this->stringContains('report creator not found'));
$this->reportService->expects($this->never())->method('createReportResult');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleSkipsWhenSavedSearchIsNull(): void
{
$creator = $this->createMock(User::class);
$report = $this->makeActiveReport();
$report->method('getCreator')->willReturn($creator);
$report->method('getSavedSearch')->willReturn(null);
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->logger->expects($this->once())
->method('warning')
->with($this->stringContains('saved search not found'));
$this->reportService->expects($this->never())->method('createReportResult');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleSkipsWhenPromptIsNull(): void
{
$creator = $this->createMock(User::class);
$savedSearch = $this->createMock(\Jiminny\Models\Activity\Search::class);
$report = $this->makeActiveReport();
$report->method('getCreator')->willReturn($creator);
$report->method('getSavedSearch')->willReturn($savedSearch);
$report->method('getAskAnythingPrompt')->willReturn(null);
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->logger->expects($this->once())
->method('warning')
->with($this->stringContains('ask anything prompt not found'));
$this->reportService->expects($this->never())->method('createReportResult');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleFailsReportWhenNotEnoughActivities(): void
{
$creator = $this->createMock(User::class);
$savedSearch = $this->createMock(\Jiminny\Models\Activity\Search::class);
$prompt = $this->createMock(\Jiminny\Models\AskAnything\AskAnythingPrompt::class);
$report = $this->makeActiveReport();
$report->method('getCreator')->willReturn($creator);
$report->method('getSavedSearch')->willReturn($savedSearch);
$report->method('getAskAnythingPrompt')->willReturn($prompt);
$reportResult = $this->createMock(AutomatedReportResult::class);
$reportResult->expects($this->once())
->method('update')
->with($this->callback(fn ($data) => $data['status'] === AutomatedReportResult::STATUS_FAILED
&& $data['reason'] === AutomatedReportResult::REASON_NOT_ENOUGH_ACTIVITIES));
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->reportService->expects($this->once())
->method('createReportResult')
->willReturn($reportResult);
$this->activityService->expects($this->once())
->method('getActivityIdsForSavedSearch')
->willReturn([]);
$this->logger->expects($this->exactly(3))
->method('info');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleSuccessfullyRequestsReport(): void
{
Carbon::setTestNow(Carbon::parse('2026-04-07 10:00:00'));
$creator = $this->createMock(User::class);
$savedSearch = $this->createMock(\Jiminny\Models\Activity\Search::class);
$prompt = $this->createMock(\Jiminny\Models\AskAnything\AskAnythingPrompt::class);
$report = $this->makeActiveReport();
$report->method('getCreator')->willReturn($creator);
$report->method('getSavedSearch')->willReturn($savedSearch);
$report->method('getAskAnythingPrompt')->willReturn($prompt);
$report->method('getUuid')->willReturn('report-uuid');
$reportResult = $this->createMock(AutomatedReportResult::class);
$reportResult->method('getUuid')->willReturn('result-uuid');
$reportResult->expects($this->once())
->method('update')
->with($this->callback(fn ($data) => $data['status'] === AutomatedReportResult::STATUS_REQUESTED
&& isset($data['name'], $data['payload'], $data['requested_at'])));
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->reportService->expects($this->once())
->method('createReportResult')
->willReturn($reportResult);
$this->reportService->expects($this->once())
->method('getAskJiminnyGenerateReportPayload')
->willReturn(['key' => 'value']);
$this->reportService->expects($this->once())
->method('getReportFileName')
->willReturn('My Report - 7 Apr 2026');
$this->activityService->expects($this->once())
->method('getActivityIdsForSavedSearch')
->willReturn(['act-1', 'act-2']);
$this->prophetClient->expects($this->once())
->method('sendRequest')
->willReturn(new \Jiminny\Component\ProphetAi\Dtos\ProphetResponseDto([]));
$this->logger->expects($this->exactly(4))
->method('info');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
Carbon::setTestNow();
}
public function testHandleCatchesGenericExceptionAndLogsError(): void
{
$this->reportService->expects($this->once())
->method('getReport')
->willThrowException(new \RuntimeException('DB error'));
$this->logger->expects($this->once())
->method('error')
->with($this->stringContains('Error'));
$job = $this->makeJob();
$reflection = new \ReflectionClass($job);
$triesProp = $reflection->getProperty('tries');
$triesProp->setAccessible(true);
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleCatchesProphetExceptionAndSetsCorrectReason(): void
{
$creator = $this->createMock(User::class);
$savedSearch = $this->createMock(\Jiminny\Models\Activity\Search::class);
$prompt = $this->createMock(\Jiminny\Models\AskAnything\AskAnythingPrompt::class);
$report = $this->makeActiveReport();
$report->method('getCreator')->willReturn($creator);
$report->method('getSavedSearch')->willReturn($savedSearch);
$report->method('getAskAnythingPrompt')->willReturn($prompt);
$reportResult = $this->createMock(AutomatedReportResult::class);
$reportResult->method('getUuid')->willReturn('result-uuid');
$reportResult->expects($this->once())
->method('update')
->with($this->callback(fn ($data) => $data['reason'] === AutomatedReportResult::REASON_PROPHET_API_ERROR));
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->reportService->expects($this->once())
->method('createReportResult')
->willReturn($reportResult);
$this->activityService->expects($this->once())
->method('getActivityIdsForSavedSearch')
->willThrowException(new ProphetException('Prophet failed'));
$this->logger->expects($this->once())
->method('error');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleCreatesReportResultBeforeActivityFetch(): void
{
$creator = $this->createMock(User::class);
$savedSearch = $this->createMock(\Jiminny\Models\Activity\Search::class);
$prompt = $this->createMock(\Jiminny\Models\AskAnything\AskAnythingPrompt::class);
$report = $this->makeActiveReport();
$report->method('getCreator')->willReturn($creator);
$report->method('getSavedSearch')->willReturn($savedSearch);
$report->method('getAskAnythingPrompt')->willReturn($prompt);
$reportResult = $this->createMock(AutomatedReportResult::class);
$reportResult->method('getUuid')->willReturn('result-uuid');
$callOrder = [];
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->reportService->expects($this->once())
->method('createReportResult')
->willReturnCallback(function () use ($reportResult, &$callOrder) {
$callOrder[] = 'createReportResult';
return $reportResult;
});
$this->activityService->expects($this->once())
->method('getActivityIdsForSavedSearch')
->willReturnCallback(function () use (&$callOrder) {
$callOrder[] = 'getActivityIds';
return [];
});
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
$this->assertEquals(['createReportResult', 'getActivityIds'], $callOrder);
}
public function testHandlePassesCorrectDataToCreateReportResult(): void
{
$creator = $this->createMock(User::class);
$savedSearch = $this->createMock(\Jiminny\Models\Activity\Search::class);
$prompt = $this->createMock(\Jiminny\Models\AskAnything\AskAnythingPrompt::class);
$report = $this->makeActiveReport();
$report->method('getCreator')->willReturn($creator);
$report->method('getSavedSearch')->willReturn($savedSearch);
$report->method('getAskAnythingPrompt')->willReturn($prompt);
$reportResult = $this->createMock(AutomatedReportResult::class);
$reportResult->method('getUuid')->willReturn('result-uuid');
$reportResult->method('update')->willReturn(true);
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->reportService->expects($this->once())
->method('createReportResult')
->with(
automatedReport: $report,
data: $this->callback(fn ($data) => $data['status'] === AutomatedReportResult::STATUS_DEFAULT
&& $data['media_type'] === AutomatedReportsService::MEDIA_TYPE_PDF)
)
->willReturn($reportResult);
$this->activityService->expects($this->once())
->method('getActivityIdsForSavedSearch')
->willReturn([]);
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide
app ~/jiminny/app
.circleci
.cursor
.github
.sonarlint
.vscode
.windsurf
app, sources root
Actions
Component
Configuration
Console
Commands
Activities
Analytics
Calendars
Crm
DealInsights
Dev
Dialers
DTOs
Elasticsearch
EngagementStats
GeckoExport
Livestream
Mailboxes
Migrate
PlaybackThemes
Playbooks
Playlists
Postmark
ProphetAi
Reports
AutomatedReportsCommand.php, class
AutomatedReportsRetentionPolicyCommand.php, class
AutomatedReportsSendCommand.php, class
CreateMockAskJiminnyReportResultCommand.php, class
DeleteReportCommand.php, class
GenerateMarketingReport.php, class
Team.php, class
Usage.php, class
Slack
Teams
Tracks
Transcription
Twilio
Users
Vocabulary
Zoom
CoachingFeedbacksUpdateEsActivities.php, class
Command.php, class
CreateDatabaseUsers.php, class
DatabaseTableCount.php, class
DeleteOldAiCrmNotesCommand.php, class
DeleteS3LeftoversCommand.php, class
DevPostmanCommand.php, final class
DiarizeViaAiParticipantIdentificationCommand.php, class
EncryptTokensCommand.php, class
EngagementStatsRegenerateCommand.php, class
FeatureFlagsHelper.php...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.03046875,"top":0.017361112,"width":0.0453125,"height":0.022222223},"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"#11894 on JY-18909-automated-reports-ask-jiminny, menu","depth":5,"bounds":{"left":0.07578125,"top":0.017361112,"width":0.14960937,"height":0.022222223},"help_text":"Pull request #11894 exists for current branch JY-18909-automated-reports-ask-jiminny, but local branch is out of sync with remote","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.76171875,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"RequestGenerateAskJiminnyReportJobTest","depth":6,"bounds":{"left":0.7796875,"top":0.017361112,"width":0.12109375,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'RequestGenerateAskJiminnyReportJobTest'","depth":6,"bounds":{"left":0.9007813,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'RequestGenerateAskJiminnyReportJobTest'","depth":6,"bounds":{"left":0.9140625,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9273437,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96015626,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9734375,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9867188,"top":0.017361112,"width":0.013281226,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.049609374,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Console\\Commands\\Reports;\n\nuse Carbon\\Carbon;\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Contracts\\Bus\\Dispatcher as BusDispatcher;\nuse Jiminny\\Jobs\\AutomatedReports\\RequestGenerateAskJiminnyReportJob;\nuse Jiminny\\Jobs\\AutomatedReports\\RequestGenerateReportJob;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Repositories\\AutomatedReportsRepository;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Psr\\Log\\LoggerInterface;\n\nclass AutomatedReportsCommand extends Command\n{\n /**\n * Log prefix for all log messages\n */\n private const string LOG_PREFIX = '[automated-reports]';\n\n /**\n * The name and signature of the console command.\n *\n * @var string\n */\n protected $signature = 'automated-reports';\n\n /**\n * The console command description.\n *\n * @var string\n */\n protected $description = 'Process automated reports based on their frequency (weekly, monthly, quarterly)';\n\n\n public function __construct(\n private readonly LoggerInterface $logger,\n private readonly BusDispatcher $dispatcher,\n private readonly AutomatedReportsRepository $reportRepository\n ) {\n parent::__construct();\n }\n\n /**\n * Execute the console command.\n *\n * @return int\n */\n public function handle(): int\n {\n $this->logger->info(self::LOG_PREFIX . ' Started');\n\n $now = Carbon::now();\n $isMonday = $now->isMonday();\n $isFirstDayOfMonth = $now->day === 1;\n $currentMonth = $now->month;\n\n // Check if the current month is a quarterly month (January, April, July, October)\n $isQuarterlyMonth = in_array($currentMonth, [1, 4, 7, 10], true);\n\n $this->logger->info(self::LOG_PREFIX . ' Checking conditions', [\n 'isMonday' => $isMonday,\n 'isFirstDayOfMonth' => $isFirstDayOfMonth,\n 'currentMonth' => $currentMonth,\n 'isQuarterlyMonth' => $isQuarterlyMonth,\n ]);\n\n // Process daily reports\n $this->processReports(AutomatedReportsService::FREQUENCY_DAILY);\n\n // Process weekly reports on Mondays\n if ($isMonday) {\n $this->processReports(AutomatedReportsService::FREQUENCY_WEEKLY);\n }\n\n // Process monthly reports on the first day of the month\n if ($isFirstDayOfMonth) {\n $this->processReports(AutomatedReportsService::FREQUENCY_MONTHLY);\n }\n\n // Process quarterly reports on the first day of January, April, July, and October\n if ($isFirstDayOfMonth && $isQuarterlyMonth) {\n $this->processReports(AutomatedReportsService::FREQUENCY_QUARTERLY);\n }\n\n $this->logger->info(self::LOG_PREFIX . ' Completed');\n\n return 0;\n }\n\n /**\n * Process reports for a specific frequency.\n *\n * @param string $frequency\n *\n * @return void\n */\n private function processReports(string $frequency): void\n {\n $this->logger->info(self::LOG_PREFIX . \" Processing $frequency reports\");\n\n // Get all enabled, not deleted reports with active teams for the specified frequency\n $reports = $this->reportRepository->getActiveReportsByFrequency($frequency);\n // $reports = collect([AutomatedReport::find(68)]);\n\n $this->logger->info(self::LOG_PREFIX . \" Found {$reports->count()} $frequency reports to process\");\n\n /** @var AutomatedReport $report */\n foreach ($reports as $report) {\n $this->logger->info(self::LOG_PREFIX . ' Dispatching Generate Report job for report', [\n 'reportUuid' => $report->getUuid(),\n 'teamId' => $report->getTeamId(),\n 'frequency' => $report->getFrequency(),\n 'type' => $report->getType(),\n ]);\n\n $job = $report->isAskJiminnyReport()\n ? new RequestGenerateAskJiminnyReportJob($report->getUuid())\n : new RequestGenerateReportJob($report->getUuid());\n\n // $this->dispatcher->dispatch($job);\n $this->dispatcher->dispatchSync($job);\n }\n }\n}","depth":4,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Console\\Commands\\Reports;\n\nuse Carbon\\Carbon;\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Contracts\\Bus\\Dispatcher as BusDispatcher;\nuse Jiminny\\Jobs\\AutomatedReports\\RequestGenerateAskJiminnyReportJob;\nuse Jiminny\\Jobs\\AutomatedReports\\RequestGenerateReportJob;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Repositories\\AutomatedReportsRepository;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Psr\\Log\\LoggerInterface;\n\nclass AutomatedReportsCommand extends Command\n{\n /**\n * Log prefix for all log messages\n */\n private const string LOG_PREFIX = '[automated-reports]';\n\n /**\n * The name and signature of the console command.\n *\n * @var string\n */\n protected $signature = 'automated-reports';\n\n /**\n * The console command description.\n *\n * @var string\n */\n protected $description = 'Process automated reports based on their frequency (weekly, monthly, quarterly)';\n\n\n public function __construct(\n private readonly LoggerInterface $logger,\n private readonly BusDispatcher $dispatcher,\n private readonly AutomatedReportsRepository $reportRepository\n ) {\n parent::__construct();\n }\n\n /**\n * Execute the console command.\n *\n * @return int\n */\n public function handle(): int\n {\n $this->logger->info(self::LOG_PREFIX . ' Started');\n\n $now = Carbon::now();\n $isMonday = $now->isMonday();\n $isFirstDayOfMonth = $now->day === 1;\n $currentMonth = $now->month;\n\n // Check if the current month is a quarterly month (January, April, July, October)\n $isQuarterlyMonth = in_array($currentMonth, [1, 4, 7, 10], true);\n\n $this->logger->info(self::LOG_PREFIX . ' Checking conditions', [\n 'isMonday' => $isMonday,\n 'isFirstDayOfMonth' => $isFirstDayOfMonth,\n 'currentMonth' => $currentMonth,\n 'isQuarterlyMonth' => $isQuarterlyMonth,\n ]);\n\n // Process daily reports\n $this->processReports(AutomatedReportsService::FREQUENCY_DAILY);\n\n // Process weekly reports on Mondays\n if ($isMonday) {\n $this->processReports(AutomatedReportsService::FREQUENCY_WEEKLY);\n }\n\n // Process monthly reports on the first day of the month\n if ($isFirstDayOfMonth) {\n $this->processReports(AutomatedReportsService::FREQUENCY_MONTHLY);\n }\n\n // Process quarterly reports on the first day of January, April, July, and October\n if ($isFirstDayOfMonth && $isQuarterlyMonth) {\n $this->processReports(AutomatedReportsService::FREQUENCY_QUARTERLY);\n }\n\n $this->logger->info(self::LOG_PREFIX . ' Completed');\n\n return 0;\n }\n\n /**\n * Process reports for a specific frequency.\n *\n * @param string $frequency\n *\n * @return void\n */\n private function processReports(string $frequency): void\n {\n $this->logger->info(self::LOG_PREFIX . \" Processing $frequency reports\");\n\n // Get all enabled, not deleted reports with active teams for the specified frequency\n $reports = $this->reportRepository->getActiveReportsByFrequency($frequency);\n // $reports = collect([AutomatedReport::find(68)]);\n\n $this->logger->info(self::LOG_PREFIX . \" Found {$reports->count()} $frequency reports to process\");\n\n /** @var AutomatedReport $report */\n foreach ($reports as $report) {\n $this->logger->info(self::LOG_PREFIX . ' Dispatching Generate Report job for report', [\n 'reportUuid' => $report->getUuid(),\n 'teamId' => $report->getTeamId(),\n 'frequency' => $report->getFrequency(),\n 'type' => $report->getType(),\n ]);\n\n $job = $report->isAskJiminnyReport()\n ? new RequestGenerateAskJiminnyReportJob($report->getUuid())\n : new RequestGenerateReportJob($report->getUuid());\n\n // $this->dispatcher->dispatch($job);\n $this->dispatcher->dispatchSync($job);\n }\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.049609374,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"1","depth":4,"bounds":{"left":0.9339844,"top":0.0875,"width":0.00859375,"height":0.013194445},"role_description":"text"},{"role":"AXStaticText","text":"14","depth":4,"bounds":{"left":0.94492185,"top":0.0875,"width":0.011328125,"height":0.013194445},"role_description":"text"},{"role":"AXStaticText","text":"4","depth":4,"bounds":{"left":0.9585937,"top":0.0875,"width":0.009375,"height":0.013194445},"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.9699219,"top":0.08611111,"width":0.00859375,"height":0.015972223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.9785156,"top":0.08611111,"width":0.008203125,"height":0.015972223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Tests\\Unit\\Jobs\\AutomatedReports;\n\nuse Carbon\\Carbon;\nuse Jiminny\\Component\\ProphetAi\\Exceptions\\ProphetException;\nuse Jiminny\\Component\\ProphetAi\\ProphetClient;\nuse Jiminny\\Jobs\\AutomatedReports\\RequestGenerateAskJiminnyReportJob;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Models\\AutomatedReportResult;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AskJiminnyReportActivityService;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse PHPUnit\\Framework\\MockObject\\MockObject;\nuse PHPUnit\\Framework\\TestCase;\nuse Psr\\Log\\LoggerInterface;\n\nclass RequestGenerateAskJiminnyReportJobTest extends TestCase\n{\n private AutomatedReportsService&MockObject $reportService;\n private AskJiminnyReportActivityService&MockObject $activityService;\n private ProphetClient&MockObject $prophetClient;\n private LoggerInterface&MockObject $logger;\n\n protected function setUp(): void\n {\n $this->reportService = $this->createMock(AutomatedReportsService::class);\n $this->activityService = $this->createMock(AskJiminnyReportActivityService::class);\n $this->prophetClient = $this->createMock(ProphetClient::class);\n $this->logger = $this->createMock(LoggerInterface::class);\n }\n\n private function makeJob(string $uuid = 'report-uuid'): RequestGenerateAskJiminnyReportJob\n {\n return new RequestGenerateAskJiminnyReportJob($uuid);\n }\n\n private function makeActiveReport(\n string $type = AutomatedReportsService::TYPE_ASK_JIMINNY,\n bool $status = true,\n string $teamStatus = Team::STATUS_ACTIVE,\n ): AutomatedReport&MockObject { // @phpstan-ignore-line\n $team = $this->createMock(Team::class);\n $team->method('getStatus')->willReturn($teamStatus);\n\n $report = $this->createMock(AutomatedReport::class);\n $report->method('getType')->willReturn($type);\n $report->method('getStatus')->willReturn($status);\n $report->method('getTeam')->willReturn($team);\n\n return $report;\n }\n\n public function testUniqueIdReturnsReportUuid(): void\n {\n $job = $this->makeJob('my-unique-uuid');\n\n $this->assertEquals('my-unique-uuid', $job->uniqueId());\n }\n\n public function testHandleSkipsWhenReportTypeIsNotAskJiminny(): void\n {\n $report = $this->makeActiveReport(type: 'exec_summary');\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->logger->expects($this->once())\n ->method('info')\n ->with($this->stringContains('Started'));\n\n $this->logger->expects($this->once())\n ->method('warning')\n ->with($this->stringContains('not an ask_jiminny report'));\n\n $this->reportService->expects($this->never())->method('createReportResult');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleSkipsWhenReportIsInactive(): void\n {\n $report = $this->makeActiveReport(status: false);\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->logger->expects($this->exactly(2))\n ->method('info');\n\n $this->reportService->expects($this->never())->method('createReportResult');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleSkipsWhenTeamIsInactive(): void\n {\n $report = $this->makeActiveReport(teamStatus: Team::STATUS_DEACTIVATED);\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->logger->expects($this->exactly(2))\n ->method('info');\n\n $this->reportService->expects($this->never())->method('createReportResult');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleSkipsWhenCreatorIsNull(): void\n {\n $report = $this->makeActiveReport();\n $report->method('getCreator')->willReturn(null);\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->logger->expects($this->once())\n ->method('warning')\n ->with($this->stringContains('report creator not found'));\n\n $this->reportService->expects($this->never())->method('createReportResult');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleSkipsWhenSavedSearchIsNull(): void\n {\n $creator = $this->createMock(User::class);\n\n $report = $this->makeActiveReport();\n $report->method('getCreator')->willReturn($creator);\n $report->method('getSavedSearch')->willReturn(null);\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->logger->expects($this->once())\n ->method('warning')\n ->with($this->stringContains('saved search not found'));\n\n $this->reportService->expects($this->never())->method('createReportResult');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleSkipsWhenPromptIsNull(): void\n {\n $creator = $this->createMock(User::class);\n $savedSearch = $this->createMock(\\Jiminny\\Models\\Activity\\Search::class);\n\n $report = $this->makeActiveReport();\n $report->method('getCreator')->willReturn($creator);\n $report->method('getSavedSearch')->willReturn($savedSearch);\n $report->method('getAskAnythingPrompt')->willReturn(null);\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->logger->expects($this->once())\n ->method('warning')\n ->with($this->stringContains('ask anything prompt not found'));\n\n $this->reportService->expects($this->never())->method('createReportResult');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleFailsReportWhenNotEnoughActivities(): void\n {\n $creator = $this->createMock(User::class);\n $savedSearch = $this->createMock(\\Jiminny\\Models\\Activity\\Search::class);\n $prompt = $this->createMock(\\Jiminny\\Models\\AskAnything\\AskAnythingPrompt::class);\n\n $report = $this->makeActiveReport();\n $report->method('getCreator')->willReturn($creator);\n $report->method('getSavedSearch')->willReturn($savedSearch);\n $report->method('getAskAnythingPrompt')->willReturn($prompt);\n\n $reportResult = $this->createMock(AutomatedReportResult::class);\n $reportResult->expects($this->once())\n ->method('update')\n ->with($this->callback(fn ($data) => $data['status'] === AutomatedReportResult::STATUS_FAILED\n && $data['reason'] === AutomatedReportResult::REASON_NOT_ENOUGH_ACTIVITIES));\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->reportService->expects($this->once())\n ->method('createReportResult')\n ->willReturn($reportResult);\n\n $this->activityService->expects($this->once())\n ->method('getActivityIdsForSavedSearch')\n ->willReturn([]);\n\n $this->logger->expects($this->exactly(3))\n ->method('info');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleSuccessfullyRequestsReport(): void\n {\n Carbon::setTestNow(Carbon::parse('2026-04-07 10:00:00'));\n\n $creator = $this->createMock(User::class);\n $savedSearch = $this->createMock(\\Jiminny\\Models\\Activity\\Search::class);\n $prompt = $this->createMock(\\Jiminny\\Models\\AskAnything\\AskAnythingPrompt::class);\n\n $report = $this->makeActiveReport();\n $report->method('getCreator')->willReturn($creator);\n $report->method('getSavedSearch')->willReturn($savedSearch);\n $report->method('getAskAnythingPrompt')->willReturn($prompt);\n $report->method('getUuid')->willReturn('report-uuid');\n\n $reportResult = $this->createMock(AutomatedReportResult::class);\n $reportResult->method('getUuid')->willReturn('result-uuid');\n $reportResult->expects($this->once())\n ->method('update')\n ->with($this->callback(fn ($data) => $data['status'] === AutomatedReportResult::STATUS_REQUESTED\n && isset($data['name'], $data['payload'], $data['requested_at'])));\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->reportService->expects($this->once())\n ->method('createReportResult')\n ->willReturn($reportResult);\n\n $this->reportService->expects($this->once())\n ->method('getAskJiminnyGenerateReportPayload')\n ->willReturn(['key' => 'value']);\n\n $this->reportService->expects($this->once())\n ->method('getReportFileName')\n ->willReturn('My Report - 7 Apr 2026');\n\n $this->activityService->expects($this->once())\n ->method('getActivityIdsForSavedSearch')\n ->willReturn(['act-1', 'act-2']);\n\n $this->prophetClient->expects($this->once())\n ->method('sendRequest')\n ->willReturn(new \\Jiminny\\Component\\ProphetAi\\Dtos\\ProphetResponseDto([]));\n\n $this->logger->expects($this->exactly(4))\n ->method('info');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n\n Carbon::setTestNow();\n }\n\n public function testHandleCatchesGenericExceptionAndLogsError(): void\n {\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willThrowException(new \\RuntimeException('DB error'));\n\n $this->logger->expects($this->once())\n ->method('error')\n ->with($this->stringContains('Error'));\n\n $job = $this->makeJob();\n\n $reflection = new \\ReflectionClass($job);\n $triesProp = $reflection->getProperty('tries');\n $triesProp->setAccessible(true);\n\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleCatchesProphetExceptionAndSetsCorrectReason(): void\n {\n $creator = $this->createMock(User::class);\n $savedSearch = $this->createMock(\\Jiminny\\Models\\Activity\\Search::class);\n $prompt = $this->createMock(\\Jiminny\\Models\\AskAnything\\AskAnythingPrompt::class);\n\n $report = $this->makeActiveReport();\n $report->method('getCreator')->willReturn($creator);\n $report->method('getSavedSearch')->willReturn($savedSearch);\n $report->method('getAskAnythingPrompt')->willReturn($prompt);\n\n $reportResult = $this->createMock(AutomatedReportResult::class);\n $reportResult->method('getUuid')->willReturn('result-uuid');\n $reportResult->expects($this->once())\n ->method('update')\n ->with($this->callback(fn ($data) => $data['reason'] === AutomatedReportResult::REASON_PROPHET_API_ERROR));\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->reportService->expects($this->once())\n ->method('createReportResult')\n ->willReturn($reportResult);\n\n $this->activityService->expects($this->once())\n ->method('getActivityIdsForSavedSearch')\n ->willThrowException(new ProphetException('Prophet failed'));\n\n $this->logger->expects($this->once())\n ->method('error');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleCreatesReportResultBeforeActivityFetch(): void\n {\n $creator = $this->createMock(User::class);\n $savedSearch = $this->createMock(\\Jiminny\\Models\\Activity\\Search::class);\n $prompt = $this->createMock(\\Jiminny\\Models\\AskAnything\\AskAnythingPrompt::class);\n\n $report = $this->makeActiveReport();\n $report->method('getCreator')->willReturn($creator);\n $report->method('getSavedSearch')->willReturn($savedSearch);\n $report->method('getAskAnythingPrompt')->willReturn($prompt);\n\n $reportResult = $this->createMock(AutomatedReportResult::class);\n $reportResult->method('getUuid')->willReturn('result-uuid');\n\n $callOrder = [];\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->reportService->expects($this->once())\n ->method('createReportResult')\n ->willReturnCallback(function () use ($reportResult, &$callOrder) {\n $callOrder[] = 'createReportResult';\n\n return $reportResult;\n });\n\n $this->activityService->expects($this->once())\n ->method('getActivityIdsForSavedSearch')\n ->willReturnCallback(function () use (&$callOrder) {\n $callOrder[] = 'getActivityIds';\n\n return [];\n });\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n\n $this->assertEquals(['createReportResult', 'getActivityIds'], $callOrder);\n }\n\n public function testHandlePassesCorrectDataToCreateReportResult(): void\n {\n $creator = $this->createMock(User::class);\n $savedSearch = $this->createMock(\\Jiminny\\Models\\Activity\\Search::class);\n $prompt = $this->createMock(\\Jiminny\\Models\\AskAnything\\AskAnythingPrompt::class);\n\n $report = $this->makeActiveReport();\n $report->method('getCreator')->willReturn($creator);\n $report->method('getSavedSearch')->willReturn($savedSearch);\n $report->method('getAskAnythingPrompt')->willReturn($prompt);\n\n $reportResult = $this->createMock(AutomatedReportResult::class);\n $reportResult->method('getUuid')->willReturn('result-uuid');\n $reportResult->method('update')->willReturn(true);\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->reportService->expects($this->once())\n ->method('createReportResult')\n ->with(\n automatedReport: $report,\n data: $this->callback(fn ($data) => $data['status'] === AutomatedReportResult::STATUS_DEFAULT\n && $data['media_type'] === AutomatedReportsService::MEDIA_TYPE_PDF)\n )\n ->willReturn($reportResult);\n\n $this->activityService->expects($this->once())\n ->method('getActivityIdsForSavedSearch')\n ->willReturn([]);\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n}","depth":4,"bounds":{"left":0.55507815,"top":0.08472222,"width":0.43125,"height":0.9152778},"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Tests\\Unit\\Jobs\\AutomatedReports;\n\nuse Carbon\\Carbon;\nuse Jiminny\\Component\\ProphetAi\\Exceptions\\ProphetException;\nuse Jiminny\\Component\\ProphetAi\\ProphetClient;\nuse Jiminny\\Jobs\\AutomatedReports\\RequestGenerateAskJiminnyReportJob;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Models\\AutomatedReportResult;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AskJiminnyReportActivityService;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse PHPUnit\\Framework\\MockObject\\MockObject;\nuse PHPUnit\\Framework\\TestCase;\nuse Psr\\Log\\LoggerInterface;\n\nclass RequestGenerateAskJiminnyReportJobTest extends TestCase\n{\n private AutomatedReportsService&MockObject $reportService;\n private AskJiminnyReportActivityService&MockObject $activityService;\n private ProphetClient&MockObject $prophetClient;\n private LoggerInterface&MockObject $logger;\n\n protected function setUp(): void\n {\n $this->reportService = $this->createMock(AutomatedReportsService::class);\n $this->activityService = $this->createMock(AskJiminnyReportActivityService::class);\n $this->prophetClient = $this->createMock(ProphetClient::class);\n $this->logger = $this->createMock(LoggerInterface::class);\n }\n\n private function makeJob(string $uuid = 'report-uuid'): RequestGenerateAskJiminnyReportJob\n {\n return new RequestGenerateAskJiminnyReportJob($uuid);\n }\n\n private function makeActiveReport(\n string $type = AutomatedReportsService::TYPE_ASK_JIMINNY,\n bool $status = true,\n string $teamStatus = Team::STATUS_ACTIVE,\n ): AutomatedReport&MockObject { // @phpstan-ignore-line\n $team = $this->createMock(Team::class);\n $team->method('getStatus')->willReturn($teamStatus);\n\n $report = $this->createMock(AutomatedReport::class);\n $report->method('getType')->willReturn($type);\n $report->method('getStatus')->willReturn($status);\n $report->method('getTeam')->willReturn($team);\n\n return $report;\n }\n\n public function testUniqueIdReturnsReportUuid(): void\n {\n $job = $this->makeJob('my-unique-uuid');\n\n $this->assertEquals('my-unique-uuid', $job->uniqueId());\n }\n\n public function testHandleSkipsWhenReportTypeIsNotAskJiminny(): void\n {\n $report = $this->makeActiveReport(type: 'exec_summary');\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->logger->expects($this->once())\n ->method('info')\n ->with($this->stringContains('Started'));\n\n $this->logger->expects($this->once())\n ->method('warning')\n ->with($this->stringContains('not an ask_jiminny report'));\n\n $this->reportService->expects($this->never())->method('createReportResult');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleSkipsWhenReportIsInactive(): void\n {\n $report = $this->makeActiveReport(status: false);\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->logger->expects($this->exactly(2))\n ->method('info');\n\n $this->reportService->expects($this->never())->method('createReportResult');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleSkipsWhenTeamIsInactive(): void\n {\n $report = $this->makeActiveReport(teamStatus: Team::STATUS_DEACTIVATED);\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->logger->expects($this->exactly(2))\n ->method('info');\n\n $this->reportService->expects($this->never())->method('createReportResult');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleSkipsWhenCreatorIsNull(): void\n {\n $report = $this->makeActiveReport();\n $report->method('getCreator')->willReturn(null);\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->logger->expects($this->once())\n ->method('warning')\n ->with($this->stringContains('report creator not found'));\n\n $this->reportService->expects($this->never())->method('createReportResult');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleSkipsWhenSavedSearchIsNull(): void\n {\n $creator = $this->createMock(User::class);\n\n $report = $this->makeActiveReport();\n $report->method('getCreator')->willReturn($creator);\n $report->method('getSavedSearch')->willReturn(null);\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->logger->expects($this->once())\n ->method('warning')\n ->with($this->stringContains('saved search not found'));\n\n $this->reportService->expects($this->never())->method('createReportResult');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleSkipsWhenPromptIsNull(): void\n {\n $creator = $this->createMock(User::class);\n $savedSearch = $this->createMock(\\Jiminny\\Models\\Activity\\Search::class);\n\n $report = $this->makeActiveReport();\n $report->method('getCreator')->willReturn($creator);\n $report->method('getSavedSearch')->willReturn($savedSearch);\n $report->method('getAskAnythingPrompt')->willReturn(null);\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->logger->expects($this->once())\n ->method('warning')\n ->with($this->stringContains('ask anything prompt not found'));\n\n $this->reportService->expects($this->never())->method('createReportResult');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleFailsReportWhenNotEnoughActivities(): void\n {\n $creator = $this->createMock(User::class);\n $savedSearch = $this->createMock(\\Jiminny\\Models\\Activity\\Search::class);\n $prompt = $this->createMock(\\Jiminny\\Models\\AskAnything\\AskAnythingPrompt::class);\n\n $report = $this->makeActiveReport();\n $report->method('getCreator')->willReturn($creator);\n $report->method('getSavedSearch')->willReturn($savedSearch);\n $report->method('getAskAnythingPrompt')->willReturn($prompt);\n\n $reportResult = $this->createMock(AutomatedReportResult::class);\n $reportResult->expects($this->once())\n ->method('update')\n ->with($this->callback(fn ($data) => $data['status'] === AutomatedReportResult::STATUS_FAILED\n && $data['reason'] === AutomatedReportResult::REASON_NOT_ENOUGH_ACTIVITIES));\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->reportService->expects($this->once())\n ->method('createReportResult')\n ->willReturn($reportResult);\n\n $this->activityService->expects($this->once())\n ->method('getActivityIdsForSavedSearch')\n ->willReturn([]);\n\n $this->logger->expects($this->exactly(3))\n ->method('info');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleSuccessfullyRequestsReport(): void\n {\n Carbon::setTestNow(Carbon::parse('2026-04-07 10:00:00'));\n\n $creator = $this->createMock(User::class);\n $savedSearch = $this->createMock(\\Jiminny\\Models\\Activity\\Search::class);\n $prompt = $this->createMock(\\Jiminny\\Models\\AskAnything\\AskAnythingPrompt::class);\n\n $report = $this->makeActiveReport();\n $report->method('getCreator')->willReturn($creator);\n $report->method('getSavedSearch')->willReturn($savedSearch);\n $report->method('getAskAnythingPrompt')->willReturn($prompt);\n $report->method('getUuid')->willReturn('report-uuid');\n\n $reportResult = $this->createMock(AutomatedReportResult::class);\n $reportResult->method('getUuid')->willReturn('result-uuid');\n $reportResult->expects($this->once())\n ->method('update')\n ->with($this->callback(fn ($data) => $data['status'] === AutomatedReportResult::STATUS_REQUESTED\n && isset($data['name'], $data['payload'], $data['requested_at'])));\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->reportService->expects($this->once())\n ->method('createReportResult')\n ->willReturn($reportResult);\n\n $this->reportService->expects($this->once())\n ->method('getAskJiminnyGenerateReportPayload')\n ->willReturn(['key' => 'value']);\n\n $this->reportService->expects($this->once())\n ->method('getReportFileName')\n ->willReturn('My Report - 7 Apr 2026');\n\n $this->activityService->expects($this->once())\n ->method('getActivityIdsForSavedSearch')\n ->willReturn(['act-1', 'act-2']);\n\n $this->prophetClient->expects($this->once())\n ->method('sendRequest')\n ->willReturn(new \\Jiminny\\Component\\ProphetAi\\Dtos\\ProphetResponseDto([]));\n\n $this->logger->expects($this->exactly(4))\n ->method('info');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n\n Carbon::setTestNow();\n }\n\n public function testHandleCatchesGenericExceptionAndLogsError(): void\n {\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willThrowException(new \\RuntimeException('DB error'));\n\n $this->logger->expects($this->once())\n ->method('error')\n ->with($this->stringContains('Error'));\n\n $job = $this->makeJob();\n\n $reflection = new \\ReflectionClass($job);\n $triesProp = $reflection->getProperty('tries');\n $triesProp->setAccessible(true);\n\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleCatchesProphetExceptionAndSetsCorrectReason(): void\n {\n $creator = $this->createMock(User::class);\n $savedSearch = $this->createMock(\\Jiminny\\Models\\Activity\\Search::class);\n $prompt = $this->createMock(\\Jiminny\\Models\\AskAnything\\AskAnythingPrompt::class);\n\n $report = $this->makeActiveReport();\n $report->method('getCreator')->willReturn($creator);\n $report->method('getSavedSearch')->willReturn($savedSearch);\n $report->method('getAskAnythingPrompt')->willReturn($prompt);\n\n $reportResult = $this->createMock(AutomatedReportResult::class);\n $reportResult->method('getUuid')->willReturn('result-uuid');\n $reportResult->expects($this->once())\n ->method('update')\n ->with($this->callback(fn ($data) => $data['reason'] === AutomatedReportResult::REASON_PROPHET_API_ERROR));\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->reportService->expects($this->once())\n ->method('createReportResult')\n ->willReturn($reportResult);\n\n $this->activityService->expects($this->once())\n ->method('getActivityIdsForSavedSearch')\n ->willThrowException(new ProphetException('Prophet failed'));\n\n $this->logger->expects($this->once())\n ->method('error');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleCreatesReportResultBeforeActivityFetch(): void\n {\n $creator = $this->createMock(User::class);\n $savedSearch = $this->createMock(\\Jiminny\\Models\\Activity\\Search::class);\n $prompt = $this->createMock(\\Jiminny\\Models\\AskAnything\\AskAnythingPrompt::class);\n\n $report = $this->makeActiveReport();\n $report->method('getCreator')->willReturn($creator);\n $report->method('getSavedSearch')->willReturn($savedSearch);\n $report->method('getAskAnythingPrompt')->willReturn($prompt);\n\n $reportResult = $this->createMock(AutomatedReportResult::class);\n $reportResult->method('getUuid')->willReturn('result-uuid');\n\n $callOrder = [];\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->reportService->expects($this->once())\n ->method('createReportResult')\n ->willReturnCallback(function () use ($reportResult, &$callOrder) {\n $callOrder[] = 'createReportResult';\n\n return $reportResult;\n });\n\n $this->activityService->expects($this->once())\n ->method('getActivityIdsForSavedSearch')\n ->willReturnCallback(function () use (&$callOrder) {\n $callOrder[] = 'getActivityIds';\n\n return [];\n });\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n\n $this->assertEquals(['createReportResult', 'getActivityIds'], $callOrder);\n }\n\n public function testHandlePassesCorrectDataToCreateReportResult(): void\n {\n $creator = $this->createMock(User::class);\n $savedSearch = $this->createMock(\\Jiminny\\Models\\Activity\\Search::class);\n $prompt = $this->createMock(\\Jiminny\\Models\\AskAnything\\AskAnythingPrompt::class);\n\n $report = $this->makeActiveReport();\n $report->method('getCreator')->willReturn($creator);\n $report->method('getSavedSearch')->willReturn($savedSearch);\n $report->method('getAskAnythingPrompt')->willReturn($prompt);\n\n $reportResult = $this->createMock(AutomatedReportResult::class);\n $reportResult->method('getUuid')->willReturn('result-uuid');\n $reportResult->method('update')->willReturn(true);\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->reportService->expects($this->once())\n ->method('createReportResult')\n ->with(\n automatedReport: $report,\n data: $this->callback(fn ($data) => $data['status'] === AutomatedReportResult::STATUS_DEFAULT\n && $data['media_type'] === AutomatedReportsService::MEDIA_TYPE_PDF)\n )\n ->willReturn($reportResult);\n\n $this->activityService->expects($this->once())\n ->method('getActivityIdsForSavedSearch')\n ->willReturn([]);\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"bounds":{"left":0.0140625,"top":0.041666668,"width":0.028515626,"height":0.021527778},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"app ~/jiminny/app","depth":6,"bounds":{"left":0.024609376,"top":0.047222223,"width":0.05390625,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":".circleci","depth":7,"bounds":{"left":0.03203125,"top":0.0625,"width":0.028125,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":".cursor","depth":7,"bounds":{"left":0.03203125,"top":0.07777778,"width":0.026171874,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":".github","depth":7,"bounds":{"left":0.03203125,"top":0.093055554,"width":0.026171874,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":".sonarlint","depth":7,"bounds":{"left":0.03203125,"top":0.108333334,"width":0.031640626,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":".vscode","depth":7,"bounds":{"left":0.03203125,"top":0.12361111,"width":0.028515626,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":".windsurf","depth":7,"bounds":{"left":0.03203125,"top":0.1388889,"width":0.031640626,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"app, sources root","depth":7,"bounds":{"left":0.03203125,"top":0.15416667,"width":0.01875,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"Actions","depth":8,"bounds":{"left":0.039453126,"top":0.16944444,"width":0.027734375,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"Component","depth":8,"bounds":{"left":0.039453126,"top":0.18472221,"width":0.0375,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"Configuration","depth":8,"bounds":{"left":0.039453126,"top":0.2,"width":0.0421875,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"Console","depth":8,"bounds":{"left":0.039453126,"top":0.21527778,"width":0.029296875,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"Commands","depth":9,"bounds":{"left":0.046875,"top":0.23055555,"width":0.03671875,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"Activities","depth":10,"bounds":{"left":0.054296874,"top":0.24583334,"width":0.031640626,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"Analytics","depth":10,"bounds":{"left":0.054296874,"top":0.2611111,"width":0.03125,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"Calendars","depth":10,"bounds":{"left":0.054296874,"top":0.27638888,"width":0.033984374,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"Crm","depth":10,"bounds":{"left":0.054296874,"top":0.29166666,"width":0.01953125,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"DealInsights","depth":10,"bounds":{"left":0.054296874,"top":0.30694443,"width":0.0390625,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"Dev","depth":10,"bounds":{"left":0.054296874,"top":0.32222223,"width":0.019140625,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"Dialers","depth":10,"bounds":{"left":0.054296874,"top":0.3375,"width":0.026171874,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"DTOs","depth":10,"bounds":{"left":0.054296874,"top":0.35277778,"width":0.023046875,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"Elasticsearch","depth":10,"bounds":{"left":0.054296874,"top":0.36805555,"width":0.04140625,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"EngagementStats","depth":10,"bounds":{"left":0.054296874,"top":0.38333333,"width":0.05234375,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"GeckoExport","depth":10,"bounds":{"left":0.054296874,"top":0.3986111,"width":0.040625,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"Livestream","depth":10,"bounds":{"left":0.054296874,"top":0.4138889,"width":0.0359375,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"Mailboxes","depth":10,"bounds":{"left":0.054296874,"top":0.42916667,"width":0.033984374,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"Migrate","depth":10,"bounds":{"left":0.054296874,"top":0.44444445,"width":0.028125,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"PlaybackThemes","depth":10,"bounds":{"left":0.054296874,"top":0.45972222,"width":0.050390624,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"Playbooks","depth":10,"bounds":{"left":0.054296874,"top":0.475,"width":0.034375,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"Playlists","depth":10,"bounds":{"left":0.054296874,"top":0.49027777,"width":0.029296875,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"Postmark","depth":10,"bounds":{"left":0.054296874,"top":0.50555557,"width":0.032421876,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"ProphetAi","depth":10,"bounds":{"left":0.054296874,"top":0.5208333,"width":0.033203125,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"Reports","depth":10,"bounds":{"left":0.054296874,"top":0.5361111,"width":0.028125,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"AutomatedReportsCommand.php, class","depth":11,"bounds":{"left":0.06171875,"top":0.55138886,"width":0.08984375,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"AutomatedReportsRetentionPolicyCommand.php, class","depth":11,"bounds":{"left":0.06171875,"top":0.56666666,"width":0.12734374,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"AutomatedReportsSendCommand.php, class","depth":11,"bounds":{"left":0.06171875,"top":0.58194447,"width":0.10234375,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"CreateMockAskJiminnyReportResultCommand.php, class","depth":11,"bounds":{"left":0.06171875,"top":0.5972222,"width":0.13203125,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"DeleteReportCommand.php, class","depth":11,"bounds":{"left":0.06171875,"top":0.6125,"width":0.076171875,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"GenerateMarketingReport.php, class","depth":11,"bounds":{"left":0.06171875,"top":0.62777776,"width":0.08242188,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"Team.php, class","depth":11,"bounds":{"left":0.06171875,"top":0.64305556,"width":0.03359375,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"Usage.php, class","depth":11,"bounds":{"left":0.06171875,"top":0.65833336,"width":0.035546876,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"Slack","depth":10,"bounds":{"left":0.054296874,"top":0.6736111,"width":0.02265625,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"Teams","depth":10,"bounds":{"left":0.054296874,"top":0.6888889,"width":0.02578125,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"Tracks","depth":10,"bounds":{"left":0.054296874,"top":0.70416665,"width":0.02578125,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"Transcription","depth":10,"bounds":{"left":0.054296874,"top":0.71944445,"width":0.04140625,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"Twilio","depth":10,"bounds":{"left":0.054296874,"top":0.7347222,"width":0.0234375,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"Users","depth":10,"bounds":{"left":0.054296874,"top":0.75,"width":0.0234375,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"Vocabulary","depth":10,"bounds":{"left":0.054296874,"top":0.7652778,"width":0.03671875,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"Zoom","depth":10,"bounds":{"left":0.054296874,"top":0.78055555,"width":0.023046875,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"CoachingFeedbacksUpdateEsActivities.php, class","depth":10,"bounds":{"left":0.054296874,"top":0.79583335,"width":0.11445312,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"Command.php, class","depth":10,"bounds":{"left":0.054296874,"top":0.8111111,"width":0.04453125,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"CreateDatabaseUsers.php, class","depth":10,"bounds":{"left":0.054296874,"top":0.8263889,"width":0.07304688,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"DatabaseTableCount.php, class","depth":10,"bounds":{"left":0.054296874,"top":0.84166664,"width":0.07109375,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"DeleteOldAiCrmNotesCommand.php, class","depth":10,"bounds":{"left":0.054296874,"top":0.85694444,"width":0.09726562,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"DeleteS3LeftoversCommand.php, class","depth":10,"bounds":{"left":0.054296874,"top":0.87222224,"width":0.08945312,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"DevPostmanCommand.php, final class","depth":10,"bounds":{"left":0.054296874,"top":0.8875,"width":0.075,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"DiarizeViaAiParticipantIdentificationCommand.php, class","depth":10,"bounds":{"left":0.054296874,"top":0.9027778,"width":0.13046876,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"EncryptTokensCommand.php, class","depth":10,"bounds":{"left":0.054296874,"top":0.91805553,"width":0.08085938,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"EngagementStatsRegenerateCommand.php, class","depth":10,"bounds":{"left":0.054296874,"top":0.93333334,"width":0.115234375,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"FeatureFlagsHelper.php","depth":10,"bounds":{"left":0.054296874,"top":0.94861114,"width":0.0671875,"height":0.015277778},"role_description":"text"}]...
|
4788244587282610802
|
8726798778017204625
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
#11894 on JY-18909-automa Project: faVsco.js, menu
#11894 on JY-18909-automated-reports-ask-jiminny, menu
Start Listening for PHP Debug Connections
RequestGenerateAskJiminnyReportJobTest
Run 'RequestGenerateAskJiminnyReportJobTest'
Debug 'RequestGenerateAskJiminnyReportJobTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Console\Commands\Reports;
use Carbon\Carbon;
use Illuminate\Console\Command;
use Illuminate\Contracts\Bus\Dispatcher as BusDispatcher;
use Jiminny\Jobs\AutomatedReports\RequestGenerateAskJiminnyReportJob;
use Jiminny\Jobs\AutomatedReports\RequestGenerateReportJob;
use Jiminny\Models\AutomatedReport;
use Jiminny\Repositories\AutomatedReportsRepository;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Psr\Log\LoggerInterface;
class AutomatedReportsCommand extends Command
{
/**
* Log prefix for all log messages
*/
private const string LOG_PREFIX = '[automated-reports]';
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'automated-reports';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Process automated reports based on their frequency (weekly, monthly, quarterly)';
public function __construct(
private readonly LoggerInterface $logger,
private readonly BusDispatcher $dispatcher,
private readonly AutomatedReportsRepository $reportRepository
) {
parent::__construct();
}
/**
* Execute the console command.
*
* @return int
*/
public function handle(): int
{
$this->logger->info(self::LOG_PREFIX . ' Started');
$now = Carbon::now();
$isMonday = $now->isMonday();
$isFirstDayOfMonth = $now->day === 1;
$currentMonth = $now->month;
// Check if the current month is a quarterly month (January, April, July, October)
$isQuarterlyMonth = in_array($currentMonth, [1, 4, 7, 10], true);
$this->logger->info(self::LOG_PREFIX . ' Checking conditions', [
'isMonday' => $isMonday,
'isFirstDayOfMonth' => $isFirstDayOfMonth,
'currentMonth' => $currentMonth,
'isQuarterlyMonth' => $isQuarterlyMonth,
]);
// Process daily reports
$this->processReports(AutomatedReportsService::FREQUENCY_DAILY);
// Process weekly reports on Mondays
if ($isMonday) {
$this->processReports(AutomatedReportsService::FREQUENCY_WEEKLY);
}
// Process monthly reports on the first day of the month
if ($isFirstDayOfMonth) {
$this->processReports(AutomatedReportsService::FREQUENCY_MONTHLY);
}
// Process quarterly reports on the first day of January, April, July, and October
if ($isFirstDayOfMonth && $isQuarterlyMonth) {
$this->processReports(AutomatedReportsService::FREQUENCY_QUARTERLY);
}
$this->logger->info(self::LOG_PREFIX . ' Completed');
return 0;
}
/**
* Process reports for a specific frequency.
*
* @param string $frequency
*
* @return void
*/
private function processReports(string $frequency): void
{
$this->logger->info(self::LOG_PREFIX . " Processing $frequency reports");
// Get all enabled, not deleted reports with active teams for the specified frequency
$reports = $this->reportRepository->getActiveReportsByFrequency($frequency);
// $reports = collect([AutomatedReport::find(68)]);
$this->logger->info(self::LOG_PREFIX . " Found {$reports->count()} $frequency reports to process");
/** @var AutomatedReport $report */
foreach ($reports as $report) {
$this->logger->info(self::LOG_PREFIX . ' Dispatching Generate Report job for report', [
'reportUuid' => $report->getUuid(),
'teamId' => $report->getTeamId(),
'frequency' => $report->getFrequency(),
'type' => $report->getType(),
]);
$job = $report->isAskJiminnyReport()
? new RequestGenerateAskJiminnyReportJob($report->getUuid())
: new RequestGenerateReportJob($report->getUuid());
// $this->dispatcher->dispatch($job);
$this->dispatcher->dispatchSync($job);
}
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
1
14
4
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Tests\Unit\Jobs\AutomatedReports;
use Carbon\Carbon;
use Jiminny\Component\ProphetAi\Exceptions\ProphetException;
use Jiminny\Component\ProphetAi\ProphetClient;
use Jiminny\Jobs\AutomatedReports\RequestGenerateAskJiminnyReportJob;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\AutomatedReportResult;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityService;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
use Psr\Log\LoggerInterface;
class RequestGenerateAskJiminnyReportJobTest extends TestCase
{
private AutomatedReportsService&MockObject $reportService;
private AskJiminnyReportActivityService&MockObject $activityService;
private ProphetClient&MockObject $prophetClient;
private LoggerInterface&MockObject $logger;
protected function setUp(): void
{
$this->reportService = $this->createMock(AutomatedReportsService::class);
$this->activityService = $this->createMock(AskJiminnyReportActivityService::class);
$this->prophetClient = $this->createMock(ProphetClient::class);
$this->logger = $this->createMock(LoggerInterface::class);
}
private function makeJob(string $uuid = 'report-uuid'): RequestGenerateAskJiminnyReportJob
{
return new RequestGenerateAskJiminnyReportJob($uuid);
}
private function makeActiveReport(
string $type = AutomatedReportsService::TYPE_ASK_JIMINNY,
bool $status = true,
string $teamStatus = Team::STATUS_ACTIVE,
): AutomatedReport&MockObject { // @phpstan-ignore-line
$team = $this->createMock(Team::class);
$team->method('getStatus')->willReturn($teamStatus);
$report = $this->createMock(AutomatedReport::class);
$report->method('getType')->willReturn($type);
$report->method('getStatus')->willReturn($status);
$report->method('getTeam')->willReturn($team);
return $report;
}
public function testUniqueIdReturnsReportUuid(): void
{
$job = $this->makeJob('my-unique-uuid');
$this->assertEquals('my-unique-uuid', $job->uniqueId());
}
public function testHandleSkipsWhenReportTypeIsNotAskJiminny(): void
{
$report = $this->makeActiveReport(type: 'exec_summary');
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->logger->expects($this->once())
->method('info')
->with($this->stringContains('Started'));
$this->logger->expects($this->once())
->method('warning')
->with($this->stringContains('not an ask_jiminny report'));
$this->reportService->expects($this->never())->method('createReportResult');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleSkipsWhenReportIsInactive(): void
{
$report = $this->makeActiveReport(status: false);
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->logger->expects($this->exactly(2))
->method('info');
$this->reportService->expects($this->never())->method('createReportResult');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleSkipsWhenTeamIsInactive(): void
{
$report = $this->makeActiveReport(teamStatus: Team::STATUS_DEACTIVATED);
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->logger->expects($this->exactly(2))
->method('info');
$this->reportService->expects($this->never())->method('createReportResult');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleSkipsWhenCreatorIsNull(): void
{
$report = $this->makeActiveReport();
$report->method('getCreator')->willReturn(null);
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->logger->expects($this->once())
->method('warning')
->with($this->stringContains('report creator not found'));
$this->reportService->expects($this->never())->method('createReportResult');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleSkipsWhenSavedSearchIsNull(): void
{
$creator = $this->createMock(User::class);
$report = $this->makeActiveReport();
$report->method('getCreator')->willReturn($creator);
$report->method('getSavedSearch')->willReturn(null);
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->logger->expects($this->once())
->method('warning')
->with($this->stringContains('saved search not found'));
$this->reportService->expects($this->never())->method('createReportResult');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleSkipsWhenPromptIsNull(): void
{
$creator = $this->createMock(User::class);
$savedSearch = $this->createMock(\Jiminny\Models\Activity\Search::class);
$report = $this->makeActiveReport();
$report->method('getCreator')->willReturn($creator);
$report->method('getSavedSearch')->willReturn($savedSearch);
$report->method('getAskAnythingPrompt')->willReturn(null);
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->logger->expects($this->once())
->method('warning')
->with($this->stringContains('ask anything prompt not found'));
$this->reportService->expects($this->never())->method('createReportResult');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleFailsReportWhenNotEnoughActivities(): void
{
$creator = $this->createMock(User::class);
$savedSearch = $this->createMock(\Jiminny\Models\Activity\Search::class);
$prompt = $this->createMock(\Jiminny\Models\AskAnything\AskAnythingPrompt::class);
$report = $this->makeActiveReport();
$report->method('getCreator')->willReturn($creator);
$report->method('getSavedSearch')->willReturn($savedSearch);
$report->method('getAskAnythingPrompt')->willReturn($prompt);
$reportResult = $this->createMock(AutomatedReportResult::class);
$reportResult->expects($this->once())
->method('update')
->with($this->callback(fn ($data) => $data['status'] === AutomatedReportResult::STATUS_FAILED
&& $data['reason'] === AutomatedReportResult::REASON_NOT_ENOUGH_ACTIVITIES));
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->reportService->expects($this->once())
->method('createReportResult')
->willReturn($reportResult);
$this->activityService->expects($this->once())
->method('getActivityIdsForSavedSearch')
->willReturn([]);
$this->logger->expects($this->exactly(3))
->method('info');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleSuccessfullyRequestsReport(): void
{
Carbon::setTestNow(Carbon::parse('2026-04-07 10:00:00'));
$creator = $this->createMock(User::class);
$savedSearch = $this->createMock(\Jiminny\Models\Activity\Search::class);
$prompt = $this->createMock(\Jiminny\Models\AskAnything\AskAnythingPrompt::class);
$report = $this->makeActiveReport();
$report->method('getCreator')->willReturn($creator);
$report->method('getSavedSearch')->willReturn($savedSearch);
$report->method('getAskAnythingPrompt')->willReturn($prompt);
$report->method('getUuid')->willReturn('report-uuid');
$reportResult = $this->createMock(AutomatedReportResult::class);
$reportResult->method('getUuid')->willReturn('result-uuid');
$reportResult->expects($this->once())
->method('update')
->with($this->callback(fn ($data) => $data['status'] === AutomatedReportResult::STATUS_REQUESTED
&& isset($data['name'], $data['payload'], $data['requested_at'])));
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->reportService->expects($this->once())
->method('createReportResult')
->willReturn($reportResult);
$this->reportService->expects($this->once())
->method('getAskJiminnyGenerateReportPayload')
->willReturn(['key' => 'value']);
$this->reportService->expects($this->once())
->method('getReportFileName')
->willReturn('My Report - 7 Apr 2026');
$this->activityService->expects($this->once())
->method('getActivityIdsForSavedSearch')
->willReturn(['act-1', 'act-2']);
$this->prophetClient->expects($this->once())
->method('sendRequest')
->willReturn(new \Jiminny\Component\ProphetAi\Dtos\ProphetResponseDto([]));
$this->logger->expects($this->exactly(4))
->method('info');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
Carbon::setTestNow();
}
public function testHandleCatchesGenericExceptionAndLogsError(): void
{
$this->reportService->expects($this->once())
->method('getReport')
->willThrowException(new \RuntimeException('DB error'));
$this->logger->expects($this->once())
->method('error')
->with($this->stringContains('Error'));
$job = $this->makeJob();
$reflection = new \ReflectionClass($job);
$triesProp = $reflection->getProperty('tries');
$triesProp->setAccessible(true);
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleCatchesProphetExceptionAndSetsCorrectReason(): void
{
$creator = $this->createMock(User::class);
$savedSearch = $this->createMock(\Jiminny\Models\Activity\Search::class);
$prompt = $this->createMock(\Jiminny\Models\AskAnything\AskAnythingPrompt::class);
$report = $this->makeActiveReport();
$report->method('getCreator')->willReturn($creator);
$report->method('getSavedSearch')->willReturn($savedSearch);
$report->method('getAskAnythingPrompt')->willReturn($prompt);
$reportResult = $this->createMock(AutomatedReportResult::class);
$reportResult->method('getUuid')->willReturn('result-uuid');
$reportResult->expects($this->once())
->method('update')
->with($this->callback(fn ($data) => $data['reason'] === AutomatedReportResult::REASON_PROPHET_API_ERROR));
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->reportService->expects($this->once())
->method('createReportResult')
->willReturn($reportResult);
$this->activityService->expects($this->once())
->method('getActivityIdsForSavedSearch')
->willThrowException(new ProphetException('Prophet failed'));
$this->logger->expects($this->once())
->method('error');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleCreatesReportResultBeforeActivityFetch(): void
{
$creator = $this->createMock(User::class);
$savedSearch = $this->createMock(\Jiminny\Models\Activity\Search::class);
$prompt = $this->createMock(\Jiminny\Models\AskAnything\AskAnythingPrompt::class);
$report = $this->makeActiveReport();
$report->method('getCreator')->willReturn($creator);
$report->method('getSavedSearch')->willReturn($savedSearch);
$report->method('getAskAnythingPrompt')->willReturn($prompt);
$reportResult = $this->createMock(AutomatedReportResult::class);
$reportResult->method('getUuid')->willReturn('result-uuid');
$callOrder = [];
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->reportService->expects($this->once())
->method('createReportResult')
->willReturnCallback(function () use ($reportResult, &$callOrder) {
$callOrder[] = 'createReportResult';
return $reportResult;
});
$this->activityService->expects($this->once())
->method('getActivityIdsForSavedSearch')
->willReturnCallback(function () use (&$callOrder) {
$callOrder[] = 'getActivityIds';
return [];
});
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
$this->assertEquals(['createReportResult', 'getActivityIds'], $callOrder);
}
public function testHandlePassesCorrectDataToCreateReportResult(): void
{
$creator = $this->createMock(User::class);
$savedSearch = $this->createMock(\Jiminny\Models\Activity\Search::class);
$prompt = $this->createMock(\Jiminny\Models\AskAnything\AskAnythingPrompt::class);
$report = $this->makeActiveReport();
$report->method('getCreator')->willReturn($creator);
$report->method('getSavedSearch')->willReturn($savedSearch);
$report->method('getAskAnythingPrompt')->willReturn($prompt);
$reportResult = $this->createMock(AutomatedReportResult::class);
$reportResult->method('getUuid')->willReturn('result-uuid');
$reportResult->method('update')->willReturn(true);
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->reportService->expects($this->once())
->method('createReportResult')
->with(
automatedReport: $report,
data: $this->callback(fn ($data) => $data['status'] === AutomatedReportResult::STATUS_DEFAULT
&& $data['media_type'] === AutomatedReportsService::MEDIA_TYPE_PDF)
)
->willReturn($reportResult);
$this->activityService->expects($this->once())
->method('getActivityIdsForSavedSearch')
->willReturn([]);
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide
app ~/jiminny/app
.circleci
.cursor
.github
.sonarlint
.vscode
.windsurf
app, sources root
Actions
Component
Configuration
Console
Commands
Activities
Analytics
Calendars
Crm
DealInsights
Dev
Dialers
DTOs
Elasticsearch
EngagementStats
GeckoExport
Livestream
Mailboxes
Migrate
PlaybackThemes
Playbooks
Playlists
Postmark
ProphetAi
Reports
AutomatedReportsCommand.php, class
AutomatedReportsRetentionPolicyCommand.php, class
AutomatedReportsSendCommand.php, class
CreateMockAskJiminnyReportResultCommand.php, class
DeleteReportCommand.php, class
GenerateMarketingReport.php, class
Team.php, class
Usage.php, class
Slack
Teams
Tracks
Transcription
Twilio
Users
Vocabulary
Zoom
CoachingFeedbacksUpdateEsActivities.php, class
Command.php, class
CreateDatabaseUsers.php, class
DatabaseTableCount.php, class
DeleteOldAiCrmNotesCommand.php, class
DeleteS3LeftoversCommand.php, class
DevPostmanCommand.php, final class
DiarizeViaAiParticipantIdentificationCommand.php, class
EncryptTokensCommand.php, class
EngagementStatsRegenerateCommand.php, class
FeatureFlagsHelper.php...
|
NULL
|
|
9466
|
182
|
13
|
2026-04-14T07:39:48.514497+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776152388514_m1.jpg...
|
PhpStorm
|
faVsco.js – AutomatedReportsCommand.php
|
True
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
#11894 on JY-18909-automa Project: faVsco.js, menu
#11894 on JY-18909-automated-reports-ask-jiminny, menu
Start Listening for PHP Debug Connections
RequestGenerateAskJiminnyReportJobTest
Run 'RequestGenerateAskJiminnyReportJobTest'
Debug 'RequestGenerateAskJiminnyReportJobTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Console\Commands\Reports;
use Carbon\Carbon;
use Illuminate\Console\Command;
use Illuminate\Contracts\Bus\Dispatcher as BusDispatcher;
use Jiminny\Jobs\AutomatedReports\RequestGenerateAskJiminnyReportJob;
use Jiminny\Jobs\AutomatedReports\RequestGenerateReportJob;
use Jiminny\Models\AutomatedReport;
use Jiminny\Repositories\AutomatedReportsRepository;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Psr\Log\LoggerInterface;
class AutomatedReportsCommand extends Command
{
/**
* Log prefix for all log messages
*/
private const string LOG_PREFIX = '[automated-reports]';
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'automated-reports';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Process automated reports based on their frequency (weekly, monthly, quarterly)';
public function __construct(
private readonly LoggerInterface $logger,
private readonly BusDispatcher $dispatcher,
private readonly AutomatedReportsRepository $reportRepository
) {
parent::__construct();
}
/**
* Execute the console command.
*
* @return int
*/
public function handle(): int
{
$this->logger->info(self::LOG_PREFIX . ' Started');
$now = Carbon::now();
$isMonday = $now->isMonday();
$isFirstDayOfMonth = $now->day === 1;
$currentMonth = $now->month;
// Check if the current month is a quarterly month (January, April, July, October)
$isQuarterlyMonth = in_array($currentMonth, [1, 4, 7, 10], true);
$this->logger->info(self::LOG_PREFIX . ' Checking conditions', [
'isMonday' => $isMonday,
'isFirstDayOfMonth' => $isFirstDayOfMonth,
'currentMonth' => $currentMonth,
'isQuarterlyMonth' => $isQuarterlyMonth,
]);
// Process daily reports
$this->processReports(AutomatedReportsService::FREQUENCY_DAILY);
// Process weekly reports on Mondays
if ($isMonday) {
$this->processReports(AutomatedReportsService::FREQUENCY_WEEKLY);
}
// Process monthly reports on the first day of the month
if ($isFirstDayOfMonth) {
$this->processReports(AutomatedReportsService::FREQUENCY_MONTHLY);
}
// Process quarterly reports on the first day of January, April, July, and October
if ($isFirstDayOfMonth && $isQuarterlyMonth) {
$this->processReports(AutomatedReportsService::FREQUENCY_QUARTERLY);
}
$this->logger->info(self::LOG_PREFIX . ' Completed');
return 0;
}
/**
* Process reports for a specific frequency.
*
* @param string $frequency
*
* @return void
*/
private function processReports(string $frequency): void
{
$this->logger->info(self::LOG_PREFIX . " Processing $frequency reports");
// Get all enabled, not deleted reports with active teams for the specified frequency
$reports = $this->reportRepository->getActiveReportsByFrequency($frequency);
// $reports = collect([AutomatedReport::find(68)]);
$this->logger->info(self::LOG_PREFIX . " Found {$reports->count()} $frequency reports to process");
/** @var AutomatedReport $report */
foreach ($reports as $report) {
$this->logger->info(self::LOG_PREFIX . ' Dispatching Generate Report job for report', [
'reportUuid' => $report->getUuid(),
'teamId' => $report->getTeamId(),
'frequency' => $report->getFrequency(),
'type' => $report->getType(),
]);
$job = $report->isAskJiminnyReport()
? new RequestGenerateAskJiminnyReportJob($report->getUuid())
: new RequestGenerateReportJob($report->getUuid());
// $this->dispatcher->dispatch($job);
$this->dispatcher->dispatchSync($job);
}
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
1
14
4
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Tests\Unit\Jobs\AutomatedReports;
use Carbon\Carbon;
use Jiminny\Component\ProphetAi\Exceptions\ProphetException;
use Jiminny\Component\ProphetAi\ProphetClient;
use Jiminny\Jobs\AutomatedReports\RequestGenerateAskJiminnyReportJob;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\AutomatedReportResult;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityService;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
use Psr\Log\LoggerInterface;
class RequestGenerateAskJiminnyReportJobTest extends TestCase
{
private AutomatedReportsService&MockObject $reportService;
private AskJiminnyReportActivityService&MockObject $activityService;
private ProphetClient&MockObject $prophetClient;
private LoggerInterface&MockObject $logger;
protected function setUp(): void
{
$this->reportService = $this->createMock(AutomatedReportsService::class);
$this->activityService = $this->createMock(AskJiminnyReportActivityService::class);
$this->prophetClient = $this->createMock(ProphetClient::class);
$this->logger = $this->createMock(LoggerInterface::class);
}
private function makeJob(string $uuid = 'report-uuid'): RequestGenerateAskJiminnyReportJob
{
return new RequestGenerateAskJiminnyReportJob($uuid);
}
private function makeActiveReport(
string $type = AutomatedReportsService::TYPE_ASK_JIMINNY,
bool $status = true,
string $teamStatus = Team::STATUS_ACTIVE,
): AutomatedReport&MockObject { // @phpstan-ignore-line
$team = $this->createMock(Team::class);
$team->method('getStatus')->willReturn($teamStatus);
$report = $this->createMock(AutomatedReport::class);
$report->method('getType')->willReturn($type);
$report->method('getStatus')->willReturn($status);
$report->method('getTeam')->willReturn($team);
return $report;
}
public function testUniqueIdReturnsReportUuid(): void
{
$job = $this->makeJob('my-unique-uuid');
$this->assertEquals('my-unique-uuid', $job->uniqueId());
}
public function testHandleSkipsWhenReportTypeIsNotAskJiminny(): void
{
$report = $this->makeActiveReport(type: 'exec_summary');
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->logger->expects($this->once())
->method('info')
->with($this->stringContains('Started'));
$this->logger->expects($this->once())
->method('warning')
->with($this->stringContains('not an ask_jiminny report'));
$this->reportService->expects($this->never())->method('createReportResult');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleSkipsWhenReportIsInactive(): void
{
$report = $this->makeActiveReport(status: false);
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->logger->expects($this->exactly(2))
->method('info');
$this->reportService->expects($this->never())->method('createReportResult');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleSkipsWhenTeamIsInactive(): void
{
$report = $this->makeActiveReport(teamStatus: Team::STATUS_DEACTIVATED);
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->logger->expects($this->exactly(2))
->method('info');
$this->reportService->expects($this->never())->method('createReportResult');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleSkipsWhenCreatorIsNull(): void
{
$report = $this->makeActiveReport();
$report->method('getCreator')->willReturn(null);
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->logger->expects($this->once())
->method('warning')
->with($this->stringContains('report creator not found'));
$this->reportService->expects($this->never())->method('createReportResult');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleSkipsWhenSavedSearchIsNull(): void
{
$creator = $this->createMock(User::class);
$report = $this->makeActiveReport();
$report->method('getCreator')->willReturn($creator);
$report->method('getSavedSearch')->willReturn(null);
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->logger->expects($this->once())
->method('warning')
->with($this->stringContains('saved search not found'));
$this->reportService->expects($this->never())->method('createReportResult');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleSkipsWhenPromptIsNull(): void
{
$creator = $this->createMock(User::class);
$savedSearch = $this->createMock(\Jiminny\Models\Activity\Search::class);
$report = $this->makeActiveReport();
$report->method('getCreator')->willReturn($creator);
$report->method('getSavedSearch')->willReturn($savedSearch);
$report->method('getAskAnythingPrompt')->willReturn(null);
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->logger->expects($this->once())
->method('warning')
->with($this->stringContains('ask anything prompt not found'));
$this->reportService->expects($this->never())->method('createReportResult');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleFailsReportWhenNotEnoughActivities(): void
{
$creator = $this->createMock(User::class);
$savedSearch = $this->createMock(\Jiminny\Models\Activity\Search::class);
$prompt = $this->createMock(\Jiminny\Models\AskAnything\AskAnythingPrompt::class);
$report = $this->makeActiveReport();
$report->method('getCreator')->willReturn($creator);
$report->method('getSavedSearch')->willReturn($savedSearch);
$report->method('getAskAnythingPrompt')->willReturn($prompt);
$reportResult = $this->createMock(AutomatedReportResult::class);
$reportResult->expects($this->once())
->method('update')
->with($this->callback(fn ($data) => $data['status'] === AutomatedReportResult::STATUS_FAILED
&& $data['reason'] === AutomatedReportResult::REASON_NOT_ENOUGH_ACTIVITIES));
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->reportService->expects($this->once())
->method('createReportResult')
->willReturn($reportResult);
$this->activityService->expects($this->once())
->method('getActivityIdsForSavedSearch')
->willReturn([]);
$this->logger->expects($this->exactly(3))
->method('info');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleSuccessfullyRequestsReport(): void
{
Carbon::setTestNow(Carbon::parse('2026-04-07 10:00:00'));
$creator = $this->createMock(User::class);
$savedSearch = $this->createMock(\Jiminny\Models\Activity\Search::class);
$prompt = $this->createMock(\Jiminny\Models\AskAnything\AskAnythingPrompt::class);
$report = $this->makeActiveReport();
$report->method('getCreator')->willReturn($creator);
$report->method('getSavedSearch')->willReturn($savedSearch);
$report->method('getAskAnythingPrompt')->willReturn($prompt);
$report->method('getUuid')->willReturn('report-uuid');
$reportResult = $this->createMock(AutomatedReportResult::class);
$reportResult->method('getUuid')->willReturn('result-uuid');
$reportResult->expects($this->once())
->method('update')
->with($this->callback(fn ($data) => $data['status'] === AutomatedReportResult::STATUS_REQUESTED
&& isset($data['name'], $data['payload'], $data['requested_at'])));
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->reportService->expects($this->once())
->method('createReportResult')
->willReturn($reportResult);
$this->reportService->expects($this->once())
->method('getAskJiminnyGenerateReportPayload')
->willReturn(['key' => 'value']);
$this->reportService->expects($this->once())
->method('getReportFileName')
->willReturn('My Report - 7 Apr 2026');
$this->activityService->expects($this->once())
->method('getActivityIdsForSavedSearch')
->willReturn(['act-1', 'act-2']);
$this->prophetClient->expects($this->once())
->method('sendRequest')
->willReturn(new \Jiminny\Component\ProphetAi\Dtos\ProphetResponseDto([]));
$this->logger->expects($this->exactly(4))
->method('info');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
Carbon::setTestNow();
}
public function testHandleCatchesGenericExceptionAndLogsError(): void
{
$this->reportService->expects($this->once())
->method('getReport')
->willThrowException(new \RuntimeException('DB error'));
$this->logger->expects($this->once())
->method('error')
->with($this->stringContains('Error'));
$job = $this->makeJob();
$reflection = new \ReflectionClass($job);
$triesProp = $reflection->getProperty('tries');
$triesProp->setAccessible(true);
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleCatchesProphetExceptionAndSetsCorrectReason(): void
{
$creator = $this->createMock(User::class);
$savedSearch = $this->createMock(\Jiminny\Models\Activity\Search::class);
$prompt = $this->createMock(\Jiminny\Models\AskAnything\AskAnythingPrompt::class);
$report = $this->makeActiveReport();
$report->method('getCreator')->willReturn($creator);
$report->method('getSavedSearch')->willReturn($savedSearch);
$report->method('getAskAnythingPrompt')->willReturn($prompt);
$reportResult = $this->createMock(AutomatedReportResult::class);
$reportResult->method('getUuid')->willReturn('result-uuid');
$reportResult->expects($this->once())
->method('update')
->with($this->callback(fn ($data) => $data['reason'] === AutomatedReportResult::REASON_PROPHET_API_ERROR));
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->reportService->expects($this->once())
->method('createReportResult')
->willReturn($reportResult);
$this->activityService->expects($this->once())
->method('getActivityIdsForSavedSearch')
->willThrowException(new ProphetException('Prophet failed'));
$this->logger->expects($this->once())
->method('error');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleCreatesReportResultBeforeActivityFetch(): void
{
$creator = $this->createMock(User::class);
$savedSearch = $this->createMock(\Jiminny\Models\Activity\Search::class);
$prompt = $this->createMock(\Jiminny\Models\AskAnything\AskAnythingPrompt::class);
$report = $this->makeActiveReport();
$report->method('getCreator')->willReturn($creator);
$report->method('getSavedSearch')->willReturn($savedSearch);
$report->method('getAskAnythingPrompt')->willReturn($prompt);
$reportResult = $this->createMock(AutomatedReportResult::class);
$reportResult->method('getUuid')->willReturn('result-uuid');
$callOrder = [];
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->reportService->expects($this->once())
->method('createReportResult')
->willReturnCallback(function () use ($reportResult, &$callOrder) {
$callOrder[] = 'createReportResult';
return $reportResult;
});
$this->activityService->expects($this->once())
->method('getActivityIdsForSavedSearch')
->willReturnCallback(function () use (&$callOrder) {
$callOrder[] = 'getActivityIds';
return [];
});
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
$this->assertEquals(['createReportResult', 'getActivityIds'], $callOrder);
}
public function testHandlePassesCorrectDataToCreateReportResult(): void
{
$creator = $this->createMock(User::class);
$savedSearch = $this->createMock(\Jiminny\Models\Activity\Search::class);
$prompt = $this->createMock(\Jiminny\Models\AskAnything\AskAnythingPrompt::class);
$report = $this->makeActiveReport();
$report->method('getCreator')->willReturn($creator);
$report->method('getSavedSearch')->willReturn($savedSearch);
$report->method('getAskAnythingPrompt')->willReturn($prompt);
$reportResult = $this->createMock(AutomatedReportResult::class);
$reportResult->method('getUuid')->willReturn('result-uuid');
$reportResult->method('update')->willReturn(true);
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->reportService->expects($this->once())
->method('createReportResult')
->with(
automatedReport: $report,
data: $this->callback(fn ($data) => $data['status'] === AutomatedReportResult::STATUS_DEFAULT
&& $data['media_type'] === AutomatedReportsService::MEDIA_TYPE_PDF)
)
->willReturn($reportResult);
$this->activityService->expects($this->once())
->method('getActivityIdsForSavedSearch')
->willReturn([]);
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide
app ~/jiminny/app
.circleci
.cursor
.github
.sonarlint
.vscode
.windsurf
app, sources root
Actions
Component
Configuration
Console
Commands
Activities
Analytics
Calendars
Crm
DealInsights
Dev
Dialers
DTOs
Elasticsearch
EngagementStats
GeckoExport
Livestream
Mailboxes
Migrate
PlaybackThemes
Playbooks
Playlists
Postmark
ProphetAi
Reports
AutomatedReportsCommand.php, class
AutomatedReportsRetentionPolicyCommand.php, class
AutomatedReportsSendCommand.php, class
CreateMockAskJiminnyReportResultCommand.php, class
DeleteReportCommand.php, class
GenerateMarketingReport.php, class
Team.php, class
Usage.php, class
Slack
Teams...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"#11894 on JY-18909-automated-reports-ask-jiminny, menu","depth":5,"help_text":"Pull request #11894 exists for current branch JY-18909-automated-reports-ask-jiminny, but local branch is out of sync with remote","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"RequestGenerateAskJiminnyReportJobTest","depth":6,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'RequestGenerateAskJiminnyReportJobTest'","depth":6,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'RequestGenerateAskJiminnyReportJobTest'","depth":6,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Console\\Commands\\Reports;\n\nuse Carbon\\Carbon;\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Contracts\\Bus\\Dispatcher as BusDispatcher;\nuse Jiminny\\Jobs\\AutomatedReports\\RequestGenerateAskJiminnyReportJob;\nuse Jiminny\\Jobs\\AutomatedReports\\RequestGenerateReportJob;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Repositories\\AutomatedReportsRepository;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Psr\\Log\\LoggerInterface;\n\nclass AutomatedReportsCommand extends Command\n{\n /**\n * Log prefix for all log messages\n */\n private const string LOG_PREFIX = '[automated-reports]';\n\n /**\n * The name and signature of the console command.\n *\n * @var string\n */\n protected $signature = 'automated-reports';\n\n /**\n * The console command description.\n *\n * @var string\n */\n protected $description = 'Process automated reports based on their frequency (weekly, monthly, quarterly)';\n\n\n public function __construct(\n private readonly LoggerInterface $logger,\n private readonly BusDispatcher $dispatcher,\n private readonly AutomatedReportsRepository $reportRepository\n ) {\n parent::__construct();\n }\n\n /**\n * Execute the console command.\n *\n * @return int\n */\n public function handle(): int\n {\n $this->logger->info(self::LOG_PREFIX . ' Started');\n\n $now = Carbon::now();\n $isMonday = $now->isMonday();\n $isFirstDayOfMonth = $now->day === 1;\n $currentMonth = $now->month;\n\n // Check if the current month is a quarterly month (January, April, July, October)\n $isQuarterlyMonth = in_array($currentMonth, [1, 4, 7, 10], true);\n\n $this->logger->info(self::LOG_PREFIX . ' Checking conditions', [\n 'isMonday' => $isMonday,\n 'isFirstDayOfMonth' => $isFirstDayOfMonth,\n 'currentMonth' => $currentMonth,\n 'isQuarterlyMonth' => $isQuarterlyMonth,\n ]);\n\n // Process daily reports\n $this->processReports(AutomatedReportsService::FREQUENCY_DAILY);\n\n // Process weekly reports on Mondays\n if ($isMonday) {\n $this->processReports(AutomatedReportsService::FREQUENCY_WEEKLY);\n }\n\n // Process monthly reports on the first day of the month\n if ($isFirstDayOfMonth) {\n $this->processReports(AutomatedReportsService::FREQUENCY_MONTHLY);\n }\n\n // Process quarterly reports on the first day of January, April, July, and October\n if ($isFirstDayOfMonth && $isQuarterlyMonth) {\n $this->processReports(AutomatedReportsService::FREQUENCY_QUARTERLY);\n }\n\n $this->logger->info(self::LOG_PREFIX . ' Completed');\n\n return 0;\n }\n\n /**\n * Process reports for a specific frequency.\n *\n * @param string $frequency\n *\n * @return void\n */\n private function processReports(string $frequency): void\n {\n $this->logger->info(self::LOG_PREFIX . \" Processing $frequency reports\");\n\n // Get all enabled, not deleted reports with active teams for the specified frequency\n $reports = $this->reportRepository->getActiveReportsByFrequency($frequency);\n // $reports = collect([AutomatedReport::find(68)]);\n\n $this->logger->info(self::LOG_PREFIX . \" Found {$reports->count()} $frequency reports to process\");\n\n /** @var AutomatedReport $report */\n foreach ($reports as $report) {\n $this->logger->info(self::LOG_PREFIX . ' Dispatching Generate Report job for report', [\n 'reportUuid' => $report->getUuid(),\n 'teamId' => $report->getTeamId(),\n 'frequency' => $report->getFrequency(),\n 'type' => $report->getType(),\n ]);\n\n $job = $report->isAskJiminnyReport()\n ? new RequestGenerateAskJiminnyReportJob($report->getUuid())\n : new RequestGenerateReportJob($report->getUuid());\n\n // $this->dispatcher->dispatch($job);\n $this->dispatcher->dispatchSync($job);\n }\n }\n}","depth":4,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Console\\Commands\\Reports;\n\nuse Carbon\\Carbon;\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Contracts\\Bus\\Dispatcher as BusDispatcher;\nuse Jiminny\\Jobs\\AutomatedReports\\RequestGenerateAskJiminnyReportJob;\nuse Jiminny\\Jobs\\AutomatedReports\\RequestGenerateReportJob;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Repositories\\AutomatedReportsRepository;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Psr\\Log\\LoggerInterface;\n\nclass AutomatedReportsCommand extends Command\n{\n /**\n * Log prefix for all log messages\n */\n private const string LOG_PREFIX = '[automated-reports]';\n\n /**\n * The name and signature of the console command.\n *\n * @var string\n */\n protected $signature = 'automated-reports';\n\n /**\n * The console command description.\n *\n * @var string\n */\n protected $description = 'Process automated reports based on their frequency (weekly, monthly, quarterly)';\n\n\n public function __construct(\n private readonly LoggerInterface $logger,\n private readonly BusDispatcher $dispatcher,\n private readonly AutomatedReportsRepository $reportRepository\n ) {\n parent::__construct();\n }\n\n /**\n * Execute the console command.\n *\n * @return int\n */\n public function handle(): int\n {\n $this->logger->info(self::LOG_PREFIX . ' Started');\n\n $now = Carbon::now();\n $isMonday = $now->isMonday();\n $isFirstDayOfMonth = $now->day === 1;\n $currentMonth = $now->month;\n\n // Check if the current month is a quarterly month (January, April, July, October)\n $isQuarterlyMonth = in_array($currentMonth, [1, 4, 7, 10], true);\n\n $this->logger->info(self::LOG_PREFIX . ' Checking conditions', [\n 'isMonday' => $isMonday,\n 'isFirstDayOfMonth' => $isFirstDayOfMonth,\n 'currentMonth' => $currentMonth,\n 'isQuarterlyMonth' => $isQuarterlyMonth,\n ]);\n\n // Process daily reports\n $this->processReports(AutomatedReportsService::FREQUENCY_DAILY);\n\n // Process weekly reports on Mondays\n if ($isMonday) {\n $this->processReports(AutomatedReportsService::FREQUENCY_WEEKLY);\n }\n\n // Process monthly reports on the first day of the month\n if ($isFirstDayOfMonth) {\n $this->processReports(AutomatedReportsService::FREQUENCY_MONTHLY);\n }\n\n // Process quarterly reports on the first day of January, April, July, and October\n if ($isFirstDayOfMonth && $isQuarterlyMonth) {\n $this->processReports(AutomatedReportsService::FREQUENCY_QUARTERLY);\n }\n\n $this->logger->info(self::LOG_PREFIX . ' Completed');\n\n return 0;\n }\n\n /**\n * Process reports for a specific frequency.\n *\n * @param string $frequency\n *\n * @return void\n */\n private function processReports(string $frequency): void\n {\n $this->logger->info(self::LOG_PREFIX . \" Processing $frequency reports\");\n\n // Get all enabled, not deleted reports with active teams for the specified frequency\n $reports = $this->reportRepository->getActiveReportsByFrequency($frequency);\n // $reports = collect([AutomatedReport::find(68)]);\n\n $this->logger->info(self::LOG_PREFIX . \" Found {$reports->count()} $frequency reports to process\");\n\n /** @var AutomatedReport $report */\n foreach ($reports as $report) {\n $this->logger->info(self::LOG_PREFIX . ' Dispatching Generate Report job for report', [\n 'reportUuid' => $report->getUuid(),\n 'teamId' => $report->getTeamId(),\n 'frequency' => $report->getFrequency(),\n 'type' => $report->getType(),\n ]);\n\n $job = $report->isAskJiminnyReport()\n ? new RequestGenerateAskJiminnyReportJob($report->getUuid())\n : new RequestGenerateReportJob($report->getUuid());\n\n // $this->dispatcher->dispatch($job);\n $this->dispatcher->dispatchSync($job);\n }\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"1","depth":4,"role_description":"text"},{"role":"AXStaticText","text":"14","depth":4,"role_description":"text"},{"role":"AXStaticText","text":"4","depth":4,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Tests\\Unit\\Jobs\\AutomatedReports;\n\nuse Carbon\\Carbon;\nuse Jiminny\\Component\\ProphetAi\\Exceptions\\ProphetException;\nuse Jiminny\\Component\\ProphetAi\\ProphetClient;\nuse Jiminny\\Jobs\\AutomatedReports\\RequestGenerateAskJiminnyReportJob;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Models\\AutomatedReportResult;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AskJiminnyReportActivityService;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse PHPUnit\\Framework\\MockObject\\MockObject;\nuse PHPUnit\\Framework\\TestCase;\nuse Psr\\Log\\LoggerInterface;\n\nclass RequestGenerateAskJiminnyReportJobTest extends TestCase\n{\n private AutomatedReportsService&MockObject $reportService;\n private AskJiminnyReportActivityService&MockObject $activityService;\n private ProphetClient&MockObject $prophetClient;\n private LoggerInterface&MockObject $logger;\n\n protected function setUp(): void\n {\n $this->reportService = $this->createMock(AutomatedReportsService::class);\n $this->activityService = $this->createMock(AskJiminnyReportActivityService::class);\n $this->prophetClient = $this->createMock(ProphetClient::class);\n $this->logger = $this->createMock(LoggerInterface::class);\n }\n\n private function makeJob(string $uuid = 'report-uuid'): RequestGenerateAskJiminnyReportJob\n {\n return new RequestGenerateAskJiminnyReportJob($uuid);\n }\n\n private function makeActiveReport(\n string $type = AutomatedReportsService::TYPE_ASK_JIMINNY,\n bool $status = true,\n string $teamStatus = Team::STATUS_ACTIVE,\n ): AutomatedReport&MockObject { // @phpstan-ignore-line\n $team = $this->createMock(Team::class);\n $team->method('getStatus')->willReturn($teamStatus);\n\n $report = $this->createMock(AutomatedReport::class);\n $report->method('getType')->willReturn($type);\n $report->method('getStatus')->willReturn($status);\n $report->method('getTeam')->willReturn($team);\n\n return $report;\n }\n\n public function testUniqueIdReturnsReportUuid(): void\n {\n $job = $this->makeJob('my-unique-uuid');\n\n $this->assertEquals('my-unique-uuid', $job->uniqueId());\n }\n\n public function testHandleSkipsWhenReportTypeIsNotAskJiminny(): void\n {\n $report = $this->makeActiveReport(type: 'exec_summary');\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->logger->expects($this->once())\n ->method('info')\n ->with($this->stringContains('Started'));\n\n $this->logger->expects($this->once())\n ->method('warning')\n ->with($this->stringContains('not an ask_jiminny report'));\n\n $this->reportService->expects($this->never())->method('createReportResult');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleSkipsWhenReportIsInactive(): void\n {\n $report = $this->makeActiveReport(status: false);\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->logger->expects($this->exactly(2))\n ->method('info');\n\n $this->reportService->expects($this->never())->method('createReportResult');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleSkipsWhenTeamIsInactive(): void\n {\n $report = $this->makeActiveReport(teamStatus: Team::STATUS_DEACTIVATED);\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->logger->expects($this->exactly(2))\n ->method('info');\n\n $this->reportService->expects($this->never())->method('createReportResult');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleSkipsWhenCreatorIsNull(): void\n {\n $report = $this->makeActiveReport();\n $report->method('getCreator')->willReturn(null);\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->logger->expects($this->once())\n ->method('warning')\n ->with($this->stringContains('report creator not found'));\n\n $this->reportService->expects($this->never())->method('createReportResult');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleSkipsWhenSavedSearchIsNull(): void\n {\n $creator = $this->createMock(User::class);\n\n $report = $this->makeActiveReport();\n $report->method('getCreator')->willReturn($creator);\n $report->method('getSavedSearch')->willReturn(null);\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->logger->expects($this->once())\n ->method('warning')\n ->with($this->stringContains('saved search not found'));\n\n $this->reportService->expects($this->never())->method('createReportResult');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleSkipsWhenPromptIsNull(): void\n {\n $creator = $this->createMock(User::class);\n $savedSearch = $this->createMock(\\Jiminny\\Models\\Activity\\Search::class);\n\n $report = $this->makeActiveReport();\n $report->method('getCreator')->willReturn($creator);\n $report->method('getSavedSearch')->willReturn($savedSearch);\n $report->method('getAskAnythingPrompt')->willReturn(null);\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->logger->expects($this->once())\n ->method('warning')\n ->with($this->stringContains('ask anything prompt not found'));\n\n $this->reportService->expects($this->never())->method('createReportResult');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleFailsReportWhenNotEnoughActivities(): void\n {\n $creator = $this->createMock(User::class);\n $savedSearch = $this->createMock(\\Jiminny\\Models\\Activity\\Search::class);\n $prompt = $this->createMock(\\Jiminny\\Models\\AskAnything\\AskAnythingPrompt::class);\n\n $report = $this->makeActiveReport();\n $report->method('getCreator')->willReturn($creator);\n $report->method('getSavedSearch')->willReturn($savedSearch);\n $report->method('getAskAnythingPrompt')->willReturn($prompt);\n\n $reportResult = $this->createMock(AutomatedReportResult::class);\n $reportResult->expects($this->once())\n ->method('update')\n ->with($this->callback(fn ($data) => $data['status'] === AutomatedReportResult::STATUS_FAILED\n && $data['reason'] === AutomatedReportResult::REASON_NOT_ENOUGH_ACTIVITIES));\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->reportService->expects($this->once())\n ->method('createReportResult')\n ->willReturn($reportResult);\n\n $this->activityService->expects($this->once())\n ->method('getActivityIdsForSavedSearch')\n ->willReturn([]);\n\n $this->logger->expects($this->exactly(3))\n ->method('info');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleSuccessfullyRequestsReport(): void\n {\n Carbon::setTestNow(Carbon::parse('2026-04-07 10:00:00'));\n\n $creator = $this->createMock(User::class);\n $savedSearch = $this->createMock(\\Jiminny\\Models\\Activity\\Search::class);\n $prompt = $this->createMock(\\Jiminny\\Models\\AskAnything\\AskAnythingPrompt::class);\n\n $report = $this->makeActiveReport();\n $report->method('getCreator')->willReturn($creator);\n $report->method('getSavedSearch')->willReturn($savedSearch);\n $report->method('getAskAnythingPrompt')->willReturn($prompt);\n $report->method('getUuid')->willReturn('report-uuid');\n\n $reportResult = $this->createMock(AutomatedReportResult::class);\n $reportResult->method('getUuid')->willReturn('result-uuid');\n $reportResult->expects($this->once())\n ->method('update')\n ->with($this->callback(fn ($data) => $data['status'] === AutomatedReportResult::STATUS_REQUESTED\n && isset($data['name'], $data['payload'], $data['requested_at'])));\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->reportService->expects($this->once())\n ->method('createReportResult')\n ->willReturn($reportResult);\n\n $this->reportService->expects($this->once())\n ->method('getAskJiminnyGenerateReportPayload')\n ->willReturn(['key' => 'value']);\n\n $this->reportService->expects($this->once())\n ->method('getReportFileName')\n ->willReturn('My Report - 7 Apr 2026');\n\n $this->activityService->expects($this->once())\n ->method('getActivityIdsForSavedSearch')\n ->willReturn(['act-1', 'act-2']);\n\n $this->prophetClient->expects($this->once())\n ->method('sendRequest')\n ->willReturn(new \\Jiminny\\Component\\ProphetAi\\Dtos\\ProphetResponseDto([]));\n\n $this->logger->expects($this->exactly(4))\n ->method('info');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n\n Carbon::setTestNow();\n }\n\n public function testHandleCatchesGenericExceptionAndLogsError(): void\n {\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willThrowException(new \\RuntimeException('DB error'));\n\n $this->logger->expects($this->once())\n ->method('error')\n ->with($this->stringContains('Error'));\n\n $job = $this->makeJob();\n\n $reflection = new \\ReflectionClass($job);\n $triesProp = $reflection->getProperty('tries');\n $triesProp->setAccessible(true);\n\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleCatchesProphetExceptionAndSetsCorrectReason(): void\n {\n $creator = $this->createMock(User::class);\n $savedSearch = $this->createMock(\\Jiminny\\Models\\Activity\\Search::class);\n $prompt = $this->createMock(\\Jiminny\\Models\\AskAnything\\AskAnythingPrompt::class);\n\n $report = $this->makeActiveReport();\n $report->method('getCreator')->willReturn($creator);\n $report->method('getSavedSearch')->willReturn($savedSearch);\n $report->method('getAskAnythingPrompt')->willReturn($prompt);\n\n $reportResult = $this->createMock(AutomatedReportResult::class);\n $reportResult->method('getUuid')->willReturn('result-uuid');\n $reportResult->expects($this->once())\n ->method('update')\n ->with($this->callback(fn ($data) => $data['reason'] === AutomatedReportResult::REASON_PROPHET_API_ERROR));\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->reportService->expects($this->once())\n ->method('createReportResult')\n ->willReturn($reportResult);\n\n $this->activityService->expects($this->once())\n ->method('getActivityIdsForSavedSearch')\n ->willThrowException(new ProphetException('Prophet failed'));\n\n $this->logger->expects($this->once())\n ->method('error');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleCreatesReportResultBeforeActivityFetch(): void\n {\n $creator = $this->createMock(User::class);\n $savedSearch = $this->createMock(\\Jiminny\\Models\\Activity\\Search::class);\n $prompt = $this->createMock(\\Jiminny\\Models\\AskAnything\\AskAnythingPrompt::class);\n\n $report = $this->makeActiveReport();\n $report->method('getCreator')->willReturn($creator);\n $report->method('getSavedSearch')->willReturn($savedSearch);\n $report->method('getAskAnythingPrompt')->willReturn($prompt);\n\n $reportResult = $this->createMock(AutomatedReportResult::class);\n $reportResult->method('getUuid')->willReturn('result-uuid');\n\n $callOrder = [];\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->reportService->expects($this->once())\n ->method('createReportResult')\n ->willReturnCallback(function () use ($reportResult, &$callOrder) {\n $callOrder[] = 'createReportResult';\n\n return $reportResult;\n });\n\n $this->activityService->expects($this->once())\n ->method('getActivityIdsForSavedSearch')\n ->willReturnCallback(function () use (&$callOrder) {\n $callOrder[] = 'getActivityIds';\n\n return [];\n });\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n\n $this->assertEquals(['createReportResult', 'getActivityIds'], $callOrder);\n }\n\n public function testHandlePassesCorrectDataToCreateReportResult(): void\n {\n $creator = $this->createMock(User::class);\n $savedSearch = $this->createMock(\\Jiminny\\Models\\Activity\\Search::class);\n $prompt = $this->createMock(\\Jiminny\\Models\\AskAnything\\AskAnythingPrompt::class);\n\n $report = $this->makeActiveReport();\n $report->method('getCreator')->willReturn($creator);\n $report->method('getSavedSearch')->willReturn($savedSearch);\n $report->method('getAskAnythingPrompt')->willReturn($prompt);\n\n $reportResult = $this->createMock(AutomatedReportResult::class);\n $reportResult->method('getUuid')->willReturn('result-uuid');\n $reportResult->method('update')->willReturn(true);\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->reportService->expects($this->once())\n ->method('createReportResult')\n ->with(\n automatedReport: $report,\n data: $this->callback(fn ($data) => $data['status'] === AutomatedReportResult::STATUS_DEFAULT\n && $data['media_type'] === AutomatedReportsService::MEDIA_TYPE_PDF)\n )\n ->willReturn($reportResult);\n\n $this->activityService->expects($this->once())\n ->method('getActivityIdsForSavedSearch')\n ->willReturn([]);\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n}","depth":4,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Tests\\Unit\\Jobs\\AutomatedReports;\n\nuse Carbon\\Carbon;\nuse Jiminny\\Component\\ProphetAi\\Exceptions\\ProphetException;\nuse Jiminny\\Component\\ProphetAi\\ProphetClient;\nuse Jiminny\\Jobs\\AutomatedReports\\RequestGenerateAskJiminnyReportJob;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Models\\AutomatedReportResult;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AskJiminnyReportActivityService;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse PHPUnit\\Framework\\MockObject\\MockObject;\nuse PHPUnit\\Framework\\TestCase;\nuse Psr\\Log\\LoggerInterface;\n\nclass RequestGenerateAskJiminnyReportJobTest extends TestCase\n{\n private AutomatedReportsService&MockObject $reportService;\n private AskJiminnyReportActivityService&MockObject $activityService;\n private ProphetClient&MockObject $prophetClient;\n private LoggerInterface&MockObject $logger;\n\n protected function setUp(): void\n {\n $this->reportService = $this->createMock(AutomatedReportsService::class);\n $this->activityService = $this->createMock(AskJiminnyReportActivityService::class);\n $this->prophetClient = $this->createMock(ProphetClient::class);\n $this->logger = $this->createMock(LoggerInterface::class);\n }\n\n private function makeJob(string $uuid = 'report-uuid'): RequestGenerateAskJiminnyReportJob\n {\n return new RequestGenerateAskJiminnyReportJob($uuid);\n }\n\n private function makeActiveReport(\n string $type = AutomatedReportsService::TYPE_ASK_JIMINNY,\n bool $status = true,\n string $teamStatus = Team::STATUS_ACTIVE,\n ): AutomatedReport&MockObject { // @phpstan-ignore-line\n $team = $this->createMock(Team::class);\n $team->method('getStatus')->willReturn($teamStatus);\n\n $report = $this->createMock(AutomatedReport::class);\n $report->method('getType')->willReturn($type);\n $report->method('getStatus')->willReturn($status);\n $report->method('getTeam')->willReturn($team);\n\n return $report;\n }\n\n public function testUniqueIdReturnsReportUuid(): void\n {\n $job = $this->makeJob('my-unique-uuid');\n\n $this->assertEquals('my-unique-uuid', $job->uniqueId());\n }\n\n public function testHandleSkipsWhenReportTypeIsNotAskJiminny(): void\n {\n $report = $this->makeActiveReport(type: 'exec_summary');\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->logger->expects($this->once())\n ->method('info')\n ->with($this->stringContains('Started'));\n\n $this->logger->expects($this->once())\n ->method('warning')\n ->with($this->stringContains('not an ask_jiminny report'));\n\n $this->reportService->expects($this->never())->method('createReportResult');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleSkipsWhenReportIsInactive(): void\n {\n $report = $this->makeActiveReport(status: false);\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->logger->expects($this->exactly(2))\n ->method('info');\n\n $this->reportService->expects($this->never())->method('createReportResult');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleSkipsWhenTeamIsInactive(): void\n {\n $report = $this->makeActiveReport(teamStatus: Team::STATUS_DEACTIVATED);\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->logger->expects($this->exactly(2))\n ->method('info');\n\n $this->reportService->expects($this->never())->method('createReportResult');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleSkipsWhenCreatorIsNull(): void\n {\n $report = $this->makeActiveReport();\n $report->method('getCreator')->willReturn(null);\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->logger->expects($this->once())\n ->method('warning')\n ->with($this->stringContains('report creator not found'));\n\n $this->reportService->expects($this->never())->method('createReportResult');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleSkipsWhenSavedSearchIsNull(): void\n {\n $creator = $this->createMock(User::class);\n\n $report = $this->makeActiveReport();\n $report->method('getCreator')->willReturn($creator);\n $report->method('getSavedSearch')->willReturn(null);\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->logger->expects($this->once())\n ->method('warning')\n ->with($this->stringContains('saved search not found'));\n\n $this->reportService->expects($this->never())->method('createReportResult');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleSkipsWhenPromptIsNull(): void\n {\n $creator = $this->createMock(User::class);\n $savedSearch = $this->createMock(\\Jiminny\\Models\\Activity\\Search::class);\n\n $report = $this->makeActiveReport();\n $report->method('getCreator')->willReturn($creator);\n $report->method('getSavedSearch')->willReturn($savedSearch);\n $report->method('getAskAnythingPrompt')->willReturn(null);\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->logger->expects($this->once())\n ->method('warning')\n ->with($this->stringContains('ask anything prompt not found'));\n\n $this->reportService->expects($this->never())->method('createReportResult');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleFailsReportWhenNotEnoughActivities(): void\n {\n $creator = $this->createMock(User::class);\n $savedSearch = $this->createMock(\\Jiminny\\Models\\Activity\\Search::class);\n $prompt = $this->createMock(\\Jiminny\\Models\\AskAnything\\AskAnythingPrompt::class);\n\n $report = $this->makeActiveReport();\n $report->method('getCreator')->willReturn($creator);\n $report->method('getSavedSearch')->willReturn($savedSearch);\n $report->method('getAskAnythingPrompt')->willReturn($prompt);\n\n $reportResult = $this->createMock(AutomatedReportResult::class);\n $reportResult->expects($this->once())\n ->method('update')\n ->with($this->callback(fn ($data) => $data['status'] === AutomatedReportResult::STATUS_FAILED\n && $data['reason'] === AutomatedReportResult::REASON_NOT_ENOUGH_ACTIVITIES));\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->reportService->expects($this->once())\n ->method('createReportResult')\n ->willReturn($reportResult);\n\n $this->activityService->expects($this->once())\n ->method('getActivityIdsForSavedSearch')\n ->willReturn([]);\n\n $this->logger->expects($this->exactly(3))\n ->method('info');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleSuccessfullyRequestsReport(): void\n {\n Carbon::setTestNow(Carbon::parse('2026-04-07 10:00:00'));\n\n $creator = $this->createMock(User::class);\n $savedSearch = $this->createMock(\\Jiminny\\Models\\Activity\\Search::class);\n $prompt = $this->createMock(\\Jiminny\\Models\\AskAnything\\AskAnythingPrompt::class);\n\n $report = $this->makeActiveReport();\n $report->method('getCreator')->willReturn($creator);\n $report->method('getSavedSearch')->willReturn($savedSearch);\n $report->method('getAskAnythingPrompt')->willReturn($prompt);\n $report->method('getUuid')->willReturn('report-uuid');\n\n $reportResult = $this->createMock(AutomatedReportResult::class);\n $reportResult->method('getUuid')->willReturn('result-uuid');\n $reportResult->expects($this->once())\n ->method('update')\n ->with($this->callback(fn ($data) => $data['status'] === AutomatedReportResult::STATUS_REQUESTED\n && isset($data['name'], $data['payload'], $data['requested_at'])));\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->reportService->expects($this->once())\n ->method('createReportResult')\n ->willReturn($reportResult);\n\n $this->reportService->expects($this->once())\n ->method('getAskJiminnyGenerateReportPayload')\n ->willReturn(['key' => 'value']);\n\n $this->reportService->expects($this->once())\n ->method('getReportFileName')\n ->willReturn('My Report - 7 Apr 2026');\n\n $this->activityService->expects($this->once())\n ->method('getActivityIdsForSavedSearch')\n ->willReturn(['act-1', 'act-2']);\n\n $this->prophetClient->expects($this->once())\n ->method('sendRequest')\n ->willReturn(new \\Jiminny\\Component\\ProphetAi\\Dtos\\ProphetResponseDto([]));\n\n $this->logger->expects($this->exactly(4))\n ->method('info');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n\n Carbon::setTestNow();\n }\n\n public function testHandleCatchesGenericExceptionAndLogsError(): void\n {\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willThrowException(new \\RuntimeException('DB error'));\n\n $this->logger->expects($this->once())\n ->method('error')\n ->with($this->stringContains('Error'));\n\n $job = $this->makeJob();\n\n $reflection = new \\ReflectionClass($job);\n $triesProp = $reflection->getProperty('tries');\n $triesProp->setAccessible(true);\n\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleCatchesProphetExceptionAndSetsCorrectReason(): void\n {\n $creator = $this->createMock(User::class);\n $savedSearch = $this->createMock(\\Jiminny\\Models\\Activity\\Search::class);\n $prompt = $this->createMock(\\Jiminny\\Models\\AskAnything\\AskAnythingPrompt::class);\n\n $report = $this->makeActiveReport();\n $report->method('getCreator')->willReturn($creator);\n $report->method('getSavedSearch')->willReturn($savedSearch);\n $report->method('getAskAnythingPrompt')->willReturn($prompt);\n\n $reportResult = $this->createMock(AutomatedReportResult::class);\n $reportResult->method('getUuid')->willReturn('result-uuid');\n $reportResult->expects($this->once())\n ->method('update')\n ->with($this->callback(fn ($data) => $data['reason'] === AutomatedReportResult::REASON_PROPHET_API_ERROR));\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->reportService->expects($this->once())\n ->method('createReportResult')\n ->willReturn($reportResult);\n\n $this->activityService->expects($this->once())\n ->method('getActivityIdsForSavedSearch')\n ->willThrowException(new ProphetException('Prophet failed'));\n\n $this->logger->expects($this->once())\n ->method('error');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleCreatesReportResultBeforeActivityFetch(): void\n {\n $creator = $this->createMock(User::class);\n $savedSearch = $this->createMock(\\Jiminny\\Models\\Activity\\Search::class);\n $prompt = $this->createMock(\\Jiminny\\Models\\AskAnything\\AskAnythingPrompt::class);\n\n $report = $this->makeActiveReport();\n $report->method('getCreator')->willReturn($creator);\n $report->method('getSavedSearch')->willReturn($savedSearch);\n $report->method('getAskAnythingPrompt')->willReturn($prompt);\n\n $reportResult = $this->createMock(AutomatedReportResult::class);\n $reportResult->method('getUuid')->willReturn('result-uuid');\n\n $callOrder = [];\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->reportService->expects($this->once())\n ->method('createReportResult')\n ->willReturnCallback(function () use ($reportResult, &$callOrder) {\n $callOrder[] = 'createReportResult';\n\n return $reportResult;\n });\n\n $this->activityService->expects($this->once())\n ->method('getActivityIdsForSavedSearch')\n ->willReturnCallback(function () use (&$callOrder) {\n $callOrder[] = 'getActivityIds';\n\n return [];\n });\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n\n $this->assertEquals(['createReportResult', 'getActivityIds'], $callOrder);\n }\n\n public function testHandlePassesCorrectDataToCreateReportResult(): void\n {\n $creator = $this->createMock(User::class);\n $savedSearch = $this->createMock(\\Jiminny\\Models\\Activity\\Search::class);\n $prompt = $this->createMock(\\Jiminny\\Models\\AskAnything\\AskAnythingPrompt::class);\n\n $report = $this->makeActiveReport();\n $report->method('getCreator')->willReturn($creator);\n $report->method('getSavedSearch')->willReturn($savedSearch);\n $report->method('getAskAnythingPrompt')->willReturn($prompt);\n\n $reportResult = $this->createMock(AutomatedReportResult::class);\n $reportResult->method('getUuid')->willReturn('result-uuid');\n $reportResult->method('update')->willReturn(true);\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->reportService->expects($this->once())\n ->method('createReportResult')\n ->with(\n automatedReport: $report,\n data: $this->callback(fn ($data) => $data['status'] === AutomatedReportResult::STATUS_DEFAULT\n && $data['media_type'] === AutomatedReportsService::MEDIA_TYPE_PDF)\n )\n ->willReturn($reportResult);\n\n $this->activityService->expects($this->once())\n ->method('getActivityIdsForSavedSearch')\n ->willReturn([]);\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"app ~/jiminny/app","depth":6,"role_description":"text"},{"role":"AXStaticText","text":".circleci","depth":7,"role_description":"text"},{"role":"AXStaticText","text":".cursor","depth":7,"role_description":"text"},{"role":"AXStaticText","text":".github","depth":7,"role_description":"text"},{"role":"AXStaticText","text":".sonarlint","depth":7,"role_description":"text"},{"role":"AXStaticText","text":".vscode","depth":7,"role_description":"text"},{"role":"AXStaticText","text":".windsurf","depth":7,"role_description":"text"},{"role":"AXStaticText","text":"app, sources root","depth":7,"role_description":"text"},{"role":"AXStaticText","text":"Actions","depth":8,"role_description":"text"},{"role":"AXStaticText","text":"Component","depth":8,"role_description":"text"},{"role":"AXStaticText","text":"Configuration","depth":8,"role_description":"text"},{"role":"AXStaticText","text":"Console","depth":8,"role_description":"text"},{"role":"AXStaticText","text":"Commands","depth":9,"role_description":"text"},{"role":"AXStaticText","text":"Activities","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Analytics","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Calendars","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Crm","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DealInsights","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Dev","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Dialers","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"DTOs","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Elasticsearch","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"EngagementStats","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"GeckoExport","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Livestream","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Mailboxes","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Migrate","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"PlaybackThemes","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Playbooks","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Playlists","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Postmark","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"ProphetAi","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Reports","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"AutomatedReportsCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"AutomatedReportsRetentionPolicyCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"AutomatedReportsSendCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"CreateMockAskJiminnyReportResultCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"DeleteReportCommand.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"GenerateMarketingReport.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"Team.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"Usage.php, class","depth":11,"role_description":"text"},{"role":"AXStaticText","text":"Slack","depth":10,"role_description":"text"},{"role":"AXStaticText","text":"Teams","depth":10,"role_description":"text"}]...
|
-939637532160075803
|
8722295178528246161
|
visual_change
|
accessibility
|
NULL
|
Project: faVsco.js, menu
#11894 on JY-18909-automa Project: faVsco.js, menu
#11894 on JY-18909-automated-reports-ask-jiminny, menu
Start Listening for PHP Debug Connections
RequestGenerateAskJiminnyReportJobTest
Run 'RequestGenerateAskJiminnyReportJobTest'
Debug 'RequestGenerateAskJiminnyReportJobTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Console\Commands\Reports;
use Carbon\Carbon;
use Illuminate\Console\Command;
use Illuminate\Contracts\Bus\Dispatcher as BusDispatcher;
use Jiminny\Jobs\AutomatedReports\RequestGenerateAskJiminnyReportJob;
use Jiminny\Jobs\AutomatedReports\RequestGenerateReportJob;
use Jiminny\Models\AutomatedReport;
use Jiminny\Repositories\AutomatedReportsRepository;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Psr\Log\LoggerInterface;
class AutomatedReportsCommand extends Command
{
/**
* Log prefix for all log messages
*/
private const string LOG_PREFIX = '[automated-reports]';
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'automated-reports';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Process automated reports based on their frequency (weekly, monthly, quarterly)';
public function __construct(
private readonly LoggerInterface $logger,
private readonly BusDispatcher $dispatcher,
private readonly AutomatedReportsRepository $reportRepository
) {
parent::__construct();
}
/**
* Execute the console command.
*
* @return int
*/
public function handle(): int
{
$this->logger->info(self::LOG_PREFIX . ' Started');
$now = Carbon::now();
$isMonday = $now->isMonday();
$isFirstDayOfMonth = $now->day === 1;
$currentMonth = $now->month;
// Check if the current month is a quarterly month (January, April, July, October)
$isQuarterlyMonth = in_array($currentMonth, [1, 4, 7, 10], true);
$this->logger->info(self::LOG_PREFIX . ' Checking conditions', [
'isMonday' => $isMonday,
'isFirstDayOfMonth' => $isFirstDayOfMonth,
'currentMonth' => $currentMonth,
'isQuarterlyMonth' => $isQuarterlyMonth,
]);
// Process daily reports
$this->processReports(AutomatedReportsService::FREQUENCY_DAILY);
// Process weekly reports on Mondays
if ($isMonday) {
$this->processReports(AutomatedReportsService::FREQUENCY_WEEKLY);
}
// Process monthly reports on the first day of the month
if ($isFirstDayOfMonth) {
$this->processReports(AutomatedReportsService::FREQUENCY_MONTHLY);
}
// Process quarterly reports on the first day of January, April, July, and October
if ($isFirstDayOfMonth && $isQuarterlyMonth) {
$this->processReports(AutomatedReportsService::FREQUENCY_QUARTERLY);
}
$this->logger->info(self::LOG_PREFIX . ' Completed');
return 0;
}
/**
* Process reports for a specific frequency.
*
* @param string $frequency
*
* @return void
*/
private function processReports(string $frequency): void
{
$this->logger->info(self::LOG_PREFIX . " Processing $frequency reports");
// Get all enabled, not deleted reports with active teams for the specified frequency
$reports = $this->reportRepository->getActiveReportsByFrequency($frequency);
// $reports = collect([AutomatedReport::find(68)]);
$this->logger->info(self::LOG_PREFIX . " Found {$reports->count()} $frequency reports to process");
/** @var AutomatedReport $report */
foreach ($reports as $report) {
$this->logger->info(self::LOG_PREFIX . ' Dispatching Generate Report job for report', [
'reportUuid' => $report->getUuid(),
'teamId' => $report->getTeamId(),
'frequency' => $report->getFrequency(),
'type' => $report->getType(),
]);
$job = $report->isAskJiminnyReport()
? new RequestGenerateAskJiminnyReportJob($report->getUuid())
: new RequestGenerateReportJob($report->getUuid());
// $this->dispatcher->dispatch($job);
$this->dispatcher->dispatchSync($job);
}
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
1
14
4
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Tests\Unit\Jobs\AutomatedReports;
use Carbon\Carbon;
use Jiminny\Component\ProphetAi\Exceptions\ProphetException;
use Jiminny\Component\ProphetAi\ProphetClient;
use Jiminny\Jobs\AutomatedReports\RequestGenerateAskJiminnyReportJob;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\AutomatedReportResult;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityService;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
use Psr\Log\LoggerInterface;
class RequestGenerateAskJiminnyReportJobTest extends TestCase
{
private AutomatedReportsService&MockObject $reportService;
private AskJiminnyReportActivityService&MockObject $activityService;
private ProphetClient&MockObject $prophetClient;
private LoggerInterface&MockObject $logger;
protected function setUp(): void
{
$this->reportService = $this->createMock(AutomatedReportsService::class);
$this->activityService = $this->createMock(AskJiminnyReportActivityService::class);
$this->prophetClient = $this->createMock(ProphetClient::class);
$this->logger = $this->createMock(LoggerInterface::class);
}
private function makeJob(string $uuid = 'report-uuid'): RequestGenerateAskJiminnyReportJob
{
return new RequestGenerateAskJiminnyReportJob($uuid);
}
private function makeActiveReport(
string $type = AutomatedReportsService::TYPE_ASK_JIMINNY,
bool $status = true,
string $teamStatus = Team::STATUS_ACTIVE,
): AutomatedReport&MockObject { // @phpstan-ignore-line
$team = $this->createMock(Team::class);
$team->method('getStatus')->willReturn($teamStatus);
$report = $this->createMock(AutomatedReport::class);
$report->method('getType')->willReturn($type);
$report->method('getStatus')->willReturn($status);
$report->method('getTeam')->willReturn($team);
return $report;
}
public function testUniqueIdReturnsReportUuid(): void
{
$job = $this->makeJob('my-unique-uuid');
$this->assertEquals('my-unique-uuid', $job->uniqueId());
}
public function testHandleSkipsWhenReportTypeIsNotAskJiminny(): void
{
$report = $this->makeActiveReport(type: 'exec_summary');
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->logger->expects($this->once())
->method('info')
->with($this->stringContains('Started'));
$this->logger->expects($this->once())
->method('warning')
->with($this->stringContains('not an ask_jiminny report'));
$this->reportService->expects($this->never())->method('createReportResult');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleSkipsWhenReportIsInactive(): void
{
$report = $this->makeActiveReport(status: false);
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->logger->expects($this->exactly(2))
->method('info');
$this->reportService->expects($this->never())->method('createReportResult');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleSkipsWhenTeamIsInactive(): void
{
$report = $this->makeActiveReport(teamStatus: Team::STATUS_DEACTIVATED);
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->logger->expects($this->exactly(2))
->method('info');
$this->reportService->expects($this->never())->method('createReportResult');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleSkipsWhenCreatorIsNull(): void
{
$report = $this->makeActiveReport();
$report->method('getCreator')->willReturn(null);
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->logger->expects($this->once())
->method('warning')
->with($this->stringContains('report creator not found'));
$this->reportService->expects($this->never())->method('createReportResult');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleSkipsWhenSavedSearchIsNull(): void
{
$creator = $this->createMock(User::class);
$report = $this->makeActiveReport();
$report->method('getCreator')->willReturn($creator);
$report->method('getSavedSearch')->willReturn(null);
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->logger->expects($this->once())
->method('warning')
->with($this->stringContains('saved search not found'));
$this->reportService->expects($this->never())->method('createReportResult');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleSkipsWhenPromptIsNull(): void
{
$creator = $this->createMock(User::class);
$savedSearch = $this->createMock(\Jiminny\Models\Activity\Search::class);
$report = $this->makeActiveReport();
$report->method('getCreator')->willReturn($creator);
$report->method('getSavedSearch')->willReturn($savedSearch);
$report->method('getAskAnythingPrompt')->willReturn(null);
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->logger->expects($this->once())
->method('warning')
->with($this->stringContains('ask anything prompt not found'));
$this->reportService->expects($this->never())->method('createReportResult');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleFailsReportWhenNotEnoughActivities(): void
{
$creator = $this->createMock(User::class);
$savedSearch = $this->createMock(\Jiminny\Models\Activity\Search::class);
$prompt = $this->createMock(\Jiminny\Models\AskAnything\AskAnythingPrompt::class);
$report = $this->makeActiveReport();
$report->method('getCreator')->willReturn($creator);
$report->method('getSavedSearch')->willReturn($savedSearch);
$report->method('getAskAnythingPrompt')->willReturn($prompt);
$reportResult = $this->createMock(AutomatedReportResult::class);
$reportResult->expects($this->once())
->method('update')
->with($this->callback(fn ($data) => $data['status'] === AutomatedReportResult::STATUS_FAILED
&& $data['reason'] === AutomatedReportResult::REASON_NOT_ENOUGH_ACTIVITIES));
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->reportService->expects($this->once())
->method('createReportResult')
->willReturn($reportResult);
$this->activityService->expects($this->once())
->method('getActivityIdsForSavedSearch')
->willReturn([]);
$this->logger->expects($this->exactly(3))
->method('info');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleSuccessfullyRequestsReport(): void
{
Carbon::setTestNow(Carbon::parse('2026-04-07 10:00:00'));
$creator = $this->createMock(User::class);
$savedSearch = $this->createMock(\Jiminny\Models\Activity\Search::class);
$prompt = $this->createMock(\Jiminny\Models\AskAnything\AskAnythingPrompt::class);
$report = $this->makeActiveReport();
$report->method('getCreator')->willReturn($creator);
$report->method('getSavedSearch')->willReturn($savedSearch);
$report->method('getAskAnythingPrompt')->willReturn($prompt);
$report->method('getUuid')->willReturn('report-uuid');
$reportResult = $this->createMock(AutomatedReportResult::class);
$reportResult->method('getUuid')->willReturn('result-uuid');
$reportResult->expects($this->once())
->method('update')
->with($this->callback(fn ($data) => $data['status'] === AutomatedReportResult::STATUS_REQUESTED
&& isset($data['name'], $data['payload'], $data['requested_at'])));
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->reportService->expects($this->once())
->method('createReportResult')
->willReturn($reportResult);
$this->reportService->expects($this->once())
->method('getAskJiminnyGenerateReportPayload')
->willReturn(['key' => 'value']);
$this->reportService->expects($this->once())
->method('getReportFileName')
->willReturn('My Report - 7 Apr 2026');
$this->activityService->expects($this->once())
->method('getActivityIdsForSavedSearch')
->willReturn(['act-1', 'act-2']);
$this->prophetClient->expects($this->once())
->method('sendRequest')
->willReturn(new \Jiminny\Component\ProphetAi\Dtos\ProphetResponseDto([]));
$this->logger->expects($this->exactly(4))
->method('info');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
Carbon::setTestNow();
}
public function testHandleCatchesGenericExceptionAndLogsError(): void
{
$this->reportService->expects($this->once())
->method('getReport')
->willThrowException(new \RuntimeException('DB error'));
$this->logger->expects($this->once())
->method('error')
->with($this->stringContains('Error'));
$job = $this->makeJob();
$reflection = new \ReflectionClass($job);
$triesProp = $reflection->getProperty('tries');
$triesProp->setAccessible(true);
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleCatchesProphetExceptionAndSetsCorrectReason(): void
{
$creator = $this->createMock(User::class);
$savedSearch = $this->createMock(\Jiminny\Models\Activity\Search::class);
$prompt = $this->createMock(\Jiminny\Models\AskAnything\AskAnythingPrompt::class);
$report = $this->makeActiveReport();
$report->method('getCreator')->willReturn($creator);
$report->method('getSavedSearch')->willReturn($savedSearch);
$report->method('getAskAnythingPrompt')->willReturn($prompt);
$reportResult = $this->createMock(AutomatedReportResult::class);
$reportResult->method('getUuid')->willReturn('result-uuid');
$reportResult->expects($this->once())
->method('update')
->with($this->callback(fn ($data) => $data['reason'] === AutomatedReportResult::REASON_PROPHET_API_ERROR));
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->reportService->expects($this->once())
->method('createReportResult')
->willReturn($reportResult);
$this->activityService->expects($this->once())
->method('getActivityIdsForSavedSearch')
->willThrowException(new ProphetException('Prophet failed'));
$this->logger->expects($this->once())
->method('error');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleCreatesReportResultBeforeActivityFetch(): void
{
$creator = $this->createMock(User::class);
$savedSearch = $this->createMock(\Jiminny\Models\Activity\Search::class);
$prompt = $this->createMock(\Jiminny\Models\AskAnything\AskAnythingPrompt::class);
$report = $this->makeActiveReport();
$report->method('getCreator')->willReturn($creator);
$report->method('getSavedSearch')->willReturn($savedSearch);
$report->method('getAskAnythingPrompt')->willReturn($prompt);
$reportResult = $this->createMock(AutomatedReportResult::class);
$reportResult->method('getUuid')->willReturn('result-uuid');
$callOrder = [];
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->reportService->expects($this->once())
->method('createReportResult')
->willReturnCallback(function () use ($reportResult, &$callOrder) {
$callOrder[] = 'createReportResult';
return $reportResult;
});
$this->activityService->expects($this->once())
->method('getActivityIdsForSavedSearch')
->willReturnCallback(function () use (&$callOrder) {
$callOrder[] = 'getActivityIds';
return [];
});
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
$this->assertEquals(['createReportResult', 'getActivityIds'], $callOrder);
}
public function testHandlePassesCorrectDataToCreateReportResult(): void
{
$creator = $this->createMock(User::class);
$savedSearch = $this->createMock(\Jiminny\Models\Activity\Search::class);
$prompt = $this->createMock(\Jiminny\Models\AskAnything\AskAnythingPrompt::class);
$report = $this->makeActiveReport();
$report->method('getCreator')->willReturn($creator);
$report->method('getSavedSearch')->willReturn($savedSearch);
$report->method('getAskAnythingPrompt')->willReturn($prompt);
$reportResult = $this->createMock(AutomatedReportResult::class);
$reportResult->method('getUuid')->willReturn('result-uuid');
$reportResult->method('update')->willReturn(true);
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->reportService->expects($this->once())
->method('createReportResult')
->with(
automatedReport: $report,
data: $this->callback(fn ($data) => $data['status'] === AutomatedReportResult::STATUS_DEFAULT
&& $data['media_type'] === AutomatedReportsService::MEDIA_TYPE_PDF)
)
->willReturn($reportResult);
$this->activityService->expects($this->once())
->method('getActivityIdsForSavedSearch')
->willReturn([]);
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide
app ~/jiminny/app
.circleci
.cursor
.github
.sonarlint
.vscode
.windsurf
app, sources root
Actions
Component
Configuration
Console
Commands
Activities
Analytics
Calendars
Crm
DealInsights
Dev
Dialers
DTOs
Elasticsearch
EngagementStats
GeckoExport
Livestream
Mailboxes
Migrate
PlaybackThemes
Playbooks
Playlists
Postmark
ProphetAi
Reports
AutomatedReportsCommand.php, class
AutomatedReportsRetentionPolicyCommand.php, class
AutomatedReportsSendCommand.php, class
CreateMockAskJiminnyReportResultCommand.php, class
DeleteReportCommand.php, class
GenerateMarketingReport.php, class
Team.php, class
Usage.php, class
Slack
Teams...
|
NULL
|
|
9481
|
183
|
25
|
2026-04-14T07:40:44.567544+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776152444567_m2.jpg...
|
PhpStorm
|
faVsco.js – AutomatedReportsCommand.php
|
True
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
#11894 on JY-18909-automa Project: faVsco.js, menu
#11894 on JY-18909-automated-reports-ask-jiminny, menu
Start Listening for PHP Debug Connections
RequestGenerateAskJiminnyReportJobTest
Run 'RequestGenerateAskJiminnyReportJobTest'
Debug 'RequestGenerateAskJiminnyReportJobTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Console\Commands\Reports;
use Carbon\Carbon;
use Illuminate\Console\Command;
use Illuminate\Contracts\Bus\Dispatcher as BusDispatcher;
use Jiminny\Jobs\AutomatedReports\RequestGenerateAskJiminnyReportJob;
use Jiminny\Jobs\AutomatedReports\RequestGenerateReportJob;
use Jiminny\Models\AutomatedReport;
use Jiminny\Repositories\AutomatedReportsRepository;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Psr\Log\LoggerInterface;
class AutomatedReportsCommand extends Command
{
/**
* Log prefix for all log messages
*/
private const string LOG_PREFIX = '[automated-reports]';
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'automated-reports';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Process automated reports based on their frequency (weekly, monthly, quarterly)';
public function __construct(
private readonly LoggerInterface $logger,
private readonly BusDispatcher $dispatcher,
private readonly AutomatedReportsRepository $reportRepository
) {
parent::__construct();
}
/**
* Execute the console command.
*
* @return int
*/
public function handle(): int
{
$this->logger->info(self::LOG_PREFIX . ' Started');
$now = Carbon::now();
$isMonday = $now->isMonday();
$isFirstDayOfMonth = $now->day === 1;
$currentMonth = $now->month;
// Check if the current month is a quarterly month (January, April, July, October)
$isQuarterlyMonth = in_array($currentMonth, [1, 4, 7, 10], true);
$this->logger->info(self::LOG_PREFIX . ' Checking conditions', [
'isMonday' => $isMonday,
'isFirstDayOfMonth' => $isFirstDayOfMonth,
'currentMonth' => $currentMonth,
'isQuarterlyMonth' => $isQuarterlyMonth,
]);
// Process daily reports
$this->processReports(AutomatedReportsService::FREQUENCY_DAILY);
// Process weekly reports on Mondays
if ($isMonday) {
$this->processReports(AutomatedReportsService::FREQUENCY_WEEKLY);
}
// Process monthly reports on the first day of the month
if ($isFirstDayOfMonth) {
$this->processReports(AutomatedReportsService::FREQUENCY_MONTHLY);
}
// Process quarterly reports on the first day of January, April, July, and October
if ($isFirstDayOfMonth && $isQuarterlyMonth) {
$this->processReports(AutomatedReportsService::FREQUENCY_QUARTERLY);
}
$this->logger->info(self::LOG_PREFIX . ' Completed');
return 0;
}
/**
* Process reports for a specific frequency.
*
* @param string $frequency
*
* @return void
*/
private function processReports(string $frequency): void
{
$this->logger->info(self::LOG_PREFIX . " Processing $frequency reports");
// Get all enabled, not deleted reports with active teams for the specified frequency
$reports = $this->reportRepository->getActiveReportsByFrequency($frequency);
// $reports = collect([AutomatedReport::find(68)]);
$this->logger->info(self::LOG_PREFIX . " Found {$reports->count()} $frequency reports to process");
/** @var AutomatedReport $report */
foreach ($reports as $report) {
$this->logger->info(self::LOG_PREFIX . ' Dispatching Generate Report job for report', [
'reportUuid' => $report->getUuid(),
'teamId' => $report->getTeamId(),
'frequency' => $report->getFrequency(),
'type' => $report->getType(),
]);
$job = $report->isAskJiminnyReport()
? new RequestGenerateAskJiminnyReportJob($report->getUuid())
: new RequestGenerateReportJob($report->getUuid());
// $this->dispatcher->dispatch($job);
$this->dispatcher->dispatchSync($job);
}
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
1
14
4
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Tests\Unit\Jobs\AutomatedReports;
use Carbon\Carbon;
use Jiminny\Component\ProphetAi\Exceptions\ProphetException;
use Jiminny\Component\ProphetAi\ProphetClient;
use Jiminny\Jobs\AutomatedReports\RequestGenerateAskJiminnyReportJob;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\AutomatedReportResult;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityService;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
use Psr\Log\LoggerInterface;
class RequestGenerateAskJiminnyReportJobTest extends TestCase
{
private AutomatedReportsService&MockObject $reportService;
private AskJiminnyReportActivityService&MockObject $activityService;
private ProphetClient&MockObject $prophetClient;
private LoggerInterface&MockObject $logger;
protected function setUp(): void
{
$this->reportService = $this->createMock(AutomatedReportsService::class);
$this->activityService = $this->createMock(AskJiminnyReportActivityService::class);
$this->prophetClient = $this->createMock(ProphetClient::class);
$this->logger = $this->createMock(LoggerInterface::class);
}
private function makeJob(string $uuid = 'report-uuid'): RequestGenerateAskJiminnyReportJob
{
return new RequestGenerateAskJiminnyReportJob($uuid);
}
private function makeActiveReport(
string $type = AutomatedReportsService::TYPE_ASK_JIMINNY,
bool $status = true,
string $teamStatus = Team::STATUS_ACTIVE,
): AutomatedReport&MockObject { // @phpstan-ignore-line
$team = $this->createMock(Team::class);
$team->method('getStatus')->willReturn($teamStatus);
$report = $this->createMock(AutomatedReport::class);
$report->method('getType')->willReturn($type);
$report->method('getStatus')->willReturn($status);
$report->method('getTeam')->willReturn($team);
return $report;
}
public function testUniqueIdReturnsReportUuid(): void
{
$job = $this->makeJob('my-unique-uuid');
$this->assertEquals('my-unique-uuid', $job->uniqueId());
}
public function testHandleSkipsWhenReportTypeIsNotAskJiminny(): void
{
$report = $this->makeActiveReport(type: 'exec_summary');
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->logger->expects($this->once())
->method('info')
->with($this->stringContains('Started'));
$this->logger->expects($this->once())
->method('warning')
->with($this->stringContains('not an ask_jiminny report'));
$this->reportService->expects($this->never())->method('createReportResult');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleSkipsWhenReportIsInactive(): void
{
$report = $this->makeActiveReport(status: false);
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->logger->expects($this->exactly(2))
->method('info');
$this->reportService->expects($this->never())->method('createReportResult');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleSkipsWhenTeamIsInactive(): void
{
$report = $this->makeActiveReport(teamStatus: Team::STATUS_DEACTIVATED);
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->logger->expects($this->exactly(2))
->method('info');
$this->reportService->expects($this->never())->method('createReportResult');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleSkipsWhenCreatorIsNull(): void
{
$report = $this->makeActiveReport();
$report->method('getCreator')->willReturn(null);
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->logger->expects($this->once())
->method('warning')
->with($this->stringContains('report creator not found'));
$this->reportService->expects($this->never())->method('createReportResult');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleSkipsWhenSavedSearchIsNull(): void
{
$creator = $this->createMock(User::class);
$report = $this->makeActiveReport();
$report->method('getCreator')->willReturn($creator);
$report->method('getSavedSearch')->willReturn(null);
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->logger->expects($this->once())
->method('warning')
->with($this->stringContains('saved search not found'));
$this->reportService->expects($this->never())->method('createReportResult');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleSkipsWhenPromptIsNull(): void
{
$creator = $this->createMock(User::class);
$savedSearch = $this->createMock(\Jiminny\Models\Activity\Search::class);
$report = $this->makeActiveReport();
$report->method('getCreator')->willReturn($creator);
$report->method('getSavedSearch')->willReturn($savedSearch);
$report->method('getAskAnythingPrompt')->willReturn(null);
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->logger->expects($this->once())
->method('warning')
->with($this->stringContains('ask anything prompt not found'));
$this->reportService->expects($this->never())->method('createReportResult');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleFailsReportWhenNotEnoughActivities(): void
{
$creator = $this->createMock(User::class);
$savedSearch = $this->createMock(\Jiminny\Models\Activity\Search::class);
$prompt = $this->createMock(\Jiminny\Models\AskAnything\AskAnythingPrompt::class);
$report = $this->makeActiveReport();
$report->method('getCreator')->willReturn($creator);
$report->method('getSavedSearch')->willReturn($savedSearch);
$report->method('getAskAnythingPrompt')->willReturn($prompt);
$reportResult = $this->createMock(AutomatedReportResult::class);
$reportResult->expects($this->once())
->method('update')
->with($this->callback(fn ($data) => $data['status'] === AutomatedReportResult::STATUS_FAILED
&& $data['reason'] === AutomatedReportResult::REASON_NOT_ENOUGH_ACTIVITIES));
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->reportService->expects($this->once())
->method('createReportResult')
->willReturn($reportResult);
$this->activityService->expects($this->once())
->method('getActivityIdsForSavedSearch')
->willReturn([]);
$this->logger->expects($this->exactly(3))
->method('info');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleSuccessfullyRequestsReport(): void
{
Carbon::setTestNow(Carbon::parse('2026-04-07 10:00:00'));
$creator = $this->createMock(User::class);
$savedSearch = $this->createMock(\Jiminny\Models\Activity\Search::class);
$prompt = $this->createMock(\Jiminny\Models\AskAnything\AskAnythingPrompt::class);
$report = $this->makeActiveReport();
$report->method('getCreator')->willReturn($creator);
$report->method('getSavedSearch')->willReturn($savedSearch);
$report->method('getAskAnythingPrompt')->willReturn($prompt);
$report->method('getUuid')->willReturn('report-uuid');
$reportResult = $this->createMock(AutomatedReportResult::class);
$reportResult->method('getUuid')->willReturn('result-uuid');
$reportResult->expects($this->once())
->method('update')
->with($this->callback(fn ($data) => $data['status'] === AutomatedReportResult::STATUS_REQUESTED
&& isset($data['name'], $data['payload'], $data['requested_at'])));
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->reportService->expects($this->once())
->method('createReportResult')
->willReturn($reportResult);
$this->reportService->expects($this->once())
->method('getAskJiminnyGenerateReportPayload')
->willReturn(['key' => 'value']);
$this->reportService->expects($this->once())
->method('getReportFileName')
->willReturn('My Report - 7 Apr 2026');
$this->activityService->expects($this->once())
->method('getActivityIdsForSavedSearch')
->willReturn(['act-1', 'act-2']);
$this->prophetClient->expects($this->once())
->method('sendRequest')
->willReturn(new \Jiminny\Component\ProphetAi\Dtos\ProphetResponseDto([]));
$this->logger->expects($this->exactly(4))
->method('info');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
Carbon::setTestNow();
}
public function testHandleCatchesGenericExceptionAndLogsError(): void
{
$this->reportService->expects($this->once())
->method('getReport')
->willThrowException(new \RuntimeException('DB error'));
$this->logger->expects($this->once())
->method('error')
->with($this->stringContains('Error'));
$job = $this->makeJob();
$reflection = new \ReflectionClass($job);
$triesProp = $reflection->getProperty('tries');
$triesProp->setAccessible(true);
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleCatchesProphetExceptionAndSetsCorrectReason(): void
{
$creator = $this->createMock(User::class);
$savedSearch = $this->createMock(\Jiminny\Models\Activity\Search::class);
$prompt = $this->createMock(\Jiminny\Models\AskAnything\AskAnythingPrompt::class);
$report = $this->makeActiveReport();
$report->method('getCreator')->willReturn($creator);
$report->method('getSavedSearch')->willReturn($savedSearch);
$report->method('getAskAnythingPrompt')->willReturn($prompt);
$reportResult = $this->createMock(AutomatedReportResult::class);
$reportResult->method('getUuid')->willReturn('result-uuid');
$reportResult->expects($this->once())
->method('update')
->with($this->callback(fn ($data) => $data['reason'] === AutomatedReportResult::REASON_PROPHET_API_ERROR));
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->reportService->expects($this->once())
->method('createReportResult')
->willReturn($reportResult);
$this->activityService->expects($this->once())
->method('getActivityIdsForSavedSearch')
->willThrowException(new ProphetException('Prophet failed'));
$this->logger->expects($this->once())
->method('error');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleCreatesReportResultBeforeActivityFetch(): void
{
$creator = $this->createMock(User::class);
$savedSearch = $this->createMock(\Jiminny\Models\Activity\Search::class);
$prompt = $this->createMock(\Jiminny\Models\AskAnything\AskAnythingPrompt::class);
$report = $this->makeActiveReport();
$report->method('getCreator')->willReturn($creator);
$report->method('getSavedSearch')->willReturn($savedSearch);
$report->method('getAskAnythingPrompt')->willReturn($prompt);
$reportResult = $this->createMock(AutomatedReportResult::class);
$reportResult->method('getUuid')->willReturn('result-uuid');
$callOrder = [];
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->reportService->expects($this->once())
->method('createReportResult')
->willReturnCallback(function () use ($reportResult, &$callOrder) {
$callOrder[] = 'createReportResult';
return $reportResult;
});
$this->activityService->expects($this->once())
->method('getActivityIdsForSavedSearch')
->willReturnCallback(function () use (&$callOrder) {
$callOrder[] = 'getActivityIds';
return [];
});
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
$this->assertEquals(['createReportResult', 'getActivityIds'], $callOrder);
}
public function testHandlePassesCorrectDataToCreateReportResult(): void
{
$creator = $this->createMock(User::class);
$savedSearch = $this->createMock(\Jiminny\Models\Activity\Search::class);
$prompt = $this->createMock(\Jiminny\Models\AskAnything\AskAnythingPrompt::class);
$report = $this->makeActiveReport();
$report->method('getCreator')->willReturn($creator);
$report->method('getSavedSearch')->willReturn($savedSearch);
$report->method('getAskAnythingPrompt')->willReturn($prompt);
$reportResult = $this->createMock(AutomatedReportResult::class);
$reportResult->method('getUuid')->willReturn('result-uuid');
$reportResult->method('update')->willReturn(true);
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->reportService->expects($this->once())
->method('createReportResult')
->with(
automatedReport: $report,
data: $this->callback(fn ($data) => $data['status'] === AutomatedReportResult::STATUS_DEFAULT
&& $data['media_type'] === AutomatedReportsService::MEDIA_TYPE_PDF)
)
->willReturn($reportResult);
$this->activityService->expects($this->once())
->method('getActivityIdsForSavedSearch')
->willReturn([]);
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.03046875,"top":0.017361112,"width":0.0453125,"height":0.022222223},"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"#11894 on JY-18909-automated-reports-ask-jiminny, menu","depth":5,"bounds":{"left":0.07578125,"top":0.017361112,"width":0.14960937,"height":0.022222223},"help_text":"Pull request #11894 exists for current branch JY-18909-automated-reports-ask-jiminny, but local branch is out of sync with remote","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.76171875,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"RequestGenerateAskJiminnyReportJobTest","depth":6,"bounds":{"left":0.7796875,"top":0.017361112,"width":0.12109375,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'RequestGenerateAskJiminnyReportJobTest'","depth":6,"bounds":{"left":0.9007813,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'RequestGenerateAskJiminnyReportJobTest'","depth":6,"bounds":{"left":0.9140625,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9273437,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96015626,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9734375,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9867188,"top":0.017361112,"width":0.013281226,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.049609374,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Console\\Commands\\Reports;\n\nuse Carbon\\Carbon;\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Contracts\\Bus\\Dispatcher as BusDispatcher;\nuse Jiminny\\Jobs\\AutomatedReports\\RequestGenerateAskJiminnyReportJob;\nuse Jiminny\\Jobs\\AutomatedReports\\RequestGenerateReportJob;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Repositories\\AutomatedReportsRepository;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Psr\\Log\\LoggerInterface;\n\nclass AutomatedReportsCommand extends Command\n{\n /**\n * Log prefix for all log messages\n */\n private const string LOG_PREFIX = '[automated-reports]';\n\n /**\n * The name and signature of the console command.\n *\n * @var string\n */\n protected $signature = 'automated-reports';\n\n /**\n * The console command description.\n *\n * @var string\n */\n protected $description = 'Process automated reports based on their frequency (weekly, monthly, quarterly)';\n\n\n public function __construct(\n private readonly LoggerInterface $logger,\n private readonly BusDispatcher $dispatcher,\n private readonly AutomatedReportsRepository $reportRepository\n ) {\n parent::__construct();\n }\n\n /**\n * Execute the console command.\n *\n * @return int\n */\n public function handle(): int\n {\n $this->logger->info(self::LOG_PREFIX . ' Started');\n\n $now = Carbon::now();\n $isMonday = $now->isMonday();\n $isFirstDayOfMonth = $now->day === 1;\n $currentMonth = $now->month;\n\n // Check if the current month is a quarterly month (January, April, July, October)\n $isQuarterlyMonth = in_array($currentMonth, [1, 4, 7, 10], true);\n\n $this->logger->info(self::LOG_PREFIX . ' Checking conditions', [\n 'isMonday' => $isMonday,\n 'isFirstDayOfMonth' => $isFirstDayOfMonth,\n 'currentMonth' => $currentMonth,\n 'isQuarterlyMonth' => $isQuarterlyMonth,\n ]);\n\n // Process daily reports\n $this->processReports(AutomatedReportsService::FREQUENCY_DAILY);\n\n // Process weekly reports on Mondays\n if ($isMonday) {\n $this->processReports(AutomatedReportsService::FREQUENCY_WEEKLY);\n }\n\n // Process monthly reports on the first day of the month\n if ($isFirstDayOfMonth) {\n $this->processReports(AutomatedReportsService::FREQUENCY_MONTHLY);\n }\n\n // Process quarterly reports on the first day of January, April, July, and October\n if ($isFirstDayOfMonth && $isQuarterlyMonth) {\n $this->processReports(AutomatedReportsService::FREQUENCY_QUARTERLY);\n }\n\n $this->logger->info(self::LOG_PREFIX . ' Completed');\n\n return 0;\n }\n\n /**\n * Process reports for a specific frequency.\n *\n * @param string $frequency\n *\n * @return void\n */\n private function processReports(string $frequency): void\n {\n $this->logger->info(self::LOG_PREFIX . \" Processing $frequency reports\");\n\n // Get all enabled, not deleted reports with active teams for the specified frequency\n $reports = $this->reportRepository->getActiveReportsByFrequency($frequency);\n // $reports = collect([AutomatedReport::find(68)]);\n\n $this->logger->info(self::LOG_PREFIX . \" Found {$reports->count()} $frequency reports to process\");\n\n /** @var AutomatedReport $report */\n foreach ($reports as $report) {\n $this->logger->info(self::LOG_PREFIX . ' Dispatching Generate Report job for report', [\n 'reportUuid' => $report->getUuid(),\n 'teamId' => $report->getTeamId(),\n 'frequency' => $report->getFrequency(),\n 'type' => $report->getType(),\n ]);\n\n $job = $report->isAskJiminnyReport()\n ? new RequestGenerateAskJiminnyReportJob($report->getUuid())\n : new RequestGenerateReportJob($report->getUuid());\n\n // $this->dispatcher->dispatch($job);\n $this->dispatcher->dispatchSync($job);\n }\n }\n}","depth":4,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Console\\Commands\\Reports;\n\nuse Carbon\\Carbon;\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Contracts\\Bus\\Dispatcher as BusDispatcher;\nuse Jiminny\\Jobs\\AutomatedReports\\RequestGenerateAskJiminnyReportJob;\nuse Jiminny\\Jobs\\AutomatedReports\\RequestGenerateReportJob;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Repositories\\AutomatedReportsRepository;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Psr\\Log\\LoggerInterface;\n\nclass AutomatedReportsCommand extends Command\n{\n /**\n * Log prefix for all log messages\n */\n private const string LOG_PREFIX = '[automated-reports]';\n\n /**\n * The name and signature of the console command.\n *\n * @var string\n */\n protected $signature = 'automated-reports';\n\n /**\n * The console command description.\n *\n * @var string\n */\n protected $description = 'Process automated reports based on their frequency (weekly, monthly, quarterly)';\n\n\n public function __construct(\n private readonly LoggerInterface $logger,\n private readonly BusDispatcher $dispatcher,\n private readonly AutomatedReportsRepository $reportRepository\n ) {\n parent::__construct();\n }\n\n /**\n * Execute the console command.\n *\n * @return int\n */\n public function handle(): int\n {\n $this->logger->info(self::LOG_PREFIX . ' Started');\n\n $now = Carbon::now();\n $isMonday = $now->isMonday();\n $isFirstDayOfMonth = $now->day === 1;\n $currentMonth = $now->month;\n\n // Check if the current month is a quarterly month (January, April, July, October)\n $isQuarterlyMonth = in_array($currentMonth, [1, 4, 7, 10], true);\n\n $this->logger->info(self::LOG_PREFIX . ' Checking conditions', [\n 'isMonday' => $isMonday,\n 'isFirstDayOfMonth' => $isFirstDayOfMonth,\n 'currentMonth' => $currentMonth,\n 'isQuarterlyMonth' => $isQuarterlyMonth,\n ]);\n\n // Process daily reports\n $this->processReports(AutomatedReportsService::FREQUENCY_DAILY);\n\n // Process weekly reports on Mondays\n if ($isMonday) {\n $this->processReports(AutomatedReportsService::FREQUENCY_WEEKLY);\n }\n\n // Process monthly reports on the first day of the month\n if ($isFirstDayOfMonth) {\n $this->processReports(AutomatedReportsService::FREQUENCY_MONTHLY);\n }\n\n // Process quarterly reports on the first day of January, April, July, and October\n if ($isFirstDayOfMonth && $isQuarterlyMonth) {\n $this->processReports(AutomatedReportsService::FREQUENCY_QUARTERLY);\n }\n\n $this->logger->info(self::LOG_PREFIX . ' Completed');\n\n return 0;\n }\n\n /**\n * Process reports for a specific frequency.\n *\n * @param string $frequency\n *\n * @return void\n */\n private function processReports(string $frequency): void\n {\n $this->logger->info(self::LOG_PREFIX . \" Processing $frequency reports\");\n\n // Get all enabled, not deleted reports with active teams for the specified frequency\n $reports = $this->reportRepository->getActiveReportsByFrequency($frequency);\n // $reports = collect([AutomatedReport::find(68)]);\n\n $this->logger->info(self::LOG_PREFIX . \" Found {$reports->count()} $frequency reports to process\");\n\n /** @var AutomatedReport $report */\n foreach ($reports as $report) {\n $this->logger->info(self::LOG_PREFIX . ' Dispatching Generate Report job for report', [\n 'reportUuid' => $report->getUuid(),\n 'teamId' => $report->getTeamId(),\n 'frequency' => $report->getFrequency(),\n 'type' => $report->getType(),\n ]);\n\n $job = $report->isAskJiminnyReport()\n ? new RequestGenerateAskJiminnyReportJob($report->getUuid())\n : new RequestGenerateReportJob($report->getUuid());\n\n // $this->dispatcher->dispatch($job);\n $this->dispatcher->dispatchSync($job);\n }\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.049609374,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"1","depth":4,"bounds":{"left":0.9339844,"top":0.0875,"width":0.00859375,"height":0.013194445},"role_description":"text"},{"role":"AXStaticText","text":"14","depth":4,"bounds":{"left":0.94492185,"top":0.0875,"width":0.011328125,"height":0.013194445},"role_description":"text"},{"role":"AXStaticText","text":"4","depth":4,"bounds":{"left":0.9585937,"top":0.0875,"width":0.009375,"height":0.013194445},"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.9699219,"top":0.08611111,"width":0.00859375,"height":0.015972223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.9785156,"top":0.08611111,"width":0.008203125,"height":0.015972223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Tests\\Unit\\Jobs\\AutomatedReports;\n\nuse Carbon\\Carbon;\nuse Jiminny\\Component\\ProphetAi\\Exceptions\\ProphetException;\nuse Jiminny\\Component\\ProphetAi\\ProphetClient;\nuse Jiminny\\Jobs\\AutomatedReports\\RequestGenerateAskJiminnyReportJob;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Models\\AutomatedReportResult;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AskJiminnyReportActivityService;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse PHPUnit\\Framework\\MockObject\\MockObject;\nuse PHPUnit\\Framework\\TestCase;\nuse Psr\\Log\\LoggerInterface;\n\nclass RequestGenerateAskJiminnyReportJobTest extends TestCase\n{\n private AutomatedReportsService&MockObject $reportService;\n private AskJiminnyReportActivityService&MockObject $activityService;\n private ProphetClient&MockObject $prophetClient;\n private LoggerInterface&MockObject $logger;\n\n protected function setUp(): void\n {\n $this->reportService = $this->createMock(AutomatedReportsService::class);\n $this->activityService = $this->createMock(AskJiminnyReportActivityService::class);\n $this->prophetClient = $this->createMock(ProphetClient::class);\n $this->logger = $this->createMock(LoggerInterface::class);\n }\n\n private function makeJob(string $uuid = 'report-uuid'): RequestGenerateAskJiminnyReportJob\n {\n return new RequestGenerateAskJiminnyReportJob($uuid);\n }\n\n private function makeActiveReport(\n string $type = AutomatedReportsService::TYPE_ASK_JIMINNY,\n bool $status = true,\n string $teamStatus = Team::STATUS_ACTIVE,\n ): AutomatedReport&MockObject { // @phpstan-ignore-line\n $team = $this->createMock(Team::class);\n $team->method('getStatus')->willReturn($teamStatus);\n\n $report = $this->createMock(AutomatedReport::class);\n $report->method('getType')->willReturn($type);\n $report->method('getStatus')->willReturn($status);\n $report->method('getTeam')->willReturn($team);\n\n return $report;\n }\n\n public function testUniqueIdReturnsReportUuid(): void\n {\n $job = $this->makeJob('my-unique-uuid');\n\n $this->assertEquals('my-unique-uuid', $job->uniqueId());\n }\n\n public function testHandleSkipsWhenReportTypeIsNotAskJiminny(): void\n {\n $report = $this->makeActiveReport(type: 'exec_summary');\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->logger->expects($this->once())\n ->method('info')\n ->with($this->stringContains('Started'));\n\n $this->logger->expects($this->once())\n ->method('warning')\n ->with($this->stringContains('not an ask_jiminny report'));\n\n $this->reportService->expects($this->never())->method('createReportResult');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleSkipsWhenReportIsInactive(): void\n {\n $report = $this->makeActiveReport(status: false);\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->logger->expects($this->exactly(2))\n ->method('info');\n\n $this->reportService->expects($this->never())->method('createReportResult');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleSkipsWhenTeamIsInactive(): void\n {\n $report = $this->makeActiveReport(teamStatus: Team::STATUS_DEACTIVATED);\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->logger->expects($this->exactly(2))\n ->method('info');\n\n $this->reportService->expects($this->never())->method('createReportResult');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleSkipsWhenCreatorIsNull(): void\n {\n $report = $this->makeActiveReport();\n $report->method('getCreator')->willReturn(null);\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->logger->expects($this->once())\n ->method('warning')\n ->with($this->stringContains('report creator not found'));\n\n $this->reportService->expects($this->never())->method('createReportResult');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleSkipsWhenSavedSearchIsNull(): void\n {\n $creator = $this->createMock(User::class);\n\n $report = $this->makeActiveReport();\n $report->method('getCreator')->willReturn($creator);\n $report->method('getSavedSearch')->willReturn(null);\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->logger->expects($this->once())\n ->method('warning')\n ->with($this->stringContains('saved search not found'));\n\n $this->reportService->expects($this->never())->method('createReportResult');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleSkipsWhenPromptIsNull(): void\n {\n $creator = $this->createMock(User::class);\n $savedSearch = $this->createMock(\\Jiminny\\Models\\Activity\\Search::class);\n\n $report = $this->makeActiveReport();\n $report->method('getCreator')->willReturn($creator);\n $report->method('getSavedSearch')->willReturn($savedSearch);\n $report->method('getAskAnythingPrompt')->willReturn(null);\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->logger->expects($this->once())\n ->method('warning')\n ->with($this->stringContains('ask anything prompt not found'));\n\n $this->reportService->expects($this->never())->method('createReportResult');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleFailsReportWhenNotEnoughActivities(): void\n {\n $creator = $this->createMock(User::class);\n $savedSearch = $this->createMock(\\Jiminny\\Models\\Activity\\Search::class);\n $prompt = $this->createMock(\\Jiminny\\Models\\AskAnything\\AskAnythingPrompt::class);\n\n $report = $this->makeActiveReport();\n $report->method('getCreator')->willReturn($creator);\n $report->method('getSavedSearch')->willReturn($savedSearch);\n $report->method('getAskAnythingPrompt')->willReturn($prompt);\n\n $reportResult = $this->createMock(AutomatedReportResult::class);\n $reportResult->expects($this->once())\n ->method('update')\n ->with($this->callback(fn ($data) => $data['status'] === AutomatedReportResult::STATUS_FAILED\n && $data['reason'] === AutomatedReportResult::REASON_NOT_ENOUGH_ACTIVITIES));\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->reportService->expects($this->once())\n ->method('createReportResult')\n ->willReturn($reportResult);\n\n $this->activityService->expects($this->once())\n ->method('getActivityIdsForSavedSearch')\n ->willReturn([]);\n\n $this->logger->expects($this->exactly(3))\n ->method('info');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleSuccessfullyRequestsReport(): void\n {\n Carbon::setTestNow(Carbon::parse('2026-04-07 10:00:00'));\n\n $creator = $this->createMock(User::class);\n $savedSearch = $this->createMock(\\Jiminny\\Models\\Activity\\Search::class);\n $prompt = $this->createMock(\\Jiminny\\Models\\AskAnything\\AskAnythingPrompt::class);\n\n $report = $this->makeActiveReport();\n $report->method('getCreator')->willReturn($creator);\n $report->method('getSavedSearch')->willReturn($savedSearch);\n $report->method('getAskAnythingPrompt')->willReturn($prompt);\n $report->method('getUuid')->willReturn('report-uuid');\n\n $reportResult = $this->createMock(AutomatedReportResult::class);\n $reportResult->method('getUuid')->willReturn('result-uuid');\n $reportResult->expects($this->once())\n ->method('update')\n ->with($this->callback(fn ($data) => $data['status'] === AutomatedReportResult::STATUS_REQUESTED\n && isset($data['name'], $data['payload'], $data['requested_at'])));\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->reportService->expects($this->once())\n ->method('createReportResult')\n ->willReturn($reportResult);\n\n $this->reportService->expects($this->once())\n ->method('getAskJiminnyGenerateReportPayload')\n ->willReturn(['key' => 'value']);\n\n $this->reportService->expects($this->once())\n ->method('getReportFileName')\n ->willReturn('My Report - 7 Apr 2026');\n\n $this->activityService->expects($this->once())\n ->method('getActivityIdsForSavedSearch')\n ->willReturn(['act-1', 'act-2']);\n\n $this->prophetClient->expects($this->once())\n ->method('sendRequest')\n ->willReturn(new \\Jiminny\\Component\\ProphetAi\\Dtos\\ProphetResponseDto([]));\n\n $this->logger->expects($this->exactly(4))\n ->method('info');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n\n Carbon::setTestNow();\n }\n\n public function testHandleCatchesGenericExceptionAndLogsError(): void\n {\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willThrowException(new \\RuntimeException('DB error'));\n\n $this->logger->expects($this->once())\n ->method('error')\n ->with($this->stringContains('Error'));\n\n $job = $this->makeJob();\n\n $reflection = new \\ReflectionClass($job);\n $triesProp = $reflection->getProperty('tries');\n $triesProp->setAccessible(true);\n\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleCatchesProphetExceptionAndSetsCorrectReason(): void\n {\n $creator = $this->createMock(User::class);\n $savedSearch = $this->createMock(\\Jiminny\\Models\\Activity\\Search::class);\n $prompt = $this->createMock(\\Jiminny\\Models\\AskAnything\\AskAnythingPrompt::class);\n\n $report = $this->makeActiveReport();\n $report->method('getCreator')->willReturn($creator);\n $report->method('getSavedSearch')->willReturn($savedSearch);\n $report->method('getAskAnythingPrompt')->willReturn($prompt);\n\n $reportResult = $this->createMock(AutomatedReportResult::class);\n $reportResult->method('getUuid')->willReturn('result-uuid');\n $reportResult->expects($this->once())\n ->method('update')\n ->with($this->callback(fn ($data) => $data['reason'] === AutomatedReportResult::REASON_PROPHET_API_ERROR));\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->reportService->expects($this->once())\n ->method('createReportResult')\n ->willReturn($reportResult);\n\n $this->activityService->expects($this->once())\n ->method('getActivityIdsForSavedSearch')\n ->willThrowException(new ProphetException('Prophet failed'));\n\n $this->logger->expects($this->once())\n ->method('error');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleCreatesReportResultBeforeActivityFetch(): void\n {\n $creator = $this->createMock(User::class);\n $savedSearch = $this->createMock(\\Jiminny\\Models\\Activity\\Search::class);\n $prompt = $this->createMock(\\Jiminny\\Models\\AskAnything\\AskAnythingPrompt::class);\n\n $report = $this->makeActiveReport();\n $report->method('getCreator')->willReturn($creator);\n $report->method('getSavedSearch')->willReturn($savedSearch);\n $report->method('getAskAnythingPrompt')->willReturn($prompt);\n\n $reportResult = $this->createMock(AutomatedReportResult::class);\n $reportResult->method('getUuid')->willReturn('result-uuid');\n\n $callOrder = [];\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->reportService->expects($this->once())\n ->method('createReportResult')\n ->willReturnCallback(function () use ($reportResult, &$callOrder) {\n $callOrder[] = 'createReportResult';\n\n return $reportResult;\n });\n\n $this->activityService->expects($this->once())\n ->method('getActivityIdsForSavedSearch')\n ->willReturnCallback(function () use (&$callOrder) {\n $callOrder[] = 'getActivityIds';\n\n return [];\n });\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n\n $this->assertEquals(['createReportResult', 'getActivityIds'], $callOrder);\n }\n\n public function testHandlePassesCorrectDataToCreateReportResult(): void\n {\n $creator = $this->createMock(User::class);\n $savedSearch = $this->createMock(\\Jiminny\\Models\\Activity\\Search::class);\n $prompt = $this->createMock(\\Jiminny\\Models\\AskAnything\\AskAnythingPrompt::class);\n\n $report = $this->makeActiveReport();\n $report->method('getCreator')->willReturn($creator);\n $report->method('getSavedSearch')->willReturn($savedSearch);\n $report->method('getAskAnythingPrompt')->willReturn($prompt);\n\n $reportResult = $this->createMock(AutomatedReportResult::class);\n $reportResult->method('getUuid')->willReturn('result-uuid');\n $reportResult->method('update')->willReturn(true);\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->reportService->expects($this->once())\n ->method('createReportResult')\n ->with(\n automatedReport: $report,\n data: $this->callback(fn ($data) => $data['status'] === AutomatedReportResult::STATUS_DEFAULT\n && $data['media_type'] === AutomatedReportsService::MEDIA_TYPE_PDF)\n )\n ->willReturn($reportResult);\n\n $this->activityService->expects($this->once())\n ->method('getActivityIdsForSavedSearch')\n ->willReturn([]);\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n}","depth":4,"bounds":{"left":0.55507815,"top":0.08472222,"width":0.43125,"height":0.9152778},"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Tests\\Unit\\Jobs\\AutomatedReports;\n\nuse Carbon\\Carbon;\nuse Jiminny\\Component\\ProphetAi\\Exceptions\\ProphetException;\nuse Jiminny\\Component\\ProphetAi\\ProphetClient;\nuse Jiminny\\Jobs\\AutomatedReports\\RequestGenerateAskJiminnyReportJob;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Models\\AutomatedReportResult;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AskJiminnyReportActivityService;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse PHPUnit\\Framework\\MockObject\\MockObject;\nuse PHPUnit\\Framework\\TestCase;\nuse Psr\\Log\\LoggerInterface;\n\nclass RequestGenerateAskJiminnyReportJobTest extends TestCase\n{\n private AutomatedReportsService&MockObject $reportService;\n private AskJiminnyReportActivityService&MockObject $activityService;\n private ProphetClient&MockObject $prophetClient;\n private LoggerInterface&MockObject $logger;\n\n protected function setUp(): void\n {\n $this->reportService = $this->createMock(AutomatedReportsService::class);\n $this->activityService = $this->createMock(AskJiminnyReportActivityService::class);\n $this->prophetClient = $this->createMock(ProphetClient::class);\n $this->logger = $this->createMock(LoggerInterface::class);\n }\n\n private function makeJob(string $uuid = 'report-uuid'): RequestGenerateAskJiminnyReportJob\n {\n return new RequestGenerateAskJiminnyReportJob($uuid);\n }\n\n private function makeActiveReport(\n string $type = AutomatedReportsService::TYPE_ASK_JIMINNY,\n bool $status = true,\n string $teamStatus = Team::STATUS_ACTIVE,\n ): AutomatedReport&MockObject { // @phpstan-ignore-line\n $team = $this->createMock(Team::class);\n $team->method('getStatus')->willReturn($teamStatus);\n\n $report = $this->createMock(AutomatedReport::class);\n $report->method('getType')->willReturn($type);\n $report->method('getStatus')->willReturn($status);\n $report->method('getTeam')->willReturn($team);\n\n return $report;\n }\n\n public function testUniqueIdReturnsReportUuid(): void\n {\n $job = $this->makeJob('my-unique-uuid');\n\n $this->assertEquals('my-unique-uuid', $job->uniqueId());\n }\n\n public function testHandleSkipsWhenReportTypeIsNotAskJiminny(): void\n {\n $report = $this->makeActiveReport(type: 'exec_summary');\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->logger->expects($this->once())\n ->method('info')\n ->with($this->stringContains('Started'));\n\n $this->logger->expects($this->once())\n ->method('warning')\n ->with($this->stringContains('not an ask_jiminny report'));\n\n $this->reportService->expects($this->never())->method('createReportResult');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleSkipsWhenReportIsInactive(): void\n {\n $report = $this->makeActiveReport(status: false);\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->logger->expects($this->exactly(2))\n ->method('info');\n\n $this->reportService->expects($this->never())->method('createReportResult');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleSkipsWhenTeamIsInactive(): void\n {\n $report = $this->makeActiveReport(teamStatus: Team::STATUS_DEACTIVATED);\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->logger->expects($this->exactly(2))\n ->method('info');\n\n $this->reportService->expects($this->never())->method('createReportResult');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleSkipsWhenCreatorIsNull(): void\n {\n $report = $this->makeActiveReport();\n $report->method('getCreator')->willReturn(null);\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->logger->expects($this->once())\n ->method('warning')\n ->with($this->stringContains('report creator not found'));\n\n $this->reportService->expects($this->never())->method('createReportResult');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleSkipsWhenSavedSearchIsNull(): void\n {\n $creator = $this->createMock(User::class);\n\n $report = $this->makeActiveReport();\n $report->method('getCreator')->willReturn($creator);\n $report->method('getSavedSearch')->willReturn(null);\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->logger->expects($this->once())\n ->method('warning')\n ->with($this->stringContains('saved search not found'));\n\n $this->reportService->expects($this->never())->method('createReportResult');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleSkipsWhenPromptIsNull(): void\n {\n $creator = $this->createMock(User::class);\n $savedSearch = $this->createMock(\\Jiminny\\Models\\Activity\\Search::class);\n\n $report = $this->makeActiveReport();\n $report->method('getCreator')->willReturn($creator);\n $report->method('getSavedSearch')->willReturn($savedSearch);\n $report->method('getAskAnythingPrompt')->willReturn(null);\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->logger->expects($this->once())\n ->method('warning')\n ->with($this->stringContains('ask anything prompt not found'));\n\n $this->reportService->expects($this->never())->method('createReportResult');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleFailsReportWhenNotEnoughActivities(): void\n {\n $creator = $this->createMock(User::class);\n $savedSearch = $this->createMock(\\Jiminny\\Models\\Activity\\Search::class);\n $prompt = $this->createMock(\\Jiminny\\Models\\AskAnything\\AskAnythingPrompt::class);\n\n $report = $this->makeActiveReport();\n $report->method('getCreator')->willReturn($creator);\n $report->method('getSavedSearch')->willReturn($savedSearch);\n $report->method('getAskAnythingPrompt')->willReturn($prompt);\n\n $reportResult = $this->createMock(AutomatedReportResult::class);\n $reportResult->expects($this->once())\n ->method('update')\n ->with($this->callback(fn ($data) => $data['status'] === AutomatedReportResult::STATUS_FAILED\n && $data['reason'] === AutomatedReportResult::REASON_NOT_ENOUGH_ACTIVITIES));\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->reportService->expects($this->once())\n ->method('createReportResult')\n ->willReturn($reportResult);\n\n $this->activityService->expects($this->once())\n ->method('getActivityIdsForSavedSearch')\n ->willReturn([]);\n\n $this->logger->expects($this->exactly(3))\n ->method('info');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleSuccessfullyRequestsReport(): void\n {\n Carbon::setTestNow(Carbon::parse('2026-04-07 10:00:00'));\n\n $creator = $this->createMock(User::class);\n $savedSearch = $this->createMock(\\Jiminny\\Models\\Activity\\Search::class);\n $prompt = $this->createMock(\\Jiminny\\Models\\AskAnything\\AskAnythingPrompt::class);\n\n $report = $this->makeActiveReport();\n $report->method('getCreator')->willReturn($creator);\n $report->method('getSavedSearch')->willReturn($savedSearch);\n $report->method('getAskAnythingPrompt')->willReturn($prompt);\n $report->method('getUuid')->willReturn('report-uuid');\n\n $reportResult = $this->createMock(AutomatedReportResult::class);\n $reportResult->method('getUuid')->willReturn('result-uuid');\n $reportResult->expects($this->once())\n ->method('update')\n ->with($this->callback(fn ($data) => $data['status'] === AutomatedReportResult::STATUS_REQUESTED\n && isset($data['name'], $data['payload'], $data['requested_at'])));\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->reportService->expects($this->once())\n ->method('createReportResult')\n ->willReturn($reportResult);\n\n $this->reportService->expects($this->once())\n ->method('getAskJiminnyGenerateReportPayload')\n ->willReturn(['key' => 'value']);\n\n $this->reportService->expects($this->once())\n ->method('getReportFileName')\n ->willReturn('My Report - 7 Apr 2026');\n\n $this->activityService->expects($this->once())\n ->method('getActivityIdsForSavedSearch')\n ->willReturn(['act-1', 'act-2']);\n\n $this->prophetClient->expects($this->once())\n ->method('sendRequest')\n ->willReturn(new \\Jiminny\\Component\\ProphetAi\\Dtos\\ProphetResponseDto([]));\n\n $this->logger->expects($this->exactly(4))\n ->method('info');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n\n Carbon::setTestNow();\n }\n\n public function testHandleCatchesGenericExceptionAndLogsError(): void\n {\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willThrowException(new \\RuntimeException('DB error'));\n\n $this->logger->expects($this->once())\n ->method('error')\n ->with($this->stringContains('Error'));\n\n $job = $this->makeJob();\n\n $reflection = new \\ReflectionClass($job);\n $triesProp = $reflection->getProperty('tries');\n $triesProp->setAccessible(true);\n\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleCatchesProphetExceptionAndSetsCorrectReason(): void\n {\n $creator = $this->createMock(User::class);\n $savedSearch = $this->createMock(\\Jiminny\\Models\\Activity\\Search::class);\n $prompt = $this->createMock(\\Jiminny\\Models\\AskAnything\\AskAnythingPrompt::class);\n\n $report = $this->makeActiveReport();\n $report->method('getCreator')->willReturn($creator);\n $report->method('getSavedSearch')->willReturn($savedSearch);\n $report->method('getAskAnythingPrompt')->willReturn($prompt);\n\n $reportResult = $this->createMock(AutomatedReportResult::class);\n $reportResult->method('getUuid')->willReturn('result-uuid');\n $reportResult->expects($this->once())\n ->method('update')\n ->with($this->callback(fn ($data) => $data['reason'] === AutomatedReportResult::REASON_PROPHET_API_ERROR));\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->reportService->expects($this->once())\n ->method('createReportResult')\n ->willReturn($reportResult);\n\n $this->activityService->expects($this->once())\n ->method('getActivityIdsForSavedSearch')\n ->willThrowException(new ProphetException('Prophet failed'));\n\n $this->logger->expects($this->once())\n ->method('error');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleCreatesReportResultBeforeActivityFetch(): void\n {\n $creator = $this->createMock(User::class);\n $savedSearch = $this->createMock(\\Jiminny\\Models\\Activity\\Search::class);\n $prompt = $this->createMock(\\Jiminny\\Models\\AskAnything\\AskAnythingPrompt::class);\n\n $report = $this->makeActiveReport();\n $report->method('getCreator')->willReturn($creator);\n $report->method('getSavedSearch')->willReturn($savedSearch);\n $report->method('getAskAnythingPrompt')->willReturn($prompt);\n\n $reportResult = $this->createMock(AutomatedReportResult::class);\n $reportResult->method('getUuid')->willReturn('result-uuid');\n\n $callOrder = [];\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->reportService->expects($this->once())\n ->method('createReportResult')\n ->willReturnCallback(function () use ($reportResult, &$callOrder) {\n $callOrder[] = 'createReportResult';\n\n return $reportResult;\n });\n\n $this->activityService->expects($this->once())\n ->method('getActivityIdsForSavedSearch')\n ->willReturnCallback(function () use (&$callOrder) {\n $callOrder[] = 'getActivityIds';\n\n return [];\n });\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n\n $this->assertEquals(['createReportResult', 'getActivityIds'], $callOrder);\n }\n\n public function testHandlePassesCorrectDataToCreateReportResult(): void\n {\n $creator = $this->createMock(User::class);\n $savedSearch = $this->createMock(\\Jiminny\\Models\\Activity\\Search::class);\n $prompt = $this->createMock(\\Jiminny\\Models\\AskAnything\\AskAnythingPrompt::class);\n\n $report = $this->makeActiveReport();\n $report->method('getCreator')->willReturn($creator);\n $report->method('getSavedSearch')->willReturn($savedSearch);\n $report->method('getAskAnythingPrompt')->willReturn($prompt);\n\n $reportResult = $this->createMock(AutomatedReportResult::class);\n $reportResult->method('getUuid')->willReturn('result-uuid');\n $reportResult->method('update')->willReturn(true);\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->reportService->expects($this->once())\n ->method('createReportResult')\n ->with(\n automatedReport: $report,\n data: $this->callback(fn ($data) => $data['status'] === AutomatedReportResult::STATUS_DEFAULT\n && $data['media_type'] === AutomatedReportsService::MEDIA_TYPE_PDF)\n )\n ->willReturn($reportResult);\n\n $this->activityService->expects($this->once())\n ->method('getActivityIdsForSavedSearch')\n ->willReturn([]);\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"bounds":{"left":0.0140625,"top":0.041666668,"width":0.028515626,"height":0.021527778},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
8260492435066441110
|
8722295178528246161
|
visual_change
|
accessibility
|
NULL
|
Project: faVsco.js, menu
#11894 on JY-18909-automa Project: faVsco.js, menu
#11894 on JY-18909-automated-reports-ask-jiminny, menu
Start Listening for PHP Debug Connections
RequestGenerateAskJiminnyReportJobTest
Run 'RequestGenerateAskJiminnyReportJobTest'
Debug 'RequestGenerateAskJiminnyReportJobTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Console\Commands\Reports;
use Carbon\Carbon;
use Illuminate\Console\Command;
use Illuminate\Contracts\Bus\Dispatcher as BusDispatcher;
use Jiminny\Jobs\AutomatedReports\RequestGenerateAskJiminnyReportJob;
use Jiminny\Jobs\AutomatedReports\RequestGenerateReportJob;
use Jiminny\Models\AutomatedReport;
use Jiminny\Repositories\AutomatedReportsRepository;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Psr\Log\LoggerInterface;
class AutomatedReportsCommand extends Command
{
/**
* Log prefix for all log messages
*/
private const string LOG_PREFIX = '[automated-reports]';
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'automated-reports';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Process automated reports based on their frequency (weekly, monthly, quarterly)';
public function __construct(
private readonly LoggerInterface $logger,
private readonly BusDispatcher $dispatcher,
private readonly AutomatedReportsRepository $reportRepository
) {
parent::__construct();
}
/**
* Execute the console command.
*
* @return int
*/
public function handle(): int
{
$this->logger->info(self::LOG_PREFIX . ' Started');
$now = Carbon::now();
$isMonday = $now->isMonday();
$isFirstDayOfMonth = $now->day === 1;
$currentMonth = $now->month;
// Check if the current month is a quarterly month (January, April, July, October)
$isQuarterlyMonth = in_array($currentMonth, [1, 4, 7, 10], true);
$this->logger->info(self::LOG_PREFIX . ' Checking conditions', [
'isMonday' => $isMonday,
'isFirstDayOfMonth' => $isFirstDayOfMonth,
'currentMonth' => $currentMonth,
'isQuarterlyMonth' => $isQuarterlyMonth,
]);
// Process daily reports
$this->processReports(AutomatedReportsService::FREQUENCY_DAILY);
// Process weekly reports on Mondays
if ($isMonday) {
$this->processReports(AutomatedReportsService::FREQUENCY_WEEKLY);
}
// Process monthly reports on the first day of the month
if ($isFirstDayOfMonth) {
$this->processReports(AutomatedReportsService::FREQUENCY_MONTHLY);
}
// Process quarterly reports on the first day of January, April, July, and October
if ($isFirstDayOfMonth && $isQuarterlyMonth) {
$this->processReports(AutomatedReportsService::FREQUENCY_QUARTERLY);
}
$this->logger->info(self::LOG_PREFIX . ' Completed');
return 0;
}
/**
* Process reports for a specific frequency.
*
* @param string $frequency
*
* @return void
*/
private function processReports(string $frequency): void
{
$this->logger->info(self::LOG_PREFIX . " Processing $frequency reports");
// Get all enabled, not deleted reports with active teams for the specified frequency
$reports = $this->reportRepository->getActiveReportsByFrequency($frequency);
// $reports = collect([AutomatedReport::find(68)]);
$this->logger->info(self::LOG_PREFIX . " Found {$reports->count()} $frequency reports to process");
/** @var AutomatedReport $report */
foreach ($reports as $report) {
$this->logger->info(self::LOG_PREFIX . ' Dispatching Generate Report job for report', [
'reportUuid' => $report->getUuid(),
'teamId' => $report->getTeamId(),
'frequency' => $report->getFrequency(),
'type' => $report->getType(),
]);
$job = $report->isAskJiminnyReport()
? new RequestGenerateAskJiminnyReportJob($report->getUuid())
: new RequestGenerateReportJob($report->getUuid());
// $this->dispatcher->dispatch($job);
$this->dispatcher->dispatchSync($job);
}
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
1
14
4
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Tests\Unit\Jobs\AutomatedReports;
use Carbon\Carbon;
use Jiminny\Component\ProphetAi\Exceptions\ProphetException;
use Jiminny\Component\ProphetAi\ProphetClient;
use Jiminny\Jobs\AutomatedReports\RequestGenerateAskJiminnyReportJob;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\AutomatedReportResult;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityService;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
use Psr\Log\LoggerInterface;
class RequestGenerateAskJiminnyReportJobTest extends TestCase
{
private AutomatedReportsService&MockObject $reportService;
private AskJiminnyReportActivityService&MockObject $activityService;
private ProphetClient&MockObject $prophetClient;
private LoggerInterface&MockObject $logger;
protected function setUp(): void
{
$this->reportService = $this->createMock(AutomatedReportsService::class);
$this->activityService = $this->createMock(AskJiminnyReportActivityService::class);
$this->prophetClient = $this->createMock(ProphetClient::class);
$this->logger = $this->createMock(LoggerInterface::class);
}
private function makeJob(string $uuid = 'report-uuid'): RequestGenerateAskJiminnyReportJob
{
return new RequestGenerateAskJiminnyReportJob($uuid);
}
private function makeActiveReport(
string $type = AutomatedReportsService::TYPE_ASK_JIMINNY,
bool $status = true,
string $teamStatus = Team::STATUS_ACTIVE,
): AutomatedReport&MockObject { // @phpstan-ignore-line
$team = $this->createMock(Team::class);
$team->method('getStatus')->willReturn($teamStatus);
$report = $this->createMock(AutomatedReport::class);
$report->method('getType')->willReturn($type);
$report->method('getStatus')->willReturn($status);
$report->method('getTeam')->willReturn($team);
return $report;
}
public function testUniqueIdReturnsReportUuid(): void
{
$job = $this->makeJob('my-unique-uuid');
$this->assertEquals('my-unique-uuid', $job->uniqueId());
}
public function testHandleSkipsWhenReportTypeIsNotAskJiminny(): void
{
$report = $this->makeActiveReport(type: 'exec_summary');
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->logger->expects($this->once())
->method('info')
->with($this->stringContains('Started'));
$this->logger->expects($this->once())
->method('warning')
->with($this->stringContains('not an ask_jiminny report'));
$this->reportService->expects($this->never())->method('createReportResult');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleSkipsWhenReportIsInactive(): void
{
$report = $this->makeActiveReport(status: false);
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->logger->expects($this->exactly(2))
->method('info');
$this->reportService->expects($this->never())->method('createReportResult');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleSkipsWhenTeamIsInactive(): void
{
$report = $this->makeActiveReport(teamStatus: Team::STATUS_DEACTIVATED);
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->logger->expects($this->exactly(2))
->method('info');
$this->reportService->expects($this->never())->method('createReportResult');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleSkipsWhenCreatorIsNull(): void
{
$report = $this->makeActiveReport();
$report->method('getCreator')->willReturn(null);
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->logger->expects($this->once())
->method('warning')
->with($this->stringContains('report creator not found'));
$this->reportService->expects($this->never())->method('createReportResult');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleSkipsWhenSavedSearchIsNull(): void
{
$creator = $this->createMock(User::class);
$report = $this->makeActiveReport();
$report->method('getCreator')->willReturn($creator);
$report->method('getSavedSearch')->willReturn(null);
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->logger->expects($this->once())
->method('warning')
->with($this->stringContains('saved search not found'));
$this->reportService->expects($this->never())->method('createReportResult');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleSkipsWhenPromptIsNull(): void
{
$creator = $this->createMock(User::class);
$savedSearch = $this->createMock(\Jiminny\Models\Activity\Search::class);
$report = $this->makeActiveReport();
$report->method('getCreator')->willReturn($creator);
$report->method('getSavedSearch')->willReturn($savedSearch);
$report->method('getAskAnythingPrompt')->willReturn(null);
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->logger->expects($this->once())
->method('warning')
->with($this->stringContains('ask anything prompt not found'));
$this->reportService->expects($this->never())->method('createReportResult');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleFailsReportWhenNotEnoughActivities(): void
{
$creator = $this->createMock(User::class);
$savedSearch = $this->createMock(\Jiminny\Models\Activity\Search::class);
$prompt = $this->createMock(\Jiminny\Models\AskAnything\AskAnythingPrompt::class);
$report = $this->makeActiveReport();
$report->method('getCreator')->willReturn($creator);
$report->method('getSavedSearch')->willReturn($savedSearch);
$report->method('getAskAnythingPrompt')->willReturn($prompt);
$reportResult = $this->createMock(AutomatedReportResult::class);
$reportResult->expects($this->once())
->method('update')
->with($this->callback(fn ($data) => $data['status'] === AutomatedReportResult::STATUS_FAILED
&& $data['reason'] === AutomatedReportResult::REASON_NOT_ENOUGH_ACTIVITIES));
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->reportService->expects($this->once())
->method('createReportResult')
->willReturn($reportResult);
$this->activityService->expects($this->once())
->method('getActivityIdsForSavedSearch')
->willReturn([]);
$this->logger->expects($this->exactly(3))
->method('info');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleSuccessfullyRequestsReport(): void
{
Carbon::setTestNow(Carbon::parse('2026-04-07 10:00:00'));
$creator = $this->createMock(User::class);
$savedSearch = $this->createMock(\Jiminny\Models\Activity\Search::class);
$prompt = $this->createMock(\Jiminny\Models\AskAnything\AskAnythingPrompt::class);
$report = $this->makeActiveReport();
$report->method('getCreator')->willReturn($creator);
$report->method('getSavedSearch')->willReturn($savedSearch);
$report->method('getAskAnythingPrompt')->willReturn($prompt);
$report->method('getUuid')->willReturn('report-uuid');
$reportResult = $this->createMock(AutomatedReportResult::class);
$reportResult->method('getUuid')->willReturn('result-uuid');
$reportResult->expects($this->once())
->method('update')
->with($this->callback(fn ($data) => $data['status'] === AutomatedReportResult::STATUS_REQUESTED
&& isset($data['name'], $data['payload'], $data['requested_at'])));
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->reportService->expects($this->once())
->method('createReportResult')
->willReturn($reportResult);
$this->reportService->expects($this->once())
->method('getAskJiminnyGenerateReportPayload')
->willReturn(['key' => 'value']);
$this->reportService->expects($this->once())
->method('getReportFileName')
->willReturn('My Report - 7 Apr 2026');
$this->activityService->expects($this->once())
->method('getActivityIdsForSavedSearch')
->willReturn(['act-1', 'act-2']);
$this->prophetClient->expects($this->once())
->method('sendRequest')
->willReturn(new \Jiminny\Component\ProphetAi\Dtos\ProphetResponseDto([]));
$this->logger->expects($this->exactly(4))
->method('info');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
Carbon::setTestNow();
}
public function testHandleCatchesGenericExceptionAndLogsError(): void
{
$this->reportService->expects($this->once())
->method('getReport')
->willThrowException(new \RuntimeException('DB error'));
$this->logger->expects($this->once())
->method('error')
->with($this->stringContains('Error'));
$job = $this->makeJob();
$reflection = new \ReflectionClass($job);
$triesProp = $reflection->getProperty('tries');
$triesProp->setAccessible(true);
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleCatchesProphetExceptionAndSetsCorrectReason(): void
{
$creator = $this->createMock(User::class);
$savedSearch = $this->createMock(\Jiminny\Models\Activity\Search::class);
$prompt = $this->createMock(\Jiminny\Models\AskAnything\AskAnythingPrompt::class);
$report = $this->makeActiveReport();
$report->method('getCreator')->willReturn($creator);
$report->method('getSavedSearch')->willReturn($savedSearch);
$report->method('getAskAnythingPrompt')->willReturn($prompt);
$reportResult = $this->createMock(AutomatedReportResult::class);
$reportResult->method('getUuid')->willReturn('result-uuid');
$reportResult->expects($this->once())
->method('update')
->with($this->callback(fn ($data) => $data['reason'] === AutomatedReportResult::REASON_PROPHET_API_ERROR));
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->reportService->expects($this->once())
->method('createReportResult')
->willReturn($reportResult);
$this->activityService->expects($this->once())
->method('getActivityIdsForSavedSearch')
->willThrowException(new ProphetException('Prophet failed'));
$this->logger->expects($this->once())
->method('error');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleCreatesReportResultBeforeActivityFetch(): void
{
$creator = $this->createMock(User::class);
$savedSearch = $this->createMock(\Jiminny\Models\Activity\Search::class);
$prompt = $this->createMock(\Jiminny\Models\AskAnything\AskAnythingPrompt::class);
$report = $this->makeActiveReport();
$report->method('getCreator')->willReturn($creator);
$report->method('getSavedSearch')->willReturn($savedSearch);
$report->method('getAskAnythingPrompt')->willReturn($prompt);
$reportResult = $this->createMock(AutomatedReportResult::class);
$reportResult->method('getUuid')->willReturn('result-uuid');
$callOrder = [];
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->reportService->expects($this->once())
->method('createReportResult')
->willReturnCallback(function () use ($reportResult, &$callOrder) {
$callOrder[] = 'createReportResult';
return $reportResult;
});
$this->activityService->expects($this->once())
->method('getActivityIdsForSavedSearch')
->willReturnCallback(function () use (&$callOrder) {
$callOrder[] = 'getActivityIds';
return [];
});
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
$this->assertEquals(['createReportResult', 'getActivityIds'], $callOrder);
}
public function testHandlePassesCorrectDataToCreateReportResult(): void
{
$creator = $this->createMock(User::class);
$savedSearch = $this->createMock(\Jiminny\Models\Activity\Search::class);
$prompt = $this->createMock(\Jiminny\Models\AskAnything\AskAnythingPrompt::class);
$report = $this->makeActiveReport();
$report->method('getCreator')->willReturn($creator);
$report->method('getSavedSearch')->willReturn($savedSearch);
$report->method('getAskAnythingPrompt')->willReturn($prompt);
$reportResult = $this->createMock(AutomatedReportResult::class);
$reportResult->method('getUuid')->willReturn('result-uuid');
$reportResult->method('update')->willReturn(true);
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->reportService->expects($this->once())
->method('createReportResult')
->with(
automatedReport: $report,
data: $this->callback(fn ($data) => $data['status'] === AutomatedReportResult::STATUS_DEFAULT
&& $data['media_type'] === AutomatedReportsService::MEDIA_TYPE_PDF)
)
->willReturn($reportResult);
$this->activityService->expects($this->once())
->method('getActivityIdsForSavedSearch')
->willReturn([]);
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
NULL
|
|
9496
|
185
|
0
|
2026-04-14T07:41:24.495621+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776152484495_m2.jpg...
|
PhpStorm
|
faVsco.js – AutomatedReportsCommand.php
|
True
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
#11894 on JY-18909-automa Project: faVsco.js, menu
#11894 on JY-18909-automated-reports-ask-jiminny, menu
Start Listening for PHP Debug Connections
RequestGenerateAskJiminnyReportJobTest
Run 'RequestGenerateAskJiminnyReportJobTest'
Debug 'RequestGenerateAskJiminnyReportJobTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
Analyzing…
<?php
declare(strict_types=1);
namespace Jiminny\Console\Commands\Reports;
use Carbon\Carbon;
use Illuminate\Console\Command;
use Illuminate\Contracts\Bus\Dispatcher as BusDispatcher;
use Jiminny\Jobs\AutomatedReports\RequestGenerateAskJiminnyReportJob;
use Jiminny\Jobs\AutomatedReports\RequestGenerateReportJob;
use Jiminny\Models\AutomatedReport;
use Jiminny\Repositories\AutomatedReportsRepository;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Psr\Log\LoggerInterface;
class AutomatedReportsCommand extends Command
{
/**
* Log prefix for all log messages
*/
private const string LOG_PREFIX = '[automated-reports]';
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'automated-reports';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Process automated reports based on their frequency (weekly, monthly, quarterly)';
public function __construct(
private readonly LoggerInterface $logger,
private readonly BusDispatcher $dispatcher,
private readonly AutomatedReportsRepository $reportRepository
) {
parent::__construct();
}
/**
* Execute the console command.
*
* @return int
*/
public function handle(): int
{
$this->logger->info(self::LOG_PREFIX . ' Started');
$now = Carbon::now();
$isMonday = $now->isMonday();
$isFirstDayOfMonth = $now->day === 1;
$currentMonth = $now->month;
// Check if the current month is a quarterly month (January, April, July, October)
$isQuarterlyMonth = in_array($currentMonth, [1, 4, 7, 10], true);
$this->logger->info(self::LOG_PREFIX . ' Checking conditions', [
'isMonday' => $isMonday,
'isFirstDayOfMonth' => $isFirstDayOfMonth,
'currentMonth' => $currentMonth,
'isQuarterlyMonth' => $isQuarterlyMonth,
]);
// Process daily reports
$this->processReports(AutomatedReportsService::FREQUENCY_DAILY);
// Process weekly reports on Mondays
if ($isMonday) {
$this->processReports(AutomatedReportsService::FREQUENCY_WEEKLY);
}
// Process monthly reports on the first day of the month
if ($isFirstDayOfMonth) {
$this->processReports(AutomatedReportsService::FREQUENCY_MONTHLY);
}
// Process quarterly reports on the first day of January, April, July, and October
if ($isFirstDayOfMonth && $isQuarterlyMonth) {
$this->processReports(AutomatedReportsService::FREQUENCY_QUARTERLY);
}
$this->logger->info(self::LOG_PREFIX . ' Completed');
return 0;
}
/**
* Process reports for a specific frequency.
*
* @param string $frequency
*
* @return void
*/
private function processReports(string $frequency): void
{
$this->logger->info(self::LOG_PREFIX . " Processing $frequency reports");
// Get all enabled, not deleted reports with active teams for the specified frequency
$reports = $this->reportRepository->getActiveReportsByFrequency($frequency);
// $reports = collect([AutomatedReport::find(68)]);
$this->logger->info(self::LOG_PREFIX . " Found {$reports->count()} $frequency reports to process");
/** @var AutomatedReport $report */
foreach ($reports as $report) {
$this->logger->info(self::LOG_PREFIX . ' Dispatching Generate Report job for report', [
'reportUuid' => $report->getUuid(),
'teamId' => $report->getTeamId(),
'frequency' => $report->getFrequency(),
'type' => $report->getType(),
]);
$job = $report->isAskJiminnyReport()
? new RequestGenerateAskJiminnyReportJob($report->getUuid())
: new RequestGenerateReportJob($report->getUuid());
// $this->dispatcher->dispatch($job);
$this->dispatcher->dispatchSync($job);
}
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
1
14
4
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Tests\Unit\Jobs\AutomatedReports;
use Carbon\Carbon;
use Jiminny\Component\ProphetAi\Exceptions\ProphetException;
use Jiminny\Component\ProphetAi\ProphetClient;
use Jiminny\Jobs\AutomatedReports\RequestGenerateAskJiminnyReportJob;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\AutomatedReportResult;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityService;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
use Psr\Log\LoggerInterface;
class RequestGenerateAskJiminnyReportJobTest extends TestCase
{
private AutomatedReportsService&MockObject $reportService;
private AskJiminnyReportActivityService&MockObject $activityService;
private ProphetClient&MockObject $prophetClient;
private LoggerInterface&MockObject $logger;
protected function setUp(): void
{
$this->reportService = $this->createMock(AutomatedReportsService::class);
$this->activityService = $this->createMock(AskJiminnyReportActivityService::class);
$this->prophetClient = $this->createMock(ProphetClient::class);
$this->logger = $this->createMock(LoggerInterface::class);
}
private function makeJob(string $uuid = 'report-uuid'): RequestGenerateAskJiminnyReportJob
{
return new RequestGenerateAskJiminnyReportJob($uuid);
}
private function makeActiveReport(
string $type = AutomatedReportsService::TYPE_ASK_JIMINNY,
bool $status = true,
string $teamStatus = Team::STATUS_ACTIVE,
): AutomatedReport&MockObject { // @phpstan-ignore-line
$team = $this->createMock(Team::class);
$team->method('getStatus')->willReturn($teamStatus);
$report = $this->createMock(AutomatedReport::class);
$report->method('getType')->willReturn($type);
$report->method('getStatus')->willReturn($status);
$report->method('getTeam')->willReturn($team);
return $report;
}
public function testUniqueIdReturnsReportUuid(): void
{
$job = $this->makeJob('my-unique-uuid');
$this->assertEquals('my-unique-uuid', $job->uniqueId());
}
public function testHandleSkipsWhenReportTypeIsNotAskJiminny(): void
{
$report = $this->makeActiveReport(type: 'exec_summary');
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->logger->expects($this->once())
->method('info')
->with($this->stringContains('Started'));
$this->logger->expects($this->once())
->method('warning')
->with($this->stringContains('not an ask_jiminny report'));
$this->reportService->expects($this->never())->method('createReportResult');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleSkipsWhenReportIsInactive(): void
{
$report = $this->makeActiveReport(status: false);
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->logger->expects($this->exactly(2))
->method('info');
$this->reportService->expects($this->never())->method('createReportResult');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleSkipsWhenTeamIsInactive(): void
{
$report = $this->makeActiveReport(teamStatus: Team::STATUS_DEACTIVATED);
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->logger->expects($this->exactly(2))
->method('info');
$this->reportService->expects($this->never())->method('createReportResult');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleSkipsWhenCreatorIsNull(): void
{
$report = $this->makeActiveReport();
$report->method('getCreator')->willReturn(null);
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->logger->expects($this->once())
->method('warning')
->with($this->stringContains('report creator not found'));
$this->reportService->expects($this->never())->method('createReportResult');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleSkipsWhenSavedSearchIsNull(): void
{
$creator = $this->createMock(User::class);
$report = $this->makeActiveReport();
$report->method('getCreator')->willReturn($creator);
$report->method('getSavedSearch')->willReturn(null);
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->logger->expects($this->once())
->method('warning')
->with($this->stringContains('saved search not found'));
$this->reportService->expects($this->never())->method('createReportResult');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleSkipsWhenPromptIsNull(): void
{
$creator = $this->createMock(User::class);
$savedSearch = $this->createMock(\Jiminny\Models\Activity\Search::class);
$report = $this->makeActiveReport();
$report->method('getCreator')->willReturn($creator);
$report->method('getSavedSearch')->willReturn($savedSearch);
$report->method('getAskAnythingPrompt')->willReturn(null);
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->logger->expects($this->once())
->method('warning')
->with($this->stringContains('ask anything prompt not found'));
$this->reportService->expects($this->never())->method('createReportResult');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleFailsReportWhenNotEnoughActivities(): void
{
$creator = $this->createMock(User::class);
$savedSearch = $this->createMock(\Jiminny\Models\Activity\Search::class);
$prompt = $this->createMock(\Jiminny\Models\AskAnything\AskAnythingPrompt::class);
$report = $this->makeActiveReport();
$report->method('getCreator')->willReturn($creator);
$report->method('getSavedSearch')->willReturn($savedSearch);
$report->method('getAskAnythingPrompt')->willReturn($prompt);
$reportResult = $this->createMock(AutomatedReportResult::class);
$reportResult->expects($this->once())
->method('update')
->with($this->callback(fn ($data) => $data['status'] === AutomatedReportResult::STATUS_FAILED
&& $data['reason'] === AutomatedReportResult::REASON_NOT_ENOUGH_ACTIVITIES));
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->reportService->expects($this->once())
->method('createReportResult')
->willReturn($reportResult);
$this->activityService->expects($this->once())
->method('getActivityIdsForSavedSearch')
->willReturn([]);
$this->logger->expects($this->exactly(3))
->method('info');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleSuccessfullyRequestsReport(): void
{
Carbon::setTestNow(Carbon::parse('2026-04-07 10:00:00'));
$creator = $this->createMock(User::class);
$savedSearch = $this->createMock(\Jiminny\Models\Activity\Search::class);
$prompt = $this->createMock(\Jiminny\Models\AskAnything\AskAnythingPrompt::class);
$report = $this->makeActiveReport();
$report->method('getCreator')->willReturn($creator);
$report->method('getSavedSearch')->willReturn($savedSearch);
$report->method('getAskAnythingPrompt')->willReturn($prompt);
$report->method('getUuid')->willReturn('report-uuid');
$reportResult = $this->createMock(AutomatedReportResult::class);
$reportResult->method('getUuid')->willReturn('result-uuid');
$reportResult->expects($this->once())
->method('update')
->with($this->callback(fn ($data) => $data['status'] === AutomatedReportResult::STATUS_REQUESTED
&& isset($data['name'], $data['payload'], $data['requested_at'])));
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->reportService->expects($this->once())
->method('createReportResult')
->willReturn($reportResult);
$this->reportService->expects($this->once())
->method('getAskJiminnyGenerateReportPayload')
->willReturn(['key' => 'value']);
$this->reportService->expects($this->once())
->method('getReportFileName')
->willReturn('My Report - 7 Apr 2026');
$this->activityService->expects($this->once())
->method('getActivityIdsForSavedSearch')
->willReturn(['act-1', 'act-2']);
$this->prophetClient->expects($this->once())
->method('sendRequest')
->willReturn(new \Jiminny\Component\ProphetAi\Dtos\ProphetResponseDto([]));
$this->logger->expects($this->exactly(4))
->method('info');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
Carbon::setTestNow();
}
public function testHandleCatchesGenericExceptionAndLogsError(): void
{
$this->reportService->expects($this->once())
->method('getReport')
->willThrowException(new \RuntimeException('DB error'));
$this->logger->expects($this->once())
->method('error')
->with($this->stringContains('Error'));
$job = $this->makeJob();
$reflection = new \ReflectionClass($job);
$triesProp = $reflection->getProperty('tries');
$triesProp->setAccessible(true);
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleCatchesProphetExceptionAndSetsCorrectReason(): void
{
$creator = $this->createMock(User::class);
$savedSearch = $this->createMock(\Jiminny\Models\Activity\Search::class);
$prompt = $this->createMock(\Jiminny\Models\AskAnything\AskAnythingPrompt::class);
$report = $this->makeActiveReport();
$report->method('getCreator')->willReturn($creator);
$report->method('getSavedSearch')->willReturn($savedSearch);
$report->method('getAskAnythingPrompt')->willReturn($prompt);
$reportResult = $this->createMock(AutomatedReportResult::class);
$reportResult->method('getUuid')->willReturn('result-uuid');
$reportResult->expects($this->once())
->method('update')
->with($this->callback(fn ($data) => $data['reason'] === AutomatedReportResult::REASON_PROPHET_API_ERROR));
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->reportService->expects($this->once())
->method('createReportResult')
->willReturn($reportResult);
$this->activityService->expects($this->once())
->method('getActivityIdsForSavedSearch')
->willThrowException(new ProphetException('Prophet failed'));
$this->logger->expects($this->once())
->method('error');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleCreatesReportResultBeforeActivityFetch(): void
{
$creator = $this->createMock(User::class);
$savedSearch = $this->createMock(\Jiminny\Models\Activity\Search::class);
$prompt = $this->createMock(\Jiminny\Models\AskAnything\AskAnythingPrompt::class);
$report = $this->makeActiveReport();
$report->method('getCreator')->willReturn($creator);
$report->method('getSavedSearch')->willReturn($savedSearch);
$report->method('getAskAnythingPrompt')->willReturn($prompt);
$reportResult = $this->createMock(AutomatedReportResult::class);
$reportResult->method('getUuid')->willReturn('result-uuid');
$callOrder = [];
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->reportService->expects($this->once())
->method('createReportResult')
->willReturnCallback(function () use ($reportResult, &$callOrder) {
$callOrder[] = 'createReportResult';
return $reportResult;
});
$this->activityService->expects($this->once())
->method('getActivityIdsForSavedSearch')
->willReturnCallback(function () use (&$callOrder) {
$callOrder[] = 'getActivityIds';
return [];
});
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
$this->assertEquals(['createReportResult', 'getActivityIds'], $callOrder);
}
public function testHandlePassesCorrectDataToCreateReportResult(): void
{
$creator = $this->createMock(User::class);
$savedSearch = $this->createMock(\Jiminny\Models\Activity\Search::class);
$prompt = $this->createMock(\Jiminny\Models\AskAnything\AskAnythingPrompt::class);
$report = $this->makeActiveReport();
$report->method('getCreator')->willReturn($creator);
$report->method('getSavedSearch')->willReturn($savedSearch);
$report->method('getAskAnythingPrompt')->willReturn($prompt);
$reportResult = $this->createMock(AutomatedReportResult::class);
$reportResult->method('getUuid')->willReturn('result-uuid');
$reportResult->method('update')->willReturn(true);
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->reportService->expects($this->once())
->method('createReportResult')
->with(
automatedReport: $report,
data: $this->callback(fn ($data) => $data['status'] === AutomatedReportResult::STATUS_DEFAULT
&& $data['media_type'] === AutomatedReportsService::MEDIA_TYPE_PDF)
)
->willReturn($reportResult);
$this->activityService->expects($this->once())
->method('getActivityIdsForSavedSearch')
->willReturn([]);
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.03046875,"top":0.017361112,"width":0.0453125,"height":0.022222223},"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"#11894 on JY-18909-automated-reports-ask-jiminny, menu","depth":5,"bounds":{"left":0.07578125,"top":0.017361112,"width":0.14960937,"height":0.022222223},"help_text":"Pull request #11894 exists for current branch JY-18909-automated-reports-ask-jiminny, but local branch is out of sync with remote","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.76171875,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"RequestGenerateAskJiminnyReportJobTest","depth":6,"bounds":{"left":0.7796875,"top":0.017361112,"width":0.12109375,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'RequestGenerateAskJiminnyReportJobTest'","depth":6,"bounds":{"left":0.9007813,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'RequestGenerateAskJiminnyReportJobTest'","depth":6,"bounds":{"left":0.9140625,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9273437,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96015626,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9734375,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9867188,"top":0.017361112,"width":0.013281226,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.049609374,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Analyzing…","depth":4,"bounds":{"left":0.50273436,"top":0.13055556,"width":0.0234375,"height":0.013194445},"role_description":"text"},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Console\\Commands\\Reports;\n\nuse Carbon\\Carbon;\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Contracts\\Bus\\Dispatcher as BusDispatcher;\nuse Jiminny\\Jobs\\AutomatedReports\\RequestGenerateAskJiminnyReportJob;\nuse Jiminny\\Jobs\\AutomatedReports\\RequestGenerateReportJob;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Repositories\\AutomatedReportsRepository;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Psr\\Log\\LoggerInterface;\n\nclass AutomatedReportsCommand extends Command\n{\n /**\n * Log prefix for all log messages\n */\n private const string LOG_PREFIX = '[automated-reports]';\n\n /**\n * The name and signature of the console command.\n *\n * @var string\n */\n protected $signature = 'automated-reports';\n\n /**\n * The console command description.\n *\n * @var string\n */\n protected $description = 'Process automated reports based on their frequency (weekly, monthly, quarterly)';\n\n\n public function __construct(\n private readonly LoggerInterface $logger,\n private readonly BusDispatcher $dispatcher,\n private readonly AutomatedReportsRepository $reportRepository\n ) {\n parent::__construct();\n }\n\n /**\n * Execute the console command.\n *\n * @return int\n */\n public function handle(): int\n {\n $this->logger->info(self::LOG_PREFIX . ' Started');\n\n $now = Carbon::now();\n $isMonday = $now->isMonday();\n $isFirstDayOfMonth = $now->day === 1;\n $currentMonth = $now->month;\n\n // Check if the current month is a quarterly month (January, April, July, October)\n $isQuarterlyMonth = in_array($currentMonth, [1, 4, 7, 10], true);\n\n $this->logger->info(self::LOG_PREFIX . ' Checking conditions', [\n 'isMonday' => $isMonday,\n 'isFirstDayOfMonth' => $isFirstDayOfMonth,\n 'currentMonth' => $currentMonth,\n 'isQuarterlyMonth' => $isQuarterlyMonth,\n ]);\n\n // Process daily reports\n $this->processReports(AutomatedReportsService::FREQUENCY_DAILY);\n\n // Process weekly reports on Mondays\n if ($isMonday) {\n $this->processReports(AutomatedReportsService::FREQUENCY_WEEKLY);\n }\n\n // Process monthly reports on the first day of the month\n if ($isFirstDayOfMonth) {\n $this->processReports(AutomatedReportsService::FREQUENCY_MONTHLY);\n }\n\n // Process quarterly reports on the first day of January, April, July, and October\n if ($isFirstDayOfMonth && $isQuarterlyMonth) {\n $this->processReports(AutomatedReportsService::FREQUENCY_QUARTERLY);\n }\n\n $this->logger->info(self::LOG_PREFIX . ' Completed');\n\n return 0;\n }\n\n /**\n * Process reports for a specific frequency.\n *\n * @param string $frequency\n *\n * @return void\n */\n private function processReports(string $frequency): void\n {\n $this->logger->info(self::LOG_PREFIX . \" Processing $frequency reports\");\n\n // Get all enabled, not deleted reports with active teams for the specified frequency\n $reports = $this->reportRepository->getActiveReportsByFrequency($frequency);\n // $reports = collect([AutomatedReport::find(68)]);\n\n $this->logger->info(self::LOG_PREFIX . \" Found {$reports->count()} $frequency reports to process\");\n\n /** @var AutomatedReport $report */\n foreach ($reports as $report) {\n $this->logger->info(self::LOG_PREFIX . ' Dispatching Generate Report job for report', [\n 'reportUuid' => $report->getUuid(),\n 'teamId' => $report->getTeamId(),\n 'frequency' => $report->getFrequency(),\n 'type' => $report->getType(),\n ]);\n\n $job = $report->isAskJiminnyReport()\n ? new RequestGenerateAskJiminnyReportJob($report->getUuid())\n : new RequestGenerateReportJob($report->getUuid());\n\n // $this->dispatcher->dispatch($job);\n $this->dispatcher->dispatchSync($job);\n }\n }\n}","depth":4,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Console\\Commands\\Reports;\n\nuse Carbon\\Carbon;\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Contracts\\Bus\\Dispatcher as BusDispatcher;\nuse Jiminny\\Jobs\\AutomatedReports\\RequestGenerateAskJiminnyReportJob;\nuse Jiminny\\Jobs\\AutomatedReports\\RequestGenerateReportJob;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Repositories\\AutomatedReportsRepository;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Psr\\Log\\LoggerInterface;\n\nclass AutomatedReportsCommand extends Command\n{\n /**\n * Log prefix for all log messages\n */\n private const string LOG_PREFIX = '[automated-reports]';\n\n /**\n * The name and signature of the console command.\n *\n * @var string\n */\n protected $signature = 'automated-reports';\n\n /**\n * The console command description.\n *\n * @var string\n */\n protected $description = 'Process automated reports based on their frequency (weekly, monthly, quarterly)';\n\n\n public function __construct(\n private readonly LoggerInterface $logger,\n private readonly BusDispatcher $dispatcher,\n private readonly AutomatedReportsRepository $reportRepository\n ) {\n parent::__construct();\n }\n\n /**\n * Execute the console command.\n *\n * @return int\n */\n public function handle(): int\n {\n $this->logger->info(self::LOG_PREFIX . ' Started');\n\n $now = Carbon::now();\n $isMonday = $now->isMonday();\n $isFirstDayOfMonth = $now->day === 1;\n $currentMonth = $now->month;\n\n // Check if the current month is a quarterly month (January, April, July, October)\n $isQuarterlyMonth = in_array($currentMonth, [1, 4, 7, 10], true);\n\n $this->logger->info(self::LOG_PREFIX . ' Checking conditions', [\n 'isMonday' => $isMonday,\n 'isFirstDayOfMonth' => $isFirstDayOfMonth,\n 'currentMonth' => $currentMonth,\n 'isQuarterlyMonth' => $isQuarterlyMonth,\n ]);\n\n // Process daily reports\n $this->processReports(AutomatedReportsService::FREQUENCY_DAILY);\n\n // Process weekly reports on Mondays\n if ($isMonday) {\n $this->processReports(AutomatedReportsService::FREQUENCY_WEEKLY);\n }\n\n // Process monthly reports on the first day of the month\n if ($isFirstDayOfMonth) {\n $this->processReports(AutomatedReportsService::FREQUENCY_MONTHLY);\n }\n\n // Process quarterly reports on the first day of January, April, July, and October\n if ($isFirstDayOfMonth && $isQuarterlyMonth) {\n $this->processReports(AutomatedReportsService::FREQUENCY_QUARTERLY);\n }\n\n $this->logger->info(self::LOG_PREFIX . ' Completed');\n\n return 0;\n }\n\n /**\n * Process reports for a specific frequency.\n *\n * @param string $frequency\n *\n * @return void\n */\n private function processReports(string $frequency): void\n {\n $this->logger->info(self::LOG_PREFIX . \" Processing $frequency reports\");\n\n // Get all enabled, not deleted reports with active teams for the specified frequency\n $reports = $this->reportRepository->getActiveReportsByFrequency($frequency);\n // $reports = collect([AutomatedReport::find(68)]);\n\n $this->logger->info(self::LOG_PREFIX . \" Found {$reports->count()} $frequency reports to process\");\n\n /** @var AutomatedReport $report */\n foreach ($reports as $report) {\n $this->logger->info(self::LOG_PREFIX . ' Dispatching Generate Report job for report', [\n 'reportUuid' => $report->getUuid(),\n 'teamId' => $report->getTeamId(),\n 'frequency' => $report->getFrequency(),\n 'type' => $report->getType(),\n ]);\n\n $job = $report->isAskJiminnyReport()\n ? new RequestGenerateAskJiminnyReportJob($report->getUuid())\n : new RequestGenerateReportJob($report->getUuid());\n\n // $this->dispatcher->dispatch($job);\n $this->dispatcher->dispatchSync($job);\n }\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.049609374,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"1","depth":4,"bounds":{"left":0.9339844,"top":0.0875,"width":0.00859375,"height":0.013194445},"role_description":"text"},{"role":"AXStaticText","text":"14","depth":4,"bounds":{"left":0.94492185,"top":0.0875,"width":0.011328125,"height":0.013194445},"role_description":"text"},{"role":"AXStaticText","text":"4","depth":4,"bounds":{"left":0.9585937,"top":0.0875,"width":0.009375,"height":0.013194445},"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.9699219,"top":0.08611111,"width":0.00859375,"height":0.015972223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.9785156,"top":0.08611111,"width":0.008203125,"height":0.015972223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Tests\\Unit\\Jobs\\AutomatedReports;\n\nuse Carbon\\Carbon;\nuse Jiminny\\Component\\ProphetAi\\Exceptions\\ProphetException;\nuse Jiminny\\Component\\ProphetAi\\ProphetClient;\nuse Jiminny\\Jobs\\AutomatedReports\\RequestGenerateAskJiminnyReportJob;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Models\\AutomatedReportResult;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AskJiminnyReportActivityService;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse PHPUnit\\Framework\\MockObject\\MockObject;\nuse PHPUnit\\Framework\\TestCase;\nuse Psr\\Log\\LoggerInterface;\n\nclass RequestGenerateAskJiminnyReportJobTest extends TestCase\n{\n private AutomatedReportsService&MockObject $reportService;\n private AskJiminnyReportActivityService&MockObject $activityService;\n private ProphetClient&MockObject $prophetClient;\n private LoggerInterface&MockObject $logger;\n\n protected function setUp(): void\n {\n $this->reportService = $this->createMock(AutomatedReportsService::class);\n $this->activityService = $this->createMock(AskJiminnyReportActivityService::class);\n $this->prophetClient = $this->createMock(ProphetClient::class);\n $this->logger = $this->createMock(LoggerInterface::class);\n }\n\n private function makeJob(string $uuid = 'report-uuid'): RequestGenerateAskJiminnyReportJob\n {\n return new RequestGenerateAskJiminnyReportJob($uuid);\n }\n\n private function makeActiveReport(\n string $type = AutomatedReportsService::TYPE_ASK_JIMINNY,\n bool $status = true,\n string $teamStatus = Team::STATUS_ACTIVE,\n ): AutomatedReport&MockObject { // @phpstan-ignore-line\n $team = $this->createMock(Team::class);\n $team->method('getStatus')->willReturn($teamStatus);\n\n $report = $this->createMock(AutomatedReport::class);\n $report->method('getType')->willReturn($type);\n $report->method('getStatus')->willReturn($status);\n $report->method('getTeam')->willReturn($team);\n\n return $report;\n }\n\n public function testUniqueIdReturnsReportUuid(): void\n {\n $job = $this->makeJob('my-unique-uuid');\n\n $this->assertEquals('my-unique-uuid', $job->uniqueId());\n }\n\n public function testHandleSkipsWhenReportTypeIsNotAskJiminny(): void\n {\n $report = $this->makeActiveReport(type: 'exec_summary');\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->logger->expects($this->once())\n ->method('info')\n ->with($this->stringContains('Started'));\n\n $this->logger->expects($this->once())\n ->method('warning')\n ->with($this->stringContains('not an ask_jiminny report'));\n\n $this->reportService->expects($this->never())->method('createReportResult');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleSkipsWhenReportIsInactive(): void\n {\n $report = $this->makeActiveReport(status: false);\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->logger->expects($this->exactly(2))\n ->method('info');\n\n $this->reportService->expects($this->never())->method('createReportResult');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleSkipsWhenTeamIsInactive(): void\n {\n $report = $this->makeActiveReport(teamStatus: Team::STATUS_DEACTIVATED);\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->logger->expects($this->exactly(2))\n ->method('info');\n\n $this->reportService->expects($this->never())->method('createReportResult');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleSkipsWhenCreatorIsNull(): void\n {\n $report = $this->makeActiveReport();\n $report->method('getCreator')->willReturn(null);\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->logger->expects($this->once())\n ->method('warning')\n ->with($this->stringContains('report creator not found'));\n\n $this->reportService->expects($this->never())->method('createReportResult');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleSkipsWhenSavedSearchIsNull(): void\n {\n $creator = $this->createMock(User::class);\n\n $report = $this->makeActiveReport();\n $report->method('getCreator')->willReturn($creator);\n $report->method('getSavedSearch')->willReturn(null);\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->logger->expects($this->once())\n ->method('warning')\n ->with($this->stringContains('saved search not found'));\n\n $this->reportService->expects($this->never())->method('createReportResult');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleSkipsWhenPromptIsNull(): void\n {\n $creator = $this->createMock(User::class);\n $savedSearch = $this->createMock(\\Jiminny\\Models\\Activity\\Search::class);\n\n $report = $this->makeActiveReport();\n $report->method('getCreator')->willReturn($creator);\n $report->method('getSavedSearch')->willReturn($savedSearch);\n $report->method('getAskAnythingPrompt')->willReturn(null);\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->logger->expects($this->once())\n ->method('warning')\n ->with($this->stringContains('ask anything prompt not found'));\n\n $this->reportService->expects($this->never())->method('createReportResult');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleFailsReportWhenNotEnoughActivities(): void\n {\n $creator = $this->createMock(User::class);\n $savedSearch = $this->createMock(\\Jiminny\\Models\\Activity\\Search::class);\n $prompt = $this->createMock(\\Jiminny\\Models\\AskAnything\\AskAnythingPrompt::class);\n\n $report = $this->makeActiveReport();\n $report->method('getCreator')->willReturn($creator);\n $report->method('getSavedSearch')->willReturn($savedSearch);\n $report->method('getAskAnythingPrompt')->willReturn($prompt);\n\n $reportResult = $this->createMock(AutomatedReportResult::class);\n $reportResult->expects($this->once())\n ->method('update')\n ->with($this->callback(fn ($data) => $data['status'] === AutomatedReportResult::STATUS_FAILED\n && $data['reason'] === AutomatedReportResult::REASON_NOT_ENOUGH_ACTIVITIES));\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->reportService->expects($this->once())\n ->method('createReportResult')\n ->willReturn($reportResult);\n\n $this->activityService->expects($this->once())\n ->method('getActivityIdsForSavedSearch')\n ->willReturn([]);\n\n $this->logger->expects($this->exactly(3))\n ->method('info');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleSuccessfullyRequestsReport(): void\n {\n Carbon::setTestNow(Carbon::parse('2026-04-07 10:00:00'));\n\n $creator = $this->createMock(User::class);\n $savedSearch = $this->createMock(\\Jiminny\\Models\\Activity\\Search::class);\n $prompt = $this->createMock(\\Jiminny\\Models\\AskAnything\\AskAnythingPrompt::class);\n\n $report = $this->makeActiveReport();\n $report->method('getCreator')->willReturn($creator);\n $report->method('getSavedSearch')->willReturn($savedSearch);\n $report->method('getAskAnythingPrompt')->willReturn($prompt);\n $report->method('getUuid')->willReturn('report-uuid');\n\n $reportResult = $this->createMock(AutomatedReportResult::class);\n $reportResult->method('getUuid')->willReturn('result-uuid');\n $reportResult->expects($this->once())\n ->method('update')\n ->with($this->callback(fn ($data) => $data['status'] === AutomatedReportResult::STATUS_REQUESTED\n && isset($data['name'], $data['payload'], $data['requested_at'])));\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->reportService->expects($this->once())\n ->method('createReportResult')\n ->willReturn($reportResult);\n\n $this->reportService->expects($this->once())\n ->method('getAskJiminnyGenerateReportPayload')\n ->willReturn(['key' => 'value']);\n\n $this->reportService->expects($this->once())\n ->method('getReportFileName')\n ->willReturn('My Report - 7 Apr 2026');\n\n $this->activityService->expects($this->once())\n ->method('getActivityIdsForSavedSearch')\n ->willReturn(['act-1', 'act-2']);\n\n $this->prophetClient->expects($this->once())\n ->method('sendRequest')\n ->willReturn(new \\Jiminny\\Component\\ProphetAi\\Dtos\\ProphetResponseDto([]));\n\n $this->logger->expects($this->exactly(4))\n ->method('info');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n\n Carbon::setTestNow();\n }\n\n public function testHandleCatchesGenericExceptionAndLogsError(): void\n {\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willThrowException(new \\RuntimeException('DB error'));\n\n $this->logger->expects($this->once())\n ->method('error')\n ->with($this->stringContains('Error'));\n\n $job = $this->makeJob();\n\n $reflection = new \\ReflectionClass($job);\n $triesProp = $reflection->getProperty('tries');\n $triesProp->setAccessible(true);\n\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleCatchesProphetExceptionAndSetsCorrectReason(): void\n {\n $creator = $this->createMock(User::class);\n $savedSearch = $this->createMock(\\Jiminny\\Models\\Activity\\Search::class);\n $prompt = $this->createMock(\\Jiminny\\Models\\AskAnything\\AskAnythingPrompt::class);\n\n $report = $this->makeActiveReport();\n $report->method('getCreator')->willReturn($creator);\n $report->method('getSavedSearch')->willReturn($savedSearch);\n $report->method('getAskAnythingPrompt')->willReturn($prompt);\n\n $reportResult = $this->createMock(AutomatedReportResult::class);\n $reportResult->method('getUuid')->willReturn('result-uuid');\n $reportResult->expects($this->once())\n ->method('update')\n ->with($this->callback(fn ($data) => $data['reason'] === AutomatedReportResult::REASON_PROPHET_API_ERROR));\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->reportService->expects($this->once())\n ->method('createReportResult')\n ->willReturn($reportResult);\n\n $this->activityService->expects($this->once())\n ->method('getActivityIdsForSavedSearch')\n ->willThrowException(new ProphetException('Prophet failed'));\n\n $this->logger->expects($this->once())\n ->method('error');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleCreatesReportResultBeforeActivityFetch(): void\n {\n $creator = $this->createMock(User::class);\n $savedSearch = $this->createMock(\\Jiminny\\Models\\Activity\\Search::class);\n $prompt = $this->createMock(\\Jiminny\\Models\\AskAnything\\AskAnythingPrompt::class);\n\n $report = $this->makeActiveReport();\n $report->method('getCreator')->willReturn($creator);\n $report->method('getSavedSearch')->willReturn($savedSearch);\n $report->method('getAskAnythingPrompt')->willReturn($prompt);\n\n $reportResult = $this->createMock(AutomatedReportResult::class);\n $reportResult->method('getUuid')->willReturn('result-uuid');\n\n $callOrder = [];\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->reportService->expects($this->once())\n ->method('createReportResult')\n ->willReturnCallback(function () use ($reportResult, &$callOrder) {\n $callOrder[] = 'createReportResult';\n\n return $reportResult;\n });\n\n $this->activityService->expects($this->once())\n ->method('getActivityIdsForSavedSearch')\n ->willReturnCallback(function () use (&$callOrder) {\n $callOrder[] = 'getActivityIds';\n\n return [];\n });\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n\n $this->assertEquals(['createReportResult', 'getActivityIds'], $callOrder);\n }\n\n public function testHandlePassesCorrectDataToCreateReportResult(): void\n {\n $creator = $this->createMock(User::class);\n $savedSearch = $this->createMock(\\Jiminny\\Models\\Activity\\Search::class);\n $prompt = $this->createMock(\\Jiminny\\Models\\AskAnything\\AskAnythingPrompt::class);\n\n $report = $this->makeActiveReport();\n $report->method('getCreator')->willReturn($creator);\n $report->method('getSavedSearch')->willReturn($savedSearch);\n $report->method('getAskAnythingPrompt')->willReturn($prompt);\n\n $reportResult = $this->createMock(AutomatedReportResult::class);\n $reportResult->method('getUuid')->willReturn('result-uuid');\n $reportResult->method('update')->willReturn(true);\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->reportService->expects($this->once())\n ->method('createReportResult')\n ->with(\n automatedReport: $report,\n data: $this->callback(fn ($data) => $data['status'] === AutomatedReportResult::STATUS_DEFAULT\n && $data['media_type'] === AutomatedReportsService::MEDIA_TYPE_PDF)\n )\n ->willReturn($reportResult);\n\n $this->activityService->expects($this->once())\n ->method('getActivityIdsForSavedSearch')\n ->willReturn([]);\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n}","depth":4,"bounds":{"left":0.55507815,"top":0.08472222,"width":0.43125,"height":0.9152778},"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Tests\\Unit\\Jobs\\AutomatedReports;\n\nuse Carbon\\Carbon;\nuse Jiminny\\Component\\ProphetAi\\Exceptions\\ProphetException;\nuse Jiminny\\Component\\ProphetAi\\ProphetClient;\nuse Jiminny\\Jobs\\AutomatedReports\\RequestGenerateAskJiminnyReportJob;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Models\\AutomatedReportResult;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AskJiminnyReportActivityService;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse PHPUnit\\Framework\\MockObject\\MockObject;\nuse PHPUnit\\Framework\\TestCase;\nuse Psr\\Log\\LoggerInterface;\n\nclass RequestGenerateAskJiminnyReportJobTest extends TestCase\n{\n private AutomatedReportsService&MockObject $reportService;\n private AskJiminnyReportActivityService&MockObject $activityService;\n private ProphetClient&MockObject $prophetClient;\n private LoggerInterface&MockObject $logger;\n\n protected function setUp(): void\n {\n $this->reportService = $this->createMock(AutomatedReportsService::class);\n $this->activityService = $this->createMock(AskJiminnyReportActivityService::class);\n $this->prophetClient = $this->createMock(ProphetClient::class);\n $this->logger = $this->createMock(LoggerInterface::class);\n }\n\n private function makeJob(string $uuid = 'report-uuid'): RequestGenerateAskJiminnyReportJob\n {\n return new RequestGenerateAskJiminnyReportJob($uuid);\n }\n\n private function makeActiveReport(\n string $type = AutomatedReportsService::TYPE_ASK_JIMINNY,\n bool $status = true,\n string $teamStatus = Team::STATUS_ACTIVE,\n ): AutomatedReport&MockObject { // @phpstan-ignore-line\n $team = $this->createMock(Team::class);\n $team->method('getStatus')->willReturn($teamStatus);\n\n $report = $this->createMock(AutomatedReport::class);\n $report->method('getType')->willReturn($type);\n $report->method('getStatus')->willReturn($status);\n $report->method('getTeam')->willReturn($team);\n\n return $report;\n }\n\n public function testUniqueIdReturnsReportUuid(): void\n {\n $job = $this->makeJob('my-unique-uuid');\n\n $this->assertEquals('my-unique-uuid', $job->uniqueId());\n }\n\n public function testHandleSkipsWhenReportTypeIsNotAskJiminny(): void\n {\n $report = $this->makeActiveReport(type: 'exec_summary');\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->logger->expects($this->once())\n ->method('info')\n ->with($this->stringContains('Started'));\n\n $this->logger->expects($this->once())\n ->method('warning')\n ->with($this->stringContains('not an ask_jiminny report'));\n\n $this->reportService->expects($this->never())->method('createReportResult');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleSkipsWhenReportIsInactive(): void\n {\n $report = $this->makeActiveReport(status: false);\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->logger->expects($this->exactly(2))\n ->method('info');\n\n $this->reportService->expects($this->never())->method('createReportResult');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleSkipsWhenTeamIsInactive(): void\n {\n $report = $this->makeActiveReport(teamStatus: Team::STATUS_DEACTIVATED);\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->logger->expects($this->exactly(2))\n ->method('info');\n\n $this->reportService->expects($this->never())->method('createReportResult');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleSkipsWhenCreatorIsNull(): void\n {\n $report = $this->makeActiveReport();\n $report->method('getCreator')->willReturn(null);\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->logger->expects($this->once())\n ->method('warning')\n ->with($this->stringContains('report creator not found'));\n\n $this->reportService->expects($this->never())->method('createReportResult');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleSkipsWhenSavedSearchIsNull(): void\n {\n $creator = $this->createMock(User::class);\n\n $report = $this->makeActiveReport();\n $report->method('getCreator')->willReturn($creator);\n $report->method('getSavedSearch')->willReturn(null);\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->logger->expects($this->once())\n ->method('warning')\n ->with($this->stringContains('saved search not found'));\n\n $this->reportService->expects($this->never())->method('createReportResult');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleSkipsWhenPromptIsNull(): void\n {\n $creator = $this->createMock(User::class);\n $savedSearch = $this->createMock(\\Jiminny\\Models\\Activity\\Search::class);\n\n $report = $this->makeActiveReport();\n $report->method('getCreator')->willReturn($creator);\n $report->method('getSavedSearch')->willReturn($savedSearch);\n $report->method('getAskAnythingPrompt')->willReturn(null);\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->logger->expects($this->once())\n ->method('warning')\n ->with($this->stringContains('ask anything prompt not found'));\n\n $this->reportService->expects($this->never())->method('createReportResult');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleFailsReportWhenNotEnoughActivities(): void\n {\n $creator = $this->createMock(User::class);\n $savedSearch = $this->createMock(\\Jiminny\\Models\\Activity\\Search::class);\n $prompt = $this->createMock(\\Jiminny\\Models\\AskAnything\\AskAnythingPrompt::class);\n\n $report = $this->makeActiveReport();\n $report->method('getCreator')->willReturn($creator);\n $report->method('getSavedSearch')->willReturn($savedSearch);\n $report->method('getAskAnythingPrompt')->willReturn($prompt);\n\n $reportResult = $this->createMock(AutomatedReportResult::class);\n $reportResult->expects($this->once())\n ->method('update')\n ->with($this->callback(fn ($data) => $data['status'] === AutomatedReportResult::STATUS_FAILED\n && $data['reason'] === AutomatedReportResult::REASON_NOT_ENOUGH_ACTIVITIES));\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->reportService->expects($this->once())\n ->method('createReportResult')\n ->willReturn($reportResult);\n\n $this->activityService->expects($this->once())\n ->method('getActivityIdsForSavedSearch')\n ->willReturn([]);\n\n $this->logger->expects($this->exactly(3))\n ->method('info');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleSuccessfullyRequestsReport(): void\n {\n Carbon::setTestNow(Carbon::parse('2026-04-07 10:00:00'));\n\n $creator = $this->createMock(User::class);\n $savedSearch = $this->createMock(\\Jiminny\\Models\\Activity\\Search::class);\n $prompt = $this->createMock(\\Jiminny\\Models\\AskAnything\\AskAnythingPrompt::class);\n\n $report = $this->makeActiveReport();\n $report->method('getCreator')->willReturn($creator);\n $report->method('getSavedSearch')->willReturn($savedSearch);\n $report->method('getAskAnythingPrompt')->willReturn($prompt);\n $report->method('getUuid')->willReturn('report-uuid');\n\n $reportResult = $this->createMock(AutomatedReportResult::class);\n $reportResult->method('getUuid')->willReturn('result-uuid');\n $reportResult->expects($this->once())\n ->method('update')\n ->with($this->callback(fn ($data) => $data['status'] === AutomatedReportResult::STATUS_REQUESTED\n && isset($data['name'], $data['payload'], $data['requested_at'])));\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->reportService->expects($this->once())\n ->method('createReportResult')\n ->willReturn($reportResult);\n\n $this->reportService->expects($this->once())\n ->method('getAskJiminnyGenerateReportPayload')\n ->willReturn(['key' => 'value']);\n\n $this->reportService->expects($this->once())\n ->method('getReportFileName')\n ->willReturn('My Report - 7 Apr 2026');\n\n $this->activityService->expects($this->once())\n ->method('getActivityIdsForSavedSearch')\n ->willReturn(['act-1', 'act-2']);\n\n $this->prophetClient->expects($this->once())\n ->method('sendRequest')\n ->willReturn(new \\Jiminny\\Component\\ProphetAi\\Dtos\\ProphetResponseDto([]));\n\n $this->logger->expects($this->exactly(4))\n ->method('info');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n\n Carbon::setTestNow();\n }\n\n public function testHandleCatchesGenericExceptionAndLogsError(): void\n {\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willThrowException(new \\RuntimeException('DB error'));\n\n $this->logger->expects($this->once())\n ->method('error')\n ->with($this->stringContains('Error'));\n\n $job = $this->makeJob();\n\n $reflection = new \\ReflectionClass($job);\n $triesProp = $reflection->getProperty('tries');\n $triesProp->setAccessible(true);\n\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleCatchesProphetExceptionAndSetsCorrectReason(): void\n {\n $creator = $this->createMock(User::class);\n $savedSearch = $this->createMock(\\Jiminny\\Models\\Activity\\Search::class);\n $prompt = $this->createMock(\\Jiminny\\Models\\AskAnything\\AskAnythingPrompt::class);\n\n $report = $this->makeActiveReport();\n $report->method('getCreator')->willReturn($creator);\n $report->method('getSavedSearch')->willReturn($savedSearch);\n $report->method('getAskAnythingPrompt')->willReturn($prompt);\n\n $reportResult = $this->createMock(AutomatedReportResult::class);\n $reportResult->method('getUuid')->willReturn('result-uuid');\n $reportResult->expects($this->once())\n ->method('update')\n ->with($this->callback(fn ($data) => $data['reason'] === AutomatedReportResult::REASON_PROPHET_API_ERROR));\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->reportService->expects($this->once())\n ->method('createReportResult')\n ->willReturn($reportResult);\n\n $this->activityService->expects($this->once())\n ->method('getActivityIdsForSavedSearch')\n ->willThrowException(new ProphetException('Prophet failed'));\n\n $this->logger->expects($this->once())\n ->method('error');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleCreatesReportResultBeforeActivityFetch(): void\n {\n $creator = $this->createMock(User::class);\n $savedSearch = $this->createMock(\\Jiminny\\Models\\Activity\\Search::class);\n $prompt = $this->createMock(\\Jiminny\\Models\\AskAnything\\AskAnythingPrompt::class);\n\n $report = $this->makeActiveReport();\n $report->method('getCreator')->willReturn($creator);\n $report->method('getSavedSearch')->willReturn($savedSearch);\n $report->method('getAskAnythingPrompt')->willReturn($prompt);\n\n $reportResult = $this->createMock(AutomatedReportResult::class);\n $reportResult->method('getUuid')->willReturn('result-uuid');\n\n $callOrder = [];\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->reportService->expects($this->once())\n ->method('createReportResult')\n ->willReturnCallback(function () use ($reportResult, &$callOrder) {\n $callOrder[] = 'createReportResult';\n\n return $reportResult;\n });\n\n $this->activityService->expects($this->once())\n ->method('getActivityIdsForSavedSearch')\n ->willReturnCallback(function () use (&$callOrder) {\n $callOrder[] = 'getActivityIds';\n\n return [];\n });\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n\n $this->assertEquals(['createReportResult', 'getActivityIds'], $callOrder);\n }\n\n public function testHandlePassesCorrectDataToCreateReportResult(): void\n {\n $creator = $this->createMock(User::class);\n $savedSearch = $this->createMock(\\Jiminny\\Models\\Activity\\Search::class);\n $prompt = $this->createMock(\\Jiminny\\Models\\AskAnything\\AskAnythingPrompt::class);\n\n $report = $this->makeActiveReport();\n $report->method('getCreator')->willReturn($creator);\n $report->method('getSavedSearch')->willReturn($savedSearch);\n $report->method('getAskAnythingPrompt')->willReturn($prompt);\n\n $reportResult = $this->createMock(AutomatedReportResult::class);\n $reportResult->method('getUuid')->willReturn('result-uuid');\n $reportResult->method('update')->willReturn(true);\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->reportService->expects($this->once())\n ->method('createReportResult')\n ->with(\n automatedReport: $report,\n data: $this->callback(fn ($data) => $data['status'] === AutomatedReportResult::STATUS_DEFAULT\n && $data['media_type'] === AutomatedReportsService::MEDIA_TYPE_PDF)\n )\n ->willReturn($reportResult);\n\n $this->activityService->expects($this->once())\n ->method('getActivityIdsForSavedSearch')\n ->willReturn([]);\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"bounds":{"left":0.0140625,"top":0.041666668,"width":0.028515626,"height":0.021527778},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
-8992757920745852993
|
8722295178528246161
|
idle
|
accessibility
|
NULL
|
Project: faVsco.js, menu
#11894 on JY-18909-automa Project: faVsco.js, menu
#11894 on JY-18909-automated-reports-ask-jiminny, menu
Start Listening for PHP Debug Connections
RequestGenerateAskJiminnyReportJobTest
Run 'RequestGenerateAskJiminnyReportJobTest'
Debug 'RequestGenerateAskJiminnyReportJobTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
Analyzing…
<?php
declare(strict_types=1);
namespace Jiminny\Console\Commands\Reports;
use Carbon\Carbon;
use Illuminate\Console\Command;
use Illuminate\Contracts\Bus\Dispatcher as BusDispatcher;
use Jiminny\Jobs\AutomatedReports\RequestGenerateAskJiminnyReportJob;
use Jiminny\Jobs\AutomatedReports\RequestGenerateReportJob;
use Jiminny\Models\AutomatedReport;
use Jiminny\Repositories\AutomatedReportsRepository;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Psr\Log\LoggerInterface;
class AutomatedReportsCommand extends Command
{
/**
* Log prefix for all log messages
*/
private const string LOG_PREFIX = '[automated-reports]';
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'automated-reports';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Process automated reports based on their frequency (weekly, monthly, quarterly)';
public function __construct(
private readonly LoggerInterface $logger,
private readonly BusDispatcher $dispatcher,
private readonly AutomatedReportsRepository $reportRepository
) {
parent::__construct();
}
/**
* Execute the console command.
*
* @return int
*/
public function handle(): int
{
$this->logger->info(self::LOG_PREFIX . ' Started');
$now = Carbon::now();
$isMonday = $now->isMonday();
$isFirstDayOfMonth = $now->day === 1;
$currentMonth = $now->month;
// Check if the current month is a quarterly month (January, April, July, October)
$isQuarterlyMonth = in_array($currentMonth, [1, 4, 7, 10], true);
$this->logger->info(self::LOG_PREFIX . ' Checking conditions', [
'isMonday' => $isMonday,
'isFirstDayOfMonth' => $isFirstDayOfMonth,
'currentMonth' => $currentMonth,
'isQuarterlyMonth' => $isQuarterlyMonth,
]);
// Process daily reports
$this->processReports(AutomatedReportsService::FREQUENCY_DAILY);
// Process weekly reports on Mondays
if ($isMonday) {
$this->processReports(AutomatedReportsService::FREQUENCY_WEEKLY);
}
// Process monthly reports on the first day of the month
if ($isFirstDayOfMonth) {
$this->processReports(AutomatedReportsService::FREQUENCY_MONTHLY);
}
// Process quarterly reports on the first day of January, April, July, and October
if ($isFirstDayOfMonth && $isQuarterlyMonth) {
$this->processReports(AutomatedReportsService::FREQUENCY_QUARTERLY);
}
$this->logger->info(self::LOG_PREFIX . ' Completed');
return 0;
}
/**
* Process reports for a specific frequency.
*
* @param string $frequency
*
* @return void
*/
private function processReports(string $frequency): void
{
$this->logger->info(self::LOG_PREFIX . " Processing $frequency reports");
// Get all enabled, not deleted reports with active teams for the specified frequency
$reports = $this->reportRepository->getActiveReportsByFrequency($frequency);
// $reports = collect([AutomatedReport::find(68)]);
$this->logger->info(self::LOG_PREFIX . " Found {$reports->count()} $frequency reports to process");
/** @var AutomatedReport $report */
foreach ($reports as $report) {
$this->logger->info(self::LOG_PREFIX . ' Dispatching Generate Report job for report', [
'reportUuid' => $report->getUuid(),
'teamId' => $report->getTeamId(),
'frequency' => $report->getFrequency(),
'type' => $report->getType(),
]);
$job = $report->isAskJiminnyReport()
? new RequestGenerateAskJiminnyReportJob($report->getUuid())
: new RequestGenerateReportJob($report->getUuid());
// $this->dispatcher->dispatch($job);
$this->dispatcher->dispatchSync($job);
}
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
1
14
4
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Tests\Unit\Jobs\AutomatedReports;
use Carbon\Carbon;
use Jiminny\Component\ProphetAi\Exceptions\ProphetException;
use Jiminny\Component\ProphetAi\ProphetClient;
use Jiminny\Jobs\AutomatedReports\RequestGenerateAskJiminnyReportJob;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\AutomatedReportResult;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityService;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
use Psr\Log\LoggerInterface;
class RequestGenerateAskJiminnyReportJobTest extends TestCase
{
private AutomatedReportsService&MockObject $reportService;
private AskJiminnyReportActivityService&MockObject $activityService;
private ProphetClient&MockObject $prophetClient;
private LoggerInterface&MockObject $logger;
protected function setUp(): void
{
$this->reportService = $this->createMock(AutomatedReportsService::class);
$this->activityService = $this->createMock(AskJiminnyReportActivityService::class);
$this->prophetClient = $this->createMock(ProphetClient::class);
$this->logger = $this->createMock(LoggerInterface::class);
}
private function makeJob(string $uuid = 'report-uuid'): RequestGenerateAskJiminnyReportJob
{
return new RequestGenerateAskJiminnyReportJob($uuid);
}
private function makeActiveReport(
string $type = AutomatedReportsService::TYPE_ASK_JIMINNY,
bool $status = true,
string $teamStatus = Team::STATUS_ACTIVE,
): AutomatedReport&MockObject { // @phpstan-ignore-line
$team = $this->createMock(Team::class);
$team->method('getStatus')->willReturn($teamStatus);
$report = $this->createMock(AutomatedReport::class);
$report->method('getType')->willReturn($type);
$report->method('getStatus')->willReturn($status);
$report->method('getTeam')->willReturn($team);
return $report;
}
public function testUniqueIdReturnsReportUuid(): void
{
$job = $this->makeJob('my-unique-uuid');
$this->assertEquals('my-unique-uuid', $job->uniqueId());
}
public function testHandleSkipsWhenReportTypeIsNotAskJiminny(): void
{
$report = $this->makeActiveReport(type: 'exec_summary');
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->logger->expects($this->once())
->method('info')
->with($this->stringContains('Started'));
$this->logger->expects($this->once())
->method('warning')
->with($this->stringContains('not an ask_jiminny report'));
$this->reportService->expects($this->never())->method('createReportResult');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleSkipsWhenReportIsInactive(): void
{
$report = $this->makeActiveReport(status: false);
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->logger->expects($this->exactly(2))
->method('info');
$this->reportService->expects($this->never())->method('createReportResult');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleSkipsWhenTeamIsInactive(): void
{
$report = $this->makeActiveReport(teamStatus: Team::STATUS_DEACTIVATED);
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->logger->expects($this->exactly(2))
->method('info');
$this->reportService->expects($this->never())->method('createReportResult');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleSkipsWhenCreatorIsNull(): void
{
$report = $this->makeActiveReport();
$report->method('getCreator')->willReturn(null);
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->logger->expects($this->once())
->method('warning')
->with($this->stringContains('report creator not found'));
$this->reportService->expects($this->never())->method('createReportResult');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleSkipsWhenSavedSearchIsNull(): void
{
$creator = $this->createMock(User::class);
$report = $this->makeActiveReport();
$report->method('getCreator')->willReturn($creator);
$report->method('getSavedSearch')->willReturn(null);
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->logger->expects($this->once())
->method('warning')
->with($this->stringContains('saved search not found'));
$this->reportService->expects($this->never())->method('createReportResult');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleSkipsWhenPromptIsNull(): void
{
$creator = $this->createMock(User::class);
$savedSearch = $this->createMock(\Jiminny\Models\Activity\Search::class);
$report = $this->makeActiveReport();
$report->method('getCreator')->willReturn($creator);
$report->method('getSavedSearch')->willReturn($savedSearch);
$report->method('getAskAnythingPrompt')->willReturn(null);
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->logger->expects($this->once())
->method('warning')
->with($this->stringContains('ask anything prompt not found'));
$this->reportService->expects($this->never())->method('createReportResult');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleFailsReportWhenNotEnoughActivities(): void
{
$creator = $this->createMock(User::class);
$savedSearch = $this->createMock(\Jiminny\Models\Activity\Search::class);
$prompt = $this->createMock(\Jiminny\Models\AskAnything\AskAnythingPrompt::class);
$report = $this->makeActiveReport();
$report->method('getCreator')->willReturn($creator);
$report->method('getSavedSearch')->willReturn($savedSearch);
$report->method('getAskAnythingPrompt')->willReturn($prompt);
$reportResult = $this->createMock(AutomatedReportResult::class);
$reportResult->expects($this->once())
->method('update')
->with($this->callback(fn ($data) => $data['status'] === AutomatedReportResult::STATUS_FAILED
&& $data['reason'] === AutomatedReportResult::REASON_NOT_ENOUGH_ACTIVITIES));
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->reportService->expects($this->once())
->method('createReportResult')
->willReturn($reportResult);
$this->activityService->expects($this->once())
->method('getActivityIdsForSavedSearch')
->willReturn([]);
$this->logger->expects($this->exactly(3))
->method('info');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleSuccessfullyRequestsReport(): void
{
Carbon::setTestNow(Carbon::parse('2026-04-07 10:00:00'));
$creator = $this->createMock(User::class);
$savedSearch = $this->createMock(\Jiminny\Models\Activity\Search::class);
$prompt = $this->createMock(\Jiminny\Models\AskAnything\AskAnythingPrompt::class);
$report = $this->makeActiveReport();
$report->method('getCreator')->willReturn($creator);
$report->method('getSavedSearch')->willReturn($savedSearch);
$report->method('getAskAnythingPrompt')->willReturn($prompt);
$report->method('getUuid')->willReturn('report-uuid');
$reportResult = $this->createMock(AutomatedReportResult::class);
$reportResult->method('getUuid')->willReturn('result-uuid');
$reportResult->expects($this->once())
->method('update')
->with($this->callback(fn ($data) => $data['status'] === AutomatedReportResult::STATUS_REQUESTED
&& isset($data['name'], $data['payload'], $data['requested_at'])));
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->reportService->expects($this->once())
->method('createReportResult')
->willReturn($reportResult);
$this->reportService->expects($this->once())
->method('getAskJiminnyGenerateReportPayload')
->willReturn(['key' => 'value']);
$this->reportService->expects($this->once())
->method('getReportFileName')
->willReturn('My Report - 7 Apr 2026');
$this->activityService->expects($this->once())
->method('getActivityIdsForSavedSearch')
->willReturn(['act-1', 'act-2']);
$this->prophetClient->expects($this->once())
->method('sendRequest')
->willReturn(new \Jiminny\Component\ProphetAi\Dtos\ProphetResponseDto([]));
$this->logger->expects($this->exactly(4))
->method('info');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
Carbon::setTestNow();
}
public function testHandleCatchesGenericExceptionAndLogsError(): void
{
$this->reportService->expects($this->once())
->method('getReport')
->willThrowException(new \RuntimeException('DB error'));
$this->logger->expects($this->once())
->method('error')
->with($this->stringContains('Error'));
$job = $this->makeJob();
$reflection = new \ReflectionClass($job);
$triesProp = $reflection->getProperty('tries');
$triesProp->setAccessible(true);
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleCatchesProphetExceptionAndSetsCorrectReason(): void
{
$creator = $this->createMock(User::class);
$savedSearch = $this->createMock(\Jiminny\Models\Activity\Search::class);
$prompt = $this->createMock(\Jiminny\Models\AskAnything\AskAnythingPrompt::class);
$report = $this->makeActiveReport();
$report->method('getCreator')->willReturn($creator);
$report->method('getSavedSearch')->willReturn($savedSearch);
$report->method('getAskAnythingPrompt')->willReturn($prompt);
$reportResult = $this->createMock(AutomatedReportResult::class);
$reportResult->method('getUuid')->willReturn('result-uuid');
$reportResult->expects($this->once())
->method('update')
->with($this->callback(fn ($data) => $data['reason'] === AutomatedReportResult::REASON_PROPHET_API_ERROR));
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->reportService->expects($this->once())
->method('createReportResult')
->willReturn($reportResult);
$this->activityService->expects($this->once())
->method('getActivityIdsForSavedSearch')
->willThrowException(new ProphetException('Prophet failed'));
$this->logger->expects($this->once())
->method('error');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleCreatesReportResultBeforeActivityFetch(): void
{
$creator = $this->createMock(User::class);
$savedSearch = $this->createMock(\Jiminny\Models\Activity\Search::class);
$prompt = $this->createMock(\Jiminny\Models\AskAnything\AskAnythingPrompt::class);
$report = $this->makeActiveReport();
$report->method('getCreator')->willReturn($creator);
$report->method('getSavedSearch')->willReturn($savedSearch);
$report->method('getAskAnythingPrompt')->willReturn($prompt);
$reportResult = $this->createMock(AutomatedReportResult::class);
$reportResult->method('getUuid')->willReturn('result-uuid');
$callOrder = [];
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->reportService->expects($this->once())
->method('createReportResult')
->willReturnCallback(function () use ($reportResult, &$callOrder) {
$callOrder[] = 'createReportResult';
return $reportResult;
});
$this->activityService->expects($this->once())
->method('getActivityIdsForSavedSearch')
->willReturnCallback(function () use (&$callOrder) {
$callOrder[] = 'getActivityIds';
return [];
});
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
$this->assertEquals(['createReportResult', 'getActivityIds'], $callOrder);
}
public function testHandlePassesCorrectDataToCreateReportResult(): void
{
$creator = $this->createMock(User::class);
$savedSearch = $this->createMock(\Jiminny\Models\Activity\Search::class);
$prompt = $this->createMock(\Jiminny\Models\AskAnything\AskAnythingPrompt::class);
$report = $this->makeActiveReport();
$report->method('getCreator')->willReturn($creator);
$report->method('getSavedSearch')->willReturn($savedSearch);
$report->method('getAskAnythingPrompt')->willReturn($prompt);
$reportResult = $this->createMock(AutomatedReportResult::class);
$reportResult->method('getUuid')->willReturn('result-uuid');
$reportResult->method('update')->willReturn(true);
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->reportService->expects($this->once())
->method('createReportResult')
->with(
automatedReport: $report,
data: $this->callback(fn ($data) => $data['status'] === AutomatedReportResult::STATUS_DEFAULT
&& $data['media_type'] === AutomatedReportsService::MEDIA_TYPE_PDF)
)
->willReturn($reportResult);
$this->activityService->expects($this->once())
->method('getActivityIdsForSavedSearch')
->willReturn([]);
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
NULL
|
|
9498
|
185
|
1
|
2026-04-14T07:41:54.919092+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776152514919_m2.jpg...
|
PhpStorm
|
faVsco.js – AutomatedReportsCommand.php
|
True
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
#11894 on JY-18909-automa Project: faVsco.js, menu
#11894 on JY-18909-automated-reports-ask-jiminny, menu
Start Listening for PHP Debug Connections
RequestGenerateAskJiminnyReportJobTest
Run 'RequestGenerateAskJiminnyReportJobTest'
Debug 'RequestGenerateAskJiminnyReportJobTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Console\Commands\Reports;
use Carbon\Carbon;
use Illuminate\Console\Command;
use Illuminate\Contracts\Bus\Dispatcher as BusDispatcher;
use Jiminny\Jobs\AutomatedReports\RequestGenerateAskJiminnyReportJob;
use Jiminny\Jobs\AutomatedReports\RequestGenerateReportJob;
use Jiminny\Models\AutomatedReport;
use Jiminny\Repositories\AutomatedReportsRepository;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Psr\Log\LoggerInterface;
class AutomatedReportsCommand extends Command
{
/**
* Log prefix for all log messages
*/
private const string LOG_PREFIX = '[automated-reports]';
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'automated-reports';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Process automated reports based on their frequency (weekly, monthly, quarterly)';
public function __construct(
private readonly LoggerInterface $logger,
private readonly BusDispatcher $dispatcher,
private readonly AutomatedReportsRepository $reportRepository
) {
parent::__construct();
}
/**
* Execute the console command.
*
* @return int
*/
public function handle(): int
{
$this->logger->info(self::LOG_PREFIX . ' Started');
$now = Carbon::now();
$isMonday = $now->isMonday();
$isFirstDayOfMonth = $now->day === 1;
$currentMonth = $now->month;
// Check if the current month is a quarterly month (January, April, July, October)
$isQuarterlyMonth = in_array($currentMonth, [1, 4, 7, 10], true);
$this->logger->info(self::LOG_PREFIX . ' Checking conditions', [
'isMonday' => $isMonday,
'isFirstDayOfMonth' => $isFirstDayOfMonth,
'currentMonth' => $currentMonth,
'isQuarterlyMonth' => $isQuarterlyMonth,
]);
// Process daily reports
$this->processReports(AutomatedReportsService::FREQUENCY_DAILY);
// Process weekly reports on Mondays
if ($isMonday) {
$this->processReports(AutomatedReportsService::FREQUENCY_WEEKLY);
}
// Process monthly reports on the first day of the month
if ($isFirstDayOfMonth) {
$this->processReports(AutomatedReportsService::FREQUENCY_MONTHLY);
}
// Process quarterly reports on the first day of January, April, July, and October
if ($isFirstDayOfMonth && $isQuarterlyMonth) {
$this->processReports(AutomatedReportsService::FREQUENCY_QUARTERLY);
}
$this->logger->info(self::LOG_PREFIX . ' Completed');
return 0;
}
/**
* Process reports for a specific frequency.
*
* @param string $frequency
*
* @return void
*/
private function processReports(string $frequency): void
{
$this->logger->info(self::LOG_PREFIX . " Processing $frequency reports");
// Get all enabled, not deleted reports with active teams for the specified frequency
$reports = $this->reportRepository->getActiveReportsByFrequency($frequency);
// $reports = collect([AutomatedReport::find(68)]);
$this->logger->info(self::LOG_PREFIX . " Found {$reports->count()} $frequency reports to process");
/** @var AutomatedReport $report */
foreach ($reports as $report) {
$this->logger->info(self::LOG_PREFIX . ' Dispatching Generate Report job for report', [
'reportUuid' => $report->getUuid(),
'teamId' => $report->getTeamId(),
'frequency' => $report->getFrequency(),
'type' => $report->getType(),
]);
$job = $report->isAskJiminnyReport()
? new RequestGenerateAskJiminnyReportJob($report->getUuid())
: new RequestGenerateReportJob($report->getUuid());
// $this->dispatcher->dispatch($job);
$this->dispatcher->dispatchSync($job);
}
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
1
14
4
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Tests\Unit\Jobs\AutomatedReports;
use Carbon\Carbon;
use Jiminny\Component\ProphetAi\Exceptions\ProphetException;
use Jiminny\Component\ProphetAi\ProphetClient;
use Jiminny\Jobs\AutomatedReports\RequestGenerateAskJiminnyReportJob;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\AutomatedReportResult;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityService;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
use Psr\Log\LoggerInterface;
class RequestGenerateAskJiminnyReportJobTest extends TestCase
{
private AutomatedReportsService&MockObject $reportService;
private AskJiminnyReportActivityService&MockObject $activityService;
private ProphetClient&MockObject $prophetClient;
private LoggerInterface&MockObject $logger;
protected function setUp(): void
{
$this->reportService = $this->createMock(AutomatedReportsService::class);
$this->activityService = $this->createMock(AskJiminnyReportActivityService::class);
$this->prophetClient = $this->createMock(ProphetClient::class);
$this->logger = $this->createMock(LoggerInterface::class);
}
private function makeJob(string $uuid = 'report-uuid'): RequestGenerateAskJiminnyReportJob
{
return new RequestGenerateAskJiminnyReportJob($uuid);
}
private function makeActiveReport(
string $type = AutomatedReportsService::TYPE_ASK_JIMINNY,
bool $status = true,
string $teamStatus = Team::STATUS_ACTIVE,
): AutomatedReport&MockObject { // @phpstan-ignore-line
$team = $this->createMock(Team::class);
$team->method('getStatus')->willReturn($teamStatus);
$report = $this->createMock(AutomatedReport::class);
$report->method('getType')->willReturn($type);
$report->method('getStatus')->willReturn($status);
$report->method('getTeam')->willReturn($team);
return $report;
}
public function testUniqueIdReturnsReportUuid(): void
{
$job = $this->makeJob('my-unique-uuid');
$this->assertEquals('my-unique-uuid', $job->uniqueId());
}
public function testHandleSkipsWhenReportTypeIsNotAskJiminny(): void
{
$report = $this->makeActiveReport(type: 'exec_summary');
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->logger->expects($this->once())
->method('info')
->with($this->stringContains('Started'));
$this->logger->expects($this->once())
->method('warning')
->with($this->stringContains('not an ask_jiminny report'));
$this->reportService->expects($this->never())->method('createReportResult');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleSkipsWhenReportIsInactive(): void
{
$report = $this->makeActiveReport(status: false);
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->logger->expects($this->exactly(2))
->method('info');
$this->reportService->expects($this->never())->method('createReportResult');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleSkipsWhenTeamIsInactive(): void
{
$report = $this->makeActiveReport(teamStatus: Team::STATUS_DEACTIVATED);
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->logger->expects($this->exactly(2))
->method('info');
$this->reportService->expects($this->never())->method('createReportResult');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleSkipsWhenCreatorIsNull(): void
{
$report = $this->makeActiveReport();
$report->method('getCreator')->willReturn(null);
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->logger->expects($this->once())
->method('warning')
->with($this->stringContains('report creator not found'));
$this->reportService->expects($this->never())->method('createReportResult');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleSkipsWhenSavedSearchIsNull(): void
{
$creator = $this->createMock(User::class);
$report = $this->makeActiveReport();
$report->method('getCreator')->willReturn($creator);
$report->method('getSavedSearch')->willReturn(null);
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->logger->expects($this->once())
->method('warning')
->with($this->stringContains('saved search not found'));
$this->reportService->expects($this->never())->method('createReportResult');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleSkipsWhenPromptIsNull(): void
{
$creator = $this->createMock(User::class);
$savedSearch = $this->createMock(\Jiminny\Models\Activity\Search::class);
$report = $this->makeActiveReport();
$report->method('getCreator')->willReturn($creator);
$report->method('getSavedSearch')->willReturn($savedSearch);
$report->method('getAskAnythingPrompt')->willReturn(null);
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->logger->expects($this->once())
->method('warning')
->with($this->stringContains('ask anything prompt not found'));
$this->reportService->expects($this->never())->method('createReportResult');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleFailsReportWhenNotEnoughActivities(): void
{
$creator = $this->createMock(User::class);
$savedSearch = $this->createMock(\Jiminny\Models\Activity\Search::class);
$prompt = $this->createMock(\Jiminny\Models\AskAnything\AskAnythingPrompt::class);
$report = $this->makeActiveReport();
$report->method('getCreator')->willReturn($creator);
$report->method('getSavedSearch')->willReturn($savedSearch);
$report->method('getAskAnythingPrompt')->willReturn($prompt);
$reportResult = $this->createMock(AutomatedReportResult::class);
$reportResult->expects($this->once())
->method('update')
->with($this->callback(fn ($data) => $data['status'] === AutomatedReportResult::STATUS_FAILED
&& $data['reason'] === AutomatedReportResult::REASON_NOT_ENOUGH_ACTIVITIES));
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->reportService->expects($this->once())
->method('createReportResult')
->willReturn($reportResult);
$this->activityService->expects($this->once())
->method('getActivityIdsForSavedSearch')
->willReturn([]);
$this->logger->expects($this->exactly(3))
->method('info');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleSuccessfullyRequestsReport(): void
{
Carbon::setTestNow(Carbon::parse('2026-04-07 10:00:00'));
$creator = $this->createMock(User::class);
$savedSearch = $this->createMock(\Jiminny\Models\Activity\Search::class);
$prompt = $this->createMock(\Jiminny\Models\AskAnything\AskAnythingPrompt::class);
$report = $this->makeActiveReport();
$report->method('getCreator')->willReturn($creator);
$report->method('getSavedSearch')->willReturn($savedSearch);
$report->method('getAskAnythingPrompt')->willReturn($prompt);
$report->method('getUuid')->willReturn('report-uuid');
$reportResult = $this->createMock(AutomatedReportResult::class);
$reportResult->method('getUuid')->willReturn('result-uuid');
$reportResult->expects($this->once())
->method('update')
->with($this->callback(fn ($data) => $data['status'] === AutomatedReportResult::STATUS_REQUESTED
&& isset($data['name'], $data['payload'], $data['requested_at'])));
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->reportService->expects($this->once())
->method('createReportResult')
->willReturn($reportResult);
$this->reportService->expects($this->once())
->method('getAskJiminnyGenerateReportPayload')
->willReturn(['key' => 'value']);
$this->reportService->expects($this->once())
->method('getReportFileName')
->willReturn('My Report - 7 Apr 2026');
$this->activityService->expects($this->once())
->method('getActivityIdsForSavedSearch')
->willReturn(['act-1', 'act-2']);
$this->prophetClient->expects($this->once())
->method('sendRequest')
->willReturn(new \Jiminny\Component\ProphetAi\Dtos\ProphetResponseDto([]));
$this->logger->expects($this->exactly(4))
->method('info');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
Carbon::setTestNow();
}
public function testHandleCatchesGenericExceptionAndLogsError(): void
{
$this->reportService->expects($this->once())
->method('getReport')
->willThrowException(new \RuntimeException('DB error'));
$this->logger->expects($this->once())
->method('error')
->with($this->stringContains('Error'));
$job = $this->makeJob();
$reflection = new \ReflectionClass($job);
$triesProp = $reflection->getProperty('tries');
$triesProp->setAccessible(true);
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleCatchesProphetExceptionAndSetsCorrectReason(): void
{
$creator = $this->createMock(User::class);
$savedSearch = $this->createMock(\Jiminny\Models\Activity\Search::class);
$prompt = $this->createMock(\Jiminny\Models\AskAnything\AskAnythingPrompt::class);
$report = $this->makeActiveReport();
$report->method('getCreator')->willReturn($creator);
$report->method('getSavedSearch')->willReturn($savedSearch);
$report->method('getAskAnythingPrompt')->willReturn($prompt);
$reportResult = $this->createMock(AutomatedReportResult::class);
$reportResult->method('getUuid')->willReturn('result-uuid');
$reportResult->expects($this->once())
->method('update')
->with($this->callback(fn ($data) => $data['reason'] === AutomatedReportResult::REASON_PROPHET_API_ERROR));
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->reportService->expects($this->once())
->method('createReportResult')
->willReturn($reportResult);
$this->activityService->expects($this->once())
->method('getActivityIdsForSavedSearch')
->willThrowException(new ProphetException('Prophet failed'));
$this->logger->expects($this->once())
->method('error');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleCreatesReportResultBeforeActivityFetch(): void
{
$creator = $this->createMock(User::class);
$savedSearch = $this->createMock(\Jiminny\Models\Activity\Search::class);
$prompt = $this->createMock(\Jiminny\Models\AskAnything\AskAnythingPrompt::class);
$report = $this->makeActiveReport();
$report->method('getCreator')->willReturn($creator);
$report->method('getSavedSearch')->willReturn($savedSearch);
$report->method('getAskAnythingPrompt')->willReturn($prompt);
$reportResult = $this->createMock(AutomatedReportResult::class);
$reportResult->method('getUuid')->willReturn('result-uuid');
$callOrder = [];
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->reportService->expects($this->once())
->method('createReportResult')
->willReturnCallback(function () use ($reportResult, &$callOrder) {
$callOrder[] = 'createReportResult';
return $reportResult;
});
$this->activityService->expects($this->once())
->method('getActivityIdsForSavedSearch')
->willReturnCallback(function () use (&$callOrder) {
$callOrder[] = 'getActivityIds';
return [];
});
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
$this->assertEquals(['createReportResult', 'getActivityIds'], $callOrder);
}
public function testHandlePassesCorrectDataToCreateReportResult(): void
{
$creator = $this->createMock(User::class);
$savedSearch = $this->createMock(\Jiminny\Models\Activity\Search::class);
$prompt = $this->createMock(\Jiminny\Models\AskAnything\AskAnythingPrompt::class);
$report = $this->makeActiveReport();
$report->method('getCreator')->willReturn($creator);
$report->method('getSavedSearch')->willReturn($savedSearch);
$report->method('getAskAnythingPrompt')->willReturn($prompt);
$reportResult = $this->createMock(AutomatedReportResult::class);
$reportResult->method('getUuid')->willReturn('result-uuid');
$reportResult->method('update')->willReturn(true);
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->reportService->expects($this->once())
->method('createReportResult')
->with(
automatedReport: $report,
data: $this->callback(fn ($data) => $data['status'] === AutomatedReportResult::STATUS_DEFAULT
&& $data['media_type'] === AutomatedReportsService::MEDIA_TYPE_PDF)
)
->willReturn($reportResult);
$this->activityService->expects($this->once())
->method('getActivityIdsForSavedSearch')
->willReturn([]);
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.03046875,"top":0.017361112,"width":0.0453125,"height":0.022222223},"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"#11894 on JY-18909-automated-reports-ask-jiminny, menu","depth":5,"bounds":{"left":0.07578125,"top":0.017361112,"width":0.14960937,"height":0.022222223},"help_text":"Pull request #11894 exists for current branch JY-18909-automated-reports-ask-jiminny, but local branch is out of sync with remote","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.76171875,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"RequestGenerateAskJiminnyReportJobTest","depth":6,"bounds":{"left":0.7796875,"top":0.017361112,"width":0.12109375,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'RequestGenerateAskJiminnyReportJobTest'","depth":6,"bounds":{"left":0.9007813,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'RequestGenerateAskJiminnyReportJobTest'","depth":6,"bounds":{"left":0.9140625,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9273437,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96015626,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9734375,"top":0.017361112,"width":0.01328125,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9867188,"top":0.017361112,"width":0.013281226,"height":0.022222223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.049609374,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Console\\Commands\\Reports;\n\nuse Carbon\\Carbon;\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Contracts\\Bus\\Dispatcher as BusDispatcher;\nuse Jiminny\\Jobs\\AutomatedReports\\RequestGenerateAskJiminnyReportJob;\nuse Jiminny\\Jobs\\AutomatedReports\\RequestGenerateReportJob;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Repositories\\AutomatedReportsRepository;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Psr\\Log\\LoggerInterface;\n\nclass AutomatedReportsCommand extends Command\n{\n /**\n * Log prefix for all log messages\n */\n private const string LOG_PREFIX = '[automated-reports]';\n\n /**\n * The name and signature of the console command.\n *\n * @var string\n */\n protected $signature = 'automated-reports';\n\n /**\n * The console command description.\n *\n * @var string\n */\n protected $description = 'Process automated reports based on their frequency (weekly, monthly, quarterly)';\n\n\n public function __construct(\n private readonly LoggerInterface $logger,\n private readonly BusDispatcher $dispatcher,\n private readonly AutomatedReportsRepository $reportRepository\n ) {\n parent::__construct();\n }\n\n /**\n * Execute the console command.\n *\n * @return int\n */\n public function handle(): int\n {\n $this->logger->info(self::LOG_PREFIX . ' Started');\n\n $now = Carbon::now();\n $isMonday = $now->isMonday();\n $isFirstDayOfMonth = $now->day === 1;\n $currentMonth = $now->month;\n\n // Check if the current month is a quarterly month (January, April, July, October)\n $isQuarterlyMonth = in_array($currentMonth, [1, 4, 7, 10], true);\n\n $this->logger->info(self::LOG_PREFIX . ' Checking conditions', [\n 'isMonday' => $isMonday,\n 'isFirstDayOfMonth' => $isFirstDayOfMonth,\n 'currentMonth' => $currentMonth,\n 'isQuarterlyMonth' => $isQuarterlyMonth,\n ]);\n\n // Process daily reports\n $this->processReports(AutomatedReportsService::FREQUENCY_DAILY);\n\n // Process weekly reports on Mondays\n if ($isMonday) {\n $this->processReports(AutomatedReportsService::FREQUENCY_WEEKLY);\n }\n\n // Process monthly reports on the first day of the month\n if ($isFirstDayOfMonth) {\n $this->processReports(AutomatedReportsService::FREQUENCY_MONTHLY);\n }\n\n // Process quarterly reports on the first day of January, April, July, and October\n if ($isFirstDayOfMonth && $isQuarterlyMonth) {\n $this->processReports(AutomatedReportsService::FREQUENCY_QUARTERLY);\n }\n\n $this->logger->info(self::LOG_PREFIX . ' Completed');\n\n return 0;\n }\n\n /**\n * Process reports for a specific frequency.\n *\n * @param string $frequency\n *\n * @return void\n */\n private function processReports(string $frequency): void\n {\n $this->logger->info(self::LOG_PREFIX . \" Processing $frequency reports\");\n\n // Get all enabled, not deleted reports with active teams for the specified frequency\n $reports = $this->reportRepository->getActiveReportsByFrequency($frequency);\n // $reports = collect([AutomatedReport::find(68)]);\n\n $this->logger->info(self::LOG_PREFIX . \" Found {$reports->count()} $frequency reports to process\");\n\n /** @var AutomatedReport $report */\n foreach ($reports as $report) {\n $this->logger->info(self::LOG_PREFIX . ' Dispatching Generate Report job for report', [\n 'reportUuid' => $report->getUuid(),\n 'teamId' => $report->getTeamId(),\n 'frequency' => $report->getFrequency(),\n 'type' => $report->getType(),\n ]);\n\n $job = $report->isAskJiminnyReport()\n ? new RequestGenerateAskJiminnyReportJob($report->getUuid())\n : new RequestGenerateReportJob($report->getUuid());\n\n // $this->dispatcher->dispatch($job);\n $this->dispatcher->dispatchSync($job);\n }\n }\n}","depth":4,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Console\\Commands\\Reports;\n\nuse Carbon\\Carbon;\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Contracts\\Bus\\Dispatcher as BusDispatcher;\nuse Jiminny\\Jobs\\AutomatedReports\\RequestGenerateAskJiminnyReportJob;\nuse Jiminny\\Jobs\\AutomatedReports\\RequestGenerateReportJob;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Repositories\\AutomatedReportsRepository;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Psr\\Log\\LoggerInterface;\n\nclass AutomatedReportsCommand extends Command\n{\n /**\n * Log prefix for all log messages\n */\n private const string LOG_PREFIX = '[automated-reports]';\n\n /**\n * The name and signature of the console command.\n *\n * @var string\n */\n protected $signature = 'automated-reports';\n\n /**\n * The console command description.\n *\n * @var string\n */\n protected $description = 'Process automated reports based on their frequency (weekly, monthly, quarterly)';\n\n\n public function __construct(\n private readonly LoggerInterface $logger,\n private readonly BusDispatcher $dispatcher,\n private readonly AutomatedReportsRepository $reportRepository\n ) {\n parent::__construct();\n }\n\n /**\n * Execute the console command.\n *\n * @return int\n */\n public function handle(): int\n {\n $this->logger->info(self::LOG_PREFIX . ' Started');\n\n $now = Carbon::now();\n $isMonday = $now->isMonday();\n $isFirstDayOfMonth = $now->day === 1;\n $currentMonth = $now->month;\n\n // Check if the current month is a quarterly month (January, April, July, October)\n $isQuarterlyMonth = in_array($currentMonth, [1, 4, 7, 10], true);\n\n $this->logger->info(self::LOG_PREFIX . ' Checking conditions', [\n 'isMonday' => $isMonday,\n 'isFirstDayOfMonth' => $isFirstDayOfMonth,\n 'currentMonth' => $currentMonth,\n 'isQuarterlyMonth' => $isQuarterlyMonth,\n ]);\n\n // Process daily reports\n $this->processReports(AutomatedReportsService::FREQUENCY_DAILY);\n\n // Process weekly reports on Mondays\n if ($isMonday) {\n $this->processReports(AutomatedReportsService::FREQUENCY_WEEKLY);\n }\n\n // Process monthly reports on the first day of the month\n if ($isFirstDayOfMonth) {\n $this->processReports(AutomatedReportsService::FREQUENCY_MONTHLY);\n }\n\n // Process quarterly reports on the first day of January, April, July, and October\n if ($isFirstDayOfMonth && $isQuarterlyMonth) {\n $this->processReports(AutomatedReportsService::FREQUENCY_QUARTERLY);\n }\n\n $this->logger->info(self::LOG_PREFIX . ' Completed');\n\n return 0;\n }\n\n /**\n * Process reports for a specific frequency.\n *\n * @param string $frequency\n *\n * @return void\n */\n private function processReports(string $frequency): void\n {\n $this->logger->info(self::LOG_PREFIX . \" Processing $frequency reports\");\n\n // Get all enabled, not deleted reports with active teams for the specified frequency\n $reports = $this->reportRepository->getActiveReportsByFrequency($frequency);\n // $reports = collect([AutomatedReport::find(68)]);\n\n $this->logger->info(self::LOG_PREFIX . \" Found {$reports->count()} $frequency reports to process\");\n\n /** @var AutomatedReport $report */\n foreach ($reports as $report) {\n $this->logger->info(self::LOG_PREFIX . ' Dispatching Generate Report job for report', [\n 'reportUuid' => $report->getUuid(),\n 'teamId' => $report->getTeamId(),\n 'frequency' => $report->getFrequency(),\n 'type' => $report->getType(),\n ]);\n\n $job = $report->isAskJiminnyReport()\n ? new RequestGenerateAskJiminnyReportJob($report->getUuid())\n : new RequestGenerateReportJob($report->getUuid());\n\n // $this->dispatcher->dispatch($job);\n $this->dispatcher->dispatchSync($job);\n }\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.049609374,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"1","depth":4,"bounds":{"left":0.9339844,"top":0.0875,"width":0.00859375,"height":0.013194445},"role_description":"text"},{"role":"AXStaticText","text":"14","depth":4,"bounds":{"left":0.94492185,"top":0.0875,"width":0.011328125,"height":0.013194445},"role_description":"text"},{"role":"AXStaticText","text":"4","depth":4,"bounds":{"left":0.9585937,"top":0.0875,"width":0.009375,"height":0.013194445},"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.9699219,"top":0.08611111,"width":0.00859375,"height":0.015972223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"bounds":{"left":0.9785156,"top":0.08611111,"width":0.008203125,"height":0.015972223},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Tests\\Unit\\Jobs\\AutomatedReports;\n\nuse Carbon\\Carbon;\nuse Jiminny\\Component\\ProphetAi\\Exceptions\\ProphetException;\nuse Jiminny\\Component\\ProphetAi\\ProphetClient;\nuse Jiminny\\Jobs\\AutomatedReports\\RequestGenerateAskJiminnyReportJob;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Models\\AutomatedReportResult;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AskJiminnyReportActivityService;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse PHPUnit\\Framework\\MockObject\\MockObject;\nuse PHPUnit\\Framework\\TestCase;\nuse Psr\\Log\\LoggerInterface;\n\nclass RequestGenerateAskJiminnyReportJobTest extends TestCase\n{\n private AutomatedReportsService&MockObject $reportService;\n private AskJiminnyReportActivityService&MockObject $activityService;\n private ProphetClient&MockObject $prophetClient;\n private LoggerInterface&MockObject $logger;\n\n protected function setUp(): void\n {\n $this->reportService = $this->createMock(AutomatedReportsService::class);\n $this->activityService = $this->createMock(AskJiminnyReportActivityService::class);\n $this->prophetClient = $this->createMock(ProphetClient::class);\n $this->logger = $this->createMock(LoggerInterface::class);\n }\n\n private function makeJob(string $uuid = 'report-uuid'): RequestGenerateAskJiminnyReportJob\n {\n return new RequestGenerateAskJiminnyReportJob($uuid);\n }\n\n private function makeActiveReport(\n string $type = AutomatedReportsService::TYPE_ASK_JIMINNY,\n bool $status = true,\n string $teamStatus = Team::STATUS_ACTIVE,\n ): AutomatedReport&MockObject { // @phpstan-ignore-line\n $team = $this->createMock(Team::class);\n $team->method('getStatus')->willReturn($teamStatus);\n\n $report = $this->createMock(AutomatedReport::class);\n $report->method('getType')->willReturn($type);\n $report->method('getStatus')->willReturn($status);\n $report->method('getTeam')->willReturn($team);\n\n return $report;\n }\n\n public function testUniqueIdReturnsReportUuid(): void\n {\n $job = $this->makeJob('my-unique-uuid');\n\n $this->assertEquals('my-unique-uuid', $job->uniqueId());\n }\n\n public function testHandleSkipsWhenReportTypeIsNotAskJiminny(): void\n {\n $report = $this->makeActiveReport(type: 'exec_summary');\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->logger->expects($this->once())\n ->method('info')\n ->with($this->stringContains('Started'));\n\n $this->logger->expects($this->once())\n ->method('warning')\n ->with($this->stringContains('not an ask_jiminny report'));\n\n $this->reportService->expects($this->never())->method('createReportResult');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleSkipsWhenReportIsInactive(): void\n {\n $report = $this->makeActiveReport(status: false);\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->logger->expects($this->exactly(2))\n ->method('info');\n\n $this->reportService->expects($this->never())->method('createReportResult');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleSkipsWhenTeamIsInactive(): void\n {\n $report = $this->makeActiveReport(teamStatus: Team::STATUS_DEACTIVATED);\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->logger->expects($this->exactly(2))\n ->method('info');\n\n $this->reportService->expects($this->never())->method('createReportResult');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleSkipsWhenCreatorIsNull(): void\n {\n $report = $this->makeActiveReport();\n $report->method('getCreator')->willReturn(null);\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->logger->expects($this->once())\n ->method('warning')\n ->with($this->stringContains('report creator not found'));\n\n $this->reportService->expects($this->never())->method('createReportResult');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleSkipsWhenSavedSearchIsNull(): void\n {\n $creator = $this->createMock(User::class);\n\n $report = $this->makeActiveReport();\n $report->method('getCreator')->willReturn($creator);\n $report->method('getSavedSearch')->willReturn(null);\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->logger->expects($this->once())\n ->method('warning')\n ->with($this->stringContains('saved search not found'));\n\n $this->reportService->expects($this->never())->method('createReportResult');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleSkipsWhenPromptIsNull(): void\n {\n $creator = $this->createMock(User::class);\n $savedSearch = $this->createMock(\\Jiminny\\Models\\Activity\\Search::class);\n\n $report = $this->makeActiveReport();\n $report->method('getCreator')->willReturn($creator);\n $report->method('getSavedSearch')->willReturn($savedSearch);\n $report->method('getAskAnythingPrompt')->willReturn(null);\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->logger->expects($this->once())\n ->method('warning')\n ->with($this->stringContains('ask anything prompt not found'));\n\n $this->reportService->expects($this->never())->method('createReportResult');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleFailsReportWhenNotEnoughActivities(): void\n {\n $creator = $this->createMock(User::class);\n $savedSearch = $this->createMock(\\Jiminny\\Models\\Activity\\Search::class);\n $prompt = $this->createMock(\\Jiminny\\Models\\AskAnything\\AskAnythingPrompt::class);\n\n $report = $this->makeActiveReport();\n $report->method('getCreator')->willReturn($creator);\n $report->method('getSavedSearch')->willReturn($savedSearch);\n $report->method('getAskAnythingPrompt')->willReturn($prompt);\n\n $reportResult = $this->createMock(AutomatedReportResult::class);\n $reportResult->expects($this->once())\n ->method('update')\n ->with($this->callback(fn ($data) => $data['status'] === AutomatedReportResult::STATUS_FAILED\n && $data['reason'] === AutomatedReportResult::REASON_NOT_ENOUGH_ACTIVITIES));\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->reportService->expects($this->once())\n ->method('createReportResult')\n ->willReturn($reportResult);\n\n $this->activityService->expects($this->once())\n ->method('getActivityIdsForSavedSearch')\n ->willReturn([]);\n\n $this->logger->expects($this->exactly(3))\n ->method('info');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleSuccessfullyRequestsReport(): void\n {\n Carbon::setTestNow(Carbon::parse('2026-04-07 10:00:00'));\n\n $creator = $this->createMock(User::class);\n $savedSearch = $this->createMock(\\Jiminny\\Models\\Activity\\Search::class);\n $prompt = $this->createMock(\\Jiminny\\Models\\AskAnything\\AskAnythingPrompt::class);\n\n $report = $this->makeActiveReport();\n $report->method('getCreator')->willReturn($creator);\n $report->method('getSavedSearch')->willReturn($savedSearch);\n $report->method('getAskAnythingPrompt')->willReturn($prompt);\n $report->method('getUuid')->willReturn('report-uuid');\n\n $reportResult = $this->createMock(AutomatedReportResult::class);\n $reportResult->method('getUuid')->willReturn('result-uuid');\n $reportResult->expects($this->once())\n ->method('update')\n ->with($this->callback(fn ($data) => $data['status'] === AutomatedReportResult::STATUS_REQUESTED\n && isset($data['name'], $data['payload'], $data['requested_at'])));\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->reportService->expects($this->once())\n ->method('createReportResult')\n ->willReturn($reportResult);\n\n $this->reportService->expects($this->once())\n ->method('getAskJiminnyGenerateReportPayload')\n ->willReturn(['key' => 'value']);\n\n $this->reportService->expects($this->once())\n ->method('getReportFileName')\n ->willReturn('My Report - 7 Apr 2026');\n\n $this->activityService->expects($this->once())\n ->method('getActivityIdsForSavedSearch')\n ->willReturn(['act-1', 'act-2']);\n\n $this->prophetClient->expects($this->once())\n ->method('sendRequest')\n ->willReturn(new \\Jiminny\\Component\\ProphetAi\\Dtos\\ProphetResponseDto([]));\n\n $this->logger->expects($this->exactly(4))\n ->method('info');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n\n Carbon::setTestNow();\n }\n\n public function testHandleCatchesGenericExceptionAndLogsError(): void\n {\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willThrowException(new \\RuntimeException('DB error'));\n\n $this->logger->expects($this->once())\n ->method('error')\n ->with($this->stringContains('Error'));\n\n $job = $this->makeJob();\n\n $reflection = new \\ReflectionClass($job);\n $triesProp = $reflection->getProperty('tries');\n $triesProp->setAccessible(true);\n\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleCatchesProphetExceptionAndSetsCorrectReason(): void\n {\n $creator = $this->createMock(User::class);\n $savedSearch = $this->createMock(\\Jiminny\\Models\\Activity\\Search::class);\n $prompt = $this->createMock(\\Jiminny\\Models\\AskAnything\\AskAnythingPrompt::class);\n\n $report = $this->makeActiveReport();\n $report->method('getCreator')->willReturn($creator);\n $report->method('getSavedSearch')->willReturn($savedSearch);\n $report->method('getAskAnythingPrompt')->willReturn($prompt);\n\n $reportResult = $this->createMock(AutomatedReportResult::class);\n $reportResult->method('getUuid')->willReturn('result-uuid');\n $reportResult->expects($this->once())\n ->method('update')\n ->with($this->callback(fn ($data) => $data['reason'] === AutomatedReportResult::REASON_PROPHET_API_ERROR));\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->reportService->expects($this->once())\n ->method('createReportResult')\n ->willReturn($reportResult);\n\n $this->activityService->expects($this->once())\n ->method('getActivityIdsForSavedSearch')\n ->willThrowException(new ProphetException('Prophet failed'));\n\n $this->logger->expects($this->once())\n ->method('error');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleCreatesReportResultBeforeActivityFetch(): void\n {\n $creator = $this->createMock(User::class);\n $savedSearch = $this->createMock(\\Jiminny\\Models\\Activity\\Search::class);\n $prompt = $this->createMock(\\Jiminny\\Models\\AskAnything\\AskAnythingPrompt::class);\n\n $report = $this->makeActiveReport();\n $report->method('getCreator')->willReturn($creator);\n $report->method('getSavedSearch')->willReturn($savedSearch);\n $report->method('getAskAnythingPrompt')->willReturn($prompt);\n\n $reportResult = $this->createMock(AutomatedReportResult::class);\n $reportResult->method('getUuid')->willReturn('result-uuid');\n\n $callOrder = [];\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->reportService->expects($this->once())\n ->method('createReportResult')\n ->willReturnCallback(function () use ($reportResult, &$callOrder) {\n $callOrder[] = 'createReportResult';\n\n return $reportResult;\n });\n\n $this->activityService->expects($this->once())\n ->method('getActivityIdsForSavedSearch')\n ->willReturnCallback(function () use (&$callOrder) {\n $callOrder[] = 'getActivityIds';\n\n return [];\n });\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n\n $this->assertEquals(['createReportResult', 'getActivityIds'], $callOrder);\n }\n\n public function testHandlePassesCorrectDataToCreateReportResult(): void\n {\n $creator = $this->createMock(User::class);\n $savedSearch = $this->createMock(\\Jiminny\\Models\\Activity\\Search::class);\n $prompt = $this->createMock(\\Jiminny\\Models\\AskAnything\\AskAnythingPrompt::class);\n\n $report = $this->makeActiveReport();\n $report->method('getCreator')->willReturn($creator);\n $report->method('getSavedSearch')->willReturn($savedSearch);\n $report->method('getAskAnythingPrompt')->willReturn($prompt);\n\n $reportResult = $this->createMock(AutomatedReportResult::class);\n $reportResult->method('getUuid')->willReturn('result-uuid');\n $reportResult->method('update')->willReturn(true);\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->reportService->expects($this->once())\n ->method('createReportResult')\n ->with(\n automatedReport: $report,\n data: $this->callback(fn ($data) => $data['status'] === AutomatedReportResult::STATUS_DEFAULT\n && $data['media_type'] === AutomatedReportsService::MEDIA_TYPE_PDF)\n )\n ->willReturn($reportResult);\n\n $this->activityService->expects($this->once())\n ->method('getActivityIdsForSavedSearch')\n ->willReturn([]);\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n}","depth":4,"bounds":{"left":0.55507815,"top":0.08472222,"width":0.43125,"height":0.9152778},"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Tests\\Unit\\Jobs\\AutomatedReports;\n\nuse Carbon\\Carbon;\nuse Jiminny\\Component\\ProphetAi\\Exceptions\\ProphetException;\nuse Jiminny\\Component\\ProphetAi\\ProphetClient;\nuse Jiminny\\Jobs\\AutomatedReports\\RequestGenerateAskJiminnyReportJob;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Models\\AutomatedReportResult;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AskJiminnyReportActivityService;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse PHPUnit\\Framework\\MockObject\\MockObject;\nuse PHPUnit\\Framework\\TestCase;\nuse Psr\\Log\\LoggerInterface;\n\nclass RequestGenerateAskJiminnyReportJobTest extends TestCase\n{\n private AutomatedReportsService&MockObject $reportService;\n private AskJiminnyReportActivityService&MockObject $activityService;\n private ProphetClient&MockObject $prophetClient;\n private LoggerInterface&MockObject $logger;\n\n protected function setUp(): void\n {\n $this->reportService = $this->createMock(AutomatedReportsService::class);\n $this->activityService = $this->createMock(AskJiminnyReportActivityService::class);\n $this->prophetClient = $this->createMock(ProphetClient::class);\n $this->logger = $this->createMock(LoggerInterface::class);\n }\n\n private function makeJob(string $uuid = 'report-uuid'): RequestGenerateAskJiminnyReportJob\n {\n return new RequestGenerateAskJiminnyReportJob($uuid);\n }\n\n private function makeActiveReport(\n string $type = AutomatedReportsService::TYPE_ASK_JIMINNY,\n bool $status = true,\n string $teamStatus = Team::STATUS_ACTIVE,\n ): AutomatedReport&MockObject { // @phpstan-ignore-line\n $team = $this->createMock(Team::class);\n $team->method('getStatus')->willReturn($teamStatus);\n\n $report = $this->createMock(AutomatedReport::class);\n $report->method('getType')->willReturn($type);\n $report->method('getStatus')->willReturn($status);\n $report->method('getTeam')->willReturn($team);\n\n return $report;\n }\n\n public function testUniqueIdReturnsReportUuid(): void\n {\n $job = $this->makeJob('my-unique-uuid');\n\n $this->assertEquals('my-unique-uuid', $job->uniqueId());\n }\n\n public function testHandleSkipsWhenReportTypeIsNotAskJiminny(): void\n {\n $report = $this->makeActiveReport(type: 'exec_summary');\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->logger->expects($this->once())\n ->method('info')\n ->with($this->stringContains('Started'));\n\n $this->logger->expects($this->once())\n ->method('warning')\n ->with($this->stringContains('not an ask_jiminny report'));\n\n $this->reportService->expects($this->never())->method('createReportResult');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleSkipsWhenReportIsInactive(): void\n {\n $report = $this->makeActiveReport(status: false);\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->logger->expects($this->exactly(2))\n ->method('info');\n\n $this->reportService->expects($this->never())->method('createReportResult');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleSkipsWhenTeamIsInactive(): void\n {\n $report = $this->makeActiveReport(teamStatus: Team::STATUS_DEACTIVATED);\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->logger->expects($this->exactly(2))\n ->method('info');\n\n $this->reportService->expects($this->never())->method('createReportResult');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleSkipsWhenCreatorIsNull(): void\n {\n $report = $this->makeActiveReport();\n $report->method('getCreator')->willReturn(null);\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->logger->expects($this->once())\n ->method('warning')\n ->with($this->stringContains('report creator not found'));\n\n $this->reportService->expects($this->never())->method('createReportResult');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleSkipsWhenSavedSearchIsNull(): void\n {\n $creator = $this->createMock(User::class);\n\n $report = $this->makeActiveReport();\n $report->method('getCreator')->willReturn($creator);\n $report->method('getSavedSearch')->willReturn(null);\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->logger->expects($this->once())\n ->method('warning')\n ->with($this->stringContains('saved search not found'));\n\n $this->reportService->expects($this->never())->method('createReportResult');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleSkipsWhenPromptIsNull(): void\n {\n $creator = $this->createMock(User::class);\n $savedSearch = $this->createMock(\\Jiminny\\Models\\Activity\\Search::class);\n\n $report = $this->makeActiveReport();\n $report->method('getCreator')->willReturn($creator);\n $report->method('getSavedSearch')->willReturn($savedSearch);\n $report->method('getAskAnythingPrompt')->willReturn(null);\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->logger->expects($this->once())\n ->method('warning')\n ->with($this->stringContains('ask anything prompt not found'));\n\n $this->reportService->expects($this->never())->method('createReportResult');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleFailsReportWhenNotEnoughActivities(): void\n {\n $creator = $this->createMock(User::class);\n $savedSearch = $this->createMock(\\Jiminny\\Models\\Activity\\Search::class);\n $prompt = $this->createMock(\\Jiminny\\Models\\AskAnything\\AskAnythingPrompt::class);\n\n $report = $this->makeActiveReport();\n $report->method('getCreator')->willReturn($creator);\n $report->method('getSavedSearch')->willReturn($savedSearch);\n $report->method('getAskAnythingPrompt')->willReturn($prompt);\n\n $reportResult = $this->createMock(AutomatedReportResult::class);\n $reportResult->expects($this->once())\n ->method('update')\n ->with($this->callback(fn ($data) => $data['status'] === AutomatedReportResult::STATUS_FAILED\n && $data['reason'] === AutomatedReportResult::REASON_NOT_ENOUGH_ACTIVITIES));\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->reportService->expects($this->once())\n ->method('createReportResult')\n ->willReturn($reportResult);\n\n $this->activityService->expects($this->once())\n ->method('getActivityIdsForSavedSearch')\n ->willReturn([]);\n\n $this->logger->expects($this->exactly(3))\n ->method('info');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleSuccessfullyRequestsReport(): void\n {\n Carbon::setTestNow(Carbon::parse('2026-04-07 10:00:00'));\n\n $creator = $this->createMock(User::class);\n $savedSearch = $this->createMock(\\Jiminny\\Models\\Activity\\Search::class);\n $prompt = $this->createMock(\\Jiminny\\Models\\AskAnything\\AskAnythingPrompt::class);\n\n $report = $this->makeActiveReport();\n $report->method('getCreator')->willReturn($creator);\n $report->method('getSavedSearch')->willReturn($savedSearch);\n $report->method('getAskAnythingPrompt')->willReturn($prompt);\n $report->method('getUuid')->willReturn('report-uuid');\n\n $reportResult = $this->createMock(AutomatedReportResult::class);\n $reportResult->method('getUuid')->willReturn('result-uuid');\n $reportResult->expects($this->once())\n ->method('update')\n ->with($this->callback(fn ($data) => $data['status'] === AutomatedReportResult::STATUS_REQUESTED\n && isset($data['name'], $data['payload'], $data['requested_at'])));\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->reportService->expects($this->once())\n ->method('createReportResult')\n ->willReturn($reportResult);\n\n $this->reportService->expects($this->once())\n ->method('getAskJiminnyGenerateReportPayload')\n ->willReturn(['key' => 'value']);\n\n $this->reportService->expects($this->once())\n ->method('getReportFileName')\n ->willReturn('My Report - 7 Apr 2026');\n\n $this->activityService->expects($this->once())\n ->method('getActivityIdsForSavedSearch')\n ->willReturn(['act-1', 'act-2']);\n\n $this->prophetClient->expects($this->once())\n ->method('sendRequest')\n ->willReturn(new \\Jiminny\\Component\\ProphetAi\\Dtos\\ProphetResponseDto([]));\n\n $this->logger->expects($this->exactly(4))\n ->method('info');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n\n Carbon::setTestNow();\n }\n\n public function testHandleCatchesGenericExceptionAndLogsError(): void\n {\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willThrowException(new \\RuntimeException('DB error'));\n\n $this->logger->expects($this->once())\n ->method('error')\n ->with($this->stringContains('Error'));\n\n $job = $this->makeJob();\n\n $reflection = new \\ReflectionClass($job);\n $triesProp = $reflection->getProperty('tries');\n $triesProp->setAccessible(true);\n\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleCatchesProphetExceptionAndSetsCorrectReason(): void\n {\n $creator = $this->createMock(User::class);\n $savedSearch = $this->createMock(\\Jiminny\\Models\\Activity\\Search::class);\n $prompt = $this->createMock(\\Jiminny\\Models\\AskAnything\\AskAnythingPrompt::class);\n\n $report = $this->makeActiveReport();\n $report->method('getCreator')->willReturn($creator);\n $report->method('getSavedSearch')->willReturn($savedSearch);\n $report->method('getAskAnythingPrompt')->willReturn($prompt);\n\n $reportResult = $this->createMock(AutomatedReportResult::class);\n $reportResult->method('getUuid')->willReturn('result-uuid');\n $reportResult->expects($this->once())\n ->method('update')\n ->with($this->callback(fn ($data) => $data['reason'] === AutomatedReportResult::REASON_PROPHET_API_ERROR));\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->reportService->expects($this->once())\n ->method('createReportResult')\n ->willReturn($reportResult);\n\n $this->activityService->expects($this->once())\n ->method('getActivityIdsForSavedSearch')\n ->willThrowException(new ProphetException('Prophet failed'));\n\n $this->logger->expects($this->once())\n ->method('error');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleCreatesReportResultBeforeActivityFetch(): void\n {\n $creator = $this->createMock(User::class);\n $savedSearch = $this->createMock(\\Jiminny\\Models\\Activity\\Search::class);\n $prompt = $this->createMock(\\Jiminny\\Models\\AskAnything\\AskAnythingPrompt::class);\n\n $report = $this->makeActiveReport();\n $report->method('getCreator')->willReturn($creator);\n $report->method('getSavedSearch')->willReturn($savedSearch);\n $report->method('getAskAnythingPrompt')->willReturn($prompt);\n\n $reportResult = $this->createMock(AutomatedReportResult::class);\n $reportResult->method('getUuid')->willReturn('result-uuid');\n\n $callOrder = [];\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->reportService->expects($this->once())\n ->method('createReportResult')\n ->willReturnCallback(function () use ($reportResult, &$callOrder) {\n $callOrder[] = 'createReportResult';\n\n return $reportResult;\n });\n\n $this->activityService->expects($this->once())\n ->method('getActivityIdsForSavedSearch')\n ->willReturnCallback(function () use (&$callOrder) {\n $callOrder[] = 'getActivityIds';\n\n return [];\n });\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n\n $this->assertEquals(['createReportResult', 'getActivityIds'], $callOrder);\n }\n\n public function testHandlePassesCorrectDataToCreateReportResult(): void\n {\n $creator = $this->createMock(User::class);\n $savedSearch = $this->createMock(\\Jiminny\\Models\\Activity\\Search::class);\n $prompt = $this->createMock(\\Jiminny\\Models\\AskAnything\\AskAnythingPrompt::class);\n\n $report = $this->makeActiveReport();\n $report->method('getCreator')->willReturn($creator);\n $report->method('getSavedSearch')->willReturn($savedSearch);\n $report->method('getAskAnythingPrompt')->willReturn($prompt);\n\n $reportResult = $this->createMock(AutomatedReportResult::class);\n $reportResult->method('getUuid')->willReturn('result-uuid');\n $reportResult->method('update')->willReturn(true);\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->reportService->expects($this->once())\n ->method('createReportResult')\n ->with(\n automatedReport: $report,\n data: $this->callback(fn ($data) => $data['status'] === AutomatedReportResult::STATUS_DEFAULT\n && $data['media_type'] === AutomatedReportsService::MEDIA_TYPE_PDF)\n )\n ->willReturn($reportResult);\n\n $this->activityService->expects($this->once())\n ->method('getActivityIdsForSavedSearch')\n ->willReturn([]);\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"bounds":{"left":0.0140625,"top":0.041666668,"width":0.028515626,"height":0.021527778},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.23320313,"top":1.0,"width":0.01015625,"height":0.0},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
8260492435066441110
|
8722295178528246161
|
idle
|
accessibility
|
NULL
|
Project: faVsco.js, menu
#11894 on JY-18909-automa Project: faVsco.js, menu
#11894 on JY-18909-automated-reports-ask-jiminny, menu
Start Listening for PHP Debug Connections
RequestGenerateAskJiminnyReportJobTest
Run 'RequestGenerateAskJiminnyReportJobTest'
Debug 'RequestGenerateAskJiminnyReportJobTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Console\Commands\Reports;
use Carbon\Carbon;
use Illuminate\Console\Command;
use Illuminate\Contracts\Bus\Dispatcher as BusDispatcher;
use Jiminny\Jobs\AutomatedReports\RequestGenerateAskJiminnyReportJob;
use Jiminny\Jobs\AutomatedReports\RequestGenerateReportJob;
use Jiminny\Models\AutomatedReport;
use Jiminny\Repositories\AutomatedReportsRepository;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Psr\Log\LoggerInterface;
class AutomatedReportsCommand extends Command
{
/**
* Log prefix for all log messages
*/
private const string LOG_PREFIX = '[automated-reports]';
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'automated-reports';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Process automated reports based on their frequency (weekly, monthly, quarterly)';
public function __construct(
private readonly LoggerInterface $logger,
private readonly BusDispatcher $dispatcher,
private readonly AutomatedReportsRepository $reportRepository
) {
parent::__construct();
}
/**
* Execute the console command.
*
* @return int
*/
public function handle(): int
{
$this->logger->info(self::LOG_PREFIX . ' Started');
$now = Carbon::now();
$isMonday = $now->isMonday();
$isFirstDayOfMonth = $now->day === 1;
$currentMonth = $now->month;
// Check if the current month is a quarterly month (January, April, July, October)
$isQuarterlyMonth = in_array($currentMonth, [1, 4, 7, 10], true);
$this->logger->info(self::LOG_PREFIX . ' Checking conditions', [
'isMonday' => $isMonday,
'isFirstDayOfMonth' => $isFirstDayOfMonth,
'currentMonth' => $currentMonth,
'isQuarterlyMonth' => $isQuarterlyMonth,
]);
// Process daily reports
$this->processReports(AutomatedReportsService::FREQUENCY_DAILY);
// Process weekly reports on Mondays
if ($isMonday) {
$this->processReports(AutomatedReportsService::FREQUENCY_WEEKLY);
}
// Process monthly reports on the first day of the month
if ($isFirstDayOfMonth) {
$this->processReports(AutomatedReportsService::FREQUENCY_MONTHLY);
}
// Process quarterly reports on the first day of January, April, July, and October
if ($isFirstDayOfMonth && $isQuarterlyMonth) {
$this->processReports(AutomatedReportsService::FREQUENCY_QUARTERLY);
}
$this->logger->info(self::LOG_PREFIX . ' Completed');
return 0;
}
/**
* Process reports for a specific frequency.
*
* @param string $frequency
*
* @return void
*/
private function processReports(string $frequency): void
{
$this->logger->info(self::LOG_PREFIX . " Processing $frequency reports");
// Get all enabled, not deleted reports with active teams for the specified frequency
$reports = $this->reportRepository->getActiveReportsByFrequency($frequency);
// $reports = collect([AutomatedReport::find(68)]);
$this->logger->info(self::LOG_PREFIX . " Found {$reports->count()} $frequency reports to process");
/** @var AutomatedReport $report */
foreach ($reports as $report) {
$this->logger->info(self::LOG_PREFIX . ' Dispatching Generate Report job for report', [
'reportUuid' => $report->getUuid(),
'teamId' => $report->getTeamId(),
'frequency' => $report->getFrequency(),
'type' => $report->getType(),
]);
$job = $report->isAskJiminnyReport()
? new RequestGenerateAskJiminnyReportJob($report->getUuid())
: new RequestGenerateReportJob($report->getUuid());
// $this->dispatcher->dispatch($job);
$this->dispatcher->dispatchSync($job);
}
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
1
14
4
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Tests\Unit\Jobs\AutomatedReports;
use Carbon\Carbon;
use Jiminny\Component\ProphetAi\Exceptions\ProphetException;
use Jiminny\Component\ProphetAi\ProphetClient;
use Jiminny\Jobs\AutomatedReports\RequestGenerateAskJiminnyReportJob;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\AutomatedReportResult;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityService;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
use Psr\Log\LoggerInterface;
class RequestGenerateAskJiminnyReportJobTest extends TestCase
{
private AutomatedReportsService&MockObject $reportService;
private AskJiminnyReportActivityService&MockObject $activityService;
private ProphetClient&MockObject $prophetClient;
private LoggerInterface&MockObject $logger;
protected function setUp(): void
{
$this->reportService = $this->createMock(AutomatedReportsService::class);
$this->activityService = $this->createMock(AskJiminnyReportActivityService::class);
$this->prophetClient = $this->createMock(ProphetClient::class);
$this->logger = $this->createMock(LoggerInterface::class);
}
private function makeJob(string $uuid = 'report-uuid'): RequestGenerateAskJiminnyReportJob
{
return new RequestGenerateAskJiminnyReportJob($uuid);
}
private function makeActiveReport(
string $type = AutomatedReportsService::TYPE_ASK_JIMINNY,
bool $status = true,
string $teamStatus = Team::STATUS_ACTIVE,
): AutomatedReport&MockObject { // @phpstan-ignore-line
$team = $this->createMock(Team::class);
$team->method('getStatus')->willReturn($teamStatus);
$report = $this->createMock(AutomatedReport::class);
$report->method('getType')->willReturn($type);
$report->method('getStatus')->willReturn($status);
$report->method('getTeam')->willReturn($team);
return $report;
}
public function testUniqueIdReturnsReportUuid(): void
{
$job = $this->makeJob('my-unique-uuid');
$this->assertEquals('my-unique-uuid', $job->uniqueId());
}
public function testHandleSkipsWhenReportTypeIsNotAskJiminny(): void
{
$report = $this->makeActiveReport(type: 'exec_summary');
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->logger->expects($this->once())
->method('info')
->with($this->stringContains('Started'));
$this->logger->expects($this->once())
->method('warning')
->with($this->stringContains('not an ask_jiminny report'));
$this->reportService->expects($this->never())->method('createReportResult');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleSkipsWhenReportIsInactive(): void
{
$report = $this->makeActiveReport(status: false);
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->logger->expects($this->exactly(2))
->method('info');
$this->reportService->expects($this->never())->method('createReportResult');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleSkipsWhenTeamIsInactive(): void
{
$report = $this->makeActiveReport(teamStatus: Team::STATUS_DEACTIVATED);
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->logger->expects($this->exactly(2))
->method('info');
$this->reportService->expects($this->never())->method('createReportResult');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleSkipsWhenCreatorIsNull(): void
{
$report = $this->makeActiveReport();
$report->method('getCreator')->willReturn(null);
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->logger->expects($this->once())
->method('warning')
->with($this->stringContains('report creator not found'));
$this->reportService->expects($this->never())->method('createReportResult');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleSkipsWhenSavedSearchIsNull(): void
{
$creator = $this->createMock(User::class);
$report = $this->makeActiveReport();
$report->method('getCreator')->willReturn($creator);
$report->method('getSavedSearch')->willReturn(null);
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->logger->expects($this->once())
->method('warning')
->with($this->stringContains('saved search not found'));
$this->reportService->expects($this->never())->method('createReportResult');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleSkipsWhenPromptIsNull(): void
{
$creator = $this->createMock(User::class);
$savedSearch = $this->createMock(\Jiminny\Models\Activity\Search::class);
$report = $this->makeActiveReport();
$report->method('getCreator')->willReturn($creator);
$report->method('getSavedSearch')->willReturn($savedSearch);
$report->method('getAskAnythingPrompt')->willReturn(null);
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->logger->expects($this->once())
->method('warning')
->with($this->stringContains('ask anything prompt not found'));
$this->reportService->expects($this->never())->method('createReportResult');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleFailsReportWhenNotEnoughActivities(): void
{
$creator = $this->createMock(User::class);
$savedSearch = $this->createMock(\Jiminny\Models\Activity\Search::class);
$prompt = $this->createMock(\Jiminny\Models\AskAnything\AskAnythingPrompt::class);
$report = $this->makeActiveReport();
$report->method('getCreator')->willReturn($creator);
$report->method('getSavedSearch')->willReturn($savedSearch);
$report->method('getAskAnythingPrompt')->willReturn($prompt);
$reportResult = $this->createMock(AutomatedReportResult::class);
$reportResult->expects($this->once())
->method('update')
->with($this->callback(fn ($data) => $data['status'] === AutomatedReportResult::STATUS_FAILED
&& $data['reason'] === AutomatedReportResult::REASON_NOT_ENOUGH_ACTIVITIES));
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->reportService->expects($this->once())
->method('createReportResult')
->willReturn($reportResult);
$this->activityService->expects($this->once())
->method('getActivityIdsForSavedSearch')
->willReturn([]);
$this->logger->expects($this->exactly(3))
->method('info');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleSuccessfullyRequestsReport(): void
{
Carbon::setTestNow(Carbon::parse('2026-04-07 10:00:00'));
$creator = $this->createMock(User::class);
$savedSearch = $this->createMock(\Jiminny\Models\Activity\Search::class);
$prompt = $this->createMock(\Jiminny\Models\AskAnything\AskAnythingPrompt::class);
$report = $this->makeActiveReport();
$report->method('getCreator')->willReturn($creator);
$report->method('getSavedSearch')->willReturn($savedSearch);
$report->method('getAskAnythingPrompt')->willReturn($prompt);
$report->method('getUuid')->willReturn('report-uuid');
$reportResult = $this->createMock(AutomatedReportResult::class);
$reportResult->method('getUuid')->willReturn('result-uuid');
$reportResult->expects($this->once())
->method('update')
->with($this->callback(fn ($data) => $data['status'] === AutomatedReportResult::STATUS_REQUESTED
&& isset($data['name'], $data['payload'], $data['requested_at'])));
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->reportService->expects($this->once())
->method('createReportResult')
->willReturn($reportResult);
$this->reportService->expects($this->once())
->method('getAskJiminnyGenerateReportPayload')
->willReturn(['key' => 'value']);
$this->reportService->expects($this->once())
->method('getReportFileName')
->willReturn('My Report - 7 Apr 2026');
$this->activityService->expects($this->once())
->method('getActivityIdsForSavedSearch')
->willReturn(['act-1', 'act-2']);
$this->prophetClient->expects($this->once())
->method('sendRequest')
->willReturn(new \Jiminny\Component\ProphetAi\Dtos\ProphetResponseDto([]));
$this->logger->expects($this->exactly(4))
->method('info');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
Carbon::setTestNow();
}
public function testHandleCatchesGenericExceptionAndLogsError(): void
{
$this->reportService->expects($this->once())
->method('getReport')
->willThrowException(new \RuntimeException('DB error'));
$this->logger->expects($this->once())
->method('error')
->with($this->stringContains('Error'));
$job = $this->makeJob();
$reflection = new \ReflectionClass($job);
$triesProp = $reflection->getProperty('tries');
$triesProp->setAccessible(true);
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleCatchesProphetExceptionAndSetsCorrectReason(): void
{
$creator = $this->createMock(User::class);
$savedSearch = $this->createMock(\Jiminny\Models\Activity\Search::class);
$prompt = $this->createMock(\Jiminny\Models\AskAnything\AskAnythingPrompt::class);
$report = $this->makeActiveReport();
$report->method('getCreator')->willReturn($creator);
$report->method('getSavedSearch')->willReturn($savedSearch);
$report->method('getAskAnythingPrompt')->willReturn($prompt);
$reportResult = $this->createMock(AutomatedReportResult::class);
$reportResult->method('getUuid')->willReturn('result-uuid');
$reportResult->expects($this->once())
->method('update')
->with($this->callback(fn ($data) => $data['reason'] === AutomatedReportResult::REASON_PROPHET_API_ERROR));
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->reportService->expects($this->once())
->method('createReportResult')
->willReturn($reportResult);
$this->activityService->expects($this->once())
->method('getActivityIdsForSavedSearch')
->willThrowException(new ProphetException('Prophet failed'));
$this->logger->expects($this->once())
->method('error');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleCreatesReportResultBeforeActivityFetch(): void
{
$creator = $this->createMock(User::class);
$savedSearch = $this->createMock(\Jiminny\Models\Activity\Search::class);
$prompt = $this->createMock(\Jiminny\Models\AskAnything\AskAnythingPrompt::class);
$report = $this->makeActiveReport();
$report->method('getCreator')->willReturn($creator);
$report->method('getSavedSearch')->willReturn($savedSearch);
$report->method('getAskAnythingPrompt')->willReturn($prompt);
$reportResult = $this->createMock(AutomatedReportResult::class);
$reportResult->method('getUuid')->willReturn('result-uuid');
$callOrder = [];
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->reportService->expects($this->once())
->method('createReportResult')
->willReturnCallback(function () use ($reportResult, &$callOrder) {
$callOrder[] = 'createReportResult';
return $reportResult;
});
$this->activityService->expects($this->once())
->method('getActivityIdsForSavedSearch')
->willReturnCallback(function () use (&$callOrder) {
$callOrder[] = 'getActivityIds';
return [];
});
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
$this->assertEquals(['createReportResult', 'getActivityIds'], $callOrder);
}
public function testHandlePassesCorrectDataToCreateReportResult(): void
{
$creator = $this->createMock(User::class);
$savedSearch = $this->createMock(\Jiminny\Models\Activity\Search::class);
$prompt = $this->createMock(\Jiminny\Models\AskAnything\AskAnythingPrompt::class);
$report = $this->makeActiveReport();
$report->method('getCreator')->willReturn($creator);
$report->method('getSavedSearch')->willReturn($savedSearch);
$report->method('getAskAnythingPrompt')->willReturn($prompt);
$reportResult = $this->createMock(AutomatedReportResult::class);
$reportResult->method('getUuid')->willReturn('result-uuid');
$reportResult->method('update')->willReturn(true);
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->reportService->expects($this->once())
->method('createReportResult')
->with(
automatedReport: $report,
data: $this->callback(fn ($data) => $data['status'] === AutomatedReportResult::STATUS_DEFAULT
&& $data['media_type'] === AutomatedReportsService::MEDIA_TYPE_PDF)
)
->willReturn($reportResult);
$this->activityService->expects($this->once())
->method('getActivityIdsForSavedSearch')
->willReturn([]);
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
9496
|
|
9499
|
184
|
1
|
2026-04-14T07:42:00.845428+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776152520845_m1.jpg...
|
PhpStorm
|
faVsco.js – AutomatedReportsCommand.php
|
True
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
#11894 on JY-18909-automa Project: faVsco.js, menu
#11894 on JY-18909-automated-reports-ask-jiminny, menu
Start Listening for PHP Debug Connections
RequestGenerateAskJiminnyReportJobTest
Run 'RequestGenerateAskJiminnyReportJobTest'
Debug 'RequestGenerateAskJiminnyReportJobTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Console\Commands\Reports;
use Carbon\Carbon;
use Illuminate\Console\Command;
use Illuminate\Contracts\Bus\Dispatcher as BusDispatcher;
use Jiminny\Jobs\AutomatedReports\RequestGenerateAskJiminnyReportJob;
use Jiminny\Jobs\AutomatedReports\RequestGenerateReportJob;
use Jiminny\Models\AutomatedReport;
use Jiminny\Repositories\AutomatedReportsRepository;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Psr\Log\LoggerInterface;
class AutomatedReportsCommand extends Command
{
/**
* Log prefix for all log messages
*/
private const string LOG_PREFIX = '[automated-reports]';
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'automated-reports';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Process automated reports based on their frequency (weekly, monthly, quarterly)';
public function __construct(
private readonly LoggerInterface $logger,
private readonly BusDispatcher $dispatcher,
private readonly AutomatedReportsRepository $reportRepository
) {
parent::__construct();
}
/**
* Execute the console command.
*
* @return int
*/
public function handle(): int
{
$this->logger->info(self::LOG_PREFIX . ' Started');
$now = Carbon::now();
$isMonday = $now->isMonday();
$isFirstDayOfMonth = $now->day === 1;
$currentMonth = $now->month;
// Check if the current month is a quarterly month (January, April, July, October)
$isQuarterlyMonth = in_array($currentMonth, [1, 4, 7, 10], true);
$this->logger->info(self::LOG_PREFIX . ' Checking conditions', [
'isMonday' => $isMonday,
'isFirstDayOfMonth' => $isFirstDayOfMonth,
'currentMonth' => $currentMonth,
'isQuarterlyMonth' => $isQuarterlyMonth,
]);
// Process daily reports
$this->processReports(AutomatedReportsService::FREQUENCY_DAILY);
// Process weekly reports on Mondays
if ($isMonday) {
$this->processReports(AutomatedReportsService::FREQUENCY_WEEKLY);
}
// Process monthly reports on the first day of the month
if ($isFirstDayOfMonth) {
$this->processReports(AutomatedReportsService::FREQUENCY_MONTHLY);
}
// Process quarterly reports on the first day of January, April, July, and October
if ($isFirstDayOfMonth && $isQuarterlyMonth) {
$this->processReports(AutomatedReportsService::FREQUENCY_QUARTERLY);
}
$this->logger->info(self::LOG_PREFIX . ' Completed');
return 0;
}
/**
* Process reports for a specific frequency.
*
* @param string $frequency
*
* @return void
*/
private function processReports(string $frequency): void
{
$this->logger->info(self::LOG_PREFIX . " Processing $frequency reports");
// Get all enabled, not deleted reports with active teams for the specified frequency
$reports = $this->reportRepository->getActiveReportsByFrequency($frequency);
// $reports = collect([AutomatedReport::find(68)]);
$this->logger->info(self::LOG_PREFIX . " Found {$reports->count()} $frequency reports to process");
/** @var AutomatedReport $report */
foreach ($reports as $report) {
$this->logger->info(self::LOG_PREFIX . ' Dispatching Generate Report job for report', [
'reportUuid' => $report->getUuid(),
'teamId' => $report->getTeamId(),
'frequency' => $report->getFrequency(),
'type' => $report->getType(),
]);
$job = $report->isAskJiminnyReport()
? new RequestGenerateAskJiminnyReportJob($report->getUuid())
: new RequestGenerateReportJob($report->getUuid());
// $this->dispatcher->dispatch($job);
$this->dispatcher->dispatchSync($job);
}
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
1
14
4
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Tests\Unit\Jobs\AutomatedReports;
use Carbon\Carbon;
use Jiminny\Component\ProphetAi\Exceptions\ProphetException;
use Jiminny\Component\ProphetAi\ProphetClient;
use Jiminny\Jobs\AutomatedReports\RequestGenerateAskJiminnyReportJob;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\AutomatedReportResult;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityService;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
use Psr\Log\LoggerInterface;
class RequestGenerateAskJiminnyReportJobTest extends TestCase
{
private AutomatedReportsService&MockObject $reportService;
private AskJiminnyReportActivityService&MockObject $activityService;
private ProphetClient&MockObject $prophetClient;
private LoggerInterface&MockObject $logger;
protected function setUp(): void
{
$this->reportService = $this->createMock(AutomatedReportsService::class);
$this->activityService = $this->createMock(AskJiminnyReportActivityService::class);
$this->prophetClient = $this->createMock(ProphetClient::class);
$this->logger = $this->createMock(LoggerInterface::class);
}
private function makeJob(string $uuid = 'report-uuid'): RequestGenerateAskJiminnyReportJob
{
return new RequestGenerateAskJiminnyReportJob($uuid);
}
private function makeActiveReport(
string $type = AutomatedReportsService::TYPE_ASK_JIMINNY,
bool $status = true,
string $teamStatus = Team::STATUS_ACTIVE,
): AutomatedReport&MockObject { // @phpstan-ignore-line
$team = $this->createMock(Team::class);
$team->method('getStatus')->willReturn($teamStatus);
$report = $this->createMock(AutomatedReport::class);
$report->method('getType')->willReturn($type);
$report->method('getStatus')->willReturn($status);
$report->method('getTeam')->willReturn($team);
return $report;
}
public function testUniqueIdReturnsReportUuid(): void
{
$job = $this->makeJob('my-unique-uuid');
$this->assertEquals('my-unique-uuid', $job->uniqueId());
}
public function testHandleSkipsWhenReportTypeIsNotAskJiminny(): void
{
$report = $this->makeActiveReport(type: 'exec_summary');
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->logger->expects($this->once())
->method('info')
->with($this->stringContains('Started'));
$this->logger->expects($this->once())
->method('warning')
->with($this->stringContains('not an ask_jiminny report'));
$this->reportService->expects($this->never())->method('createReportResult');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleSkipsWhenReportIsInactive(): void
{
$report = $this->makeActiveReport(status: false);
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->logger->expects($this->exactly(2))
->method('info');
$this->reportService->expects($this->never())->method('createReportResult');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleSkipsWhenTeamIsInactive(): void
{
$report = $this->makeActiveReport(teamStatus: Team::STATUS_DEACTIVATED);
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->logger->expects($this->exactly(2))
->method('info');
$this->reportService->expects($this->never())->method('createReportResult');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleSkipsWhenCreatorIsNull(): void
{
$report = $this->makeActiveReport();
$report->method('getCreator')->willReturn(null);
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->logger->expects($this->once())
->method('warning')
->with($this->stringContains('report creator not found'));
$this->reportService->expects($this->never())->method('createReportResult');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleSkipsWhenSavedSearchIsNull(): void
{
$creator = $this->createMock(User::class);
$report = $this->makeActiveReport();
$report->method('getCreator')->willReturn($creator);
$report->method('getSavedSearch')->willReturn(null);
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->logger->expects($this->once())
->method('warning')
->with($this->stringContains('saved search not found'));
$this->reportService->expects($this->never())->method('createReportResult');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleSkipsWhenPromptIsNull(): void
{
$creator = $this->createMock(User::class);
$savedSearch = $this->createMock(\Jiminny\Models\Activity\Search::class);
$report = $this->makeActiveReport();
$report->method('getCreator')->willReturn($creator);
$report->method('getSavedSearch')->willReturn($savedSearch);
$report->method('getAskAnythingPrompt')->willReturn(null);
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->logger->expects($this->once())
->method('warning')
->with($this->stringContains('ask anything prompt not found'));
$this->reportService->expects($this->never())->method('createReportResult');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleFailsReportWhenNotEnoughActivities(): void
{
$creator = $this->createMock(User::class);
$savedSearch = $this->createMock(\Jiminny\Models\Activity\Search::class);
$prompt = $this->createMock(\Jiminny\Models\AskAnything\AskAnythingPrompt::class);
$report = $this->makeActiveReport();
$report->method('getCreator')->willReturn($creator);
$report->method('getSavedSearch')->willReturn($savedSearch);
$report->method('getAskAnythingPrompt')->willReturn($prompt);
$reportResult = $this->createMock(AutomatedReportResult::class);
$reportResult->expects($this->once())
->method('update')
->with($this->callback(fn ($data) => $data['status'] === AutomatedReportResult::STATUS_FAILED
&& $data['reason'] === AutomatedReportResult::REASON_NOT_ENOUGH_ACTIVITIES));
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->reportService->expects($this->once())
->method('createReportResult')
->willReturn($reportResult);
$this->activityService->expects($this->once())
->method('getActivityIdsForSavedSearch')
->willReturn([]);
$this->logger->expects($this->exactly(3))
->method('info');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleSuccessfullyRequestsReport(): void
{
Carbon::setTestNow(Carbon::parse('2026-04-07 10:00:00'));
$creator = $this->createMock(User::class);
$savedSearch = $this->createMock(\Jiminny\Models\Activity\Search::class);
$prompt = $this->createMock(\Jiminny\Models\AskAnything\AskAnythingPrompt::class);
$report = $this->makeActiveReport();
$report->method('getCreator')->willReturn($creator);
$report->method('getSavedSearch')->willReturn($savedSearch);
$report->method('getAskAnythingPrompt')->willReturn($prompt);
$report->method('getUuid')->willReturn('report-uuid');
$reportResult = $this->createMock(AutomatedReportResult::class);
$reportResult->method('getUuid')->willReturn('result-uuid');
$reportResult->expects($this->once())
->method('update')
->with($this->callback(fn ($data) => $data['status'] === AutomatedReportResult::STATUS_REQUESTED
&& isset($data['name'], $data['payload'], $data['requested_at'])));
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->reportService->expects($this->once())
->method('createReportResult')
->willReturn($reportResult);
$this->reportService->expects($this->once())
->method('getAskJiminnyGenerateReportPayload')
->willReturn(['key' => 'value']);
$this->reportService->expects($this->once())
->method('getReportFileName')
->willReturn('My Report - 7 Apr 2026');
$this->activityService->expects($this->once())
->method('getActivityIdsForSavedSearch')
->willReturn(['act-1', 'act-2']);
$this->prophetClient->expects($this->once())
->method('sendRequest')
->willReturn(new \Jiminny\Component\ProphetAi\Dtos\ProphetResponseDto([]));
$this->logger->expects($this->exactly(4))
->method('info');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
Carbon::setTestNow();
}
public function testHandleCatchesGenericExceptionAndLogsError(): void
{
$this->reportService->expects($this->once())
->method('getReport')
->willThrowException(new \RuntimeException('DB error'));
$this->logger->expects($this->once())
->method('error')
->with($this->stringContains('Error'));
$job = $this->makeJob();
$reflection = new \ReflectionClass($job);
$triesProp = $reflection->getProperty('tries');
$triesProp->setAccessible(true);
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleCatchesProphetExceptionAndSetsCorrectReason(): void
{
$creator = $this->createMock(User::class);
$savedSearch = $this->createMock(\Jiminny\Models\Activity\Search::class);
$prompt = $this->createMock(\Jiminny\Models\AskAnything\AskAnythingPrompt::class);
$report = $this->makeActiveReport();
$report->method('getCreator')->willReturn($creator);
$report->method('getSavedSearch')->willReturn($savedSearch);
$report->method('getAskAnythingPrompt')->willReturn($prompt);
$reportResult = $this->createMock(AutomatedReportResult::class);
$reportResult->method('getUuid')->willReturn('result-uuid');
$reportResult->expects($this->once())
->method('update')
->with($this->callback(fn ($data) => $data['reason'] === AutomatedReportResult::REASON_PROPHET_API_ERROR));
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->reportService->expects($this->once())
->method('createReportResult')
->willReturn($reportResult);
$this->activityService->expects($this->once())
->method('getActivityIdsForSavedSearch')
->willThrowException(new ProphetException('Prophet failed'));
$this->logger->expects($this->once())
->method('error');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleCreatesReportResultBeforeActivityFetch(): void
{
$creator = $this->createMock(User::class);
$savedSearch = $this->createMock(\Jiminny\Models\Activity\Search::class);
$prompt = $this->createMock(\Jiminny\Models\AskAnything\AskAnythingPrompt::class);
$report = $this->makeActiveReport();
$report->method('getCreator')->willReturn($creator);
$report->method('getSavedSearch')->willReturn($savedSearch);
$report->method('getAskAnythingPrompt')->willReturn($prompt);
$reportResult = $this->createMock(AutomatedReportResult::class);
$reportResult->method('getUuid')->willReturn('result-uuid');
$callOrder = [];
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->reportService->expects($this->once())
->method('createReportResult')
->willReturnCallback(function () use ($reportResult, &$callOrder) {
$callOrder[] = 'createReportResult';
return $reportResult;
});
$this->activityService->expects($this->once())
->method('getActivityIdsForSavedSearch')
->willReturnCallback(function () use (&$callOrder) {
$callOrder[] = 'getActivityIds';
return [];
});
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
$this->assertEquals(['createReportResult', 'getActivityIds'], $callOrder);
}
public function testHandlePassesCorrectDataToCreateReportResult(): void
{
$creator = $this->createMock(User::class);
$savedSearch = $this->createMock(\Jiminny\Models\Activity\Search::class);
$prompt = $this->createMock(\Jiminny\Models\AskAnything\AskAnythingPrompt::class);
$report = $this->makeActiveReport();
$report->method('getCreator')->willReturn($creator);
$report->method('getSavedSearch')->willReturn($savedSearch);
$report->method('getAskAnythingPrompt')->willReturn($prompt);
$reportResult = $this->createMock(AutomatedReportResult::class);
$reportResult->method('getUuid')->willReturn('result-uuid');
$reportResult->method('update')->willReturn(true);
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->reportService->expects($this->once())
->method('createReportResult')
->with(
automatedReport: $report,
data: $this->callback(fn ($data) => $data['status'] === AutomatedReportResult::STATUS_DEFAULT
&& $data['media_type'] === AutomatedReportsService::MEDIA_TYPE_PDF)
)
->willReturn($reportResult);
$this->activityService->expects($this->once())
->method('getActivityIdsForSavedSearch')
->willReturn([]);
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"#11894 on JY-18909-automated-reports-ask-jiminny, menu","depth":5,"help_text":"Pull request #11894 exists for current branch JY-18909-automated-reports-ask-jiminny, but local branch is out of sync with remote","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"RequestGenerateAskJiminnyReportJobTest","depth":6,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'RequestGenerateAskJiminnyReportJobTest'","depth":6,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'RequestGenerateAskJiminnyReportJobTest'","depth":6,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Console\\Commands\\Reports;\n\nuse Carbon\\Carbon;\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Contracts\\Bus\\Dispatcher as BusDispatcher;\nuse Jiminny\\Jobs\\AutomatedReports\\RequestGenerateAskJiminnyReportJob;\nuse Jiminny\\Jobs\\AutomatedReports\\RequestGenerateReportJob;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Repositories\\AutomatedReportsRepository;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Psr\\Log\\LoggerInterface;\n\nclass AutomatedReportsCommand extends Command\n{\n /**\n * Log prefix for all log messages\n */\n private const string LOG_PREFIX = '[automated-reports]';\n\n /**\n * The name and signature of the console command.\n *\n * @var string\n */\n protected $signature = 'automated-reports';\n\n /**\n * The console command description.\n *\n * @var string\n */\n protected $description = 'Process automated reports based on their frequency (weekly, monthly, quarterly)';\n\n\n public function __construct(\n private readonly LoggerInterface $logger,\n private readonly BusDispatcher $dispatcher,\n private readonly AutomatedReportsRepository $reportRepository\n ) {\n parent::__construct();\n }\n\n /**\n * Execute the console command.\n *\n * @return int\n */\n public function handle(): int\n {\n $this->logger->info(self::LOG_PREFIX . ' Started');\n\n $now = Carbon::now();\n $isMonday = $now->isMonday();\n $isFirstDayOfMonth = $now->day === 1;\n $currentMonth = $now->month;\n\n // Check if the current month is a quarterly month (January, April, July, October)\n $isQuarterlyMonth = in_array($currentMonth, [1, 4, 7, 10], true);\n\n $this->logger->info(self::LOG_PREFIX . ' Checking conditions', [\n 'isMonday' => $isMonday,\n 'isFirstDayOfMonth' => $isFirstDayOfMonth,\n 'currentMonth' => $currentMonth,\n 'isQuarterlyMonth' => $isQuarterlyMonth,\n ]);\n\n // Process daily reports\n $this->processReports(AutomatedReportsService::FREQUENCY_DAILY);\n\n // Process weekly reports on Mondays\n if ($isMonday) {\n $this->processReports(AutomatedReportsService::FREQUENCY_WEEKLY);\n }\n\n // Process monthly reports on the first day of the month\n if ($isFirstDayOfMonth) {\n $this->processReports(AutomatedReportsService::FREQUENCY_MONTHLY);\n }\n\n // Process quarterly reports on the first day of January, April, July, and October\n if ($isFirstDayOfMonth && $isQuarterlyMonth) {\n $this->processReports(AutomatedReportsService::FREQUENCY_QUARTERLY);\n }\n\n $this->logger->info(self::LOG_PREFIX . ' Completed');\n\n return 0;\n }\n\n /**\n * Process reports for a specific frequency.\n *\n * @param string $frequency\n *\n * @return void\n */\n private function processReports(string $frequency): void\n {\n $this->logger->info(self::LOG_PREFIX . \" Processing $frequency reports\");\n\n // Get all enabled, not deleted reports with active teams for the specified frequency\n $reports = $this->reportRepository->getActiveReportsByFrequency($frequency);\n // $reports = collect([AutomatedReport::find(68)]);\n\n $this->logger->info(self::LOG_PREFIX . \" Found {$reports->count()} $frequency reports to process\");\n\n /** @var AutomatedReport $report */\n foreach ($reports as $report) {\n $this->logger->info(self::LOG_PREFIX . ' Dispatching Generate Report job for report', [\n 'reportUuid' => $report->getUuid(),\n 'teamId' => $report->getTeamId(),\n 'frequency' => $report->getFrequency(),\n 'type' => $report->getType(),\n ]);\n\n $job = $report->isAskJiminnyReport()\n ? new RequestGenerateAskJiminnyReportJob($report->getUuid())\n : new RequestGenerateReportJob($report->getUuid());\n\n // $this->dispatcher->dispatch($job);\n $this->dispatcher->dispatchSync($job);\n }\n }\n}","depth":4,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Console\\Commands\\Reports;\n\nuse Carbon\\Carbon;\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Contracts\\Bus\\Dispatcher as BusDispatcher;\nuse Jiminny\\Jobs\\AutomatedReports\\RequestGenerateAskJiminnyReportJob;\nuse Jiminny\\Jobs\\AutomatedReports\\RequestGenerateReportJob;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Repositories\\AutomatedReportsRepository;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Psr\\Log\\LoggerInterface;\n\nclass AutomatedReportsCommand extends Command\n{\n /**\n * Log prefix for all log messages\n */\n private const string LOG_PREFIX = '[automated-reports]';\n\n /**\n * The name and signature of the console command.\n *\n * @var string\n */\n protected $signature = 'automated-reports';\n\n /**\n * The console command description.\n *\n * @var string\n */\n protected $description = 'Process automated reports based on their frequency (weekly, monthly, quarterly)';\n\n\n public function __construct(\n private readonly LoggerInterface $logger,\n private readonly BusDispatcher $dispatcher,\n private readonly AutomatedReportsRepository $reportRepository\n ) {\n parent::__construct();\n }\n\n /**\n * Execute the console command.\n *\n * @return int\n */\n public function handle(): int\n {\n $this->logger->info(self::LOG_PREFIX . ' Started');\n\n $now = Carbon::now();\n $isMonday = $now->isMonday();\n $isFirstDayOfMonth = $now->day === 1;\n $currentMonth = $now->month;\n\n // Check if the current month is a quarterly month (January, April, July, October)\n $isQuarterlyMonth = in_array($currentMonth, [1, 4, 7, 10], true);\n\n $this->logger->info(self::LOG_PREFIX . ' Checking conditions', [\n 'isMonday' => $isMonday,\n 'isFirstDayOfMonth' => $isFirstDayOfMonth,\n 'currentMonth' => $currentMonth,\n 'isQuarterlyMonth' => $isQuarterlyMonth,\n ]);\n\n // Process daily reports\n $this->processReports(AutomatedReportsService::FREQUENCY_DAILY);\n\n // Process weekly reports on Mondays\n if ($isMonday) {\n $this->processReports(AutomatedReportsService::FREQUENCY_WEEKLY);\n }\n\n // Process monthly reports on the first day of the month\n if ($isFirstDayOfMonth) {\n $this->processReports(AutomatedReportsService::FREQUENCY_MONTHLY);\n }\n\n // Process quarterly reports on the first day of January, April, July, and October\n if ($isFirstDayOfMonth && $isQuarterlyMonth) {\n $this->processReports(AutomatedReportsService::FREQUENCY_QUARTERLY);\n }\n\n $this->logger->info(self::LOG_PREFIX . ' Completed');\n\n return 0;\n }\n\n /**\n * Process reports for a specific frequency.\n *\n * @param string $frequency\n *\n * @return void\n */\n private function processReports(string $frequency): void\n {\n $this->logger->info(self::LOG_PREFIX . \" Processing $frequency reports\");\n\n // Get all enabled, not deleted reports with active teams for the specified frequency\n $reports = $this->reportRepository->getActiveReportsByFrequency($frequency);\n // $reports = collect([AutomatedReport::find(68)]);\n\n $this->logger->info(self::LOG_PREFIX . \" Found {$reports->count()} $frequency reports to process\");\n\n /** @var AutomatedReport $report */\n foreach ($reports as $report) {\n $this->logger->info(self::LOG_PREFIX . ' Dispatching Generate Report job for report', [\n 'reportUuid' => $report->getUuid(),\n 'teamId' => $report->getTeamId(),\n 'frequency' => $report->getFrequency(),\n 'type' => $report->getType(),\n ]);\n\n $job = $report->isAskJiminnyReport()\n ? new RequestGenerateAskJiminnyReportJob($report->getUuid())\n : new RequestGenerateReportJob($report->getUuid());\n\n // $this->dispatcher->dispatch($job);\n $this->dispatcher->dispatchSync($job);\n }\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"1","depth":4,"role_description":"text"},{"role":"AXStaticText","text":"14","depth":4,"role_description":"text"},{"role":"AXStaticText","text":"4","depth":4,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Highlighted Error","depth":4,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Tests\\Unit\\Jobs\\AutomatedReports;\n\nuse Carbon\\Carbon;\nuse Jiminny\\Component\\ProphetAi\\Exceptions\\ProphetException;\nuse Jiminny\\Component\\ProphetAi\\ProphetClient;\nuse Jiminny\\Jobs\\AutomatedReports\\RequestGenerateAskJiminnyReportJob;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Models\\AutomatedReportResult;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AskJiminnyReportActivityService;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse PHPUnit\\Framework\\MockObject\\MockObject;\nuse PHPUnit\\Framework\\TestCase;\nuse Psr\\Log\\LoggerInterface;\n\nclass RequestGenerateAskJiminnyReportJobTest extends TestCase\n{\n private AutomatedReportsService&MockObject $reportService;\n private AskJiminnyReportActivityService&MockObject $activityService;\n private ProphetClient&MockObject $prophetClient;\n private LoggerInterface&MockObject $logger;\n\n protected function setUp(): void\n {\n $this->reportService = $this->createMock(AutomatedReportsService::class);\n $this->activityService = $this->createMock(AskJiminnyReportActivityService::class);\n $this->prophetClient = $this->createMock(ProphetClient::class);\n $this->logger = $this->createMock(LoggerInterface::class);\n }\n\n private function makeJob(string $uuid = 'report-uuid'): RequestGenerateAskJiminnyReportJob\n {\n return new RequestGenerateAskJiminnyReportJob($uuid);\n }\n\n private function makeActiveReport(\n string $type = AutomatedReportsService::TYPE_ASK_JIMINNY,\n bool $status = true,\n string $teamStatus = Team::STATUS_ACTIVE,\n ): AutomatedReport&MockObject { // @phpstan-ignore-line\n $team = $this->createMock(Team::class);\n $team->method('getStatus')->willReturn($teamStatus);\n\n $report = $this->createMock(AutomatedReport::class);\n $report->method('getType')->willReturn($type);\n $report->method('getStatus')->willReturn($status);\n $report->method('getTeam')->willReturn($team);\n\n return $report;\n }\n\n public function testUniqueIdReturnsReportUuid(): void\n {\n $job = $this->makeJob('my-unique-uuid');\n\n $this->assertEquals('my-unique-uuid', $job->uniqueId());\n }\n\n public function testHandleSkipsWhenReportTypeIsNotAskJiminny(): void\n {\n $report = $this->makeActiveReport(type: 'exec_summary');\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->logger->expects($this->once())\n ->method('info')\n ->with($this->stringContains('Started'));\n\n $this->logger->expects($this->once())\n ->method('warning')\n ->with($this->stringContains('not an ask_jiminny report'));\n\n $this->reportService->expects($this->never())->method('createReportResult');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleSkipsWhenReportIsInactive(): void\n {\n $report = $this->makeActiveReport(status: false);\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->logger->expects($this->exactly(2))\n ->method('info');\n\n $this->reportService->expects($this->never())->method('createReportResult');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleSkipsWhenTeamIsInactive(): void\n {\n $report = $this->makeActiveReport(teamStatus: Team::STATUS_DEACTIVATED);\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->logger->expects($this->exactly(2))\n ->method('info');\n\n $this->reportService->expects($this->never())->method('createReportResult');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleSkipsWhenCreatorIsNull(): void\n {\n $report = $this->makeActiveReport();\n $report->method('getCreator')->willReturn(null);\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->logger->expects($this->once())\n ->method('warning')\n ->with($this->stringContains('report creator not found'));\n\n $this->reportService->expects($this->never())->method('createReportResult');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleSkipsWhenSavedSearchIsNull(): void\n {\n $creator = $this->createMock(User::class);\n\n $report = $this->makeActiveReport();\n $report->method('getCreator')->willReturn($creator);\n $report->method('getSavedSearch')->willReturn(null);\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->logger->expects($this->once())\n ->method('warning')\n ->with($this->stringContains('saved search not found'));\n\n $this->reportService->expects($this->never())->method('createReportResult');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleSkipsWhenPromptIsNull(): void\n {\n $creator = $this->createMock(User::class);\n $savedSearch = $this->createMock(\\Jiminny\\Models\\Activity\\Search::class);\n\n $report = $this->makeActiveReport();\n $report->method('getCreator')->willReturn($creator);\n $report->method('getSavedSearch')->willReturn($savedSearch);\n $report->method('getAskAnythingPrompt')->willReturn(null);\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->logger->expects($this->once())\n ->method('warning')\n ->with($this->stringContains('ask anything prompt not found'));\n\n $this->reportService->expects($this->never())->method('createReportResult');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleFailsReportWhenNotEnoughActivities(): void\n {\n $creator = $this->createMock(User::class);\n $savedSearch = $this->createMock(\\Jiminny\\Models\\Activity\\Search::class);\n $prompt = $this->createMock(\\Jiminny\\Models\\AskAnything\\AskAnythingPrompt::class);\n\n $report = $this->makeActiveReport();\n $report->method('getCreator')->willReturn($creator);\n $report->method('getSavedSearch')->willReturn($savedSearch);\n $report->method('getAskAnythingPrompt')->willReturn($prompt);\n\n $reportResult = $this->createMock(AutomatedReportResult::class);\n $reportResult->expects($this->once())\n ->method('update')\n ->with($this->callback(fn ($data) => $data['status'] === AutomatedReportResult::STATUS_FAILED\n && $data['reason'] === AutomatedReportResult::REASON_NOT_ENOUGH_ACTIVITIES));\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->reportService->expects($this->once())\n ->method('createReportResult')\n ->willReturn($reportResult);\n\n $this->activityService->expects($this->once())\n ->method('getActivityIdsForSavedSearch')\n ->willReturn([]);\n\n $this->logger->expects($this->exactly(3))\n ->method('info');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleSuccessfullyRequestsReport(): void\n {\n Carbon::setTestNow(Carbon::parse('2026-04-07 10:00:00'));\n\n $creator = $this->createMock(User::class);\n $savedSearch = $this->createMock(\\Jiminny\\Models\\Activity\\Search::class);\n $prompt = $this->createMock(\\Jiminny\\Models\\AskAnything\\AskAnythingPrompt::class);\n\n $report = $this->makeActiveReport();\n $report->method('getCreator')->willReturn($creator);\n $report->method('getSavedSearch')->willReturn($savedSearch);\n $report->method('getAskAnythingPrompt')->willReturn($prompt);\n $report->method('getUuid')->willReturn('report-uuid');\n\n $reportResult = $this->createMock(AutomatedReportResult::class);\n $reportResult->method('getUuid')->willReturn('result-uuid');\n $reportResult->expects($this->once())\n ->method('update')\n ->with($this->callback(fn ($data) => $data['status'] === AutomatedReportResult::STATUS_REQUESTED\n && isset($data['name'], $data['payload'], $data['requested_at'])));\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->reportService->expects($this->once())\n ->method('createReportResult')\n ->willReturn($reportResult);\n\n $this->reportService->expects($this->once())\n ->method('getAskJiminnyGenerateReportPayload')\n ->willReturn(['key' => 'value']);\n\n $this->reportService->expects($this->once())\n ->method('getReportFileName')\n ->willReturn('My Report - 7 Apr 2026');\n\n $this->activityService->expects($this->once())\n ->method('getActivityIdsForSavedSearch')\n ->willReturn(['act-1', 'act-2']);\n\n $this->prophetClient->expects($this->once())\n ->method('sendRequest')\n ->willReturn(new \\Jiminny\\Component\\ProphetAi\\Dtos\\ProphetResponseDto([]));\n\n $this->logger->expects($this->exactly(4))\n ->method('info');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n\n Carbon::setTestNow();\n }\n\n public function testHandleCatchesGenericExceptionAndLogsError(): void\n {\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willThrowException(new \\RuntimeException('DB error'));\n\n $this->logger->expects($this->once())\n ->method('error')\n ->with($this->stringContains('Error'));\n\n $job = $this->makeJob();\n\n $reflection = new \\ReflectionClass($job);\n $triesProp = $reflection->getProperty('tries');\n $triesProp->setAccessible(true);\n\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleCatchesProphetExceptionAndSetsCorrectReason(): void\n {\n $creator = $this->createMock(User::class);\n $savedSearch = $this->createMock(\\Jiminny\\Models\\Activity\\Search::class);\n $prompt = $this->createMock(\\Jiminny\\Models\\AskAnything\\AskAnythingPrompt::class);\n\n $report = $this->makeActiveReport();\n $report->method('getCreator')->willReturn($creator);\n $report->method('getSavedSearch')->willReturn($savedSearch);\n $report->method('getAskAnythingPrompt')->willReturn($prompt);\n\n $reportResult = $this->createMock(AutomatedReportResult::class);\n $reportResult->method('getUuid')->willReturn('result-uuid');\n $reportResult->expects($this->once())\n ->method('update')\n ->with($this->callback(fn ($data) => $data['reason'] === AutomatedReportResult::REASON_PROPHET_API_ERROR));\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->reportService->expects($this->once())\n ->method('createReportResult')\n ->willReturn($reportResult);\n\n $this->activityService->expects($this->once())\n ->method('getActivityIdsForSavedSearch')\n ->willThrowException(new ProphetException('Prophet failed'));\n\n $this->logger->expects($this->once())\n ->method('error');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleCreatesReportResultBeforeActivityFetch(): void\n {\n $creator = $this->createMock(User::class);\n $savedSearch = $this->createMock(\\Jiminny\\Models\\Activity\\Search::class);\n $prompt = $this->createMock(\\Jiminny\\Models\\AskAnything\\AskAnythingPrompt::class);\n\n $report = $this->makeActiveReport();\n $report->method('getCreator')->willReturn($creator);\n $report->method('getSavedSearch')->willReturn($savedSearch);\n $report->method('getAskAnythingPrompt')->willReturn($prompt);\n\n $reportResult = $this->createMock(AutomatedReportResult::class);\n $reportResult->method('getUuid')->willReturn('result-uuid');\n\n $callOrder = [];\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->reportService->expects($this->once())\n ->method('createReportResult')\n ->willReturnCallback(function () use ($reportResult, &$callOrder) {\n $callOrder[] = 'createReportResult';\n\n return $reportResult;\n });\n\n $this->activityService->expects($this->once())\n ->method('getActivityIdsForSavedSearch')\n ->willReturnCallback(function () use (&$callOrder) {\n $callOrder[] = 'getActivityIds';\n\n return [];\n });\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n\n $this->assertEquals(['createReportResult', 'getActivityIds'], $callOrder);\n }\n\n public function testHandlePassesCorrectDataToCreateReportResult(): void\n {\n $creator = $this->createMock(User::class);\n $savedSearch = $this->createMock(\\Jiminny\\Models\\Activity\\Search::class);\n $prompt = $this->createMock(\\Jiminny\\Models\\AskAnything\\AskAnythingPrompt::class);\n\n $report = $this->makeActiveReport();\n $report->method('getCreator')->willReturn($creator);\n $report->method('getSavedSearch')->willReturn($savedSearch);\n $report->method('getAskAnythingPrompt')->willReturn($prompt);\n\n $reportResult = $this->createMock(AutomatedReportResult::class);\n $reportResult->method('getUuid')->willReturn('result-uuid');\n $reportResult->method('update')->willReturn(true);\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->reportService->expects($this->once())\n ->method('createReportResult')\n ->with(\n automatedReport: $report,\n data: $this->callback(fn ($data) => $data['status'] === AutomatedReportResult::STATUS_DEFAULT\n && $data['media_type'] === AutomatedReportsService::MEDIA_TYPE_PDF)\n )\n ->willReturn($reportResult);\n\n $this->activityService->expects($this->once())\n ->method('getActivityIdsForSavedSearch')\n ->willReturn([]);\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n}","depth":4,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Tests\\Unit\\Jobs\\AutomatedReports;\n\nuse Carbon\\Carbon;\nuse Jiminny\\Component\\ProphetAi\\Exceptions\\ProphetException;\nuse Jiminny\\Component\\ProphetAi\\ProphetClient;\nuse Jiminny\\Jobs\\AutomatedReports\\RequestGenerateAskJiminnyReportJob;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Models\\AutomatedReportResult;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AskJiminnyReportActivityService;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse PHPUnit\\Framework\\MockObject\\MockObject;\nuse PHPUnit\\Framework\\TestCase;\nuse Psr\\Log\\LoggerInterface;\n\nclass RequestGenerateAskJiminnyReportJobTest extends TestCase\n{\n private AutomatedReportsService&MockObject $reportService;\n private AskJiminnyReportActivityService&MockObject $activityService;\n private ProphetClient&MockObject $prophetClient;\n private LoggerInterface&MockObject $logger;\n\n protected function setUp(): void\n {\n $this->reportService = $this->createMock(AutomatedReportsService::class);\n $this->activityService = $this->createMock(AskJiminnyReportActivityService::class);\n $this->prophetClient = $this->createMock(ProphetClient::class);\n $this->logger = $this->createMock(LoggerInterface::class);\n }\n\n private function makeJob(string $uuid = 'report-uuid'): RequestGenerateAskJiminnyReportJob\n {\n return new RequestGenerateAskJiminnyReportJob($uuid);\n }\n\n private function makeActiveReport(\n string $type = AutomatedReportsService::TYPE_ASK_JIMINNY,\n bool $status = true,\n string $teamStatus = Team::STATUS_ACTIVE,\n ): AutomatedReport&MockObject { // @phpstan-ignore-line\n $team = $this->createMock(Team::class);\n $team->method('getStatus')->willReturn($teamStatus);\n\n $report = $this->createMock(AutomatedReport::class);\n $report->method('getType')->willReturn($type);\n $report->method('getStatus')->willReturn($status);\n $report->method('getTeam')->willReturn($team);\n\n return $report;\n }\n\n public function testUniqueIdReturnsReportUuid(): void\n {\n $job = $this->makeJob('my-unique-uuid');\n\n $this->assertEquals('my-unique-uuid', $job->uniqueId());\n }\n\n public function testHandleSkipsWhenReportTypeIsNotAskJiminny(): void\n {\n $report = $this->makeActiveReport(type: 'exec_summary');\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->logger->expects($this->once())\n ->method('info')\n ->with($this->stringContains('Started'));\n\n $this->logger->expects($this->once())\n ->method('warning')\n ->with($this->stringContains('not an ask_jiminny report'));\n\n $this->reportService->expects($this->never())->method('createReportResult');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleSkipsWhenReportIsInactive(): void\n {\n $report = $this->makeActiveReport(status: false);\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->logger->expects($this->exactly(2))\n ->method('info');\n\n $this->reportService->expects($this->never())->method('createReportResult');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleSkipsWhenTeamIsInactive(): void\n {\n $report = $this->makeActiveReport(teamStatus: Team::STATUS_DEACTIVATED);\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->logger->expects($this->exactly(2))\n ->method('info');\n\n $this->reportService->expects($this->never())->method('createReportResult');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleSkipsWhenCreatorIsNull(): void\n {\n $report = $this->makeActiveReport();\n $report->method('getCreator')->willReturn(null);\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->logger->expects($this->once())\n ->method('warning')\n ->with($this->stringContains('report creator not found'));\n\n $this->reportService->expects($this->never())->method('createReportResult');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleSkipsWhenSavedSearchIsNull(): void\n {\n $creator = $this->createMock(User::class);\n\n $report = $this->makeActiveReport();\n $report->method('getCreator')->willReturn($creator);\n $report->method('getSavedSearch')->willReturn(null);\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->logger->expects($this->once())\n ->method('warning')\n ->with($this->stringContains('saved search not found'));\n\n $this->reportService->expects($this->never())->method('createReportResult');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleSkipsWhenPromptIsNull(): void\n {\n $creator = $this->createMock(User::class);\n $savedSearch = $this->createMock(\\Jiminny\\Models\\Activity\\Search::class);\n\n $report = $this->makeActiveReport();\n $report->method('getCreator')->willReturn($creator);\n $report->method('getSavedSearch')->willReturn($savedSearch);\n $report->method('getAskAnythingPrompt')->willReturn(null);\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->logger->expects($this->once())\n ->method('warning')\n ->with($this->stringContains('ask anything prompt not found'));\n\n $this->reportService->expects($this->never())->method('createReportResult');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleFailsReportWhenNotEnoughActivities(): void\n {\n $creator = $this->createMock(User::class);\n $savedSearch = $this->createMock(\\Jiminny\\Models\\Activity\\Search::class);\n $prompt = $this->createMock(\\Jiminny\\Models\\AskAnything\\AskAnythingPrompt::class);\n\n $report = $this->makeActiveReport();\n $report->method('getCreator')->willReturn($creator);\n $report->method('getSavedSearch')->willReturn($savedSearch);\n $report->method('getAskAnythingPrompt')->willReturn($prompt);\n\n $reportResult = $this->createMock(AutomatedReportResult::class);\n $reportResult->expects($this->once())\n ->method('update')\n ->with($this->callback(fn ($data) => $data['status'] === AutomatedReportResult::STATUS_FAILED\n && $data['reason'] === AutomatedReportResult::REASON_NOT_ENOUGH_ACTIVITIES));\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->reportService->expects($this->once())\n ->method('createReportResult')\n ->willReturn($reportResult);\n\n $this->activityService->expects($this->once())\n ->method('getActivityIdsForSavedSearch')\n ->willReturn([]);\n\n $this->logger->expects($this->exactly(3))\n ->method('info');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleSuccessfullyRequestsReport(): void\n {\n Carbon::setTestNow(Carbon::parse('2026-04-07 10:00:00'));\n\n $creator = $this->createMock(User::class);\n $savedSearch = $this->createMock(\\Jiminny\\Models\\Activity\\Search::class);\n $prompt = $this->createMock(\\Jiminny\\Models\\AskAnything\\AskAnythingPrompt::class);\n\n $report = $this->makeActiveReport();\n $report->method('getCreator')->willReturn($creator);\n $report->method('getSavedSearch')->willReturn($savedSearch);\n $report->method('getAskAnythingPrompt')->willReturn($prompt);\n $report->method('getUuid')->willReturn('report-uuid');\n\n $reportResult = $this->createMock(AutomatedReportResult::class);\n $reportResult->method('getUuid')->willReturn('result-uuid');\n $reportResult->expects($this->once())\n ->method('update')\n ->with($this->callback(fn ($data) => $data['status'] === AutomatedReportResult::STATUS_REQUESTED\n && isset($data['name'], $data['payload'], $data['requested_at'])));\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->reportService->expects($this->once())\n ->method('createReportResult')\n ->willReturn($reportResult);\n\n $this->reportService->expects($this->once())\n ->method('getAskJiminnyGenerateReportPayload')\n ->willReturn(['key' => 'value']);\n\n $this->reportService->expects($this->once())\n ->method('getReportFileName')\n ->willReturn('My Report - 7 Apr 2026');\n\n $this->activityService->expects($this->once())\n ->method('getActivityIdsForSavedSearch')\n ->willReturn(['act-1', 'act-2']);\n\n $this->prophetClient->expects($this->once())\n ->method('sendRequest')\n ->willReturn(new \\Jiminny\\Component\\ProphetAi\\Dtos\\ProphetResponseDto([]));\n\n $this->logger->expects($this->exactly(4))\n ->method('info');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n\n Carbon::setTestNow();\n }\n\n public function testHandleCatchesGenericExceptionAndLogsError(): void\n {\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willThrowException(new \\RuntimeException('DB error'));\n\n $this->logger->expects($this->once())\n ->method('error')\n ->with($this->stringContains('Error'));\n\n $job = $this->makeJob();\n\n $reflection = new \\ReflectionClass($job);\n $triesProp = $reflection->getProperty('tries');\n $triesProp->setAccessible(true);\n\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleCatchesProphetExceptionAndSetsCorrectReason(): void\n {\n $creator = $this->createMock(User::class);\n $savedSearch = $this->createMock(\\Jiminny\\Models\\Activity\\Search::class);\n $prompt = $this->createMock(\\Jiminny\\Models\\AskAnything\\AskAnythingPrompt::class);\n\n $report = $this->makeActiveReport();\n $report->method('getCreator')->willReturn($creator);\n $report->method('getSavedSearch')->willReturn($savedSearch);\n $report->method('getAskAnythingPrompt')->willReturn($prompt);\n\n $reportResult = $this->createMock(AutomatedReportResult::class);\n $reportResult->method('getUuid')->willReturn('result-uuid');\n $reportResult->expects($this->once())\n ->method('update')\n ->with($this->callback(fn ($data) => $data['reason'] === AutomatedReportResult::REASON_PROPHET_API_ERROR));\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->reportService->expects($this->once())\n ->method('createReportResult')\n ->willReturn($reportResult);\n\n $this->activityService->expects($this->once())\n ->method('getActivityIdsForSavedSearch')\n ->willThrowException(new ProphetException('Prophet failed'));\n\n $this->logger->expects($this->once())\n ->method('error');\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n\n public function testHandleCreatesReportResultBeforeActivityFetch(): void\n {\n $creator = $this->createMock(User::class);\n $savedSearch = $this->createMock(\\Jiminny\\Models\\Activity\\Search::class);\n $prompt = $this->createMock(\\Jiminny\\Models\\AskAnything\\AskAnythingPrompt::class);\n\n $report = $this->makeActiveReport();\n $report->method('getCreator')->willReturn($creator);\n $report->method('getSavedSearch')->willReturn($savedSearch);\n $report->method('getAskAnythingPrompt')->willReturn($prompt);\n\n $reportResult = $this->createMock(AutomatedReportResult::class);\n $reportResult->method('getUuid')->willReturn('result-uuid');\n\n $callOrder = [];\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->reportService->expects($this->once())\n ->method('createReportResult')\n ->willReturnCallback(function () use ($reportResult, &$callOrder) {\n $callOrder[] = 'createReportResult';\n\n return $reportResult;\n });\n\n $this->activityService->expects($this->once())\n ->method('getActivityIdsForSavedSearch')\n ->willReturnCallback(function () use (&$callOrder) {\n $callOrder[] = 'getActivityIds';\n\n return [];\n });\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n\n $this->assertEquals(['createReportResult', 'getActivityIds'], $callOrder);\n }\n\n public function testHandlePassesCorrectDataToCreateReportResult(): void\n {\n $creator = $this->createMock(User::class);\n $savedSearch = $this->createMock(\\Jiminny\\Models\\Activity\\Search::class);\n $prompt = $this->createMock(\\Jiminny\\Models\\AskAnything\\AskAnythingPrompt::class);\n\n $report = $this->makeActiveReport();\n $report->method('getCreator')->willReturn($creator);\n $report->method('getSavedSearch')->willReturn($savedSearch);\n $report->method('getAskAnythingPrompt')->willReturn($prompt);\n\n $reportResult = $this->createMock(AutomatedReportResult::class);\n $reportResult->method('getUuid')->willReturn('result-uuid');\n $reportResult->method('update')->willReturn(true);\n\n $this->reportService->expects($this->once())\n ->method('getReport')\n ->willReturn($report);\n\n $this->reportService->expects($this->once())\n ->method('createReportResult')\n ->with(\n automatedReport: $report,\n data: $this->callback(fn ($data) => $data['status'] === AutomatedReportResult::STATUS_DEFAULT\n && $data['media_type'] === AutomatedReportsService::MEDIA_TYPE_PDF)\n )\n ->willReturn($reportResult);\n\n $this->activityService->expects($this->once())\n ->method('getActivityIdsForSavedSearch')\n ->willReturn([]);\n\n $job = $this->makeJob();\n $job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
8260492435066441110
|
8722295178528246161
|
idle
|
accessibility
|
NULL
|
Project: faVsco.js, menu
#11894 on JY-18909-automa Project: faVsco.js, menu
#11894 on JY-18909-automated-reports-ask-jiminny, menu
Start Listening for PHP Debug Connections
RequestGenerateAskJiminnyReportJobTest
Run 'RequestGenerateAskJiminnyReportJobTest'
Debug 'RequestGenerateAskJiminnyReportJobTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Console\Commands\Reports;
use Carbon\Carbon;
use Illuminate\Console\Command;
use Illuminate\Contracts\Bus\Dispatcher as BusDispatcher;
use Jiminny\Jobs\AutomatedReports\RequestGenerateAskJiminnyReportJob;
use Jiminny\Jobs\AutomatedReports\RequestGenerateReportJob;
use Jiminny\Models\AutomatedReport;
use Jiminny\Repositories\AutomatedReportsRepository;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Psr\Log\LoggerInterface;
class AutomatedReportsCommand extends Command
{
/**
* Log prefix for all log messages
*/
private const string LOG_PREFIX = '[automated-reports]';
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'automated-reports';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Process automated reports based on their frequency (weekly, monthly, quarterly)';
public function __construct(
private readonly LoggerInterface $logger,
private readonly BusDispatcher $dispatcher,
private readonly AutomatedReportsRepository $reportRepository
) {
parent::__construct();
}
/**
* Execute the console command.
*
* @return int
*/
public function handle(): int
{
$this->logger->info(self::LOG_PREFIX . ' Started');
$now = Carbon::now();
$isMonday = $now->isMonday();
$isFirstDayOfMonth = $now->day === 1;
$currentMonth = $now->month;
// Check if the current month is a quarterly month (January, April, July, October)
$isQuarterlyMonth = in_array($currentMonth, [1, 4, 7, 10], true);
$this->logger->info(self::LOG_PREFIX . ' Checking conditions', [
'isMonday' => $isMonday,
'isFirstDayOfMonth' => $isFirstDayOfMonth,
'currentMonth' => $currentMonth,
'isQuarterlyMonth' => $isQuarterlyMonth,
]);
// Process daily reports
$this->processReports(AutomatedReportsService::FREQUENCY_DAILY);
// Process weekly reports on Mondays
if ($isMonday) {
$this->processReports(AutomatedReportsService::FREQUENCY_WEEKLY);
}
// Process monthly reports on the first day of the month
if ($isFirstDayOfMonth) {
$this->processReports(AutomatedReportsService::FREQUENCY_MONTHLY);
}
// Process quarterly reports on the first day of January, April, July, and October
if ($isFirstDayOfMonth && $isQuarterlyMonth) {
$this->processReports(AutomatedReportsService::FREQUENCY_QUARTERLY);
}
$this->logger->info(self::LOG_PREFIX . ' Completed');
return 0;
}
/**
* Process reports for a specific frequency.
*
* @param string $frequency
*
* @return void
*/
private function processReports(string $frequency): void
{
$this->logger->info(self::LOG_PREFIX . " Processing $frequency reports");
// Get all enabled, not deleted reports with active teams for the specified frequency
$reports = $this->reportRepository->getActiveReportsByFrequency($frequency);
// $reports = collect([AutomatedReport::find(68)]);
$this->logger->info(self::LOG_PREFIX . " Found {$reports->count()} $frequency reports to process");
/** @var AutomatedReport $report */
foreach ($reports as $report) {
$this->logger->info(self::LOG_PREFIX . ' Dispatching Generate Report job for report', [
'reportUuid' => $report->getUuid(),
'teamId' => $report->getTeamId(),
'frequency' => $report->getFrequency(),
'type' => $report->getType(),
]);
$job = $report->isAskJiminnyReport()
? new RequestGenerateAskJiminnyReportJob($report->getUuid())
: new RequestGenerateReportJob($report->getUuid());
// $this->dispatcher->dispatch($job);
$this->dispatcher->dispatchSync($job);
}
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
1
14
4
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Tests\Unit\Jobs\AutomatedReports;
use Carbon\Carbon;
use Jiminny\Component\ProphetAi\Exceptions\ProphetException;
use Jiminny\Component\ProphetAi\ProphetClient;
use Jiminny\Jobs\AutomatedReports\RequestGenerateAskJiminnyReportJob;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\AutomatedReportResult;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Services\Kiosk\AutomatedReports\AskJiminnyReportActivityService;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
use Psr\Log\LoggerInterface;
class RequestGenerateAskJiminnyReportJobTest extends TestCase
{
private AutomatedReportsService&MockObject $reportService;
private AskJiminnyReportActivityService&MockObject $activityService;
private ProphetClient&MockObject $prophetClient;
private LoggerInterface&MockObject $logger;
protected function setUp(): void
{
$this->reportService = $this->createMock(AutomatedReportsService::class);
$this->activityService = $this->createMock(AskJiminnyReportActivityService::class);
$this->prophetClient = $this->createMock(ProphetClient::class);
$this->logger = $this->createMock(LoggerInterface::class);
}
private function makeJob(string $uuid = 'report-uuid'): RequestGenerateAskJiminnyReportJob
{
return new RequestGenerateAskJiminnyReportJob($uuid);
}
private function makeActiveReport(
string $type = AutomatedReportsService::TYPE_ASK_JIMINNY,
bool $status = true,
string $teamStatus = Team::STATUS_ACTIVE,
): AutomatedReport&MockObject { // @phpstan-ignore-line
$team = $this->createMock(Team::class);
$team->method('getStatus')->willReturn($teamStatus);
$report = $this->createMock(AutomatedReport::class);
$report->method('getType')->willReturn($type);
$report->method('getStatus')->willReturn($status);
$report->method('getTeam')->willReturn($team);
return $report;
}
public function testUniqueIdReturnsReportUuid(): void
{
$job = $this->makeJob('my-unique-uuid');
$this->assertEquals('my-unique-uuid', $job->uniqueId());
}
public function testHandleSkipsWhenReportTypeIsNotAskJiminny(): void
{
$report = $this->makeActiveReport(type: 'exec_summary');
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->logger->expects($this->once())
->method('info')
->with($this->stringContains('Started'));
$this->logger->expects($this->once())
->method('warning')
->with($this->stringContains('not an ask_jiminny report'));
$this->reportService->expects($this->never())->method('createReportResult');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleSkipsWhenReportIsInactive(): void
{
$report = $this->makeActiveReport(status: false);
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->logger->expects($this->exactly(2))
->method('info');
$this->reportService->expects($this->never())->method('createReportResult');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleSkipsWhenTeamIsInactive(): void
{
$report = $this->makeActiveReport(teamStatus: Team::STATUS_DEACTIVATED);
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->logger->expects($this->exactly(2))
->method('info');
$this->reportService->expects($this->never())->method('createReportResult');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleSkipsWhenCreatorIsNull(): void
{
$report = $this->makeActiveReport();
$report->method('getCreator')->willReturn(null);
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->logger->expects($this->once())
->method('warning')
->with($this->stringContains('report creator not found'));
$this->reportService->expects($this->never())->method('createReportResult');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleSkipsWhenSavedSearchIsNull(): void
{
$creator = $this->createMock(User::class);
$report = $this->makeActiveReport();
$report->method('getCreator')->willReturn($creator);
$report->method('getSavedSearch')->willReturn(null);
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->logger->expects($this->once())
->method('warning')
->with($this->stringContains('saved search not found'));
$this->reportService->expects($this->never())->method('createReportResult');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleSkipsWhenPromptIsNull(): void
{
$creator = $this->createMock(User::class);
$savedSearch = $this->createMock(\Jiminny\Models\Activity\Search::class);
$report = $this->makeActiveReport();
$report->method('getCreator')->willReturn($creator);
$report->method('getSavedSearch')->willReturn($savedSearch);
$report->method('getAskAnythingPrompt')->willReturn(null);
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->logger->expects($this->once())
->method('warning')
->with($this->stringContains('ask anything prompt not found'));
$this->reportService->expects($this->never())->method('createReportResult');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleFailsReportWhenNotEnoughActivities(): void
{
$creator = $this->createMock(User::class);
$savedSearch = $this->createMock(\Jiminny\Models\Activity\Search::class);
$prompt = $this->createMock(\Jiminny\Models\AskAnything\AskAnythingPrompt::class);
$report = $this->makeActiveReport();
$report->method('getCreator')->willReturn($creator);
$report->method('getSavedSearch')->willReturn($savedSearch);
$report->method('getAskAnythingPrompt')->willReturn($prompt);
$reportResult = $this->createMock(AutomatedReportResult::class);
$reportResult->expects($this->once())
->method('update')
->with($this->callback(fn ($data) => $data['status'] === AutomatedReportResult::STATUS_FAILED
&& $data['reason'] === AutomatedReportResult::REASON_NOT_ENOUGH_ACTIVITIES));
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->reportService->expects($this->once())
->method('createReportResult')
->willReturn($reportResult);
$this->activityService->expects($this->once())
->method('getActivityIdsForSavedSearch')
->willReturn([]);
$this->logger->expects($this->exactly(3))
->method('info');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleSuccessfullyRequestsReport(): void
{
Carbon::setTestNow(Carbon::parse('2026-04-07 10:00:00'));
$creator = $this->createMock(User::class);
$savedSearch = $this->createMock(\Jiminny\Models\Activity\Search::class);
$prompt = $this->createMock(\Jiminny\Models\AskAnything\AskAnythingPrompt::class);
$report = $this->makeActiveReport();
$report->method('getCreator')->willReturn($creator);
$report->method('getSavedSearch')->willReturn($savedSearch);
$report->method('getAskAnythingPrompt')->willReturn($prompt);
$report->method('getUuid')->willReturn('report-uuid');
$reportResult = $this->createMock(AutomatedReportResult::class);
$reportResult->method('getUuid')->willReturn('result-uuid');
$reportResult->expects($this->once())
->method('update')
->with($this->callback(fn ($data) => $data['status'] === AutomatedReportResult::STATUS_REQUESTED
&& isset($data['name'], $data['payload'], $data['requested_at'])));
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->reportService->expects($this->once())
->method('createReportResult')
->willReturn($reportResult);
$this->reportService->expects($this->once())
->method('getAskJiminnyGenerateReportPayload')
->willReturn(['key' => 'value']);
$this->reportService->expects($this->once())
->method('getReportFileName')
->willReturn('My Report - 7 Apr 2026');
$this->activityService->expects($this->once())
->method('getActivityIdsForSavedSearch')
->willReturn(['act-1', 'act-2']);
$this->prophetClient->expects($this->once())
->method('sendRequest')
->willReturn(new \Jiminny\Component\ProphetAi\Dtos\ProphetResponseDto([]));
$this->logger->expects($this->exactly(4))
->method('info');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
Carbon::setTestNow();
}
public function testHandleCatchesGenericExceptionAndLogsError(): void
{
$this->reportService->expects($this->once())
->method('getReport')
->willThrowException(new \RuntimeException('DB error'));
$this->logger->expects($this->once())
->method('error')
->with($this->stringContains('Error'));
$job = $this->makeJob();
$reflection = new \ReflectionClass($job);
$triesProp = $reflection->getProperty('tries');
$triesProp->setAccessible(true);
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleCatchesProphetExceptionAndSetsCorrectReason(): void
{
$creator = $this->createMock(User::class);
$savedSearch = $this->createMock(\Jiminny\Models\Activity\Search::class);
$prompt = $this->createMock(\Jiminny\Models\AskAnything\AskAnythingPrompt::class);
$report = $this->makeActiveReport();
$report->method('getCreator')->willReturn($creator);
$report->method('getSavedSearch')->willReturn($savedSearch);
$report->method('getAskAnythingPrompt')->willReturn($prompt);
$reportResult = $this->createMock(AutomatedReportResult::class);
$reportResult->method('getUuid')->willReturn('result-uuid');
$reportResult->expects($this->once())
->method('update')
->with($this->callback(fn ($data) => $data['reason'] === AutomatedReportResult::REASON_PROPHET_API_ERROR));
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->reportService->expects($this->once())
->method('createReportResult')
->willReturn($reportResult);
$this->activityService->expects($this->once())
->method('getActivityIdsForSavedSearch')
->willThrowException(new ProphetException('Prophet failed'));
$this->logger->expects($this->once())
->method('error');
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
public function testHandleCreatesReportResultBeforeActivityFetch(): void
{
$creator = $this->createMock(User::class);
$savedSearch = $this->createMock(\Jiminny\Models\Activity\Search::class);
$prompt = $this->createMock(\Jiminny\Models\AskAnything\AskAnythingPrompt::class);
$report = $this->makeActiveReport();
$report->method('getCreator')->willReturn($creator);
$report->method('getSavedSearch')->willReturn($savedSearch);
$report->method('getAskAnythingPrompt')->willReturn($prompt);
$reportResult = $this->createMock(AutomatedReportResult::class);
$reportResult->method('getUuid')->willReturn('result-uuid');
$callOrder = [];
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->reportService->expects($this->once())
->method('createReportResult')
->willReturnCallback(function () use ($reportResult, &$callOrder) {
$callOrder[] = 'createReportResult';
return $reportResult;
});
$this->activityService->expects($this->once())
->method('getActivityIdsForSavedSearch')
->willReturnCallback(function () use (&$callOrder) {
$callOrder[] = 'getActivityIds';
return [];
});
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
$this->assertEquals(['createReportResult', 'getActivityIds'], $callOrder);
}
public function testHandlePassesCorrectDataToCreateReportResult(): void
{
$creator = $this->createMock(User::class);
$savedSearch = $this->createMock(\Jiminny\Models\Activity\Search::class);
$prompt = $this->createMock(\Jiminny\Models\AskAnything\AskAnythingPrompt::class);
$report = $this->makeActiveReport();
$report->method('getCreator')->willReturn($creator);
$report->method('getSavedSearch')->willReturn($savedSearch);
$report->method('getAskAnythingPrompt')->willReturn($prompt);
$reportResult = $this->createMock(AutomatedReportResult::class);
$reportResult->method('getUuid')->willReturn('result-uuid');
$reportResult->method('update')->willReturn(true);
$this->reportService->expects($this->once())
->method('getReport')
->willReturn($report);
$this->reportService->expects($this->once())
->method('createReportResult')
->with(
automatedReport: $report,
data: $this->callback(fn ($data) => $data['status'] === AutomatedReportResult::STATUS_DEFAULT
&& $data['media_type'] === AutomatedReportsService::MEDIA_TYPE_PDF)
)
->willReturn($reportResult);
$this->activityService->expects($this->once())
->method('getActivityIdsForSavedSearch')
->willReturn([]);
$job = $this->makeJob();
$job->handle($this->reportService, $this->activityService, $this->prophetClient, $this->logger);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
9497
|
|
7628
|
143
|
11
|
2026-04-13T16:14:05.984397+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-13/1776 /Users/lukas/.screenpipe/data/data/2026-04-13/1776096845984_m1.jpg...
|
Firefox
|
google maps timeline export - Google Search — Pers google maps timeline export - Google Search — Personal...
|
True
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
DXP4800PLUS-B5F8
Inbox - [EMAIL] - Gmail
Like Fat DXP4800PLUS-B5F8
Inbox - [EMAIL] - Gmail
Like Father, Like Daughter • HBO Max
Like Father, Like Daughter • HBO Max
Proeurópska bublina si po Orbánovom páde vydýchla, víťazná Tisza však môže Brusel prekvapiť — Denník N
Proeurópska bublina si po Orbánovom páde vydýchla, víťazná Tisza však môže Brusel prekvapiť — Denník N
Machines - Tailscale
Machines - Tailscale
Screenpipe Dashboard
Screenpipe Dashboard
Western Digital Red Plus 3.5 6TB 5400rpm 256MB SATA3 (WD60EFPX) от 239,76 € (468,93 лв.) Вътрешен хард диск Western Digital - Pazaruvaj.com
Western Digital Red Plus 3.5 6TB 5400rpm 256MB SATA3 (WD60EFPX) от 239,76 € (468,93 лв.) Вътрешен хард диск Western Digital - Pazaruvaj.com
Поръчка
Поръчка
Screenpipe: Open Source 24/7 Screen & Audio Capture : r/software
Screenpipe: Open Source 24/7 Screen & Audio Capture : r/software
google maps timeline export - Google Search
google maps timeline export - Google Search
Close tab
New Tab
Customize sidebar
Close Google Gemini (⌃X)
Open history (⇧⌘H)
Open bookmarks (⌘B)
Bitwarden
AI Chat settings
Close
Google Account: Lukáš Koválik ([EMAIL])
Main menu
New chat
Gemini
Temporary chat
PLUS
PLUS
Conversation with Gemini
Conversation with Gemini
Hi Lukáš
Where should we start?
Where should we start?
🖼️ Create image, button, tap to use tool
🖼️ Create image
🎸 Create music, button, tap to use tool
🎸 Create music
Create a video, button, tap to use tool
Create a video
Help me learn, button, tap to use tool
Help me learn
Write anything, button, tap to use tool
Write anything
Boost my day, button, tap to use tool
Boost my day
using screenpipe I want to watch videos but it seems that it is not possible on f
using screenpipe I want to watch videos but it seems that it is not possible on f
Open upload file menu
Tools
Open mode picker
Pro
Send message
Summarize page
Summarize page
Skip to main content
Skip to main content
Accessibility help
Accessibility help
Accessibility feedback
Accessibility feedback
Go to Google Home
google maps timeline export
google maps timeline export
Clear
Search by voice
Search by image
Search
Google apps
Google Account: Lukáš Koválik ([EMAIL])
AI Mode
AI Mode
All
All
Images
Images
Videos
Videos
Forums
Forums
News
News
Web
Web
More filters
More
Tools
Tools
Add Free
Free
Add Reddit
Reddit
Add To Excel
To Excel
Add GPX
GPX
Add Ios
Ios
Add To KML
To KML
Add Android
Android
Search Results
Search Results
AI Overview
AI Overview
About this result
Exporting Google Maps Timeline data is now primarily done on-device via Android settings, as location history has moved from cloud storage to local device storage
.
Navigate to
Settings > Location > Location services > Timeline
and tap "Export timeline data" to save a local JSON file
. This ensures you have a backup of your visited places and routes.
Google Help (+4) – View related links
Google Help
+4
How to Export Timeline Data
Android (On-Device):
Open Device
Settings
.
Tap
Location
>
Location Services
>
Timeline
.
Select
Export timeline data
.
Select a storage location and save as a JSON file.
Alternative Android Method:
Go to
Google Maps App
>
Account Circle
>
Your Timeline
>
Menu (three dots)
>
Export
.
Backup Method:
Turn on the "Backup" setting in
Your Timeline
to save data to the cloud.
Google Help (+4) – View related links
Important Information
Data Format:
The exported data is in a JSON format.
Processing Data:
For easier viewing, you may need a converter to turn the JSON into KML format
.
Third-Party Tools:
You can use
Free Google Maps Timeline Export to Excel
Free Google Maps Timeline Export to Excel
to visualize the data, or see
this GitHub repository
this GitHub repository
for conversion scripts.
Desktop Limitation:
As of 2025, Google Takeout may not contain current location history data.
For in-depth, user-driven, and detailed information about exporting timeline data, see
the Google Maps community thread
the Google Maps community thread
.
For in-depth, user-driven, and detailed information about exporting Google Maps timeline data on Android, see
the Reddit thread
the Reddit thread
.
For detailed instructions and tips on using a
Google Maps multi-day timeline
, please refer to the
Medium article
Medium article
.
View related links
Export timeline data. Opens in new tab....
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"DXP4800PLUS-B5F8","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Inbox - kovaliklukas@gmail.com - Gmail","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Like Father, Like Daughter • HBO Max","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Like Father, Like Daughter • HBO Max","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Proeurópska bublina si po Orbánovom páde vydýchla, víťazná Tisza však môže Brusel prekvapiť — Denník N","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Proeurópska bublina si po Orbánovom páde vydýchla, víťazná Tisza však môže Brusel prekvapiť — Denník N","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Machines - Tailscale","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Machines - Tailscale","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Screenpipe Dashboard","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Screenpipe Dashboard","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Western Digital Red Plus 3.5 6TB 5400rpm 256MB SATA3 (WD60EFPX) от 239,76 € (468,93 лв.) Вътрешен хард диск Western Digital - Pazaruvaj.com","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Western Digital Red Plus 3.5 6TB 5400rpm 256MB SATA3 (WD60EFPX) от 239,76 € (468,93 лв.) Вътрешен хард диск Western Digital - Pazaruvaj.com","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Поръчка","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Поръчка","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Screenpipe: Open Source 24/7 Screen & Audio Capture : r/software","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Screenpipe: Open Source 24/7 Screen & Audio Capture : r/software","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"google maps timeline export - Google Search","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"google maps timeline export - Google Search","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Tab","depth":4,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Close Google Gemini (⌃X)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Bitwarden","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"AI Chat settings","depth":7,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Close","depth":7,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Google Account: Lukáš Koválik (kovaliklukas@gmail.com)","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Main menu","depth":12,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New chat","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Gemini","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Temporary chat","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"PLUS","depth":11,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"PLUS","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Conversation with Gemini","depth":15,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Conversation with Gemini","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Hi Lukáš","depth":23,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Where should we start?","depth":22,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Where should we start?","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"🖼️ Create image, button, tap to use tool","depth":22,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"🖼️ Create image","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"🎸 Create music, button, tap to use tool","depth":22,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"🎸 Create music","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Create a video, button, tap to use tool","depth":22,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Create a video","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Help me learn, button, tap to use tool","depth":22,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Help me learn","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Write anything, button, tap to use tool","depth":22,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Write anything","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Boost my day, button, tap to use tool","depth":22,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Boost my day","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextArea","text":"using screenpipe I want to watch videos but it seems that it is not possible on f","depth":20,"value":"using screenpipe I want to watch videos but it seems that it is not possible on f","help_text":"","role_description":"text entry area","subrole":"AXUnknown","is_enabled":true,"is_focused":true,"is_selected":false},{"role":"AXStaticText","text":"using screenpipe I want to watch videos but it seems that it is not possible on f","depth":22,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open upload file menu","depth":20,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Tools","depth":18,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Open mode picker","depth":20,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pro","depth":23,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Send message","depth":19,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Summarize page","depth":7,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Summarize page","depth":9,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Skip to main content","depth":7,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip to main content","depth":8,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Accessibility help","depth":7,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Accessibility help","depth":8,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Accessibility feedback","depth":7,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Accessibility feedback","depth":8,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Go to Google Home","depth":10,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXComboBox","text":"google maps timeline export","depth":9,"value":"google maps timeline export","help_text":"","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"google maps timeline export","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Clear","depth":9,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Search by voice","depth":9,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Search by image","depth":9,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Search","depth":9,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Google apps","depth":9,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXMenuButton","text":"Google Account: Lukáš Koválik (kovaliklukas@gmail.com)","depth":8,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"AI Mode","depth":16,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"AI Mode","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"All","depth":16,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"All","depth":19,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Images","depth":16,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Images","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Videos","depth":16,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Videos","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Forums","depth":16,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Forums","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"News","depth":16,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"News","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Web","depth":16,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Web","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"More filters","depth":16,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"More","depth":19,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Tools","depth":15,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Tools","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Add Free","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Free","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Add Reddit","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Reddit","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Add To Excel","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"To Excel","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Add GPX","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"GPX","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Add Ios","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Ios","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Add To KML","depth":15,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"To KML","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Add Android","depth":15,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Android","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Search Results","depth":8,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Search Results","depth":9,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"AI Overview","depth":20,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"AI Overview","depth":21,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"About this result","depth":21,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Exporting Google Maps Timeline data is now primarily done on-device via Android settings, as location history has moved from cloud storage to local device storage","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Navigate to","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Settings > Location > Location services > Timeline","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"and tap \"Export timeline data\" to save a local JSON file","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":". This ensures you have a backup of your visited places and routes.","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Google Help (+4) – View related links","depth":25,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Google Help","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"+4","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"How to Export Timeline Data","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Android (On-Device):","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Open Device","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Settings","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Tap","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Location","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":">","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Location Services","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":">","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Timeline","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Select","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Export timeline data","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Select a storage location and save as a JSON file.","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Alternative Android Method:","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Go to","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Google Maps App","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":">","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Account Circle","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":">","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Your Timeline","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":">","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Menu (three dots)","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":">","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Export","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Backup Method:","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Turn on the \"Backup\" setting in","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Your Timeline","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"to save data to the cloud.","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Google Help (+4) – View related links","depth":26,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Important Information","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Data Format:","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"The exported data is in a JSON format.","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Processing Data:","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"For easier viewing, you may need a converter to turn the JSON into KML format","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Third-Party Tools:","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"You can use","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Free Google Maps Timeline Export to Excel","depth":26,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Free Google Maps Timeline Export to Excel","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"to visualize the data, or see","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"this GitHub repository","depth":26,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"this GitHub repository","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"for conversion scripts.","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Desktop Limitation:","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"As of 2025, Google Takeout may not contain current location history data.","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"For in-depth, user-driven, and detailed information about exporting timeline data, see","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"the Google Maps community thread","depth":26,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"the Google Maps community thread","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"For in-depth, user-driven, and detailed information about exporting Google Maps timeline data on Android, see","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"the Reddit thread","depth":26,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"the Reddit thread","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"For detailed instructions and tips on using a","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Google Maps multi-day timeline","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":", please refer to the","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Medium article","depth":26,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Medium article","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":26,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"View related links","depth":26,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Export timeline data. Opens in new tab.","depth":28,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false}]...
|
9158766048139113389
|
8717210057888795218
|
idle
|
accessibility
|
NULL
|
DXP4800PLUS-B5F8
Inbox - [EMAIL] - Gmail
Like Fat DXP4800PLUS-B5F8
Inbox - [EMAIL] - Gmail
Like Father, Like Daughter • HBO Max
Like Father, Like Daughter • HBO Max
Proeurópska bublina si po Orbánovom páde vydýchla, víťazná Tisza však môže Brusel prekvapiť — Denník N
Proeurópska bublina si po Orbánovom páde vydýchla, víťazná Tisza však môže Brusel prekvapiť — Denník N
Machines - Tailscale
Machines - Tailscale
Screenpipe Dashboard
Screenpipe Dashboard
Western Digital Red Plus 3.5 6TB 5400rpm 256MB SATA3 (WD60EFPX) от 239,76 € (468,93 лв.) Вътрешен хард диск Western Digital - Pazaruvaj.com
Western Digital Red Plus 3.5 6TB 5400rpm 256MB SATA3 (WD60EFPX) от 239,76 € (468,93 лв.) Вътрешен хард диск Western Digital - Pazaruvaj.com
Поръчка
Поръчка
Screenpipe: Open Source 24/7 Screen & Audio Capture : r/software
Screenpipe: Open Source 24/7 Screen & Audio Capture : r/software
google maps timeline export - Google Search
google maps timeline export - Google Search
Close tab
New Tab
Customize sidebar
Close Google Gemini (⌃X)
Open history (⇧⌘H)
Open bookmarks (⌘B)
Bitwarden
AI Chat settings
Close
Google Account: Lukáš Koválik ([EMAIL])
Main menu
New chat
Gemini
Temporary chat
PLUS
PLUS
Conversation with Gemini
Conversation with Gemini
Hi Lukáš
Where should we start?
Where should we start?
🖼️ Create image, button, tap to use tool
🖼️ Create image
🎸 Create music, button, tap to use tool
🎸 Create music
Create a video, button, tap to use tool
Create a video
Help me learn, button, tap to use tool
Help me learn
Write anything, button, tap to use tool
Write anything
Boost my day, button, tap to use tool
Boost my day
using screenpipe I want to watch videos but it seems that it is not possible on f
using screenpipe I want to watch videos but it seems that it is not possible on f
Open upload file menu
Tools
Open mode picker
Pro
Send message
Summarize page
Summarize page
Skip to main content
Skip to main content
Accessibility help
Accessibility help
Accessibility feedback
Accessibility feedback
Go to Google Home
google maps timeline export
google maps timeline export
Clear
Search by voice
Search by image
Search
Google apps
Google Account: Lukáš Koválik ([EMAIL])
AI Mode
AI Mode
All
All
Images
Images
Videos
Videos
Forums
Forums
News
News
Web
Web
More filters
More
Tools
Tools
Add Free
Free
Add Reddit
Reddit
Add To Excel
To Excel
Add GPX
GPX
Add Ios
Ios
Add To KML
To KML
Add Android
Android
Search Results
Search Results
AI Overview
AI Overview
About this result
Exporting Google Maps Timeline data is now primarily done on-device via Android settings, as location history has moved from cloud storage to local device storage
.
Navigate to
Settings > Location > Location services > Timeline
and tap "Export timeline data" to save a local JSON file
. This ensures you have a backup of your visited places and routes.
Google Help (+4) – View related links
Google Help
+4
How to Export Timeline Data
Android (On-Device):
Open Device
Settings
.
Tap
Location
>
Location Services
>
Timeline
.
Select
Export timeline data
.
Select a storage location and save as a JSON file.
Alternative Android Method:
Go to
Google Maps App
>
Account Circle
>
Your Timeline
>
Menu (three dots)
>
Export
.
Backup Method:
Turn on the "Backup" setting in
Your Timeline
to save data to the cloud.
Google Help (+4) – View related links
Important Information
Data Format:
The exported data is in a JSON format.
Processing Data:
For easier viewing, you may need a converter to turn the JSON into KML format
.
Third-Party Tools:
You can use
Free Google Maps Timeline Export to Excel
Free Google Maps Timeline Export to Excel
to visualize the data, or see
this GitHub repository
this GitHub repository
for conversion scripts.
Desktop Limitation:
As of 2025, Google Takeout may not contain current location history data.
For in-depth, user-driven, and detailed information about exporting timeline data, see
the Google Maps community thread
the Google Maps community thread
.
For in-depth, user-driven, and detailed information about exporting Google Maps timeline data on Android, see
the Reddit thread
the Reddit thread
.
For detailed instructions and tips on using a
Google Maps multi-day timeline
, please refer to the
Medium article
Medium article
.
View related links
Export timeline data. Opens in new tab....
|
7627
|
|
14354
|
323
|
21
|
2026-04-14T13:44:02.567426+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776174242567_m2.jpg...
|
PhpStorm
|
|
True
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project Files
Preview
Filter
Open in Find Tool Win Project Files
Preview
Filter
Open in Find Tool Window
repositor
Repositories app/Repositories
Repositories app/Component/AiCallScoring/Repositories
Repositories app/Services/Mail/Repositories
Repositories tests/Unit/Repositories
Repositories app/Contracts/Repositories
Repositories app/Component/AiAutomation/Repositories
Repositories app/Component/BillingManagement/Repositories
Repositories app/Component/ES/Repositories
Repositories tests/Feature/Repositories
Repositories build/coverage/Repositories
Repositories build/coverage/Contracts/Repositories
Repositories build/coverage/Component/BillingManagement/Repositories
Repository app/VO/Repository
Repository app/Component/ActivityAnalytics/Repository
Repository app/Component/MobileSettings/Repository
… more
Repositories app/Repositories
Repositories app/Component/AiCallScoring/Repositories
Repositories app/Services/Mail/Repositories
Repositories tests/Unit/Repositories
Repositories app/Contracts/Repositories
Repositories app/Component/AiAutomation/Repositories
Repositories app/Component/BillingManagement/Repositories
Repositories app/Component/ES/Repositories
Repositories tests/Feature/Repositories
Repositories build/coverage/Repositories
Repositories build/coverage/Contracts/Repositories
Repositories build/coverage/Component/BillingManagement/Repositories
Repository app/VO/Repository
Repository app/Component/ActivityAnalytics/Repository
Repository app/Component/MobileSettings/Repository
… more
Repositories
Open In Right Split...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project Files","depth":2,"bounds":{"left":0.6855469,"top":0.23888889,"width":0.041796874,"height":0.016666668},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Preview","depth":2,"bounds":{"left":0.72734374,"top":0.23888889,"width":0.01015625,"height":0.016666668},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Filter","depth":2,"bounds":{"left":0.7375,"top":0.23888889,"width":0.01015625,"height":0.016666668},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Open in Find Tool Window","depth":2,"bounds":{"left":0.7476562,"top":0.23888889,"width":0.01015625,"height":0.016666668},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextField","text":"repositor","depth":1,"bounds":{"left":0.50273436,"top":0.26527777,"width":0.25507814,"height":0.02013889},"value":"repositor","role_description":"text field","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Repositories app/Repositories","depth":2,"bounds":{"left":0.49921876,"top":0.29305556,"width":0.26210937,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"Repositories app/Component/AiCallScoring/Repositories","depth":2,"bounds":{"left":0.49921876,"top":0.30833334,"width":0.26210937,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"Repositories app/Services/Mail/Repositories","depth":2,"bounds":{"left":0.49921876,"top":0.3236111,"width":0.26210937,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"Repositories tests/Unit/Repositories","depth":2,"bounds":{"left":0.49921876,"top":0.33888888,"width":0.26210937,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"Repositories app/Contracts/Repositories","depth":2,"bounds":{"left":0.49921876,"top":0.35416666,"width":0.26210937,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"Repositories app/Component/AiAutomation/Repositories","depth":2,"bounds":{"left":0.49921876,"top":0.36944443,"width":0.26210937,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"Repositories app/Component/BillingManagement/Repositories","depth":2,"bounds":{"left":0.49921876,"top":0.38472223,"width":0.26210937,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"Repositories app/Component/ES/Repositories","depth":2,"bounds":{"left":0.49921876,"top":0.4,"width":0.26210937,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"Repositories tests/Feature/Repositories","depth":2,"bounds":{"left":0.49921876,"top":0.41527778,"width":0.26210937,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"Repositories build/coverage/Repositories","depth":2,"bounds":{"left":0.49921876,"top":0.43055555,"width":0.26210937,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"Repositories build/coverage/Contracts/Repositories","depth":2,"bounds":{"left":0.49921876,"top":0.44583333,"width":0.26210937,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"Repositories build/coverage/Component/BillingManagement/Repositories","depth":2,"bounds":{"left":0.49921876,"top":0.4611111,"width":0.26210937,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"Repository app/VO/Repository","depth":2,"bounds":{"left":0.49921876,"top":0.4763889,"width":0.26210937,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"Repository app/Component/ActivityAnalytics/Repository","depth":2,"bounds":{"left":0.49921876,"top":0.49166667,"width":0.26210937,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"Repository app/Component/MobileSettings/Repository","depth":2,"bounds":{"left":0.49921876,"top":0.5069444,"width":0.26210937,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"… more","depth":2,"bounds":{"left":0.49921876,"top":0.5222222,"width":0.26210937,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"Repositories app/Repositories","depth":4,"bounds":{"left":0.49921876,"top":0.29305556,"width":0.26210937,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"Repositories app/Component/AiCallScoring/Repositories","depth":4,"bounds":{"left":0.49921876,"top":0.30833334,"width":0.26210937,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"Repositories app/Services/Mail/Repositories","depth":4,"bounds":{"left":0.49921876,"top":0.3236111,"width":0.26210937,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"Repositories tests/Unit/Repositories","depth":4,"bounds":{"left":0.49921876,"top":0.33888888,"width":0.26210937,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"Repositories app/Contracts/Repositories","depth":4,"bounds":{"left":0.49921876,"top":0.35416666,"width":0.26210937,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"Repositories app/Component/AiAutomation/Repositories","depth":4,"bounds":{"left":0.49921876,"top":0.36944443,"width":0.26210937,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"Repositories app/Component/BillingManagement/Repositories","depth":4,"bounds":{"left":0.49921876,"top":0.38472223,"width":0.26210937,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"Repositories app/Component/ES/Repositories","depth":4,"bounds":{"left":0.49921876,"top":0.4,"width":0.26210937,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"Repositories tests/Feature/Repositories","depth":4,"bounds":{"left":0.49921876,"top":0.41527778,"width":0.26210937,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"Repositories build/coverage/Repositories","depth":4,"bounds":{"left":0.49921876,"top":0.43055555,"width":0.26210937,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"Repositories build/coverage/Contracts/Repositories","depth":4,"bounds":{"left":0.49921876,"top":0.44583333,"width":0.26210937,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"Repositories build/coverage/Component/BillingManagement/Repositories","depth":4,"bounds":{"left":0.49921876,"top":0.4611111,"width":0.26210937,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"Repository app/VO/Repository","depth":4,"bounds":{"left":0.49921876,"top":0.4763889,"width":0.26210937,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"Repository app/Component/ActivityAnalytics/Repository","depth":4,"bounds":{"left":0.49921876,"top":0.49166667,"width":0.26210937,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"Repository app/Component/MobileSettings/Repository","depth":4,"bounds":{"left":0.49921876,"top":0.5069444,"width":0.26210937,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"… more","depth":4,"bounds":{"left":0.49921876,"top":0.5222222,"width":0.26210937,"height":0.015277778},"role_description":"text"},{"role":"AXStaticText","text":"Repositories","depth":1,"bounds":{"left":0.50703126,"top":0.7548611,"width":0.02734375,"height":0.011805556},"help_text":"Repositories","role_description":"text"},{"role":"AXLink","text":"Open In Right Split","depth":1,"bounds":{"left":0.7066406,"top":0.7548611,"width":0.0453125,"height":0.011805556},"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
-8770403163097921490
|
8716627605792489487
|
visual_change
|
accessibility
|
NULL
|
Project Files
Preview
Filter
Open in Find Tool Win Project Files
Preview
Filter
Open in Find Tool Window
repositor
Repositories app/Repositories
Repositories app/Component/AiCallScoring/Repositories
Repositories app/Services/Mail/Repositories
Repositories tests/Unit/Repositories
Repositories app/Contracts/Repositories
Repositories app/Component/AiAutomation/Repositories
Repositories app/Component/BillingManagement/Repositories
Repositories app/Component/ES/Repositories
Repositories tests/Feature/Repositories
Repositories build/coverage/Repositories
Repositories build/coverage/Contracts/Repositories
Repositories build/coverage/Component/BillingManagement/Repositories
Repository app/VO/Repository
Repository app/Component/ActivityAnalytics/Repository
Repository app/Component/MobileSettings/Repository
… more
Repositories app/Repositories
Repositories app/Component/AiCallScoring/Repositories
Repositories app/Services/Mail/Repositories
Repositories tests/Unit/Repositories
Repositories app/Contracts/Repositories
Repositories app/Component/AiAutomation/Repositories
Repositories app/Component/BillingManagement/Repositories
Repositories app/Component/ES/Repositories
Repositories tests/Feature/Repositories
Repositories build/coverage/Repositories
Repositories build/coverage/Contracts/Repositories
Repositories build/coverage/Component/BillingManagement/Repositories
Repository app/VO/Repository
Repository app/Component/ActivityAnalytics/Repository
Repository app/Component/MobileSettings/Repository
… more
Repositories
Open In Right Split...
|
14353
|
|
80622
|
2129
|
14
|
2026-04-25T14:30:46.960727+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-25/1777 /Users/lukas/.screenpipe/data/data/2026-04-25/1777127446960_m1.jpg...
|
Firefox
|
Screenpipe — Archive — Personal
|
True
|
http://192.168.0.242:8766
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
DXP4800PLUS-B5F8
5 Signs You Have Successfully Hur DXP4800PLUS-B5F8
5 Signs You Have Successfully Hurt a Narcissist; - [EMAIL] - Gmail
(56) Inbox | [EMAIL] | Proton Mail
Welcome back
Welcome back
Western Digital Red Plus 3.5 6TB 5400rpm 256MB SATA3 (WD60EFPX) от 241,72 € (472,76 лв.) Вътрешен хард диск Western Digital - Pazaruvaj.com
Western Digital Red Plus 3.5 6TB 5400rpm 256MB SATA3 (WD60EFPX) от 241,72 € (472,76 лв.) Вътрешен хард диск Western Digital - Pazaruvaj.com
Today's Deals
Today's Deals
architecture - screenpipe docs
architecture - screenpipe docs
Claude Code works better when you stop treating it like a machine - [EMAIL] - Gmail
Claude Code works better when you stop treating it like a machine - [EMAIL] - Gmail
Screenpipe — Archive
Screenpipe — Archive
Close tab
SQLite Web: archive.db
SQLite Web: archive.db
SQLite Web: db.sqlite
SQLite Web: db.sqlite
Claude Platform
Claude Platform
Hey @louis030195 Ill check during my - screenpipe.com
Hey @louis030195 Ill check during my - screenpipe.com
GitHub - screenpipe/screenpipe: Run agents that work for you based on what you do. AI finally knows what you are doing · GitHub
GitHub - screenpipe/screenpipe: Run agents that work for you based on what you do. AI finally knows what you are doing · GitHub
Gong Pricing in 2026: Costs, Plans & Is It Worth It?
Gong Pricing in 2026: Costs, Plans & Is It Worth It?
GLM 5.1 Thinks Strategically, Data-Center Revolt Intensifies, When Helpful LLMs Turn Unhelpful, Humanoid Robots Get to Work - [EMAIL] - Gmail
GLM 5.1 Thinks Strategically, Data-Center Revolt Intensifies, When Helpful LLMs Turn Unhelpful, Humanoid Robots Get to Work - [EMAIL] - Gmail
Gitea Official Website
Gitea Official Website
lakylak/screenpipe - screenpipe - Gitea: Git with a cup of tea
lakylak/screenpipe - screenpipe - Gitea: Git with a cup of tea
New Tab
Customize sidebar
Open Le Chat Mistral (⌃X)
Open history (⇧⌘H)
Open bookmarks (⌘B)
Bitwarden
Screenpipe [archive.db · 6175.9MB]
Screenpipe
[archive.db · 6175.9MB]
Activity
Search
Audio
Work Report
Timetable
AI Summary
Date
23
/
04
/
2026
Calendar
Monitor
Jump to
--
:
--
Go
APP TIMELINE · CLICK TO PLAY · DRAG SCROLLBAR TO PAN
−
4×
+
Follow
Follow
09:20
09:30
09:40
09:50
10:00
10:10
10:20
10:30
10:40
10:50
11:00
11:10
11:20
11:30
11:40
11:50
12:00
12:10
12:20
12:30
12:40
12:50
13:00
13:10
13:20
13:30
13:40
13:50
14:00
23 Apr 10:07 · Slack / Aneliya Angelova, Nikolay Yankov, Steliyan Georgiev (DM) - Jiminny Inc - 4 new items - Slack
⏮ 30s
◀ 10s
⏸ Pause
10s ▶
30s ⏭
10:07
iTerm2
Firefox
Slack
Alfred
PhpStorm
CleanShot X
Finder
QuickTime Player
Activity Monitor
Preview
Sequel Ace
Raycast
Music...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"DXP4800PLUS-B5F8","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"5 Signs You Have Successfully Hurt a Narcissist; - kovaliklukas@gmail.com - Gmail","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"(56) Inbox | kovaliklukas@proton.me | Proton Mail","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Welcome back","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Welcome back","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Western Digital Red Plus 3.5 6TB 5400rpm 256MB SATA3 (WD60EFPX) от 241,72 € (472,76 лв.) Вътрешен хард диск Western Digital - Pazaruvaj.com","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Western Digital Red Plus 3.5 6TB 5400rpm 256MB SATA3 (WD60EFPX) от 241,72 € (472,76 лв.) Вътрешен хард диск Western Digital - Pazaruvaj.com","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Today's Deals","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Today's Deals","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"architecture - screenpipe docs","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"architecture - screenpipe docs","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Claude Code works better when you stop treating it like a machine - kovaliklukas@gmail.com - Gmail","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Claude Code works better when you stop treating it like a machine - kovaliklukas@gmail.com - Gmail","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Screenpipe — Archive","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Screenpipe — Archive","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"SQLite Web: archive.db","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"SQLite Web: archive.db","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"SQLite Web: db.sqlite","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"SQLite Web: db.sqlite","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Claude Platform","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Claude Platform","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Hey @louis030195 Ill check during my - screenpipe.com","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Hey @louis030195 Ill check during my - screenpipe.com","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"GitHub - screenpipe/screenpipe: Run agents that work for you based on what you do. AI finally knows what you are doing · GitHub","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"GitHub - screenpipe/screenpipe: Run agents that work for you based on what you do. AI finally knows what you are doing · GitHub","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Gong Pricing in 2026: Costs, Plans & Is It Worth It?","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Gong Pricing in 2026: Costs, Plans & Is It Worth It?","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"GLM 5.1 Thinks Strategically, Data-Center Revolt Intensifies, When Helpful LLMs Turn Unhelpful, Humanoid Robots Get to Work - kovaliklukas@gmail.com - Gmail","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"GLM 5.1 Thinks Strategically, Data-Center Revolt Intensifies, When Helpful LLMs Turn Unhelpful, Humanoid Robots Get to Work - kovaliklukas@gmail.com - Gmail","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Gitea Official Website","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Gitea Official Website","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"lakylak/screenpipe - screenpipe - Gitea: Git with a cup of tea","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"lakylak/screenpipe - screenpipe - Gitea: Git with a cup of tea","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"New Tab","depth":4,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Le Chat Mistral (⌃X)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Bitwarden","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Screenpipe [archive.db · 6175.9MB]","depth":7,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Screenpipe","depth":8,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"[archive.db · 6175.9MB]","depth":9,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Activity","depth":7,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Search","depth":7,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Audio","depth":7,"help_text":"No audio data in this database","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Work Report","depth":7,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Timetable","depth":7,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"AI Summary","depth":7,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Date","depth":8,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"23","depth":9,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"/","depth":8,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"04","depth":9,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"/","depth":8,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026","depth":9,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Calendar","depth":8,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Monitor","depth":9,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Jump to","depth":9,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"--","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":":","depth":9,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"--","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Go","depth":8,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"APP TIMELINE · CLICK TO PLAY · DRAG SCROLLBAR TO PAN","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"−","depth":9,"help_text":"Zoom out","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"4×","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"+","depth":9,"help_text":"Zoom in","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":true,"is_selected":false},{"role":"AXCheckBox","text":"Follow","depth":10,"help_text":"","role_description":"checkbox","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Follow","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"09:20","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"09:30","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"09:40","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"09:50","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"10:00","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"10:10","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"10:20","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"10:30","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"10:40","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"10:50","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"11:00","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"11:10","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"11:20","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"11:30","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"11:40","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"11:50","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"12:00","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"12:10","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"12:20","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"12:30","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"12:40","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"12:50","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"13:00","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"13:10","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"13:20","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"13:30","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"13:40","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"13:50","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"14:00","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"23 Apr 10:07 · Slack / Aneliya Angelova, Nikolay Yankov, Steliyan Georgiev (DM) - Jiminny Inc - 4 new items - Slack","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"⏮ 30s","depth":9,"help_text":"Ctrl+←","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"◀ 10s","depth":9,"help_text":"←","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"⏸ Pause","depth":9,"help_text":"Space","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"10s ▶","depth":9,"help_text":"→","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"30s ⏭","depth":9,"help_text":"Ctrl+→","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"10:07","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"iTerm2","depth":9,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Firefox","depth":9,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Slack","depth":9,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Alfred","depth":9,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"PhpStorm","depth":9,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"CleanShot X","depth":9,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Finder","depth":9,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"QuickTime Player","depth":9,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Activity Monitor","depth":9,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Preview","depth":9,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Sequel Ace","depth":9,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Raycast","depth":9,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Music","depth":9,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
-7439355829712892437
|
8716494159565308559
|
click
|
accessibility
|
NULL
|
DXP4800PLUS-B5F8
5 Signs You Have Successfully Hur DXP4800PLUS-B5F8
5 Signs You Have Successfully Hurt a Narcissist; - [EMAIL] - Gmail
(56) Inbox | [EMAIL] | Proton Mail
Welcome back
Welcome back
Western Digital Red Plus 3.5 6TB 5400rpm 256MB SATA3 (WD60EFPX) от 241,72 € (472,76 лв.) Вътрешен хард диск Western Digital - Pazaruvaj.com
Western Digital Red Plus 3.5 6TB 5400rpm 256MB SATA3 (WD60EFPX) от 241,72 € (472,76 лв.) Вътрешен хард диск Western Digital - Pazaruvaj.com
Today's Deals
Today's Deals
architecture - screenpipe docs
architecture - screenpipe docs
Claude Code works better when you stop treating it like a machine - [EMAIL] - Gmail
Claude Code works better when you stop treating it like a machine - [EMAIL] - Gmail
Screenpipe — Archive
Screenpipe — Archive
Close tab
SQLite Web: archive.db
SQLite Web: archive.db
SQLite Web: db.sqlite
SQLite Web: db.sqlite
Claude Platform
Claude Platform
Hey @louis030195 Ill check during my - screenpipe.com
Hey @louis030195 Ill check during my - screenpipe.com
GitHub - screenpipe/screenpipe: Run agents that work for you based on what you do. AI finally knows what you are doing · GitHub
GitHub - screenpipe/screenpipe: Run agents that work for you based on what you do. AI finally knows what you are doing · GitHub
Gong Pricing in 2026: Costs, Plans & Is It Worth It?
Gong Pricing in 2026: Costs, Plans & Is It Worth It?
GLM 5.1 Thinks Strategically, Data-Center Revolt Intensifies, When Helpful LLMs Turn Unhelpful, Humanoid Robots Get to Work - [EMAIL] - Gmail
GLM 5.1 Thinks Strategically, Data-Center Revolt Intensifies, When Helpful LLMs Turn Unhelpful, Humanoid Robots Get to Work - [EMAIL] - Gmail
Gitea Official Website
Gitea Official Website
lakylak/screenpipe - screenpipe - Gitea: Git with a cup of tea
lakylak/screenpipe - screenpipe - Gitea: Git with a cup of tea
New Tab
Customize sidebar
Open Le Chat Mistral (⌃X)
Open history (⇧⌘H)
Open bookmarks (⌘B)
Bitwarden
Screenpipe [archive.db · 6175.9MB]
Screenpipe
[archive.db · 6175.9MB]
Activity
Search
Audio
Work Report
Timetable
AI Summary
Date
23
/
04
/
2026
Calendar
Monitor
Jump to
--
:
--
Go
APP TIMELINE · CLICK TO PLAY · DRAG SCROLLBAR TO PAN
−
4×
+
Follow
Follow
09:20
09:30
09:40
09:50
10:00
10:10
10:20
10:30
10:40
10:50
11:00
11:10
11:20
11:30
11:40
11:50
12:00
12:10
12:20
12:30
12:40
12:50
13:00
13:10
13:20
13:30
13:40
13:50
14:00
23 Apr 10:07 · Slack / Aneliya Angelova, Nikolay Yankov, Steliyan Georgiev (DM) - Jiminny Inc - 4 new items - Slack
⏮ 30s
◀ 10s
⏸ Pause
10s ▶
30s ⏭
10:07
iTerm2
Firefox
Slack
Alfred
PhpStorm
CleanShot X
Finder
QuickTime Player
Activity Monitor
Preview
Sequel Ace
Raycast
Music...
|
80620
|
|
80788
|
2133
|
23
|
2026-04-25T14:44:10.442239+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-25/1777 /Users/lukas/.screenpipe/data/data/2026-04-25/1777128250442_m1.jpg...
|
Firefox
|
Your Steam account: Access from new web or mobile Your Steam account: Access from new web or mobile device - kovaliklukas@gmail.com - Gmail — Personal...
|
True
|
mail.google.com/mail/u/0/#inbox/FMfcgzQgLXqngSBLbR mail.google.com/mail/u/0/#inbox/FMfcgzQgLXqngSBLbRwsNXBbXSJDZcph...
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
DXP4800PLUS-B5F8
Your Steam account: Access from n DXP4800PLUS-B5F8
Your Steam account: Access from new web or mobile device - [EMAIL] - Gmail
(56) Inbox | [EMAIL] | Proton Mail
Welcome back
Welcome back
Western Digital Red Plus 3.5 6TB 5400rpm 256MB SATA3 (WD60EFPX) от 241,72 € (472,76 лв.) Вътрешен хард диск Western Digital - Pazaruvaj.com
Western Digital Red Plus 3.5 6TB 5400rpm 256MB SATA3 (WD60EFPX) от 241,72 € (472,76 лв.) Вътрешен хард диск Western Digital - Pazaruvaj.com
Today's Deals
Today's Deals
architecture - screenpipe docs
architecture - screenpipe docs
Claude Code works better when you stop treating it like a machine - [EMAIL] - Gmail
Claude Code works better when you stop treating it like a machine - [EMAIL] - Gmail
Screenpipe — Archive
Screenpipe — Archive
SQLite Web: archive.db
SQLite Web: archive.db
SQLite Web: db.sqlite
SQLite Web: db.sqlite
Claude Platform
Claude Platform
Hey @louis030195 Ill check during my - screenpipe.com
Hey @louis030195 Ill check during my - screenpipe.com
GitHub - screenpipe/screenpipe: Run agents that work for you based on what you do. AI finally knows what you are doing · GitHub
GitHub - screenpipe/screenpipe: Run agents that work for you based on what you do. AI finally knows what you are doing · GitHub
Gong Pricing in 2026: Costs, Plans & Is It Worth It?
Gong Pricing in 2026: Costs, Plans & Is It Worth It?
GLM 5.1 Thinks Strategically, Data-Center Revolt Intensifies, When Helpful LLMs Turn Unhelpful, Humanoid Robots Get to Work - [EMAIL] - Gmail
GLM 5.1 Thinks Strategically, Data-Center Revolt Intensifies, When Helpful LLMs Turn Unhelpful, Humanoid Robots Get to Work - [EMAIL] - Gmail
Gitea Official Website
Gitea Official Website
lakylak/screenpipe - screenpipe - Gitea: Git with a cup of tea
lakylak/screenpipe - screenpipe - Gitea: Git with a cup of tea
New Tab
New Tab
New Tab
Customize sidebar
Open Le Chat Mistral (⌃X)
Open history (⇧⌘H)
Open bookmarks (⌘B)
Bitwarden
Skip to content
Skip to content
Using Gmail with screen readers
Using Gmail with screen readers
Main menu
Gmail
Search
Search
Search mail
Advanced search options
Search mail
Support
Settings
Ask Gemini
Google apps
Google Account: Lukáš Koválik ([EMAIL]), Storage usage alert
Compose
Labels
Labels
Inbox 8 unread
Inbox
8
Starred
Starred
Snoozed
Snoozed
Important
Important
Sent
Sent
Drafts 8 unread
Drafts
8
Purchases 2 unread has menu
Purchases
2
Social 5169 unread has menu
Social
5,169
Updates 8700 unread has menu
Updates
8,700
Forums 6050 unread has menu
Forums
6,050
Promotions 38642 unread has menu
Promotions
38,642
More labels
More
Labels
Labels
Create new label
Labels
Labels
[Imap]/Nevyžiadaná pošta has menu
[Imap]/Nevyžiadaná pošta
arch has menu
arch
Deleted Items has menu
Deleted Items
Fibank 1229 unread has menu
Fibank
1,229
FL 6 unread has menu
FL
6
Hardware & Software has menu
Hardware & Software
HOSTING 5 unread has menu
HOSTING
5
Infected Items has menu
Infected Items
jiminny-github 7425 unread has menu
jiminny-github
7,425
Junk E-mail 219 unread has menu
Junk E-mail
219
Kontakty has menu
Kontakty
Sent Items has menu
Sent Items
WORK 848 unread has menu
WORK
848
z centra 1274 unread has menu
z centra
1,274
More labels
More
Back to Inbox...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"DXP4800PLUS-B5F8","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Your Steam account: Access from new web or mobile device - kovaliklukas@gmail.com - Gmail","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXRadioButton","text":"(56) Inbox | kovaliklukas@proton.me | Proton Mail","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Welcome back","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Welcome back","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Western Digital Red Plus 3.5 6TB 5400rpm 256MB SATA3 (WD60EFPX) от 241,72 € (472,76 лв.) Вътрешен хард диск Western Digital - Pazaruvaj.com","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Western Digital Red Plus 3.5 6TB 5400rpm 256MB SATA3 (WD60EFPX) от 241,72 € (472,76 лв.) Вътрешен хард диск Western Digital - Pazaruvaj.com","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Today's Deals","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Today's Deals","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"architecture - screenpipe docs","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"architecture - screenpipe docs","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Claude Code works better when you stop treating it like a machine - kovaliklukas@gmail.com - Gmail","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Claude Code works better when you stop treating it like a machine - kovaliklukas@gmail.com - Gmail","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Screenpipe — Archive","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Screenpipe — Archive","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"SQLite Web: archive.db","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"SQLite Web: archive.db","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"SQLite Web: db.sqlite","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"SQLite Web: db.sqlite","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Claude Platform","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Claude Platform","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Hey @louis030195 Ill check during my - screenpipe.com","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Hey @louis030195 Ill check during my - screenpipe.com","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"GitHub - screenpipe/screenpipe: Run agents that work for you based on what you do. AI finally knows what you are doing · GitHub","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"GitHub - screenpipe/screenpipe: Run agents that work for you based on what you do. AI finally knows what you are doing · GitHub","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Gong Pricing in 2026: Costs, Plans & Is It Worth It?","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Gong Pricing in 2026: Costs, Plans & Is It Worth It?","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"GLM 5.1 Thinks Strategically, Data-Center Revolt Intensifies, When Helpful LLMs Turn Unhelpful, Humanoid Robots Get to Work - kovaliklukas@gmail.com - Gmail","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"GLM 5.1 Thinks Strategically, Data-Center Revolt Intensifies, When Helpful LLMs Turn Unhelpful, Humanoid Robots Get to Work - kovaliklukas@gmail.com - Gmail","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Gitea Official Website","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Gitea Official Website","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"lakylak/screenpipe - screenpipe - Gitea: Git with a cup of tea","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"lakylak/screenpipe - screenpipe - Gitea: Git with a cup of tea","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"New Tab","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"New Tab","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"New Tab","depth":4,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Le Chat Mistral (⌃X)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Bitwarden","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Skip to content","depth":10,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip to content","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Using Gmail with screen readers","depth":10,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Using Gmail with screen readers","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Main menu","depth":11,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":true},{"role":"AXLink","text":"Gmail","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Search","depth":12,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Search","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"Search mail","depth":18,"help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Advanced search options","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Search mail","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXMenuButton","text":"Support","depth":12,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXMenuButton","text":"Settings","depth":12,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Ask Gemini","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Google apps","depth":14,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Google Account: Lukáš Koválik (kovaliklukas@gmail.com), Storage usage alert","depth":14,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Compose","depth":9,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Labels","depth":12,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Labels","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Inbox 8 unread","depth":16,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Inbox","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"8","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Starred","depth":16,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Starred","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Snoozed","depth":16,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Snoozed","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Important","depth":17,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Important","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Sent","depth":16,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Sent","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Drafts 8 unread","depth":16,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Drafts","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"8","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Purchases 2 unread has menu","depth":16,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Purchases","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Social 5169 unread has menu","depth":16,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Social","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"5,169","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Updates 8700 unread has menu","depth":16,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Updates","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"8,700","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Forums 6050 unread has menu","depth":16,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Forums","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"6,050","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Promotions 38642 unread has menu","depth":16,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Promotions","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"38,642","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"More labels","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"More","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Labels","depth":11,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Labels","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Create new label","depth":11,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Labels","depth":12,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Labels","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"[Imap]/Nevyžiadaná pošta has menu","depth":16,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[Imap]/Nevyžiadaná pošta","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"arch has menu","depth":16,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"arch","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Deleted Items has menu","depth":16,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Deleted Items","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Fibank 1229 unread has menu","depth":16,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Fibank","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1,229","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"FL 6 unread has menu","depth":16,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"FL","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"6","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Hardware & Software has menu","depth":16,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Hardware & Software","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"HOSTING 5 unread has menu","depth":16,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"HOSTING","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"5","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Infected Items has menu","depth":16,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Infected Items","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"jiminny-github 7425 unread has menu","depth":16,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"jiminny-github","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"7,425","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Junk E-mail 219 unread has menu","depth":16,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Junk E-mail","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"219","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Kontakty has menu","depth":16,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Kontakty","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Sent Items has menu","depth":16,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Sent Items","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"WORK 848 unread has menu","depth":16,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"WORK","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"848","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"z centra 1274 unread has menu","depth":16,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"z centra","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1,274","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"More labels","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"More","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Back to Inbox","depth":11,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false}]...
|
-1821400905569157640
|
8711426540520885165
|
click
|
accessibility
|
NULL
|
DXP4800PLUS-B5F8
Your Steam account: Access from n DXP4800PLUS-B5F8
Your Steam account: Access from new web or mobile device - [EMAIL] - Gmail
(56) Inbox | [EMAIL] | Proton Mail
Welcome back
Welcome back
Western Digital Red Plus 3.5 6TB 5400rpm 256MB SATA3 (WD60EFPX) от 241,72 € (472,76 лв.) Вътрешен хард диск Western Digital - Pazaruvaj.com
Western Digital Red Plus 3.5 6TB 5400rpm 256MB SATA3 (WD60EFPX) от 241,72 € (472,76 лв.) Вътрешен хард диск Western Digital - Pazaruvaj.com
Today's Deals
Today's Deals
architecture - screenpipe docs
architecture - screenpipe docs
Claude Code works better when you stop treating it like a machine - [EMAIL] - Gmail
Claude Code works better when you stop treating it like a machine - [EMAIL] - Gmail
Screenpipe — Archive
Screenpipe — Archive
SQLite Web: archive.db
SQLite Web: archive.db
SQLite Web: db.sqlite
SQLite Web: db.sqlite
Claude Platform
Claude Platform
Hey @louis030195 Ill check during my - screenpipe.com
Hey @louis030195 Ill check during my - screenpipe.com
GitHub - screenpipe/screenpipe: Run agents that work for you based on what you do. AI finally knows what you are doing · GitHub
GitHub - screenpipe/screenpipe: Run agents that work for you based on what you do. AI finally knows what you are doing · GitHub
Gong Pricing in 2026: Costs, Plans & Is It Worth It?
Gong Pricing in 2026: Costs, Plans & Is It Worth It?
GLM 5.1 Thinks Strategically, Data-Center Revolt Intensifies, When Helpful LLMs Turn Unhelpful, Humanoid Robots Get to Work - [EMAIL] - Gmail
GLM 5.1 Thinks Strategically, Data-Center Revolt Intensifies, When Helpful LLMs Turn Unhelpful, Humanoid Robots Get to Work - [EMAIL] - Gmail
Gitea Official Website
Gitea Official Website
lakylak/screenpipe - screenpipe - Gitea: Git with a cup of tea
lakylak/screenpipe - screenpipe - Gitea: Git with a cup of tea
New Tab
New Tab
New Tab
Customize sidebar
Open Le Chat Mistral (⌃X)
Open history (⇧⌘H)
Open bookmarks (⌘B)
Bitwarden
Skip to content
Skip to content
Using Gmail with screen readers
Using Gmail with screen readers
Main menu
Gmail
Search
Search
Search mail
Advanced search options
Search mail
Support
Settings
Ask Gemini
Google apps
Google Account: Lukáš Koválik ([EMAIL]), Storage usage alert
Compose
Labels
Labels
Inbox 8 unread
Inbox
8
Starred
Starred
Snoozed
Snoozed
Important
Important
Sent
Sent
Drafts 8 unread
Drafts
8
Purchases 2 unread has menu
Purchases
2
Social 5169 unread has menu
Social
5,169
Updates 8700 unread has menu
Updates
8,700
Forums 6050 unread has menu
Forums
6,050
Promotions 38642 unread has menu
Promotions
38,642
More labels
More
Labels
Labels
Create new label
Labels
Labels
[Imap]/Nevyžiadaná pošta has menu
[Imap]/Nevyžiadaná pošta
arch has menu
arch
Deleted Items has menu
Deleted Items
Fibank 1229 unread has menu
Fibank
1,229
FL 6 unread has menu
FL
6
Hardware & Software has menu
Hardware & Software
HOSTING 5 unread has menu
HOSTING
5
Infected Items has menu
Infected Items
jiminny-github 7425 unread has menu
jiminny-github
7,425
Junk E-mail 219 unread has menu
Junk E-mail
219
Kontakty has menu
Kontakty
Sent Items has menu
Sent Items
WORK 848 unread has menu
WORK
848
z centra 1274 unread has menu
z centra
1,274
More labels
More
Back to Inbox...
|
80786
|
|
14460
|
326
|
2
|
2026-04-14T13:50:09.120346+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-14/1776 /Users/lukas/.screenpipe/data/data/2026-04-14/1776174609120_m1.jpg...
|
Firefox
|
pazaruvaj - Google Search — Personal
|
True
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
DXP4800PLUS-B5F8
Gmail
pazaruvaj - Google Search
p DXP4800PLUS-B5F8
Gmail
pazaruvaj - Google Search
pazaruvaj - Google Search...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"DXP4800PLUS-B5F8","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Gmail","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"pazaruvaj - Google Search","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"pazaruvaj - Google Search","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
-4968767897939302360
|
8706799985675753645
|
click
|
hybrid
|
NULL
|
DXP4800PLUS-B5F8
Gmail
pazaruvaj - Google Search
p DXP4800PLUS-B5F8
Gmail
pazaruvaj - Google Search
pazaruvaj - Google Search
SlackFileEditViewGoHistoryWindowHelpDOCKER₴81DEV (docker)882APP (-zsh)[EMAIL]'s next:Try Docker Debug forseamless,persistentdebugging tools in any container or imaLearn moreat [URL_WITH_CREDENTIALS] ~/jiminny/app (JY-18909-automated-reports-asdocker exec -it docker_lamp_1./vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.diPHP CS Fixer 3.87.1 Alexander by Fabien Potencier, Dariusz Ruminskiandcontributors.PHP runtime: 8.3.30Running analysis on 7 cores with 10 files per process.Parallel runner is an experimental feature and may be unstable,useitatyourownLoadedconfig default from-php-cs-fixer.dist.php".5589/5589100%Fixed 0 of 5589 files in 49.458 seconds, 67.00 MB memory usedWhat's next:Try Docker Debug forseamless, persistent debugging tools in any container or imaLearn more at https://docs.docker.com/go/debug-cli/lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/Jiminny/app (JY-18909-automated-reports-as.env.localMapp/Console/Commands/JiminnyDebugCommand.phpapp/Http/Controllers/API/ActivityController.phpapp/Http/Controllers/Webhook/ReportController.phpapp/Jobs/Team/SyncToIntercom.phpMapp/Services/PlaybackService.phpconfig/logging.phproutes/web.phpAlready on 'JY-18909-automated-reports-ask-jiminny'Your branch is up to date with 'origin/JY-18909-automated-reports-ask-jiminny'.lukas@Lukas-Kovaliks-MacBook-Pro-Jiminny ~/jiminny/app (JY-18909-automated-reports-as+HomeDMsActivityFilesLater.*•More(aol• Retro - Platform • in 10 m100% 147Tue 14 Apr 16:50:08→Search Jiminny IncJiminny ...+tscnicrel# infra-changes# jiminny-bg# platform-tickets# product_launches# random# releases# sofia-office# support# thank-yous# the_people_of jimi...Aneliya Angelova, ...846 0• Messages+Direct messagesAneliya Angelova, ...€. Vasil Vasilevlo Steliyan GeorgievAdelina Petrova, Ili...0. Adelina Petrova. Galya Dimitrova *Rs Nikolay Nikolov "2 Galya Dimitrova, Ni...2Galya Dimitrova, Ni...P. Nikolay YankovAdd canvas@ FilesизпратенToday ~Steliyan Georgiev 4:08 PMВиждам 2 проблема с линковете:• линковете са в края на документа, а неинлайн в отговорите• има странни символи в тях. Това езащото в заглавията на срещите иманякакви имотикони - тикви например,предполагам, че ги нямаме в шрифта наПДФ-а. Не съм сигурен какво да гиправя?@Nikolay Yankov, някой от горните ли имашпредвид или трето? (edited)Nikolay Yankov 4:09 PMпоследния дето пратихSteliyan Georgiev 4:09 PMда, за него говоря и азNikolay Yankov 4:10 PMможе би да ги скипваме такива emojisда не пречат на процесването и отговораNew::: AppsToastJira CloudGoogle Cale...Steliyan Georgiev 4:10 PMне сьм много сигурен какMessage Aneliya Angelova, Nikolay Yankov, Steli...Aa...
|
14456
|
|
69052
|
1579
|
15
|
2026-04-22T07:24:44.311675+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-22/1776 /Users/lukas/.screenpipe/data/data/2026-04-22/1776842684311_m2.jpg...
|
Finder
|
Copy
|
True
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Copying “CleanShot 2026-04-22 at 09.44.58.mp4” to Copying “CleanShot 2026-04-22 at 09.44.58.mp4” to “2026”
stop progress
805,3 MB of 1,36 GB - Less than a minute
Copying “CleanShot 2026-04-22 at 09.44.58.mp4” to “Work”
stop progress
604,0 MB of 1,36 GB - Less than a minute...
|
[{"role":"AXStaticText","text& [{"role":"AXStaticText","text":"Copying “CleanShot 2026-04-22 at 09.44.58.mp4” to “2026”","depth":2,"bounds":{"left":0.2081117,"top":0.6440543,"width":0.10405585,"height":0.011173184},"automation_id":"_NS:59","role_description":"text"},{"role":"AXButton","text":"stop progress","depth":2,"bounds":{"left":0.31416222,"top":0.6556265,"width":0.0043218085,"height":0.0103751},"automation_id":"_NS:8","role_description":"button","is_enabled":true,"is_focused":true},{"role":"AXStaticText","text":"805,3 MB of 1,36 GB - Less than a minute","depth":2,"bounds":{"left":0.2081117,"top":0.6671987,"width":0.10405585,"height":0.011173184},"automation_id":"_NS:89","role_description":"text"},{"role":"AXStaticText","text":"Copying “CleanShot 2026-04-22 at 09.44.58.mp4” to “Work”","depth":2,"bounds":{"left":0.2081117,"top":0.5969673,"width":0.10405585,"height":0.011173184},"automation_id":"_NS:59","role_description":"text"},{"role":"AXButton","text":"stop progress","depth":2,"bounds":{"left":0.31416222,"top":0.6085395,"width":0.0043218085,"height":0.0103751},"automation_id":"_NS:8","role_description":"button","is_enabled":true,"is_focused":false},{"role":"AXStaticText","text":"604,0 MB of 1,36 GB - Less than a minute","depth":2,"bounds":{"left":0.2081117,"top":0.6201117,"width":0.10405585,"height":0.011173184},"automation_id":"_NS:89","role_description":"text"}]...
|
-6704927004046763593
|
8696231246175213760
|
visual_change
|
accessibility
|
NULL
|
Copying “CleanShot 2026-04-22 at 09.44.58.mp4” to Copying “CleanShot 2026-04-22 at 09.44.58.mp4” to “2026”
stop progress
805,3 MB of 1,36 GB - Less than a minute
Copying “CleanShot 2026-04-22 at 09.44.58.mp4” to “Work”
stop progress
604,0 MB of 1,36 GB - Less than a minute...
|
69050
|
|
7520
|
140
|
18
|
2026-04-13T15:58:15.865153+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-13/1776 /Users/lukas/.screenpipe/data/data/2026-04-13/1776095895865_m1.jpg...
|
Firefox
|
Screenpipe Dashboard — Personal
|
True
|
http://100.73.206.126:8766
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
DXP4800PLUS-B5F8
Inbox - [EMAIL] - Gmail
Shameles DXP4800PLUS-B5F8
Inbox - [EMAIL] - Gmail
Shameless • HBO Max
Shameless • HBO Max
Proeurópska bublina si po Orbánovom páde vydýchla, víťazná Tisza však môže Brusel prekvapiť — Denník N
Mute tab
Proeurópska bublina si po Orbánovom páde vydýchla, víťazná Tisza však môže Brusel prekvapiť — Denník N
Machines - Tailscale
Machines - Tailscale
Screenpipe Dashboard
Screenpipe Dashboard
Close tab
Pazaruvaj.com — Знак, че е време за най-добрите оферти
Pazaruvaj.com — Знак, че е време за най-добрите оферти
Screenpipe: Open Source 24/7 Screen & Audio Capture : r/software
Screenpipe: Open Source 24/7 Screen & Audio Capture : r/software
google maps timeline export - Google Search
google maps timeline export - Google Search
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Open history (⇧⌘H)
Open bookmarks (⌘B)
Bitwarden
Screenpipe
Screenpipe
Activity
Search
Audio
Work Report
AI Summary
Date
12
/
04
/
2026
Calendar
TOTAL SPAN
12.6h
11:35 → 00:10
ACTIVE TIME
(WALL CLOCK)
4.6h
BREAKS
3 · 8.0h
SESSIONS — CLICK TO FILTER
S1: 11:35–11:46 (11.1m)
S2: 12:10–13:13 (63.3m)
S3: 15:09–16:37 (87.1m)
S4: 22:16–00:10 (113.9m)
Click a session segment to filter activity to that time window
S2 63m
S3 87m
S4 114m
117m
340m
11:35
13:41
15:46
17:52
19:58
22:04
00:10
Filtered:
📱 Firefox
×
FRAMES
2455
APPS
10
UI EVENTS
3628
AUDIO
0
ACTIVE PERIOD
(TIMES IN LOCAL TIMEZONE)
11:35 → 00:10
TIME PER APP
— CLICK TO FILTER ALL PANELS BY APP
Boosteroid
43.4m
Firefox
9.7m
iTerm2
5.7m
Claude
5.1m
System Settings
1.9m
Alfred
0.4m
Control Centre
0.2m
Code
0.1m
Activity Monitor
0.1m
Preview
0m
Websites
Windows
UI Events
screenpi.pe/onboarding
0.6m
dennikn.sk
0.3m
screenpi.pe/ideas
0.2m
nas.lakylak.xyz/desktop/#/
0.2m
screenpi.pe/why
0.2m
www.reddit.com/r/software/comments/1fjfwg0/comment/lnr7nqd/
0.1m
jiminny.atlassian.net/jira/software/c/projects/JY/boards/37?selectedIssue=JY-18909
0.1m
app.dev.jiminny.com
0.1m
addons.mozilla.org/en-US/firefox/?utm_source=firefox-browser&utm_medium=firefox-browser&utm_content=find-more-link-bottom
0.1m
screenpi.pe/resources
0.1m
screenpi.pe
0.1m
mail.google.com/mail/u/0/#inbox
0.1m
jiminny.atlassian.net/jira/software/c/projects/JY/boards/37?selectedIssue=JY-20543
0.1m
http://localhost:3030
0.1m
addons.mozilla.org/en-US/firefox/addon/proxy-switcher-and-manager/?utm_source=addons.mozilla.org&utm_medium=referral&utm_content=search
0.1m
www.rtings.com/projector/reviews/dangbei/atom-laser-projector
0m
www.reddit.com/r/software/comments/1fjfwg0/screenpipe_open_source_247_screen_audio_capture/
0m
jiminny.atlassian.net/jira/software/c/projects/JY/boards/37
0m
dennikn.sk/tema/iran/
0m
dennikn.sk/5268962/sledujte-madarske-volby-ako-experti-toto-su-najdolezitejsie-veci-ktore-treba-vediet/
0m
addons.mozilla.org/en-US/firefox/search/?q=profile
0m...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"DXP4800PLUS-B5F8","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Inbox - kovaliklukas@gmail.com - Gmail","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Shameless • HBO Max","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Shameless • HBO Max","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Proeurópska bublina si po Orbánovom páde vydýchla, víťazná Tisza však môže Brusel prekvapiť — Denník N","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Mute tab","depth":5,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Proeurópska bublina si po Orbánovom páde vydýchla, víťazná Tisza však môže Brusel prekvapiť — Denník N","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Machines - Tailscale","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Machines - Tailscale","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Screenpipe Dashboard","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Screenpipe Dashboard","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Pazaruvaj.com — Знак, че е време за най-добрите оферти","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pazaruvaj.com — Знак, че е време за най-добрите оферти","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Screenpipe: Open Source 24/7 Screen & Audio Capture : r/software","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Screenpipe: Open Source 24/7 Screen & Audio Capture : r/software","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"google maps timeline export - Google Search","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"google maps timeline export - Google Search","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"New Tab","depth":4,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Bitwarden","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Screenpipe","depth":7,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Screenpipe","depth":8,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Activity","depth":7,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Search","depth":7,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Audio","depth":7,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Work Report","depth":7,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"AI Summary","depth":7,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Date","depth":8,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"12","depth":9,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"/","depth":8,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"04","depth":9,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"/","depth":8,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026","depth":9,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Calendar","depth":8,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"TOTAL SPAN","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"12.6h","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"11:35 → 00:10","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ACTIVE TIME","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(WALL CLOCK)","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"4.6h","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"BREAKS","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"3 · 8.0h","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"SESSIONS — CLICK TO FILTER","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"S1: 11:35–11:46 (11.1m)","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"S2: 12:10–13:13 (63.3m)","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"S3: 15:09–16:37 (87.1m)","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"S4: 22:16–00:10 (113.9m)","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Click a session segment to filter activity to that time window","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"S2 63m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"S3 87m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"S4 114m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"117m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"340m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"11:35","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"13:41","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"15:46","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"17:52","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"19:58","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"22:04","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"00:10","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Filtered:","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"📱 Firefox","depth":9,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"×","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"FRAMES","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2455","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"APPS","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"10","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"UI EVENTS","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"3628","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"AUDIO","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ACTIVE PERIOD","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(TIMES IN LOCAL TIMEZONE)","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"11:35 → 00:10","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"TIME PER APP","depth":9,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"— CLICK TO FILTER ALL PANELS BY APP","depth":9,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Boosteroid","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"43.4m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Firefox","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"9.7m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"iTerm2","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"5.7m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Claude","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"5.1m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"System Settings","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1.9m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Alfred","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.4m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Control Centre","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.2m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Code","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.1m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Activity Monitor","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.1m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Preview","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Websites","depth":8,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Windows","depth":8,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"UI Events","depth":8,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"screenpi.pe/onboarding","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.6m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"dennikn.sk","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.3m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"screenpi.pe/ideas","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.2m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"nas.lakylak.xyz/desktop/#/","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.2m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"screenpi.pe/why","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.2m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"www.reddit.com/r/software/comments/1fjfwg0/comment/lnr7nqd/","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.1m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"jiminny.atlassian.net/jira/software/c/projects/JY/boards/37?selectedIssue=JY-18909","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.1m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"app.dev.jiminny.com","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.1m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"addons.mozilla.org/en-US/firefox/?utm_source=firefox-browser&utm_medium=firefox-browser&utm_content=find-more-link-bottom","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.1m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"screenpi.pe/resources","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.1m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"screenpi.pe","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.1m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"mail.google.com/mail/u/0/#inbox","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.1m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"jiminny.atlassian.net/jira/software/c/projects/JY/boards/37?selectedIssue=JY-20543","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.1m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"http://localhost:3030","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.1m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"addons.mozilla.org/en-US/firefox/addon/proxy-switcher-and-manager/?utm_source=addons.mozilla.org&utm_medium=referral&utm_content=search","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.1m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"www.rtings.com/projector/reviews/dangbei/atom-laser-projector","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"www.reddit.com/r/software/comments/1fjfwg0/screenpipe_open_source_247_screen_audio_capture/","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"jiminny.atlassian.net/jira/software/c/projects/JY/boards/37","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"dennikn.sk/tema/iran/","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"dennikn.sk/5268962/sledujte-madarske-volby-ako-experti-toto-su-najdolezitejsie-veci-ktore-treba-vediet/","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"addons.mozilla.org/en-US/firefox/search/?q=profile","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
7066729612755168096
|
8694592698007632328
|
click
|
accessibility
|
NULL
|
DXP4800PLUS-B5F8
Inbox - [EMAIL] - Gmail
Shameles DXP4800PLUS-B5F8
Inbox - [EMAIL] - Gmail
Shameless • HBO Max
Shameless • HBO Max
Proeurópska bublina si po Orbánovom páde vydýchla, víťazná Tisza však môže Brusel prekvapiť — Denník N
Mute tab
Proeurópska bublina si po Orbánovom páde vydýchla, víťazná Tisza však môže Brusel prekvapiť — Denník N
Machines - Tailscale
Machines - Tailscale
Screenpipe Dashboard
Screenpipe Dashboard
Close tab
Pazaruvaj.com — Знак, че е време за най-добрите оферти
Pazaruvaj.com — Знак, че е време за най-добрите оферти
Screenpipe: Open Source 24/7 Screen & Audio Capture : r/software
Screenpipe: Open Source 24/7 Screen & Audio Capture : r/software
google maps timeline export - Google Search
google maps timeline export - Google Search
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Open history (⇧⌘H)
Open bookmarks (⌘B)
Bitwarden
Screenpipe
Screenpipe
Activity
Search
Audio
Work Report
AI Summary
Date
12
/
04
/
2026
Calendar
TOTAL SPAN
12.6h
11:35 → 00:10
ACTIVE TIME
(WALL CLOCK)
4.6h
BREAKS
3 · 8.0h
SESSIONS — CLICK TO FILTER
S1: 11:35–11:46 (11.1m)
S2: 12:10–13:13 (63.3m)
S3: 15:09–16:37 (87.1m)
S4: 22:16–00:10 (113.9m)
Click a session segment to filter activity to that time window
S2 63m
S3 87m
S4 114m
117m
340m
11:35
13:41
15:46
17:52
19:58
22:04
00:10
Filtered:
📱 Firefox
×
FRAMES
2455
APPS
10
UI EVENTS
3628
AUDIO
0
ACTIVE PERIOD
(TIMES IN LOCAL TIMEZONE)
11:35 → 00:10
TIME PER APP
— CLICK TO FILTER ALL PANELS BY APP
Boosteroid
43.4m
Firefox
9.7m
iTerm2
5.7m
Claude
5.1m
System Settings
1.9m
Alfred
0.4m
Control Centre
0.2m
Code
0.1m
Activity Monitor
0.1m
Preview
0m
Websites
Windows
UI Events
screenpi.pe/onboarding
0.6m
dennikn.sk
0.3m
screenpi.pe/ideas
0.2m
nas.lakylak.xyz/desktop/#/
0.2m
screenpi.pe/why
0.2m
www.reddit.com/r/software/comments/1fjfwg0/comment/lnr7nqd/
0.1m
jiminny.atlassian.net/jira/software/c/projects/JY/boards/37?selectedIssue=JY-18909
0.1m
app.dev.jiminny.com
0.1m
addons.mozilla.org/en-US/firefox/?utm_source=firefox-browser&utm_medium=firefox-browser&utm_content=find-more-link-bottom
0.1m
screenpi.pe/resources
0.1m
screenpi.pe
0.1m
mail.google.com/mail/u/0/#inbox
0.1m
jiminny.atlassian.net/jira/software/c/projects/JY/boards/37?selectedIssue=JY-20543
0.1m
http://localhost:3030
0.1m
addons.mozilla.org/en-US/firefox/addon/proxy-switcher-and-manager/?utm_source=addons.mozilla.org&utm_medium=referral&utm_content=search
0.1m
www.rtings.com/projector/reviews/dangbei/atom-laser-projector
0m
www.reddit.com/r/software/comments/1fjfwg0/screenpipe_open_source_247_screen_audio_capture/
0m
jiminny.atlassian.net/jira/software/c/projects/JY/boards/37
0m
dennikn.sk/tema/iran/
0m
dennikn.sk/5268962/sledujte-madarske-volby-ako-experti-toto-su-najdolezitejsie-veci-ktore-treba-vediet/
0m
addons.mozilla.org/en-US/firefox/search/?q=profile
0m...
|
NULL
|
|
7530
|
140
|
28
|
2026-04-13T15:58:59.464166+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-13/1776 /Users/lukas/.screenpipe/data/data/2026-04-13/1776095939464_m1.jpg...
|
Firefox
|
Screenpipe Dashboard — Personal
|
True
|
http://100.73.206.126:8766
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
DXP4800PLUS-B5F8
Inbox - [EMAIL] - Gmail
Shameles DXP4800PLUS-B5F8
Inbox - [EMAIL] - Gmail
Shameless • HBO Max
Shameless • HBO Max
Proeurópska bublina si po Orbánovom páde vydýchla, víťazná Tisza však môže Brusel prekvapiť — Denník N
Mute tab
Proeurópska bublina si po Orbánovom páde vydýchla, víťazná Tisza však môže Brusel prekvapiť — Denník N
Machines - Tailscale
Machines - Tailscale
Screenpipe Dashboard
Screenpipe Dashboard
Close tab
Pazaruvaj.com — Знак, че е време за най-добрите оферти
Pazaruvaj.com — Знак, че е време за най-добрите оферти
Screenpipe: Open Source 24/7 Screen & Audio Capture : r/software
Screenpipe: Open Source 24/7 Screen & Audio Capture : r/software
google maps timeline export - Google Search
google maps timeline export - Google Search
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Open history (⇧⌘H)
Open bookmarks (⌘B)
Bitwarden
Screenpipe
Screenpipe
Activity
Search
Audio
Work Report
AI Summary
Date
12
/
04
/
2026
Calendar
TOTAL SPAN
12.6h
11:35 → 00:10
ACTIVE TIME
(WALL CLOCK)
4.6h
BREAKS
3 · 8.0h
SESSIONS — CLICK TO FILTER
S1: 11:35–11:46 (11.1m)
S2: 12:10–13:13 (63.3m)
S3: 15:09–16:37 (87.1m)
S4: 22:16–00:10 (113.9m)
Click a session segment to filter activity to that time window
S2 63m
S3 87m
S4 114m
117m
340m
11:35
13:41
15:46
17:52
19:58
22:04
00:10
Filtered:
📱 Firefox
×
FRAMES
2455
APPS
10
UI EVENTS
3628
AUDIO
0
ACTIVE PERIOD
(TIMES IN LOCAL TIMEZONE)
11:35 → 00:10
TIME PER APP
— CLICK TO FILTER ALL PANELS BY APP
Boosteroid
43.4m
Firefox
9.7m
iTerm2
5.7m
Claude
5.1m
System Settings
1.9m
Alfred
0.4m
Control Centre
0.2m
Code
0.1m
Activity Monitor
0.1m
Preview
0m
Websites
Windows
UI Events
screenpi.pe/onboarding
0.6m
dennikn.sk
0.3m
screenpi.pe/ideas
0.2m
nas.lakylak.xyz/desktop/#/
0.2m
screenpi.pe/why
0.2m
www.reddit.com/r/software/comments/1fjfwg0/comment/lnr7nqd/
0.1m
jiminny.atlassian.net/jira/software/c/projects/JY/boards/37?selectedIssue=JY-18909
0.1m
app.dev.jiminny.com
0.1m
addons.mozilla.org/en-US/firefox/?utm_source=firefox-browser&utm_medium=firefox-browser&utm_content=find-more-link-bottom
0.1m
screenpi.pe/resources
0.1m
screenpi.pe
0.1m
mail.google.com/mail/u/0/#inbox
0.1m
jiminny.atlassian.net/jira/software/c/projects/JY/boards/37?selectedIssue=JY-20543
0.1m
http://localhost:3030
0.1m
addons.mozilla.org/en-US/firefox/addon/proxy-switcher-and-manager/?utm_source=addons.mozilla.org&utm_medium=referral&utm_content=search
0.1m
www.rtings.com/projector/reviews/dangbei/atom-laser-projector
0m
www.reddit.com/r/software/comments/1fjfwg0/screenpipe_open_source_247_screen_audio_capture/
0m
jiminny.atlassian.net/jira/software/c/projects/JY/boards/37
0m
dennikn.sk/tema/iran/
0m
dennikn.sk/5268962/sledujte-madarske-volby-ako-experti-toto-su-najdolezitejsie-veci-ktore-treba-vediet/
0m
addons.mozilla.org/en-US/firefox/search/?q=profile
0m...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"DXP4800PLUS-B5F8","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Inbox - kovaliklukas@gmail.com - Gmail","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Shameless • HBO Max","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Shameless • HBO Max","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Proeurópska bublina si po Orbánovom páde vydýchla, víťazná Tisza však môže Brusel prekvapiť — Denník N","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Mute tab","depth":5,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Proeurópska bublina si po Orbánovom páde vydýchla, víťazná Tisza však môže Brusel prekvapiť — Denník N","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Machines - Tailscale","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Machines - Tailscale","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Screenpipe Dashboard","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Screenpipe Dashboard","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Pazaruvaj.com — Знак, че е време за най-добрите оферти","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pazaruvaj.com — Знак, че е време за най-добрите оферти","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Screenpipe: Open Source 24/7 Screen & Audio Capture : r/software","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Screenpipe: Open Source 24/7 Screen & Audio Capture : r/software","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"google maps timeline export - Google Search","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"google maps timeline export - Google Search","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"New Tab","depth":4,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Bitwarden","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Screenpipe","depth":7,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Screenpipe","depth":8,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Activity","depth":7,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Search","depth":7,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Audio","depth":7,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Work Report","depth":7,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"AI Summary","depth":7,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Date","depth":8,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"12","depth":9,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"/","depth":8,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"04","depth":9,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"/","depth":8,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026","depth":9,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Calendar","depth":8,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"TOTAL SPAN","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"12.6h","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"11:35 → 00:10","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ACTIVE TIME","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(WALL CLOCK)","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"4.6h","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"BREAKS","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"3 · 8.0h","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"SESSIONS — CLICK TO FILTER","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"S1: 11:35–11:46 (11.1m)","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"S2: 12:10–13:13 (63.3m)","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"S3: 15:09–16:37 (87.1m)","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"S4: 22:16–00:10 (113.9m)","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Click a session segment to filter activity to that time window","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"S2 63m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"S3 87m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"S4 114m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"117m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"340m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"11:35","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"13:41","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"15:46","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"17:52","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"19:58","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"22:04","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"00:10","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Filtered:","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"📱 Firefox","depth":9,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"×","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"FRAMES","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2455","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"APPS","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"10","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"UI EVENTS","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"3628","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"AUDIO","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ACTIVE PERIOD","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(TIMES IN LOCAL TIMEZONE)","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"11:35 → 00:10","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"TIME PER APP","depth":9,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"— CLICK TO FILTER ALL PANELS BY APP","depth":9,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Boosteroid","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"43.4m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Firefox","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"9.7m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"iTerm2","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"5.7m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Claude","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"5.1m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"System Settings","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1.9m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Alfred","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.4m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Control Centre","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.2m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Code","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.1m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Activity Monitor","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.1m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Preview","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Websites","depth":8,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Windows","depth":8,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"UI Events","depth":8,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"screenpi.pe/onboarding","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.6m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"dennikn.sk","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.3m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"screenpi.pe/ideas","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.2m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"nas.lakylak.xyz/desktop/#/","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.2m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"screenpi.pe/why","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.2m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"www.reddit.com/r/software/comments/1fjfwg0/comment/lnr7nqd/","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.1m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"jiminny.atlassian.net/jira/software/c/projects/JY/boards/37?selectedIssue=JY-18909","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.1m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"app.dev.jiminny.com","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.1m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"addons.mozilla.org/en-US/firefox/?utm_source=firefox-browser&utm_medium=firefox-browser&utm_content=find-more-link-bottom","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.1m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"screenpi.pe/resources","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.1m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"screenpi.pe","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.1m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"mail.google.com/mail/u/0/#inbox","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.1m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"jiminny.atlassian.net/jira/software/c/projects/JY/boards/37?selectedIssue=JY-20543","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.1m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"http://localhost:3030","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.1m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"addons.mozilla.org/en-US/firefox/addon/proxy-switcher-and-manager/?utm_source=addons.mozilla.org&utm_medium=referral&utm_content=search","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.1m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"www.rtings.com/projector/reviews/dangbei/atom-laser-projector","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"www.reddit.com/r/software/comments/1fjfwg0/screenpipe_open_source_247_screen_audio_capture/","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"jiminny.atlassian.net/jira/software/c/projects/JY/boards/37","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"dennikn.sk/tema/iran/","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"dennikn.sk/5268962/sledujte-madarske-volby-ako-experti-toto-su-najdolezitejsie-veci-ktore-treba-vediet/","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"addons.mozilla.org/en-US/firefox/search/?q=profile","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
7066729612755168096
|
8694592698007632328
|
click
|
accessibility
|
NULL
|
DXP4800PLUS-B5F8
Inbox - [EMAIL] - Gmail
Shameles DXP4800PLUS-B5F8
Inbox - [EMAIL] - Gmail
Shameless • HBO Max
Shameless • HBO Max
Proeurópska bublina si po Orbánovom páde vydýchla, víťazná Tisza však môže Brusel prekvapiť — Denník N
Mute tab
Proeurópska bublina si po Orbánovom páde vydýchla, víťazná Tisza však môže Brusel prekvapiť — Denník N
Machines - Tailscale
Machines - Tailscale
Screenpipe Dashboard
Screenpipe Dashboard
Close tab
Pazaruvaj.com — Знак, че е време за най-добрите оферти
Pazaruvaj.com — Знак, че е време за най-добрите оферти
Screenpipe: Open Source 24/7 Screen & Audio Capture : r/software
Screenpipe: Open Source 24/7 Screen & Audio Capture : r/software
google maps timeline export - Google Search
google maps timeline export - Google Search
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Open history (⇧⌘H)
Open bookmarks (⌘B)
Bitwarden
Screenpipe
Screenpipe
Activity
Search
Audio
Work Report
AI Summary
Date
12
/
04
/
2026
Calendar
TOTAL SPAN
12.6h
11:35 → 00:10
ACTIVE TIME
(WALL CLOCK)
4.6h
BREAKS
3 · 8.0h
SESSIONS — CLICK TO FILTER
S1: 11:35–11:46 (11.1m)
S2: 12:10–13:13 (63.3m)
S3: 15:09–16:37 (87.1m)
S4: 22:16–00:10 (113.9m)
Click a session segment to filter activity to that time window
S2 63m
S3 87m
S4 114m
117m
340m
11:35
13:41
15:46
17:52
19:58
22:04
00:10
Filtered:
📱 Firefox
×
FRAMES
2455
APPS
10
UI EVENTS
3628
AUDIO
0
ACTIVE PERIOD
(TIMES IN LOCAL TIMEZONE)
11:35 → 00:10
TIME PER APP
— CLICK TO FILTER ALL PANELS BY APP
Boosteroid
43.4m
Firefox
9.7m
iTerm2
5.7m
Claude
5.1m
System Settings
1.9m
Alfred
0.4m
Control Centre
0.2m
Code
0.1m
Activity Monitor
0.1m
Preview
0m
Websites
Windows
UI Events
screenpi.pe/onboarding
0.6m
dennikn.sk
0.3m
screenpi.pe/ideas
0.2m
nas.lakylak.xyz/desktop/#/
0.2m
screenpi.pe/why
0.2m
www.reddit.com/r/software/comments/1fjfwg0/comment/lnr7nqd/
0.1m
jiminny.atlassian.net/jira/software/c/projects/JY/boards/37?selectedIssue=JY-18909
0.1m
app.dev.jiminny.com
0.1m
addons.mozilla.org/en-US/firefox/?utm_source=firefox-browser&utm_medium=firefox-browser&utm_content=find-more-link-bottom
0.1m
screenpi.pe/resources
0.1m
screenpi.pe
0.1m
mail.google.com/mail/u/0/#inbox
0.1m
jiminny.atlassian.net/jira/software/c/projects/JY/boards/37?selectedIssue=JY-20543
0.1m
http://localhost:3030
0.1m
addons.mozilla.org/en-US/firefox/addon/proxy-switcher-and-manager/?utm_source=addons.mozilla.org&utm_medium=referral&utm_content=search
0.1m
www.rtings.com/projector/reviews/dangbei/atom-laser-projector
0m
www.reddit.com/r/software/comments/1fjfwg0/screenpipe_open_source_247_screen_audio_capture/
0m
jiminny.atlassian.net/jira/software/c/projects/JY/boards/37
0m
dennikn.sk/tema/iran/
0m
dennikn.sk/5268962/sledujte-madarske-volby-ako-experti-toto-su-najdolezitejsie-veci-ktore-treba-vediet/
0m
addons.mozilla.org/en-US/firefox/search/?q=profile
0m...
|
NULL
|
|
7543
|
140
|
41
|
2026-04-13T16:01:19.812174+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-13/1776 /Users/lukas/.screenpipe/data/data/2026-04-13/1776096079812_m1.jpg...
|
Firefox
|
Screenpipe Dashboard — Personal
|
True
|
http://100.73.206.126:8766
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
DXP4800PLUS-B5F8
Inbox - [EMAIL] - Gmail
Shameles DXP4800PLUS-B5F8
Inbox - [EMAIL] - Gmail
Shameless • HBO Max
Shameless • HBO Max
Proeurópska bublina si po Orbánovom páde vydýchla, víťazná Tisza však môže Brusel prekvapiť — Denník N
Mute tab
Proeurópska bublina si po Orbánovom páde vydýchla, víťazná Tisza však môže Brusel prekvapiť — Denník N
Machines - Tailscale
Machines - Tailscale
Screenpipe Dashboard
Screenpipe Dashboard
Close tab
Pazaruvaj.com — Знак, че е време за най-добрите оферти
Pazaruvaj.com — Знак, че е време за най-добрите оферти
Screenpipe: Open Source 24/7 Screen & Audio Capture : r/software
Screenpipe: Open Source 24/7 Screen & Audio Capture : r/software
google maps timeline export - Google Search
google maps timeline export - Google Search
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Open history (⇧⌘H)
Open bookmarks (⌘B)
Bitwarden
Screenpipe
Screenpipe
Activity
Search
Audio
Work Report
AI Summary
Date
12
/
04
/
2026
Calendar
TOTAL SPAN
12.6h
11:35 → 00:10
ACTIVE TIME
(WALL CLOCK)
4.6h
BREAKS
3 · 8.0h
SESSIONS — CLICK TO FILTER
S1: 11:35–11:46 (11.1m)
S2: 12:10–13:13 (63.3m)
S3: 15:09–16:37 (87.1m)
S4: 22:16–00:10 (113.9m)
Click a session segment to filter activity to that time window
S2 63m
S3 87m
S4 114m
117m
340m
11:35
13:41
15:46
17:52
19:58
22:04
00:10
Filtered:
📱 Firefox
×
FRAMES
2455
APPS
10
UI EVENTS
3628
AUDIO
0
ACTIVE PERIOD
(TIMES IN LOCAL TIMEZONE)
11:35 → 00:10
TIME PER APP
— CLICK TO FILTER ALL PANELS BY APP
Boosteroid
43.4m
Firefox
9.7m
iTerm2
5.7m
Claude
5.1m
System Settings
1.9m
Alfred
0.4m
Control Centre
0.2m
Code
0.1m
Activity Monitor
0.1m
Preview
0m
Websites
Windows
UI Events
screenpi.pe/onboarding
0.6m
dennikn.sk
0.3m
screenpi.pe/ideas
0.2m
nas.lakylak.xyz/desktop/#/
0.2m
screenpi.pe/why
0.2m
www.reddit.com/r/software/comments/1fjfwg0/comment/lnr7nqd/
0.1m
jiminny.atlassian.net/jira/software/c/projects/JY/boards/37?selectedIssue=JY-18909
0.1m
app.dev.jiminny.com
0.1m
addons.mozilla.org/en-US/firefox/?utm_source=firefox-browser&utm_medium=firefox-browser&utm_content=find-more-link-bottom
0.1m
screenpi.pe/resources
0.1m
screenpi.pe
0.1m
mail.google.com/mail/u/0/#inbox
0.1m
jiminny.atlassian.net/jira/software/c/projects/JY/boards/37?selectedIssue=JY-20543
0.1m
http://localhost:3030
0.1m
addons.mozilla.org/en-US/firefox/addon/proxy-switcher-and-manager/?utm_source=addons.mozilla.org&utm_medium=referral&utm_content=search
0.1m
www.rtings.com/projector/reviews/dangbei/atom-laser-projector
0m
www.reddit.com/r/software/comments/1fjfwg0/screenpipe_open_source_247_screen_audio_capture/
0m
jiminny.atlassian.net/jira/software/c/projects/JY/boards/37
0m
dennikn.sk/tema/iran/
0m
dennikn.sk/5268962/sledujte-madarske-volby-ako-experti-toto-su-najdolezitejsie-veci-ktore-treba-vediet/
0m
addons.mozilla.org/en-US/firefox/search/?q=profile
0m...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"DXP4800PLUS-B5F8","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Inbox - kovaliklukas@gmail.com - Gmail","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Shameless • HBO Max","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Shameless • HBO Max","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Proeurópska bublina si po Orbánovom páde vydýchla, víťazná Tisza však môže Brusel prekvapiť — Denník N","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Mute tab","depth":5,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Proeurópska bublina si po Orbánovom páde vydýchla, víťazná Tisza však môže Brusel prekvapiť — Denník N","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Machines - Tailscale","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Machines - Tailscale","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Screenpipe Dashboard","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Screenpipe Dashboard","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Pazaruvaj.com — Знак, че е време за най-добрите оферти","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pazaruvaj.com — Знак, че е време за най-добрите оферти","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Screenpipe: Open Source 24/7 Screen & Audio Capture : r/software","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Screenpipe: Open Source 24/7 Screen & Audio Capture : r/software","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"google maps timeline export - Google Search","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"google maps timeline export - Google Search","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"New Tab","depth":4,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Bitwarden","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Screenpipe","depth":7,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Screenpipe","depth":8,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Activity","depth":7,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Search","depth":7,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Audio","depth":7,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Work Report","depth":7,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"AI Summary","depth":7,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Date","depth":8,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"12","depth":9,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"/","depth":8,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"04","depth":9,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"/","depth":8,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026","depth":9,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Calendar","depth":8,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"TOTAL SPAN","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"12.6h","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"11:35 → 00:10","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ACTIVE TIME","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(WALL CLOCK)","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"4.6h","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"BREAKS","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"3 · 8.0h","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"SESSIONS — CLICK TO FILTER","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"S1: 11:35–11:46 (11.1m)","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"S2: 12:10–13:13 (63.3m)","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"S3: 15:09–16:37 (87.1m)","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"S4: 22:16–00:10 (113.9m)","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Click a session segment to filter activity to that time window","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"S2 63m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"S3 87m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"S4 114m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"117m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"340m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"11:35","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"13:41","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"15:46","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"17:52","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"19:58","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"22:04","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"00:10","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Filtered:","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"📱 Firefox","depth":9,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"×","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"FRAMES","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2455","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"APPS","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"10","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"UI EVENTS","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"3628","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"AUDIO","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ACTIVE PERIOD","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(TIMES IN LOCAL TIMEZONE)","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"11:35 → 00:10","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"TIME PER APP","depth":9,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"— CLICK TO FILTER ALL PANELS BY APP","depth":9,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Boosteroid","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"43.4m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Firefox","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"9.7m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"iTerm2","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"5.7m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Claude","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"5.1m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"System Settings","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1.9m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Alfred","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.4m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Control Centre","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.2m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Code","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.1m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Activity Monitor","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.1m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Preview","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Websites","depth":8,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Windows","depth":8,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"UI Events","depth":8,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"screenpi.pe/onboarding","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.6m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"dennikn.sk","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.3m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"screenpi.pe/ideas","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.2m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"nas.lakylak.xyz/desktop/#/","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.2m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"screenpi.pe/why","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.2m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"www.reddit.com/r/software/comments/1fjfwg0/comment/lnr7nqd/","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.1m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"jiminny.atlassian.net/jira/software/c/projects/JY/boards/37?selectedIssue=JY-18909","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.1m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"app.dev.jiminny.com","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.1m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"addons.mozilla.org/en-US/firefox/?utm_source=firefox-browser&utm_medium=firefox-browser&utm_content=find-more-link-bottom","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.1m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"screenpi.pe/resources","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.1m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"screenpi.pe","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.1m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"mail.google.com/mail/u/0/#inbox","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.1m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"jiminny.atlassian.net/jira/software/c/projects/JY/boards/37?selectedIssue=JY-20543","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.1m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"http://localhost:3030","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.1m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"addons.mozilla.org/en-US/firefox/addon/proxy-switcher-and-manager/?utm_source=addons.mozilla.org&utm_medium=referral&utm_content=search","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.1m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"www.rtings.com/projector/reviews/dangbei/atom-laser-projector","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"www.reddit.com/r/software/comments/1fjfwg0/screenpipe_open_source_247_screen_audio_capture/","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"jiminny.atlassian.net/jira/software/c/projects/JY/boards/37","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"dennikn.sk/tema/iran/","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"dennikn.sk/5268962/sledujte-madarske-volby-ako-experti-toto-su-najdolezitejsie-veci-ktore-treba-vediet/","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"addons.mozilla.org/en-US/firefox/search/?q=profile","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
7066729612755168096
|
8694592698007632328
|
click
|
accessibility
|
NULL
|
DXP4800PLUS-B5F8
Inbox - [EMAIL] - Gmail
Shameles DXP4800PLUS-B5F8
Inbox - [EMAIL] - Gmail
Shameless • HBO Max
Shameless • HBO Max
Proeurópska bublina si po Orbánovom páde vydýchla, víťazná Tisza však môže Brusel prekvapiť — Denník N
Mute tab
Proeurópska bublina si po Orbánovom páde vydýchla, víťazná Tisza však môže Brusel prekvapiť — Denník N
Machines - Tailscale
Machines - Tailscale
Screenpipe Dashboard
Screenpipe Dashboard
Close tab
Pazaruvaj.com — Знак, че е време за най-добрите оферти
Pazaruvaj.com — Знак, че е време за най-добрите оферти
Screenpipe: Open Source 24/7 Screen & Audio Capture : r/software
Screenpipe: Open Source 24/7 Screen & Audio Capture : r/software
google maps timeline export - Google Search
google maps timeline export - Google Search
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Open history (⇧⌘H)
Open bookmarks (⌘B)
Bitwarden
Screenpipe
Screenpipe
Activity
Search
Audio
Work Report
AI Summary
Date
12
/
04
/
2026
Calendar
TOTAL SPAN
12.6h
11:35 → 00:10
ACTIVE TIME
(WALL CLOCK)
4.6h
BREAKS
3 · 8.0h
SESSIONS — CLICK TO FILTER
S1: 11:35–11:46 (11.1m)
S2: 12:10–13:13 (63.3m)
S3: 15:09–16:37 (87.1m)
S4: 22:16–00:10 (113.9m)
Click a session segment to filter activity to that time window
S2 63m
S3 87m
S4 114m
117m
340m
11:35
13:41
15:46
17:52
19:58
22:04
00:10
Filtered:
📱 Firefox
×
FRAMES
2455
APPS
10
UI EVENTS
3628
AUDIO
0
ACTIVE PERIOD
(TIMES IN LOCAL TIMEZONE)
11:35 → 00:10
TIME PER APP
— CLICK TO FILTER ALL PANELS BY APP
Boosteroid
43.4m
Firefox
9.7m
iTerm2
5.7m
Claude
5.1m
System Settings
1.9m
Alfred
0.4m
Control Centre
0.2m
Code
0.1m
Activity Monitor
0.1m
Preview
0m
Websites
Windows
UI Events
screenpi.pe/onboarding
0.6m
dennikn.sk
0.3m
screenpi.pe/ideas
0.2m
nas.lakylak.xyz/desktop/#/
0.2m
screenpi.pe/why
0.2m
www.reddit.com/r/software/comments/1fjfwg0/comment/lnr7nqd/
0.1m
jiminny.atlassian.net/jira/software/c/projects/JY/boards/37?selectedIssue=JY-18909
0.1m
app.dev.jiminny.com
0.1m
addons.mozilla.org/en-US/firefox/?utm_source=firefox-browser&utm_medium=firefox-browser&utm_content=find-more-link-bottom
0.1m
screenpi.pe/resources
0.1m
screenpi.pe
0.1m
mail.google.com/mail/u/0/#inbox
0.1m
jiminny.atlassian.net/jira/software/c/projects/JY/boards/37?selectedIssue=JY-20543
0.1m
http://localhost:3030
0.1m
addons.mozilla.org/en-US/firefox/addon/proxy-switcher-and-manager/?utm_source=addons.mozilla.org&utm_medium=referral&utm_content=search
0.1m
www.rtings.com/projector/reviews/dangbei/atom-laser-projector
0m
www.reddit.com/r/software/comments/1fjfwg0/screenpipe_open_source_247_screen_audio_capture/
0m
jiminny.atlassian.net/jira/software/c/projects/JY/boards/37
0m
dennikn.sk/tema/iran/
0m
dennikn.sk/5268962/sledujte-madarske-volby-ako-experti-toto-su-najdolezitejsie-veci-ktore-treba-vediet/
0m
addons.mozilla.org/en-US/firefox/search/?q=profile
0m...
|
7542
|
|
7545
|
140
|
43
|
2026-04-13T16:01:26.653164+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-13/1776 /Users/lukas/.screenpipe/data/data/2026-04-13/1776096086653_m1.jpg...
|
Firefox
|
Screenpipe Dashboard — Personal
|
True
|
http://100.73.206.126:8766
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
DXP4800PLUS-B5F8
Inbox - [EMAIL] - Gmail
Shameles DXP4800PLUS-B5F8
Inbox - [EMAIL] - Gmail
Shameless • HBO Max
Shameless • HBO Max
Proeurópska bublina si po Orbánovom páde vydýchla, víťazná Tisza však môže Brusel prekvapiť — Denník N
Mute tab
Proeurópska bublina si po Orbánovom páde vydýchla, víťazná Tisza však môže Brusel prekvapiť — Denník N
Machines - Tailscale
Machines - Tailscale
Screenpipe Dashboard
Screenpipe Dashboard
Close tab
Pazaruvaj.com — Знак, че е време за най-добрите оферти
Pazaruvaj.com — Знак, че е време за най-добрите оферти
Screenpipe: Open Source 24/7 Screen & Audio Capture : r/software
Screenpipe: Open Source 24/7 Screen & Audio Capture : r/software
google maps timeline export - Google Search
google maps timeline export - Google Search
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Open history (⇧⌘H)
Open bookmarks (⌘B)
Bitwarden
Screenpipe
Screenpipe
Activity
Search
Audio
Work Report
AI Summary
Date
12
/
04
/
2026
Calendar
TOTAL SPAN
12.6h
11:35 → 00:10
ACTIVE TIME
(WALL CLOCK)
4.6h
BREAKS
3 · 8.0h
SESSIONS — CLICK TO FILTER
S1: 11:35–11:46 (11.1m)
S2: 12:10–13:13 (63.3m)
S3: 15:09–16:37 (87.1m)
S4: 22:16–00:10 (113.9m)
Click a session segment to filter activity to that time window
S2 63m
S3 87m
S4 114m
117m
340m
11:35
13:41
15:46
17:52
19:58
22:04
00:10
Filtered:
📱 Firefox
×
FRAMES
2455
APPS
10
UI EVENTS
3628
AUDIO
0
ACTIVE PERIOD
(TIMES IN LOCAL TIMEZONE)
11:35 → 00:10
TIME PER APP
— CLICK TO FILTER ALL PANELS BY APP
Boosteroid
43.4m
Firefox
9.7m
iTerm2
5.7m
Claude
5.1m
System Settings
1.9m
Alfred
0.4m
Control Centre
0.2m
Code
0.1m
Activity Monitor
0.1m
Preview
0m
Websites
Windows
UI Events
screenpi.pe/onboarding
0.6m
dennikn.sk
0.3m
screenpi.pe/ideas
0.2m
nas.lakylak.xyz/desktop/#/
0.2m
screenpi.pe/why
0.2m
www.reddit.com/r/software/comments/1fjfwg0/comment/lnr7nqd/
0.1m
jiminny.atlassian.net/jira/software/c/projects/JY/boards/37?selectedIssue=JY-18909
0.1m
app.dev.jiminny.com
0.1m
addons.mozilla.org/en-US/firefox/?utm_source=firefox-browser&utm_medium=firefox-browser&utm_content=find-more-link-bottom
0.1m
screenpi.pe/resources
0.1m
screenpi.pe
0.1m
mail.google.com/mail/u/0/#inbox
0.1m
jiminny.atlassian.net/jira/software/c/projects/JY/boards/37?selectedIssue=JY-20543
0.1m
http://localhost:3030
0.1m
addons.mozilla.org/en-US/firefox/addon/proxy-switcher-and-manager/?utm_source=addons.mozilla.org&utm_medium=referral&utm_content=search
0.1m
www.rtings.com/projector/reviews/dangbei/atom-laser-projector
0m
www.reddit.com/r/software/comments/1fjfwg0/screenpipe_open_source_247_screen_audio_capture/
0m
jiminny.atlassian.net/jira/software/c/projects/JY/boards/37
0m
dennikn.sk/tema/iran/
0m
dennikn.sk/5268962/sledujte-madarske-volby-ako-experti-toto-su-najdolezitejsie-veci-ktore-treba-vediet/
0m
addons.mozilla.org/en-US/firefox/search/?q=profile
0m...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"DXP4800PLUS-B5F8","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Inbox - kovaliklukas@gmail.com - Gmail","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Shameless • HBO Max","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Shameless • HBO Max","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Proeurópska bublina si po Orbánovom páde vydýchla, víťazná Tisza však môže Brusel prekvapiť — Denník N","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Mute tab","depth":5,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Proeurópska bublina si po Orbánovom páde vydýchla, víťazná Tisza však môže Brusel prekvapiť — Denník N","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Machines - Tailscale","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Machines - Tailscale","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Screenpipe Dashboard","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Screenpipe Dashboard","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Pazaruvaj.com — Знак, че е време за най-добрите оферти","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pazaruvaj.com — Знак, че е време за най-добрите оферти","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Screenpipe: Open Source 24/7 Screen & Audio Capture : r/software","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Screenpipe: Open Source 24/7 Screen & Audio Capture : r/software","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"google maps timeline export - Google Search","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"google maps timeline export - Google Search","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"New Tab","depth":4,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Bitwarden","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Screenpipe","depth":7,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Screenpipe","depth":8,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Activity","depth":7,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Search","depth":7,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Audio","depth":7,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Work Report","depth":7,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"AI Summary","depth":7,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Date","depth":8,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"12","depth":9,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"/","depth":8,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"04","depth":9,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"/","depth":8,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026","depth":9,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Calendar","depth":8,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"TOTAL SPAN","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"12.6h","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"11:35 → 00:10","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ACTIVE TIME","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(WALL CLOCK)","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"4.6h","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"BREAKS","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"3 · 8.0h","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"SESSIONS — CLICK TO FILTER","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"S1: 11:35–11:46 (11.1m)","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"S2: 12:10–13:13 (63.3m)","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"S3: 15:09–16:37 (87.1m)","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"S4: 22:16–00:10 (113.9m)","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Click a session segment to filter activity to that time window","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"S2 63m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"S3 87m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"S4 114m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"117m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"340m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"11:35","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"13:41","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"15:46","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"17:52","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"19:58","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"22:04","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"00:10","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Filtered:","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"📱 Firefox","depth":9,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"×","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"FRAMES","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2455","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"APPS","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"10","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"UI EVENTS","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"3628","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"AUDIO","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ACTIVE PERIOD","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(TIMES IN LOCAL TIMEZONE)","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"11:35 → 00:10","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"TIME PER APP","depth":9,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"— CLICK TO FILTER ALL PANELS BY APP","depth":9,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Boosteroid","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"43.4m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Firefox","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"9.7m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"iTerm2","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"5.7m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Claude","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"5.1m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"System Settings","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1.9m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Alfred","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.4m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Control Centre","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.2m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Code","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.1m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Activity Monitor","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.1m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Preview","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Websites","depth":8,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Windows","depth":8,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"UI Events","depth":8,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"screenpi.pe/onboarding","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.6m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"dennikn.sk","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.3m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"screenpi.pe/ideas","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.2m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"nas.lakylak.xyz/desktop/#/","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.2m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"screenpi.pe/why","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.2m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"www.reddit.com/r/software/comments/1fjfwg0/comment/lnr7nqd/","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.1m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"jiminny.atlassian.net/jira/software/c/projects/JY/boards/37?selectedIssue=JY-18909","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.1m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"app.dev.jiminny.com","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.1m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"addons.mozilla.org/en-US/firefox/?utm_source=firefox-browser&utm_medium=firefox-browser&utm_content=find-more-link-bottom","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.1m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"screenpi.pe/resources","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.1m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"screenpi.pe","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.1m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"mail.google.com/mail/u/0/#inbox","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.1m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"jiminny.atlassian.net/jira/software/c/projects/JY/boards/37?selectedIssue=JY-20543","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.1m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"http://localhost:3030","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.1m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"addons.mozilla.org/en-US/firefox/addon/proxy-switcher-and-manager/?utm_source=addons.mozilla.org&utm_medium=referral&utm_content=search","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.1m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"www.rtings.com/projector/reviews/dangbei/atom-laser-projector","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"www.reddit.com/r/software/comments/1fjfwg0/screenpipe_open_source_247_screen_audio_capture/","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"jiminny.atlassian.net/jira/software/c/projects/JY/boards/37","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"dennikn.sk/tema/iran/","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"dennikn.sk/5268962/sledujte-madarske-volby-ako-experti-toto-su-najdolezitejsie-veci-ktore-treba-vediet/","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"addons.mozilla.org/en-US/firefox/search/?q=profile","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
7066729612755168096
|
8694592698007632328
|
click
|
accessibility
|
NULL
|
DXP4800PLUS-B5F8
Inbox - [EMAIL] - Gmail
Shameles DXP4800PLUS-B5F8
Inbox - [EMAIL] - Gmail
Shameless • HBO Max
Shameless • HBO Max
Proeurópska bublina si po Orbánovom páde vydýchla, víťazná Tisza však môže Brusel prekvapiť — Denník N
Mute tab
Proeurópska bublina si po Orbánovom páde vydýchla, víťazná Tisza však môže Brusel prekvapiť — Denník N
Machines - Tailscale
Machines - Tailscale
Screenpipe Dashboard
Screenpipe Dashboard
Close tab
Pazaruvaj.com — Знак, че е време за най-добрите оферти
Pazaruvaj.com — Знак, че е време за най-добрите оферти
Screenpipe: Open Source 24/7 Screen & Audio Capture : r/software
Screenpipe: Open Source 24/7 Screen & Audio Capture : r/software
google maps timeline export - Google Search
google maps timeline export - Google Search
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Open history (⇧⌘H)
Open bookmarks (⌘B)
Bitwarden
Screenpipe
Screenpipe
Activity
Search
Audio
Work Report
AI Summary
Date
12
/
04
/
2026
Calendar
TOTAL SPAN
12.6h
11:35 → 00:10
ACTIVE TIME
(WALL CLOCK)
4.6h
BREAKS
3 · 8.0h
SESSIONS — CLICK TO FILTER
S1: 11:35–11:46 (11.1m)
S2: 12:10–13:13 (63.3m)
S3: 15:09–16:37 (87.1m)
S4: 22:16–00:10 (113.9m)
Click a session segment to filter activity to that time window
S2 63m
S3 87m
S4 114m
117m
340m
11:35
13:41
15:46
17:52
19:58
22:04
00:10
Filtered:
📱 Firefox
×
FRAMES
2455
APPS
10
UI EVENTS
3628
AUDIO
0
ACTIVE PERIOD
(TIMES IN LOCAL TIMEZONE)
11:35 → 00:10
TIME PER APP
— CLICK TO FILTER ALL PANELS BY APP
Boosteroid
43.4m
Firefox
9.7m
iTerm2
5.7m
Claude
5.1m
System Settings
1.9m
Alfred
0.4m
Control Centre
0.2m
Code
0.1m
Activity Monitor
0.1m
Preview
0m
Websites
Windows
UI Events
screenpi.pe/onboarding
0.6m
dennikn.sk
0.3m
screenpi.pe/ideas
0.2m
nas.lakylak.xyz/desktop/#/
0.2m
screenpi.pe/why
0.2m
www.reddit.com/r/software/comments/1fjfwg0/comment/lnr7nqd/
0.1m
jiminny.atlassian.net/jira/software/c/projects/JY/boards/37?selectedIssue=JY-18909
0.1m
app.dev.jiminny.com
0.1m
addons.mozilla.org/en-US/firefox/?utm_source=firefox-browser&utm_medium=firefox-browser&utm_content=find-more-link-bottom
0.1m
screenpi.pe/resources
0.1m
screenpi.pe
0.1m
mail.google.com/mail/u/0/#inbox
0.1m
jiminny.atlassian.net/jira/software/c/projects/JY/boards/37?selectedIssue=JY-20543
0.1m
http://localhost:3030
0.1m
addons.mozilla.org/en-US/firefox/addon/proxy-switcher-and-manager/?utm_source=addons.mozilla.org&utm_medium=referral&utm_content=search
0.1m
www.rtings.com/projector/reviews/dangbei/atom-laser-projector
0m
www.reddit.com/r/software/comments/1fjfwg0/screenpipe_open_source_247_screen_audio_capture/
0m
jiminny.atlassian.net/jira/software/c/projects/JY/boards/37
0m
dennikn.sk/tema/iran/
0m
dennikn.sk/5268962/sledujte-madarske-volby-ako-experti-toto-su-najdolezitejsie-veci-ktore-treba-vediet/
0m
addons.mozilla.org/en-US/firefox/search/?q=profile
0m...
|
7544
|
|
7491
|
139
|
38
|
2026-04-13T15:56:39.344477+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-13/1776 /Users/lukas/.screenpipe/data/data/2026-04-13/1776095799344_m1.jpg...
|
Firefox
|
Screenpipe Dashboard — Personal
|
True
|
http://100.73.206.126:8766
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
DXP4800PLUS-B5F8
Inbox - [EMAIL] - Gmail
Shameles DXP4800PLUS-B5F8
Inbox - [EMAIL] - Gmail
Shameless • HBO Max
Shameless • HBO Max
Proeurópska bublina si po Orbánovom páde vydýchla, víťazná Tisza však môže Brusel prekvapiť — Denník N
Mute tab
Proeurópska bublina si po Orbánovom páde vydýchla, víťazná Tisza však môže Brusel prekvapiť — Denník N
Machines - Tailscale
Machines - Tailscale
Screenpipe Dashboard
Screenpipe Dashboard
Close tab
Pazaruvaj.com — Знак, че е време за най-добрите оферти
Pazaruvaj.com — Знак, че е време за най-добрите оферти
Screenpipe: Open Source 24/7 Screen & Audio Capture : r/software
Screenpipe: Open Source 24/7 Screen & Audio Capture : r/software
google maps timeline export - Google Search
google maps timeline export - Google Search
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Open history (⇧⌘H)
Open bookmarks (⌘B)
Bitwarden
Screenpipe
Screenpipe
Activity
Search
Audio
Work Report
AI Summary
Date
12
/
04
/
2026
Calendar
TOTAL SPAN
12.6h
11:35 → 00:10
ACTIVE TIME
(WALL CLOCK)
4.6h
BREAKS
3 · 8.0h
SESSIONS — CLICK TO FILTER
S1: 11:35–11:46 (11.1m)
S2: 12:10–13:13 (63.3m)
S3: 15:09–16:37 (87.1m)
S4: 22:16–00:10 (113.9m)
Click a session segment to filter activity to that time window
S2 63m
S3 87m
S4 114m
117m
340m
11:35
13:41
15:46
17:52
19:58
22:04
00:10
FRAMES
2455
APPS
10
UI EVENTS
3628
AUDIO
0
ACTIVE PERIOD
(TIMES IN LOCAL TIMEZONE)
11:35 → 00:10
TIME PER APP
— CLICK TO FILTER ALL PANELS BY APP
Boosteroid
43.4m
Firefox
9.7m
iTerm2
5.7m
Claude
5.1m
System Settings
1.9m
Alfred
0.4m
Control Centre
0.2m
Code
0.1m
Activity Monitor
0.1m
Preview
0m
Websites
Windows
UI Events
screenpi.pe/onboarding
0.6m
dennikn.sk
0.3m
screenpi.pe/ideas
0.2m
nas.lakylak.xyz/desktop/#/
0.2m
screenpi.pe/why
0.2m
www.reddit.com/r/software/comments/1fjfwg0/comment/lnr7nqd/
0.1m
jiminny.atlassian.net/jira/software/c/projects/JY/boards/37?selectedIssue=JY-18909
0.1m
app.dev.jiminny.com
0.1m
addons.mozilla.org/en-US/firefox/?utm_source=firefox-browser&utm_medium=firefox-browser&utm_content=find-more-link-bottom
0.1m
screenpi.pe/resources
0.1m
screenpi.pe
0.1m
mail.google.com/mail/u/0/#inbox
0.1m
jiminny.atlassian.net/jira/software/c/projects/JY/boards/37?selectedIssue=JY-20543
0.1m
http://localhost:3030
0.1m
addons.mozilla.org/en-US/firefox/addon/proxy-switcher-and-manager/?utm_source=addons.mozilla.org&utm_medium=referral&utm_content=search
0.1m
www.rtings.com/projector/reviews/dangbei/atom-laser-projector
0m
www.reddit.com/r/software/comments/1fjfwg0/screenpipe_open_source_247_screen_audio_capture/
0m
jiminny.atlassian.net/jira/software/c/projects/JY/boards/37
0m
dennikn.sk/tema/iran/
0m
dennikn.sk/5268962/sledujte-madarske-volby-ako-experti-toto-su-najdolezitejsie-veci-ktore-treba-vediet/
0m
addons.mozilla.org/en-US/firefox/search/?q=profile
0m...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"DXP4800PLUS-B5F8","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Inbox - kovaliklukas@gmail.com - Gmail","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Shameless • HBO Max","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Shameless • HBO Max","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Proeurópska bublina si po Orbánovom páde vydýchla, víťazná Tisza však môže Brusel prekvapiť — Denník N","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Mute tab","depth":5,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Proeurópska bublina si po Orbánovom páde vydýchla, víťazná Tisza však môže Brusel prekvapiť — Denník N","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Machines - Tailscale","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Machines - Tailscale","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Screenpipe Dashboard","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Screenpipe Dashboard","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Pazaruvaj.com — Знак, че е време за най-добрите оферти","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pazaruvaj.com — Знак, че е време за най-добрите оферти","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Screenpipe: Open Source 24/7 Screen & Audio Capture : r/software","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Screenpipe: Open Source 24/7 Screen & Audio Capture : r/software","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"google maps timeline export - Google Search","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"google maps timeline export - Google Search","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"New Tab","depth":4,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Bitwarden","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Screenpipe","depth":7,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Screenpipe","depth":8,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Activity","depth":7,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Search","depth":7,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Audio","depth":7,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Work Report","depth":7,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"AI Summary","depth":7,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Date","depth":8,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"12","depth":9,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"/","depth":8,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"04","depth":9,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"/","depth":8,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026","depth":9,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Calendar","depth":8,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"TOTAL SPAN","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"12.6h","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"11:35 → 00:10","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ACTIVE TIME","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(WALL CLOCK)","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"4.6h","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"BREAKS","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"3 · 8.0h","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"SESSIONS — CLICK TO FILTER","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"S1: 11:35–11:46 (11.1m)","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"S2: 12:10–13:13 (63.3m)","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"S3: 15:09–16:37 (87.1m)","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"S4: 22:16–00:10 (113.9m)","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Click a session segment to filter activity to that time window","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"S2 63m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"S3 87m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"S4 114m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"117m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"340m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"11:35","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"13:41","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"15:46","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"17:52","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"19:58","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"22:04","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"00:10","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"FRAMES","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2455","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"APPS","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"10","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"UI EVENTS","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"3628","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"AUDIO","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ACTIVE PERIOD","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(TIMES IN LOCAL TIMEZONE)","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"11:35 → 00:10","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"TIME PER APP","depth":9,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"— CLICK TO FILTER ALL PANELS BY APP","depth":9,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Boosteroid","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"43.4m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Firefox","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"9.7m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"iTerm2","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"5.7m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Claude","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"5.1m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"System Settings","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1.9m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Alfred","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.4m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Control Centre","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.2m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Code","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.1m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Activity Monitor","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.1m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Preview","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Websites","depth":8,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Windows","depth":8,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"UI Events","depth":8,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"screenpi.pe/onboarding","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.6m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"dennikn.sk","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.3m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"screenpi.pe/ideas","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.2m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"nas.lakylak.xyz/desktop/#/","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.2m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"screenpi.pe/why","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.2m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"www.reddit.com/r/software/comments/1fjfwg0/comment/lnr7nqd/","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.1m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"jiminny.atlassian.net/jira/software/c/projects/JY/boards/37?selectedIssue=JY-18909","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.1m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"app.dev.jiminny.com","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.1m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"addons.mozilla.org/en-US/firefox/?utm_source=firefox-browser&utm_medium=firefox-browser&utm_content=find-more-link-bottom","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.1m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"screenpi.pe/resources","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.1m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"screenpi.pe","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.1m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"mail.google.com/mail/u/0/#inbox","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.1m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"jiminny.atlassian.net/jira/software/c/projects/JY/boards/37?selectedIssue=JY-20543","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.1m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"http://localhost:3030","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.1m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"addons.mozilla.org/en-US/firefox/addon/proxy-switcher-and-manager/?utm_source=addons.mozilla.org&utm_medium=referral&utm_content=search","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.1m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"www.rtings.com/projector/reviews/dangbei/atom-laser-projector","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"www.reddit.com/r/software/comments/1fjfwg0/screenpipe_open_source_247_screen_audio_capture/","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"jiminny.atlassian.net/jira/software/c/projects/JY/boards/37","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"dennikn.sk/tema/iran/","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"dennikn.sk/5268962/sledujte-madarske-volby-ako-experti-toto-su-najdolezitejsie-veci-ktore-treba-vediet/","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"addons.mozilla.org/en-US/firefox/search/?q=profile","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
-3083206748653337432
|
8694592698003438040
|
click
|
accessibility
|
NULL
|
DXP4800PLUS-B5F8
Inbox - [EMAIL] - Gmail
Shameles DXP4800PLUS-B5F8
Inbox - [EMAIL] - Gmail
Shameless • HBO Max
Shameless • HBO Max
Proeurópska bublina si po Orbánovom páde vydýchla, víťazná Tisza však môže Brusel prekvapiť — Denník N
Mute tab
Proeurópska bublina si po Orbánovom páde vydýchla, víťazná Tisza však môže Brusel prekvapiť — Denník N
Machines - Tailscale
Machines - Tailscale
Screenpipe Dashboard
Screenpipe Dashboard
Close tab
Pazaruvaj.com — Знак, че е време за най-добрите оферти
Pazaruvaj.com — Знак, че е време за най-добрите оферти
Screenpipe: Open Source 24/7 Screen & Audio Capture : r/software
Screenpipe: Open Source 24/7 Screen & Audio Capture : r/software
google maps timeline export - Google Search
google maps timeline export - Google Search
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Open history (⇧⌘H)
Open bookmarks (⌘B)
Bitwarden
Screenpipe
Screenpipe
Activity
Search
Audio
Work Report
AI Summary
Date
12
/
04
/
2026
Calendar
TOTAL SPAN
12.6h
11:35 → 00:10
ACTIVE TIME
(WALL CLOCK)
4.6h
BREAKS
3 · 8.0h
SESSIONS — CLICK TO FILTER
S1: 11:35–11:46 (11.1m)
S2: 12:10–13:13 (63.3m)
S3: 15:09–16:37 (87.1m)
S4: 22:16–00:10 (113.9m)
Click a session segment to filter activity to that time window
S2 63m
S3 87m
S4 114m
117m
340m
11:35
13:41
15:46
17:52
19:58
22:04
00:10
FRAMES
2455
APPS
10
UI EVENTS
3628
AUDIO
0
ACTIVE PERIOD
(TIMES IN LOCAL TIMEZONE)
11:35 → 00:10
TIME PER APP
— CLICK TO FILTER ALL PANELS BY APP
Boosteroid
43.4m
Firefox
9.7m
iTerm2
5.7m
Claude
5.1m
System Settings
1.9m
Alfred
0.4m
Control Centre
0.2m
Code
0.1m
Activity Monitor
0.1m
Preview
0m
Websites
Windows
UI Events
screenpi.pe/onboarding
0.6m
dennikn.sk
0.3m
screenpi.pe/ideas
0.2m
nas.lakylak.xyz/desktop/#/
0.2m
screenpi.pe/why
0.2m
www.reddit.com/r/software/comments/1fjfwg0/comment/lnr7nqd/
0.1m
jiminny.atlassian.net/jira/software/c/projects/JY/boards/37?selectedIssue=JY-18909
0.1m
app.dev.jiminny.com
0.1m
addons.mozilla.org/en-US/firefox/?utm_source=firefox-browser&utm_medium=firefox-browser&utm_content=find-more-link-bottom
0.1m
screenpi.pe/resources
0.1m
screenpi.pe
0.1m
mail.google.com/mail/u/0/#inbox
0.1m
jiminny.atlassian.net/jira/software/c/projects/JY/boards/37?selectedIssue=JY-20543
0.1m
http://localhost:3030
0.1m
addons.mozilla.org/en-US/firefox/addon/proxy-switcher-and-manager/?utm_source=addons.mozilla.org&utm_medium=referral&utm_content=search
0.1m
www.rtings.com/projector/reviews/dangbei/atom-laser-projector
0m
www.reddit.com/r/software/comments/1fjfwg0/screenpipe_open_source_247_screen_audio_capture/
0m
jiminny.atlassian.net/jira/software/c/projects/JY/boards/37
0m
dennikn.sk/tema/iran/
0m
dennikn.sk/5268962/sledujte-madarske-volby-ako-experti-toto-su-najdolezitejsie-veci-ktore-treba-vediet/
0m
addons.mozilla.org/en-US/firefox/search/?q=profile
0m...
|
7490
|
|
7503
|
140
|
1
|
2026-04-13T15:57:37.292389+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-13/1776 /Users/lukas/.screenpipe/data/data/2026-04-13/1776095857292_m1.jpg...
|
Firefox
|
Screenpipe Dashboard — Personal
|
True
|
http://100.73.206.126:8766
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
DXP4800PLUS-B5F8
Inbox - [EMAIL] - Gmail
Shameles DXP4800PLUS-B5F8
Inbox - [EMAIL] - Gmail
Shameless • HBO Max
Shameless • HBO Max
Proeurópska bublina si po Orbánovom páde vydýchla, víťazná Tisza však môže Brusel prekvapiť — Denník N
Mute tab
Proeurópska bublina si po Orbánovom páde vydýchla, víťazná Tisza však môže Brusel prekvapiť — Denník N
Machines - Tailscale
Machines - Tailscale
Screenpipe Dashboard
Screenpipe Dashboard
Close tab
Pazaruvaj.com — Знак, че е време за най-добрите оферти
Pazaruvaj.com — Знак, че е време за най-добрите оферти
Screenpipe: Open Source 24/7 Screen & Audio Capture : r/software
Screenpipe: Open Source 24/7 Screen & Audio Capture : r/software
google maps timeline export - Google Search
google maps timeline export - Google Search
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Open history (⇧⌘H)
Open bookmarks (⌘B)
Bitwarden
Screenpipe
Screenpipe
Activity
Search
Audio
Work Report
AI Summary
Date
12
/
04
/
2026
Calendar
TOTAL SPAN
12.6h
11:35 → 00:10
ACTIVE TIME
(WALL CLOCK)
4.6h
BREAKS
3 · 8.0h
SESSIONS — CLICK TO FILTER
S1: 11:35–11:46 (11.1m)
S2: 12:10–13:13 (63.3m)
S3: 15:09–16:37 (87.1m)
S4: 22:16–00:10 (113.9m)
Click a session segment to filter activity to that time window
S2 63m
S3 87m
S4 114m
117m
340m
11:35
13:41
15:46
17:52
19:58
22:04
00:10
FRAMES
2455
APPS
10
UI EVENTS
3628
AUDIO
0
ACTIVE PERIOD
(TIMES IN LOCAL TIMEZONE)
11:35 → 00:10
TIME PER APP
— CLICK TO FILTER ALL PANELS BY APP
Boosteroid
43.4m
Firefox
9.7m
iTerm2
5.7m
Claude
5.1m
System Settings
1.9m
Alfred
0.4m
Control Centre
0.2m
Code
0.1m
Activity Monitor
0.1m
Preview
0m
Websites
Windows
UI Events
screenpi.pe/onboarding
0.6m
dennikn.sk
0.3m
screenpi.pe/ideas
0.2m
nas.lakylak.xyz/desktop/#/
0.2m
screenpi.pe/why
0.2m
www.reddit.com/r/software/comments/1fjfwg0/comment/lnr7nqd/
0.1m
jiminny.atlassian.net/jira/software/c/projects/JY/boards/37?selectedIssue=JY-18909
0.1m
app.dev.jiminny.com
0.1m
addons.mozilla.org/en-US/firefox/?utm_source=firefox-browser&utm_medium=firefox-browser&utm_content=find-more-link-bottom
0.1m
screenpi.pe/resources
0.1m
screenpi.pe
0.1m
mail.google.com/mail/u/0/#inbox
0.1m
jiminny.atlassian.net/jira/software/c/projects/JY/boards/37?selectedIssue=JY-20543
0.1m
http://localhost:3030
0.1m
addons.mozilla.org/en-US/firefox/addon/proxy-switcher-and-manager/?utm_source=addons.mozilla.org&utm_medium=referral&utm_content=search
0.1m
www.rtings.com/projector/reviews/dangbei/atom-laser-projector
0m
www.reddit.com/r/software/comments/1fjfwg0/screenpipe_open_source_247_screen_audio_capture/
0m
jiminny.atlassian.net/jira/software/c/projects/JY/boards/37
0m
dennikn.sk/tema/iran/
0m
dennikn.sk/5268962/sledujte-madarske-volby-ako-experti-toto-su-najdolezitejsie-veci-ktore-treba-vediet/
0m
addons.mozilla.org/en-US/firefox/search/?q=profile
0m...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"DXP4800PLUS-B5F8","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Inbox - kovaliklukas@gmail.com - Gmail","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Shameless • HBO Max","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Shameless • HBO Max","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Proeurópska bublina si po Orbánovom páde vydýchla, víťazná Tisza však môže Brusel prekvapiť — Denník N","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Mute tab","depth":5,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Proeurópska bublina si po Orbánovom páde vydýchla, víťazná Tisza však môže Brusel prekvapiť — Denník N","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Machines - Tailscale","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Machines - Tailscale","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Screenpipe Dashboard","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Screenpipe Dashboard","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Pazaruvaj.com — Знак, че е време за най-добрите оферти","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pazaruvaj.com — Знак, че е време за най-добрите оферти","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Screenpipe: Open Source 24/7 Screen & Audio Capture : r/software","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Screenpipe: Open Source 24/7 Screen & Audio Capture : r/software","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"google maps timeline export - Google Search","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"google maps timeline export - Google Search","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"New Tab","depth":4,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Bitwarden","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Screenpipe","depth":7,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Screenpipe","depth":8,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Activity","depth":7,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Search","depth":7,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Audio","depth":7,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Work Report","depth":7,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"AI Summary","depth":7,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Date","depth":8,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"12","depth":9,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"/","depth":8,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"04","depth":9,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"/","depth":8,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026","depth":9,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Calendar","depth":8,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"TOTAL SPAN","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"12.6h","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"11:35 → 00:10","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ACTIVE TIME","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(WALL CLOCK)","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"4.6h","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"BREAKS","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"3 · 8.0h","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"SESSIONS — CLICK TO FILTER","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"S1: 11:35–11:46 (11.1m)","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"S2: 12:10–13:13 (63.3m)","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"S3: 15:09–16:37 (87.1m)","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"S4: 22:16–00:10 (113.9m)","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Click a session segment to filter activity to that time window","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"S2 63m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"S3 87m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"S4 114m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"117m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"340m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"11:35","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"13:41","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"15:46","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"17:52","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"19:58","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"22:04","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"00:10","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"FRAMES","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2455","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"APPS","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"10","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"UI EVENTS","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"3628","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"AUDIO","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ACTIVE PERIOD","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(TIMES IN LOCAL TIMEZONE)","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"11:35 → 00:10","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"TIME PER APP","depth":9,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"— CLICK TO FILTER ALL PANELS BY APP","depth":9,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Boosteroid","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"43.4m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Firefox","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"9.7m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"iTerm2","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"5.7m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Claude","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"5.1m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"System Settings","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1.9m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Alfred","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.4m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Control Centre","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.2m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Code","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.1m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Activity Monitor","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.1m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Preview","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Websites","depth":8,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Windows","depth":8,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"UI Events","depth":8,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"screenpi.pe/onboarding","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.6m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"dennikn.sk","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.3m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"screenpi.pe/ideas","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.2m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"nas.lakylak.xyz/desktop/#/","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.2m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"screenpi.pe/why","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.2m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"www.reddit.com/r/software/comments/1fjfwg0/comment/lnr7nqd/","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.1m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"jiminny.atlassian.net/jira/software/c/projects/JY/boards/37?selectedIssue=JY-18909","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.1m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"app.dev.jiminny.com","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.1m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"addons.mozilla.org/en-US/firefox/?utm_source=firefox-browser&utm_medium=firefox-browser&utm_content=find-more-link-bottom","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.1m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"screenpi.pe/resources","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.1m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"screenpi.pe","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.1m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"mail.google.com/mail/u/0/#inbox","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.1m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"jiminny.atlassian.net/jira/software/c/projects/JY/boards/37?selectedIssue=JY-20543","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.1m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"http://localhost:3030","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.1m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"addons.mozilla.org/en-US/firefox/addon/proxy-switcher-and-manager/?utm_source=addons.mozilla.org&utm_medium=referral&utm_content=search","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.1m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"www.rtings.com/projector/reviews/dangbei/atom-laser-projector","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"www.reddit.com/r/software/comments/1fjfwg0/screenpipe_open_source_247_screen_audio_capture/","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"jiminny.atlassian.net/jira/software/c/projects/JY/boards/37","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"dennikn.sk/tema/iran/","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"dennikn.sk/5268962/sledujte-madarske-volby-ako-experti-toto-su-najdolezitejsie-veci-ktore-treba-vediet/","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"addons.mozilla.org/en-US/firefox/search/?q=profile","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
-3083206748653337432
|
8694592698003438040
|
click
|
accessibility
|
NULL
|
DXP4800PLUS-B5F8
Inbox - [EMAIL] - Gmail
Shameles DXP4800PLUS-B5F8
Inbox - [EMAIL] - Gmail
Shameless • HBO Max
Shameless • HBO Max
Proeurópska bublina si po Orbánovom páde vydýchla, víťazná Tisza však môže Brusel prekvapiť — Denník N
Mute tab
Proeurópska bublina si po Orbánovom páde vydýchla, víťazná Tisza však môže Brusel prekvapiť — Denník N
Machines - Tailscale
Machines - Tailscale
Screenpipe Dashboard
Screenpipe Dashboard
Close tab
Pazaruvaj.com — Знак, че е време за най-добрите оферти
Pazaruvaj.com — Знак, че е време за най-добрите оферти
Screenpipe: Open Source 24/7 Screen & Audio Capture : r/software
Screenpipe: Open Source 24/7 Screen & Audio Capture : r/software
google maps timeline export - Google Search
google maps timeline export - Google Search
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Open history (⇧⌘H)
Open bookmarks (⌘B)
Bitwarden
Screenpipe
Screenpipe
Activity
Search
Audio
Work Report
AI Summary
Date
12
/
04
/
2026
Calendar
TOTAL SPAN
12.6h
11:35 → 00:10
ACTIVE TIME
(WALL CLOCK)
4.6h
BREAKS
3 · 8.0h
SESSIONS — CLICK TO FILTER
S1: 11:35–11:46 (11.1m)
S2: 12:10–13:13 (63.3m)
S3: 15:09–16:37 (87.1m)
S4: 22:16–00:10 (113.9m)
Click a session segment to filter activity to that time window
S2 63m
S3 87m
S4 114m
117m
340m
11:35
13:41
15:46
17:52
19:58
22:04
00:10
FRAMES
2455
APPS
10
UI EVENTS
3628
AUDIO
0
ACTIVE PERIOD
(TIMES IN LOCAL TIMEZONE)
11:35 → 00:10
TIME PER APP
— CLICK TO FILTER ALL PANELS BY APP
Boosteroid
43.4m
Firefox
9.7m
iTerm2
5.7m
Claude
5.1m
System Settings
1.9m
Alfred
0.4m
Control Centre
0.2m
Code
0.1m
Activity Monitor
0.1m
Preview
0m
Websites
Windows
UI Events
screenpi.pe/onboarding
0.6m
dennikn.sk
0.3m
screenpi.pe/ideas
0.2m
nas.lakylak.xyz/desktop/#/
0.2m
screenpi.pe/why
0.2m
www.reddit.com/r/software/comments/1fjfwg0/comment/lnr7nqd/
0.1m
jiminny.atlassian.net/jira/software/c/projects/JY/boards/37?selectedIssue=JY-18909
0.1m
app.dev.jiminny.com
0.1m
addons.mozilla.org/en-US/firefox/?utm_source=firefox-browser&utm_medium=firefox-browser&utm_content=find-more-link-bottom
0.1m
screenpi.pe/resources
0.1m
screenpi.pe
0.1m
mail.google.com/mail/u/0/#inbox
0.1m
jiminny.atlassian.net/jira/software/c/projects/JY/boards/37?selectedIssue=JY-20543
0.1m
http://localhost:3030
0.1m
addons.mozilla.org/en-US/firefox/addon/proxy-switcher-and-manager/?utm_source=addons.mozilla.org&utm_medium=referral&utm_content=search
0.1m
www.rtings.com/projector/reviews/dangbei/atom-laser-projector
0m
www.reddit.com/r/software/comments/1fjfwg0/screenpipe_open_source_247_screen_audio_capture/
0m
jiminny.atlassian.net/jira/software/c/projects/JY/boards/37
0m
dennikn.sk/tema/iran/
0m
dennikn.sk/5268962/sledujte-madarske-volby-ako-experti-toto-su-najdolezitejsie-veci-ktore-treba-vediet/
0m
addons.mozilla.org/en-US/firefox/search/?q=profile
0m...
|
7502
|
|
7519
|
140
|
17
|
2026-04-13T15:58:10.872683+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-13/1776 /Users/lukas/.screenpipe/data/data/2026-04-13/1776095890872_m1.jpg...
|
Firefox
|
Screenpipe Dashboard — Personal
|
True
|
http://100.73.206.126:8766
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
DXP4800PLUS-B5F8
Inbox - [EMAIL] - Gmail
Shameles DXP4800PLUS-B5F8
Inbox - [EMAIL] - Gmail
Shameless • HBO Max
Shameless • HBO Max
Proeurópska bublina si po Orbánovom páde vydýchla, víťazná Tisza však môže Brusel prekvapiť — Denník N
Mute tab
Proeurópska bublina si po Orbánovom páde vydýchla, víťazná Tisza však môže Brusel prekvapiť — Denník N
Machines - Tailscale
Machines - Tailscale
Screenpipe Dashboard
Screenpipe Dashboard
Close tab
Pazaruvaj.com — Знак, че е време за най-добрите оферти
Pazaruvaj.com — Знак, че е време за най-добрите оферти
Screenpipe: Open Source 24/7 Screen & Audio Capture : r/software
Screenpipe: Open Source 24/7 Screen & Audio Capture : r/software
google maps timeline export - Google Search
google maps timeline export - Google Search
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Open history (⇧⌘H)
Open bookmarks (⌘B)
Bitwarden
Screenpipe
Screenpipe
Activity
Search
Audio
Work Report
AI Summary
Date
12
/
04
/
2026
Calendar
TOTAL SPAN
12.6h
11:35 → 00:10
ACTIVE TIME
(WALL CLOCK)
4.6h
BREAKS
3 · 8.0h
SESSIONS — CLICK TO FILTER
S1: 11:35–11:46 (11.1m)
S2: 12:10–13:13 (63.3m)
S3: 15:09–16:37 (87.1m)
S4: 22:16–00:10 (113.9m)
Click a session segment to filter activity to that time window
S2 63m
S3 87m
S4 114m
117m
340m
11:35
13:41
15:46
17:52
19:58
22:04
00:10
FRAMES
2455
APPS
10
UI EVENTS
3628
AUDIO
0
ACTIVE PERIOD
(TIMES IN LOCAL TIMEZONE)
11:35 → 00:10
TIME PER APP
— CLICK TO FILTER ALL PANELS BY APP
Boosteroid
43.4m
Firefox
9.7m
iTerm2
5.7m
Claude
5.1m
System Settings
1.9m
Alfred
0.4m
Control Centre
0.2m
Code
0.1m
Activity Monitor
0.1m
Preview
0m
Websites
Windows
UI Events
screenpi.pe/onboarding
0.6m
dennikn.sk
0.3m
screenpi.pe/ideas
0.2m
nas.lakylak.xyz/desktop/#/
0.2m
screenpi.pe/why
0.2m
www.reddit.com/r/software/comments/1fjfwg0/comment/lnr7nqd/
0.1m
jiminny.atlassian.net/jira/software/c/projects/JY/boards/37?selectedIssue=JY-18909
0.1m
app.dev.jiminny.com
0.1m
addons.mozilla.org/en-US/firefox/?utm_source=firefox-browser&utm_medium=firefox-browser&utm_content=find-more-link-bottom
0.1m
screenpi.pe/resources
0.1m
screenpi.pe
0.1m
mail.google.com/mail/u/0/#inbox
0.1m
jiminny.atlassian.net/jira/software/c/projects/JY/boards/37?selectedIssue=JY-20543
0.1m
http://localhost:3030
0.1m
addons.mozilla.org/en-US/firefox/addon/proxy-switcher-and-manager/?utm_source=addons.mozilla.org&utm_medium=referral&utm_content=search
0.1m
www.rtings.com/projector/reviews/dangbei/atom-laser-projector
0m
www.reddit.com/r/software/comments/1fjfwg0/screenpipe_open_source_247_screen_audio_capture/
0m
jiminny.atlassian.net/jira/software/c/projects/JY/boards/37
0m
dennikn.sk/tema/iran/
0m
dennikn.sk/5268962/sledujte-madarske-volby-ako-experti-toto-su-najdolezitejsie-veci-ktore-treba-vediet/
0m
addons.mozilla.org/en-US/firefox/search/?q=profile
0m...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"DXP4800PLUS-B5F8","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Inbox - kovaliklukas@gmail.com - Gmail","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Shameless • HBO Max","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Shameless • HBO Max","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Proeurópska bublina si po Orbánovom páde vydýchla, víťazná Tisza však môže Brusel prekvapiť — Denník N","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Mute tab","depth":5,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Proeurópska bublina si po Orbánovom páde vydýchla, víťazná Tisza však môže Brusel prekvapiť — Denník N","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Machines - Tailscale","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Machines - Tailscale","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Screenpipe Dashboard","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Screenpipe Dashboard","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Pazaruvaj.com — Знак, че е време за най-добрите оферти","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pazaruvaj.com — Знак, че е време за най-добрите оферти","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Screenpipe: Open Source 24/7 Screen & Audio Capture : r/software","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Screenpipe: Open Source 24/7 Screen & Audio Capture : r/software","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"google maps timeline export - Google Search","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"google maps timeline export - Google Search","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"New Tab","depth":4,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Bitwarden","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Screenpipe","depth":7,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Screenpipe","depth":8,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Activity","depth":7,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Search","depth":7,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Audio","depth":7,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Work Report","depth":7,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"AI Summary","depth":7,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Date","depth":8,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"12","depth":9,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"/","depth":8,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"04","depth":9,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"/","depth":8,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026","depth":9,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Calendar","depth":8,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"TOTAL SPAN","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"12.6h","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"11:35 → 00:10","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ACTIVE TIME","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(WALL CLOCK)","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"4.6h","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"BREAKS","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"3 · 8.0h","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"SESSIONS — CLICK TO FILTER","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"S1: 11:35–11:46 (11.1m)","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"S2: 12:10–13:13 (63.3m)","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"S3: 15:09–16:37 (87.1m)","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"S4: 22:16–00:10 (113.9m)","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Click a session segment to filter activity to that time window","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"S2 63m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"S3 87m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"S4 114m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"117m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"340m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"11:35","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"13:41","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"15:46","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"17:52","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"19:58","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"22:04","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"00:10","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"FRAMES","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2455","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"APPS","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"10","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"UI EVENTS","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"3628","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"AUDIO","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ACTIVE PERIOD","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(TIMES IN LOCAL TIMEZONE)","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"11:35 → 00:10","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"TIME PER APP","depth":9,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"— CLICK TO FILTER ALL PANELS BY APP","depth":9,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Boosteroid","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"43.4m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Firefox","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"9.7m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"iTerm2","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"5.7m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Claude","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"5.1m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"System Settings","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1.9m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Alfred","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.4m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Control Centre","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.2m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Code","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.1m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Activity Monitor","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.1m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Preview","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Websites","depth":8,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Windows","depth":8,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"UI Events","depth":8,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"screenpi.pe/onboarding","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.6m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"dennikn.sk","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.3m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"screenpi.pe/ideas","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.2m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"nas.lakylak.xyz/desktop/#/","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.2m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"screenpi.pe/why","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.2m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"www.reddit.com/r/software/comments/1fjfwg0/comment/lnr7nqd/","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.1m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"jiminny.atlassian.net/jira/software/c/projects/JY/boards/37?selectedIssue=JY-18909","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.1m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"app.dev.jiminny.com","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.1m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"addons.mozilla.org/en-US/firefox/?utm_source=firefox-browser&utm_medium=firefox-browser&utm_content=find-more-link-bottom","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.1m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"screenpi.pe/resources","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.1m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"screenpi.pe","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.1m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"mail.google.com/mail/u/0/#inbox","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.1m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"jiminny.atlassian.net/jira/software/c/projects/JY/boards/37?selectedIssue=JY-20543","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.1m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"http://localhost:3030","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.1m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"addons.mozilla.org/en-US/firefox/addon/proxy-switcher-and-manager/?utm_source=addons.mozilla.org&utm_medium=referral&utm_content=search","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0.1m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"www.rtings.com/projector/reviews/dangbei/atom-laser-projector","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"www.reddit.com/r/software/comments/1fjfwg0/screenpipe_open_source_247_screen_audio_capture/","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"jiminny.atlassian.net/jira/software/c/projects/JY/boards/37","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"dennikn.sk/tema/iran/","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"dennikn.sk/5268962/sledujte-madarske-volby-ako-experti-toto-su-najdolezitejsie-veci-ktore-treba-vediet/","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"addons.mozilla.org/en-US/firefox/search/?q=profile","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0m","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
-3083206748653337432
|
8694592698003438040
|
click
|
accessibility
|
NULL
|
DXP4800PLUS-B5F8
Inbox - [EMAIL] - Gmail
Shameles DXP4800PLUS-B5F8
Inbox - [EMAIL] - Gmail
Shameless • HBO Max
Shameless • HBO Max
Proeurópska bublina si po Orbánovom páde vydýchla, víťazná Tisza však môže Brusel prekvapiť — Denník N
Mute tab
Proeurópska bublina si po Orbánovom páde vydýchla, víťazná Tisza však môže Brusel prekvapiť — Denník N
Machines - Tailscale
Machines - Tailscale
Screenpipe Dashboard
Screenpipe Dashboard
Close tab
Pazaruvaj.com — Знак, че е време за най-добрите оферти
Pazaruvaj.com — Знак, че е време за най-добрите оферти
Screenpipe: Open Source 24/7 Screen & Audio Capture : r/software
Screenpipe: Open Source 24/7 Screen & Audio Capture : r/software
google maps timeline export - Google Search
google maps timeline export - Google Search
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Open history (⇧⌘H)
Open bookmarks (⌘B)
Bitwarden
Screenpipe
Screenpipe
Activity
Search
Audio
Work Report
AI Summary
Date
12
/
04
/
2026
Calendar
TOTAL SPAN
12.6h
11:35 → 00:10
ACTIVE TIME
(WALL CLOCK)
4.6h
BREAKS
3 · 8.0h
SESSIONS — CLICK TO FILTER
S1: 11:35–11:46 (11.1m)
S2: 12:10–13:13 (63.3m)
S3: 15:09–16:37 (87.1m)
S4: 22:16–00:10 (113.9m)
Click a session segment to filter activity to that time window
S2 63m
S3 87m
S4 114m
117m
340m
11:35
13:41
15:46
17:52
19:58
22:04
00:10
FRAMES
2455
APPS
10
UI EVENTS
3628
AUDIO
0
ACTIVE PERIOD
(TIMES IN LOCAL TIMEZONE)
11:35 → 00:10
TIME PER APP
— CLICK TO FILTER ALL PANELS BY APP
Boosteroid
43.4m
Firefox
9.7m
iTerm2
5.7m
Claude
5.1m
System Settings
1.9m
Alfred
0.4m
Control Centre
0.2m
Code
0.1m
Activity Monitor
0.1m
Preview
0m
Websites
Windows
UI Events
screenpi.pe/onboarding
0.6m
dennikn.sk
0.3m
screenpi.pe/ideas
0.2m
nas.lakylak.xyz/desktop/#/
0.2m
screenpi.pe/why
0.2m
www.reddit.com/r/software/comments/1fjfwg0/comment/lnr7nqd/
0.1m
jiminny.atlassian.net/jira/software/c/projects/JY/boards/37?selectedIssue=JY-18909
0.1m
app.dev.jiminny.com
0.1m
addons.mozilla.org/en-US/firefox/?utm_source=firefox-browser&utm_medium=firefox-browser&utm_content=find-more-link-bottom
0.1m
screenpi.pe/resources
0.1m
screenpi.pe
0.1m
mail.google.com/mail/u/0/#inbox
0.1m
jiminny.atlassian.net/jira/software/c/projects/JY/boards/37?selectedIssue=JY-20543
0.1m
http://localhost:3030
0.1m
addons.mozilla.org/en-US/firefox/addon/proxy-switcher-and-manager/?utm_source=addons.mozilla.org&utm_medium=referral&utm_content=search
0.1m
www.rtings.com/projector/reviews/dangbei/atom-laser-projector
0m
www.reddit.com/r/software/comments/1fjfwg0/screenpipe_open_source_247_screen_audio_capture/
0m
jiminny.atlassian.net/jira/software/c/projects/JY/boards/37
0m
dennikn.sk/tema/iran/
0m
dennikn.sk/5268962/sledujte-madarske-volby-ako-experti-toto-su-najdolezitejsie-veci-ktore-treba-vediet/
0m
addons.mozilla.org/en-US/firefox/search/?q=profile
0m...
|
7518
|
|
7415
|
138
|
20
|
2026-04-13T15:49:19.128377+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-13/1776 /Users/lukas/.screenpipe/data/data/2026-04-13/1776095359128_m1.jpg...
|
Firefox
|
Add-ons Manager — Personal
|
True
|
dennikn.sk
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Add-ons Manager
about:addons
DXP4800PLUS-B5F8
Inbo Add-ons Manager
about:addons
DXP4800PLUS-B5F8
Inbox (10) - [EMAIL] - Gmail
Shameless • HBO Max
Shameless • HBO Max
Settings
Settings
firefox sidebar - Google Search
firefox sidebar - Google Search
How to use AI-enhanced tab groups | Firefox Help
How to use AI-enhanced tab groups | Firefox Help
Add-ons Manager
Add-ons Manager
Close tab
Denník N - Nezávislý denník
Denník N - Nezávislý denník
Proeurópska bublina si po Orbánovom páde vydýchla, víťazná Tisza však môže Brusel prekvapiť — Denník N
Mute tab
Proeurópska bublina si po Orbánovom páde vydýchla, víťazná Tisza však môže Brusel prekvapiť — Denník N
Machines - Tailscale
Machines - Tailscale
Screenpipe Dashboard
Screenpipe Dashboard
Pazaruvaj.com — Знак, че е време за най-добрите оферти
Pazaruvaj.com — Знак, че е време за най-добрите оферти
Browser Extension Getting Started | Bitwarden
Browser Extension Getting Started | Bitwarden
Extensions – Add-ons for Firefox (en-US)
Extensions – Add-ons for Firefox (en-US)
Dangbei Atom Review - RTINGS.com
Dangbei Atom Review - RTINGS.com
Screenpipe: Open Source 24/7 Screen & Audio Capture : r/software
Screenpipe: Open Source 24/7 Screen & Audio Capture : r/software
Add-ons for Firefox (en-US)
Add-ons for Firefox (en-US)
Problem loading page
Problem loading page
Welcome to Firefox
Welcome to Firefox
New Tab
Customize sidebar
Close Google Gemini (⌃X)
Open history (⇧⌘H)
Open bookmarks (⌘B)
Bitwarden
AI Chat settings
Close
Google Account: Lukáš Koválik ([EMAIL])
Main menu
New chat
Gemini
Temporary chat
PLUS
PLUS
Conversation with Gemini
Conversation with Gemini
Hi Lukáš
Where should we start?
Where should we start?
🖼️ Create image, button, tap to use tool
🖼️ Create image
🎸 Create music, button, tap to use tool
🎸 Create music
Boost my day, button, tap to use tool
Boost my day
Help me learn, button, tap to use tool
Help me learn
Write anything, button, tap to use tool
Write anything
Create a video, button, tap to use tool
Create a video
Dismiss
Try video templates instead of starting from scratch
Try it
Try it
Ask Gemini
Ask Gemini
Open upload file menu
Tools
Open mode picker
Pro
Microphone
Summarize page
Summarize page
Recommendations
Recommendations
Extensions
Extensions
Themes
Themes
Plugins
Plugins
Firefox Settings
Firefox Settings
Add-ons Support
Add-ons Support
Find more add-ons
Search addons.mozilla.org
Search addons.mozilla.org
Personalize Your Firefox
Personalize Your Firefox
Tools for all add-ons
Extensions and themes let you customize Firefox. They can boost privacy, enhance productivity, improve media, change the way Firefox looks, and so much more. These small software programs are often developed by a third party. Here’s a selection Firefox
recommends
recommends
for exceptional security, performance, and functionality.
Some of these recommendations are personalized. They are based on other extensions you’ve installed, profile preferences, and usage statistics.
Learn more
Learn more
Close
Crimson Merlot
Crimson Merlot
by
DV8
DV8
Install Theme
ClearURLs
ClearURLs
by
Kevin
Kevin
Add to Firefox
Remove tracking elements from web links.
Users: 517,539
automaticDark - Time-Based Theme Changer
automaticDark - Time-Based Theme Changer
by
simonkhzhang
simonkhzhang...
|
[{"role":"AXStaticText","text& [{"role":"AXStaticText","text":"Add-ons Manager","depth":4,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"about:addons","depth":4,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"DXP4800PLUS-B5F8","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Inbox (10) - kovaliklukas@gmail.com - Gmail","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Shameless • HBO Max","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Shameless • HBO Max","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Settings","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Settings","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"firefox sidebar - Google Search","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"firefox sidebar - Google Search","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"How to use AI-enhanced tab groups | Firefox Help","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"How to use AI-enhanced tab groups | Firefox Help","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Add-ons Manager","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Add-ons Manager","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Denník N - Nezávislý denník","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Denník N - Nezávislý denník","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Proeurópska bublina si po Orbánovom páde vydýchla, víťazná Tisza však môže Brusel prekvapiť — Denník N","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Mute tab","depth":5,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Proeurópska bublina si po Orbánovom páde vydýchla, víťazná Tisza však môže Brusel prekvapiť — Denník N","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Machines - Tailscale","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Machines - Tailscale","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Screenpipe Dashboard","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Screenpipe Dashboard","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Pazaruvaj.com — Знак, че е време за най-добрите оферти","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pazaruvaj.com — Знак, че е време за най-добрите оферти","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Browser Extension Getting Started | Bitwarden","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Browser Extension Getting Started | Bitwarden","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Extensions – Add-ons for Firefox (en-US)","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Extensions – Add-ons for Firefox (en-US)","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Dangbei Atom Review - RTINGS.com","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Dangbei Atom Review - RTINGS.com","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Screenpipe: Open Source 24/7 Screen & Audio Capture : r/software","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Screenpipe: Open Source 24/7 Screen & Audio Capture : r/software","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Add-ons for Firefox (en-US)","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Add-ons for Firefox (en-US)","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Problem loading page","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Problem loading page","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Welcome to Firefox","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Welcome to Firefox","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"New Tab","depth":4,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Close Google Gemini (⌃X)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Bitwarden","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"AI Chat settings","depth":7,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Close","depth":7,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Google Account: Lukáš Koválik (kovaliklukas@gmail.com)","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Main menu","depth":12,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New chat","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Gemini","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Temporary chat","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"PLUS","depth":11,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"PLUS","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Conversation with Gemini","depth":15,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Conversation with Gemini","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Hi Lukáš","depth":23,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Where should we start?","depth":22,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Where should we start?","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"🖼️ Create image, button, tap to use tool","depth":22,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"🖼️ Create image","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"🎸 Create music, button, tap to use tool","depth":22,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"🎸 Create music","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Boost my day, button, tap to use tool","depth":22,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Boost my day","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Help me learn, button, tap to use tool","depth":22,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Help me learn","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Write anything, button, tap to use tool","depth":22,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Write anything","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Create a video, button, tap to use tool","depth":22,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Create a video","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Dismiss","depth":19,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Try video templates instead of starting from scratch","depth":20,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Try it","depth":19,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Try it","depth":21,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextArea","text":"Ask Gemini","depth":20,"value":"Ask Gemini","help_text":"","role_description":"text entry area","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Ask Gemini","depth":21,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open upload file menu","depth":20,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Tools","depth":18,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Open mode picker","depth":20,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pro","depth":23,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Microphone","depth":19,"role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Summarize page","depth":7,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Summarize page","depth":9,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Recommendations","depth":9,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Recommendations","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Extensions","depth":9,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Extensions","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Themes","depth":9,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Themes","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Plugins","depth":9,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Plugins","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Firefox Settings","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Firefox Settings","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Add-ons Support","depth":11,"bounds":{"left":0.12986112,"top":0.0,"width":0.17083333,"height":0.04222222},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Add-ons Support","depth":13,"bounds":{"left":0.16041666,"top":0.0,"width":0.075,"height":0.018888889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Find more add-ons","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"Search addons.mozilla.org","depth":12,"help_text":"","role_description":"search text field","subrole":"AXSearchField","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Search addons.mozilla.org","depth":11,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Personalize Your Firefox","depth":10,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Personalize Your Firefox","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Tools for all add-ons","depth":10,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Extensions and themes let you customize Firefox. They can boost privacy, enhance productivity, improve media, change the way Firefox looks, and so much more. These small software programs are often developed by a third party. Here’s a selection Firefox","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"recommends","depth":11,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"recommends","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"for exceptional security, performance, and functionality.","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Some of these recommendations are personalized. They are based on other extensions you’ve installed, profile preferences, and usage statistics.","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Learn more","depth":13,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Learn more","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close","depth":12,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Crimson Merlot","depth":11,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Crimson Merlot","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"DV8","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"DV8","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Install Theme","depth":11,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"ClearURLs","depth":11,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"ClearURLs","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Kevin","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Kevin","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Add to Firefox","depth":11,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Remove tracking elements from web links.","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Users: 517,539","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"automaticDark - Time-Based Theme Changer","depth":11,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"automaticDark - Time-Based Theme Changer","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"by","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"simonkhzhang","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"simonkhzhang","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
4096520111715323801
|
8693958135287073850
|
click
|
accessibility
|
NULL
|
Add-ons Manager
about:addons
DXP4800PLUS-B5F8
Inbo Add-ons Manager
about:addons
DXP4800PLUS-B5F8
Inbox (10) - [EMAIL] - Gmail
Shameless • HBO Max
Shameless • HBO Max
Settings
Settings
firefox sidebar - Google Search
firefox sidebar - Google Search
How to use AI-enhanced tab groups | Firefox Help
How to use AI-enhanced tab groups | Firefox Help
Add-ons Manager
Add-ons Manager
Close tab
Denník N - Nezávislý denník
Denník N - Nezávislý denník
Proeurópska bublina si po Orbánovom páde vydýchla, víťazná Tisza však môže Brusel prekvapiť — Denník N
Mute tab
Proeurópska bublina si po Orbánovom páde vydýchla, víťazná Tisza však môže Brusel prekvapiť — Denník N
Machines - Tailscale
Machines - Tailscale
Screenpipe Dashboard
Screenpipe Dashboard
Pazaruvaj.com — Знак, че е време за най-добрите оферти
Pazaruvaj.com — Знак, че е време за най-добрите оферти
Browser Extension Getting Started | Bitwarden
Browser Extension Getting Started | Bitwarden
Extensions – Add-ons for Firefox (en-US)
Extensions – Add-ons for Firefox (en-US)
Dangbei Atom Review - RTINGS.com
Dangbei Atom Review - RTINGS.com
Screenpipe: Open Source 24/7 Screen & Audio Capture : r/software
Screenpipe: Open Source 24/7 Screen & Audio Capture : r/software
Add-ons for Firefox (en-US)
Add-ons for Firefox (en-US)
Problem loading page
Problem loading page
Welcome to Firefox
Welcome to Firefox
New Tab
Customize sidebar
Close Google Gemini (⌃X)
Open history (⇧⌘H)
Open bookmarks (⌘B)
Bitwarden
AI Chat settings
Close
Google Account: Lukáš Koválik ([EMAIL])
Main menu
New chat
Gemini
Temporary chat
PLUS
PLUS
Conversation with Gemini
Conversation with Gemini
Hi Lukáš
Where should we start?
Where should we start?
🖼️ Create image, button, tap to use tool
🖼️ Create image
🎸 Create music, button, tap to use tool
🎸 Create music
Boost my day, button, tap to use tool
Boost my day
Help me learn, button, tap to use tool
Help me learn
Write anything, button, tap to use tool
Write anything
Create a video, button, tap to use tool
Create a video
Dismiss
Try video templates instead of starting from scratch
Try it
Try it
Ask Gemini
Ask Gemini
Open upload file menu
Tools
Open mode picker
Pro
Microphone
Summarize page
Summarize page
Recommendations
Recommendations
Extensions
Extensions
Themes
Themes
Plugins
Plugins
Firefox Settings
Firefox Settings
Add-ons Support
Add-ons Support
Find more add-ons
Search addons.mozilla.org
Search addons.mozilla.org
Personalize Your Firefox
Personalize Your Firefox
Tools for all add-ons
Extensions and themes let you customize Firefox. They can boost privacy, enhance productivity, improve media, change the way Firefox looks, and so much more. These small software programs are often developed by a third party. Here’s a selection Firefox
recommends
recommends
for exceptional security, performance, and functionality.
Some of these recommendations are personalized. They are based on other extensions you’ve installed, profile preferences, and usage statistics.
Learn more
Learn more
Close
Crimson Merlot
Crimson Merlot
by
DV8
DV8
Install Theme
ClearURLs
ClearURLs
by
Kevin
Kevin
Add to Firefox
Remove tracking elements from web links.
Users: 517,539
automaticDark - Time-Based Theme Changer
automaticDark - Time-Based Theme Changer
by
simonkhzhang
simonkhzhang...
|
7414
|
|
47581
|
1008
|
31
|
2026-04-17T11:48:55.154144+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-17/1776 /Users/lukas/.screenpipe/data/data/2026-04-17/1776426535154_m2.jpg...
|
Firefox
|
App "Zoho CRM" · Jiminny · Membrane — Work
|
True
|
console.getmembrane.com/w/66fd5a6e813fde5d1b8aa505 console.getmembrane.com/w/66fd5a6e813fde5d1b8aa505?element=/integrations/66fe6c913202f3a165e3c14d...
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Workers | Datadog
Developers | HubSpot
Developers Workers | Datadog
Developers | HubSpot
Developers | HubSpot
Inbox (1,576) - [EMAIL] - Jiminny Mail
Inbox (1,576) - [EMAIL] - Jiminny Mail
120216 is your HubSpot Log In Code - [EMAIL] - Jiminny Mail
120216 is your HubSpot Log In Code - [EMAIL] - Jiminny Mail
CloudWatch | eu-west-1
CloudWatch | eu-west-1
New Tab
New Tab
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
fix-cache-for-business-processes by ilian-jiminny · Pull Request #11985 · jiminny/app
fix-cache-for-business-processes by ilian-jiminny · Pull Request #11985 · jiminny/app
[JY-20692] Issue with reconnecting Zoho - Jira
[JY-20692] Issue with reconnecting Zoho - Jira
Jiminny
Jiminny
Auth Proxy
Auth Proxy
Dashboard · Jiminny · Membrane
Dashboard · Jiminny · Membrane
App "Zoho CRM" · Jiminny · Membrane
App "Zoho CRM" · Jiminny · Membrane
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Workspace: Jiminny
Jiminny
Search
⌘K
Dashboard
Dashboard
Explore
Explore
Activity
Activity
Settings
Settings
Docs
Docs
Logout
Version
2026-04-16
Integrations
Integrations
Zoho CRM
Zoho CRM
Status:
Success
Ready
Test
Test
Add to your product
Add to your product
Basic Info
Basic Info
Name
Zoho CRM
Key
zohocrm
Description
Add a description for this integration
Logo
https://static.integration.app/connectors/zoho-crm/logo.png
Zoho CRM
App
Connector
Zoho CRM Zoho CRM
Zoho CRM
Connector Version
Connector Version
Current Version:
3.0.3
Parameters
Parameters
Editor content
Options
Options
Connect via Membrane
Connect via Membrane
OAuth 2.0
OAuth 2.0
Configuration guide
Client ID
Field is required
Client Secret
Field is required
Scopes
Delete
Add Scopes Item
oAuth Configuration
oAuth Configuration
In some cases you may need to use a custom Callback URL instead of the default one. It will be used for all connections created for this integration.
OAuth Callback URI
https://api.integration.app/oauth-callback
Explore
Explore
Connections 22
Connections
22
Packages 0
Packages
0
Actions 44
Actions
44
Flows 10
Flows
10
External Event Subscriptions 237
External Event Subscriptions
237
Internal Event Subscriptions 0
Internal Event Subscriptions
0
Data Sources 7
Data Sources
7
Field Mappings 6
Field Mappings
6
Internal Data Schemas 0
Internal Data Schemas
0
Data Link Tables 0
Data Link Tables
0
System Activity
System Activity
Last 7 days
Last 7 days
Flow Runs 9765 Status: Success 678 Status: Error
Flow Runs
9765
Status:
Success
678
Status:
Error
Action Runs 18529 Status: Success 6732 Status: Error
Action Runs...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Workers | Datadog","depth":4,"bounds":{"left":0.00234375,"top":0.045138888,"width":0.0890625,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Developers | HubSpot","depth":4,"bounds":{"left":0.0,"top":0.08263889,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Developers | HubSpot","depth":5,"bounds":{"left":0.015625,"top":0.09236111,"width":0.04453125,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Inbox (1,576) - lukas.kovalik@jiminny.com - Jiminny Mail","depth":4,"bounds":{"left":0.0,"top":0.11111111,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Inbox (1,576) - lukas.kovalik@jiminny.com - Jiminny Mail","depth":5,"bounds":{"left":0.015625,"top":0.12083333,"width":0.11445312,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"120216 is your HubSpot Log In Code - integration-account@jiminny.com - Jiminny Mail","depth":4,"bounds":{"left":0.0,"top":0.13958333,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"120216 is your HubSpot Log In Code - integration-account@jiminny.com - Jiminny Mail","depth":5,"bounds":{"left":0.015625,"top":0.14930555,"width":0.17734376,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"CloudWatch | eu-west-1","depth":4,"bounds":{"left":0.0,"top":0.16805555,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"CloudWatch | eu-west-1","depth":5,"bounds":{"left":0.015625,"top":0.17777778,"width":0.048828125,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"New Tab","depth":4,"bounds":{"left":0.0,"top":0.19652778,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"New Tab","depth":5,"bounds":{"left":0.015625,"top":0.20625,"width":0.017578125,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":4,"bounds":{"left":0.0,"top":0.225,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":5,"bounds":{"left":0.015625,"top":0.23472223,"width":0.1515625,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"fix-cache-for-business-processes by ilian-jiminny · Pull Request #11985 · jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.2534722,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"fix-cache-for-business-processes by ilian-jiminny · Pull Request #11985 · jiminny/app","depth":5,"bounds":{"left":0.015625,"top":0.26319444,"width":0.17421874,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[JY-20692] Issue with reconnecting Zoho - Jira","depth":4,"bounds":{"left":0.0,"top":0.28194445,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[JY-20692] Issue with reconnecting Zoho - Jira","depth":5,"bounds":{"left":0.015625,"top":0.29166666,"width":0.09726562,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jiminny","depth":4,"bounds":{"left":0.0,"top":0.31041667,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny","depth":5,"bounds":{"left":0.015625,"top":0.3201389,"width":0.015625,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Auth Proxy","depth":4,"bounds":{"left":0.0,"top":0.33888888,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Auth Proxy","depth":5,"bounds":{"left":0.015625,"top":0.34861112,"width":0.021875,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Dashboard · Jiminny · Membrane","depth":4,"bounds":{"left":0.0,"top":0.3673611,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Dashboard · Jiminny · Membrane","depth":5,"bounds":{"left":0.015625,"top":0.37708333,"width":0.06679688,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"App \"Zoho CRM\" · Jiminny · Membrane","depth":4,"bounds":{"left":0.0,"top":0.39583334,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"App \"Zoho CRM\" · Jiminny · Membrane","depth":5,"bounds":{"left":0.015625,"top":0.40555555,"width":0.0796875,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.07890625,"top":0.40208334,"width":0.009375,"height":0.016666668},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Tab","depth":4,"bounds":{"left":0.003125,"top":0.42569444,"width":0.08710937,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.003125,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"bounds":{"left":0.01640625,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"bounds":{"left":0.029296875,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"bounds":{"left":0.0421875,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"bounds":{"left":0.05546875,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Workspace: Jiminny","depth":10,"bounds":{"left":0.09609375,"top":0.047916666,"width":0.0265625,"height":0.05277778},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny","depth":12,"bounds":{"left":0.09921875,"top":0.088194445,"width":0.01484375,"height":0.009027778},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Search","depth":10,"bounds":{"left":0.09765625,"top":0.10625,"width":0.0234375,"height":0.023611112},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"⌘K","depth":11,"bounds":{"left":0.11054687,"top":0.11388889,"width":0.00546875,"height":0.008333334},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Dashboard","depth":11,"bounds":{"left":0.09609375,"top":0.13541667,"width":0.0265625,"height":0.038194444},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Dashboard","depth":12,"bounds":{"left":0.09921875,"top":0.15833333,"width":0.0203125,"height":0.009027778},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Explore","depth":11,"bounds":{"left":0.09609375,"top":0.17638889,"width":0.0265625,"height":0.038194444},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Explore","depth":12,"bounds":{"left":0.10234375,"top":0.19930555,"width":0.0140625,"height":0.009027778},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Activity","depth":11,"bounds":{"left":0.09609375,"top":0.21736111,"width":0.0265625,"height":0.038194444},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Activity","depth":12,"bounds":{"left":0.10195313,"top":0.24027778,"width":0.01484375,"height":0.009027778},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Settings","depth":11,"bounds":{"left":0.09609375,"top":0.25833333,"width":0.0265625,"height":0.038194444},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Settings","depth":12,"bounds":{"left":0.1015625,"top":0.28125,"width":0.015625,"height":0.009027778},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Docs","depth":11,"bounds":{"left":0.09609375,"top":0.30833334,"width":0.0265625,"height":0.038194444},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Docs","depth":12,"bounds":{"left":0.10234375,"top":0.33125,"width":0.009375,"height":0.009027778},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Logout","depth":10,"bounds":{"left":0.09609375,"top":0.9166667,"width":0.0265625,"height":0.038194444},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Version","depth":11,"bounds":{"left":0.10234375,"top":0.9673611,"width":0.0140625,"height":0.009027778},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-04-16","depth":11,"bounds":{"left":0.0984375,"top":0.9791667,"width":0.021875,"height":0.009027778},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Integrations","depth":18,"bounds":{"left":0.1296875,"top":0.054166667,"width":0.03046875,"height":0.0125},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Integrations","depth":19,"bounds":{"left":0.1296875,"top":0.054166667,"width":0.03046875,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Zoho CRM","depth":18,"bounds":{"left":0.16835937,"top":0.054166667,"width":0.026953125,"height":0.0125},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Zoho CRM","depth":19,"bounds":{"left":0.16835937,"top":0.054166667,"width":0.026953125,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Status:","depth":17,"bounds":{"left":0.20078126,"top":0.057638887,"width":0.016796876,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Success","depth":17,"bounds":{"left":0.21757813,"top":0.057638887,"width":0.01875,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Ready","depth":15,"bounds":{"left":0.20664063,"top":0.055555556,"width":0.0140625,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Test","depth":15,"bounds":{"left":0.55507815,"top":0.050694443,"width":0.032421876,"height":0.019444445},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Test","depth":16,"bounds":{"left":0.56953126,"top":0.054166667,"width":0.011328125,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Add to your product","depth":15,"bounds":{"left":0.6046875,"top":0.050694443,"width":0.071875,"height":0.019444445},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Add to your product","depth":17,"bounds":{"left":0.61875,"top":0.054166667,"width":0.0515625,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Basic Info","depth":16,"bounds":{"left":0.15664062,"top":0.10902778,"width":0.02578125,"height":0.014583333},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Basic Info","depth":17,"bounds":{"left":0.15664062,"top":0.10972222,"width":0.02578125,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Name","depth":17,"bounds":{"left":0.1484375,"top":0.14861111,"width":0.015234375,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"Zoho CRM","depth":16,"bounds":{"left":0.20664063,"top":0.1423611,"width":0.22695312,"height":0.025},"value":"Zoho CRM","help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Key","depth":17,"bounds":{"left":0.1484375,"top":0.18055555,"width":0.009765625,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"zohocrm","depth":16,"bounds":{"left":0.20664063,"top":0.17430556,"width":0.22695312,"height":0.025},"value":"zohocrm","help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Description","depth":17,"bounds":{"left":0.1484375,"top":0.21319444,"width":0.030078124,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"","depth":16,"bounds":{"left":0.21289062,"top":0.21041666,"width":0.21757813,"height":0.055555556},"value":"","help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Add a description for this integration","depth":17,"bounds":{"left":0.21289062,"top":0.21180555,"width":0.09414063,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Logo","depth":17,"bounds":{"left":0.1484375,"top":0.28541666,"width":0.012890625,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"https://static.integration.app/connectors/zoho-crm/logo.png","depth":16,"bounds":{"left":0.20664063,"top":0.27916667,"width":0.209375,"height":0.025},"value":"https://static.integration.app/connectors/zoho-crm/logo.png","help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Zoho CRM","depth":17,"bounds":{"left":0.4203125,"top":0.28125,"width":0.009375,"height":0.016666668},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"App","depth":16,"bounds":{"left":0.1484375,"top":0.32083333,"width":0.010546875,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Connector","depth":16,"bounds":{"left":0.1484375,"top":0.35555556,"width":0.026953125,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXComboBox","text":"Zoho CRM Zoho CRM","depth":18,"bounds":{"left":0.20664063,"top":0.34791666,"width":0.2125,"height":0.027777778},"value":"Zoho CRM Zoho CRM","help_text":"","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Zoho CRM","depth":19,"bounds":{"left":0.22382812,"top":0.35555556,"width":0.02734375,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Connector Version","depth":16,"bounds":{"left":0.14726563,"top":0.40625,"width":0.04921875,"height":0.014583333},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Connector Version","depth":17,"bounds":{"left":0.14726563,"top":0.40763888,"width":0.04921875,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Current Version:","depth":16,"bounds":{"left":0.14414063,"top":0.44027779,"width":0.0421875,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"3.0.3","depth":16,"bounds":{"left":0.18789062,"top":0.44027779,"width":0.01171875,"height":0.0125},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Parameters","depth":16,"bounds":{"left":0.15273437,"top":0.48402777,"width":0.03046875,"height":0.014583333},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Parameters","depth":17,"bounds":{"left":0.15273437,"top":0.48541668,"width":0.03046875,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextArea","text":"Editor content","depth":20,"help_text":"","role_description":"editor","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Options","depth":16,"bounds":{"left":0.15273437,"top":0.65833336,"width":0.020703126,"height":0.014583333},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Options","depth":17,"bounds":{"left":0.15273437,"top":0.6597222,"width":0.020703126,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Connect via Membrane","depth":16,"bounds":{"left":0.16835937,"top":0.70416665,"width":0.061328124,"height":0.014583333},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Connect via Membrane","depth":17,"bounds":{"left":0.16835937,"top":0.70555556,"width":0.061328124,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"OAuth 2.0","depth":16,"bounds":{"left":0.16835937,"top":0.75,"width":0.0265625,"height":0.014583333},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"OAuth 2.0","depth":17,"bounds":{"left":0.16835937,"top":0.7513889,"width":0.0265625,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Configuration guide","depth":16,"bounds":{"left":0.15976563,"top":0.78333336,"width":0.27421874,"height":0.0125},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Client ID","depth":17,"bounds":{"left":0.1640625,"top":0.81666666,"width":0.021875,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Field is required","depth":18,"bounds":{"left":0.21484375,"top":0.82361114,"width":0.041015625,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"","depth":19,"bounds":{"left":0.22382812,"top":0.8138889,"width":0.20820312,"height":0.01875},"value":"","help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Client Secret","depth":17,"bounds":{"left":0.1640625,"top":0.84791666,"width":0.03359375,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Field is required","depth":18,"bounds":{"left":0.21484375,"top":0.85486114,"width":0.041015625,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"","depth":19,"bounds":{"left":0.22382812,"top":0.8451389,"width":0.20820312,"height":0.01875},"value":"","help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Scopes","depth":17,"bounds":{"left":0.1640625,"top":0.87916666,"width":0.01953125,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Delete","depth":16,"bounds":{"left":0.22226563,"top":0.87291664,"width":0.013671875,"height":0.025},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Add Scopes Item","depth":17,"bounds":{"left":0.17226562,"top":0.90347224,"width":0.0609375,"height":0.021527778},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"oAuth Configuration","depth":16,"bounds":{"left":0.15273437,"top":0.9548611,"width":0.053515624,"height":0.014583333},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"oAuth Configuration","depth":17,"bounds":{"left":0.15273437,"top":0.95625,"width":0.053515624,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"In some cases you may need to use a custom Callback URL instead of the default one. It will be used for all connections created for this integration.","depth":17,"bounds":{"left":0.14414063,"top":0.98888886,"width":0.27617186,"height":0.01111114},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"OAuth Callback URI","depth":17,"bounds":{"left":0.1484375,"top":1.0,"width":0.05078125,"height":-0.035416722},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"https://api.integration.app/oauth-callback","depth":16,"bounds":{"left":0.20664063,"top":1.0,"width":0.22695312,"height":-0.029166698},"value":"https://api.integration.app/oauth-callback","help_text":"","role_description":"text field","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Explore","depth":16,"bounds":{"left":0.15664062,"top":1.0,"width":0.019921875,"height":-0.08472228},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Explore","depth":17,"bounds":{"left":0.15664062,"top":1.0,"width":0.019921875,"height":-0.08611107},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Connections 22","depth":16,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Connections","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"22","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Packages 0","depth":16,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Packages","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Actions 44","depth":16,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Actions","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"44","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Flows 10","depth":16,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Flows","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"10","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"External Event Subscriptions 237","depth":16,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"External Event Subscriptions","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"237","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Internal Event Subscriptions 0","depth":16,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Internal Event Subscriptions","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Data Sources 7","depth":16,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Data Sources","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"7","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Field Mappings 6","depth":16,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Field Mappings","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"6","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Internal Data Schemas 0","depth":16,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Internal Data Schemas","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Data Link Tables 0","depth":16,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Data Link Tables","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"0","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"System Activity","depth":16,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"System Activity","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXComboBox","text":"Last 7 days","depth":18,"value":"Last 7 days","help_text":"","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Last 7 days","depth":20,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Flow Runs 9765 Status: Success 678 Status: Error","depth":16,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Flow Runs","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"9765","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Status:","depth":19,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Success","depth":19,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"678","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Status:","depth":19,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Error","depth":19,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Action Runs 18529 Status: Success 6732 Status: Error","depth":16,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Action Runs","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
1491689937559550185
|
8689448196169034369
|
visual_change
|
accessibility
|
NULL
|
Workers | Datadog
Developers | HubSpot
Developers Workers | Datadog
Developers | HubSpot
Developers | HubSpot
Inbox (1,576) - [EMAIL] - Jiminny Mail
Inbox (1,576) - [EMAIL] - Jiminny Mail
120216 is your HubSpot Log In Code - [EMAIL] - Jiminny Mail
120216 is your HubSpot Log In Code - [EMAIL] - Jiminny Mail
CloudWatch | eu-west-1
CloudWatch | eu-west-1
New Tab
New Tab
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
fix-cache-for-business-processes by ilian-jiminny · Pull Request #11985 · jiminny/app
fix-cache-for-business-processes by ilian-jiminny · Pull Request #11985 · jiminny/app
[JY-20692] Issue with reconnecting Zoho - Jira
[JY-20692] Issue with reconnecting Zoho - Jira
Jiminny
Jiminny
Auth Proxy
Auth Proxy
Dashboard · Jiminny · Membrane
Dashboard · Jiminny · Membrane
App "Zoho CRM" · Jiminny · Membrane
App "Zoho CRM" · Jiminny · Membrane
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Workspace: Jiminny
Jiminny
Search
⌘K
Dashboard
Dashboard
Explore
Explore
Activity
Activity
Settings
Settings
Docs
Docs
Logout
Version
2026-04-16
Integrations
Integrations
Zoho CRM
Zoho CRM
Status:
Success
Ready
Test
Test
Add to your product
Add to your product
Basic Info
Basic Info
Name
Zoho CRM
Key
zohocrm
Description
Add a description for this integration
Logo
https://static.integration.app/connectors/zoho-crm/logo.png
Zoho CRM
App
Connector
Zoho CRM Zoho CRM
Zoho CRM
Connector Version
Connector Version
Current Version:
3.0.3
Parameters
Parameters
Editor content
Options
Options
Connect via Membrane
Connect via Membrane
OAuth 2.0
OAuth 2.0
Configuration guide
Client ID
Field is required
Client Secret
Field is required
Scopes
Delete
Add Scopes Item
oAuth Configuration
oAuth Configuration
In some cases you may need to use a custom Callback URL instead of the default one. It will be used for all connections created for this integration.
OAuth Callback URI
https://api.integration.app/oauth-callback
Explore
Explore
Connections 22
Connections
22
Packages 0
Packages
0
Actions 44
Actions
44
Flows 10
Flows
10
External Event Subscriptions 237
External Event Subscriptions
237
Internal Event Subscriptions 0
Internal Event Subscriptions
0
Data Sources 7
Data Sources
7
Field Mappings 6
Field Mappings
6
Internal Data Schemas 0
Internal Data Schemas
0
Data Link Tables 0
Data Link Tables
0
System Activity
System Activity
Last 7 days
Last 7 days
Flow Runs 9765 Status: Success 678 Status: Error
Flow Runs
9765
Status:
Success
678
Status:
Error
Action Runs 18529 Status: Success 6732 Status: Error
Action Runs...
|
47580
|
|
72622
|
1770
|
27
|
2026-04-22T15:58:36.191711+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-22/1776 /Users/lukas/.screenpipe/data/data/2026-04-22/1776873516191_m1.jpg...
|
Control Centre
|
Control Centre
|
True
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Wi‑Fi
Focus
Bluetooth
AirDrop
Stage Manager
Screen Wi‑Fi
Focus
Bluetooth
AirDrop
Stage Manager
Screen Mirroring
Display
Sound
Airplay Audio
Freelancers & Teams: Get Automatic Time Tracking + Distraction Protection in One Tool, RescueTime
pause
next...
|
[{"role":"AXCheckBox","text [{"role":"AXCheckBox","text":"Wi‑Fi","depth":2,"bounds":{"left":0.79583335,"top":0.051666666,"width":0.093055554,"height":0.045555554},"automation_id":"controlcenter-wifi","role_description":"toggle button","subrole":"AXToggle","is_enabled":true},{"role":"AXCheckBox","text":"Focus","depth":2,"bounds":{"left":0.8958333,"top":0.044444446,"width":0.093055554,"height":0.06888889},"automation_id":"controlcenter-focus-modes","role_description":"toggle button","subrole":"AXToggle","is_enabled":true},{"role":"AXCheckBox","text":"Bluetooth","depth":2,"bounds":{"left":0.79583335,"top":0.09611111,"width":0.093055554,"height":0.045555554},"automation_id":"controlcenter-bluetooth","role_description":"toggle button","subrole":"AXToggle","is_enabled":true},{"role":"AXCheckBox","text":"AirDrop","depth":2,"bounds":{"left":0.79583335,"top":0.14055556,"width":0.093055554,"height":0.045555554},"automation_id":"controlcenter-airdrop","role_description":"toggle button","subrole":"AXToggle","is_enabled":true},{"role":"AXButton","text":"Stage Manager","depth":2,"bounds":{"left":0.90260416,"top":0.135,"width":0.029513888,"height":0.050555557},"automation_id":"controlcenter-stagemanager","role_description":"toggle button","subrole":"AXToggle","is_enabled":true},{"role":"AXButton","text":"Screen Mirroring","depth":2,"bounds":{"left":0.9458333,"top":0.12444445,"width":0.043055557,"height":0.06888889},"automation_id":"controlcenter-screen-mirroring","role_description":"toggle button","subrole":"AXToggle","is_enabled":true},{"role":"AXStaticText","text":"Display","depth":3,"bounds":{"left":0.80277777,"top":0.21166667,"width":0.029513888,"height":0.016666668},"role_description":"text"},{"role":"AXStaticText","text":"Sound","depth":2,"bounds":{"left":0.80277777,"top":0.29166666,"width":0.025694445,"height":0.016666668},"automation_id":"controlcenter-volume","role_description":"text"},{"role":"AXCheckBox","text":"Airplay Audio","depth":2,"bounds":{"left":0.9638889,"top":0.31333333,"width":0.018055556,"height":0.028888889},"automation_id":"controlcenter-airplay","role_description":"toggle button","subrole":"AXToggle","is_enabled":true},{"role":"AXStaticText","text":"Freelancers & Teams: Get Automatic Time Tracking + Distraction Protection in One Tool, RescueTime","depth":2,"bounds":{"left":0.8375,"top":0.38333333,"width":0.099652775,"height":0.031111112},"role_description":"text"},{"role":"AXButton","text":"pause","depth":2,"bounds":{"left":0.9458333,"top":0.38444445,"width":0.018055556,"height":0.028888889},"role_description":"button","is_enabled":true,"is_focused":false},{"role":"AXButton","text":"next","depth":2,"bounds":{"left":0.9638889,"top":0.38444445,"width":0.018055556,"height":0.028888889},"role_description":"button","is_enabled":false}]...
|
-8545831866306753471
|
8682004382524819492
|
click
|
accessibility
|
NULL
|
Wi‑Fi
Focus
Bluetooth
AirDrop
Stage Manager
Screen Wi‑Fi
Focus
Bluetooth
AirDrop
Stage Manager
Screen Mirroring
Display
Sound
Airplay Audio
Freelancers & Teams: Get Automatic Time Tracking + Distraction Protection in One Tool, RescueTime
pause
next...
|
NULL
|
|
60921
|
1313
|
44
|
2026-04-21T06:25:25.522511+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-21/1776 /Users/lukas/.screenpipe/data/data/2026-04-21/1776752725522_m2.jpg...
|
Firefox
|
JY-20701 | Reschedule HubSpot Sync Objects by yalo JY-20701 | Reschedule HubSpot Sync Objects by yalokin-jiminny · Pull Request #11989 · jiminny/app — Work...
|
True
|
github.com/jiminny/app/pull/11989
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Platform Sprint 2 Q2 - Platform Team - Scrum Board Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira
[SRD-6787] Issue with reconnecting Zoho - Jira
[SRD-6787] Issue with reconnecting Zoho - Jira
[SRD-6787] Issue with reconnecting Zoho - Jira
[SRD-6787] Issue with reconnecting Zoho - Jira
JY-20698 handle failed field sync on playbook import activity types by LakyLak · Pull Request #11988 · jiminny/app
JY-20698 handle failed field sync on playbook import activity types by LakyLak · Pull Request #11988 · jiminny/app
Jiminny MCP Connector - Product - Confluence
Jiminny MCP Connector - Product - Confluence
[JY-20676] Notify the user if a Panorama prompts is deleted but is used in AJ Report - Jira
[JY-20676] Notify the user if a Panorama prompts is deleted but is used in AJ Report - Jira
Jiminny Mail
Jiminny Mail
[JY-20500] Batch initial sync for Salesforce - Jira
[JY-20500] Batch initial sync for Salesforce - Jira
Feed — jiminny — Sentry
Feed — jiminny — Sentry
Jiminny
Jiminny
JY-20701 | Reschedule HubSpot Sync Objects by yalokin-jiminny · Pull Request #11989 · jiminny/app
JY-20701 | Reschedule HubSpot Sync Objects by yalokin-jiminny · Pull Request #11989 · jiminny/app
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to content
Skip to content
Open menu
Homepage (g then d)
jiminny
jiminny
app
app
Search or jump to…
Type
/
to search
Chat with Copilot
Open Copilot…
Create new...
Issues(g then i)
Pull requests
Repositories
You have unread notifications(g then n)
Open user navigation menu
Repository navigation
Repository navigation
Code
Code
Pull requests (31)
Pull requests
(
31
)
Agents
Agents
Actions
Actions
Wiki
Wiki
Security and quality (21)
Security and quality
(
21
)
Insights
Insights
Settings
Settings
Important update
Important update
On April 24 we'll start using GitHub Copilot interaction data for AI model training unless you opt out.
Review this update
Review this update
and manage your preferences in your
GitHub account settings
GitHub account settings
.
Dismiss banner
Review requested
Review requested
yalokin-jiminny
yalokin-jiminny
requested your review on this pull request.
Add your review
Add your review
JY-20701 | Reschedule HubSpot Sync Objects #11989 Edit title
JY-20701 | Reschedule HubSpot Sync Objects
#
11989
Edit title
Awaiting approval
Awaiting approval
Code
Code
Open
yalokin-jiminny
yalokin-jiminny
wants to merge 22 commits into
master
master
from
JY-20701-reschedule-HubSpot-processing
JY-20701-reschedule-HubSpot-processing
Copy head branch name to clipboard
Lines changed: 949 additions & 97 deletions
Conversation (5)
Conversation
(
5
)
Commits (22)
Commits
(
22
)
Checks (3)
Checks
(
3
)
Files changed (11)
Files changed
(
11
)
Open
JY-20701 | Reschedule HubSpot Sync Objects #11989 yalokin-jiminny wants to merge 22 commits into master from JY-20701-reschedule-HubSpot-processing Copy head branch name to clipboard
JY-20701 | Reschedule HubSpot Sync Objects
JY-20701 | Reschedule HubSpot Sync Objects
#
11989
yalokin-jiminny
yalokin-jiminny
wants to merge 22 commits into
master
master
from
JY-20701-reschedule-HubSpot-processing
JY-20701-reschedule-HubSpot-processing
Copy head branch name to clipboard
Conversation
Conversation
@yalokin-jiminny
Show options
yalokin-jiminny commented 4 days ago •
yalokin-jiminny
yalokin-jiminny
commented
4 days ago
4 days ago
•
edited
edited
JIRA: JY-20701
JIRA:
JY-20701
JY-20701
Casus:
Casus:
We want more fluent curve of the jobs distribution (no spikes) in
crm-sync
queue
The more frequent HubSpot processing will help to have less auto-scaling / down-scaling events, thus reducing the jobs wait times
Changes:
Changes:
Remove HubSpot from SyncObjects
Create separate HubSpotSyncObjects that runs each 5 min instead of each 30
Extract common code
Improve processing Webhooks jobs distribution
Optimize ImportOpportunityBatch:
cache OpportunitySyncableFields, OwnerProfiles, RecordType
remove findContactByConfigurationAndId - Contact ID already exist
add timings log
Add or remove reactions
@yalokin-jiminny
Show options
Author
yalokin-jiminny commented 4 days ago
yalokin-jiminny
yalokin-jiminny
commented
4 days ago
4 days ago
@claude
@claude
Add or remove reactions
react with eyes
👀
1
@claude
Show options
claude bot commented 4 days ago •
claude
claude
bot
commented
4 days ago
4 days ago
•
edited
edited
Claude finished
@yalokin-jiminny
@yalokin-jiminny
's task in 1m 59s
——
View job
View job
Code Review
Code Review
Overall the approach is clean — extracting the shared logic into
SyncObjectsCommandTrait
is a good call, and the scheduling design (offset cron at
:01
to avoid spikes) makes sense. I found two bugs and a few minor points.
Bugs
Bugs
1. Null dereference on
$crmConfig
—
app/Jobs/Crm/SyncHubspotObjects.php:49-51
$
crmConfig
=
$
team
->
crm
;
if
(
$
crmConfig
->
provider
!== Configuration::
PROVIDER_HUBSPOT
) {
Copy
$team->crm
can be null if the team has no CRM configuration record. Accessing
->provider
on null will throw a fatal error. The existing
SyncObjects
job handles this by using
??
(
$crmConfig->provider ?? 'unknown'
). The new job needs a null guard here:
$
crmConfig
=
$
team
->
crm
;
if
(
$
crmConfig
===
null
||
$
crmConfig
->
provider
!== Configuration::
PROVIDER_HUBSPOT
) {
$
logger
->
warning
(
'
[SyncHubspotObjects] Team has no HubSpot CRM config
'
, [
'
team
'
=>
$
this
->
teamId
]);
return
;
}
Copy
Fix this →
Fix this →
2.
$lastSyncedAt
is nullable but
syncHubspotCrmObjects
requires
Carbon
—
app/Jobs/Crm/SyncHubspotObjects.php:85,88,116
$
lastSyncedAt
=
$
crmConfig
->
last_synced_at
;
// can be null on first run
.
.
.
$
this
->
syncHubspotCrmObjects
(
$
crmService
,
$
lastSyncedAt
);
// ...
private
function
syncHubspotCrmObjects(
HubspotInterface
$
crmService
,
Carbon
$
lastSyncedAt
):
void
Copy
With
declare(strict_types=1)
, passing
null
to a
Carbon
-typed parameter throws a
TypeError
. A team that has never synced before will crash on the first run. The parameter should be
?Carbon
(and
syncOpportunities
should handle null), or provide a fallback like
Carbon::createFromTimestamp(0)
.
Fix this →
Fix this →
Minor Issues
Minor Issues
3. Double call to
getLogPrefix()
—
app/Console/Commands/Crm/Traits/SyncObjectsCommandTrait.php:52
$
prefix
=
$
this
->
getLogPrefix
() ?
$
this
->
getLogPrefix
() .
'
'
:
''
;
Copy
getLogPrefix()
is called twice. Trivial but unnecessary — capture the result in a variable first.
4.
SyncObjects
command doesn't guard HubSpot when
{team}
argument is given —
app/Console/Commands/Crm/SyncObjects.php:40-41
if
(
$
teamId
) {
$
teams
[] = Team::
idOrUuId
(
$
teamId
);
// no provider check
Copy
Running
crm:sync-objects <hubspot-team-id>
dispatches a
SyncObjectsJob
for a HubSpot team, which now silently warns and returns. From an operator perspective this is confusing — the command appears to accept the team but does nothing. Worth adding a provider check and a console error message pointing to
crm:sync-hubspot-objects
.
Design Notes
Design Notes
Scheduler placement
:
crm:sync-hubspot-objects
is placed inside
scheduleEveryFiveMinutes()
but uses a manual cron
'1,6,11,16,21,26,31,36,41,46,51,56 * * * *'
instead of
->everyFiveMinutes()
. The 1-minute offset is intentional (good thinking to stagger from the other jobs), but it's slightly inconsistent with the method's name. A comment explaining the offset would help future readers.
SQS visibility timeout
:
SyncHubspotObjects
uses 1 hour (
60 * 60
) vs
SyncObjects
's 6 hours (
60 * 60 * 6
). Appropriate given the more frequent, presumably lighter runs.
Stagger delay
: HubSpot uses 1s between teams vs 2s for general sync. Fine for 5-min runs, though worth monitoring if the number of HubSpot teams grows large enough that the last job barely fits within the 5-minute window.
Add or remove reactions
@yalokin-jiminny
yalokin-jiminny
yalokin-jiminny
force-pushed
force-pushed
the
JY-20553-debug-crm-sync-delays
branch from
f6c0ec3
f6c0ec3
to
5928f60
5928f60
Compare
Compare
yesterday
yesterday
@yalokin-jiminny
yalokin-jiminny
yalokin-jiminny
force-pushed
force-pushed
the
JY-20701-reschedule-HubSpot-processing
branch from
3d7234a
3d7234a
to
1d10796
1d10796
Compare
Compare
yesterday
yesterday
Base automatically changed from
JY-20553-debug-crm-sync-delays
to
master
19 hours ago
19 hours ago
@yalokin-jiminny
yalokin-jiminny
yalokin-jiminny
force-pushed
force-pushed
the
JY-20701-reschedule-HubSpot-processing
branch from
fec25f3
fec25f3
to
f0119c9
f0119c9
Compare
Compare
19 hours ago
19 hours ago
yalokin-jiminny
yalokin-jiminny
added
17
commits
15 hours ago
15 hours ago
@yalokin-jiminny
JY-20701
JY-20701
| remove HubSpot from 30 min scheduler
| remove HubSpot from 30 min scheduler
2f38f13
2f38f13
@yalokin-jiminny
JY-20701
JY-20701
| Add SyncHubspotObjects Job
| Add SyncHubspotObjects Job
50b0e20
50b0e20
@yalokin-jiminny
JY-20701
JY-20701
| Add HubSpot sync objects scheduler each 5 min
| Add HubSpot sync objects scheduler each 5 min
ea92c0f
ea92c0f
@yalokin-jiminny
JY-20701
JY-20701
| extract duplicated code
| extract duplicated code
7ecdad3
7ecdad3
@yalokin-jiminny
JY-20701
JY-20701
| cs
| cs
525cbb2
525cbb2
@yalokin-jiminny
JY-20701
JY-20701
| safe crm check
| safe crm check
35de0d5
35de0d5
@yalokin-jiminny
JY-20701
JY-20701
| null on first-time sync
| null on first-time sync
ac1f89e
ac1f89e
@yalokin-jiminny
JY-20701
JY-20701
| minor improvement
| minor improvement
bab377e
bab377e
@yalokin-jiminny
JY-20701
JY-20701
| improve filter by team
| improve filter by team
f39dc56
f39dc56
@yalokin-jiminny
JY-20701
JY-20701
| add scheduler comment
| add scheduler comment
f2109d7
f2109d7
@yalokin-jiminny
JY-20701
JY-20701
| improve delays
| improve delays
f929670
f929670
@yalokin-jiminny
JY-20701
JY-20701
| add tests
| add tests
9691864
9691864
@yalokin-jiminny
JY-20701
JY-20701
| improve webhook delays
| improve webhook delays
a3a308f
a3a308f
@yalokin-jiminny
JY-20701
JY-20701
| update tests
| update tests
64251d2
64251d2
@yalokin-jiminny
JY-20701
JY-20701
| add OpportunitySyncTrait timings log
| add OpportunitySyncTrait timings log
42e30cf
42e30cf...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira","depth":4,"bounds":{"left":0.0018284575,"top":0.0518755,"width":0.07596409,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"[SRD-6787] Issue with reconnecting Zoho - Jira","depth":4,"bounds":{"left":0.0,"top":0.09497207,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[SRD-6787] Issue with reconnecting Zoho - Jira","depth":5,"bounds":{"left":0.013297873,"top":0.10614525,"width":0.08344415,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[SRD-6787] Issue with reconnecting Zoho - Jira","depth":4,"bounds":{"left":0.0,"top":0.12769353,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[SRD-6787] Issue with reconnecting Zoho - Jira","depth":5,"bounds":{"left":0.013297873,"top":0.13886672,"width":0.08344415,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20698 handle failed field sync on playbook import activity types by LakyLak · Pull Request #11988 · jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.16041501,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20698 handle failed field sync on playbook import activity types by LakyLak · Pull Request #11988 · jiminny/app","depth":5,"bounds":{"left":0.013297873,"top":0.17158818,"width":0.19963431,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jiminny MCP Connector - Product - Confluence","depth":4,"bounds":{"left":0.0,"top":0.19313647,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny MCP Connector - Product - Confluence","depth":5,"bounds":{"left":0.013297873,"top":0.20430966,"width":0.08294548,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[JY-20676] Notify the user if a Panorama prompts is deleted but is used in AJ Report - Jira","depth":4,"bounds":{"left":0.0,"top":0.22585794,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[JY-20676] Notify the user if a Panorama prompts is deleted but is used in AJ Report - Jira","depth":5,"bounds":{"left":0.013297873,"top":0.23703113,"width":0.15791224,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jiminny Mail","depth":4,"bounds":{"left":0.0,"top":0.2585794,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny Mail","depth":5,"bounds":{"left":0.013297873,"top":0.2697526,"width":0.02144282,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[JY-20500] Batch initial sync for Salesforce - Jira","depth":4,"bounds":{"left":0.0,"top":0.29130086,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[JY-20500] Batch initial sync for Salesforce - Jira","depth":5,"bounds":{"left":0.013297873,"top":0.30247405,"width":0.08610372,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Feed — jiminny — Sentry","depth":4,"bounds":{"left":0.0,"top":0.32402235,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Feed — jiminny — Sentry","depth":5,"bounds":{"left":0.013297873,"top":0.33519554,"width":0.042719416,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jiminny","depth":4,"bounds":{"left":0.0,"top":0.3567438,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny","depth":5,"bounds":{"left":0.013297873,"top":0.367917,"width":0.013131649,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20701 | Reschedule HubSpot Sync Objects by yalokin-jiminny · Pull Request #11989 · jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.38946527,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"JY-20701 | Reschedule HubSpot Sync Objects by yalokin-jiminny · Pull Request #11989 · jiminny/app","depth":5,"bounds":{"left":0.013297873,"top":0.40063846,"width":0.1740359,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.06732048,"top":0.39664805,"width":0.007978723,"height":0.01915403},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Tab","depth":4,"bounds":{"left":0.0028257978,"top":0.4237829,"width":0.07413564,"height":0.025538707},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.0028257978,"top":0.97007185,"width":0.010638298,"height":0.025538707},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"bounds":{"left":0.013796543,"top":0.97007185,"width":0.010638298,"height":0.025538707},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"bounds":{"left":0.024933511,"top":0.97007185,"width":0.010638298,"height":0.025538707},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"bounds":{"left":0.036070477,"top":0.97007185,"width":0.010638298,"height":0.025538707},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"bounds":{"left":0.04720745,"top":0.97007185,"width":0.010638298,"height":0.025538707},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Skip to content","depth":6,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip to content","depth":7,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open menu","depth":10,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Homepage (g then d)","depth":9,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"jiminny","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"jiminny","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"app","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"app","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Search or jump to…","depth":9,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Type","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"/","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"to search","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Chat with Copilot","depth":10,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXMenuButton","text":"Open Copilot…","depth":9,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXMenuButton","text":"Create new...","depth":9,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"Issues(g then i)","depth":9,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Pull requests","depth":9,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Repositories","depth":9,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"You have unread notifications(g then n)","depth":9,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Open user navigation menu","depth":9,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Repository navigation","depth":9,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Repository navigation","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Code","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Code","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Pull requests (31)","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pull requests","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"31","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Agents","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Agents","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Actions","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Actions","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Wiki","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Wiki","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Security and quality (21)","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Security and quality","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"21","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Insights","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Insights","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Settings","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Settings","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Important update","depth":10,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Important update","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"On April 24 we'll start using GitHub Copilot interaction data for AI model training unless you opt out.","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review this update","depth":10,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review this update","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"and manage your preferences in your","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"GitHub account settings","depth":10,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"GitHub account settings","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Dismiss banner","depth":9,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Review requested","depth":15,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Review requested","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"yalokin-jiminny","depth":15,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"yalokin-jiminny","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"requested your review on this pull request.","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Add your review","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Add your review","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"JY-20701 | Reschedule HubSpot Sync Objects #11989 Edit title","depth":13,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"JY-20701 | Reschedule HubSpot Sync Objects","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"#","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"11989","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Edit title","depth":14,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Awaiting approval","depth":13,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Awaiting approval","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Code","depth":13,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Code","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Open","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"yalokin-jiminny","depth":15,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"yalokin-jiminny","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"wants to merge 22 commits into","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"master","depth":15,"role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"master","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"from","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"JY-20701-reschedule-HubSpot-processing","depth":16,"role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20701-reschedule-HubSpot-processing","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Copy head branch name to clipboard","depth":16,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Lines changed: 949 additions & 97 deletions","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Conversation (5)","depth":16,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Conversation","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"5","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Commits (22)","depth":16,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Commits","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"22","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Checks (3)","depth":16,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Checks","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"3","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Files changed (11)","depth":16,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Files changed","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"11","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Open","depth":14,"bounds":{"left":0.34840426,"top":0.0726257,"width":0.011968086,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"JY-20701 | Reschedule HubSpot Sync Objects #11989 yalokin-jiminny wants to merge 22 commits into master from JY-20701-reschedule-HubSpot-processing Copy head branch name to clipboard","depth":14,"bounds":{"left":0.36702126,"top":0.058260176,"width":0.23138298,"height":0.042298485},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXLink","text":"JY-20701 | Reschedule HubSpot Sync Objects","depth":16,"bounds":{"left":0.36702126,"top":0.05865922,"width":0.10322473,"height":0.01915403},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20701 | Reschedule HubSpot Sync Objects","depth":17,"bounds":{"left":0.36702126,"top":0.06304868,"width":0.10322473,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"#","depth":16,"bounds":{"left":0.47290558,"top":0.06304868,"width":0.0029920214,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"11989","depth":16,"bounds":{"left":0.4758976,"top":0.06304868,"width":0.012965426,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"yalokin-jiminny","depth":18,"bounds":{"left":0.36702126,"top":0.08339984,"width":0.029920213,"height":0.011971269},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"yalokin-jiminny","depth":19,"bounds":{"left":0.36702126,"top":0.08339984,"width":0.029920213,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"wants to merge 22 commits into","depth":18,"bounds":{"left":0.39827126,"top":0.08339984,"width":0.06017287,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"master","depth":18,"bounds":{"left":0.45977393,"top":0.08180367,"width":0.018450798,"height":0.015163607},"role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"master","depth":19,"bounds":{"left":0.46176863,"top":0.083798885,"width":0.014461436,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"from","depth":19,"bounds":{"left":0.47955453,"top":0.08339984,"width":0.008643617,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"JY-20701-reschedule-HubSpot-processing","depth":19,"bounds":{"left":0.4895279,"top":0.08180367,"width":0.09524601,"height":0.015163607},"role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20701-reschedule-HubSpot-processing","depth":20,"bounds":{"left":0.4915226,"top":0.083798885,"width":0.09125665,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Copy head branch name to clipboard","depth":19,"bounds":{"left":0.58610374,"top":0.07821229,"width":0.00930851,"height":0.022346368},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Conversation","depth":12,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Conversation","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"@yalokin-jiminny","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Show options","depth":15,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXHeading","text":"yalokin-jiminny commented 4 days ago •","depth":14,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXLink","text":"yalokin-jiminny","depth":16,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"yalokin-jiminny","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"commented","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"4 days ago","depth":15,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"4 days ago","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"edited","depth":17,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"edited","depth":19,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"JIRA: JY-20701","depth":16,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"JIRA:","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"JY-20701","depth":17,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20701","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Casus:","depth":16,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Casus:","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"We want more fluent curve of the jobs distribution (no spikes) in","depth":18,"bounds":{"left":0.3700133,"top":0.0,"width":0.13879654,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"crm-sync","depth":19,"bounds":{"left":0.51047206,"top":0.0,"width":0.018949468,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"queue","depth":18,"bounds":{"left":0.53108376,"top":0.0,"width":0.01462766,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"The more frequent HubSpot processing will help to have less auto-scaling / down-scaling events, thus reducing the jobs wait times","depth":18,"bounds":{"left":0.3700133,"top":0.0,"width":0.24750665,"height":0.030726258},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Changes:","depth":16,"bounds":{"left":0.3620346,"top":0.0,"width":0.25731382,"height":0.01396648},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Changes:","depth":17,"bounds":{"left":0.3620346,"top":0.0,"width":0.021110373,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Remove HubSpot from SyncObjects","depth":18,"bounds":{"left":0.3700133,"top":0.01396648,"width":0.07712766,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Create separate HubSpotSyncObjects that runs each 5 min instead of each 30","depth":18,"bounds":{"left":0.3700133,"top":0.033519555,"width":0.16855054,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Extract common code","depth":18,"bounds":{"left":0.3700133,"top":0.05347167,"width":0.047041222,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Improve processing Webhooks jobs distribution","depth":18,"bounds":{"left":0.3700133,"top":0.07302474,"width":0.101894945,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Optimize ImportOpportunityBatch:","depth":18,"bounds":{"left":0.3700133,"top":0.09297685,"width":0.07396942,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"cache OpportunitySyncableFields, OwnerProfiles, RecordType","depth":20,"bounds":{"left":0.37799203,"top":0.10973663,"width":0.13347739,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"remove findContactByConfigurationAndId - Contact ID already exist","depth":20,"bounds":{"left":0.37799203,"top":0.12968874,"width":0.1456117,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"add timings log","depth":20,"bounds":{"left":0.37799203,"top":0.14924182,"width":0.032912236,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Add or remove reactions","depth":16,"bounds":{"left":0.3620346,"top":0.17757383,"width":0.008643617,"height":0.0207502},"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"@yalokin-jiminny","depth":13,"bounds":{"left":0.33776596,"top":0.23743017,"width":0.013297873,"height":0.031923383},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Show options","depth":14,"bounds":{"left":0.61136967,"top":0.23822825,"width":0.007978723,"height":0.02952913},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Author","depth":15,"bounds":{"left":0.5934175,"top":0.24740623,"width":0.012965426,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"yalokin-jiminny commented 4 days ago","depth":13,"bounds":{"left":0.3620346,"top":0.23822825,"width":0.22240691,"height":0.02952913},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXLink","text":"yalokin-jiminny","depth":15,"bounds":{"left":0.3620346,"top":0.2462091,"width":0.034075797,"height":0.013567438},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"yalokin-jiminny","depth":16,"bounds":{"left":0.3620346,"top":0.2462091,"width":0.034075797,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"commented","depth":14,"bounds":{"left":0.39744017,"top":0.2462091,"width":0.025598405,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"4 days ago","depth":14,"bounds":{"left":0.42436835,"top":0.24461293,"width":0.023603724,"height":0.016759777},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"4 days ago","depth":16,"bounds":{"left":0.42436835,"top":0.2462091,"width":0.023603724,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"@claude","depth":17,"bounds":{"left":0.3620346,"top":0.282921,"width":0.019115692,"height":0.013567438},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"@claude","depth":18,"bounds":{"left":0.3620346,"top":0.282921,"width":0.019115692,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Add or remove reactions","depth":15,"bounds":{"left":0.3620346,"top":0.31085396,"width":0.008643617,"height":0.0207502},"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"react with eyes","depth":14,"bounds":{"left":0.37200797,"top":0.31085396,"width":0.013796543,"height":0.0207502},"role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"👀","depth":16,"bounds":{"left":0.37416887,"top":0.3160415,"width":0.004155585,"height":0.012769354},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1","depth":16,"bounds":{"left":0.38098404,"top":0.3160415,"width":0.0018284575,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"@claude","depth":13,"bounds":{"left":0.33776596,"top":0.37071028,"width":0.013297873,"height":0.031923383},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Show options","depth":14,"bounds":{"left":0.61136967,"top":0.3715084,"width":0.007978723,"height":0.02952913},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXHeading","text":"claude bot commented 4 days ago •","depth":13,"bounds":{"left":0.3620346,"top":0.3715084,"width":0.24135639,"height":0.029928172},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXLink","text":"claude","depth":15,"bounds":{"left":0.3620346,"top":0.3794892,"width":0.014960106,"height":0.013567438},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"claude","depth":16,"bounds":{"left":0.3620346,"top":0.3794892,"width":0.014960106,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"bot","depth":16,"bounds":{"left":0.3804854,"top":0.3810854,"width":0.006482713,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"commented","depth":14,"bounds":{"left":0.390625,"top":0.3794892,"width":0.02543218,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"4 days ago","depth":14,"bounds":{"left":0.41738698,"top":0.37789306,"width":0.023603724,"height":0.016759777},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"4 days ago","depth":16,"bounds":{"left":0.41738698,"top":0.3794892,"width":0.023603724,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":16,"bounds":{"left":0.44232047,"top":0.3794892,"width":0.0021609042,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"edited","depth":16,"bounds":{"left":0.44581118,"top":0.37789306,"width":0.020113032,"height":0.016759777},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"edited","depth":18,"bounds":{"left":0.44581118,"top":0.3794892,"width":0.014793883,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Claude finished","depth":18,"bounds":{"left":0.3620346,"top":0.41660017,"width":0.036070477,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"@yalokin-jiminny","depth":18,"bounds":{"left":0.39810506,"top":0.41660017,"width":0.038397606,"height":0.013567438},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"@yalokin-jiminny","depth":19,"bounds":{"left":0.39810506,"top":0.41660017,"width":0.038397606,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"'s task in 1m 59s","depth":18,"bounds":{"left":0.43650267,"top":0.41660017,"width":0.03756649,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"——","depth":17,"bounds":{"left":0.47406915,"top":0.41660017,"width":0.010638298,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"View job","depth":17,"bounds":{"left":0.48470744,"top":0.41660017,"width":0.018284574,"height":0.013567438},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"View job","depth":18,"bounds":{"left":0.48470744,"top":0.41660017,"width":0.018284574,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Code Review","depth":16,"bounds":{"left":0.3620346,"top":0.47286513,"width":0.25731382,"height":0.01715882},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Code Review","depth":17,"bounds":{"left":0.3620346,"top":0.47326416,"width":0.03523936,"height":0.016759777},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Overall the approach is clean — extracting the shared logic into","depth":17,"bounds":{"left":0.3620346,"top":0.50438946,"width":0.13696809,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"SyncObjectsCommandTrait","depth":18,"bounds":{"left":0.5006649,"top":0.5063847,"width":0.0546875,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"is a good call, and the scheduling design (offset cron at","depth":17,"bounds":{"left":0.3620346,"top":0.50438946,"width":0.24335106,"height":0.030327214},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":":01","depth":18,"bounds":{"left":0.43567154,"top":0.5231444,"width":0.0071476065,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"to avoid spikes) makes sense. I found two bugs and a few minor points.","depth":17,"bounds":{"left":0.44448137,"top":0.5211492,"width":0.15425532,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Bugs","depth":16,"bounds":{"left":0.3620346,"top":0.5774142,"width":0.25731382,"height":0.017557861},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Bugs","depth":17,"bounds":{"left":0.3620346,"top":0.57781327,"width":0.013796543,"height":0.016759777},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1. Null dereference on","depth":18,"bounds":{"left":0.3620346,"top":0.60933757,"width":0.050033245,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$crmConfig","depth":19,"bounds":{"left":0.41373006,"top":0.6113328,"width":0.023769947,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"—","depth":18,"bounds":{"left":0.43916222,"top":0.60933757,"width":0.006482713,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"app/Jobs/Crm/SyncHubspotObjects.php:49-51","depth":19,"bounds":{"left":0.44730717,"top":0.6113328,"width":0.09773936,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$","depth":17,"bounds":{"left":0.36735374,"top":0.651237,"width":0.0023271276,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"crmConfig","depth":17,"bounds":{"left":0.36968085,"top":0.651237,"width":0.02144282,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"=","depth":17,"bounds":{"left":0.39112368,"top":0.651237,"width":0.0071476065,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$","depth":17,"bounds":{"left":0.39827126,"top":0.651237,"width":0.0023271276,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"team","depth":17,"bounds":{"left":0.4005984,"top":0.651237,"width":0.009640957,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"->","depth":17,"bounds":{"left":0.41023937,"top":0.651237,"width":0.004654255,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"crm","depth":17,"bounds":{"left":0.41489363,"top":0.651237,"width":0.0071476065,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":";","depth":17,"bounds":{"left":0.42204124,"top":0.651237,"width":0.002493351,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"if","depth":17,"bounds":{"left":0.36735374,"top":0.67877096,"width":0.004654255,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":17,"bounds":{"left":0.37200797,"top":0.67877096,"width":0.0048204786,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$","depth":17,"bounds":{"left":0.37682846,"top":0.67877096,"width":0.0023271276,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"crmConfig","depth":17,"bounds":{"left":0.37915558,"top":0.67877096,"width":0.02144282,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"->","depth":17,"bounds":{"left":0.4005984,"top":0.67877096,"width":0.0048204786,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"provider","depth":17,"bounds":{"left":0.40541887,"top":0.67877096,"width":0.019115692,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"!== Configuration::","depth":17,"bounds":{"left":0.4245346,"top":0.67877096,"width":0.047539894,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"PROVIDER_HUBSPOT","depth":17,"bounds":{"left":0.47207448,"top":0.67877096,"width":0.038231384,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":") {","depth":17,"bounds":{"left":0.5103058,"top":0.67877096,"width":0.0071476065,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Copy","depth":17,"bounds":{"left":0.60538566,"top":0.64365524,"width":0.011303191,"height":0.028332002},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"$team->crm","depth":18,"bounds":{"left":0.36353058,"top":0.7206704,"width":0.023769947,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"can be null if the team has no CRM configuration record. Accessing","depth":17,"bounds":{"left":0.38896278,"top":0.7186752,"width":0.1471077,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"->provider","depth":18,"bounds":{"left":0.5375665,"top":0.7206704,"width":0.023936171,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"on null will throw a fatal error. The existing","depth":17,"bounds":{"left":0.3620346,"top":0.7186752,"width":0.2526596,"height":0.030327214},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"SyncObjects","depth":18,"bounds":{"left":0.40375665,"top":0.73743016,"width":0.026097074,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"job handles this by using","depth":17,"bounds":{"left":0.43151596,"top":0.73543495,"width":0.055851065,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"??","depth":18,"bounds":{"left":0.48902926,"top":0.73743016,"width":0.004654255,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":17,"bounds":{"left":0.49534574,"top":0.73543495,"width":0.0029920214,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$crmConfig->provider ?? 'unknown'","depth":18,"bounds":{"left":0.5,"top":0.73743016,"width":0.07862367,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"). The new job needs a null guard here:","depth":17,"bounds":{"left":0.3620346,"top":0.73543495,"width":0.2486702,"height":0.030327214},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$","depth":17,"bounds":{"left":0.36735374,"top":0.79369515,"width":0.0023271276,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"crmConfig","depth":17,"bounds":{"left":0.36968085,"top":0.79369515,"width":0.02144282,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"=","depth":17,"bounds":{"left":0.39112368,"top":0.79369515,"width":0.0071476065,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$","depth":17,"bounds":{"left":0.39827126,"top":0.79369515,"width":0.0023271276,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"team","depth":17,"bounds":{"left":0.4005984,"top":0.79369515,"width":0.009640957,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"->","depth":17,"bounds":{"left":0.41023937,"top":0.79369515,"width":0.004654255,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"crm","depth":17,"bounds":{"left":0.41489363,"top":0.79369515,"width":0.0071476065,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":";","depth":17,"bounds":{"left":0.42204124,"top":0.79369515,"width":0.002493351,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"if","depth":17,"bounds":{"left":0.36735374,"top":0.82122904,"width":0.004654255,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":17,"bounds":{"left":0.37200797,"top":0.82122904,"width":0.0048204786,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$","depth":17,"bounds":{"left":0.37682846,"top":0.82122904,"width":0.0023271276,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"crmConfig","depth":17,"bounds":{"left":0.37915558,"top":0.82122904,"width":0.02144282,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"===","depth":17,"bounds":{"left":0.4005984,"top":0.82122904,"width":0.011968086,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"null","depth":17,"bounds":{"left":0.41256648,"top":0.82122904,"width":0.009474734,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"||","depth":17,"bounds":{"left":0.42204124,"top":0.82122904,"width":0.009640957,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$","depth":17,"bounds":{"left":0.43168217,"top":0.82122904,"width":0.0023271276,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"crmConfig","depth":17,"bounds":{"left":0.4340093,"top":0.82122904,"width":0.02144282,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"->","depth":17,"bounds":{"left":0.4554521,"top":0.82122904,"width":0.0048204786,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"provider","depth":17,"bounds":{"left":0.4602726,"top":0.82122904,"width":0.018949468,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"!== Configuration::","depth":17,"bounds":{"left":0.4792221,"top":0.82122904,"width":0.047706116,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"PROVIDER_HUBSPOT","depth":17,"bounds":{"left":0.5269282,"top":0.82122904,"width":0.038065158,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":") {","depth":17,"bounds":{"left":0.36735374,"top":0.82122904,"width":0.20478724,"height":0.025538707},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$","depth":17,"bounds":{"left":0.37682846,"top":0.83519554,"width":0.0023271276,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"logger","depth":17,"bounds":{"left":0.37915558,"top":0.83519554,"width":0.014295213,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"->","depth":17,"bounds":{"left":0.3934508,"top":0.83519554,"width":0.0048204786,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"warning","depth":17,"bounds":{"left":0.39827126,"top":0.83519554,"width":0.01662234,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":17,"bounds":{"left":0.41489363,"top":0.83519554,"width":0.002493351,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"'","depth":17,"bounds":{"left":0.41738698,"top":0.83519554,"width":0.0023271276,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"[SyncHubspotObjects] Team has no HubSpot CRM config","depth":17,"bounds":{"left":0.4197141,"top":0.83519554,"width":0.121509306,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"'","depth":17,"bounds":{"left":0.5412234,"top":0.83519554,"width":0.0023271276,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":", [","depth":17,"bounds":{"left":0.54355055,"top":0.83519554,"width":0.0071476065,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"'","depth":17,"bounds":{"left":0.55069816,"top":0.83519554,"width":0.002493351,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"team","depth":17,"bounds":{"left":0.5531915,"top":0.83519554,"width":0.009474734,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"'","depth":17,"bounds":{"left":0.56266624,"top":0.83519554,"width":0.0023271276,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"=>","depth":17,"bounds":{"left":0.5649933,"top":0.83519554,"width":0.009640957,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$","depth":17,"bounds":{"left":0.5746343,"top":0.83519554,"width":0.0023271276,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"this","depth":17,"bounds":{"left":0.57696146,"top":0.83519554,"width":0.009474734,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"->","depth":17,"bounds":{"left":0.58643615,"top":0.83519554,"width":0.0048204786,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"teamId","depth":17,"bounds":{"left":0.5912567,"top":0.83519554,"width":0.014295213,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"]);","depth":17,"bounds":{"left":0.36735374,"top":0.83519554,"width":0.24534574,"height":0.025139665},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"return","depth":17,"bounds":{"left":0.37682846,"top":0.848763,"width":0.014295213,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":";\n}","depth":17,"bounds":{"left":0.36735374,"top":0.848763,"width":0.026097074,"height":0.025538707},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Copy","depth":17,"bounds":{"left":0.60538566,"top":0.7865124,"width":0.011303191,"height":0.028332002},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Fix this →","depth":17,"bounds":{"left":0.3620346,"top":0.90263367,"width":0.020611702,"height":0.013567438},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Fix this →","depth":18,"bounds":{"left":0.3620346,"top":0.90263367,"width":0.020611702,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2.","depth":18,"bounds":{"left":0.3620346,"top":0.9604948,"width":0.005485372,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$lastSyncedAt","depth":19,"bounds":{"left":0.36918217,"top":0.96249,"width":0.030917553,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"is nullable but","depth":18,"bounds":{"left":0.40159574,"top":0.9604948,"width":0.033909574,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"syncHubspotCrmObjects","depth":19,"bounds":{"left":0.43716756,"top":0.96249,"width":0.050033245,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"requires","depth":18,"bounds":{"left":0.4886968,"top":0.9604948,"width":0.020944148,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Carbon","depth":19,"bounds":{"left":0.5113032,"top":0.96249,"width":0.014295213,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"—","depth":18,"bounds":{"left":0.5270944,"top":0.9604948,"width":0.0066489363,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"app/Jobs/Crm/SyncHubspotObjects.php:85,88,116","depth":19,"bounds":{"left":0.3620346,"top":0.96249,"width":0.20428856,"height":0.028332002},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$","depth":17,"bounds":{"left":0.36735374,"top":1.0,"width":0.0023271276,"height":-0.01875496},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"lastSyncedAt","depth":17,"bounds":{"left":0.36968085,"top":1.0,"width":0.028590426,"height":-0.01875496},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"=","depth":17,"bounds":{"left":0.39827126,"top":1.0,"width":0.0071476065,"height":-0.01875496},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$","depth":17,"bounds":{"left":0.40541887,"top":1.0,"width":0.0023271276,"height":-0.01875496},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"crmConfig","depth":17,"bounds":{"left":0.40774602,"top":1.0,"width":0.02144282,"height":-0.01875496},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"->","depth":17,"bounds":{"left":0.42918882,"top":1.0,"width":0.0048204786,"height":-0.01875496},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"last_synced_at","depth":17,"bounds":{"left":0.4340093,"top":1.0,"width":0.033410903,"height":-0.01875496},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":";","depth":17,"bounds":{"left":0.46742022,"top":1.0,"width":0.0071476065,"height":-0.01875496},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"// can be null on first run","depth":17,"bounds":{"left":0.47456783,"top":1.0,"width":0.064328454,"height":-0.01875496},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":17,"bounds":{"left":0.36735374,"top":1.0,"width":0.0023271276,"height":-0.03272152},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":17,"bounds":{"left":0.36968085,"top":1.0,"width":0.0023271276,"height":-0.03272152},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":17,"bounds":{"left":0.37200797,"top":1.0,"width":0.002493351,"height":-0.03272152},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$","depth":17,"bounds":{"left":0.36735374,"top":1.0,"width":0.0023271276,"height":-0.046288848},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"this","depth":17,"bounds":{"left":0.36968085,"top":1.0,"width":0.009474734,"height":-0.046288848},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"->","depth":17,"bounds":{"left":0.37915558,"top":1.0,"width":0.0048204786,"height":-0.046288848},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"syncHubspotCrmObjects","depth":17,"bounds":{"left":0.38397607,"top":1.0,"width":0.050033245,"height":-0.046288848},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":17,"bounds":{"left":0.4340093,"top":1.0,"width":0.0023271276,"height":-0.046288848},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$","depth":17,"bounds":{"left":0.43633643,"top":1.0,"width":0.002493351,"height":-0.046288848},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"crmService","depth":17,"bounds":{"left":0.43882978,"top":1.0,"width":0.023769947,"height":-0.046288848},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":",","depth":17,"bounds":{"left":0.46259972,"top":1.0,"width":0.0048204786,"height":-0.046288848},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$","depth":17,"bounds":{"left":0.46742022,"top":1.0,"width":0.0023271276,"height":-0.046288848},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"lastSyncedAt","depth":17,"bounds":{"left":0.46974733,"top":1.0,"width":0.028590426,"height":-0.046288848},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":");","depth":17,"bounds":{"left":0.49833778,"top":1.0,"width":0.0048204786,"height":-0.046288848},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"// ...","depth":17,"bounds":{"left":0.36735374,"top":1.0,"width":0.014295213,"height":-0.073822856},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"private","depth":17,"bounds":{"left":0.36735374,"top":1.0,"width":0.01662234,"height":-0.0877893},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"function","depth":17,"bounds":{"left":0.3863032,"top":1.0,"width":0.019115692,"height":-0.0877893},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"syncHubspotCrmObjects(","depth":17,"bounds":{"left":0.40541887,"top":1.0,"width":0.054853722,"height":-0.0877893},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"HubspotInterface","depth":17,"bounds":{"left":0.4602726,"top":1.0,"width":0.038065158,"height":-0.0877893},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$","depth":17,"bounds":{"left":0.5006649,"top":1.0,"width":0.002493351,"height":-0.0877893},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"crmService","depth":17,"bounds":{"left":0.5031583,"top":1.0,"width":0.023769947,"height":-0.0877893},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":",","depth":17,"bounds":{"left":0.5269282,"top":1.0,"width":0.0048204786,"height":-0.0877893},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Carbon","depth":17,"bounds":{"left":0.53174865,"top":1.0,"width":0.014295213,"height":-0.0877893},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$","depth":17,"bounds":{"left":0.548371,"top":1.0,"width":0.0023271276,"height":-0.0877893},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"lastSyncedAt","depth":17,"bounds":{"left":0.55069816,"top":1.0,"width":0.028590426,"height":-0.0877893},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"):","depth":17,"bounds":{"left":0.57928854,"top":1.0,"width":0.0071476065,"height":-0.0877893},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"void","depth":17,"bounds":{"left":0.58643615,"top":1.0,"width":0.009640957,"height":-0.0877893},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Copy","depth":17,"bounds":{"left":0.60538566,"top":1.0,"width":0.011303191,"height":-0.011572242},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"With","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"declare(strict_types=1)","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":", passing","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"null","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"to a","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Carbon","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-typed parameter throws a","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"TypeError","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":". A team that has never synced before will crash on the first run. The parameter should be","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"?Carbon","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(and","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"syncOpportunities","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"should handle null), or provide a fallback like","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Carbon::createFromTimestamp(0)","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Fix this →","depth":17,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Fix this →","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Minor Issues","depth":16,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Minor Issues","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"3. Double call to","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"getLogPrefix()","depth":19,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"—","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"app/Console/Commands/Crm/Traits/SyncObjectsCommandTrait.php:52","depth":19,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"prefix","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"=","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"this","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"->","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"getLogPrefix","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"() ?","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"this","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"->","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"getLogPrefix","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"() .","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"'","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"'","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":":","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"''","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":";","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Copy","depth":17,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"getLogPrefix()","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"is called twice. Trivial but unnecessary — capture the result in a variable first.","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"4.","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"SyncObjects","depth":19,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"command doesn't guard HubSpot when","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"{team}","depth":19,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"argument is given —","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"app/Console/Commands/Crm/SyncObjects.php:40-41","depth":19,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"if","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"teamId","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":") {","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"teams","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"[] = Team::","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"idOrUuId","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"teamId","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":");","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"// no provider check","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Copy","depth":17,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Running","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"crm:sync-objects <hubspot-team-id>","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"dispatches a","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"SyncObjectsJob","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"for a HubSpot team, which now silently warns and returns. From an operator perspective this is confusing — the command appears to accept the team but does nothing. Worth adding a provider check and a console error message pointing to","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"crm:sync-hubspot-objects","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Design Notes","depth":16,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Design Notes","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Scheduler placement","depth":20,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":":","depth":19,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"crm:sync-hubspot-objects","depth":20,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"is placed inside","depth":19,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"scheduleEveryFiveMinutes()","depth":20,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"but uses a manual cron","depth":19,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"'1,6,11,16,21,26,31,36,41,46,51,56 * * * *'","depth":20,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"instead of","depth":19,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"->everyFiveMinutes()","depth":20,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":". The 1-minute offset is intentional (good thinking to stagger from the other jobs), but it's slightly inconsistent with the method's name. A comment explaining the offset would help future readers.","depth":19,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"SQS visibility timeout","depth":20,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":":","depth":19,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"SyncHubspotObjects","depth":20,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"uses 1 hour (","depth":19,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"60 * 60","depth":20,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":") vs","depth":19,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"SyncObjects","depth":20,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"'s 6 hours (","depth":19,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"60 * 60 * 6","depth":20,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"). Appropriate given the more frequent, presumably lighter runs.","depth":19,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Stagger delay","depth":20,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":": HubSpot uses 1s between teams vs 2s for general sync. Fine for 5-min runs, though worth monitoring if the number of HubSpot teams grows large enough that the last job barely fits within the 5-minute window.","depth":19,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Add or remove reactions","depth":15,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"@yalokin-jiminny","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"yalokin-jiminny","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"yalokin-jiminny","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"force-pushed","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"force-pushed","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"the","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"JY-20553-debug-crm-sync-delays","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"branch from","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"f6c0ec3","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"f6c0ec3","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"to","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"5928f60","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"5928f60","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Compare","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Compare","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"yesterday","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"yesterday","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"@yalokin-jiminny","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"yalokin-jiminny","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"yalokin-jiminny","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"force-pushed","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"force-pushed","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"the","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"JY-20701-reschedule-HubSpot-processing","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"branch from","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"3d7234a","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"3d7234a","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"to","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"1d10796","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"1d10796","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Compare","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Compare","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"yesterday","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"yesterday","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Base automatically changed from","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"JY-20553-debug-crm-sync-delays","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"to","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"master","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"19 hours ago","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"19 hours ago","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"@yalokin-jiminny","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"yalokin-jiminny","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"yalokin-jiminny","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"force-pushed","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"force-pushed","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"the","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"JY-20701-reschedule-HubSpot-processing","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"branch from","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"fec25f3","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"fec25f3","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"to","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"f0119c9","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"f0119c9","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Compare","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Compare","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"19 hours ago","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"19 hours ago","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"yalokin-jiminny","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"yalokin-jiminny","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"added","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"17","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"commits","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"15 hours ago","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"15 hours ago","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"@yalokin-jiminny","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-20701","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20701","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"| remove HubSpot from 30 min scheduler","depth":14,"help_text":"JY-20701 | remove HubSpot from 30 min scheduler","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"| remove HubSpot from 30 min scheduler","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"2f38f13","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"2f38f13","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"@yalokin-jiminny","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-20701","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20701","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"| Add SyncHubspotObjects Job","depth":14,"help_text":"JY-20701 | Add SyncHubspotObjects Job","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"| Add SyncHubspotObjects Job","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"50b0e20","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"50b0e20","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"@yalokin-jiminny","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-20701","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20701","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"| Add HubSpot sync objects scheduler each 5 min","depth":14,"help_text":"JY-20701 | Add HubSpot sync objects scheduler each 5 min","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"| Add HubSpot sync objects scheduler each 5 min","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"ea92c0f","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"ea92c0f","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"@yalokin-jiminny","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-20701","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20701","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"| extract duplicated code","depth":14,"help_text":"JY-20701 | extract duplicated code","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"| extract duplicated code","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"7ecdad3","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"7ecdad3","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"@yalokin-jiminny","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-20701","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20701","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"| cs","depth":14,"help_text":"JY-20701 | cs","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"| cs","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"525cbb2","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"525cbb2","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"@yalokin-jiminny","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-20701","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20701","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"| safe crm check","depth":14,"help_text":"JY-20701 | safe crm check","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"| safe crm check","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"35de0d5","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"35de0d5","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"@yalokin-jiminny","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-20701","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20701","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"| null on first-time sync","depth":14,"help_text":"JY-20701 | null on first-time sync","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"| null on first-time sync","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"ac1f89e","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"ac1f89e","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"@yalokin-jiminny","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-20701","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20701","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"| minor improvement","depth":14,"help_text":"JY-20701 | minor improvement","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"| minor improvement","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"bab377e","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"bab377e","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"@yalokin-jiminny","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-20701","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20701","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"| improve filter by team","depth":14,"help_text":"JY-20701 | improve filter by team","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"| improve filter by team","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"f39dc56","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"f39dc56","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"@yalokin-jiminny","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-20701","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20701","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"| add scheduler comment","depth":14,"help_text":"JY-20701 | add scheduler comment","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"| add scheduler comment","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"f2109d7","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"f2109d7","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"@yalokin-jiminny","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-20701","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20701","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"| improve delays","depth":14,"help_text":"JY-20701 | improve delays","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"| improve delays","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"f929670","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"f929670","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"@yalokin-jiminny","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-20701","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20701","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"| add tests","depth":14,"help_text":"JY-20701 | add tests","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"| add tests","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"9691864","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"9691864","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"@yalokin-jiminny","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-20701","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20701","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"| improve webhook delays","depth":14,"help_text":"JY-20701 | improve webhook delays","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"| improve webhook delays","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"a3a308f","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"a3a308f","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"@yalokin-jiminny","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-20701","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20701","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"| update tests","depth":14,"help_text":"JY-20701 | update tests","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"| update tests","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"64251d2","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"64251d2","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"@yalokin-jiminny","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-20701","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20701","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"| add OpportunitySyncTrait timings log","depth":14,"help_text":"JY-20701 | add OpportunitySyncTrait timings log","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"| add OpportunitySyncTrait timings log","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"42e30cf","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"42e30cf","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
-6953205607539964832
|
8665476273024466249
|
visual_change
|
accessibility
|
NULL
|
Platform Sprint 2 Q2 - Platform Team - Scrum Board Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira
[SRD-6787] Issue with reconnecting Zoho - Jira
[SRD-6787] Issue with reconnecting Zoho - Jira
[SRD-6787] Issue with reconnecting Zoho - Jira
[SRD-6787] Issue with reconnecting Zoho - Jira
JY-20698 handle failed field sync on playbook import activity types by LakyLak · Pull Request #11988 · jiminny/app
JY-20698 handle failed field sync on playbook import activity types by LakyLak · Pull Request #11988 · jiminny/app
Jiminny MCP Connector - Product - Confluence
Jiminny MCP Connector - Product - Confluence
[JY-20676] Notify the user if a Panorama prompts is deleted but is used in AJ Report - Jira
[JY-20676] Notify the user if a Panorama prompts is deleted but is used in AJ Report - Jira
Jiminny Mail
Jiminny Mail
[JY-20500] Batch initial sync for Salesforce - Jira
[JY-20500] Batch initial sync for Salesforce - Jira
Feed — jiminny — Sentry
Feed — jiminny — Sentry
Jiminny
Jiminny
JY-20701 | Reschedule HubSpot Sync Objects by yalokin-jiminny · Pull Request #11989 · jiminny/app
JY-20701 | Reschedule HubSpot Sync Objects by yalokin-jiminny · Pull Request #11989 · jiminny/app
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to content
Skip to content
Open menu
Homepage (g then d)
jiminny
jiminny
app
app
Search or jump to…
Type
/
to search
Chat with Copilot
Open Copilot…
Create new...
Issues(g then i)
Pull requests
Repositories
You have unread notifications(g then n)
Open user navigation menu
Repository navigation
Repository navigation
Code
Code
Pull requests (31)
Pull requests
(
31
)
Agents
Agents
Actions
Actions
Wiki
Wiki
Security and quality (21)
Security and quality
(
21
)
Insights
Insights
Settings
Settings
Important update
Important update
On April 24 we'll start using GitHub Copilot interaction data for AI model training unless you opt out.
Review this update
Review this update
and manage your preferences in your
GitHub account settings
GitHub account settings
.
Dismiss banner
Review requested
Review requested
yalokin-jiminny
yalokin-jiminny
requested your review on this pull request.
Add your review
Add your review
JY-20701 | Reschedule HubSpot Sync Objects #11989 Edit title
JY-20701 | Reschedule HubSpot Sync Objects
#
11989
Edit title
Awaiting approval
Awaiting approval
Code
Code
Open
yalokin-jiminny
yalokin-jiminny
wants to merge 22 commits into
master
master
from
JY-20701-reschedule-HubSpot-processing
JY-20701-reschedule-HubSpot-processing
Copy head branch name to clipboard
Lines changed: 949 additions & 97 deletions
Conversation (5)
Conversation
(
5
)
Commits (22)
Commits
(
22
)
Checks (3)
Checks
(
3
)
Files changed (11)
Files changed
(
11
)
Open
JY-20701 | Reschedule HubSpot Sync Objects #11989 yalokin-jiminny wants to merge 22 commits into master from JY-20701-reschedule-HubSpot-processing Copy head branch name to clipboard
JY-20701 | Reschedule HubSpot Sync Objects
JY-20701 | Reschedule HubSpot Sync Objects
#
11989
yalokin-jiminny
yalokin-jiminny
wants to merge 22 commits into
master
master
from
JY-20701-reschedule-HubSpot-processing
JY-20701-reschedule-HubSpot-processing
Copy head branch name to clipboard
Conversation
Conversation
@yalokin-jiminny
Show options
yalokin-jiminny commented 4 days ago •
yalokin-jiminny
yalokin-jiminny
commented
4 days ago
4 days ago
•
edited
edited
JIRA: JY-20701
JIRA:
JY-20701
JY-20701
Casus:
Casus:
We want more fluent curve of the jobs distribution (no spikes) in
crm-sync
queue
The more frequent HubSpot processing will help to have less auto-scaling / down-scaling events, thus reducing the jobs wait times
Changes:
Changes:
Remove HubSpot from SyncObjects
Create separate HubSpotSyncObjects that runs each 5 min instead of each 30
Extract common code
Improve processing Webhooks jobs distribution
Optimize ImportOpportunityBatch:
cache OpportunitySyncableFields, OwnerProfiles, RecordType
remove findContactByConfigurationAndId - Contact ID already exist
add timings log
Add or remove reactions
@yalokin-jiminny
Show options
Author
yalokin-jiminny commented 4 days ago
yalokin-jiminny
yalokin-jiminny
commented
4 days ago
4 days ago
@claude
@claude
Add or remove reactions
react with eyes
👀
1
@claude
Show options
claude bot commented 4 days ago •
claude
claude
bot
commented
4 days ago
4 days ago
•
edited
edited
Claude finished
@yalokin-jiminny
@yalokin-jiminny
's task in 1m 59s
——
View job
View job
Code Review
Code Review
Overall the approach is clean — extracting the shared logic into
SyncObjectsCommandTrait
is a good call, and the scheduling design (offset cron at
:01
to avoid spikes) makes sense. I found two bugs and a few minor points.
Bugs
Bugs
1. Null dereference on
$crmConfig
—
app/Jobs/Crm/SyncHubspotObjects.php:49-51
$
crmConfig
=
$
team
->
crm
;
if
(
$
crmConfig
->
provider
!== Configuration::
PROVIDER_HUBSPOT
) {
Copy
$team->crm
can be null if the team has no CRM configuration record. Accessing
->provider
on null will throw a fatal error. The existing
SyncObjects
job handles this by using
??
(
$crmConfig->provider ?? 'unknown'
). The new job needs a null guard here:
$
crmConfig
=
$
team
->
crm
;
if
(
$
crmConfig
===
null
||
$
crmConfig
->
provider
!== Configuration::
PROVIDER_HUBSPOT
) {
$
logger
->
warning
(
'
[SyncHubspotObjects] Team has no HubSpot CRM config
'
, [
'
team
'
=>
$
this
->
teamId
]);
return
;
}
Copy
Fix this →
Fix this →
2.
$lastSyncedAt
is nullable but
syncHubspotCrmObjects
requires
Carbon
—
app/Jobs/Crm/SyncHubspotObjects.php:85,88,116
$
lastSyncedAt
=
$
crmConfig
->
last_synced_at
;
// can be null on first run
.
.
.
$
this
->
syncHubspotCrmObjects
(
$
crmService
,
$
lastSyncedAt
);
// ...
private
function
syncHubspotCrmObjects(
HubspotInterface
$
crmService
,
Carbon
$
lastSyncedAt
):
void
Copy
With
declare(strict_types=1)
, passing
null
to a
Carbon
-typed parameter throws a
TypeError
. A team that has never synced before will crash on the first run. The parameter should be
?Carbon
(and
syncOpportunities
should handle null), or provide a fallback like
Carbon::createFromTimestamp(0)
.
Fix this →
Fix this →
Minor Issues
Minor Issues
3. Double call to
getLogPrefix()
—
app/Console/Commands/Crm/Traits/SyncObjectsCommandTrait.php:52
$
prefix
=
$
this
->
getLogPrefix
() ?
$
this
->
getLogPrefix
() .
'
'
:
''
;
Copy
getLogPrefix()
is called twice. Trivial but unnecessary — capture the result in a variable first.
4.
SyncObjects
command doesn't guard HubSpot when
{team}
argument is given —
app/Console/Commands/Crm/SyncObjects.php:40-41
if
(
$
teamId
) {
$
teams
[] = Team::
idOrUuId
(
$
teamId
);
// no provider check
Copy
Running
crm:sync-objects <hubspot-team-id>
dispatches a
SyncObjectsJob
for a HubSpot team, which now silently warns and returns. From an operator perspective this is confusing — the command appears to accept the team but does nothing. Worth adding a provider check and a console error message pointing to
crm:sync-hubspot-objects
.
Design Notes
Design Notes
Scheduler placement
:
crm:sync-hubspot-objects
is placed inside
scheduleEveryFiveMinutes()
but uses a manual cron
'1,6,11,16,21,26,31,36,41,46,51,56 * * * *'
instead of
->everyFiveMinutes()
. The 1-minute offset is intentional (good thinking to stagger from the other jobs), but it's slightly inconsistent with the method's name. A comment explaining the offset would help future readers.
SQS visibility timeout
:
SyncHubspotObjects
uses 1 hour (
60 * 60
) vs
SyncObjects
's 6 hours (
60 * 60 * 6
). Appropriate given the more frequent, presumably lighter runs.
Stagger delay
: HubSpot uses 1s between teams vs 2s for general sync. Fine for 5-min runs, though worth monitoring if the number of HubSpot teams grows large enough that the last job barely fits within the 5-minute window.
Add or remove reactions
@yalokin-jiminny
yalokin-jiminny
yalokin-jiminny
force-pushed
force-pushed
the
JY-20553-debug-crm-sync-delays
branch from
f6c0ec3
f6c0ec3
to
5928f60
5928f60
Compare
Compare
yesterday
yesterday
@yalokin-jiminny
yalokin-jiminny
yalokin-jiminny
force-pushed
force-pushed
the
JY-20701-reschedule-HubSpot-processing
branch from
3d7234a
3d7234a
to
1d10796
1d10796
Compare
Compare
yesterday
yesterday
Base automatically changed from
JY-20553-debug-crm-sync-delays
to
master
19 hours ago
19 hours ago
@yalokin-jiminny
yalokin-jiminny
yalokin-jiminny
force-pushed
force-pushed
the
JY-20701-reschedule-HubSpot-processing
branch from
fec25f3
fec25f3
to
f0119c9
f0119c9
Compare
Compare
19 hours ago
19 hours ago
yalokin-jiminny
yalokin-jiminny
added
17
commits
15 hours ago
15 hours ago
@yalokin-jiminny
JY-20701
JY-20701
| remove HubSpot from 30 min scheduler
| remove HubSpot from 30 min scheduler
2f38f13
2f38f13
@yalokin-jiminny
JY-20701
JY-20701
| Add SyncHubspotObjects Job
| Add SyncHubspotObjects Job
50b0e20
50b0e20
@yalokin-jiminny
JY-20701
JY-20701
| Add HubSpot sync objects scheduler each 5 min
| Add HubSpot sync objects scheduler each 5 min
ea92c0f
ea92c0f
@yalokin-jiminny
JY-20701
JY-20701
| extract duplicated code
| extract duplicated code
7ecdad3
7ecdad3
@yalokin-jiminny
JY-20701
JY-20701
| cs
| cs
525cbb2
525cbb2
@yalokin-jiminny
JY-20701
JY-20701
| safe crm check
| safe crm check
35de0d5
35de0d5
@yalokin-jiminny
JY-20701
JY-20701
| null on first-time sync
| null on first-time sync
ac1f89e
ac1f89e
@yalokin-jiminny
JY-20701
JY-20701
| minor improvement
| minor improvement
bab377e
bab377e
@yalokin-jiminny
JY-20701
JY-20701
| improve filter by team
| improve filter by team
f39dc56
f39dc56
@yalokin-jiminny
JY-20701
JY-20701
| add scheduler comment
| add scheduler comment
f2109d7
f2109d7
@yalokin-jiminny
JY-20701
JY-20701
| improve delays
| improve delays
f929670
f929670
@yalokin-jiminny
JY-20701
JY-20701
| add tests
| add tests
9691864
9691864
@yalokin-jiminny
JY-20701
JY-20701
| improve webhook delays
| improve webhook delays
a3a308f
a3a308f
@yalokin-jiminny
JY-20701
JY-20701
| update tests
| update tests
64251d2
64251d2
@yalokin-jiminny
JY-20701
JY-20701
| add OpportunitySyncTrait timings log
| add OpportunitySyncTrait timings log
42e30cf
42e30cf...
|
NULL
|
|
60922
|
1313
|
45
|
2026-04-21T06:25:37.633429+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-21/1776 /Users/lukas/.screenpipe/data/data/2026-04-21/1776752737633_m2.jpg...
|
Firefox
|
JY-20701 | Reschedule HubSpot Sync Objects by yalo JY-20701 | Reschedule HubSpot Sync Objects by yalokin-jiminny · Pull Request #11989 · jiminny/app — Work...
|
True
|
github.com/jiminny/app/pull/11989
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Platform Sprint 2 Q2 - Platform Team - Scrum Board Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira
[SRD-6787] Issue with reconnecting Zoho - Jira
[SRD-6787] Issue with reconnecting Zoho - Jira
[SRD-6787] Issue with reconnecting Zoho - Jira
[SRD-6787] Issue with reconnecting Zoho - Jira
JY-20698 handle failed field sync on playbook import activity types by LakyLak · Pull Request #11988 · jiminny/app
JY-20698 handle failed field sync on playbook import activity types by LakyLak · Pull Request #11988 · jiminny/app
Jiminny MCP Connector - Product - Confluence
Jiminny MCP Connector - Product - Confluence
[JY-20676] Notify the user if a Panorama prompts is deleted but is used in AJ Report - Jira
[JY-20676] Notify the user if a Panorama prompts is deleted but is used in AJ Report - Jira
Jiminny Mail
Jiminny Mail
[JY-20500] Batch initial sync for Salesforce - Jira
[JY-20500] Batch initial sync for Salesforce - Jira
Feed — jiminny — Sentry
Feed — jiminny — Sentry
Jiminny
Jiminny
JY-20701 | Reschedule HubSpot Sync Objects by yalokin-jiminny · Pull Request #11989 · jiminny/app
JY-20701 | Reschedule HubSpot Sync Objects by yalokin-jiminny · Pull Request #11989 · jiminny/app
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to content
Skip to content
Open menu
Homepage (g then d)
jiminny
jiminny
app
app
Search or jump to…
Type
/
to search
Chat with Copilot
Open Copilot…
Create new...
Issues(g then i)
Pull requests
Repositories
You have unread notifications(g then n)
Open user navigation menu
Repository navigation
Repository navigation
Code
Code
Pull requests (31)
Pull requests
(
31
)
Agents
Agents
Actions
Actions
Wiki
Wiki
Security and quality (21)
Security and quality
(
21
)
Insights
Insights
Settings
Settings
Important update
Important update
On April 24 we'll start using GitHub Copilot interaction data for AI model training unless you opt out.
Review this update
Review this update
and manage your preferences in your
GitHub account settings
GitHub account settings
.
Dismiss banner
Review requested
Review requested
yalokin-jiminny
yalokin-jiminny
requested your review on this pull request.
Add your review
Add your review
JY-20701 | Reschedule HubSpot Sync Objects #11989 Edit title
JY-20701 | Reschedule HubSpot Sync Objects
#
11989
Edit title
Awaiting approval
Awaiting approval
Code
Code
Open
yalokin-jiminny
yalokin-jiminny
wants to merge 22 commits into
master
master
from
JY-20701-reschedule-HubSpot-processing
JY-20701-reschedule-HubSpot-processing
Copy head branch name to clipboard
Lines changed: 949 additions & 97 deletions
Conversation (5)
Conversation
(
5
)
Commits (22)
Commits
(
22
)
Checks (3)
Checks
(
3
)
Files changed (11)
Files changed
(
11
)
Open
JY-20701 | Reschedule HubSpot Sync Objects #11989 yalokin-jiminny wants to merge 22 commits into master from JY-20701-reschedule-HubSpot-processing Copy head branch name to clipboard
JY-20701 | Reschedule HubSpot Sync Objects
JY-20701 | Reschedule HubSpot Sync Objects
#
11989
yalokin-jiminny
yalokin-jiminny
wants to merge 22 commits into
master
master
from
JY-20701-reschedule-HubSpot-processing
JY-20701-reschedule-HubSpot-processing
Copy head branch name to clipboard
Conversation
Conversation
@yalokin-jiminny
Show options
yalokin-jiminny commented 4 days ago •
yalokin-jiminny
yalokin-jiminny
commented
4 days ago
4 days ago
•
edited
edited
JIRA: JY-20701
JIRA:
JY-20701
JY-20701
Casus:
Casus:
We want more fluent curve of the jobs distribution (no spikes) in
crm-sync
queue
The more frequent HubSpot processing will help to have less auto-scaling / down-scaling events, thus reducing the jobs wait times
Changes:
Changes:
Remove HubSpot from SyncObjects
Create separate HubSpotSyncObjects that runs each 5 min instead of each 30
Extract common code
Improve processing Webhooks jobs distribution
Optimize ImportOpportunityBatch:
cache OpportunitySyncableFields, OwnerProfiles, RecordType
remove findContactByConfigurationAndId - Contact ID already exist
add timings log
Add or remove reactions
@yalokin-jiminny
Show options
Author
yalokin-jiminny commented 4 days ago
yalokin-jiminny
yalokin-jiminny
commented
4 days ago
4 days ago
@claude
@claude
Add or remove reactions
react with eyes
👀
1
@claude
Show options
claude bot commented 4 days ago •
claude
claude
bot
commented
4 days ago
4 days ago
•
edited
edited
Claude finished
@yalokin-jiminny
@yalokin-jiminny
's task in 1m 59s
——
View job
View job
Code Review
Code Review
Overall the approach is clean — extracting the shared logic into
SyncObjectsCommandTrait
is a good call, and the scheduling design (offset cron at
:01
to avoid spikes) makes sense. I found two bugs and a few minor points.
Bugs
Bugs
1. Null dereference on
$crmConfig
—
app/Jobs/Crm/SyncHubspotObjects.php:49-51
$
crmConfig
=
$
team
->
crm
;
if
(
$
crmConfig
->
provider
!== Configuration::
PROVIDER_HUBSPOT
) {
Copy
$team->crm
can be null if the team has no CRM configuration record. Accessing
->provider
on null will throw a fatal error. The existing
SyncObjects
job handles this by using
??
(
$crmConfig->provider ?? 'unknown'
). The new job needs a null guard here:
$
crmConfig
=
$
team
->
crm
;
if
(
$
crmConfig
===
null
||
$
crmConfig
->
provider
!== Configuration::
PROVIDER_HUBSPOT
) {
$
logger
->
warning
(
'
[SyncHubspotObjects] Team has no HubSpot CRM config
'
, [
'
team
'
=>
$
this
->
teamId
]);
return
;
}
Copy
Fix this →
Fix this →
2.
$lastSyncedAt
is nullable but
syncHubspotCrmObjects
requires
Carbon
—
app/Jobs/Crm/SyncHubspotObjects.php:85,88,116
$
lastSyncedAt
=
$
crmConfig
->
last_synced_at
;
// can be null on first run
.
.
.
$
this
->
syncHubspotCrmObjects
(
$
crmService
,
$
lastSyncedAt
);
// ...
private
function
syncHubspotCrmObjects(
HubspotInterface
$
crmService
,
Carbon
$
lastSyncedAt
):
void
Copy
With
declare(strict_types=1)
, passing
null
to a
Carbon
-typed parameter throws a
TypeError
. A team that has never synced before will crash on the first run. The parameter should be
?Carbon
(and
syncOpportunities
should handle null), or provide a fallback like
Carbon::createFromTimestamp(0)
.
Fix this →
Fix this →
Minor Issues
Minor Issues
3. Double call to
getLogPrefix()
—
app/Console/Commands/Crm/Traits/SyncObjectsCommandTrait.php:52
$
prefix
=
$
this
->
getLogPrefix
() ?
$
this
->
getLogPrefix
() .
'
'
:
''
;
Copy
getLogPrefix()
is called twice. Trivial but unnecessary — capture the result in a variable first.
4.
SyncObjects
command doesn't guard HubSpot when
{team}
argument is given —
app/Console/Commands/Crm/SyncObjects.php:40-41
if
(
$
teamId
) {
$
teams
[] = Team::
idOrUuId
(
$
teamId
);
// no provider check
Copy
Running
crm:sync-objects <hubspot-team-id>
dispatches a
SyncObjectsJob
for a HubSpot team, which now silently warns and returns. From an operator perspective this is confusing — the command appears to accept the team but does nothing. Worth adding a provider check and a console error message pointing to
crm:sync-hubspot-objects
.
Design Notes
Design Notes
Scheduler placement
:
crm:sync-hubspot-objects
is placed inside
scheduleEveryFiveMinutes()
but uses a manual cron
'1,6,11,16,21,26,31,36,41,46,51,56 * * * *'
instead of
->everyFiveMinutes()
. The 1-minute offset is intentional (good thinking to stagger from the other jobs), but it's slightly inconsistent with the method's name. A comment explaining the offset would help future readers.
SQS visibility timeout
:
SyncHubspotObjects
uses 1 hour (
60 * 60
) vs
SyncObjects
's 6 hours (
60 * 60 * 6
). Appropriate given the more frequent, presumably lighter runs.
Stagger delay
: HubSpot uses 1s between teams vs 2s for general sync. Fine for 5-min runs, though worth monitoring if the number of HubSpot teams grows large enough that the last job barely fits within the 5-minute window.
Add or remove reactions
@yalokin-jiminny
yalokin-jiminny
yalokin-jiminny
force-pushed
force-pushed
the
JY-20553-debug-crm-sync-delays
branch from
f6c0ec3
f6c0ec3
to
5928f60
5928f60
Compare
Compare
yesterday
yesterday
@yalokin-jiminny
yalokin-jiminny
yalokin-jiminny
force-pushed
force-pushed
the
JY-20701-reschedule-HubSpot-processing
branch from
3d7234a
3d7234a
to
1d10796
1d10796
Compare
Compare
yesterday
yesterday
Base automatically changed from
JY-20553-debug-crm-sync-delays
to
master
19 hours ago
19 hours ago
@yalokin-jiminny
yalokin-jiminny
yalokin-jiminny
force-pushed
force-pushed
the
JY-20701-reschedule-HubSpot-processing
branch from
fec25f3
fec25f3
to
f0119c9
f0119c9
Compare
Compare
19 hours ago
19 hours ago
yalokin-jiminny
yalokin-jiminny
added
17
commits
15 hours ago
15 hours ago
@yalokin-jiminny
JY-20701
JY-20701
| remove HubSpot from 30 min scheduler
| remove HubSpot from 30 min scheduler
2f38f13
2f38f13
@yalokin-jiminny
JY-20701
JY-20701
| Add SyncHubspotObjects Job
| Add SyncHubspotObjects Job
50b0e20
50b0e20
@yalokin-jiminny
JY-20701
JY-20701
| Add HubSpot sync objects scheduler each 5 min
| Add HubSpot sync objects scheduler each 5 min
ea92c0f
ea92c0f
@yalokin-jiminny
JY-20701
JY-20701
| extract duplicated code
| extract duplicated code
7ecdad3
7ecdad3
@yalokin-jiminny
JY-20701
JY-20701
| cs
| cs
525cbb2
525cbb2
@yalokin-jiminny
JY-20701
JY-20701
| safe crm check
| safe crm check
35de0d5
35de0d5
@yalokin-jiminny
JY-20701
JY-20701
| null on first-time sync
| null on first-time sync
ac1f89e
ac1f89e
@yalokin-jiminny
JY-20701
JY-20701
| minor improvement
| minor improvement
bab377e
bab377e
@yalokin-jiminny
JY-20701
JY-20701
| improve filter by team
| improve filter by team
f39dc56
f39dc56
@yalokin-jiminny
JY-20701
JY-20701
| add scheduler comment
| add scheduler comment
f2109d7
f2109d7
@yalokin-jiminny
JY-20701
JY-20701
| improve delays
| improve delays
f929670
f929670
@yalokin-jiminny
JY-20701
JY-20701
| add tests
| add tests
9691864
9691864
@yalokin-jiminny
JY-20701
JY-20701
| improve webhook delays
| improve webhook delays...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira","depth":4,"bounds":{"left":0.0018284575,"top":0.0518755,"width":0.07596409,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"[SRD-6787] Issue with reconnecting Zoho - Jira","depth":4,"bounds":{"left":0.0,"top":0.09497207,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[SRD-6787] Issue with reconnecting Zoho - Jira","depth":5,"bounds":{"left":0.013297873,"top":0.10614525,"width":0.08344415,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[SRD-6787] Issue with reconnecting Zoho - Jira","depth":4,"bounds":{"left":0.0,"top":0.12769353,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[SRD-6787] Issue with reconnecting Zoho - Jira","depth":5,"bounds":{"left":0.013297873,"top":0.13886672,"width":0.08344415,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20698 handle failed field sync on playbook import activity types by LakyLak · Pull Request #11988 · jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.16041501,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20698 handle failed field sync on playbook import activity types by LakyLak · Pull Request #11988 · jiminny/app","depth":5,"bounds":{"left":0.013297873,"top":0.17158818,"width":0.19963431,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jiminny MCP Connector - Product - Confluence","depth":4,"bounds":{"left":0.0,"top":0.19313647,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny MCP Connector - Product - Confluence","depth":5,"bounds":{"left":0.013297873,"top":0.20430966,"width":0.08294548,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[JY-20676] Notify the user if a Panorama prompts is deleted but is used in AJ Report - Jira","depth":4,"bounds":{"left":0.0,"top":0.22585794,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[JY-20676] Notify the user if a Panorama prompts is deleted but is used in AJ Report - Jira","depth":5,"bounds":{"left":0.013297873,"top":0.23703113,"width":0.15791224,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jiminny Mail","depth":4,"bounds":{"left":0.0,"top":0.2585794,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny Mail","depth":5,"bounds":{"left":0.013297873,"top":0.2697526,"width":0.02144282,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[JY-20500] Batch initial sync for Salesforce - Jira","depth":4,"bounds":{"left":0.0,"top":0.29130086,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[JY-20500] Batch initial sync for Salesforce - Jira","depth":5,"bounds":{"left":0.013297873,"top":0.30247405,"width":0.08610372,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Feed — jiminny — Sentry","depth":4,"bounds":{"left":0.0,"top":0.32402235,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Feed — jiminny — Sentry","depth":5,"bounds":{"left":0.013297873,"top":0.33519554,"width":0.042719416,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Jiminny","depth":4,"bounds":{"left":0.0,"top":0.3567438,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Jiminny","depth":5,"bounds":{"left":0.013297873,"top":0.367917,"width":0.013131649,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"JY-20701 | Reschedule HubSpot Sync Objects by yalokin-jiminny · Pull Request #11989 · jiminny/app","depth":4,"bounds":{"left":0.0,"top":0.38946527,"width":0.07962101,"height":0.032721467},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"JY-20701 | Reschedule HubSpot Sync Objects by yalokin-jiminny · Pull Request #11989 · jiminny/app","depth":5,"bounds":{"left":0.013297873,"top":0.40063846,"width":0.1740359,"height":0.010774142},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.06732048,"top":0.39664805,"width":0.007978723,"height":0.01915403},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Tab","depth":4,"bounds":{"left":0.0028257978,"top":0.4237829,"width":0.07413564,"height":0.025538707},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.0028257978,"top":0.97007185,"width":0.010638298,"height":0.025538707},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"bounds":{"left":0.013796543,"top":0.97007185,"width":0.010638298,"height":0.025538707},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"bounds":{"left":0.024933511,"top":0.97007185,"width":0.010638298,"height":0.025538707},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"bounds":{"left":0.036070477,"top":0.97007185,"width":0.010638298,"height":0.025538707},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"bounds":{"left":0.04720745,"top":0.97007185,"width":0.010638298,"height":0.025538707},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Skip to content","depth":6,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip to content","depth":7,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Open menu","depth":10,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Homepage (g then d)","depth":9,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"jiminny","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"jiminny","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"app","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"app","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Search or jump to…","depth":9,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Type","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"/","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"to search","depth":12,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Chat with Copilot","depth":10,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXMenuButton","text":"Open Copilot…","depth":9,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXMenuButton","text":"Create new...","depth":9,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"Issues(g then i)","depth":9,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Pull requests","depth":9,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Repositories","depth":9,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"You have unread notifications(g then n)","depth":9,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Open user navigation menu","depth":9,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Repository navigation","depth":9,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Repository navigation","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Code","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Code","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Pull requests (31)","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Pull requests","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"31","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Agents","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Agents","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Actions","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Actions","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Wiki","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Wiki","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Security and quality (21)","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Security and quality","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"21","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Insights","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Insights","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Settings","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Settings","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Important update","depth":10,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Important update","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"On April 24 we'll start using GitHub Copilot interaction data for AI model training unless you opt out.","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Review this update","depth":10,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Review this update","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"and manage your preferences in your","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"GitHub account settings","depth":10,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"GitHub account settings","depth":11,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":10,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Dismiss banner","depth":9,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Review requested","depth":15,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Review requested","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"yalokin-jiminny","depth":15,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"yalokin-jiminny","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"requested your review on this pull request.","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Add your review","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Add your review","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"JY-20701 | Reschedule HubSpot Sync Objects #11989 Edit title","depth":13,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"JY-20701 | Reschedule HubSpot Sync Objects","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"#","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"11989","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Edit title","depth":14,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Awaiting approval","depth":13,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Awaiting approval","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Code","depth":13,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Code","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Open","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"yalokin-jiminny","depth":15,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"yalokin-jiminny","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"wants to merge 22 commits into","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"master","depth":15,"role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"master","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"from","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"JY-20701-reschedule-HubSpot-processing","depth":16,"role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20701-reschedule-HubSpot-processing","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Copy head branch name to clipboard","depth":16,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Lines changed: 949 additions & 97 deletions","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Conversation (5)","depth":16,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Conversation","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"5","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Commits (22)","depth":16,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Commits","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"22","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Checks (3)","depth":16,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Checks","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"3","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Files changed (11)","depth":16,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Files changed","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"11","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Open","depth":14,"bounds":{"left":0.34840426,"top":0.0726257,"width":0.011968086,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"JY-20701 | Reschedule HubSpot Sync Objects #11989 yalokin-jiminny wants to merge 22 commits into master from JY-20701-reschedule-HubSpot-processing Copy head branch name to clipboard","depth":14,"bounds":{"left":0.36702126,"top":0.058260176,"width":0.23138298,"height":0.042298485},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXLink","text":"JY-20701 | Reschedule HubSpot Sync Objects","depth":16,"bounds":{"left":0.36702126,"top":0.05865922,"width":0.10322473,"height":0.01915403},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20701 | Reschedule HubSpot Sync Objects","depth":17,"bounds":{"left":0.36702126,"top":0.06304868,"width":0.10322473,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"#","depth":16,"bounds":{"left":0.47290558,"top":0.06304868,"width":0.0029920214,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"11989","depth":16,"bounds":{"left":0.4758976,"top":0.06304868,"width":0.012965426,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"yalokin-jiminny","depth":18,"bounds":{"left":0.36702126,"top":0.08339984,"width":0.029920213,"height":0.011971269},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"yalokin-jiminny","depth":19,"bounds":{"left":0.36702126,"top":0.08339984,"width":0.029920213,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"wants to merge 22 commits into","depth":18,"bounds":{"left":0.39827126,"top":0.08339984,"width":0.06017287,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"master","depth":18,"bounds":{"left":0.45977393,"top":0.08180367,"width":0.018450798,"height":0.015163607},"role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"master","depth":19,"bounds":{"left":0.46176863,"top":0.083798885,"width":0.014461436,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"from","depth":19,"bounds":{"left":0.47955453,"top":0.08339984,"width":0.008643617,"height":0.011971269},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"JY-20701-reschedule-HubSpot-processing","depth":19,"bounds":{"left":0.4895279,"top":0.08180367,"width":0.09524601,"height":0.015163607},"role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20701-reschedule-HubSpot-processing","depth":20,"bounds":{"left":0.4915226,"top":0.083798885,"width":0.09125665,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Copy head branch name to clipboard","depth":19,"bounds":{"left":0.58610374,"top":0.07821229,"width":0.00930851,"height":0.022346368},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Conversation","depth":12,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Conversation","depth":13,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"@yalokin-jiminny","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Show options","depth":15,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXHeading","text":"yalokin-jiminny commented 4 days ago •","depth":14,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXLink","text":"yalokin-jiminny","depth":16,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"yalokin-jiminny","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"commented","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"4 days ago","depth":15,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"4 days ago","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"edited","depth":17,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"edited","depth":19,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"JIRA: JY-20701","depth":16,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"JIRA:","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"JY-20701","depth":17,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20701","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Casus:","depth":16,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Casus:","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"We want more fluent curve of the jobs distribution (no spikes) in","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"crm-sync","depth":19,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"queue","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"The more frequent HubSpot processing will help to have less auto-scaling / down-scaling events, thus reducing the jobs wait times","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Changes:","depth":16,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Changes:","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Remove HubSpot from SyncObjects","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Create separate HubSpotSyncObjects that runs each 5 min instead of each 30","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Extract common code","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Improve processing Webhooks jobs distribution","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Optimize ImportOpportunityBatch:","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"cache OpportunitySyncableFields, OwnerProfiles, RecordType","depth":20,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"remove findContactByConfigurationAndId - Contact ID already exist","depth":20,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"add timings log","depth":20,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Add or remove reactions","depth":16,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"@yalokin-jiminny","depth":13,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Show options","depth":14,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Author","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"yalokin-jiminny commented 4 days ago","depth":13,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXLink","text":"yalokin-jiminny","depth":15,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"yalokin-jiminny","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"commented","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"4 days ago","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"4 days ago","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"@claude","depth":17,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"@claude","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Add or remove reactions","depth":15,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"react with eyes","depth":14,"role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"👀","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"@claude","depth":13,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Show options","depth":14,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXHeading","text":"claude bot commented 4 days ago •","depth":13,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXLink","text":"claude","depth":15,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"claude","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"bot","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"commented","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"4 days ago","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"4 days ago","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"•","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"edited","depth":16,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"edited","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Claude finished","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"@yalokin-jiminny","depth":18,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"@yalokin-jiminny","depth":19,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"'s task in 1m 59s","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"——","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"View job","depth":17,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"View job","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Code Review","depth":16,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Code Review","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Overall the approach is clean — extracting the shared logic into","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"SyncObjectsCommandTrait","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"is a good call, and the scheduling design (offset cron at","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":":01","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"to avoid spikes) makes sense. I found two bugs and a few minor points.","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Bugs","depth":16,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Bugs","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"1. Null dereference on","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$crmConfig","depth":19,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"—","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"app/Jobs/Crm/SyncHubspotObjects.php:49-51","depth":19,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$","depth":17,"bounds":{"left":0.36735374,"top":0.0,"width":0.0023271276,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"crmConfig","depth":17,"bounds":{"left":0.36968085,"top":0.0,"width":0.02144282,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"=","depth":17,"bounds":{"left":0.39112368,"top":0.0,"width":0.0071476065,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$","depth":17,"bounds":{"left":0.39827126,"top":0.0,"width":0.0023271276,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"team","depth":17,"bounds":{"left":0.4005984,"top":0.0,"width":0.009640957,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"->","depth":17,"bounds":{"left":0.41023937,"top":0.0,"width":0.004654255,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"crm","depth":17,"bounds":{"left":0.41489363,"top":0.0,"width":0.0071476065,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":";","depth":17,"bounds":{"left":0.42204124,"top":0.0,"width":0.002493351,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"if","depth":17,"bounds":{"left":0.36735374,"top":0.0,"width":0.004654255,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":17,"bounds":{"left":0.37200797,"top":0.0,"width":0.0048204786,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$","depth":17,"bounds":{"left":0.37682846,"top":0.0,"width":0.0023271276,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"crmConfig","depth":17,"bounds":{"left":0.37915558,"top":0.0,"width":0.02144282,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"->","depth":17,"bounds":{"left":0.4005984,"top":0.0,"width":0.0048204786,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"provider","depth":17,"bounds":{"left":0.40541887,"top":0.0,"width":0.019115692,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"!== Configuration::","depth":17,"bounds":{"left":0.4245346,"top":0.0,"width":0.047539894,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"PROVIDER_HUBSPOT","depth":17,"bounds":{"left":0.47207448,"top":0.0,"width":0.038231384,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":") {","depth":17,"bounds":{"left":0.5103058,"top":0.0,"width":0.0071476065,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Copy","depth":17,"bounds":{"left":0.60538566,"top":0.0,"width":0.011303191,"height":0.028332002},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"$team->crm","depth":18,"bounds":{"left":0.36353058,"top":0.0,"width":0.023769947,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"can be null if the team has no CRM configuration record. Accessing","depth":17,"bounds":{"left":0.38896278,"top":0.0,"width":0.1471077,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"->provider","depth":18,"bounds":{"left":0.5375665,"top":0.0,"width":0.023936171,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"on null will throw a fatal error. The existing","depth":17,"bounds":{"left":0.3620346,"top":0.0,"width":0.2526596,"height":0.030327214},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"SyncObjects","depth":18,"bounds":{"left":0.40375665,"top":0.0,"width":0.026097074,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"job handles this by using","depth":17,"bounds":{"left":0.43151596,"top":0.0,"width":0.055851065,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"??","depth":18,"bounds":{"left":0.48902926,"top":0.0,"width":0.004654255,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":17,"bounds":{"left":0.49534574,"top":0.0,"width":0.0029920214,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$crmConfig->provider ?? 'unknown'","depth":18,"bounds":{"left":0.5,"top":0.0,"width":0.07862367,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"). The new job needs a null guard here:","depth":17,"bounds":{"left":0.3620346,"top":0.0,"width":0.2486702,"height":0.030327214},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$","depth":17,"bounds":{"left":0.36735374,"top":0.05546688,"width":0.0023271276,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"crmConfig","depth":17,"bounds":{"left":0.36968085,"top":0.05546688,"width":0.02144282,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"=","depth":17,"bounds":{"left":0.39112368,"top":0.05546688,"width":0.0071476065,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$","depth":17,"bounds":{"left":0.39827126,"top":0.05546688,"width":0.0023271276,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"team","depth":17,"bounds":{"left":0.4005984,"top":0.05546688,"width":0.009640957,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"->","depth":17,"bounds":{"left":0.41023937,"top":0.05546688,"width":0.004654255,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"crm","depth":17,"bounds":{"left":0.41489363,"top":0.05546688,"width":0.0071476065,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":";","depth":17,"bounds":{"left":0.42204124,"top":0.05546688,"width":0.002493351,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"if","depth":17,"bounds":{"left":0.36735374,"top":0.0830008,"width":0.004654255,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":17,"bounds":{"left":0.37200797,"top":0.0830008,"width":0.0048204786,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$","depth":17,"bounds":{"left":0.37682846,"top":0.0830008,"width":0.0023271276,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"crmConfig","depth":17,"bounds":{"left":0.37915558,"top":0.0830008,"width":0.02144282,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"===","depth":17,"bounds":{"left":0.4005984,"top":0.0830008,"width":0.011968086,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"null","depth":17,"bounds":{"left":0.41256648,"top":0.0830008,"width":0.009474734,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"||","depth":17,"bounds":{"left":0.42204124,"top":0.0830008,"width":0.009640957,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$","depth":17,"bounds":{"left":0.43168217,"top":0.0830008,"width":0.0023271276,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"crmConfig","depth":17,"bounds":{"left":0.4340093,"top":0.0830008,"width":0.02144282,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"->","depth":17,"bounds":{"left":0.4554521,"top":0.0830008,"width":0.0048204786,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"provider","depth":17,"bounds":{"left":0.4602726,"top":0.0830008,"width":0.018949468,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"!== Configuration::","depth":17,"bounds":{"left":0.4792221,"top":0.0830008,"width":0.047706116,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"PROVIDER_HUBSPOT","depth":17,"bounds":{"left":0.5269282,"top":0.0830008,"width":0.038065158,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":") {","depth":17,"bounds":{"left":0.36735374,"top":0.0830008,"width":0.20478724,"height":0.025538707},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$","depth":17,"bounds":{"left":0.37682846,"top":0.09696728,"width":0.0023271276,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"logger","depth":17,"bounds":{"left":0.37915558,"top":0.09696728,"width":0.014295213,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"->","depth":17,"bounds":{"left":0.3934508,"top":0.09696728,"width":0.0048204786,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"warning","depth":17,"bounds":{"left":0.39827126,"top":0.100159615,"width":0.01662234,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":17,"bounds":{"left":0.41489363,"top":0.100159615,"width":0.002493351,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"'","depth":17,"bounds":{"left":0.41738698,"top":0.100159615,"width":0.0023271276,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"[SyncHubspotObjects] Team has no HubSpot CRM config","depth":17,"bounds":{"left":0.4197141,"top":0.100159615,"width":0.121509306,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"'","depth":17,"bounds":{"left":0.5412234,"top":0.100159615,"width":0.0023271276,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":", [","depth":17,"bounds":{"left":0.54355055,"top":0.100159615,"width":0.0071476065,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"'","depth":17,"bounds":{"left":0.55069816,"top":0.100159615,"width":0.002493351,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"team","depth":17,"bounds":{"left":0.5531915,"top":0.100159615,"width":0.009474734,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"'","depth":17,"bounds":{"left":0.56266624,"top":0.100159615,"width":0.0023271276,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"=>","depth":17,"bounds":{"left":0.5649933,"top":0.100159615,"width":0.009640957,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$","depth":17,"bounds":{"left":0.5746343,"top":0.100159615,"width":0.0023271276,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"this","depth":17,"bounds":{"left":0.57696146,"top":0.100159615,"width":0.009474734,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"->","depth":17,"bounds":{"left":0.58643615,"top":0.100159615,"width":0.0048204786,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"teamId","depth":17,"bounds":{"left":0.5912567,"top":0.100159615,"width":0.014295213,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"]);","depth":17,"bounds":{"left":0.36735374,"top":0.100159615,"width":0.24534574,"height":0.025139665},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"return","depth":17,"bounds":{"left":0.37682846,"top":0.113727055,"width":0.014295213,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":";\n}","depth":17,"bounds":{"left":0.36735374,"top":0.113727055,"width":0.026097074,"height":0.025538707},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Copy","depth":17,"bounds":{"left":0.60538566,"top":0.05387071,"width":0.011303191,"height":0.028332002},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Fix this →","depth":17,"bounds":{"left":0.3620346,"top":0.16999201,"width":0.020611702,"height":0.013567438},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Fix this →","depth":18,"bounds":{"left":0.3620346,"top":0.16999201,"width":0.020611702,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2.","depth":18,"bounds":{"left":0.3620346,"top":0.22785315,"width":0.005485372,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$lastSyncedAt","depth":19,"bounds":{"left":0.36918217,"top":0.22984837,"width":0.030917553,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"is nullable but","depth":18,"bounds":{"left":0.40159574,"top":0.22785315,"width":0.033909574,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"syncHubspotCrmObjects","depth":19,"bounds":{"left":0.43716756,"top":0.22984837,"width":0.050033245,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"requires","depth":18,"bounds":{"left":0.4886968,"top":0.22785315,"width":0.020944148,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Carbon","depth":19,"bounds":{"left":0.5113032,"top":0.22984837,"width":0.014295213,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"—","depth":18,"bounds":{"left":0.5270944,"top":0.22785315,"width":0.0066489363,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"app/Jobs/Crm/SyncHubspotObjects.php:85,88,116","depth":19,"bounds":{"left":0.3620346,"top":0.22984837,"width":0.20428856,"height":0.028332002},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$","depth":17,"bounds":{"left":0.36735374,"top":0.28611332,"width":0.0023271276,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"lastSyncedAt","depth":17,"bounds":{"left":0.36968085,"top":0.28611332,"width":0.028590426,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"=","depth":17,"bounds":{"left":0.39827126,"top":0.28611332,"width":0.0071476065,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$","depth":17,"bounds":{"left":0.40541887,"top":0.28611332,"width":0.0023271276,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"crmConfig","depth":17,"bounds":{"left":0.40774602,"top":0.28611332,"width":0.02144282,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"->","depth":17,"bounds":{"left":0.42918882,"top":0.28611332,"width":0.0048204786,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"last_synced_at","depth":17,"bounds":{"left":0.4340093,"top":0.28611332,"width":0.033410903,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":";","depth":17,"bounds":{"left":0.46742022,"top":0.28611332,"width":0.0071476065,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"// can be null on first run","depth":17,"bounds":{"left":0.47456783,"top":0.28611332,"width":0.064328454,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":17,"bounds":{"left":0.36735374,"top":0.30007982,"width":0.0023271276,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":17,"bounds":{"left":0.36968085,"top":0.30007982,"width":0.0023271276,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":17,"bounds":{"left":0.37200797,"top":0.30007982,"width":0.002493351,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$","depth":17,"bounds":{"left":0.36735374,"top":0.31364724,"width":0.0023271276,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"this","depth":17,"bounds":{"left":0.36968085,"top":0.31364724,"width":0.009474734,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"->","depth":17,"bounds":{"left":0.37915558,"top":0.31364724,"width":0.0048204786,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"syncHubspotCrmObjects","depth":17,"bounds":{"left":0.38397607,"top":0.31364724,"width":0.050033245,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":17,"bounds":{"left":0.4340093,"top":0.31364724,"width":0.0023271276,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$","depth":17,"bounds":{"left":0.43633643,"top":0.31364724,"width":0.002493351,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"crmService","depth":17,"bounds":{"left":0.43882978,"top":0.31364724,"width":0.023769947,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":",","depth":17,"bounds":{"left":0.46259972,"top":0.31364724,"width":0.0048204786,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$","depth":17,"bounds":{"left":0.46742022,"top":0.31364724,"width":0.0023271276,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"lastSyncedAt","depth":17,"bounds":{"left":0.46974733,"top":0.31364724,"width":0.028590426,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":");","depth":17,"bounds":{"left":0.49833778,"top":0.31364724,"width":0.0048204786,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"// ...","depth":17,"bounds":{"left":0.36735374,"top":0.34118116,"width":0.014295213,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"private","depth":17,"bounds":{"left":0.36735374,"top":0.35514766,"width":0.01662234,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"function","depth":17,"bounds":{"left":0.3863032,"top":0.35514766,"width":0.019115692,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"syncHubspotCrmObjects(","depth":17,"bounds":{"left":0.40541887,"top":0.35514766,"width":0.054853722,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"HubspotInterface","depth":17,"bounds":{"left":0.4602726,"top":0.35514766,"width":0.038065158,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$","depth":17,"bounds":{"left":0.5006649,"top":0.35514766,"width":0.002493351,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"crmService","depth":17,"bounds":{"left":0.5031583,"top":0.35514766,"width":0.023769947,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":",","depth":17,"bounds":{"left":0.5269282,"top":0.35514766,"width":0.0048204786,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Carbon","depth":17,"bounds":{"left":0.53174865,"top":0.35514766,"width":0.014295213,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$","depth":17,"bounds":{"left":0.548371,"top":0.35514766,"width":0.0023271276,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"lastSyncedAt","depth":17,"bounds":{"left":0.55069816,"top":0.35514766,"width":0.028590426,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"):","depth":17,"bounds":{"left":0.57928854,"top":0.35514766,"width":0.0071476065,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"void","depth":17,"bounds":{"left":0.58643615,"top":0.35514766,"width":0.009640957,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Copy","depth":17,"bounds":{"left":0.60538566,"top":0.27893057,"width":0.011303191,"height":0.028332002},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"With","depth":17,"bounds":{"left":0.3620346,"top":0.39505187,"width":0.011136968,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"declare(strict_types=1)","depth":18,"bounds":{"left":0.37466756,"top":0.39704707,"width":0.054853722,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":", passing","depth":17,"bounds":{"left":0.43118352,"top":0.39505187,"width":0.02044548,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"null","depth":18,"bounds":{"left":0.45329124,"top":0.39704707,"width":0.009474734,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"to a","depth":17,"bounds":{"left":0.4644282,"top":0.5674381,"width":0.010638298,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Carbon","depth":18,"bounds":{"left":0.47672874,"top":0.56943333,"width":0.014295213,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-typed parameter throws a","depth":17,"bounds":{"left":0.49251994,"top":0.5674381,"width":0.05867686,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"TypeError","depth":18,"bounds":{"left":0.55285907,"top":0.56943333,"width":0.02144282,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":". A team that has never synced before will crash on the first run. The parameter should be","depth":17,"bounds":{"left":0.3620346,"top":0.5674381,"width":0.25033244,"height":0.030327214},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"?Carbon","depth":18,"bounds":{"left":0.5197806,"top":0.58619314,"width":0.01662234,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(and","depth":17,"bounds":{"left":0.53806514,"top":0.58419794,"width":0.012300532,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"syncOpportunities","depth":18,"bounds":{"left":0.55202794,"top":0.58619314,"width":0.040392287,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"should handle null), or provide a fallback like","depth":17,"bounds":{"left":0.3620346,"top":0.58419794,"width":0.24767287,"height":0.030327214},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Carbon::createFromTimestamp(0)","depth":18,"bounds":{"left":0.4446476,"top":0.6029529,"width":0.071476065,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":17,"bounds":{"left":0.51761967,"top":0.6009577,"width":0.0013297872,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Fix this →","depth":17,"bounds":{"left":0.3620346,"top":0.63048685,"width":0.020611702,"height":0.013567438},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Fix this →","depth":18,"bounds":{"left":0.3620346,"top":0.63048685,"width":0.020611702,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Minor Issues","depth":16,"bounds":{"left":0.3620346,"top":0.6867518,"width":0.25731382,"height":0.017557861},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Minor Issues","depth":17,"bounds":{"left":0.3620346,"top":0.68715084,"width":0.034408245,"height":0.016759777},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"3. Double call to","depth":18,"bounds":{"left":0.3620346,"top":0.7186752,"width":0.037400264,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"getLogPrefix()","depth":19,"bounds":{"left":0.4010971,"top":0.7206704,"width":0.03324468,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"—","depth":18,"bounds":{"left":0.43600398,"top":0.7186752,"width":0.006482713,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"app/Console/Commands/Crm/Traits/SyncObjectsCommandTrait.php:52","depth":19,"bounds":{"left":0.44414893,"top":0.7206704,"width":0.14777261,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$","depth":17,"bounds":{"left":0.36735374,"top":0.7601756,"width":0.0023271276,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"prefix","depth":17,"bounds":{"left":0.36968085,"top":0.7601756,"width":0.014295213,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"=","depth":17,"bounds":{"left":0.38397607,"top":0.7601756,"width":0.0071476065,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$","depth":17,"bounds":{"left":0.39112368,"top":0.7601756,"width":0.0023271276,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"this","depth":17,"bounds":{"left":0.3934508,"top":0.7601756,"width":0.009640957,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"->","depth":17,"bounds":{"left":0.40309176,"top":0.7601756,"width":0.004654255,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"getLogPrefix","depth":17,"bounds":{"left":0.40774602,"top":0.7601756,"width":0.028590426,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"() ?","depth":17,"bounds":{"left":0.43633643,"top":0.7601756,"width":0.011968086,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$","depth":17,"bounds":{"left":0.44830453,"top":0.7601756,"width":0.0023271276,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"this","depth":17,"bounds":{"left":0.45063165,"top":0.7601756,"width":0.009640957,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"->","depth":17,"bounds":{"left":0.4602726,"top":0.7601756,"width":0.004654255,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"getLogPrefix","depth":17,"bounds":{"left":0.46492687,"top":0.7601756,"width":0.028590426,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"() .","depth":17,"bounds":{"left":0.49351728,"top":0.7601756,"width":0.011968086,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"'","depth":17,"bounds":{"left":0.50548536,"top":0.7601756,"width":0.0023271276,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"'","depth":17,"bounds":{"left":0.5103058,"top":0.7601756,"width":0.0023271276,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":":","depth":17,"bounds":{"left":0.51263297,"top":0.7601756,"width":0.0071476065,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"''","depth":17,"bounds":{"left":0.5197806,"top":0.7601756,"width":0.0048204786,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":";","depth":17,"bounds":{"left":0.52460104,"top":0.7601756,"width":0.0023271276,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Copy","depth":17,"bounds":{"left":0.60538566,"top":0.7529928,"width":0.011303191,"height":0.028332002},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"getLogPrefix()","depth":18,"bounds":{"left":0.36353058,"top":0.8044693,"width":0.033410903,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"is called twice. Trivial but unnecessary — capture the result in a variable first.","depth":17,"bounds":{"left":0.3984375,"top":0.8024741,"width":0.16655585,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"4.","depth":18,"bounds":{"left":0.3620346,"top":0.8603352,"width":0.0056515955,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"SyncObjects","depth":19,"bounds":{"left":0.36918217,"top":0.86233044,"width":0.026263298,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"command doesn't guard HubSpot when","depth":18,"bounds":{"left":0.39710772,"top":0.8603352,"width":0.09142287,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"{team}","depth":19,"bounds":{"left":0.49019283,"top":0.86233044,"width":0.014295213,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"argument is given —","depth":18,"bounds":{"left":0.50615025,"top":0.8603352,"width":0.047706116,"height":0.013567438},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"app/Console/Commands/Crm/SyncObjects.php:40-41","depth":19,"bounds":{"left":0.3620346,"top":0.86233044,"width":0.25299203,"height":0.028332002},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"if","depth":17,"bounds":{"left":0.36735374,"top":0.9185954,"width":0.004654255,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":17,"bounds":{"left":0.37200797,"top":0.9185954,"width":0.0048204786,"height":0.011572227},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"teamId","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":") {","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"teams","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"[] = Team::","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"idOrUuId","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"$","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"teamId","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":");","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"// no provider check","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Copy","depth":17,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Running","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"crm:sync-objects <hubspot-team-id>","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"dispatches a","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"SyncObjectsJob","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"for a HubSpot team, which now silently warns and returns. From an operator perspective this is confusing — the command appears to accept the team but does nothing. Worth adding a provider check and a console error message pointing to","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"crm:sync-hubspot-objects","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":".","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Design Notes","depth":16,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Design Notes","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Scheduler placement","depth":20,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":":","depth":19,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"crm:sync-hubspot-objects","depth":20,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"is placed inside","depth":19,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"scheduleEveryFiveMinutes()","depth":20,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"but uses a manual cron","depth":19,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"'1,6,11,16,21,26,31,36,41,46,51,56 * * * *'","depth":20,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"instead of","depth":19,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"->everyFiveMinutes()","depth":20,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":". The 1-minute offset is intentional (good thinking to stagger from the other jobs), but it's slightly inconsistent with the method's name. A comment explaining the offset would help future readers.","depth":19,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"SQS visibility timeout","depth":20,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":":","depth":19,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"SyncHubspotObjects","depth":20,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"uses 1 hour (","depth":19,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"60 * 60","depth":20,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":") vs","depth":19,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"SyncObjects","depth":20,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"'s 6 hours (","depth":19,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"60 * 60 * 6","depth":20,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"). Appropriate given the more frequent, presumably lighter runs.","depth":19,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Stagger delay","depth":20,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":": HubSpot uses 1s between teams vs 2s for general sync. Fine for 5-min runs, though worth monitoring if the number of HubSpot teams grows large enough that the last job barely fits within the 5-minute window.","depth":19,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Add or remove reactions","depth":15,"help_text":"","role_description":"summary","subrole":"AXSummary","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"@yalokin-jiminny","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"yalokin-jiminny","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"yalokin-jiminny","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"force-pushed","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"force-pushed","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"the","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"JY-20553-debug-crm-sync-delays","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"branch from","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"f6c0ec3","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"f6c0ec3","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"to","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"5928f60","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"5928f60","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Compare","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Compare","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"yesterday","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"yesterday","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"@yalokin-jiminny","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"yalokin-jiminny","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"yalokin-jiminny","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"force-pushed","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"force-pushed","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"the","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"JY-20701-reschedule-HubSpot-processing","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"branch from","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"3d7234a","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"3d7234a","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"to","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"1d10796","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"1d10796","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Compare","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Compare","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"yesterday","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"yesterday","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Base automatically changed from","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"JY-20553-debug-crm-sync-delays","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"to","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"master","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"19 hours ago","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"19 hours ago","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"@yalokin-jiminny","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"yalokin-jiminny","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"yalokin-jiminny","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"force-pushed","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"force-pushed","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"the","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"JY-20701-reschedule-HubSpot-processing","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"branch from","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"fec25f3","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"fec25f3","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"to","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"f0119c9","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"f0119c9","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Compare","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Compare","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"19 hours ago","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"19 hours ago","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"yalokin-jiminny","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"yalokin-jiminny","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"added","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"17","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"commits","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"15 hours ago","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"15 hours ago","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"@yalokin-jiminny","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-20701","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20701","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"| remove HubSpot from 30 min scheduler","depth":14,"help_text":"JY-20701 | remove HubSpot from 30 min scheduler","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"| remove HubSpot from 30 min scheduler","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"2f38f13","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"2f38f13","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"@yalokin-jiminny","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-20701","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20701","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"| Add SyncHubspotObjects Job","depth":14,"help_text":"JY-20701 | Add SyncHubspotObjects Job","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"| Add SyncHubspotObjects Job","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"50b0e20","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"50b0e20","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"@yalokin-jiminny","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-20701","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20701","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"| Add HubSpot sync objects scheduler each 5 min","depth":14,"help_text":"JY-20701 | Add HubSpot sync objects scheduler each 5 min","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"| Add HubSpot sync objects scheduler each 5 min","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"ea92c0f","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"ea92c0f","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"@yalokin-jiminny","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-20701","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20701","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"| extract duplicated code","depth":14,"help_text":"JY-20701 | extract duplicated code","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"| extract duplicated code","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"7ecdad3","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"7ecdad3","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"@yalokin-jiminny","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-20701","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20701","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"| cs","depth":14,"help_text":"JY-20701 | cs","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"| cs","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"525cbb2","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"525cbb2","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"@yalokin-jiminny","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-20701","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20701","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"| safe crm check","depth":14,"help_text":"JY-20701 | safe crm check","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"| safe crm check","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"35de0d5","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"35de0d5","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"@yalokin-jiminny","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-20701","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20701","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"| null on first-time sync","depth":14,"help_text":"JY-20701 | null on first-time sync","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"| null on first-time sync","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"ac1f89e","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"ac1f89e","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"@yalokin-jiminny","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-20701","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20701","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"| minor improvement","depth":14,"help_text":"JY-20701 | minor improvement","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"| minor improvement","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"bab377e","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"bab377e","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"@yalokin-jiminny","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-20701","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20701","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"| improve filter by team","depth":14,"help_text":"JY-20701 | improve filter by team","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"| improve filter by team","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"f39dc56","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"f39dc56","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"@yalokin-jiminny","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-20701","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20701","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"| add scheduler comment","depth":14,"help_text":"JY-20701 | add scheduler comment","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"| add scheduler comment","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"f2109d7","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"f2109d7","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"@yalokin-jiminny","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-20701","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20701","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"| improve delays","depth":14,"help_text":"JY-20701 | improve delays","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"| improve delays","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"f929670","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"f929670","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"@yalokin-jiminny","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-20701","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20701","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"| add tests","depth":14,"help_text":"JY-20701 | add tests","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"| add tests","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"9691864","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"9691864","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"@yalokin-jiminny","depth":12,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"JY-20701","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"JY-20701","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"| improve webhook delays","depth":14,"help_text":"JY-20701 | improve webhook delays","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"| improve webhook delays","depth":15,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
166638788734224853
|
8665476273024335177
|
visual_change
|
accessibility
|
NULL
|
Platform Sprint 2 Q2 - Platform Team - Scrum Board Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira
[SRD-6787] Issue with reconnecting Zoho - Jira
[SRD-6787] Issue with reconnecting Zoho - Jira
[SRD-6787] Issue with reconnecting Zoho - Jira
[SRD-6787] Issue with reconnecting Zoho - Jira
JY-20698 handle failed field sync on playbook import activity types by LakyLak · Pull Request #11988 · jiminny/app
JY-20698 handle failed field sync on playbook import activity types by LakyLak · Pull Request #11988 · jiminny/app
Jiminny MCP Connector - Product - Confluence
Jiminny MCP Connector - Product - Confluence
[JY-20676] Notify the user if a Panorama prompts is deleted but is used in AJ Report - Jira
[JY-20676] Notify the user if a Panorama prompts is deleted but is used in AJ Report - Jira
Jiminny Mail
Jiminny Mail
[JY-20500] Batch initial sync for Salesforce - Jira
[JY-20500] Batch initial sync for Salesforce - Jira
Feed — jiminny — Sentry
Feed — jiminny — Sentry
Jiminny
Jiminny
JY-20701 | Reschedule HubSpot Sync Objects by yalokin-jiminny · Pull Request #11989 · jiminny/app
JY-20701 | Reschedule HubSpot Sync Objects by yalokin-jiminny · Pull Request #11989 · jiminny/app
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Skip to content
Skip to content
Open menu
Homepage (g then d)
jiminny
jiminny
app
app
Search or jump to…
Type
/
to search
Chat with Copilot
Open Copilot…
Create new...
Issues(g then i)
Pull requests
Repositories
You have unread notifications(g then n)
Open user navigation menu
Repository navigation
Repository navigation
Code
Code
Pull requests (31)
Pull requests
(
31
)
Agents
Agents
Actions
Actions
Wiki
Wiki
Security and quality (21)
Security and quality
(
21
)
Insights
Insights
Settings
Settings
Important update
Important update
On April 24 we'll start using GitHub Copilot interaction data for AI model training unless you opt out.
Review this update
Review this update
and manage your preferences in your
GitHub account settings
GitHub account settings
.
Dismiss banner
Review requested
Review requested
yalokin-jiminny
yalokin-jiminny
requested your review on this pull request.
Add your review
Add your review
JY-20701 | Reschedule HubSpot Sync Objects #11989 Edit title
JY-20701 | Reschedule HubSpot Sync Objects
#
11989
Edit title
Awaiting approval
Awaiting approval
Code
Code
Open
yalokin-jiminny
yalokin-jiminny
wants to merge 22 commits into
master
master
from
JY-20701-reschedule-HubSpot-processing
JY-20701-reschedule-HubSpot-processing
Copy head branch name to clipboard
Lines changed: 949 additions & 97 deletions
Conversation (5)
Conversation
(
5
)
Commits (22)
Commits
(
22
)
Checks (3)
Checks
(
3
)
Files changed (11)
Files changed
(
11
)
Open
JY-20701 | Reschedule HubSpot Sync Objects #11989 yalokin-jiminny wants to merge 22 commits into master from JY-20701-reschedule-HubSpot-processing Copy head branch name to clipboard
JY-20701 | Reschedule HubSpot Sync Objects
JY-20701 | Reschedule HubSpot Sync Objects
#
11989
yalokin-jiminny
yalokin-jiminny
wants to merge 22 commits into
master
master
from
JY-20701-reschedule-HubSpot-processing
JY-20701-reschedule-HubSpot-processing
Copy head branch name to clipboard
Conversation
Conversation
@yalokin-jiminny
Show options
yalokin-jiminny commented 4 days ago •
yalokin-jiminny
yalokin-jiminny
commented
4 days ago
4 days ago
•
edited
edited
JIRA: JY-20701
JIRA:
JY-20701
JY-20701
Casus:
Casus:
We want more fluent curve of the jobs distribution (no spikes) in
crm-sync
queue
The more frequent HubSpot processing will help to have less auto-scaling / down-scaling events, thus reducing the jobs wait times
Changes:
Changes:
Remove HubSpot from SyncObjects
Create separate HubSpotSyncObjects that runs each 5 min instead of each 30
Extract common code
Improve processing Webhooks jobs distribution
Optimize ImportOpportunityBatch:
cache OpportunitySyncableFields, OwnerProfiles, RecordType
remove findContactByConfigurationAndId - Contact ID already exist
add timings log
Add or remove reactions
@yalokin-jiminny
Show options
Author
yalokin-jiminny commented 4 days ago
yalokin-jiminny
yalokin-jiminny
commented
4 days ago
4 days ago
@claude
@claude
Add or remove reactions
react with eyes
👀
1
@claude
Show options
claude bot commented 4 days ago •
claude
claude
bot
commented
4 days ago
4 days ago
•
edited
edited
Claude finished
@yalokin-jiminny
@yalokin-jiminny
's task in 1m 59s
——
View job
View job
Code Review
Code Review
Overall the approach is clean — extracting the shared logic into
SyncObjectsCommandTrait
is a good call, and the scheduling design (offset cron at
:01
to avoid spikes) makes sense. I found two bugs and a few minor points.
Bugs
Bugs
1. Null dereference on
$crmConfig
—
app/Jobs/Crm/SyncHubspotObjects.php:49-51
$
crmConfig
=
$
team
->
crm
;
if
(
$
crmConfig
->
provider
!== Configuration::
PROVIDER_HUBSPOT
) {
Copy
$team->crm
can be null if the team has no CRM configuration record. Accessing
->provider
on null will throw a fatal error. The existing
SyncObjects
job handles this by using
??
(
$crmConfig->provider ?? 'unknown'
). The new job needs a null guard here:
$
crmConfig
=
$
team
->
crm
;
if
(
$
crmConfig
===
null
||
$
crmConfig
->
provider
!== Configuration::
PROVIDER_HUBSPOT
) {
$
logger
->
warning
(
'
[SyncHubspotObjects] Team has no HubSpot CRM config
'
, [
'
team
'
=>
$
this
->
teamId
]);
return
;
}
Copy
Fix this →
Fix this →
2.
$lastSyncedAt
is nullable but
syncHubspotCrmObjects
requires
Carbon
—
app/Jobs/Crm/SyncHubspotObjects.php:85,88,116
$
lastSyncedAt
=
$
crmConfig
->
last_synced_at
;
// can be null on first run
.
.
.
$
this
->
syncHubspotCrmObjects
(
$
crmService
,
$
lastSyncedAt
);
// ...
private
function
syncHubspotCrmObjects(
HubspotInterface
$
crmService
,
Carbon
$
lastSyncedAt
):
void
Copy
With
declare(strict_types=1)
, passing
null
to a
Carbon
-typed parameter throws a
TypeError
. A team that has never synced before will crash on the first run. The parameter should be
?Carbon
(and
syncOpportunities
should handle null), or provide a fallback like
Carbon::createFromTimestamp(0)
.
Fix this →
Fix this →
Minor Issues
Minor Issues
3. Double call to
getLogPrefix()
—
app/Console/Commands/Crm/Traits/SyncObjectsCommandTrait.php:52
$
prefix
=
$
this
->
getLogPrefix
() ?
$
this
->
getLogPrefix
() .
'
'
:
''
;
Copy
getLogPrefix()
is called twice. Trivial but unnecessary — capture the result in a variable first.
4.
SyncObjects
command doesn't guard HubSpot when
{team}
argument is given —
app/Console/Commands/Crm/SyncObjects.php:40-41
if
(
$
teamId
) {
$
teams
[] = Team::
idOrUuId
(
$
teamId
);
// no provider check
Copy
Running
crm:sync-objects <hubspot-team-id>
dispatches a
SyncObjectsJob
for a HubSpot team, which now silently warns and returns. From an operator perspective this is confusing — the command appears to accept the team but does nothing. Worth adding a provider check and a console error message pointing to
crm:sync-hubspot-objects
.
Design Notes
Design Notes
Scheduler placement
:
crm:sync-hubspot-objects
is placed inside
scheduleEveryFiveMinutes()
but uses a manual cron
'1,6,11,16,21,26,31,36,41,46,51,56 * * * *'
instead of
->everyFiveMinutes()
. The 1-minute offset is intentional (good thinking to stagger from the other jobs), but it's slightly inconsistent with the method's name. A comment explaining the offset would help future readers.
SQS visibility timeout
:
SyncHubspotObjects
uses 1 hour (
60 * 60
) vs
SyncObjects
's 6 hours (
60 * 60 * 6
). Appropriate given the more frequent, presumably lighter runs.
Stagger delay
: HubSpot uses 1s between teams vs 2s for general sync. Fine for 5-min runs, though worth monitoring if the number of HubSpot teams grows large enough that the last job barely fits within the 5-minute window.
Add or remove reactions
@yalokin-jiminny
yalokin-jiminny
yalokin-jiminny
force-pushed
force-pushed
the
JY-20553-debug-crm-sync-delays
branch from
f6c0ec3
f6c0ec3
to
5928f60
5928f60
Compare
Compare
yesterday
yesterday
@yalokin-jiminny
yalokin-jiminny
yalokin-jiminny
force-pushed
force-pushed
the
JY-20701-reschedule-HubSpot-processing
branch from
3d7234a
3d7234a
to
1d10796
1d10796
Compare
Compare
yesterday
yesterday
Base automatically changed from
JY-20553-debug-crm-sync-delays
to
master
19 hours ago
19 hours ago
@yalokin-jiminny
yalokin-jiminny
yalokin-jiminny
force-pushed
force-pushed
the
JY-20701-reschedule-HubSpot-processing
branch from
fec25f3
fec25f3
to
f0119c9
f0119c9
Compare
Compare
19 hours ago
19 hours ago
yalokin-jiminny
yalokin-jiminny
added
17
commits
15 hours ago
15 hours ago
@yalokin-jiminny
JY-20701
JY-20701
| remove HubSpot from 30 min scheduler
| remove HubSpot from 30 min scheduler
2f38f13
2f38f13
@yalokin-jiminny
JY-20701
JY-20701
| Add SyncHubspotObjects Job
| Add SyncHubspotObjects Job
50b0e20
50b0e20
@yalokin-jiminny
JY-20701
JY-20701
| Add HubSpot sync objects scheduler each 5 min
| Add HubSpot sync objects scheduler each 5 min
ea92c0f
ea92c0f
@yalokin-jiminny
JY-20701
JY-20701
| extract duplicated code
| extract duplicated code
7ecdad3
7ecdad3
@yalokin-jiminny
JY-20701
JY-20701
| cs
| cs
525cbb2
525cbb2
@yalokin-jiminny
JY-20701
JY-20701
| safe crm check
| safe crm check
35de0d5
35de0d5
@yalokin-jiminny
JY-20701
JY-20701
| null on first-time sync
| null on first-time sync
ac1f89e
ac1f89e
@yalokin-jiminny
JY-20701
JY-20701
| minor improvement
| minor improvement
bab377e
bab377e
@yalokin-jiminny
JY-20701
JY-20701
| improve filter by team
| improve filter by team
f39dc56
f39dc56
@yalokin-jiminny
JY-20701
JY-20701
| add scheduler comment
| add scheduler comment
f2109d7
f2109d7
@yalokin-jiminny
JY-20701
JY-20701
| improve delays
| improve delays
f929670
f929670
@yalokin-jiminny
JY-20701
JY-20701
| add tests
| add tests
9691864
9691864
@yalokin-jiminny
JY-20701
JY-20701
| improve webhook delays
| improve webhook delays...
|
60921
|
|
41395
|
878
|
88
|
2026-04-17T06:12:38.223458+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-17/1776 /Users/lukas/.screenpipe/data/data/2026-04-17/1776406358223_m2.jpg...
|
Firefox
|
CloudWatch | us-east-2 — Work
|
True
|
us-east-2.console.aws.amazon.com/cloudwatch/home?r us-east-2.console.aws.amazon.com/cloudwatch/home?region=us-east-2#logsV2:logs-insights$3FqueryDetail$3D~(end~0~start~-3600~timeType~'RELATIVE~tz~'UTC~unit~'seconds~editorString~'fields*20*40timestamp*2c*20*40message*2c*20*40logStream*2c*20*40log*0a*7c*20filter*20*40message*20like*20*2fXXXXX*2f*20*0a*7c*20filter*20*40message*20not*20like*20*2fAnalytic*2f*20*7c*20filter*20*40message*20not*20like*20*2fTranscript*2f*0a*7c*20filter*20*40message*20not*20like*20*2fWebhook*2f*20*7c*20filter*20*40message*20not*20like*20*2fMeetingBot*2f*20*0a*7c*20limit*2010000~queryId~'0551e814-f51a-4339-8372-80d7ba4cef27~source~(~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-analytics~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-app~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-audio~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-calendar~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-conferences~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-crm-sync~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-default~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-delayed~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-dialers~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-dialers-fifo~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-download~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-emails~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-meeting-bot~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-nudges~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-processing-1~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-processing-2~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-processing-3~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-processing-4~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-processing-5~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-processing-delayed~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-softphone~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-video~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-video-app~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aphp~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aphp-app)~lang~'CWLI~logClass~'STANDARD~queryBy~'logGroupName)...
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Platform Sprint 2 Q2 - Platform Team - Scrum Board Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira
[SRD-6793] Les Mills activity types not pulling in - Jira
[SRD-6793] Les Mills activity types not pulling in - Jira
New Tab
New Tab
Symfony\Component\Debug\Exception\FatalThrowableError: League\Flysystem\Filesystem::has(): Argument #1 ($location) must be of type string, null given, called in /home/jiminny/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php on line
Symfony\Component\Debug\Exception\FatalThrowableError: League\Flysystem\Filesystem::has(): Argument #1 ($location) must be of type string, null given, called in /home/jiminny/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php on line
New Tab
New Tab
New Tab
New Tab
CloudWatch | us-east-2
CloudWatch | us-east-2
Close tab
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
Console Home | Console Home | eu-west-1
Console Home | Console Home | eu-west-1
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
AWS Console Home
Skip to Main Content
Skip to Main Content
Amazon Q
Services
Search
[Option+S]
CloudShell
Notifications (none available)
Help & support
Settings
United States (Ohio)
United States (Ohio)
PROD
PROD
EC2 EC2
EC2
Elastic Container Service Elastic Container Service
Elastic Container Service
S3 S3
S3
CodeDeploy CodeDeploy
CodeDeploy
CloudWatch CloudWatch
CloudWatch
ElastiCache ElastiCache
ElastiCache
Aurora and RDS Aurora and RDS
Aurora and RDS
Amazon OpenSearch Service Amazon OpenSearch Service
Amazon OpenSearch Service
CloudFront CloudFront
CloudFront
MediaLive MediaLive
MediaLive
Open navigation toggle
Close navigation toggle
CloudWatch
CloudWatch
CloudWatch
Favorites and recents
Favorites and recents
Ingestion
Ingestion
Dashboards
Dashboards
Alarms
Alarms
Number of alarms in alarm status 0
0
Number of alarms in OK status 0
0
Number of alarms with insufficient alarm data 0
0
AI Operations
AI Operations
GenAI Observability
GenAI Observability
Application Signals (APM)
Application Signals (APM)
Infrastructure Monitoring
Infrastructure Monitoring
Logs
Logs
Log Management
Log Management
Log Analytics
Log Analytics
Preview
Log Anomalies
Log Anomalies
Live Tail
Live Tail
Logs Insights
Logs Insights
Contributor Insights
Contributor Insights
Metrics
Metrics
Network Monitoring
Network Monitoring
Setup
Setup
Loading CloudWatch Logs...
CloudShell
CloudShell
Feedback
Feedback
©
2026
,
Amazon Web Services, Inc.
or its affiliates.
Privacy
Privacy
Terms
Terms
Cookie preferences...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira","depth":4,"bounds":{"left":0.0,"top":0.045138888,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira","depth":5,"bounds":{"left":0.015625,"top":0.05486111,"width":0.11875,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[SRD-6793] Les Mills activity types not pulling in - Jira","depth":4,"bounds":{"left":0.0,"top":0.07361111,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[SRD-6793] Les Mills activity types not pulling in - Jira","depth":5,"bounds":{"left":0.015625,"top":0.083333336,"width":0.11171875,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"New Tab","depth":4,"bounds":{"left":0.0,"top":0.10208333,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"New Tab","depth":5,"bounds":{"left":0.015625,"top":0.11180556,"width":0.017578125,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Symfony\\Component\\Debug\\Exception\\FatalThrowableError: League\\Flysystem\\Filesystem::has(): Argument #1 ($location) must be of type string, null given, called in /home/jiminny/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php on line","depth":4,"bounds":{"left":0.0,"top":0.13055556,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Symfony\\Component\\Debug\\Exception\\FatalThrowableError: League\\Flysystem\\Filesystem::has(): Argument #1 ($location) must be of type string, null given, called in /home/jiminny/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php on line","depth":5,"bounds":{"left":0.015625,"top":0.14027777,"width":0.53398436,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"New Tab","depth":4,"bounds":{"left":0.0,"top":0.15902779,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"New Tab","depth":5,"bounds":{"left":0.015625,"top":0.16875,"width":0.017578125,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"New Tab","depth":4,"bounds":{"left":0.0,"top":0.1875,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"New Tab","depth":5,"bounds":{"left":0.015625,"top":0.19722222,"width":0.017578125,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"CloudWatch | us-east-2","depth":4,"bounds":{"left":0.0,"top":0.21597221,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"CloudWatch | us-east-2","depth":5,"bounds":{"left":0.015625,"top":0.22569445,"width":0.0484375,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.07890625,"top":0.22222222,"width":0.009375,"height":0.016666668},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":4,"bounds":{"left":0.0,"top":0.24444444,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":5,"bounds":{"left":0.015625,"top":0.25416666,"width":0.1515625,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Console Home | Console Home | eu-west-1","depth":4,"bounds":{"left":0.0,"top":0.27291667,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Console Home | Console Home | eu-west-1","depth":5,"bounds":{"left":0.015625,"top":0.28263888,"width":0.0875,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"New Tab","depth":4,"bounds":{"left":0.003125,"top":0.30277777,"width":0.08710937,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.003125,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"bounds":{"left":0.01640625,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"bounds":{"left":0.029296875,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"bounds":{"left":0.0421875,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"bounds":{"left":0.05546875,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"AWS Console Home","depth":13,"bounds":{"left":0.09375,"top":0.047916666,"width":0.025390625,"height":0.033333335},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Skip to Main Content","depth":13,"bounds":{"left":0.09335937,"top":0.047222223,"width":0.0015625,"height":0.0013888889},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip to Main Content","depth":14,"bounds":{"left":0.09414063,"top":0.047916666,"width":0.01953125,"height":0.045138888},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Amazon Q","depth":14,"bounds":{"left":0.11953125,"top":0.047916666,"width":0.01953125,"height":0.033333335},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Services","depth":13,"bounds":{"left":0.1390625,"top":0.047916666,"width":0.01953125,"height":0.033333335},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXComboBox","text":"Search","depth":16,"bounds":{"left":0.15859374,"top":0.054166667,"width":0.2109375,"height":0.020833334},"role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"[Option+S]","depth":16,"bounds":{"left":0.33828124,"top":0.058333334,"width":0.02734375,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"CloudShell","depth":14,"bounds":{"left":0.83320314,"top":0.047916666,"width":0.01875,"height":0.033333335},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Notifications (none available)","depth":16,"bounds":{"left":0.85195315,"top":0.050694443,"width":0.01953125,"height":0.027777778},"help_text":"Notifications","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Help & support","depth":15,"bounds":{"left":0.8714844,"top":0.047916666,"width":0.01953125,"height":0.033333335},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Settings","depth":15,"bounds":{"left":0.89101565,"top":0.047916666,"width":0.01953125,"height":0.033333335},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXComboBox","text":"United States (Ohio)","depth":15,"bounds":{"left":0.9105469,"top":0.047916666,"width":0.06328125,"height":0.033333335},"value":"United States (Ohio)","help_text":"United States (Ohio)","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"United States (Ohio)","depth":17,"bounds":{"left":0.9171875,"top":0.059722222,"width":0.04375,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"PROD","depth":15,"bounds":{"left":0.97382814,"top":0.047916666,"width":0.026171863,"height":0.033333335},"help_text":"Production_View_Only @ jiminny","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"PROD","depth":18,"bounds":{"left":0.97929686,"top":0.065972224,"width":0.0125,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"EC2 EC2","depth":16,"bounds":{"left":0.096875,"top":0.083333336,"width":0.023828125,"height":0.019444445},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"EC2","depth":18,"bounds":{"left":0.109375,"top":0.088194445,"width":0.008203125,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Elastic Container Service Elastic Container Service","depth":16,"bounds":{"left":0.12070312,"top":0.083333336,"width":0.06757812,"height":0.019444445},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Elastic Container Service","depth":18,"bounds":{"left":0.13320312,"top":0.088194445,"width":0.051953126,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"S3 S3","depth":16,"bounds":{"left":0.18828125,"top":0.083333336,"width":0.02109375,"height":0.019444445},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"S3","depth":18,"bounds":{"left":0.20078126,"top":0.088194445,"width":0.00546875,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"CodeDeploy CodeDeploy","depth":16,"bounds":{"left":0.209375,"top":0.083333336,"width":0.04140625,"height":0.019444445},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"CodeDeploy","depth":18,"bounds":{"left":0.221875,"top":0.088194445,"width":0.02578125,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"CloudWatch CloudWatch","depth":16,"bounds":{"left":0.25078124,"top":0.083333336,"width":0.04140625,"height":0.019444445},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"CloudWatch","depth":18,"bounds":{"left":0.26328126,"top":0.088194445,"width":0.02578125,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"ElastiCache ElastiCache","depth":16,"bounds":{"left":0.2921875,"top":0.083333336,"width":0.03984375,"height":0.019444445},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"ElastiCache","depth":18,"bounds":{"left":0.3046875,"top":0.088194445,"width":0.02421875,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Aurora and RDS Aurora and RDS","depth":16,"bounds":{"left":0.33203125,"top":0.083333336,"width":0.048828125,"height":0.019444445},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Aurora and RDS","depth":18,"bounds":{"left":0.34453124,"top":0.088194445,"width":0.033203125,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Amazon OpenSearch Service Amazon OpenSearch Service","depth":16,"bounds":{"left":0.38085938,"top":0.083333336,"width":0.07421875,"height":0.019444445},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Amazon OpenSearch Service","depth":18,"bounds":{"left":0.39335936,"top":0.088194445,"width":0.0609375,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"CloudFront CloudFront","depth":16,"bounds":{"left":0.45507812,"top":0.083333336,"width":0.039453126,"height":0.019444445},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"CloudFront","depth":18,"bounds":{"left":0.4675781,"top":0.088194445,"width":0.023828125,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"MediaLive MediaLive","depth":16,"bounds":{"left":0.49453124,"top":0.083333336,"width":0.037109375,"height":0.019444445},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"MediaLive","depth":18,"bounds":{"left":0.50703126,"top":0.088194445,"width":0.021484375,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Open navigation toggle","depth":12,"bounds":{"left":0.1,"top":0.108333334,"width":0.01171875,"height":0.020833334},"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":true},{"role":"AXButton","text":"Close navigation toggle","depth":13,"bounds":{"left":0.17617187,"top":0.14305556,"width":0.0109375,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"CloudWatch","depth":12,"bounds":{"left":0.095703125,"top":0.13680555,"width":0.095703125,"height":0.033333335},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXLink","text":"CloudWatch","depth":13,"bounds":{"left":0.103515625,"top":0.14444445,"width":0.044921875,"height":0.01875},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"CloudWatch","depth":14,"bounds":{"left":0.10429688,"top":0.14513889,"width":0.043359376,"height":0.017361112},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Favorites and recents","depth":15,"bounds":{"left":0.10546875,"top":0.18125,"width":0.076171875,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Favorites and recents","depth":17,"bounds":{"left":0.10546875,"top":0.18194444,"width":0.05234375,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Ingestion","depth":16,"bounds":{"left":0.10546875,"top":0.21319444,"width":0.023828125,"height":0.013888889},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Ingestion","depth":17,"bounds":{"left":0.10625,"top":0.21388888,"width":0.023046875,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Dashboards","depth":16,"bounds":{"left":0.10546875,"top":0.23402777,"width":0.030078124,"height":0.013888889},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Dashboards","depth":17,"bounds":{"left":0.10625,"top":0.23472223,"width":0.029296875,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Alarms","depth":16,"bounds":{"left":0.10546875,"top":0.25486112,"width":0.01796875,"height":0.013888889},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Alarms","depth":17,"bounds":{"left":0.10625,"top":0.25555557,"width":0.0171875,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Number of alarms in alarm status 0","depth":17,"bounds":{"left":0.1265625,"top":0.25486112,"width":0.012109375,"height":0.013888889},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"0","depth":20,"bounds":{"left":0.13515624,"top":0.2576389,"width":0.002734375,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Number of alarms in OK status 0","depth":17,"bounds":{"left":0.14023438,"top":0.25486112,"width":0.01171875,"height":0.013888889},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"0","depth":20,"bounds":{"left":0.14882812,"top":0.2576389,"width":0.00234375,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Number of alarms with insufficient alarm data 0","depth":17,"bounds":{"left":0.15351562,"top":0.25486112,"width":0.012109375,"height":0.013888889},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"0","depth":20,"bounds":{"left":0.16210938,"top":0.2576389,"width":0.002734375,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"AI Operations","depth":16,"bounds":{"left":0.09882812,"top":0.27986112,"width":0.00625,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AI Operations","depth":16,"bounds":{"left":0.10703125,"top":0.27986112,"width":0.04296875,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"GenAI Observability","depth":16,"bounds":{"left":0.09882812,"top":0.30416667,"width":0.00625,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"GenAI Observability","depth":16,"bounds":{"left":0.10703125,"top":0.30416667,"width":0.06171875,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Application Signals (APM)","depth":16,"bounds":{"left":0.09882812,"top":0.32847223,"width":0.00625,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Application Signals (APM)","depth":16,"bounds":{"left":0.10703125,"top":0.32847223,"width":0.07851563,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Infrastructure Monitoring","depth":16,"bounds":{"left":0.09882812,"top":0.35277778,"width":0.00625,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Infrastructure Monitoring","depth":16,"bounds":{"left":0.10703125,"top":0.35277778,"width":0.07734375,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Logs","depth":16,"bounds":{"left":0.09882812,"top":0.37708333,"width":0.00625,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":true},{"role":"AXButton","text":"Logs","depth":16,"bounds":{"left":0.10703125,"top":0.37708333,"width":0.01640625,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Log Management","depth":19,"bounds":{"left":0.10546875,"top":0.39791667,"width":0.044140626,"height":0.013888889},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Log Management","depth":20,"bounds":{"left":0.10625,"top":0.3986111,"width":0.043359376,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Log Analytics","depth":19,"bounds":{"left":0.10546875,"top":0.41875,"width":0.033984374,"height":0.013888889},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Log Analytics","depth":20,"bounds":{"left":0.10625,"top":0.41944444,"width":0.033203125,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Preview","depth":20,"bounds":{"left":0.14570312,"top":0.42083332,"width":0.016796876,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Log Anomalies","depth":19,"bounds":{"left":0.10546875,"top":0.44027779,"width":0.037109375,"height":0.013888889},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Log Anomalies","depth":20,"bounds":{"left":0.10625,"top":0.4409722,"width":0.036328126,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Live Tail","depth":19,"bounds":{"left":0.10546875,"top":0.4611111,"width":0.020703126,"height":0.013888889},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Live Tail","depth":20,"bounds":{"left":0.10625,"top":0.46180555,"width":0.019921875,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Logs Insights","depth":19,"bounds":{"left":0.10546875,"top":0.48194444,"width":0.034375,"height":0.013888889},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Logs Insights","depth":20,"bounds":{"left":0.10625,"top":0.4826389,"width":0.03359375,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Contributor Insights","depth":19,"bounds":{"left":0.10546875,"top":0.50277776,"width":0.050390624,"height":0.013888889},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Contributor Insights","depth":20,"bounds":{"left":0.10625,"top":0.5034722,"width":0.049609374,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Metrics","depth":16,"bounds":{"left":0.09882812,"top":0.53402776,"width":0.00625,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Metrics","depth":16,"bounds":{"left":0.10703125,"top":0.53402776,"width":0.02421875,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Network Monitoring","depth":16,"bounds":{"left":0.09882812,"top":0.55833334,"width":0.00625,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Network Monitoring","depth":16,"bounds":{"left":0.10703125,"top":0.55833334,"width":0.062109374,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Setup","depth":16,"bounds":{"left":0.09882812,"top":0.59305555,"width":0.00625,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Setup","depth":16,"bounds":{"left":0.10703125,"top":0.59305555,"width":0.019921875,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"","depth":21,"bounds":{"left":0.5890625,"top":0.52847224,"width":0.015625,"height":0.027777778},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Loading CloudWatch Logs...","depth":21,"bounds":{"left":0.5726563,"top":0.55972224,"width":0.048828125,"height":0.007638889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"CloudShell","depth":12,"bounds":{"left":0.1,"top":0.98125,"width":0.03125,"height":0.013888889},"help_text":"Open CloudShell","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"CloudShell","depth":14,"bounds":{"left":0.10820313,"top":0.98333335,"width":0.023046875,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Feedback","depth":11,"bounds":{"left":0.14101562,"top":0.98333335,"width":0.019921875,"height":0.009722223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Feedback","depth":13,"bounds":{"left":0.14101562,"top":0.98333335,"width":0.019921875,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"©","depth":12,"bounds":{"left":0.784375,"top":0.98333335,"width":0.0046875,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026","depth":12,"bounds":{"left":0.7890625,"top":0.98333335,"width":0.0109375,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":",","depth":12,"bounds":{"left":0.8,"top":0.98333335,"width":0.00234375,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Amazon Web Services, Inc.","depth":12,"bounds":{"left":0.8023437,"top":0.98333335,"width":0.05625,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"or its affiliates.","depth":12,"bounds":{"left":0.85976565,"top":0.98333335,"width":0.031640626,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Privacy","depth":13,"bounds":{"left":0.903125,"top":0.9826389,"width":0.016796876,"height":0.011805556},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Privacy","depth":14,"bounds":{"left":0.9039062,"top":0.98333335,"width":0.015234375,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Terms","depth":13,"bounds":{"left":0.9296875,"top":0.9826389,"width":0.014453125,"height":0.011805556},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Terms","depth":14,"bounds":{"left":0.93046874,"top":0.98333335,"width":0.012890625,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Cookie preferences","depth":13,"bounds":{"left":0.95390624,"top":0.98333335,"width":0.040234376,"height":0.009722223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false}]...
|
-4820072597390485777
|
8663989471626392291
|
visual_change
|
accessibility
|
NULL
|
Platform Sprint 2 Q2 - Platform Team - Scrum Board Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira
[SRD-6793] Les Mills activity types not pulling in - Jira
[SRD-6793] Les Mills activity types not pulling in - Jira
New Tab
New Tab
Symfony\Component\Debug\Exception\FatalThrowableError: League\Flysystem\Filesystem::has(): Argument #1 ($location) must be of type string, null given, called in /home/jiminny/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php on line
Symfony\Component\Debug\Exception\FatalThrowableError: League\Flysystem\Filesystem::has(): Argument #1 ($location) must be of type string, null given, called in /home/jiminny/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php on line
New Tab
New Tab
New Tab
New Tab
CloudWatch | us-east-2
CloudWatch | us-east-2
Close tab
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
Console Home | Console Home | eu-west-1
Console Home | Console Home | eu-west-1
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
AWS Console Home
Skip to Main Content
Skip to Main Content
Amazon Q
Services
Search
[Option+S]
CloudShell
Notifications (none available)
Help & support
Settings
United States (Ohio)
United States (Ohio)
PROD
PROD
EC2 EC2
EC2
Elastic Container Service Elastic Container Service
Elastic Container Service
S3 S3
S3
CodeDeploy CodeDeploy
CodeDeploy
CloudWatch CloudWatch
CloudWatch
ElastiCache ElastiCache
ElastiCache
Aurora and RDS Aurora and RDS
Aurora and RDS
Amazon OpenSearch Service Amazon OpenSearch Service
Amazon OpenSearch Service
CloudFront CloudFront
CloudFront
MediaLive MediaLive
MediaLive
Open navigation toggle
Close navigation toggle
CloudWatch
CloudWatch
CloudWatch
Favorites and recents
Favorites and recents
Ingestion
Ingestion
Dashboards
Dashboards
Alarms
Alarms
Number of alarms in alarm status 0
0
Number of alarms in OK status 0
0
Number of alarms with insufficient alarm data 0
0
AI Operations
AI Operations
GenAI Observability
GenAI Observability
Application Signals (APM)
Application Signals (APM)
Infrastructure Monitoring
Infrastructure Monitoring
Logs
Logs
Log Management
Log Management
Log Analytics
Log Analytics
Preview
Log Anomalies
Log Anomalies
Live Tail
Live Tail
Logs Insights
Logs Insights
Contributor Insights
Contributor Insights
Metrics
Metrics
Network Monitoring
Network Monitoring
Setup
Setup
Loading CloudWatch Logs...
CloudShell
CloudShell
Feedback
Feedback
©
2026
,
Amazon Web Services, Inc.
or its affiliates.
Privacy
Privacy
Terms
Terms
Cookie preferences...
|
41394
|
|
41393
|
NULL
|
0
|
2026-04-17T06:12:32.419031+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-17/1776 /Users/lukas/.screenpipe/data/data/2026-04-17/1776406352419_m1.jpg...
|
Firefox
|
CloudWatch | us-east-2 — Work
|
True
|
us-east-2.console.aws.amazon.com/cloudwatch/home?r us-east-2.console.aws.amazon.com/cloudwatch/home?region=us-east-2#logsV2:logs-insights$3FqueryDetail$3D~(end~0~start~-3600~timeType~'RELATIVE~tz~'UTC~unit~'seconds~editorString~'fields*20*40timestamp*2c*20*40message*2c*20*40logStream*2c*20*40log*0a*7c*20filter*20*40message*20like*20*2fXXXXX*2f*20*0a*7c*20filter*20*40message*20not*20like*20*2fAnalytic*2f*20*7c*20filter*20*40message*20not*20like*20*2fTranscript*2f*0a*7c*20filter*20*40message*20not*20like*20*2fWebhook*2f*20*7c*20filter*20*40message*20not*20like*20*2fMeetingBot*2f*20*0a*7c*20limit*2010000~queryId~'0551e814-f51a-4339-8372-80d7ba4cef27~source~(~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-analytics~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-app~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-audio~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-calendar~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-conferences~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-crm-sync~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-default~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-delayed~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-dialers~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-dialers-fifo~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-download~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-emails~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-meeting-bot~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-nudges~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-processing-1~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-processing-2~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-processing-3~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-processing-4~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-processing-5~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-processing-delayed~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-softphone~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-video~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aworker-video-app~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aphp~'arn*3aaws*3alogs*3aus-east-2*3a410346195943*3alog-group*3aphp-app)~lang~'CWLI~logClass~'STANDARD~queryBy~'logGroupName)...
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Platform Sprint 2 Q2 - Platform Team - Scrum Board Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira
[SRD-6793] Les Mills activity types not pulling in - Jira
[SRD-6793] Les Mills activity types not pulling in - Jira
New Tab
New Tab
Symfony\Component\Debug\Exception\FatalThrowableError: League\Flysystem\Filesystem::has(): Argument #1 ($location) must be of type string, null given, called in /home/jiminny/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php on line
Symfony\Component\Debug\Exception\FatalThrowableError: League\Flysystem\Filesystem::has(): Argument #1 ($location) must be of type string, null given, called in /home/jiminny/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php on line
New Tab
New Tab
New Tab
New Tab
CloudWatch | us-east-2
CloudWatch | us-east-2
Close tab
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
Console Home | Console Home | eu-west-1
Console Home | Console Home | eu-west-1
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
AWS Console Home
Skip to Main Content
Skip to Main Content
Amazon Q
Services
Search
Ask Amazon Q
[Option+S]
CloudShell
Notifications (none available)
Help & support
Settings
United States (Ohio)
United States (Ohio)
[EMAIL] @ jmny
Account ID: 4387-4037-0364
[EMAIL]
Account ID
Copy Account Id
4387-4037-0364
Account name
Access denied
Access denied
Account color
Access denied
Access denied
Account alias
Copy account alias
jmny
IAM user
Copy Username
[EMAIL]
Role history
Press Enter key to switch to this role
STAGE
Turn on multi-session support
Turn on multi-session support
Switch role
Switch role
Sign out
Sign out
EC2 EC2
EC2
Elastic Container Service Elastic Container Service
Elastic Container Service
S3 S3
S3
CodeDeploy CodeDeploy
CodeDeploy
CloudWatch CloudWatch
CloudWatch
ElastiCache ElastiCache
ElastiCache
Aurora and RDS Aurora and RDS
Aurora and RDS
Amazon OpenSearch Service Amazon OpenSearch Service
Amazon OpenSearch Service
CloudFront CloudFront
CloudFront
MediaLive MediaLive
MediaLive
Open side navigation
CloudWatch
CloudWatch
Logs Insights
Logs Insights
Query definition
Query definition
Info : Query definition
5m (5 Minutes)
30m (30 Minutes)
1h (1 Hour)
3h (3 Hours)
12h (12 Hours)
Custom
Custom
Compare (Off)
Compare
(
Off
)
Time zone UTC timezone
UTC timezone
Start tailing with selected log group (opens in a new tab)
Start tailing
Query scope
Query scope Log group name
Log group name
Select up to 50 log groups
Browse
:
Log Groups
|
Facets
|
Lookup tables
Undo
Redo
Logs Insights QL
Query generator
Query generator
Fields
Saved and sample queries
Query commands
Run query
Cancel
Save
History
Logs (-)
Logs
(
-
)
Patterns (-)
Patterns
(
-
)
Visualization
Visualization
Logs (-)
Logs (-)
Summarize results
Summarize results
Investigate
Investigate...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[SRD-6793] Les Mills activity types not pulling in - Jira","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[SRD-6793] Les Mills activity types not pulling in - Jira","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"New Tab","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"New Tab","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Symfony\\Component\\Debug\\Exception\\FatalThrowableError: League\\Flysystem\\Filesystem::has(): Argument #1 ($location) must be of type string, null given, called in /home/jiminny/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php on line","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Symfony\\Component\\Debug\\Exception\\FatalThrowableError: League\\Flysystem\\Filesystem::has(): Argument #1 ($location) must be of type string, null given, called in /home/jiminny/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php on line","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"New Tab","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"New Tab","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"New Tab","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"New Tab","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"CloudWatch | us-east-2","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"CloudWatch | us-east-2","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Console Home | Console Home | eu-west-1","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Console Home | Console Home | eu-west-1","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"New Tab","depth":4,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"AWS Console Home","depth":13,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Skip to Main Content","depth":13,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip to Main Content","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Amazon Q","depth":14,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Services","depth":13,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXComboBox","text":"Search","depth":16,"role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Ask Amazon Q","depth":15,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[Option+S]","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"CloudShell","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Notifications (none available)","depth":16,"help_text":"Notifications","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Help & support","depth":15,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Settings","depth":15,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXComboBox","text":"United States (Ohio)","depth":15,"value":"United States (Ohio)","help_text":"United States (Ohio)","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"United States (Ohio)","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"lukas.kovalik@jiminny.com @ jmny","depth":15,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":true},{"role":"AXStaticText","text":"Account ID: 4387-4037-0364","depth":19,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"lukas.kovalik@jiminny.com","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Account ID","depth":19,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Copy Account Id","depth":20,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"4387-4037-0364","depth":19,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Account name","depth":19,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Access denied","depth":20,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Access denied","depth":22,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Account color","depth":19,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Access denied","depth":20,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Access denied","depth":22,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Account alias","depth":19,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Copy account alias","depth":20,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"jmny","depth":19,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"IAM user","depth":20,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Copy Username","depth":21,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"lukas.kovalik@jiminny.com","depth":20,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Role history","depth":20,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Press Enter key to switch to this role","depth":19,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"STAGE","depth":21,"help_text":"Staging_View_Only @ jmny","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Turn on multi-session support","depth":19,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Turn on multi-session support","depth":20,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Switch role","depth":18,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Switch role","depth":19,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Sign out","depth":18,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Sign out","depth":19,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"EC2 EC2","depth":16,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"EC2","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Elastic Container Service Elastic Container Service","depth":16,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Elastic Container Service","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"S3 S3","depth":16,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"S3","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"CodeDeploy CodeDeploy","depth":16,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"CodeDeploy","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"CloudWatch CloudWatch","depth":16,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"CloudWatch","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"ElastiCache ElastiCache","depth":16,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"ElastiCache","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Aurora and RDS Aurora and RDS","depth":16,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Aurora and RDS","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Amazon OpenSearch Service Amazon OpenSearch Service","depth":16,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Amazon OpenSearch Service","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"CloudFront CloudFront","depth":16,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"CloudFront","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"MediaLive MediaLive","depth":16,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"MediaLive","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Open side navigation","depth":13,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"CloudWatch","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"CloudWatch","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Logs Insights","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Logs Insights","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Query definition","depth":26,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXButton","text":"Query definition","depth":28,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":true},{"role":"AXButton","text":"Info : Query definition","depth":27,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"5m (5 Minutes)","depth":27,"help_text":"5 Minutes","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"30m (30 Minutes)","depth":27,"help_text":"30 Minutes","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"1h (1 Hour)","depth":27,"help_text":"1 Hour","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"3h (3 Hours)","depth":27,"help_text":"3 Hours","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"12h (12 Hours)","depth":27,"help_text":"12 Hours","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Custom","depth":27,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Custom","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Compare (Off)","depth":26,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Compare","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Off","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Time zone UTC timezone","depth":26,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"UTC timezone","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Start tailing with selected log group (opens in a new tab)","depth":26,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Start tailing","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Query scope","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Query scope Log group name","depth":27,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Log group name","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Select up to 50 log groups","depth":28,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Browse","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":":","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Log Groups","depth":27,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"|","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Facets","depth":27,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"|","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Lookup tables","depth":27,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Undo","depth":28,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Redo","depth":28,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXMenuButton","text":"Logs Insights QL","depth":29,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Query generator","depth":26,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Query generator","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Fields","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Saved and sample queries","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Query commands","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Run query","depth":27,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Cancel","depth":27,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Save","depth":27,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"History","depth":27,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Logs (-)","depth":25,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Logs","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Patterns (-)","depth":25,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Patterns","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Visualization","depth":25,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Visualization","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Logs (-)","depth":26,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Logs (-)","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Summarize results","depth":26,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Summarize results","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Investigate","depth":28,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Investigate","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
-5796181168865592184
|
8663867667266646710
|
click
|
accessibility
|
NULL
|
Platform Sprint 2 Q2 - Platform Team - Scrum Board Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira
[SRD-6793] Les Mills activity types not pulling in - Jira
[SRD-6793] Les Mills activity types not pulling in - Jira
New Tab
New Tab
Symfony\Component\Debug\Exception\FatalThrowableError: League\Flysystem\Filesystem::has(): Argument #1 ($location) must be of type string, null given, called in /home/jiminny/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php on line
Symfony\Component\Debug\Exception\FatalThrowableError: League\Flysystem\Filesystem::has(): Argument #1 ($location) must be of type string, null given, called in /home/jiminny/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php on line
New Tab
New Tab
New Tab
New Tab
CloudWatch | us-east-2
CloudWatch | us-east-2
Close tab
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
Console Home | Console Home | eu-west-1
Console Home | Console Home | eu-west-1
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
AWS Console Home
Skip to Main Content
Skip to Main Content
Amazon Q
Services
Search
Ask Amazon Q
[Option+S]
CloudShell
Notifications (none available)
Help & support
Settings
United States (Ohio)
United States (Ohio)
[EMAIL] @ jmny
Account ID: 4387-4037-0364
[EMAIL]
Account ID
Copy Account Id
4387-4037-0364
Account name
Access denied
Access denied
Account color
Access denied
Access denied
Account alias
Copy account alias
jmny
IAM user
Copy Username
[EMAIL]
Role history
Press Enter key to switch to this role
STAGE
Turn on multi-session support
Turn on multi-session support
Switch role
Switch role
Sign out
Sign out
EC2 EC2
EC2
Elastic Container Service Elastic Container Service
Elastic Container Service
S3 S3
S3
CodeDeploy CodeDeploy
CodeDeploy
CloudWatch CloudWatch
CloudWatch
ElastiCache ElastiCache
ElastiCache
Aurora and RDS Aurora and RDS
Aurora and RDS
Amazon OpenSearch Service Amazon OpenSearch Service
Amazon OpenSearch Service
CloudFront CloudFront
CloudFront
MediaLive MediaLive
MediaLive
Open side navigation
CloudWatch
CloudWatch
Logs Insights
Logs Insights
Query definition
Query definition
Info : Query definition
5m (5 Minutes)
30m (30 Minutes)
1h (1 Hour)
3h (3 Hours)
12h (12 Hours)
Custom
Custom
Compare (Off)
Compare
(
Off
)
Time zone UTC timezone
UTC timezone
Start tailing with selected log group (opens in a new tab)
Start tailing
Query scope
Query scope Log group name
Log group name
Select up to 50 log groups
Browse
:
Log Groups
|
Facets
|
Lookup tables
Undo
Redo
Logs Insights QL
Query generator
Query generator
Fields
Saved and sample queries
Query commands
Run query
Cancel
Save
History
Logs (-)
Logs
(
-
)
Patterns (-)
Patterns
(
-
)
Visualization
Visualization
Logs (-)
Logs (-)
Summarize results
Summarize results
Investigate
Investigate...
|
NULL
|
|
41634
|
883
|
28
|
2026-04-17T06:19:17.104075+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-17/1776 /Users/lukas/.screenpipe/data/data/2026-04-17/1776406757104_m2.jpg...
|
Firefox
|
CloudWatch | us-east-2 — Work
|
True
|
us-east-2.console.aws.amazon.com/cloudwatch/home?r us-east-2.console.aws.amazon.com/cloudwatch/home?region=us-east-2#logsV2:logs-insights$3FqueryDetail$3D~(end~0~start~-86400~timeType~'RELATIVE~tz~'UTC~unit~'seconds~editorString~'fields*20*40timestamp*2c*20*40message*2c*20*40logStream*2c*20*40log*0a*7c*20filter*20*40message*20like*20*2f822fa41b-afd3-43a9-a248-86b0e36f3131*2f*20*0a*7c*20filter*20*40message*20not*20like*20*2fAnalytic*2f*20*7c*20filter*20*40message*20not*20like*20*2fTranscript*2f*0a*7c*20filter*20*40message*20not*20like*20*2fWebhook*2f*20*7c*20filter*20*40message*20not*20like*20*2fMeetingBot*2f*20*0a*7c*20limit*2010000~queryId~'0551e814-f51a-4339-8372-80d7ba4cef27~source~(~'worker~'worker-analytics~'worker-app~'worker-audio~'worker-calendar~'worker-conferences~'worker-crm-sync~'worker-default~'worker-delayed~'worker-dialers~'worker-dialers-fifo~'worker-download~'worker-emails~'worker-meeting-bot~'worker-nudges~'worker-processing-1~'worker-processing-2~'worker-processing-3~'worker-processing-4~'worker-processing-5~'worker-processing-delayed~'worker-softphone~'worker-video~'worker-video-app~'php~'php-app)~lang~'CWLI~logClass~'STANDARD~queryBy~'logGroupName)...
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Platform Sprint 2 Q2 - Platform Team - Scrum Board Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira
[SRD-6793] Les Mills activity types not pulling in - Jira
[SRD-6793] Les Mills activity types not pulling in - Jira
New Tab
New Tab
Symfony\Component\Debug\Exception\FatalThrowableError: League\Flysystem\Filesystem::has(): Argument #1 ($location) must be of type string, null given, called in /home/jiminny/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php on line
Symfony\Component\Debug\Exception\FatalThrowableError: League\Flysystem\Filesystem::has(): Argument #1 ($location) must be of type string, null given, called in /home/jiminny/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php on line
CloudWatch | us-east-2
CloudWatch | us-east-2
Close tab
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
Console Home | Console Home | eu-west-1
Console Home | Console Home | eu-west-1
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
AWS Console Home
Skip to Main Content
Skip to Main Content
Amazon Q
Services
Search
Ask Amazon Q
[Option+S]
CloudShell
Notifications (none available)
Help & support
Settings
United States (Ohio)
United States (Ohio)
PROD
Account ID: 4103-4619-5943
PROD
EC2 EC2
EC2
Elastic Container Service Elastic Container Service
Elastic Container Service
S3 S3
S3
CodeDeploy CodeDeploy
CodeDeploy
CloudWatch CloudWatch
CloudWatch
ElastiCache ElastiCache
ElastiCache
Aurora and RDS Aurora and RDS
Aurora and RDS
Amazon OpenSearch Service Amazon OpenSearch Service
Amazon OpenSearch Service
CloudFront CloudFront
CloudFront
MediaLive MediaLive
MediaLive
Open side navigation
CloudWatch
CloudWatch
Logs Insights
Logs Insights
Query definition
Query definition
Info : Query definition
5m (5 Minutes)
30m (30 Minutes)
1h (1 Hour)
3h (3 Hours)
12h (12 Hours)
Custom (1d)
Custom (1d)
Compare (Off)
Compare
(
Off
)
Time zone UTC timezone
UTC timezone
Start tailing with selected log group (opens in a new tab)
Start tailing
Query scope
Query scope Log group name
Log group name
Select up to 50 log groups
Show more chosen log groups
Show more chosen log groups (+25)
Browse
:
Log Groups
|
Facets
|
Lookup tables
Undo
Redo
Logs Insights QL
Query generator
Query generator
Fields
Saved and sample queries
Query commands
Run query
Cancel
Save
History
Completed. Query executed for
26 log groups.
View log groups used in query
Logs (72)
Logs
(
72
)
Patterns (3)
Patterns
(
3
)
Visualization
Visualization
Logs (72)
Logs (72)
Summarize results
Summarize results
Investigate
Investigate
Share results
Share results
Export results
Export results
Add to dashboard
Showing 72 of 72 records matched
54,170,353 records (14.6 GB) scanned in 22.8s @ 2,372,874 records/s (656.9 MB/s)
Hide histogram
Hide histogram
Filter table results
2026-04-17T06:00:26.815Z
[2026-04-17 06:00:26] production.INFO: [Send Report] Processing report {"uuid":"822fa41b-afd3-43a9-a248-86b0e36f3131","status":"Generated"} {"correlation_id":"a39e85ea-5b74-4ac9-87a8-3a109b8fc433","trace_id":"a98d108b-c9a5-43d9-9d18-a76ccb82e5cc"}
worker-analytics/worker-analytics/fb554dc84d6140c2ad7f217bbc19b409 Opens in a new tab
410346195943:worker-analytics
2026-04-17T06:00:26.645Z
[2026-04-17 06:00:26] production.INFO: [Send Report] Processing report {"uuid":"822fa41b-afd3-43a9-a248-86b0e36f3131","status":"Generated"} {"correlation_id":"fdd3bd52-79a8-4a9a-92ea-5b9fc93fbbb2","trace_id":"a98d108b-c9a5-43d9-9d18-a76ccb82e5cc"}
worker-analytics/worker-analytics/722d81a3183d415ab2c8817c87c12a84 Opens in a new tab
410346195943:worker-analytics
2026-04-17T06:00:25.529Z
[2026-04-17 06:00:25] production.INFO: [automated-reports:send] Dispatching job {"uuid":"822fa41b-afd3-43a9-a248-86b0e36f3131"} {"correlation_id":"ea906b5c-3794-43f3-99c4-e337d437b9fc","trace_id":"a98d108b-c9a5-43d9-9d18-a76ccb82e5cc"}
worker-delayed/worker-delayed/d15dd27b01dd40468ea5aae74e7af42b Opens in a new tab
410346195943:worker-delayed
2026-04-17T05:00:20.286Z
[2026-04-17 05:00:20] production.INFO: [Send Report] Processing report {"uuid":"822fa41b-afd3-43a9-a248-86b0e36f3131","status":"Generated"} {"correlation_id":"b56f7e75-ece7-4a35-9177-1c5ebe1648aa","trace_id":"eb295dc8-469d-4e35-914f-19c174098db4"}
worker-analytics/worker-analytics/5cb754a0f75b4d7ca64762d6af1da207 Opens in a new tab
410346195943:worker-analytics
2026-04-17T05:00:20.093Z
[2026-04-17 05:00:20] production.INFO: [Send Report] Processing report {"uuid":"822fa41b-afd3-43a9-a248-86b0e36f3131","status":"Generated"} {"correlation_id":"bd05f3ce-b48b-4c4b-b529-4012294eb058","trace_id":"eb295dc8-469d-4e35-914f-19c174098db4"}
worker-analytics/worker-analytics/fb554dc84d6140c2ad7f217bbc19b409 Opens in a new tab
410346195943:worker-analytics
2026-04-17T05:00:18.321Z
[2026-04-17 05:00:18] production.INFO: [automated-reports:send] Dispatching job {"uuid":"822fa41b-afd3-43a9-a248-86b0e36f3131"} {"correlation_id":"1077f9be-7b8c-4e6a-b8dd-27c4ad0c044e","trace_id":"eb295dc8-469d-4e35-914f-19c174098db4"}
worker-delayed/worker-delayed/d15dd27b01dd40468ea5aae74e7af42b Opens in a new tab
410346195943:worker-delayed
2026-04-17T04:02:35.334Z
[2026-04-17 04:02:35] production.INFO: [Send Report] Processing report {"uuid":"822fa41b-afd3-43a9-a248-86b0e36f3131","status":"Generated"} {"correlation_id":"599e1a79-9081-4e88-af32-113cf4503a84","trace_id":"0e885db3-433d-401f-896b-3f9c8f5d2150"}
worker-analytics/worker-analytics/fb554dc84d6140c2ad7f217bbc19b409 Opens in a new tab
410346195943:worker-analytics
2026-04-17T04:02:34.808Z
[2026-04-17 04:02:34] production.INFO: [Send Report] Processing report {"uuid":"822fa41b-afd3-43a9-a248-86b0e36f3131","status":"Generated"} {"correlation_id":"a254993f-5930-4858-92b2-2e00bcfdac15","trace_id":"0e885db3-433d-401f-896b-3f9c8f5d2150"}
worker-analytics/worker-analytics/722d81a3183d415ab2c8817c87c12a84 Opens in a new tab
410346195943:worker-analytics
2026-04-17T04:00:23.302Z
[2026-04-17 04:00:23] production.INFO: [automated-reports:send] Dispatching job {"uuid":"822fa41b-afd3-43a9-a248-86b0e36f3131"} {"correlation_id":"840ff441-d597-4786-8a8d-86c41b2e618f","trace_id":"0e885db3-433d-401f-896b-3f9c8f5d2150"}
worker-conferences/worker-conferences/a7d2827044c3432aacb481432e962e9b Opens in a new tab
410346195943:worker-conferences
2026-04-17T03:00:20.945Z
[2026-04-17 03:00:20] production.INFO: [Send Report] Processing report {"uuid":"822fa41b-afd3-43a9-a248-86b0e36f3131","status":"Generated"} {"correlation_id":"2ca7bc5b-e6b5-46f4-8f58-92b02fb02478","trace_id":"72180b42-468f-429a-a297-0c6447e7b094"}
worker-analytics/worker-analytics/722d81a3183d415ab2c8817c87c12a84 Opens in a new tab
410346195943:worker-analytics
2026-04-17T03:00:19.411Z
[2026-04-17 03:00:19] production.INFO: [Send Report] Processing report {"uuid":"822fa41b-afd3-43a9-a248-86b0e36f3131","status":"Generated"} {"correlation_id":"53fa262c-2873-423e-94e2-6fd306b6a6d8","trace_id":"72180b42-468f-429a-a297-0c6447e7b094"}
worker-analytics/worker-analytics/fb554dc84d6140c2ad7f217bbc19b409 Opens in a new tab
410346195943:worker-analytics...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira","depth":4,"bounds":{"left":0.0,"top":0.045138888,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira","depth":5,"bounds":{"left":0.015625,"top":0.05486111,"width":0.11875,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[SRD-6793] Les Mills activity types not pulling in - Jira","depth":4,"bounds":{"left":0.0,"top":0.07361111,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[SRD-6793] Les Mills activity types not pulling in - Jira","depth":5,"bounds":{"left":0.015625,"top":0.083333336,"width":0.11171875,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"New Tab","depth":4,"bounds":{"left":0.0,"top":0.10208333,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"New Tab","depth":5,"bounds":{"left":0.015625,"top":0.11180556,"width":0.017578125,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Symfony\\Component\\Debug\\Exception\\FatalThrowableError: League\\Flysystem\\Filesystem::has(): Argument #1 ($location) must be of type string, null given, called in /home/jiminny/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php on line","depth":4,"bounds":{"left":0.0,"top":0.13055556,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Symfony\\Component\\Debug\\Exception\\FatalThrowableError: League\\Flysystem\\Filesystem::has(): Argument #1 ($location) must be of type string, null given, called in /home/jiminny/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php on line","depth":5,"bounds":{"left":0.015625,"top":0.14027777,"width":0.53398436,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"CloudWatch | us-east-2","depth":4,"bounds":{"left":0.0,"top":0.15902779,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"CloudWatch | us-east-2","depth":5,"bounds":{"left":0.015625,"top":0.16875,"width":0.0484375,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.07890625,"top":0.16527778,"width":0.009375,"height":0.016666668},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":4,"bounds":{"left":0.0,"top":0.1875,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":5,"bounds":{"left":0.015625,"top":0.19722222,"width":0.1515625,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Console Home | Console Home | eu-west-1","depth":4,"bounds":{"left":0.0,"top":0.21597221,"width":0.09375,"height":0.028472222},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Console Home | Console Home | eu-west-1","depth":5,"bounds":{"left":0.015625,"top":0.22569445,"width":0.0875,"height":0.009722223},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"New Tab","depth":4,"bounds":{"left":0.003125,"top":0.24583334,"width":0.08710937,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.003125,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"bounds":{"left":0.01640625,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"bounds":{"left":0.029296875,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"bounds":{"left":0.0421875,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"bounds":{"left":0.05546875,"top":0.97430557,"width":0.0125,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"AWS Console Home","depth":13,"bounds":{"left":0.09375,"top":0.047916666,"width":0.025390625,"height":0.033333335},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Skip to Main Content","depth":13,"bounds":{"left":0.09335937,"top":0.047222223,"width":0.0015625,"height":0.0013888889},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip to Main Content","depth":14,"bounds":{"left":0.09414063,"top":0.047916666,"width":0.01953125,"height":0.045138888},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Amazon Q","depth":14,"bounds":{"left":0.11953125,"top":0.047916666,"width":0.01953125,"height":0.033333335},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Services","depth":13,"bounds":{"left":0.1390625,"top":0.047916666,"width":0.01953125,"height":0.033333335},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXComboBox","text":"Search","depth":16,"bounds":{"left":0.15859374,"top":0.054166667,"width":0.2109375,"height":0.020833334},"role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Ask Amazon Q","depth":15,"bounds":{"left":0.35390624,"top":0.05625,"width":0.01171875,"height":0.016666668},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[Option+S]","depth":16,"bounds":{"left":0.32851562,"top":0.058333334,"width":0.02734375,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"CloudShell","depth":14,"bounds":{"left":0.78046876,"top":0.047916666,"width":0.01875,"height":0.033333335},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Notifications (none available)","depth":16,"bounds":{"left":0.7992188,"top":0.050694443,"width":0.01953125,"height":0.027777778},"help_text":"Notifications","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Help & support","depth":15,"bounds":{"left":0.81875,"top":0.047916666,"width":0.01953125,"height":0.033333335},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Settings","depth":15,"bounds":{"left":0.8382813,"top":0.047916666,"width":0.01953125,"height":0.033333335},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXComboBox","text":"United States (Ohio)","depth":15,"bounds":{"left":0.8578125,"top":0.047916666,"width":0.06328125,"height":0.033333335},"value":"United States (Ohio)","help_text":"United States (Ohio)","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"United States (Ohio)","depth":17,"bounds":{"left":0.86445314,"top":0.059722222,"width":0.04375,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"PROD","depth":15,"bounds":{"left":0.92109376,"top":0.047916666,"width":0.07890624,"height":0.033333335},"help_text":"Production_View_Only @ jiminny","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Account ID: 4103-4619-5943","depth":19,"bounds":{"left":0.92460936,"top":0.05,"width":0.06367187,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"PROD","depth":18,"bounds":{"left":0.97929686,"top":0.065972224,"width":0.0125,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"EC2 EC2","depth":16,"bounds":{"left":0.096875,"top":0.083333336,"width":0.023828125,"height":0.019444445},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"EC2","depth":18,"bounds":{"left":0.109375,"top":0.088194445,"width":0.008203125,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Elastic Container Service Elastic Container Service","depth":16,"bounds":{"left":0.12070312,"top":0.083333336,"width":0.06757812,"height":0.019444445},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Elastic Container Service","depth":18,"bounds":{"left":0.13320312,"top":0.088194445,"width":0.051953126,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"S3 S3","depth":16,"bounds":{"left":0.18828125,"top":0.083333336,"width":0.02109375,"height":0.019444445},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"S3","depth":18,"bounds":{"left":0.20078126,"top":0.088194445,"width":0.00546875,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"CodeDeploy CodeDeploy","depth":16,"bounds":{"left":0.209375,"top":0.083333336,"width":0.04140625,"height":0.019444445},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"CodeDeploy","depth":18,"bounds":{"left":0.221875,"top":0.088194445,"width":0.02578125,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"CloudWatch CloudWatch","depth":16,"bounds":{"left":0.25078124,"top":0.083333336,"width":0.04140625,"height":0.019444445},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"CloudWatch","depth":18,"bounds":{"left":0.26328126,"top":0.088194445,"width":0.02578125,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"ElastiCache ElastiCache","depth":16,"bounds":{"left":0.2921875,"top":0.083333336,"width":0.03984375,"height":0.019444445},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"ElastiCache","depth":18,"bounds":{"left":0.3046875,"top":0.088194445,"width":0.02421875,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Aurora and RDS Aurora and RDS","depth":16,"bounds":{"left":0.33203125,"top":0.083333336,"width":0.048828125,"height":0.019444445},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Aurora and RDS","depth":18,"bounds":{"left":0.34453124,"top":0.088194445,"width":0.033203125,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Amazon OpenSearch Service Amazon OpenSearch Service","depth":16,"bounds":{"left":0.38085938,"top":0.083333336,"width":0.07421875,"height":0.019444445},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Amazon OpenSearch Service","depth":18,"bounds":{"left":0.39335936,"top":0.088194445,"width":0.0609375,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"CloudFront CloudFront","depth":16,"bounds":{"left":0.45507812,"top":0.083333336,"width":0.039453126,"height":0.019444445},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"CloudFront","depth":18,"bounds":{"left":0.4675781,"top":0.088194445,"width":0.023828125,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"MediaLive MediaLive","depth":16,"bounds":{"left":0.49453124,"top":0.083333336,"width":0.037109375,"height":0.019444445},"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"MediaLive","depth":18,"bounds":{"left":0.50703126,"top":0.088194445,"width":0.021484375,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Open side navigation","depth":13,"bounds":{"left":0.1,"top":0.108333334,"width":0.01171875,"height":0.020833334},"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"CloudWatch","depth":14,"bounds":{"left":0.11640625,"top":0.11111111,"width":0.031640626,"height":0.015277778},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"CloudWatch","depth":16,"bounds":{"left":0.1171875,"top":0.1125,"width":0.030078124,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Logs Insights","depth":14,"bounds":{"left":0.16054687,"top":0.11180556,"width":0.03359375,"height":0.013888889},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Logs Insights","depth":16,"bounds":{"left":0.16054687,"top":0.1125,"width":0.03359375,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Query definition","depth":26,"bounds":{"left":0.1125,"top":0.14513889,"width":0.059375,"height":0.017361112},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXButton","text":"Query definition","depth":28,"bounds":{"left":0.10234375,"top":0.14513889,"width":0.06953125,"height":0.017361112},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":true},{"role":"AXButton","text":"Info : Query definition","depth":27,"bounds":{"left":0.175,"top":0.15069444,"width":0.008984375,"height":0.010416667},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"5m (5 Minutes)","depth":27,"bounds":{"left":0.6574219,"top":0.14652778,"width":0.014453125,"height":0.013888889},"help_text":"5 Minutes","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"30m (30 Minutes)","depth":27,"bounds":{"left":0.67890626,"top":0.14652778,"width":0.0171875,"height":0.013888889},"help_text":"30 Minutes","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"1h (1 Hour)","depth":27,"bounds":{"left":0.703125,"top":0.14652778,"width":0.012890625,"height":0.013888889},"help_text":"1 Hour","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"3h (3 Hours)","depth":27,"bounds":{"left":0.72265625,"top":0.14652778,"width":0.012890625,"height":0.013888889},"help_text":"3 Hours","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"12h (12 Hours)","depth":27,"bounds":{"left":0.7421875,"top":0.14652778,"width":0.016015625,"height":0.013888889},"help_text":"12 Hours","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Custom (1d)","depth":27,"bounds":{"left":0.76523435,"top":0.14652778,"width":0.041015625,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Custom (1d)","depth":29,"bounds":{"left":0.76523435,"top":0.14722222,"width":0.031640626,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Compare (Off)","depth":26,"bounds":{"left":0.8125,"top":0.14305556,"width":0.055078126,"height":0.022222223},"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Compare","depth":27,"bounds":{"left":0.82109374,"top":0.14791666,"width":0.0234375,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":27,"bounds":{"left":0.84453124,"top":0.14791666,"width":0.003515625,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Off","depth":27,"bounds":{"left":0.8480469,"top":0.14791666,"width":0.008984375,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":27,"bounds":{"left":0.8570312,"top":0.14791666,"width":0.001953125,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Time zone UTC timezone","depth":26,"bounds":{"left":0.8703125,"top":0.14305556,"width":0.054296874,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"UTC timezone","depth":28,"bounds":{"left":0.87539065,"top":0.14791666,"width":0.034765624,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Start tailing with selected log group (opens in a new tab)","depth":26,"bounds":{"left":0.92929685,"top":0.14305556,"width":0.056640625,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Start tailing","depth":27,"bounds":{"left":0.94570315,"top":0.14791666,"width":0.031640626,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Query scope","depth":28,"bounds":{"left":0.10234375,"top":0.18402778,"width":0.03203125,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Query scope Log group name","depth":27,"bounds":{"left":0.10234375,"top":0.20416667,"width":0.078125,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Log group name","depth":29,"bounds":{"left":0.107421875,"top":0.20902778,"width":0.041015625,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Select up to 50 log groups","depth":28,"bounds":{"left":0.1875,"top":0.20416667,"width":0.67148435,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Show more chosen log groups","depth":27,"bounds":{"left":0.18710938,"top":0.27083334,"width":0.09882812,"height":0.016666668},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Show more chosen log groups (+25)","depth":29,"bounds":{"left":0.19570312,"top":0.27291667,"width":0.08945312,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Browse","depth":28,"bounds":{"left":0.8636719,"top":0.20763889,"width":0.01796875,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":":","depth":28,"bounds":{"left":0.8816406,"top":0.20763889,"width":0.0015625,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Log Groups","depth":27,"bounds":{"left":0.8863281,"top":0.20763889,"width":0.0296875,"height":0.0125},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"|","depth":27,"bounds":{"left":0.91914064,"top":0.20763889,"width":0.001171875,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Facets","depth":27,"bounds":{"left":0.9234375,"top":0.20763889,"width":0.01640625,"height":0.0125},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"|","depth":27,"bounds":{"left":0.9429687,"top":0.20763889,"width":0.0015625,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Lookup tables","depth":27,"bounds":{"left":0.9476563,"top":0.20763889,"width":0.036328126,"height":0.0125},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Undo","depth":28,"bounds":{"left":0.9316406,"top":0.40555555,"width":0.0109375,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Redo","depth":28,"bounds":{"left":0.94570315,"top":0.40555555,"width":0.0109375,"height":0.013888889},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXMenuButton","text":"Logs Insights QL","depth":29,"bounds":{"left":0.10898437,"top":0.43472221,"width":0.06796875,"height":0.022222223},"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Query generator","depth":26,"bounds":{"left":0.18007812,"top":0.43194443,"width":0.06171875,"height":0.028472222},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Query generator","depth":28,"bounds":{"left":0.19414063,"top":0.43888888,"width":0.04296875,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Fields","depth":28,"bounds":{"left":0.25429687,"top":0.43888888,"width":0.01484375,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Saved and sample queries","depth":28,"bounds":{"left":0.28632814,"top":0.43888888,"width":0.06640625,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Query commands","depth":28,"bounds":{"left":0.36992186,"top":0.43888888,"width":0.0453125,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Run query","depth":27,"bounds":{"left":0.10234375,"top":0.46944445,"width":0.044140626,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Cancel","depth":27,"bounds":{"left":0.14960937,"top":0.46944445,"width":0.034375,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Save","depth":27,"bounds":{"left":0.18710938,"top":0.46944445,"width":0.02890625,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"History","depth":27,"bounds":{"left":0.29140624,"top":0.46944445,"width":0.036328126,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Completed. Query executed for","depth":28,"bounds":{"left":0.11015625,"top":0.49791667,"width":0.07773437,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"26 log groups.","depth":28,"bounds":{"left":0.18945312,"top":0.49791667,"width":0.035546876,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"View log groups used in query","depth":28,"bounds":{"left":0.2265625,"top":0.49791667,"width":0.00625,"height":0.0125},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Logs (72)","depth":25,"bounds":{"left":0.09765625,"top":0.52916664,"width":0.03671875,"height":0.030555556},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Logs","depth":27,"bounds":{"left":0.10234375,"top":0.5375,"width":0.013671875,"height":0.013888889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":27,"bounds":{"left":0.11757813,"top":0.5375,"width":0.00234375,"height":0.013888889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"72","depth":27,"bounds":{"left":0.11992188,"top":0.5375,"width":0.007421875,"height":0.013888889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":27,"bounds":{"left":0.12734374,"top":0.5375,"width":0.001953125,"height":0.013888889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Patterns (3)","depth":25,"bounds":{"left":0.14101562,"top":0.52916664,"width":0.04453125,"height":0.030555556},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Patterns","depth":27,"bounds":{"left":0.14570312,"top":0.5375,"width":0.025,"height":0.013888889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":27,"bounds":{"left":0.17070313,"top":0.5375,"width":0.00390625,"height":0.013888889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"3","depth":27,"bounds":{"left":0.17460938,"top":0.5375,"width":0.003515625,"height":0.013888889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":27,"bounds":{"left":0.178125,"top":0.5375,"width":0.00234375,"height":0.013888889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Visualization","depth":25,"bounds":{"left":0.1921875,"top":0.52916664,"width":0.04765625,"height":0.030555556},"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Visualization","depth":27,"bounds":{"left":0.196875,"top":0.5375,"width":0.037890624,"height":0.013888889},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Logs (72)","depth":26,"bounds":{"left":0.10195313,"top":0.56805557,"width":0.0328125,"height":0.017361112},"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Logs (72)","depth":27,"bounds":{"left":0.10195313,"top":0.56805557,"width":0.0328125,"height":0.017361112},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Summarize results","depth":26,"bounds":{"left":0.59648436,"top":0.56458336,"width":0.07304688,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Summarize results","depth":27,"bounds":{"left":0.6128906,"top":0.5694444,"width":0.048046876,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Investigate","depth":28,"bounds":{"left":0.67265624,"top":0.56458336,"width":0.062109374,"height":0.022222223},"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Investigate","depth":29,"bounds":{"left":0.6898438,"top":0.5694444,"width":0.028515626,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Share results","depth":26,"bounds":{"left":0.7378906,"top":0.56458336,"width":0.05859375,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Share results","depth":27,"bounds":{"left":0.7542969,"top":0.5694444,"width":0.03359375,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Export results","depth":28,"bounds":{"left":0.79960936,"top":0.56458336,"width":0.061328124,"height":0.022222223},"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Export results","depth":29,"bounds":{"left":0.8082031,"top":0.5694444,"width":0.036328126,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Add to dashboard","depth":26,"bounds":{"left":0.8640625,"top":0.56458336,"width":0.06367187,"height":0.022222223},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Showing 72 of 72 records matched","depth":29,"bounds":{"left":0.47851562,"top":0.59930557,"width":0.09492187,"height":0.014583333},"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"54,170,353 records (14.6 GB) scanned in 22.8s @ 2,372,874 records/s (656.9 MB/s)","depth":29,"bounds":{"left":0.4230469,"top":0.6145833,"width":0.20546874,"height":0.0125},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Hide histogram","depth":26,"bounds":{"left":0.95351565,"top":0.59791666,"width":0.03671875,"height":0.029861111},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Hide histogram","depth":27,"bounds":{"left":0.95351565,"top":0.59930557,"width":0.0328125,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"Filter table results","depth":25,"bounds":{"left":0.09882812,"top":0.70208335,"width":0.253125,"height":0.022222223},"help_text":"","placeholder":"Filter table results (case insensitive)...","role_description":"search text field","subrole":"AXSearchField","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"2026-04-17T06:00:26.815Z","depth":29,"bounds":{"left":0.11796875,"top":0.76875,"width":0.0671875,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"[2026-04-17 06:00:26] production.INFO: [Send Report] Processing report {\"uuid\":\"822fa41b-afd3-43a9-a248-86b0e36f3131\",\"status\":\"Generated\"} {\"correlation_id\":\"a39e85ea-5b74-4ac9-87a8-3a109b8fc433\",\"trace_id\":\"a98d108b-c9a5-43d9-9d18-a76ccb82e5cc\"}","depth":29,"bounds":{"left":0.19414063,"top":0.76875,"width":0.69453126,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"worker-analytics/worker-analytics/fb554dc84d6140c2ad7f217bbc19b409 Opens in a new tab","depth":29,"bounds":{"left":0.53828126,"top":0.76875,"width":0.16640624,"height":0.010416667},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"410346195943:worker-analytics","depth":29,"bounds":{"left":0.7242187,"top":0.76875,"width":0.08164062,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-04-17T06:00:26.645Z","depth":29,"bounds":{"left":0.11796875,"top":0.7875,"width":0.0671875,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"[2026-04-17 06:00:26] production.INFO: [Send Report] Processing report {\"uuid\":\"822fa41b-afd3-43a9-a248-86b0e36f3131\",\"status\":\"Generated\"} {\"correlation_id\":\"fdd3bd52-79a8-4a9a-92ea-5b9fc93fbbb2\",\"trace_id\":\"a98d108b-c9a5-43d9-9d18-a76ccb82e5cc\"}","depth":29,"bounds":{"left":0.19414063,"top":0.7875,"width":0.69453126,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"worker-analytics/worker-analytics/722d81a3183d415ab2c8817c87c12a84 Opens in a new tab","depth":29,"bounds":{"left":0.53828126,"top":0.7875,"width":0.16757813,"height":0.010416667},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"410346195943:worker-analytics","depth":29,"bounds":{"left":0.7242187,"top":0.7875,"width":0.08164062,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-04-17T06:00:25.529Z","depth":29,"bounds":{"left":0.11796875,"top":0.80625,"width":0.0671875,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"[2026-04-17 06:00:25] production.INFO: [automated-reports:send] Dispatching job {\"uuid\":\"822fa41b-afd3-43a9-a248-86b0e36f3131\"} {\"correlation_id\":\"ea906b5c-3794-43f3-99c4-e337d437b9fc\",\"trace_id\":\"a98d108b-c9a5-43d9-9d18-a76ccb82e5cc\"}","depth":29,"bounds":{"left":0.19414063,"top":0.80625,"width":0.6609375,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"worker-delayed/worker-delayed/d15dd27b01dd40468ea5aae74e7af42b Opens in a new tab","depth":29,"bounds":{"left":0.53828126,"top":0.80625,"width":0.16289063,"height":0.010416667},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"410346195943:worker-delayed","depth":29,"bounds":{"left":0.7242187,"top":0.80625,"width":0.07578125,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-04-17T05:00:20.286Z","depth":29,"bounds":{"left":0.11796875,"top":0.825,"width":0.0671875,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"[2026-04-17 05:00:20] production.INFO: [Send Report] Processing report {\"uuid\":\"822fa41b-afd3-43a9-a248-86b0e36f3131\",\"status\":\"Generated\"} {\"correlation_id\":\"b56f7e75-ece7-4a35-9177-1c5ebe1648aa\",\"trace_id\":\"eb295dc8-469d-4e35-914f-19c174098db4\"}","depth":29,"bounds":{"left":0.19414063,"top":0.825,"width":0.69453126,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"worker-analytics/worker-analytics/5cb754a0f75b4d7ca64762d6af1da207 Opens in a new tab","depth":29,"bounds":{"left":0.53828126,"top":0.825,"width":0.16601562,"height":0.010416667},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"410346195943:worker-analytics","depth":29,"bounds":{"left":0.7242187,"top":0.825,"width":0.08164062,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-04-17T05:00:20.093Z","depth":29,"bounds":{"left":0.11796875,"top":0.84375,"width":0.0671875,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"[2026-04-17 05:00:20] production.INFO: [Send Report] Processing report {\"uuid\":\"822fa41b-afd3-43a9-a248-86b0e36f3131\",\"status\":\"Generated\"} {\"correlation_id\":\"bd05f3ce-b48b-4c4b-b529-4012294eb058\",\"trace_id\":\"eb295dc8-469d-4e35-914f-19c174098db4\"}","depth":29,"bounds":{"left":0.19414063,"top":0.84375,"width":0.69453126,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"worker-analytics/worker-analytics/fb554dc84d6140c2ad7f217bbc19b409 Opens in a new tab","depth":29,"bounds":{"left":0.53828126,"top":0.84375,"width":0.16640624,"height":0.010416667},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"410346195943:worker-analytics","depth":29,"bounds":{"left":0.7242187,"top":0.84375,"width":0.08164062,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-04-17T05:00:18.321Z","depth":29,"bounds":{"left":0.11796875,"top":0.8625,"width":0.0671875,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"[2026-04-17 05:00:18] production.INFO: [automated-reports:send] Dispatching job {\"uuid\":\"822fa41b-afd3-43a9-a248-86b0e36f3131\"} {\"correlation_id\":\"1077f9be-7b8c-4e6a-b8dd-27c4ad0c044e\",\"trace_id\":\"eb295dc8-469d-4e35-914f-19c174098db4\"}","depth":29,"bounds":{"left":0.19414063,"top":0.8625,"width":0.6609375,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"worker-delayed/worker-delayed/d15dd27b01dd40468ea5aae74e7af42b Opens in a new tab","depth":29,"bounds":{"left":0.53828126,"top":0.8625,"width":0.16289063,"height":0.010416667},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"410346195943:worker-delayed","depth":29,"bounds":{"left":0.7242187,"top":0.8625,"width":0.07578125,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-04-17T04:02:35.334Z","depth":29,"bounds":{"left":0.11796875,"top":0.88125,"width":0.0671875,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"[2026-04-17 04:02:35] production.INFO: [Send Report] Processing report {\"uuid\":\"822fa41b-afd3-43a9-a248-86b0e36f3131\",\"status\":\"Generated\"} {\"correlation_id\":\"599e1a79-9081-4e88-af32-113cf4503a84\",\"trace_id\":\"0e885db3-433d-401f-896b-3f9c8f5d2150\"}","depth":29,"bounds":{"left":0.19414063,"top":0.88125,"width":0.69453126,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"worker-analytics/worker-analytics/fb554dc84d6140c2ad7f217bbc19b409 Opens in a new tab","depth":29,"bounds":{"left":0.53828126,"top":0.88125,"width":0.16640624,"height":0.010416667},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"410346195943:worker-analytics","depth":29,"bounds":{"left":0.7242187,"top":0.88125,"width":0.08164062,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-04-17T04:02:34.808Z","depth":29,"bounds":{"left":0.11796875,"top":0.9,"width":0.0671875,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"[2026-04-17 04:02:34] production.INFO: [Send Report] Processing report {\"uuid\":\"822fa41b-afd3-43a9-a248-86b0e36f3131\",\"status\":\"Generated\"} {\"correlation_id\":\"a254993f-5930-4858-92b2-2e00bcfdac15\",\"trace_id\":\"0e885db3-433d-401f-896b-3f9c8f5d2150\"}","depth":29,"bounds":{"left":0.19414063,"top":0.9,"width":0.69453126,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"worker-analytics/worker-analytics/722d81a3183d415ab2c8817c87c12a84 Opens in a new tab","depth":29,"bounds":{"left":0.53828126,"top":0.9,"width":0.16757813,"height":0.010416667},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"410346195943:worker-analytics","depth":29,"bounds":{"left":0.7242187,"top":0.9,"width":0.08164062,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-04-17T04:00:23.302Z","depth":29,"bounds":{"left":0.11796875,"top":0.91875,"width":0.0671875,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"[2026-04-17 04:00:23] production.INFO: [automated-reports:send] Dispatching job {\"uuid\":\"822fa41b-afd3-43a9-a248-86b0e36f3131\"} {\"correlation_id\":\"840ff441-d597-4786-8a8d-86c41b2e618f\",\"trace_id\":\"0e885db3-433d-401f-896b-3f9c8f5d2150\"}","depth":29,"bounds":{"left":0.19414063,"top":0.91875,"width":0.6609375,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"worker-conferences/worker-conferences/a7d2827044c3432aacb481432e962e9b Opens in a new tab","depth":29,"bounds":{"left":0.53828126,"top":0.91875,"width":0.18085937,"height":0.010416667},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"410346195943:worker-conferences","depth":29,"bounds":{"left":0.7242187,"top":0.91875,"width":0.08710937,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-04-17T03:00:20.945Z","depth":29,"bounds":{"left":0.11796875,"top":0.9375,"width":0.0671875,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"[2026-04-17 03:00:20] production.INFO: [Send Report] Processing report {\"uuid\":\"822fa41b-afd3-43a9-a248-86b0e36f3131\",\"status\":\"Generated\"} {\"correlation_id\":\"2ca7bc5b-e6b5-46f4-8f58-92b02fb02478\",\"trace_id\":\"72180b42-468f-429a-a297-0c6447e7b094\"}","depth":29,"bounds":{"left":0.19414063,"top":0.9375,"width":0.69453126,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"worker-analytics/worker-analytics/722d81a3183d415ab2c8817c87c12a84 Opens in a new tab","depth":29,"bounds":{"left":0.53828126,"top":0.9375,"width":0.16757813,"height":0.010416667},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"410346195943:worker-analytics","depth":29,"bounds":{"left":0.7242187,"top":0.9375,"width":0.08164062,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"2026-04-17T03:00:19.411Z","depth":29,"bounds":{"left":0.11796875,"top":0.95625,"width":0.0671875,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"[2026-04-17 03:00:19] production.INFO: [Send Report] Processing report {\"uuid\":\"822fa41b-afd3-43a9-a248-86b0e36f3131\",\"status\":\"Generated\"} {\"correlation_id\":\"53fa262c-2873-423e-94e2-6fd306b6a6d8\",\"trace_id\":\"72180b42-468f-429a-a297-0c6447e7b094\"}","depth":29,"bounds":{"left":0.19414063,"top":0.95625,"width":0.69453126,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"worker-analytics/worker-analytics/fb554dc84d6140c2ad7f217bbc19b409 Opens in a new tab","depth":29,"bounds":{"left":0.53828126,"top":0.95625,"width":0.16640624,"height":0.010416667},"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"410346195943:worker-analytics","depth":29,"bounds":{"left":0.7242187,"top":0.95625,"width":0.08164062,"height":0.010416667},"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
383922504863920752
|
8659699556859755444
|
visual_change
|
accessibility
|
NULL
|
Platform Sprint 2 Q2 - Platform Team - Scrum Board Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira
[SRD-6793] Les Mills activity types not pulling in - Jira
[SRD-6793] Les Mills activity types not pulling in - Jira
New Tab
New Tab
Symfony\Component\Debug\Exception\FatalThrowableError: League\Flysystem\Filesystem::has(): Argument #1 ($location) must be of type string, null given, called in /home/jiminny/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php on line
Symfony\Component\Debug\Exception\FatalThrowableError: League\Flysystem\Filesystem::has(): Argument #1 ($location) must be of type string, null given, called in /home/jiminny/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php on line
CloudWatch | us-east-2
CloudWatch | us-east-2
Close tab
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
Console Home | Console Home | eu-west-1
Console Home | Console Home | eu-west-1
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
AWS Console Home
Skip to Main Content
Skip to Main Content
Amazon Q
Services
Search
Ask Amazon Q
[Option+S]
CloudShell
Notifications (none available)
Help & support
Settings
United States (Ohio)
United States (Ohio)
PROD
Account ID: 4103-4619-5943
PROD
EC2 EC2
EC2
Elastic Container Service Elastic Container Service
Elastic Container Service
S3 S3
S3
CodeDeploy CodeDeploy
CodeDeploy
CloudWatch CloudWatch
CloudWatch
ElastiCache ElastiCache
ElastiCache
Aurora and RDS Aurora and RDS
Aurora and RDS
Amazon OpenSearch Service Amazon OpenSearch Service
Amazon OpenSearch Service
CloudFront CloudFront
CloudFront
MediaLive MediaLive
MediaLive
Open side navigation
CloudWatch
CloudWatch
Logs Insights
Logs Insights
Query definition
Query definition
Info : Query definition
5m (5 Minutes)
30m (30 Minutes)
1h (1 Hour)
3h (3 Hours)
12h (12 Hours)
Custom (1d)
Custom (1d)
Compare (Off)
Compare
(
Off
)
Time zone UTC timezone
UTC timezone
Start tailing with selected log group (opens in a new tab)
Start tailing
Query scope
Query scope Log group name
Log group name
Select up to 50 log groups
Show more chosen log groups
Show more chosen log groups (+25)
Browse
:
Log Groups
|
Facets
|
Lookup tables
Undo
Redo
Logs Insights QL
Query generator
Query generator
Fields
Saved and sample queries
Query commands
Run query
Cancel
Save
History
Completed. Query executed for
26 log groups.
View log groups used in query
Logs (72)
Logs
(
72
)
Patterns (3)
Patterns
(
3
)
Visualization
Visualization
Logs (72)
Logs (72)
Summarize results
Summarize results
Investigate
Investigate
Share results
Share results
Export results
Export results
Add to dashboard
Showing 72 of 72 records matched
54,170,353 records (14.6 GB) scanned in 22.8s @ 2,372,874 records/s (656.9 MB/s)
Hide histogram
Hide histogram
Filter table results
2026-04-17T06:00:26.815Z
[2026-04-17 06:00:26] production.INFO: [Send Report] Processing report {"uuid":"822fa41b-afd3-43a9-a248-86b0e36f3131","status":"Generated"} {"correlation_id":"a39e85ea-5b74-4ac9-87a8-3a109b8fc433","trace_id":"a98d108b-c9a5-43d9-9d18-a76ccb82e5cc"}
worker-analytics/worker-analytics/fb554dc84d6140c2ad7f217bbc19b409 Opens in a new tab
410346195943:worker-analytics
2026-04-17T06:00:26.645Z
[2026-04-17 06:00:26] production.INFO: [Send Report] Processing report {"uuid":"822fa41b-afd3-43a9-a248-86b0e36f3131","status":"Generated"} {"correlation_id":"fdd3bd52-79a8-4a9a-92ea-5b9fc93fbbb2","trace_id":"a98d108b-c9a5-43d9-9d18-a76ccb82e5cc"}
worker-analytics/worker-analytics/722d81a3183d415ab2c8817c87c12a84 Opens in a new tab
410346195943:worker-analytics
2026-04-17T06:00:25.529Z
[2026-04-17 06:00:25] production.INFO: [automated-reports:send] Dispatching job {"uuid":"822fa41b-afd3-43a9-a248-86b0e36f3131"} {"correlation_id":"ea906b5c-3794-43f3-99c4-e337d437b9fc","trace_id":"a98d108b-c9a5-43d9-9d18-a76ccb82e5cc"}
worker-delayed/worker-delayed/d15dd27b01dd40468ea5aae74e7af42b Opens in a new tab
410346195943:worker-delayed
2026-04-17T05:00:20.286Z
[2026-04-17 05:00:20] production.INFO: [Send Report] Processing report {"uuid":"822fa41b-afd3-43a9-a248-86b0e36f3131","status":"Generated"} {"correlation_id":"b56f7e75-ece7-4a35-9177-1c5ebe1648aa","trace_id":"eb295dc8-469d-4e35-914f-19c174098db4"}
worker-analytics/worker-analytics/5cb754a0f75b4d7ca64762d6af1da207 Opens in a new tab
410346195943:worker-analytics
2026-04-17T05:00:20.093Z
[2026-04-17 05:00:20] production.INFO: [Send Report] Processing report {"uuid":"822fa41b-afd3-43a9-a248-86b0e36f3131","status":"Generated"} {"correlation_id":"bd05f3ce-b48b-4c4b-b529-4012294eb058","trace_id":"eb295dc8-469d-4e35-914f-19c174098db4"}
worker-analytics/worker-analytics/fb554dc84d6140c2ad7f217bbc19b409 Opens in a new tab
410346195943:worker-analytics
2026-04-17T05:00:18.321Z
[2026-04-17 05:00:18] production.INFO: [automated-reports:send] Dispatching job {"uuid":"822fa41b-afd3-43a9-a248-86b0e36f3131"} {"correlation_id":"1077f9be-7b8c-4e6a-b8dd-27c4ad0c044e","trace_id":"eb295dc8-469d-4e35-914f-19c174098db4"}
worker-delayed/worker-delayed/d15dd27b01dd40468ea5aae74e7af42b Opens in a new tab
410346195943:worker-delayed
2026-04-17T04:02:35.334Z
[2026-04-17 04:02:35] production.INFO: [Send Report] Processing report {"uuid":"822fa41b-afd3-43a9-a248-86b0e36f3131","status":"Generated"} {"correlation_id":"599e1a79-9081-4e88-af32-113cf4503a84","trace_id":"0e885db3-433d-401f-896b-3f9c8f5d2150"}
worker-analytics/worker-analytics/fb554dc84d6140c2ad7f217bbc19b409 Opens in a new tab
410346195943:worker-analytics
2026-04-17T04:02:34.808Z
[2026-04-17 04:02:34] production.INFO: [Send Report] Processing report {"uuid":"822fa41b-afd3-43a9-a248-86b0e36f3131","status":"Generated"} {"correlation_id":"a254993f-5930-4858-92b2-2e00bcfdac15","trace_id":"0e885db3-433d-401f-896b-3f9c8f5d2150"}
worker-analytics/worker-analytics/722d81a3183d415ab2c8817c87c12a84 Opens in a new tab
410346195943:worker-analytics
2026-04-17T04:00:23.302Z
[2026-04-17 04:00:23] production.INFO: [automated-reports:send] Dispatching job {"uuid":"822fa41b-afd3-43a9-a248-86b0e36f3131"} {"correlation_id":"840ff441-d597-4786-8a8d-86c41b2e618f","trace_id":"0e885db3-433d-401f-896b-3f9c8f5d2150"}
worker-conferences/worker-conferences/a7d2827044c3432aacb481432e962e9b Opens in a new tab
410346195943:worker-conferences
2026-04-17T03:00:20.945Z
[2026-04-17 03:00:20] production.INFO: [Send Report] Processing report {"uuid":"822fa41b-afd3-43a9-a248-86b0e36f3131","status":"Generated"} {"correlation_id":"2ca7bc5b-e6b5-46f4-8f58-92b02fb02478","trace_id":"72180b42-468f-429a-a297-0c6447e7b094"}
worker-analytics/worker-analytics/722d81a3183d415ab2c8817c87c12a84 Opens in a new tab
410346195943:worker-analytics
2026-04-17T03:00:19.411Z
[2026-04-17 03:00:19] production.INFO: [Send Report] Processing report {"uuid":"822fa41b-afd3-43a9-a248-86b0e36f3131","status":"Generated"} {"correlation_id":"53fa262c-2873-423e-94e2-6fd306b6a6d8","trace_id":"72180b42-468f-429a-a297-0c6447e7b094"}
worker-analytics/worker-analytics/fb554dc84d6140c2ad7f217bbc19b409 Opens in a new tab
410346195943:worker-analytics...
|
41633
|
|
41449
|
879
|
25
|
2026-04-17T06:13:41.640489+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-17/1776 /Users/lukas/.screenpipe/data/data/2026-04-17/1776406421640_m1.jpg...
|
Firefox
|
CloudWatch | us-east-2 — Work
|
True
|
us-east-2.console.aws.amazon.com/cloudwatch/home?r us-east-2.console.aws.amazon.com/cloudwatch/home?region=us-east-2#logsV2:logs-insights$3FqueryDetail$3D~(end~0~start~-86400~timeType~'RELATIVE~tz~'UTC~unit~'seconds~editorString~'fields*20*40timestamp*2c*20*40message*2c*20*40logStream*2c*20*40log*0a*7c*20filter*20*40message*20like*20*2fd8fe2b34-1f65-47dd-9f3a-f6cd4b33924a*2f*20*0a*7c*20filter*20*40message*20not*20like*20*2fAnalytic*2f*20*7c*20filter*20*40message*20not*20like*20*2fTranscript*2f*0a*7c*20filter*20*40message*20not*20like*20*2fWebhook*2f*20*7c*20filter*20*40message*20not*20like*20*2fMeetingBot*2f*20*0a*7c*20limit*2010000~queryId~'0551e814-f51a-4339-8372-80d7ba4cef27~source~(~'worker~'worker-analytics~'worker-app~'worker-audio~'worker-calendar~'worker-conferences~'worker-crm-sync~'worker-default~'worker-delayed~'worker-dialers~'worker-dialers-fifo~'worker-download~'worker-emails~'worker-meeting-bot~'worker-nudges~'worker-processing-1~'worker-processing-2~'worker-processing-3~'worker-processing-4~'worker-processing-5~'worker-processing-delayed~'worker-softphone~'worker-video~'worker-video-app~'php~'php-app)~lang~'CWLI~logClass~'STANDARD~queryBy~'logGroupName)...
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Platform Sprint 2 Q2 - Platform Team - Scrum Board Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira
[SRD-6793] Les Mills activity types not pulling in - Jira
[SRD-6793] Les Mills activity types not pulling in - Jira
New Tab
New Tab
Symfony\Component\Debug\Exception\FatalThrowableError: League\Flysystem\Filesystem::has(): Argument #1 ($location) must be of type string, null given, called in /home/jiminny/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php on line
Symfony\Component\Debug\Exception\FatalThrowableError: League\Flysystem\Filesystem::has(): Argument #1 ($location) must be of type string, null given, called in /home/jiminny/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php on line
CloudWatch | us-east-2
CloudWatch | us-east-2
Close tab
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
Console Home | Console Home | eu-west-1
Console Home | Console Home | eu-west-1
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
AWS Console Home
Skip to Main Content
Skip to Main Content
Amazon Q
Services
Search
Ask Amazon Q
[Option+S]
CloudShell
Notifications (none available)
Help & support
Settings
United States (Ohio)
United States (Ohio)
PROD
Account ID: 4103-4619-5943
PROD
EC2 EC2
EC2
Elastic Container Service Elastic Container Service
Elastic Container Service
S3 S3
S3
CodeDeploy CodeDeploy
CodeDeploy
CloudWatch CloudWatch
CloudWatch
ElastiCache ElastiCache
ElastiCache
Aurora and RDS Aurora and RDS
Aurora and RDS
Amazon OpenSearch Service Amazon OpenSearch Service
Amazon OpenSearch Service
CloudFront CloudFront
CloudFront
MediaLive MediaLive
MediaLive
Open side navigation
CloudWatch
CloudWatch
Logs Insights
Logs Insights
Query definition
Query definition
Info : Query definition
5m (5 Minutes)
30m (30 Minutes)
1h (1 Hour)
3h (3 Hours)
12h (12 Hours)
Custom (1d)
Custom (1d)
Compare (Off)
Compare
(
Off
)
Time zone UTC timezone
UTC timezone
Start tailing with selected log group (opens in a new tab)
Start tailing
Query scope
Query scope Log group name
Log group name
Select up to 50 log groups
Show more chosen log groups
Show more chosen log groups (+25)
Browse
:
Log Groups
|
Facets
|
Lookup tables
Undo
Redo
Logs Insights QL
Query generator
Query generator
Fields
Saved and sample queries
Query commands
Run query
Cancel
Save
History
Fetching results
Logs (-)
Logs
(
-
)
Patterns (-)
Patterns
(
-
)
Visualization
Visualization
Logs (-)
Logs (-)
Summarize results
Summarize results
Investigate
Investigate
Share results
Share results
Export results
Export results
Add to dashboard
Fetching data...
Hide histogram
Hide histogram
Close saved and sample queries drawer
Queries
Queries
Saved queries
Saved queries
Learn more about saved queries (opens in a new tab)
Learn more
Filter by query name
Create query
CleanDB (14)
CleanDB (14)
CRM (14)
CRM (14)
Dialers (11)...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"[SRD-6793] Les Mills activity types not pulling in - Jira","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[SRD-6793] Les Mills activity types not pulling in - Jira","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"New Tab","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"New Tab","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Symfony\\Component\\Debug\\Exception\\FatalThrowableError: League\\Flysystem\\Filesystem::has(): Argument #1 ($location) must be of type string, null given, called in /home/jiminny/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php on line","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Symfony\\Component\\Debug\\Exception\\FatalThrowableError: League\\Flysystem\\Filesystem::has(): Argument #1 ($location) must be of type string, null given, called in /home/jiminny/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php on line","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"CloudWatch | us-east-2","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"CloudWatch | us-east-2","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close tab","depth":5,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXRadioButton","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Configure SSH access to multiple environment - Engineering - Confluence","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Console Home | Console Home | eu-west-1","depth":4,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Console Home | Console Home | eu-west-1","depth":5,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"New Tab","depth":4,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"AWS Console Home","depth":13,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXLink","text":"Skip to Main Content","depth":13,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Skip to Main Content","depth":14,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Amazon Q","depth":14,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Services","depth":13,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXComboBox","text":"Search","depth":16,"role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Ask Amazon Q","depth":15,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"[Option+S]","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"CloudShell","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Notifications (none available)","depth":16,"help_text":"Notifications","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Help & support","depth":15,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Settings","depth":15,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXComboBox","text":"United States (Ohio)","depth":15,"value":"United States (Ohio)","help_text":"United States (Ohio)","role_description":"combo box","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"United States (Ohio)","depth":17,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"PROD","depth":15,"help_text":"Production_View_Only @ jiminny","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Account ID: 4103-4619-5943","depth":19,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"PROD","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"EC2 EC2","depth":16,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"EC2","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Elastic Container Service Elastic Container Service","depth":16,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Elastic Container Service","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"S3 S3","depth":16,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"S3","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"CodeDeploy CodeDeploy","depth":16,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"CodeDeploy","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"CloudWatch CloudWatch","depth":16,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"CloudWatch","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"ElastiCache ElastiCache","depth":16,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"ElastiCache","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Aurora and RDS Aurora and RDS","depth":16,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Aurora and RDS","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Amazon OpenSearch Service Amazon OpenSearch Service","depth":16,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Amazon OpenSearch Service","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"CloudFront CloudFront","depth":16,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"CloudFront","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"MediaLive MediaLive","depth":16,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"MediaLive","depth":18,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Open side navigation","depth":13,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"CloudWatch","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"CloudWatch","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Logs Insights","depth":14,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Logs Insights","depth":16,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Query definition","depth":26,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXButton","text":"Query definition","depth":28,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":true},{"role":"AXButton","text":"Info : Query definition","depth":27,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"5m (5 Minutes)","depth":27,"help_text":"5 Minutes","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"30m (30 Minutes)","depth":27,"help_text":"30 Minutes","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"1h (1 Hour)","depth":27,"help_text":"1 Hour","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"3h (3 Hours)","depth":27,"help_text":"3 Hours","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"12h (12 Hours)","depth":27,"help_text":"12 Hours","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Custom (1d)","depth":27,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Custom (1d)","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXCheckBox","text":"Compare (Off)","depth":26,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Compare","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Off","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Time zone UTC timezone","depth":26,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"UTC timezone","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Start tailing with selected log group (opens in a new tab)","depth":26,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Start tailing","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Query scope","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Query scope Log group name","depth":27,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Log group name","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Select up to 50 log groups","depth":28,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Show more chosen log groups","depth":27,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Show more chosen log groups (+25)","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Browse","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":":","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Log Groups","depth":27,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"|","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Facets","depth":27,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"|","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Lookup tables","depth":27,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Undo","depth":28,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Redo","depth":28,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXMenuButton","text":"Logs Insights QL","depth":29,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Query generator","depth":26,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Query generator","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Fields","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Saved and sample queries","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Query commands","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Run query","depth":27,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Cancel","depth":27,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Save","depth":27,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"History","depth":27,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Fetching results","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Logs (-)","depth":25,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXStaticText","text":"Logs","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Patterns (-)","depth":25,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Patterns","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"(","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"-","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":")","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXRadioButton","text":"Visualization","depth":25,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Visualization","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Logs (-)","depth":26,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Logs (-)","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Summarize results","depth":26,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Summarize results","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Investigate","depth":28,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Investigate","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Share results","depth":26,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Share results","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXMenuButton","text":"Export results","depth":28,"help_text":"","role_description":"menu button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Export results","depth":29,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Add to dashboard","depth":26,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Fetching data...","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Hide histogram","depth":26,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Hide histogram","depth":27,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Close saved and sample queries drawer","depth":24,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Queries","depth":23,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Queries","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Saved queries","depth":24,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Saved queries","depth":25,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXLink","text":"Learn more about saved queries (opens in a new tab)","depth":23,"help_text":"","role_description":"link","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Learn more","depth":24,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXTextField","text":"Filter by query name","depth":23,"help_text":"","role_description":"search text field","subrole":"AXSearchField","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Create query","depth":24,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"CleanDB (14)","depth":26,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"CleanDB (14)","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"CRM (14)","depth":26,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"CRM (14)","depth":28,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Dialers (11)","depth":26,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
-669960614745973712
|
8659345236572745878
|
click
|
accessibility
|
NULL
|
Platform Sprint 2 Q2 - Platform Team - Scrum Board Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira
Platform Sprint 2 Q2 - Platform Team - Scrum Board - Jira
[SRD-6793] Les Mills activity types not pulling in - Jira
[SRD-6793] Les Mills activity types not pulling in - Jira
New Tab
New Tab
Symfony\Component\Debug\Exception\FatalThrowableError: League\Flysystem\Filesystem::has(): Argument #1 ($location) must be of type string, null given, called in /home/jiminny/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php on line
Symfony\Component\Debug\Exception\FatalThrowableError: League\Flysystem\Filesystem::has(): Argument #1 ($location) must be of type string, null given, called in /home/jiminny/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php on line
CloudWatch | us-east-2
CloudWatch | us-east-2
Close tab
Configure SSH access to multiple environment - Engineering - Confluence
Configure SSH access to multiple environment - Engineering - Confluence
Console Home | Console Home | eu-west-1
Console Home | Console Home | eu-west-1
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
AWS Console Home
Skip to Main Content
Skip to Main Content
Amazon Q
Services
Search
Ask Amazon Q
[Option+S]
CloudShell
Notifications (none available)
Help & support
Settings
United States (Ohio)
United States (Ohio)
PROD
Account ID: 4103-4619-5943
PROD
EC2 EC2
EC2
Elastic Container Service Elastic Container Service
Elastic Container Service
S3 S3
S3
CodeDeploy CodeDeploy
CodeDeploy
CloudWatch CloudWatch
CloudWatch
ElastiCache ElastiCache
ElastiCache
Aurora and RDS Aurora and RDS
Aurora and RDS
Amazon OpenSearch Service Amazon OpenSearch Service
Amazon OpenSearch Service
CloudFront CloudFront
CloudFront
MediaLive MediaLive
MediaLive
Open side navigation
CloudWatch
CloudWatch
Logs Insights
Logs Insights
Query definition
Query definition
Info : Query definition
5m (5 Minutes)
30m (30 Minutes)
1h (1 Hour)
3h (3 Hours)
12h (12 Hours)
Custom (1d)
Custom (1d)
Compare (Off)
Compare
(
Off
)
Time zone UTC timezone
UTC timezone
Start tailing with selected log group (opens in a new tab)
Start tailing
Query scope
Query scope Log group name
Log group name
Select up to 50 log groups
Show more chosen log groups
Show more chosen log groups (+25)
Browse
:
Log Groups
|
Facets
|
Lookup tables
Undo
Redo
Logs Insights QL
Query generator
Query generator
Fields
Saved and sample queries
Query commands
Run query
Cancel
Save
History
Fetching results
Logs (-)
Logs
(
-
)
Patterns (-)
Patterns
(
-
)
Visualization
Visualization
Logs (-)
Logs (-)
Summarize results
Summarize results
Investigate
Investigate
Share results
Share results
Export results
Export results
Add to dashboard
Fetching data...
Hide histogram
Hide histogram
Close saved and sample queries drawer
Queries
Queries
Saved queries
Saved queries
Learn more about saved queries (opens in a new tab)
Learn more
Filter by query name
Create query
CleanDB (14)
CleanDB (14)
CRM (14)
CRM (14)
Dialers (11)...
|
41448
|
|
53766
|
1163
|
26
|
2026-04-20T08:27:25.453725+00:00
|
/Users/lukas/.screenpipe/data/data/2026-04-20/1776 /Users/lukas/.screenpipe/data/data/2026-04-20/1776673645453_m2.jpg...
|
PhpStorm
|
|
True
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project Files
Preview
Filter
Open in Find Tool Win Project Files
Preview
Filter
Open in Find Tool Window
app/Providers/AuthServiceProvider.php
AuthServiceProvider.php .../app/Providers/AuthServiceProvider.php, final class
AuthServiceProvider.php.html build/coverage/Providers
AuthServiceProvider.php .../app/Providers/AuthServiceProvider.php, final class
AuthServiceProvider.php.html build/coverage/Providers
Providers/AuthServiceProvider.php
Open In Right Split...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project Files","depth":2,"bounds":{"left":0.6968085,"top":0.24181964,"width":0.03557181,"height":0.01915403},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Preview","depth":2,"bounds":{"left":0.73238033,"top":0.24181964,"width":0.008643617,"height":0.01915403},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Filter","depth":2,"bounds":{"left":0.74102396,"top":0.24181964,"width":0.008643617,"height":0.01915403},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Open in Find Tool Window","depth":2,"bounds":{"left":0.7496675,"top":0.24181964,"width":0.008643617,"height":0.01915403},"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextField","text":"app/Providers/AuthServiceProvider.php","depth":1,"bounds":{"left":0.50232714,"top":0.27214685,"width":0.25598404,"height":0.023144454},"value":"app/Providers/AuthServiceProvider.php","role_description":"text field","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"AuthServiceProvider.php .../app/Providers/AuthServiceProvider.php, final class","depth":2,"bounds":{"left":0.4993351,"top":0.30407023,"width":0.26196808,"height":0.017557861},"role_description":"text"},{"role":"AXStaticText","text":"AuthServiceProvider.php.html build/coverage/Providers","depth":2,"bounds":{"left":0.4993351,"top":0.3216281,"width":0.26196808,"height":0.017557861},"role_description":"text"},{"role":"AXStaticText","text":"AuthServiceProvider.php .../app/Providers/AuthServiceProvider.php, final class","depth":4,"bounds":{"left":0.4993351,"top":0.30407023,"width":0.26196808,"height":0.017557861},"role_description":"text"},{"role":"AXStaticText","text":"AuthServiceProvider.php.html build/coverage/Providers","depth":4,"bounds":{"left":0.4993351,"top":0.3216281,"width":0.26196808,"height":0.017557861},"role_description":"text"},{"role":"AXStaticText","text":"Providers/AuthServiceProvider.php","depth":1,"bounds":{"left":0.50598407,"top":0.75259376,"width":0.06615692,"height":0.013567438},"help_text":"Providers/AuthServiceProvider.php","role_description":"text"},{"role":"AXLink","text":"Open In Right Split","depth":1,"bounds":{"left":0.71476066,"top":0.75259376,"width":0.03856383,"height":0.013567438},"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
-4956447503868753337
|
8656644654603191288
|
visual_change
|
accessibility
|
NULL
|
Project Files
Preview
Filter
Open in Find Tool Win Project Files
Preview
Filter
Open in Find Tool Window
app/Providers/AuthServiceProvider.php
AuthServiceProvider.php .../app/Providers/AuthServiceProvider.php, final class
AuthServiceProvider.php.html build/coverage/Providers
AuthServiceProvider.php .../app/Providers/AuthServiceProvider.php, final class
AuthServiceProvider.php.html build/coverage/Providers
Providers/AuthServiceProvider.php
Open In Right Split...
|
53765
|