guv3-add-tool

Adds a new tool to an existing agent in guv3. Use when the user says "add a tool", "create a tool for X agent", "agrega una herramienta", "crea una tool que haga Y", "new tool for appointment assistant", or needs to add functionality to an existing agent. Do NOT use for creating new agents (use guv3-new-agent instead).

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "guv3-add-tool" with this command: npx skills add unggamx/ungga-skills/unggamx-ungga-skills-guv3-add-tool

Add Tool to Existing Agent in guv3

Overview

Tools in guv3 are decorated Python functions that agents invoke via LLM tool-calling. Adding a tool requires changes in 2-3 files depending on scope.

File Locations

ScopeLocationWhen to use
Agent-specific toolgu/agents/{agent_name}/nodes/tools.pyTool only used by one agent
Global/shared toolgu/tools/global_tools.pyTool reused across multiple agents
Arg schemasgu/tools/schemas/schemas.pyWhen tool has structured args
Tool helpersgu/tools/tool_helpers.pyPure helper functions (no @tool decorator)

Step 1: Define the Arg Schema (if needed)

File: gu/tools/schemas/schemas.py

from typing import List, Optional
from pydantic import BaseModel, Field
from enum import Enum

# For tools with no args
class DefaultEmptyArgs(BaseModel):
    "Default empty args"

# For tools with structured args
class YourToolArgs(BaseModel):
    param1: Optional[str] = Field(
        default=None,
        description="Description the LLM sees to understand this param"
    )
    param2: Optional[int] = Field(
        default=0,
        description="Another parameter"
    )
    param3: Optional[List[str]] = Field(
        default=None,
        description="List parameter"
    )

# For restricted values, use Enum
class OperationType(str, Enum):
    VENTA = "Venta"
    RENTA = "Renta"

Rules:

  • Every Field MUST have a description — this is what the LLM reads to understand the parameter
  • Use Optional[type] = Field(default=...) for all parameters
  • Descriptions can be multi-line with explicit allowed values

Step 2: Create the Tool Function

File: gu/agents/{agent_name}/nodes/tools.py

from langchain_core.tools import tool
from langchain_core.runnables import RunnableConfig
from loguru import logger
from gu.helpers.helpers import get_user, get_bot, update_user
from gu.db.connections.mongo import find_one, find, update_one, insert_one
from gu.core.notification_functions import (
    send_whatsapp_message,
    send_notification_to_owner,
    save_chat,
)
from gu.tools.schemas.schemas import YourToolArgs


@tool(args_schema=YourToolArgs)
def your_tool_name(
    param1: str = None,
    param2: int = 0,
    *,
    config: RunnableConfig,
):
    """Clear description of what this tool does.

    Use this when [specific scenario].

    Args:
        param1: Description
        param2: Description
    """
    try:
        # 1. Get user and bot context
        user = get_user(config)
        if not user:
            logger.error("[your_tool_name] No user found")
            return ""
        bot = get_bot(config)

        lead_id = user.get("lead_id")
        phone_number = user.get("phone_number")
        owner_firebase_id = user.get("owner_firebase_id")

        # 2. Your business logic here

        # 3. Database operations (if needed)
        result = find_one("collection_name", {"field": value})
        update_one(
            "collection_name",
            {"field": value},
            {"$set": {"updated_field": new_value}}
        )

        # 4. Send notifications (if needed)
        save_chat(lead_id, "Message text", "Gu")

        # 5. Return user-facing message
        return "Response the LLM will use to reply to the user"

    except Exception as e:
        logger.error(f"Error in your_tool_name: {e}")
        return "User-friendly error message"

Critical Rules

Config parameter

# CORRECT — keyword-only after *
def my_tool(param1: str, *, config: RunnableConfig):

# WRONG — positional parameter
def my_tool(param1: str, config: RunnableConfig):

Return values

# CORRECT — always return strings
return "Tu cita ha sido actualizada"
return ""  # empty string on error (LLM handles gracefully)

# WRONG — raising exceptions
raise ValueError("Bad input")  # crashes the tool node

Accessing user data

