# Tool fixes for schemas, SQLTools, FileTools, Google Calendar and search toolkits

> Agno turns Annotated[T, ...] tool parameters into the schema for T, SQLTools keeps reserved characters in passwords, FileTools.replace_file_chunk rejects bad line ranges, GoogleCalendarTools stops offering slots past closing time, and three search toolkits honor a zero result limit.

- Published: 2026-10-08
- Author: uma-prasad
- Categories: Changelog
- Canonical: https://www.agno.com/blog/tool-fixes-for-schemas-sqltools-filetools-google-calendar-and-search-toolkits
- Markdown: https://www.agno.com/blog/tool-fixes-for-schemas-sqltools-filetools-google-calendar-and-search-toolkits.md

Agno ships six tool fixes in this release. Each block below shows real output from the previous release and from this one.

### Tool schemas read `Annotated` hints

Agno's `get_json_schema_for_arg` builds the parameter schema the model reads for every tool. A tool that takes a dataclass with a field typed `Annotated[int, Field(ge=0)]` used to describe that field to the model as an empty object. The model then had no idea it should send a number. The schema for `place_order(order: Order)`:

```text
Before: {"quantity": {"type": "object", "properties": {}, "additionalProperties": false}, "note": {"type": "string"}}
Now:    {"quantity": {"type": "integer"}, "note": {"type": "string"}}
```

### `SQLTools` keeps reserved characters in passwords

When you pass `user`, `password`, `host`, `port` and `dialect`, `SQLTools` builds the engine URL with SQLAlchemy's `URL.create`. Earlier releases formatted those parts into one string, so an `@` in the password moved the rest of it into the host. For `password="p@ssword"` and `host="db.internal"`:

```text
Before: host: ssword@db.internal | password: p
Now:    host: db.internal | password: p@ssword
```

### `FileTools.replace_file_chunk` checks its line range

`replace_file_chunk` now rejects a negative start, an end before the start, and an end past the last line, and it leaves the file untouched. Its line count skips the empty piece after a final newline, so no valid range can swallow that newline. On a file holding `one\ntwo\nthree\n`:

```text
replace_file_chunk(start_line=2, end_line=1, chunk="X")
Before: 'notes.txt'  file: 'one\ntwo\nX\nthree\n'
Now:    'Error patching file: require 0 <= start_line <= end_line'  file: 'one\ntwo\nthree\n'

replace_file_chunk(start_line=1, end_line=9, chunk="X")
Before: 'notes.txt'  file: 'one\nX'
Now:    'Error patching file: end_line must be less than 3'  file: 'one\ntwo\nthree\n'
```

### `GoogleCalendarTools` slots end before closing time

`find_available_slots` compared only the hour of a slot's end with the closing hour, so with a 17:00 close it still offered a 45 minute slot from 16:30 to 17:15. It now compares the full end time with closing time on the slot's start date, which also stops a slot from crossing midnight. The last slots on an empty Friday with the default 9:00 to 17:00 hours:

```text
Before: [('15:30', '16:15'), ('16:00', '16:45'), ('16:30', '17:15')]
Now:    [('15:00', '15:45'), ('15:30', '16:15'), ('16:00', '16:45')]
```

### `BaiduSearchTools`, `Searxng` and `SpiderTools` honor a zero limit

These toolkits resolved their limit with `or`, which treats `0` like an unset value. `BaiduSearchTools(fixed_max_results=0)` and `Searxng(fixed_max_results=0)` then used the per-call `max_results`, and `SpiderTools(max_results=0)` used 5. They now check for `None`, so `0` returns no results. With a mocked backend that returns five hits:

```text
Searxng(fixed_max_results=0).search_web("agno")
Before: results returned: 5
Now:    results returned: 0

SpiderTools(max_results=0).search_web("agno")
Before: {'fetch_page_content': False, 'num': 5}
Now:    {'fetch_page_content': False, 'num': 0}
```

### `PerplexitySearch` identifies Agno traffic

`PerplexitySearch.search` and `asearch` add an `X-Pplx-Integration: agno` header, which lets Perplexity attribute requests that come through the toolkit. The `X-` headers on a search request:

```text
Before: {'X-Source': 'agno'}
Now:    {'X-Source': 'agno', 'X-Pplx-Integration': 'agno'}
```

See the [FileTools cookbook](https://github.com/agno-agi/agno/blob/main/cookbook/91_tools/file_tools.py), and learn more about [tools from Python functions](https://docs.agno.com/tools/creating-tools/python-functions), [SQLTools](https://docs.agno.com/tools/toolkits/database/sql), [FileTools](https://docs.agno.com/tools/toolkits/local/file), [Google Calendar](https://docs.agno.com/tools/toolkits/others/googlecalendar), [Searxng](https://docs.agno.com/tools/toolkits/search/searxng), [Baidu Search](https://docs.agno.com/tools/toolkits/search/baidusearch), [Spider](https://docs.agno.com/tools/toolkits/web-scrape/spider) and [Perplexity Search](https://docs.agno.com/tools/toolkits/search/perplexity) in the documentation.
