Skip to content

Factory

geoagent.core.factory

Build :class:strands.agent.agent.Agent and :class:geoagent.GeoAgent instances.

assemble_tools(*, context, extra_tools=None, include_leafmap=False, include_anymap=False, include_qgis=False, include_nasa_earthdata=False, include_nasa_opera=False, include_gee_data_catalogs=False, include_timelapse=False, include_vantor=False, include_whitebox=False, include_stac=False, include_geoai=False, include_hypercoast=False, include_image_generation=False, nasa_earthdata_plugin=None, gee_data_catalogs_plugin=None, timelapse_plugin=None, vantor_plugin=None, geoai_plugin=None, hypercoast_plugin=None, fast=False, permission_profile=None, exclude_tool_names=None)

Collect tools for a context and build a metadata registry.

Source code in geoagent/core/factory.py
def assemble_tools(
    *,
    context: GeoAgentContext,
    extra_tools: Optional[list[Any]] = None,
    include_leafmap: bool = False,
    include_anymap: bool = False,
    include_qgis: bool = False,
    include_nasa_earthdata: bool = False,
    include_nasa_opera: bool = False,
    include_gee_data_catalogs: bool = False,
    include_timelapse: bool = False,
    include_vantor: bool = False,
    include_whitebox: bool = False,
    include_stac: bool = False,
    include_geoai: bool = False,
    include_hypercoast: bool = False,
    include_image_generation: bool = False,
    nasa_earthdata_plugin: Any | None = None,
    gee_data_catalogs_plugin: Any | None = None,
    timelapse_plugin: Any | None = None,
    vantor_plugin: Any | None = None,
    geoai_plugin: Any | None = None,
    hypercoast_plugin: Any | None = None,
    fast: bool = False,
    permission_profile: str | None = None,
    exclude_tool_names: set[str] | None = None,
) -> tuple[list[Any], GeoToolRegistry]:
    """Collect tools for a context and build a metadata registry."""
    registry = GeoToolRegistry()
    collected: list[Any] = []
    if include_leafmap and context.map_obj is not None:
        lt = _filter_by_imports(leafmap_tools(context.map_obj))
        register_all_tools(registry, lt)
        collected.extend(lt)
    if include_anymap and context.map_obj is not None:
        at = _filter_by_imports(anymap_tools(context.map_obj))
        register_all_tools(registry, at)
        collected.extend(at)
    if include_qgis:
        qt = _filter_by_imports(qgis_tools(context.qgis_iface, context.qgis_project))
        register_all_tools(registry, qt)
        collected.extend(qt)
    if include_nasa_earthdata:
        earthdata_tool_list = _filter_by_imports(
            earthdata_tools(
                context.qgis_iface,
                context.qgis_project,
                plugin=nasa_earthdata_plugin,
            )
        )
        register_all_tools(registry, earthdata_tool_list)
        collected.extend(earthdata_tool_list)
    if include_nasa_opera:
        opera_tools = _filter_by_imports(
            nasa_opera_tools(context.qgis_iface, context.qgis_project)
        )
        register_all_tools(registry, opera_tools)
        collected.extend(opera_tools)
    if include_gee_data_catalogs:
        gee_tools = _filter_by_imports(
            gee_data_catalogs_tools(
                context.qgis_iface,
                plugin=gee_data_catalogs_plugin,
            )
        )
        register_all_tools(registry, gee_tools)
        collected.extend(gee_tools)
    if include_timelapse:
        timelapse_tool_list = _filter_by_imports(
            timelapse_tools(
                context.qgis_iface,
                context.qgis_project,
                plugin=timelapse_plugin,
            )
        )
        register_all_tools(registry, timelapse_tool_list)
        collected.extend(timelapse_tool_list)
    if include_vantor:
        vantor_tool_list = _filter_by_imports(
            vantor_tools(
                context.qgis_iface,
                context.qgis_project,
                plugin=vantor_plugin,
            )
        )
        register_all_tools(registry, vantor_tool_list)
        collected.extend(vantor_tool_list)
    if include_whitebox:
        whitebox_tool_list = _filter_by_imports(
            whitebox_tools(context.qgis_iface, context.qgis_project)
        )
        register_all_tools(registry, whitebox_tool_list)
        collected.extend(whitebox_tool_list)
    if include_stac:
        stac_tool_list = _filter_by_imports(
            stac_tools(context.qgis_iface, context.qgis_project)
        )
        register_all_tools(registry, stac_tool_list)
        collected.extend(stac_tool_list)
    if include_geoai:
        geoai_tool_list = _filter_by_imports(
            geoai_tools(
                context.qgis_iface,
                context.qgis_project,
                plugin=geoai_plugin,
            )
        )
        register_all_tools(registry, geoai_tool_list)
        collected.extend(geoai_tool_list)
    if include_hypercoast:
        hypercoast_tool_list = _filter_by_imports(
            hypercoast_tools(
                context.qgis_iface,
                context.qgis_project,
                plugin=hypercoast_plugin,
            )
        )
        register_all_tools(registry, hypercoast_tool_list)
        collected.extend(hypercoast_tool_list)
    if include_image_generation:
        image_tools = _filter_by_imports(image_generation_tools())
        register_all_tools(registry, image_tools)
        collected.extend(image_tools)
    if extra_tools:
        register_all_tools(registry, extra_tools)
        collected.extend(extra_tools)
    effective_exclude_tool_names = set(exclude_tool_names or set())
    if include_hypercoast:
        effective_exclude_tool_names.add("add_raster_layer")
    collected = _filter_by_permission(collected, permission_profile)
    collected = _drop_tools_by_name(collected, effective_exclude_tool_names)
    tools = collect_tools_for_context(collected, fast=fast, registry=registry)
    return tools, registry