user = get_user(config)
# Common fields:
user.get("lead_id")              # User identifier
user.get("phone_number")         # WhatsApp number
user.get("owner_firebase_id")    # Owner ID
user.get("last_property_info")   # Current property dict
user.get("country_iso")          # "MEX", "PER", "DOM", etc.
user.get("is_agent")             # True/False
user.get("name")                 # User name
user.get("email")                # User email

bot = get_bot(config)
bot.get("bot_number")            # Bot WhatsApp number
bot.get("bot_phone_number")      # Bot phone number

Database operations

from gu.db.connections.mongo import find_one, find, update_one, insert_one
from gu.config.config import MONGO_DB_NAME_V1

# Query single document
doc = find_one("appointments", {"appointment_id": appt_id})

# Query multiple documents
docs = find("appointments", {"lead_id": lead_id, "status": {"$ne": "cancelled"}})

# Update document
update_one("appointments", {"appointment_id": appt_id}, {"$set": {"status": "confirmed"}})

# Query different database
doc = find_one("property_data", {"firebase_id": prop_id}, MONGO_DB_NAME_V1)

WhatsApp notifications

from gu.core.notification_functions import (
    send_whatsapp_message,          # Send text message
    send_whatsapp_message_audio,    # Send audio message
    send_contact_of_owner,          # Send owner contact card
    send_notification_to_owner,     # Notify the property owner
    save_chat,                      # Save to chat history
)

# Send text
send_whatsapp_message(bot, user, "Your message")

# Send audio
from gu.helpers.helpers import text_to_audio
audio = text_to_audio("Message text", config)
send_whatsapp_message_audio(bot, user, audio)

# Notify owner
send_notification_to_owner({
    "user": user,
    "question": question,
    "template": TEMPLATE_NAME,
    "bot_phone_number": bot.get("bot_number"),
    "property_id": property_id,
})

# Save to chat history
save_chat(lead_id, "Message", "Gu")  # "Gu" or "User"

Step 3: Add to the Tools List

At the bottom of the same tools.py file:

tools = [
    existing_tool_1,
    existing_tool_2,
    your_tool_name,  # ADD HERE
]

That's it for agent-specific tools. No other files need changes.

Step 4: Global Tools (if sharing across agents)

If the tool needs to be used by multiple agents, define it in gu/tools/global_tools.py instead, then import it in each agent's tools.py:

# In gu/agents/{agent_name}/nodes/tools.py
from gu.tools.global_tools import your_shared_tool

tools = [
    your_shared_tool,
    # ... other tools
]

Tool Helpers (non-decorated functions)

For reusable logic that isn't a tool itself, add to gu/tools/tool_helpers.py:

# In tool_helpers.py — no @tool decorator
def calculate_something(user, property_info):
    """Helper function used by multiple tools."""
    # Logic here
    return result

# In tools.py — import and use inside a tool
from gu.tools.tool_helpers import calculate_something

@tool(args_schema=SomeArgs)
def my_tool(*, config: RunnableConfig):
    user = get_user(config)
    result = calculate_something(user, user.get("last_property_info"))
    return str(result)

Checklist

  • Schema defined in gu/tools/schemas/schemas.py (if needed)
  • Tool function created with @tool(args_schema=...) decorator
  • config: RunnableConfig is keyword-only (after *)
  • Tool returns strings only
  • User validation with get_user(config)
  • Error handling with try/except returning user-friendly message
  • Tool added to tools = [...] list
  • Tool docstring describes when the LLM should use it

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Automation

Content Id Guide

A calm way for creators to understand and organize automated content claims across platforms, so nothing important gets missed.

Registry SourceRecently Updated
2.3K1Profile unavailable
Automation

Agent101 Tool Directory

Open directory of 500+ tools, APIs, and services for AI agents. Fetch any category page to get structured tool metadata with auth, free_tier, actions, input/...

Registry SourceRecently Updated
1191Profile unavailable
Automation

tools

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

Agent Reach Setup

提供Agent Reach 1.3.0的完整安装与配置流程,支持7个核心渠道和常见问题诊断,适用于OpenClaw和Claude Code环境。

Registry SourceRecently Updated
3350Profile unavailable