> For the complete documentation index, see [llms.txt](https://docs.amigo.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.amigo.ai/developer-guide/classic-api/core-api/tools.md).

# Tools

Manage organization-scoped, versioned capabilities ("tools"). This page documents the core API endpoints and expected request/response shapes.

{% hint style="info" %}
**API Terminology**: in the API, these are called "Tools." In our conceptual documentation, we refer to them as "Actions", the execution layer that turns agent reasoning into real-world outcomes. See [Conceptual Docs: Platform Functions](https://docs.amigo.ai/agent/platform-functions) for the architectural perspective. Tools are organization-scoped and versioned; use the OpenAPI embeds below for exact request and response shapes and parameters.
{% endhint %}

{% hint style="info" %}
**Platform API uses Skills instead**: Classic API Tools are versioned code packages from Git. The Platform API uses [Skills](/developer-guide/platform-api/workspaces/skills.md), which are LLM-backed declarative micro-agents. Choose Tools for custom code execution and Skills for LLM-native reasoning.
{% endhint %}

## Scope and Behavior

* All operations are organization-scoped.
* Related operations are serialized per tool. Concurrent publish or deprecate calls on the same tool return HTTP 409.
* Tool output visibility is controlled by the `result_persistence` property configured in Context Graph tool call specifications (see [Tool Result Persistence](#tool-result-persistence)).

## How Tools Work (Actions)

Tools run as versioned actions. At a high level:

* **Versioned builds**: when you publish, the platform builds your tool from the organization's tools repository and creates a new immutable version (semantic versioning).
* **Org-scoped execution**: each organization's tools and versions are isolated and only callable within that org.
* **Managed runtime per execution**: runs execute in a managed environment with the variables you configured for the tool. Tool state is versioned and not persisted between runs.
* **Typed contracts**: your tool project defines inputs, outputs, and checks. Publishing runs validations and fails if required pieces are missing.
* **Configuration first**: environment variables (regular and secret) must exist on the tool before publishing versions that require them. In-use variables cannot be deleted.
* **Rollout control**: publishing adds a new version alongside older ones. You choose when to deprecate specific versions or the entire tool. Deprecation removes those versions from new runs.
* **Observability and traceability**: each version records who published it and the pinned source details. Use your org's monitoring to track latency, errors, and usage by version.

### Execution Modes

Tools have two execution modes, defined by the `invocation_mode` parameter when invoking a tool:

* **`regular`**: Used for production conversations with real users. Tools should perform actual operations (API calls, database updates, external integrations, etc.) in this mode.
* **`conversation-simulation`**: Used for testing and simulation scenarios. Tools may need to mock external calls, use test data, or adjust behavior to avoid side effects during automated testing.

When implementing a tool, handle both modes appropriately in your code. The `invocation_mode` is passed as part of each input in the invocation request and can be accessed within your tool's execution logic to determine the appropriate behavior.

### Tool Entry Point Signature

Your tool implements the scaffold's `run_tool()` method with the following parameters:

```python
from amigo_tool_scaffold.user_variables import UserVariables

def run_tool(
    self,
    input: Input,
    non_secret_env: NonSecretEnv,
    secret_env: SecretEnv,
    mode: InvocationMode,
    user_variables: UserVariables,
) -> str:
    ...
```

| Parameter        | Description                                                                                                 |
| ---------------- | ----------------------------------------------------------------------------------------------------------- |
| `input`          | The typed input parameters passed to the tool                                                               |
| `non_secret_env` | The tool's non-secret environment variables                                                                 |
| `secret_env`     | The tool's secret environment variables                                                                     |
| `mode`           | The invocation mode (`regular` or `conversation-simulation`)                                                |
| `user_variables` | Key-value pairs configured on the user's profile, useful for external system IDs and tool-specific settings |

{% hint style="warning" %}
Tools whose entry point omits the `user_variables` parameter (the older signature) fail CI checks during publishing.
{% endhint %}

#### Typical lifecycle

1. Create the tool (name, description, tags).
2. Add required environment variables for the tool.
3. Test the tool from a branch before publishing.
4. Publish a version from your team branch (choose major/minor/patch).
5. Invoke directly or call from your application/SDK.
6. Query invocation history for debugging and audit.
7. Iterate by publishing new versions; deprecate older ones when ready.

### Workflow (diagram)

```mermaid
%%{init: {"flowchart": {"useMaxWidth": true, "nodeSpacing": 20, "rankSpacing": 30}, "theme": "base", "themeVariables": {"primaryColor": "#D4E2E7", "primaryTextColor": "#100F0F", "primaryBorderColor": "#083241", "lineColor": "#575452", "textColor": "#100F0F", "clusterBkg": "#F1EAE7", "clusterBorder": "#D7D2D0"}}}%%
flowchart TB
  A[Create Tool]
  B[Configure Env Vars]
  C[Test on Branch]
  D[Publish Version]
  E[Version Pinned]
  F[Use from App/SDK]
  G[Direct Invoke]
  H[Tool Executes]
  I[Invocation Recorded]
  J[Query/Search History]
  K[Deprecate Versions]

  A --> B --> C
  C -.iterate.-> B
  C --> D --> E
  E --> F & G
  F & G --> H --> I --> J
  E -.-> K
  K -.-> E

  style C fill:#DDE3DB,stroke:#2c3827,color:#100F0F
  style G fill:#DDE3DB,stroke:#2c3827,color:#100F0F
  style J fill:#DDE3DB,stroke:#2c3827,color:#100F0F
```

## Tool Availability by State

In the standard HSM runtime, the agent sees the tools listed in the current state's tool call specifications, and that state-scoped set changes on transition. Native and realtime runtimes can also attach a runtime-defined set of shared platform or system tools globally. Do not treat state membership as an authorization boundary: runtime authorization, tool enablement, and write-scope checks still decide whether a call can execute.

## Tool Result Persistence

When tools are configured in Context Graphs (API: `service_hierarchical_state_machine`), each tool call specification includes a `result_persistence` property that controls how tool outputs are stored and made available to the agent across interactions.

<details>

<summary>Persistence modes reference table</summary>

### Persistence Modes

The `result_persistence` property can take three values:

| Value                   | Behavior                                                                                                                                                                                                | Use Case                                                                                                                                                    |
| ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `"ephemeral"`           | Tool result is visible only during the current LLM interaction (e.g., parameter generation, action selection) and is **not** persisted in the conversation log for future interactions.                 | Large outputs only needed for immediate decision-making; temporary processing results; intermediate computation steps that don't require long-term context. |
| `"persisted-preferred"` | Tool result is persisted in all future interaction logs **if** output is less than 5k characters. Outputs exceeding 5k characters are automatically treated as ephemeral and excluded from future logs. | Most general-purpose tools where results should be available to the agent when possible, with graceful handling of unexpectedly large outputs.              |
| `"persisted"`           | Tool result is persisted in all future interaction logs **if** output is less than 5k characters. Outputs exceeding 5k characters cause the tool invocation to **throw an error**.                      | Critical tools whose outputs must always be available to the agent; tools designed never to produce large outputs (e.g., status lookups, account queries).  |

</details>

{% hint style="warning" %}
**Persistence Threshold**

The persistence threshold is 5,000 characters for the `"persisted"` and `"persisted-preferred"` modes.
{% endhint %}

<details>

<summary>Configuration by Context Graph state type</summary>

### Configuration

The `result_persistence` property is configured within tool call specifications in your Context Graph state definitions (API: `service_hierarchical_state_machine`). Different state types support tool call specs in different contexts:

| State Type          | Field                                                 | Description                                              |
| ------------------- | ----------------------------------------------------- | -------------------------------------------------------- |
| **ActionState**     | `action_tool_call_specs[].result_persistence`         | Tools used during action execution                       |
| **ActionState**     | `exit_condition_tool_call_specs[].result_persistence` | Tools used when evaluating exit conditions               |
| **DecisionState**   | `tool_call_specs[].result_persistence`                | Helper tools during decision-making                      |
| **ReflectionState** | `tool_call_specs[].result_persistence`                | Helper tools during reflection generation                |
| **ToolCallState**   | `tool_call_specs[].result_persistence`                | Helper tools during designated tool parameter generation |

</details>

#### Example Configuration

```json
{
  "type": "action",
  "name": "customer_support",
  "action_tool_call_specs": [
    {
      "tool_id": "670a1234567890abcdef1234",
      "version_constraint": ">=1.0.0",
      "additional_instruction": "Search the knowledge base for relevant articles",
      "audio_fillers": ["Let me search for that..."],
      "audio_filler_triggered_after": 2.0,
      "result_persistence": "persisted-preferred"
    }
  ]
}
```

### Best Practices

1. **Prefer `"persisted-preferred"` for most tools**: it provides the best balance between context availability and graceful handling of large outputs.
2. **Use `"ephemeral"` for large or transient data**: tools returning large datasets, file contents, or verbose debugging information should use `"ephemeral"` to prevent context bloat and keep agent performance efficient.
3. **Use `"persisted"` for critical context**: tools whose outputs are essential for conversation continuity (user account lookups, order status, entity resolution) should use `"persisted"` to guarantee agent access to results.
4. **Design concise tool outputs**: structure outputs to stay under 5k characters when possible by returning summaries, structured data, or references rather than full raw content.

## Create a Tool

Create a new tool with metadata (name, description, tags).

{% openapi src="<https://api.amigo.ai/v1/openapi.json>" path="/v1/{organization}/tool/" method="post" %}
<https://api.amigo.ai/v1/openapi.json>
{% endopenapi %}

## List Tools

Common filters:

* `id=<id>` (repeatable), `deprecated=true|false`
* `tag=key:value` (repeatable; `value` may be `*`, or empty for null)
* `sort_by=+name|-name|+deprecated|-deprecated` (repeatable)
* `limit` (1-20, default 10), `continuation_token` (int, default 0)

{% openapi src="<https://api.amigo.ai/v1/openapi.json>" path="/v1/{organization}/tool/" method="get" %}
<https://api.amigo.ai/v1/openapi.json>
{% endopenapi %}

## Update a Tool

Update tool metadata (description, tags). Only non-null fields are updated; the tool's name cannot be changed.

{% openapi src="<https://api.amigo.ai/v1/openapi.json>" path="/v1/{organization}/tool/{tool\_id}" method="post" %}
<https://api.amigo.ai/v1/openapi.json>
{% endopenapi %}

## Manage Tool Environment Variables

Notes:

* Names must match `[A-Z_]+`.
* Variables required by any non-deprecated version cannot be deleted.

{% openapi src="<https://api.amigo.ai/v1/openapi.json>" path="/v1/{organization}/tool/{tool\_id}/envvar" method="post" %}
<https://api.amigo.ai/v1/openapi.json>
{% endopenapi %}

## Test a Tool

Test a tool from a specific repository branch without publishing. Runs CI checks and executes the tool with supplied inputs.

{% hint style="info" %}
Each test input must include `input_parameters`, `invocation_mode` (`"regular"` for testing production behavior or `"conversation-simulation"` for testing simulation behavior), `nonsensitive_user_variables`, and `sensitive_user_variables` (the latter two may be empty objects).
{% endhint %}

{% openapi src="<https://api.amigo.ai/v1/openapi.json>" path="/v1/{organization}/tool/test" method="post" %}
<https://api.amigo.ai/v1/openapi.json>
{% endopenapi %}

## Publish a Tool Version

Behavior:

* Computes next semantic version (or `1.0.0` if none), validates, builds, and publishes.
* Long-running (1-5 minutes). Serialized per tool. Returns 409 if a related operation is in progress.
* The request body takes only `project_path` and `bump_type` (`major`, `minor`, or `patch`; use `major` for the first version). Publishing always builds from the organization's team tools repository.

{% hint style="warning" %}
Publishing is a long-running operation (typically 1-5 minutes). Adjust client timeouts accordingly.
{% endhint %}

{% openapi src="<https://api.amigo.ai/v1/openapi.json>" path="/v1/{organization}/tool/{tool\_id}/version" method="post" %}
<https://api.amigo.ai/v1/openapi.json>
{% endopenapi %}

## List Tool Versions

Common filters:

* `deprecated=true|false`
* `versions=<pep440 constraint>` (for example, `">=1.2,<2"`)
* `creator=<org_id,user_id>` (repeatable)
* `sort_by=+created_at|-created_at|+version.major|...|+deprecated|-deprecated` (repeatable)
* `limit` (0-50, default 50), `continuation_token` (int)

{% openapi src="<https://api.amigo.ai/v1/openapi.json>" path="/v1/{organization}/tool/{tool\_id}/version" method="get" %}
<https://api.amigo.ai/v1/openapi.json>
{% endopenapi %}

## Invoke a Tool Version

Execute a tool version with up to 10 inputs in parallel. Each invocation returns the output and execution duration, or an error if the invocation fails.

{% hint style="info" %}
Each input must include:

* `input_parameters`: An object containing the parameters expected by your tool
* `invocation_mode`: Either `"regular"` (for production use) or `"conversation-simulation"` (for testing)
* `nonsensitive_user_variables` and `sensitive_user_variables`: The user variables to provide to the tool (may be empty objects)

See [Execution Modes](#execution-modes) for details on how to implement mode-specific behavior.
{% endhint %}

{% openapi src="<https://api.amigo.ai/v1/openapi.json>" path="/v1/{organization}/tool/{tool\_id}/version/{version}/invoke" method="post" %}
<https://api.amigo.ai/v1/openapi.json>
{% endopenapi %}

## Get Tool Invocations

Retrieve historical tool invocations across conversations and simulations. All invocations are recorded regardless of success or rollback status.

{% hint style="info" %}
Tool invocations remain in history even if the conversation or interaction that triggered them is later rolled back; in that case the referenced `conversation_id` or `interaction_id` may no longer correspond to an existing record.
{% endhint %}

Common filters:

* `tool_id=<tool_id>`
* `version=<pep440 constraint>` (for example, `">=1.2,<2"`)
* `invocation_source_type=regular-conversation|simulation-conversation`
* `conversation_id=<id>`
* `succeeded=true|false`

{% openapi src="<https://api.amigo.ai/v1/openapi.json>" path="/v1/{organization}/tool/invocation" method="get" %}
<https://api.amigo.ai/v1/openapi.json>
{% endopenapi %}

## Search Tool Invocations

Search tool invocations by text query across outputs, error messages, and stack traces.

{% openapi src="<https://api.amigo.ai/v1/openapi.json>" path="/v1/{organization}/tool/invocation/search" method="get" %}
<https://api.amigo.ai/v1/openapi.json>
{% endopenapi %}

## Deprecate Tool Versions

Remove specific tool versions from production use.

Notes:

* `versions` is a semantic version constraint (PEP 440 style), for example `>=1.0,<2`.
* Response: 204 No Content

{% hint style="info" %}
Cost note\
Deprecate versions that are no longer referenced in your applications to control storage-related costs.
{% endhint %}

{% openapi src="<https://api.amigo.ai/v1/openapi.json>" path="/v1/{organization}/tool/{tool\_id}/version/{versions}" method="delete" %}
<https://api.amigo.ai/v1/openapi.json>
{% endopenapi %}

## Deprecate a Tool

Behavior:

* Marks the tool and all its versions as deprecated; the tool is no longer used.
* Propagation across the system can take about a minute.

{% openapi src="<https://api.amigo.ai/v1/openapi.json>" path="/v1/{organization}/tool/{tool\_id}" method="delete" %}
<https://api.amigo.ai/v1/openapi.json>
{% endopenapi %}

## Tool Scaffold Setup (CLI)

The `forge tool-scaffold install` command automates installation of the `amigo_tool_scaffold` package into your tool directories, handling authentication and package manager configuration in a single step.

```bash
# Interactive tool selection
forge tool-scaffold install -e myorg

# Install in a specific tool
forge tool-scaffold install -e myorg --tool my_tool

# Install in all tools
forge tool-scaffold install -e myorg --all

# Verbose output for debugging
forge tool-scaffold install -e myorg --all --verbose
```

| Option             | Required | Description                          |
| ------------------ | -------- | ------------------------------------ |
| `--env` / `-e`     | Yes      | Environment name                     |
| `--tool` / `-t`    | No       | Install in a specific tool directory |
| `--all`            | No       | Install in all tool directories      |
| `--verbose` / `-v` | No       | Enable verbose output                |

{% hint style="info" %}
**Prerequisite**: Requires `uv >= 0.10.2`. The command validates the `uv` version at startup and provides a clear error if it is missing or outdated.
{% endhint %}

## Download Tool Scaffold

Download the latest tool scaffold release as a `.tar.gz` archive. The scaffold provides the base project structure for building new tools.

{% hint style="info" %}
**CLI Alternative** For most workflows, use the `forge tool-scaffold install` command instead of this endpoint directly. See [Tool Scaffold Setup (CLI)](#tool-scaffold-setup-cli) above.
{% endhint %}

{% openapi src="<https://api.amigo.ai/v1/openapi.json>" path="/v1/{organization}/tool/amigo\_tool\_scaffold.tar.gz" method="get" %}
<https://api.amigo.ai/v1/openapi.json>
{% endopenapi %}

## Related

* Getting Started → [Authentication](/developer-guide/getting-started/authentication.md)
* Getting Started → [Regions & Endpoints](/developer-guide/getting-started/regions-and-endpoints.md)
* Classic API -> [Services](/developer-guide/classic-api/core-api/services.md)
* Best Practices → [Version Sets & Promotion](/developer-guide/operations/devops/version-sets-best-practices.md)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.amigo.ai/developer-guide/classic-api/core-api/tools.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