create_agent(*, context=None, tools=None, config=None, model=None, provider=None, model_id=None, fast=False, confirm=None)

Create a :class:GeoAgent with explicit tools and optional model.

Source code in geoagent/core/factory.py
def create_agent(
    *,
    context: GeoAgentContext | None = None,
    tools: list[Any] | None = None,
    config: GeoAgentConfig | None = None,
    model: Any | None = None,
    provider: str | None = None,
    model_id: str | None = None,
    fast: bool = False,
    confirm: ConfirmCallback | None = None,
) -> GeoAgent:
    """Create a :class:`GeoAgent` with explicit tools and optional model."""
    ctx = context or GeoAgentContext()
    cfg = config or GeoAgentConfig()
    if provider is not None:
        cfg = cfg.model_copy(update={"provider": provider})
    if model_id is not None:
        cfg = cfg.model_copy(update={"model": model_id})
    registry = GeoToolRegistry()
    tool_list = _filter_by_imports(list(tools or []))
    register_all_tools(registry, tool_list)
    tool_list = collect_tools_for_context(tool_list, fast=fast, registry=registry)
    return GeoAgent(
        context=ctx,
        config=cfg,
        tools=tool_list,
        registry=registry,
        model=model,
        provider=provider,
        model_id=model_id,
        fast=fast,
        confirm=confirm,
    )

for_anymap(m, *, config=None, model=None, provider=None, model_id=None, fast=False, confirm=None, extra_tools=None)

Bind an agent to an anymap map instance.

Source code in geoagent/core/factory.py
def for_anymap(
    m: Any,
    *,
    config: GeoAgentConfig | None = None,
    model: Any | None = None,
    provider: str | None = None,
    model_id: str | None = None,
    fast: bool = False,
    confirm: ConfirmCallback | None = None,
    extra_tools: Optional[list[Any]] = None,
) -> GeoAgent:
    """Bind an agent to an anymap map instance."""
    ctx = GeoAgentContext(map_obj=m)
    tools, registry = assemble_tools(
        context=ctx,
        include_anymap=True,
        include_image_generation=True,
        extra_tools=extra_tools,
        fast=fast,
    )
    cfg = config or GeoAgentConfig()
    if provider is not None:
        cfg = cfg.model_copy(update={"provider": provider})
    if model_id is not None:
        cfg = cfg.model_copy(update={"model": model_id})
    return GeoAgent(
        context=ctx,
        config=cfg,
        tools=tools,
        registry=registry,
        model=model,
        provider=provider,
        model_id=model_id,
        fast=fast,
        confirm=confirm,
    )

