- AGI-569: after any click that opens a new tab, automatically dispatch
SwitchTabEvent so the agent lands on the new page immediately instead
of requiring a manual switch step (~877 occurrences)
- AGI-548: for <input type="checkbox/radio">, capture checked state
before the CDP mouse click and verify it toggled afterward; if
unchanged (custom-styled or shadow-DOM-backed inputs), fall back to
JS element.click() and report the final checked state in metadata
(~1,241 occurrences)
- Add `browser-use upload <index> <path>` command for uploading files to
file input elements via the CLI
- Extract find_file_input_near_element from nested closures in tools/service.py
to a reusable method on BrowserSession, deduplicating two copies
- Add BrowserWrapper.upload() for the Python REPL
- Resolve file paths to absolute on the client side before sending to daemon
- Update SKILL.md files and README with upload command docs
- restricted read_long_content file access to only paths in available_file_paths or browser_session.download_files to mitigate injection
- made PDF page selection truncate pages that exceed char budget instead of dropping them entirely
- fixed truncation hint in file_system.py to reference read_long_context instead of search_page
Empty string is outside most enum value sets, so model_dump would
serialize an out-of-set value violating the schema. Use None with
a type union (same treatment as nested objects) since no in-set
default can be safely chosen.
Non-required fields were always unioned with None, allowing null values
even when the JSON Schema did not permit them. Now only explicitly
nullable fields accept null. Non-required primitives get type-appropriate
zero defaults (empty string, 0, 0.0, False), arrays get [], and nested
objects fall back to None only where constructing a default is infeasible.
Gemini rejects OBJECT types with no properties in the response schema.
The output_schema field (dict | None) produced exactly that. Since this
field is only used programmatically, wrap it with SkipJsonSchema to
exclude it from the generated JSON schema while keeping it functional.
Made read_file smarter for PDFs - instead of just reading the first 20 pgs, it reads up to 60k chars and uses IDF scoring to prioritize pgs w unique content