refactor: improve type checking and linting script

- Updated `pyproject.toml` to enhance type checking configuration by refining the `exclude` list and adding an `include` section for better clarity.
- Modified `lint.sh` to run tools directly from the virtual environment, improving execution reliability and avoiding permission errors.
- Enhanced comments in `lint.sh` for better understanding of script functionality and usage.
This commit is contained in:
reformedot
2025-11-11 12:00:20 -08:00
parent 8098677a87
commit c99e1bb41f
4 changed files with 67 additions and 26 deletions
+23 -9
View File
@@ -14,7 +14,9 @@
# $ ./bin/lint.sh --staged # Only staged files - varies # $ ./bin/lint.sh --staged # Only staged files - varies
# $ ./bin/lint.sh --staged --quick # Fast pre-commit - <2s # $ ./bin/lint.sh --staged --quick # Fast pre-commit - <2s
# #
# Note: Quick mode skips type checking. Always run full mode before pushing to CI. # Note:
# - Quick mode skips type checking. Always run full mode before pushing to CI.
# - This script runs tools directly from .venv to avoid 'uv run' permission errors.
set -o pipefail set -o pipefail
IFS=$'\n' IFS=$'\n'
@@ -22,6 +24,18 @@ IFS=$'\n'
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
cd "$SCRIPT_DIR/.." || exit 1 cd "$SCRIPT_DIR/.." || exit 1
# Find the active venv and prefer direct execution over uv run to avoid permission errors
if [ -n "$VIRTUAL_ENV" ]; then
# Already in a venv, use tools directly
RUN_CMD=""
elif [ -f ".venv/bin/activate" ]; then
# Use .venv directly without activating
RUN_CMD=".venv/bin/"
else
# Fallback to uv run
RUN_CMD="uv run "
fi
# Parse arguments # Parse arguments
FAIL_FAST=0 FAIL_FAST=0
QUICK_MODE=0 QUICK_MODE=0
@@ -124,28 +138,28 @@ START_TIME=$(date +%s)
# Launch all checks in parallel # Launch all checks in parallel
if [ ${#FILE_ARRAY[@]} -eq 0 ]; then if [ ${#FILE_ARRAY[@]} -eq 0 ]; then
# Full mode: check everything # Full mode: check everything
uv run ruff check --fix > "$TEMP_DIR/ruff-check.log" 2>&1 & ${RUN_CMD}ruff check --fix > "$TEMP_DIR/ruff-check.log" 2>&1 &
RUFF_CHECK_PID=$! RUFF_CHECK_PID=$!
RUFF_CHECK_START=$(date +%s) RUFF_CHECK_START=$(date +%s)
uv run ruff format > "$TEMP_DIR/ruff-format.log" 2>&1 & ${RUN_CMD}ruff format > "$TEMP_DIR/ruff-format.log" 2>&1 &
RUFF_FORMAT_PID=$! RUFF_FORMAT_PID=$!
RUFF_FORMAT_START=$(date +%s) RUFF_FORMAT_START=$(date +%s)
uv run pyright --threads 6 > "$TEMP_DIR/pyright.log" 2>&1 & ${RUN_CMD}pyright --threads 6 > "$TEMP_DIR/pyright.log" 2>&1 &
PYRIGHT_PID=$! PYRIGHT_PID=$!
PYRIGHT_START=$(date +%s) PYRIGHT_START=$(date +%s)
SKIP=ruff-check,ruff-format,pyright uv run pre-commit run --all-files > "$TEMP_DIR/other-checks.log" 2>&1 & SKIP=ruff-check,ruff-format,pyright ${RUN_CMD}pre-commit run --all-files > "$TEMP_DIR/other-checks.log" 2>&1 &
OTHER_PID=$! OTHER_PID=$!
OTHER_START=$(date +%s) OTHER_START=$(date +%s)
else else
# Staged or quick mode: check only specific files # Staged or quick mode: check only specific files
uv run ruff check --fix "${FILE_ARRAY[@]}" > "$TEMP_DIR/ruff-check.log" 2>&1 & ${RUN_CMD}ruff check --fix "${FILE_ARRAY[@]}" > "$TEMP_DIR/ruff-check.log" 2>&1 &
RUFF_CHECK_PID=$! RUFF_CHECK_PID=$!
RUFF_CHECK_START=$(date +%s) RUFF_CHECK_START=$(date +%s)
uv run ruff format "${FILE_ARRAY[@]}" > "$TEMP_DIR/ruff-format.log" 2>&1 & ${RUN_CMD}ruff format "${FILE_ARRAY[@]}" > "$TEMP_DIR/ruff-format.log" 2>&1 &
RUFF_FORMAT_PID=$! RUFF_FORMAT_PID=$!
RUFF_FORMAT_START=$(date +%s) RUFF_FORMAT_START=$(date +%s)
@@ -155,12 +169,12 @@ else
PYRIGHT_PID=-1 PYRIGHT_PID=-1
PYRIGHT_START=$(date +%s) PYRIGHT_START=$(date +%s)
else else
uv run pyright --threads 6 "${FILE_ARRAY[@]}" > "$TEMP_DIR/pyright.log" 2>&1 & ${RUN_CMD}pyright --threads 6 "${FILE_ARRAY[@]}" > "$TEMP_DIR/pyright.log" 2>&1 &
PYRIGHT_PID=$! PYRIGHT_PID=$!
PYRIGHT_START=$(date +%s) PYRIGHT_START=$(date +%s)
fi fi
SKIP=ruff-check,ruff-format,pyright uv run pre-commit run --files "${FILE_ARRAY[@]}" > "$TEMP_DIR/other-checks.log" 2>&1 & SKIP=ruff-check,ruff-format,pyright ${RUN_CMD}pre-commit run --files "${FILE_ARRAY[@]}" > "$TEMP_DIR/other-checks.log" 2>&1 &
OTHER_PID=$! OTHER_PID=$!
OTHER_START=$(date +%s) OTHER_START=$(date +%s)
fi fi
+1 -1
View File
@@ -634,7 +634,7 @@ class SessionManager:
try: try:
# Wait for completion with timeout # Wait for completion with timeout
await asyncio.wait_for(ready_event.wait(), timeout=2.0) await asyncio.wait_for(ready_event.wait(), timeout=2.0)
except asyncio.TimeoutError: except TimeoutError:
# Timeout - count what's ready # Timeout - count what's ready
ready_count = 0 ready_count = 0
for tid in target_ids_to_wait_for: for tid in target_ids_to_wait_for:
+20 -15
View File
@@ -43,9 +43,14 @@ async def handle_model_action(browser_session: BrowserSession, action) -> Action
action_type = action.type action_type = action.type
ERROR_MSG: str = 'Could not execute the CUA action.' ERROR_MSG: str = 'Could not execute the CUA action.'
if not browser_session.agent_focus: if not browser_session.agent_focus_target_id:
return ActionResult(error='No active browser session') return ActionResult(error='No active browser session')
# Get CDP session for the focused target
cdp_session = browser_session.session_manager.get_session_for_target(browser_session.agent_focus_target_id)
if not cdp_session:
return ActionResult(error='No CDP session for focused target')
try: try:
match action_type: match action_type:
case 'click': case 'click':
@@ -57,7 +62,7 @@ async def handle_model_action(browser_session: BrowserSession, action) -> Action
button = 'left' button = 'left'
# Use CDP to click # Use CDP to click
await browser_session.agent_focus.cdp_client.send.Input.dispatchMouseEvent( await browser_session.cdp_client.send.Input.dispatchMouseEvent(
params={ params={
'type': 'mousePressed', 'type': 'mousePressed',
'x': x, 'x': x,
@@ -65,16 +70,16 @@ async def handle_model_action(browser_session: BrowserSession, action) -> Action
'button': button, 'button': button,
'clickCount': 1, 'clickCount': 1,
}, },
session_id=browser_session.agent_focus.session_id, session_id=cdp_session.session_id,
) )
await browser_session.agent_focus.cdp_client.send.Input.dispatchMouseEvent( await browser_session.cdp_client.send.Input.dispatchMouseEvent(
params={ params={
'type': 'mouseReleased', 'type': 'mouseReleased',
'x': x, 'x': x,
'y': y, 'y': y,
'button': button, 'button': button,
}, },
session_id=browser_session.agent_focus.session_id, session_id=cdp_session.session_id,
) )
msg = f'Clicked at ({x}, {y}) with button {button}' msg = f'Clicked at ({x}, {y}) with button {button}'
return ActionResult(extracted_content=msg, include_in_memory=True, long_term_memory=msg) return ActionResult(extracted_content=msg, include_in_memory=True, long_term_memory=msg)
@@ -85,21 +90,21 @@ async def handle_model_action(browser_session: BrowserSession, action) -> Action
print(f'Action: scroll at ({x}, {y}) with offsets (scroll_x={scroll_x}, scroll_y={scroll_y})') print(f'Action: scroll at ({x}, {y}) with offsets (scroll_x={scroll_x}, scroll_y={scroll_y})')
# Move mouse to position first # Move mouse to position first
await browser_session.agent_focus.cdp_client.send.Input.dispatchMouseEvent( await browser_session.cdp_client.send.Input.dispatchMouseEvent(
params={ params={
'type': 'mouseMoved', 'type': 'mouseMoved',
'x': x, 'x': x,
'y': y, 'y': y,
}, },
session_id=browser_session.agent_focus.session_id, session_id=cdp_session.session_id,
) )
# Execute scroll using JavaScript # Execute scroll using JavaScript
await browser_session.agent_focus.cdp_client.send.Runtime.evaluate( await browser_session.cdp_client.send.Runtime.evaluate(
params={ params={
'expression': f'window.scrollBy({scroll_x}, {scroll_y})', 'expression': f'window.scrollBy({scroll_x}, {scroll_y})',
}, },
session_id=browser_session.agent_focus.session_id, session_id=cdp_session.session_id,
) )
msg = f'Scrolled at ({x}, {y}) with offsets (scroll_x={scroll_x}, scroll_y={scroll_y})' msg = f'Scrolled at ({x}, {y}) with offsets (scroll_x={scroll_x}, scroll_y={scroll_y})'
return ActionResult(extracted_content=msg, include_in_memory=True, long_term_memory=msg) return ActionResult(extracted_content=msg, include_in_memory=True, long_term_memory=msg)
@@ -116,19 +121,19 @@ async def handle_model_action(browser_session: BrowserSession, action) -> Action
key_code = 'Space' key_code = 'Space'
# Use CDP to send key # Use CDP to send key
await browser_session.agent_focus.cdp_client.send.Input.dispatchKeyEvent( await browser_session.cdp_client.send.Input.dispatchKeyEvent(
params={ params={
'type': 'keyDown', 'type': 'keyDown',
'key': key_code, 'key': key_code,
}, },
session_id=browser_session.agent_focus.session_id, session_id=cdp_session.session_id,
) )
await browser_session.agent_focus.cdp_client.send.Input.dispatchKeyEvent( await browser_session.cdp_client.send.Input.dispatchKeyEvent(
params={ params={
'type': 'keyUp', 'type': 'keyUp',
'key': key_code, 'key': key_code,
}, },
session_id=browser_session.agent_focus.session_id, session_id=cdp_session.session_id,
) )
msg = f'Pressed keys: {keys}' msg = f'Pressed keys: {keys}'
return ActionResult(extracted_content=msg, include_in_memory=True, long_term_memory=msg) return ActionResult(extracted_content=msg, include_in_memory=True, long_term_memory=msg)
@@ -139,12 +144,12 @@ async def handle_model_action(browser_session: BrowserSession, action) -> Action
# Type text character by character # Type text character by character
for char in text: for char in text:
await browser_session.agent_focus.cdp_client.send.Input.dispatchKeyEvent( await browser_session.cdp_client.send.Input.dispatchKeyEvent(
params={ params={
'type': 'char', 'type': 'char',
'text': char, 'text': char,
}, },
session_id=browser_session.agent_focus.session_id, session_id=cdp_session.session_id,
) )
msg = f'Typed text: {text}' msg = f'Typed text: {text}'
return ActionResult(extracted_content=msg, include_in_memory=True, long_term_memory=msg) return ActionResult(extracted_content=msg, include_in_memory=True, long_term_memory=msg)
+23 -1
View File
@@ -141,9 +141,31 @@ skip-magic-trailing-comma = false
[tool.pyright] [tool.pyright]
typeCheckingMode = "basic" typeCheckingMode = "basic"
exclude = [".venv/", ".git/", "__pycache__/", "./test_*.py", "./debug_*.py", "private_example/", "debug/*", "tests/scripts/*", "tests/old/*", "browser_use/dom/playground/*", "examples/use-cases/onepassword.py", "browser_use/llm/oci_raw/*", "browser_use/llm/tests/test_chat_models.py", "browser_use/llm/tests/test_single_step.py", "product_extraction.py", "discover/", "list/"] include = ["browser_use", "examples", "tests"]
exclude = [
".venv/",
".venv*/",
".git/",
"__pycache__/",
"**/site-packages/",
"./test_*.py",
"./debug_*.py",
"private_example/",
"debug/*",
"tests/scripts/*",
"tests/old/*",
"browser_use/dom/playground/*",
"examples/use-cases/onepassword.py",
"browser_use/llm/oci_raw/*",
"browser_use/llm/tests/test_chat_models.py",
"browser_use/llm/tests/test_single_step.py",
"product_extraction.py",
"discover/",
"list/"
]
venvPath = "." venvPath = "."
venv = ".venv" venv = ".venv"
reportMissingTypeStubs = false
[tool.hatch.build] [tool.hatch.build]