for_browser_maplibre(session, *, config=None, model=None, provider=None, model_id=None, fast=False, confirm=None, extra_tools=None, allow_browser_code=False)

Bind an agent to a MapLibre map running in a browser session.

Source code in geoagent/core/factory.py
def for_browser_maplibre(
    session: Any,
    *,
    config: GeoAgentConfig | None = None,
    model: Any | None = None,
    provider: str | None = None,
    model_id: str | None = None,
    fast: bool = False,
    confirm: ConfirmCallback | None = None,
    extra_tools: Optional[list[Any]] = None,
    allow_browser_code: bool = False,
) -> GeoAgent:
    """Bind an agent to a MapLibre map running in a browser session."""
    system_prompt = BROWSER_MAPLIBRE_SYSTEM_PROMPT
    if allow_browser_code:
        system_prompt = f"{system_prompt}\n\n{BROWSER_MAPLIBRE_CODE_SYSTEM_PROMPT}"
    ctx = GeoAgentContext(
        metadata={
            "integration": "browser_maplibre",
            "system_prompt": system_prompt,
        }
    )
    tool_list = _filter_by_imports(
        browser_maplibre_tools(session, allow_code=allow_browser_code)
    )
    if extra_tools:
        tool_list.extend(extra_tools)
    registry = GeoToolRegistry()
    register_all_tools(registry, tool_list)
    tools = collect_tools_for_context(tool_list, fast=fast, registry=registry)
    cfg = config or GeoAgentConfig()
    if provider is not None:
        cfg = cfg.model_copy(update={"provider": provider})
    if model_id is not None:
        cfg = cfg.model_copy(update={"model": model_id})
    return GeoAgent(
        context=ctx,
        config=cfg,
        tools=tools,
        registry=registry,
        model=model,
        provider=provider,
        model_id=model_id,
        fast=fast,
        confirm=confirm,
    )

for_gee_data_catalogs(iface, project=None, *, plugin=None, config=None, model=None, provider=None, model_id=None, fast=False, confirm=None, extra_tools=None, include_qgis=True, permission_profile=None)

Bind an agent to the QGIS GEE Data Catalogs plugin runtime.

The factory exposes native GEE Data Catalogs tools and, by default, the general QGIS map/project tools used for navigation and layer management.

Source code in geoagent/core/factory.py
def for_gee_data_catalogs(
    iface: Any,
    project: Any = None,
    *,
    plugin: Any | None = None,
    config: GeoAgentConfig | None = None,
    model: Any | None = None,
    provider: str | None = None,
    model_id: str | None = None,
    fast: bool = False,
    confirm: ConfirmCallback | None = None,
    extra_tools: Optional[list[Any]] = None,
    include_qgis: bool = True,
    permission_profile: str | None = None,
) -> GeoAgent:
    """Bind an agent to the QGIS GEE Data Catalogs plugin runtime.

    The factory exposes native GEE Data Catalogs tools and, by default, the
    general QGIS map/project tools used for navigation and layer management.
    """
    ctx = GeoAgentContext(
        qgis_iface=iface,
        qgis_project=project,
        metadata={
            "integration": "gee_data_catalogs",
            "system_prompt": GEE_DATA_CATALOGS_SYSTEM_PROMPT,
        },
    )
    tools, registry = assemble_tools(
        context=ctx,
        include_qgis=include_qgis,
        include_gee_data_catalogs=True,
        include_image_generation=True,
        gee_data_catalogs_plugin=plugin,
        extra_tools=extra_tools,
        fast=fast,
        permission_profile=permission_profile,
        exclude_tool_names={"set_layer_symbology"} if include_qgis else set(),
    )
    cfg = config or GeoAgentConfig()
    if provider is not None:
        cfg = cfg.model_copy(update={"provider": provider})
    if model_id is not None:
        cfg = cfg.model_copy(update={"model": model_id})
    return GeoAgent(
        context=ctx,
        config=cfg,
        tools=tools,
        registry=registry,
        model=model,
        provider=provider,
        model_id=model_id,
        fast=fast,
        confirm=confirm,
        qgis_safe_mode=True,
    )

