Decorators¶
The @geo_tool decorator wraps LangChain's @tool to stamp GeoAgent metadata (category, confirmation requirement, required Python packages, context keys) onto each tool. The metadata is read by the registry and the safety / confirmation bridge.
geoagent.core.decorators
¶
@geo_tool — Strands :func:strands.tool plus GeoAgent metadata.
geo_tool(*, category='general', name=None, description=None, requires_confirmation=False, destructive=False, long_running=False, available_in=('full',), requires_packages=())
¶
Decorate a function as a Strands tool with GeoAgent metadata.
The returned object is a Strands DecoratedFunctionTool. Metadata is
stored on tool._geoagent_meta as :class:GeoToolMeta.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
category |
str |
Logical group ( |
'general' |
name |
str | None |
Optional override for tool name (forwarded via |
None |
description |
str | None |
Optional override; otherwise the docstring is used. |
None |
requires_confirmation |
bool |
If True, host must approve via callback. |
False |
destructive |
bool |
Implies confirmation when True. |
False |
long_running |
bool |
Marks expensive jobs (typically confirmation-required). |
False |
available_in |
Iterable[str] |
Include |
('full',) |
requires_packages |
Iterable[str] |
Skip registering tools when imports fail upstream. |
() |
Source code in geoagent/core/decorators.py
def geo_tool(
*,
category: str = "general",
name: str | None = None,
description: str | None = None,
requires_confirmation: bool = False,
destructive: bool = False,
long_running: bool = False,
available_in: Iterable[str] = ("full",),
requires_packages: Iterable[str] = (),
) -> Callable[[F], Any]:
"""Decorate a function as a Strands tool with GeoAgent metadata.
The returned object is a Strands ``DecoratedFunctionTool``. Metadata is
stored on ``tool._geoagent_meta`` as :class:`GeoToolMeta`.
Args:
category: Logical group (``map``, ``qgis``, ``data``, ...).
name: Optional override for tool name (forwarded via ``@tool(name=...)``).
description: Optional override; otherwise the docstring is used.
requires_confirmation: If True, host must approve via callback.
destructive: Implies confirmation when True.
long_running: Marks expensive jobs (typically confirmation-required).
available_in: Include ``\"fast\"`` for tools exposed in fast mode.
requires_packages: Skip registering tools when imports fail upstream.
"""
def deco(fn: F) -> Any:
"""Attach GeoAgent metadata to the decorated function."""
kwargs: dict[str, Any] = {}
if name is not None:
kwargs["name"] = name
if description is not None:
kwargs["description"] = description
base = strands_tool(**kwargs)(fn)
meta = GeoToolMeta(
name=str(base.tool_name),
description=description or (fn.__doc__ or "").strip(),
category=category,
requires_confirmation=requires_confirmation or destructive,
destructive=destructive,
long_running=long_running,
available_in=tuple(available_in),
requires_packages=tuple(requires_packages),
)
setattr(base, "_geoagent_meta", meta)
return base
return deco
get_geo_meta(tool_obj)
¶
Return GeoAgent metadata as a plain dict for callbacks / UIs.
Source code in geoagent/core/decorators.py
def get_geo_meta(tool_obj: Any) -> dict[str, Any]:
"""Return GeoAgent metadata as a plain dict for callbacks / UIs."""
meta: GeoToolMeta | None = getattr(tool_obj, "_geoagent_meta", None)
if meta is None:
return {}
return {
"category": meta.category,
"requires_confirmation": meta.requires_confirmation,
"destructive": meta.destructive,
"long_running": meta.long_running,
"available_in": meta.available_in,
"requires_packages": meta.requires_packages,
**meta.extra,
}
needs_confirmation(tool_obj)
¶
Return True if tool should use the confirmation callback.
Source code in geoagent/core/decorators.py
def needs_confirmation(tool_obj: Any) -> bool:
"""Return True if tool should use the confirmation callback."""
meta: GeoToolMeta | None = getattr(tool_obj, "_geoagent_meta", None)
if meta is None:
return False
return bool(meta.requires_confirmation or meta.destructive or meta.long_running)
stamp_geo_meta(tool_obj, **fields)
¶
Attach or merge :class:GeoToolMeta fields on a Strands tool.
Source code in geoagent/core/decorators.py
def stamp_geo_meta(tool_obj: Any, **fields: Any) -> Any:
"""Attach or merge :class:`GeoToolMeta` fields on a Strands tool."""
meta: GeoToolMeta | None = getattr(tool_obj, "_geoagent_meta", None)
if meta is None:
name = getattr(tool_obj, "tool_name", "unknown")
meta = GeoToolMeta(name=str(name))
for k, v in fields.items():
if hasattr(meta, k):
setattr(meta, k, v)
setattr(tool_obj, "_geoagent_meta", meta)
return tool_obj