fix(postgresql): wire is_available + extract_params into PostgreSQL @tool decorators#703
Conversation
…tool decorators All 5 PostgreSQL diagnostic tools previously raised `TypeError: missing 2 required positional arguments: 'host' and 'database'` whenever the agent tried to invoke them. The `@tool(...)` decorator on each was missing the `is_available` and `extract_params` callbacks, so the tool function got called with no kwargs even though `host` and `database` are required. Mirror the working MariaDB pattern from app/integrations/mariadb.py: add `postgresql_is_available` and `postgresql_extract_params` to app/integrations/postgresql.py, then wire both into all 5 PG tools' decorators (current queries, replication status, server status, slow queries, table stats). PostgreSQL integration resolves credentials internally via `resolve_postgresql_config`, so `extract_params` only surfaces the three identifying params: host, database, port. Credentials stay out of tool signatures and are never seen by the LLM. Verified against the full RDS PostgreSQL synthetic suite (make test-rds-synthetic) on Gemini 2.5-flash: PostgreSQL TypeError failures drop from 184 to 0.
Greptile SummaryAdds Confidence Score: 5/5Safe to merge — minimal, well-scoped change that mirrors an established working pattern with no regressions reported. All changes are additive and follow the existing MariaDB pattern precisely. The sources dict shape in detect_sources.py provides exactly the keys (host, database, port) that the new helpers consume, and credential handling is correctly delegated to resolve_postgresql_config. Test suite passes with zero new failures. No files require special attention. Important Files Changed
|
…ed integration
`dict.get("port", DEFAULT)` only substitutes the default when the key is
absent. If the resolved integration stores `{"port": None}` explicitly,
`pg.get("port", DEFAULT_POSTGRESQL_PORT)` returns None and `int(None)`
raises TypeError inside postgresql_extract_params.
Use `or` so both missing and None collapse to the default. Applied
preemptively — same finding Greptile raised on the MySQL side in Tracer-Cloud#704.
|
Pushed |
|
Heyyy this looks good |
|
Thanks for the contribution !!! 👍 |
|
@Devesh36 happy to contribute, and get things done. |
… decorators (#707) * fix(azure-sql): wire is_available + extract_params into Azure SQL @tool decorators Same @tool decorator wiring bug the PostgreSQL and MySQL sides fixed in #703 and #704, now for Azure SQL. All 5 Azure SQL diagnostic tools were silently failing with TypeError: missing 2 required positional arguments ('server' and 'database') on every agent invocation, because the decorator was missing the is_available and extract_params callbacks that inject identifying params from resolved integrations. Mirror the MariaDB/PostgreSQL/MySQL pattern: add azure_sql_is_available and azure_sql_extract_params to app/integrations/azure_sql.py, then wire both into all 5 Azure SQL tools (current queries, resource stats, server status, slow queries, wait stats). Azure SQL integration resolves credentials internally via resolve_azure_sql_config, so extract_params only surfaces the three identifying params (server, database, port). Credentials stay out of tool signatures and are never seen by the LLM. Applied Greptile's port-None hardening preemptively: int(az.get("port") or DEFAULT_AZURE_SQL_PORT). Covers both missing and explicit None port values in the resolved integration dict. Added 14 unit tests covering azure_sql_is_available (6 cases) and azure_sql_extract_params (8 cases including port-None, port-0, port-as-string, and credential isolation). Verified on make test-rds-synthetic (Gemini 2.5-flash): Azure SQL TypeError failures drop from 92 to 0 across the 15 RDS scenarios. * fix(azure-sql): harden server/database coercion against explicit None Address Greptile review on #707: `str(None).strip()` produces the literal string "None", not an empty string. If a stored integration has `{"server": null}` or `{"database": null}`, az.get("server", "") returns None (the default only applies when the key is absent), and str(None).strip() yields "None" — a misleading non-empty string. In practice is_available guards against this, but the extract_params function can be called directly in tests or future code paths and silently produce garbage. Mirror the `or` pattern already applied to port, and match the AzureSQLConfig._normalize_server / _normalize_database validators which use str(value or "").strip(). Added two unit tests covering the None case for both server and database.
References #702
Part 1 of 2. MySQL side ships in a separate PR opened alongside this one.
Summary
Adds the missing
is_availableandextract_paramscallbacks to the@tool(...)decorators on all 5 PostgreSQL diagnostic tools. Before this change, every one of them raisedTypeError: missing 2 required positional arguments: 'host' and 'database'the moment the agent tried to invoke them. Mirrors the existing working pattern used by the MariaDB tool family atapp/integrations/mariadb.py:160-176.What changed
postgresql_is_availableandpostgresql_extract_paramstoapp/integrations/postgresql.py.@tool(...)decorator of all 5 PostgreSQL tools (current queries, replication status, server status, slow queries, table stats).PostgreSQL integration resolves credentials internally via
resolve_postgresql_config(reading from the store/env), soextract_paramsonly surfaces the three identifying params:host,database,port. Credentials stay out of tool signatures and are never seen by the LLM.Scope: 6 files, +61 / -5 lines.
Evidence
Baseline (origin/main @
6b02982, full RDS synthetic suite on Gemini 2.5-flash)make test-rds-synthetic→ 0/15 scenarios passedTypeErrorfailures during the run:get_postgresql_server_status: 92get_postgresql_current_queries: 40get_postgresql_replication_status: 32get_postgresql_table_stats: 20After fix (this branch)
make test-rds-synthetic→ 0 PostgreSQL TypeErrors (was 184)make test-cov→ 2725 passed, 1 skipped, 10 warnings (no regressions)ruff checkon all changed files → cleanmypyon all changed files → cleanTest plan
make test-covpasses with no regressionsruff checkclean on all changed filesmypyclean on all changed filesmake test-rds-syntheticrun shows zero TypeError failures from PostgreSQL tools