for_geoai(iface, project=None, *, plugin=None, config=None, model=None, provider=None, model_id=None, fast=False, confirm=None, extra_tools=None, include_qgis=True, permission_profile=None)

Bind an agent to QGIS with GeoAI SamGeo segmentation support.

The factory exposes GeoAI plugin-backed SamGeo text-prompt segmentation and, by default, the general QGIS map/project tools used for inspection and navigation.

Source code in geoagent/core/factory.py
def for_geoai(
    iface: Any,
    project: Any = None,
    *,
    plugin: Any | None = None,
    config: GeoAgentConfig | None = None,
    model: Any | None = None,
    provider: str | None = None,
    model_id: str | None = None,
    fast: bool = False,
    confirm: ConfirmCallback | None = None,
    extra_tools: Optional[list[Any]] = None,
    include_qgis: bool = True,
    permission_profile: str | None = None,
) -> GeoAgent:
    """Bind an agent to QGIS with GeoAI SamGeo segmentation support.

    The factory exposes GeoAI plugin-backed SamGeo text-prompt segmentation
    and, by default, the general QGIS map/project tools used for inspection
    and navigation.
    """
    ctx = GeoAgentContext(
        qgis_iface=iface,
        qgis_project=project,
        metadata={
            "integration": "geoai",
            "system_prompt": GEOAI_SYSTEM_PROMPT,
        },
    )
    tools, registry = assemble_tools(
        context=ctx,
        include_qgis=include_qgis,
        include_geoai=True,
        include_image_generation=True,
        geoai_plugin=plugin,
        extra_tools=extra_tools,
        fast=fast,
        permission_profile=permission_profile,
    )
    cfg = config or GeoAgentConfig()
    if provider is not None:
        cfg = cfg.model_copy(update={"provider": provider})
    if model_id is not None:
        cfg = cfg.model_copy(update={"model": model_id})
    return GeoAgent(
        context=ctx,
        config=cfg,
        tools=tools,
        registry=registry,
        model=model,
        provider=provider,
        model_id=model_id,
        fast=fast,
        confirm=confirm,
        qgis_safe_mode=True,
    )

for_hypercoast(iface, project=None, *, plugin=None, config=None, model=None, provider=None, model_id=None, fast=False, confirm=None, extra_tools=None, include_qgis=True, permission_profile=None)

Bind an agent to the QGIS HyperCoast plugin runtime.

The factory exposes native HyperCoast search, download, and visualization tools and, by default, the general QGIS map/project tools used for inspection and navigation.

Source code in geoagent/core/factory.py
def for_hypercoast(
    iface: Any,
    project: Any = None,
    *,
    plugin: Any | None = None,
    config: GeoAgentConfig | None = None,
    model: Any | None = None,
    provider: str | None = None,
    model_id: str | None = None,
    fast: bool = False,
    confirm: ConfirmCallback | None = None,
    extra_tools: Optional[list[Any]] = None,
    include_qgis: bool = True,
    permission_profile: str | None = None,
) -> GeoAgent:
    """Bind an agent to the QGIS HyperCoast plugin runtime.

    The factory exposes native HyperCoast search, download, and visualization
    tools and, by default, the general QGIS map/project tools used for
    inspection and navigation.
    """
    ctx = GeoAgentContext(
        qgis_iface=iface,
        qgis_project=project,
        metadata={
            "integration": "hypercoast",
            "system_prompt": HYPERCOAST_SYSTEM_PROMPT,
        },
    )
    tools, registry = assemble_tools(
        context=ctx,
        include_qgis=include_qgis,
        include_hypercoast=True,
        include_image_generation=True,
        hypercoast_plugin=plugin,
        extra_tools=extra_tools,
        fast=fast,
        permission_profile=permission_profile,
    )
    cfg = config or GeoAgentConfig()
    if provider is not None:
        cfg = cfg.model_copy(update={"provider": provider})
    if model_id is not None:
        cfg = cfg.model_copy(update={"model": model_id})
    return GeoAgent(
        context=ctx,
        config=cfg,
        tools=tools,
        registry=registry,
        model=model,
        provider=provider,
        model_id=model_id,
        fast=fast,
        confirm=confirm,
        qgis_safe_mode=True,
    )

