> ## Documentation Index
> Fetch the complete documentation index at: https://docs.compozy.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Usage

> Tools are defined using the following structure:

## Structure

```yaml theme={"dark"}
tools:
  - id: string # Unique identifier for the tool
    use: string | object # Tool reference (shorthand or detailed)
    config: object # Tool-specific configuration
    env: object # Tool-specific environment variables
    import: string # Path to external tool definition file

    # Inline tool definition
    execute: string # TypeScript or Python code to run
    schema: object # Schema for the tool's input and output
      config: object # Tool-specific configuration
      input: object # Schema for the tool's input parameters
      output: object # Schema for the tool's output format
```

## Basic Usage

Tools can be used in three main ways:

<CodeGroup>
  ```yaml Simple Package theme={"dark"}
  tools:
    - id: crypto_price
      use: compozy/tools:crypto-price@1.0.0
  ```

  ```yaml Detailed Package theme={"dark"}
  tools:
    - id: blockchain_scanner
      use:
        repo: compozy/tools
        package: blockchain-scanner
        version: 0.2.1
  ```

  ```yaml Local File theme={"dark"}
  tools:
    - id: custom_tool
      use: ./tools/custom.yaml
  ```
</CodeGroup>

Each tool can be configured using the `config` property and environment variables:

```yaml theme={"dark"}
tools:
  - id: crypto_price
    use: compozy/tools:crypto-price
    config:
      api_key: "{{ env.API_KEY }}"
      currency: "USD"
    env:
      API_KEY: "your-api-key"
```

## Inline Definitions

Tools can be defined inline using either TypeScript or Python code directly in your workflow. Each tool must export a `run()` function that contains the tool's logic.

<Tabs>
  <Tab title="TypeScript">
    ```yaml theme={"dark"}
    tools:
      - id: double
        execute: |
          export function run(input: { value: number }) {
            return {
              result: input.value * 2
            };
          }
        schema:
          input:
            type: object
            properties:
              value:
                type: number
                description: "Value to double"
            required: [value]
          output:
            type: object
            properties:
              result:
                type: number
                description: "The doubled value"
            required: [result]
    ```

    ### Deno Modules

    <Note>
      You can use Deno modules in your tool's TypeScript code:
    </Note>

    ```typescript theme={"dark"}
    import { crypto } from "jsr:@std/crypto";
    import lodash from "npm:lodash";
    ```
  </Tab>

  <Tab title="Python">
    ```yaml theme={"dark"}
    tools:
      - id: double
        execute: |
          from typing import TypedDict

          class Input(TypedDict):
              value: float

          class Output(TypedDict):
              result: float

          def run(input: Input) -> Output:
              return {
                  "result": input["value"] * 2
              }
        schema:
          input:
            type: object
            properties:
              value:
                type: number
                description: "Value to double"
            required: [value]
          output:
            type: object
            properties:
              result:
                type: number
                description: "The doubled value"
            required: [result]
    ```

    ### Python Packages

    <Note>
      You can use Python packages in your tool by specifying them in your tool's requirements:
    </Note>

    ```python theme={"dark"}
    import numpy as np
    from pandas import DataFrame
    ```
  </Tab>
</Tabs>

## Schema Definition

When creating a tool, you define three types of schemas:

<Steps>
  <Step title="Configuration Schema">
    Defines the structure of the `config` object
  </Step>

  <Step title="Input Schema">
    Defines the structure of runtime parameters (used with `with`)
  </Step>

  <Step title="Output Schema">
    Defines the structure of the tool's output
  </Step>
</Steps>

Here's an example of a tool definition:

