#  Copyright (c) 2026 Cisco Systems, Inc. and its affiliates
#  SPDX-License-Identifier: Apache-2.0
$schema: "https://json-schema.org/draft-07/schema#"
$id: "mas/v1/tool"
title: "Tool Manifest"
description: >
  Schema for kind: Tool manifests (apiVersion: mas/v1).
  A Tool manifest is the declarative contract of a single tool:
    - spec.parameters[]  — semantic interface (name, type, description, examples)
    - spec.returns       — output description
    - spec.impl          — implementation (module_path, class_name, kind)
  Agent manifests reference Tool manifests via tools[].ref: ./path/to/tool.yaml.
  ToolBundle entries can also be addressed via tools[].ref: bundle://<bundle>/<tool-id>.
type: object
required:
  - apiVersion
  - kind
  - metadata
  - spec
additionalProperties: false
patternProperties:
  "^x-":
    description: "Extension properties (UI metadata, canvas state, etc.) — ignored by the runtime."
properties:

  apiVersion:
    type: string
    const: "mas/v1"

  kind:
    type: string
    const: "Tool"

  metadata:
    type: object
    required: [name]
    additionalProperties: false
    properties:
      name:
        type: string
        pattern: "^[a-z0-9][a-z0-9_-]*$"
        description: >
          Canonical tool name — used as the tool call name in LLM tool-use
          (OpenAI function name, tool-server tool name).  Must be unique within an agent.
      description:
        type: string
        default: ""
        description: "Short one-liner surfaced in tool catalogues and dashboards."
      version:
        type: string
        pattern: "^[0-9]+\\.[0-9]+\\.[0-9]+.*$"
        default: "0.1.0"
      tags:
        type: array
        items:
          type: string
        default: []

  spec:
    type: object
    additionalProperties: false
    properties:

      description:
        type: string
        default: ""
        description: >
          Full description of what the tool does, when to call it, and what
          it returns.  Published verbatim as the LLM function description
          and tool-server tool.description.
          Write from the caller's perspective:
          "Call this tool when you need X. It returns Y."

      parameters:
        type: array
        description: >
          Ordered list of input parameters.  Rendered as JSON Schema
          ``properties`` for LLM tool-use and tool-server inputSchema.
          Use ``required: true`` on mandatory parameters.
        default: []
        items:
          type: object
          required: [name, type]
          additionalProperties: false
          properties:
            name:
              type: string
              description: "Parameter name — must be a valid Python identifier."
              pattern: "^[a-zA-Z_][a-zA-Z0-9_]*$"
            type:
              type: string
              enum: [string, integer, number, boolean, array, object]
              description: "JSON Schema primitive type."
            description:
              type: string
              default: ""
              description: "Human-readable description injected into the LLM tool spec."
            required:
              type: boolean
              default: false
              description: >
                When true, the parameter is added to JSON Schema ``required[]``.
                Omit or set false for optional parameters.
            default:
              description: "Default value used when the parameter is absent."
            enum:
              type: array
              description: "Allowed values for the parameter."
              items: {}
            examples:
              type: array
              description: >
                Representative values shown to LLMs in the tool spec.
                Helps the model understand the expected format.
              items: {}

      returns:
        type: object
        description: "Description of the tool's return value."
        additionalProperties: false
        properties:
          type:
            type: string
            enum: [string, integer, number, boolean, array, object, any]
            default: "any"
            description: "JSON Schema type of the return value."
          description:
            type: string
            default: ""
            description: >
              Human-readable description of the return value.
              Published in tool-server tool spec output schemas and LLM docs.

      idempotent:
        type: boolean
        default: false
        description: >
          True if calling with the same args always gives the same result.
          Used by the governance layer for safe retries.

      timeout_seconds:
        type: integer
        minimum: 1
        maximum: 3600
        default: 30
        description: "Max wall-clock execution time enforced by the pre_tool_call hook."

      title:
        type: string
        description: >
          Optional display name distinct from metadata.name (tool-server title).

      read_only:
        type: boolean
        description: >
          Optional hint: the tool does not modify its environment.
          Omit to leave unspecified (do not treat omission as false).

      destructive:
        type: boolean
        description: >
          Optional hint: the tool may delete or overwrite data.

      open_world:
        type: boolean
        description: >
          Optional hint: the tool may contact the open world (network, search).

      icons:
        type: array
        description: "Optional icons advertised to clients."
        items:
          type: object
          required: [src]
          additionalProperties: false
          properties:
            src:
              type: string
            mime_type:
              type: string
            sizes:
              type: array
              items:
                type: string
            theme:
              type: string
              enum: [light, dark]

      task_support:
        type: string
        enum: [forbidden, optional, required]
        description: >
          Optional: whether the tool may run as a background task.

      output_schema:
        type: object
        additionalProperties: true
        description: >
          Optional JSON Schema for the tool result (MCP outputSchema).
          Richer than spec.returns; omit for daily-ops tools.

      meta:
        type: object
        additionalProperties: true
        description: "Optional advertise metadata forwarded to protocol adapters."

      semantics:
        type: object
        additionalProperties: false
        description: >
          Optional interpretation of this tool for traces and metrics.
          The kernel copies this onto ExchangeRecord and does not infer
          meaning from the tool name. Composite providers (several call
          names in one class) advertise per-entry semantics on list_tools()
          instead of this single-tool YAML field.
        properties:
          concept:
            type: string
            minLength: 1
            description: >
              Stable concept id used for metrics (skill, memory, …).
          op:
            type: string
            description: >
              Operation within the concept (activate, read, write, execute, …).
          subject_arg:
            description: >
              Argument name, or list of names tried in order, whose value
              identifies the subject (skill id, memory key, …).
            oneOf:
              - type: string
              - type: array
                items:
                  type: string

      execution_mode:
        type: string
        enum: [sync, async, realtime]
        default: sync

      result_mode:
        type: string
        enum: [inline, stream, session]
        default: inline

      tool_category:
        type: string

      events:
        type: array
        items:
          type: object
          additionalProperties: true

      impl:
        type: object
        description: >
          Implementation section — maps the semantic contract to a concrete
          runtime executor.  Hidden from LLM callers; used only by the runtime
          loader.
        required: [module_path]
        additionalProperties: false
        properties:
          kind:
            type: string
            enum: [python, remote_tool, openapi]
            default: python
            description: >
              python   — ToolContract subclass loaded via module_path.
              remote_tool  — remote tool-server tool; module_path points to the ToolServerClient adapter.
              openapi  — OpenAPI endpoint; module_path points to the OpenAPITool adapter.
          module_path:
            type: string
            description: >
              Dotted Python module path, e.g. library-samples/tools/calc.py.
              May also be a relative filesystem path (./tools/my_tool.py).
          class_name:
            type: [string, "null"]
            default: null
            description: "Class implementing ToolContract. Auto-discovered when null."
          params:
            type: object
            description: "Optional constructor kwargs forwarded to the class at instantiation."
            additionalProperties: true
            default: {}