for_leafmap(m, *, config=None, model=None, provider=None, model_id=None, fast=False, confirm=None, extra_tools=None)

Bind an agent to a leafmap-compatible map instance.

Source code in geoagent/core/factory.py
def for_leafmap(
    m: Any,
    *,
    config: GeoAgentConfig | None = None,
    model: Any | None = None,
    provider: str | None = None,
    model_id: str | None = None,
    fast: bool = False,
    confirm: ConfirmCallback | None = None,
    extra_tools: Optional[list[Any]] = None,
) -> GeoAgent:
    """Bind an agent to a leafmap-compatible map instance."""
    ctx = GeoAgentContext(map_obj=m)
    tools, registry = assemble_tools(
        context=ctx,
        include_leafmap=True,
        include_image_generation=True,
        extra_tools=extra_tools,
        fast=fast,
    )
    cfg = config or GeoAgentConfig()
    if provider is not None:
        cfg = cfg.model_copy(update={"provider": provider})
    if model_id is not None:
        cfg = cfg.model_copy(update={"model": model_id})
    return GeoAgent(
        context=ctx,
        config=cfg,
        tools=tools,
        registry=registry,
        model=model,
        provider=provider,
        model_id=model_id,
        fast=fast,
        confirm=confirm,
    )

for_nasa_earthdata(iface, project=None, *, plugin=None, config=None, model=None, provider=None, model_id=None, fast=False, confirm=None, extra_tools=None, include_qgis=True, permission_profile=None)

Bind an agent to the NASA Earthdata QGIS plugin runtime.

The factory exposes native NASA Earthdata tools and, by default, the general QGIS map/project tools used for navigation and layer management.

Source code in geoagent/core/factory.py
def for_nasa_earthdata(
    iface: Any,
    project: Any = None,
    *,
    plugin: Any | None = None,
    config: GeoAgentConfig | None = None,
    model: Any | None = None,
    provider: str | None = None,
    model_id: str | None = None,
    fast: bool = False,
    confirm: ConfirmCallback | None = None,
    extra_tools: Optional[list[Any]] = None,
    include_qgis: bool = True,
    permission_profile: str | None = None,
) -> GeoAgent:
    """Bind an agent to the NASA Earthdata QGIS plugin runtime.

    The factory exposes native NASA Earthdata tools and, by default, the
    general QGIS map/project tools used for navigation and layer management.
    """
    ctx = GeoAgentContext(
        qgis_iface=iface,
        qgis_project=project,
        metadata={
            "integration": "nasa_earthdata",
            "system_prompt": NASA_EARTHDATA_SYSTEM_PROMPT,
        },
    )
    tools, registry = assemble_tools(
        context=ctx,
        include_qgis=include_qgis,
        include_nasa_earthdata=True,
        include_image_generation=True,
        nasa_earthdata_plugin=plugin,
        extra_tools=extra_tools,
        fast=fast,
        permission_profile=permission_profile,
    )
    cfg = config or GeoAgentConfig()
    if provider is not None:
        cfg = cfg.model_copy(update={"provider": provider})
    if model_id is not None:
        cfg = cfg.model_copy(update={"model": model_id})
    return GeoAgent(
        context=ctx,
        config=cfg,
        tools=tools,
        registry=registry,
        model=model,
        provider=provider,
        model_id=model_id,
        fast=fast,
        confirm=confirm,
        qgis_safe_mode=True,
    )