<CodeGroup>
  ```yaml TypeScript {20-58} theme={"dark"}
  tools:
    - id: crypto_price
      execute: |
        type Input = {
          symbol: string
        }

        type Config = {
          api_key: string
          currency?: string
        }

        export function run(input: Input, config: Config) {
          return {
            price: 0,
            currency: config.currency || 'USD'
          };
        }
      schema:
        config:
          type: object
          properties:
            api_key:
              type: string
              description: "API key for the cryptocurrency data provider"
            currency:
              type: string
              description: "Default currency for price conversion"
              default: "USD"
          required: [api_key]

        input:
          type: object
          properties:
            symbol:
              type: string
              description: "Cryptocurrency symbol (e.g., BTC, ETH)"
          required: [symbol]

        output:
          type: object
          properties:
            price:
              type: number
              description: "Current price of the cryptocurrency"
            currency:
              type: string
              description: "Currency of the price"
          required: [price, currency]
  ```

  ```yaml Python {20-58} theme={"dark"}
  tools:
    - id: crypto_price
      execute: |
        from typing import TypedDict
        from typing import Optional

        class Input(TypedDict):
            symbol: str

        class Config(TypedDict):
            api_key: str
            currency: Optional[str]

        def run(input: Input, config: Config):
            return {
                "price": 0,
                "currency": config.get("currency", "USD")
            }
      schema:
        config:
          type: object
          properties:
            api_key:
              type: string
              description: "API key for the cryptocurrency data provider"
            currency:
              type: string
              description: "Default currency for price conversion"
              default: "USD"
          required: [api_key]

        input:
          type: object
          properties:
            symbol:
              type: string
              description: "Cryptocurrency symbol (e.g., BTC, ETH)"
          required: [symbol]

        output:
          type: object
          properties:
            price:
              type: number
              description: "Current price of the cryptocurrency"
            currency:
              type: string
              description: "Currency of the price"
          required: [price, currency]
  ```
</CodeGroup>

This tool can then be used like this:

```yaml theme={"dark"}
tools:
  - id: price_checker
    use: ./crypto_price
    config:
      api_key: {{ env.API_KEY }}    # Matches config schema
      currency: "EUR"            # Optional config parameter

tasks:
  - id: check_price
    use: tool(price_checker)
    with:
      symbol: "BTC"             # Matches input schema
```

## Key Points

<Steps>
  <Step title="Configuration Schema" icon="check">
    The `config` schema defines persistent configuration options that are set when the tool is initialized.
  </Step>

  <Step title="Input & Output Schema" icon="check">
    The `input` and `output` schemas define runtime parameters and the tool's output.
  </Step>

  <Step title="Schema Format" icon="check">
    Both configuration and input schemas use [JSON Schema](https://json-schema.org/) for validation and documentation.
  </Step>

  <Step title="Run Function Parameters" icon="check">
    The `run()` function receives both `input` and `config` parameters during execution.
  </Step>

  <Step title="Required Fields" icon="check">
    Required fields must be specified in the respective `required` arrays within each schema definition.
  </Step>
</Steps>

## Best Practices

<Steps>
  <Step title="Tool Organization" icon="folder-tree">
    * Use clear, descriptive tool IDs
    * Group related tools together
    * Document tool-specific configuration
  </Step>

  <Step title="Configuration Management" icon="gear">
    * Use environment variables for sensitive data
    * Set sensible defaults in tool definitions
    * Override only necessary config at usage points
  </Step>

  <Step title="Error Handling" icon="shield-check">
    * Always check tool error outputs
    * Provide fallback behavior where appropriate
    * Log tool execution metadata for debugging
  </Step>

  <Step title="Security" icon="lock">
    * Never expose sensitive credentials in tool code
    * Validate and sanitize all inputs
    * Follow security best practices for external services
  </Step>
</Steps>

## References

* [Deno Runtime](https://deno.com/) - The JavaScript/TypeScript runtime used by Compozy
* [Python Documentation](https://docs.python.org/) - Official Python documentation
* [JSON Schema](https://json-schema.org/) - The schema format used for tool configuration and input/output
* [Deno Standard Library](https://deno.land/std) - Built-in modules available for TypeScript tools
* [Python Standard Library](https://docs.python.org/3/library/) - Built-in modules available for Python tools
* [JSR (JavaScript Registry)](https://jsr.io/) - Package registry for Deno modules
* [PyPI](https://pypi.org/) - Python Package Index for Python modules