for_nasa_opera(iface, project=None, *, config=None, model=None, provider=None, model_id=None, fast=False, confirm=None, extra_tools=None, include_qgis=True, permission_profile=None)

Bind an agent to the NASA OPERA QGIS plugin runtime.

The factory exposes native GeoAgent OPERA tools and, by default, the general QGIS map/project tools used for navigation and layer management.

Source code in geoagent/core/factory.py
def for_nasa_opera(
    iface: Any,
    project: Any = None,
    *,
    config: GeoAgentConfig | None = None,
    model: Any | None = None,
    provider: str | None = None,
    model_id: str | None = None,
    fast: bool = False,
    confirm: ConfirmCallback | None = None,
    extra_tools: Optional[list[Any]] = None,
    include_qgis: bool = True,
    permission_profile: str | None = None,
) -> GeoAgent:
    """Bind an agent to the NASA OPERA QGIS plugin runtime.

    The factory exposes native GeoAgent OPERA tools and, by default, the
    general QGIS map/project tools used for navigation and layer management.
    """
    ctx = GeoAgentContext(
        qgis_iface=iface,
        qgis_project=project,
        metadata={
            "integration": "nasa_opera",
            "system_prompt": NASA_OPERA_SYSTEM_PROMPT,
        },
    )
    tools, registry = assemble_tools(
        context=ctx,
        include_qgis=include_qgis,
        include_nasa_opera=True,
        include_image_generation=True,
        extra_tools=extra_tools,
        fast=fast,
        permission_profile=permission_profile,
    )
    cfg = config or GeoAgentConfig()
    if provider is not None:
        cfg = cfg.model_copy(update={"provider": provider})
    if model_id is not None:
        cfg = cfg.model_copy(update={"model": model_id})
    return GeoAgent(
        context=ctx,
        config=cfg,
        tools=tools,
        registry=registry,
        model=model,
        provider=provider,
        model_id=model_id,
        fast=fast,
        confirm=confirm,
        qgis_safe_mode=True,
    )

for_qgis(iface, project=None, *, config=None, model=None, provider=None, model_id=None, fast=False, confirm=None, extra_tools=None, permission_profile=None)

Bind an agent to QGIS iface (and optional project).

Source code in geoagent/core/factory.py
def for_qgis(
    iface: Any,
    project: Any = None,
    *,
    config: GeoAgentConfig | None = None,
    model: Any | None = None,
    provider: str | None = None,
    model_id: str | None = None,
    fast: bool = False,
    confirm: ConfirmCallback | None = None,
    extra_tools: Optional[list[Any]] = None,
    permission_profile: str | None = None,
) -> GeoAgent:
    """Bind an agent to QGIS ``iface`` (and optional ``project``)."""
    ctx = GeoAgentContext(
        qgis_iface=iface,
        qgis_project=project,
        metadata={"system_prompt": QGIS_SYSTEM_PROMPT},
    )
    tools, registry = assemble_tools(
        context=ctx,
        include_qgis=True,
        include_image_generation=True,
        extra_tools=extra_tools,
        fast=fast,
        permission_profile=permission_profile,
    )
    cfg = config or GeoAgentConfig()
    if provider is not None:
        cfg = cfg.model_copy(update={"provider": provider})
    if model_id is not None:
        cfg = cfg.model_copy(update={"model": model_id})
    return GeoAgent(
        context=ctx,
        config=cfg,
        tools=tools,
        registry=registry,
        model=model,
        provider=provider,
        model_id=model_id,
        fast=fast,
        confirm=confirm,
        qgis_safe_mode=True,
    )

for_stac(iface=None, project=None, *, config=None, model=None, provider=None, model_id=None, fast=False, confirm=None, extra_tools=None, include_qgis=True, permission_profile=None)

Bind an agent to STAC catalog workflows and optional QGIS loading.

Source code in geoagent/core/factory.py
def for_stac(
    iface: Any = None,
    project: Any = None,
    *,
    config: GeoAgentConfig | None = None,
    model: Any | None = None,
    provider: str | None = None,
    model_id: str | None = None,
    fast: bool = False,
    confirm: ConfirmCallback | None = None,
    extra_tools: Optional[list[Any]] = None,
    include_qgis: bool = True,
    permission_profile: str | None = None,
) -> GeoAgent:
    """Bind an agent to STAC catalog workflows and optional QGIS loading."""
    ctx = GeoAgentContext(
        qgis_iface=iface,
        qgis_project=project,
        metadata={
            "integration": "stac",
            "system_prompt": STAC_SYSTEM_PROMPT,
        },
    )
    tools, registry = assemble_tools(
        context=ctx,
        include_qgis=include_qgis,
        include_stac=True,
        include_image_generation=True,
        extra_tools=extra_tools,
        fast=fast,
        permission_profile=permission_profile,
        exclude_tool_names={"run_pyqgis_script"},
    )
    cfg = config or GeoAgentConfig()
    if provider is not None:
        cfg = cfg.model_copy(update={"provider": provider})
    if model_id is not None:
        cfg = cfg.model_copy(update={"model": model_id})
    return GeoAgent(
        context=ctx,
        config=cfg,
        tools=tools,
        registry=registry,
        model=model,
        provider=provider,
        model_id=model_id,
        fast=fast,
        confirm=confirm,
        qgis_safe_mode=iface is not None,
    )

for_timelapse(iface, project=None, *, plugin=None, config=None, model=None, provider=None, model_id=None, fast=False, confirm=None, extra_tools=None, include_qgis=True, permission_profile=None)

Bind an agent to the QGIS Timelapse plugin runtime.

The factory exposes native Timelapse tools and, by default, the general QGIS map/project tools used for inspection and navigation.

Source code in geoagent/core/factory.py
def for_timelapse(
    iface: Any,
    project: Any = None,
    *,
    plugin: Any | None = None,
    config: GeoAgentConfig | None = None,
    model: Any | None = None,
    provider: str | None = None,
    model_id: str | None = None,
    fast: bool = False,
    confirm: ConfirmCallback | None = None,
    extra_tools: Optional[list[Any]] = None,
    include_qgis: bool = True,
    permission_profile: str | None = None,
) -> GeoAgent:
    """Bind an agent to the QGIS Timelapse plugin runtime.

    The factory exposes native Timelapse tools and, by default, the general
    QGIS map/project tools used for inspection and navigation.
    """
    ctx = GeoAgentContext(
        qgis_iface=iface,
        qgis_project=project,
        metadata={
            "integration": "timelapse",
            "system_prompt": TIMELAPSE_SYSTEM_PROMPT,
        },
    )
    tools, registry = assemble_tools(
        context=ctx,
        include_qgis=include_qgis,
        include_timelapse=True,
        include_image_generation=True,
        timelapse_plugin=plugin,
        extra_tools=extra_tools,
        fast=fast,
        permission_profile=permission_profile,
    )
    cfg = config or GeoAgentConfig()
    if provider is not None:
        cfg = cfg.model_copy(update={"provider": provider})
    if model_id is not None:
        cfg = cfg.model_copy(update={"model": model_id})
    return GeoAgent(
        context=ctx,
        config=cfg,
        tools=tools,
        registry=registry,
        model=model,
        provider=provider,
        model_id=model_id,
        fast=fast,
        confirm=confirm,
        qgis_safe_mode=True,
    )

for_vantor(iface, project=None, *, plugin=None, config=None, model=None, provider=None, model_id=None, fast=False, confirm=None, extra_tools=None, include_qgis=True, permission_profile=None)

Bind an agent to the QGIS Vantor plugin runtime.

The factory exposes native Vantor Open Data STAC tools and, by default, the general QGIS map/project tools used for navigation and layer management.

Source code in geoagent/core/factory.py
def for_vantor(
    iface: Any,
    project: Any = None,
    *,
    plugin: Any | None = None,
    config: GeoAgentConfig | None = None,
    model: Any | None = None,
    provider: str | None = None,
    model_id: str | None = None,
    fast: bool = False,
    confirm: ConfirmCallback | None = None,
    extra_tools: Optional[list[Any]] = None,
    include_qgis: bool = True,
    permission_profile: str | None = None,
) -> GeoAgent:
    """Bind an agent to the QGIS Vantor plugin runtime.

    The factory exposes native Vantor Open Data STAC tools and, by default,
    the general QGIS map/project tools used for navigation and layer
    management.
    """
    ctx = GeoAgentContext(
        qgis_iface=iface,
        qgis_project=project,
        metadata={
            "integration": "vantor",
            "system_prompt": VANTOR_SYSTEM_PROMPT,
        },
    )
    tools, registry = assemble_tools(
        context=ctx,
        include_qgis=include_qgis,
        include_vantor=True,
        include_image_generation=True,
        vantor_plugin=plugin,
        extra_tools=extra_tools,
        fast=fast,
        permission_profile=permission_profile,
    )
    cfg = config or GeoAgentConfig()
    if provider is not None:
        cfg = cfg.model_copy(update={"provider": provider})
    if model_id is not None:
        cfg = cfg.model_copy(update={"model": model_id})
    return GeoAgent(
        context=ctx,
        config=cfg,
        tools=tools,
        registry=registry,
        model=model,
        provider=provider,
        model_id=model_id,
        fast=fast,
        confirm=confirm,
        qgis_safe_mode=True,
    )

for_whitebox(iface, project=None, *, config=None, model=None, provider=None, model_id=None, fast=False, confirm=None, extra_tools=None, include_qgis=True, permission_profile=None)

Bind an agent to QGIS with WhiteboxTools analysis support.

The factory exposes a routed WhiteboxTools broker surface and, by default, the general QGIS map/project tools used for inspection and navigation.

Source code in geoagent/core/factory.py
def for_whitebox(
    iface: Any,
    project: Any = None,
    *,
    config: GeoAgentConfig | None = None,
    model: Any | None = None,
    provider: str | None = None,
    model_id: str | None = None,
    fast: bool = False,
    confirm: ConfirmCallback | None = None,
    extra_tools: Optional[list[Any]] = None,
    include_qgis: bool = True,
    permission_profile: str | None = None,
) -> GeoAgent:
    """Bind an agent to QGIS with WhiteboxTools analysis support.

    The factory exposes a routed WhiteboxTools broker surface and, by default,
    the general QGIS map/project tools used for inspection and navigation.
    """
    ctx = GeoAgentContext(
        qgis_iface=iface,
        qgis_project=project,
        metadata={
            "integration": "whitebox",
            "system_prompt": WHITEBOX_SYSTEM_PROMPT,
        },
    )
    tools, registry = assemble_tools(
        context=ctx,
        include_qgis=include_qgis,
        include_whitebox=True,
        include_image_generation=True,
        extra_tools=extra_tools,
        fast=fast,
        permission_profile=permission_profile,
    )
    cfg = config or GeoAgentConfig()
    if provider is not None:
        cfg = cfg.model_copy(update={"provider": provider})
    if model_id is not None:
        cfg = cfg.model_copy(update={"model": model_id})
    return GeoAgent(
        context=ctx,
        config=cfg,
        tools=tools,
        registry=registry,
        model=model,
        provider=provider,
        model_id=model_id,
        fast=fast,
        confirm=confirm,
        qgis_safe_mode=True,
    )

register_all_tools(registry, tools)

Populate registry from decorated tools.

Source code in geoagent/core/factory.py
def register_all_tools(registry: GeoToolRegistry, tools: Iterable[Any]) -> None:
    """Populate registry from decorated tools."""
    for t in tools:
        meta = getattr(t, "_geoagent_meta", None)
        if meta is not None:
            registry.register_tool(t, meta)