Skip to main content

Framework-agnostic SDK for building Cadence AI agent plugins

Project description

Cadence SDK

Python 3.13+ PyPI version License: MIT Docs

Write your plugin once — works on LangGraph, OpenAI Agents SDK, and Google ADK.


What is this?

Cadence SDK lets you build AI agent plugins that are completely decoupled from any orchestration framework. You define tools and domain logic; the Cadence platform handles LLM configuration, routing, and multi-agent orchestration.

A plugin is two things:

  • A Plugin (stateless factory) — declares metadata and creates agent instances
  • An Agent — holds tools, a system prompt, and optional lifecycle hooks

The SDK provides the base classes, decorators, and types to wire these together.


Installation

pip install cadence-sdk

Quick Start

Create my_plugin/plugin.py:

from cadence_sdk import BasePlugin, BaseSpecializedAgent, PluginMetadata, uvtool, plugin_settings, UvTool
from typing import List


class MyAgent(BaseSpecializedAgent):
    def initialize(self, config: dict) -> None:
        self.api_key = config["api_key"]
        self._search_tool = self._make_search_tool()

    def _make_search_tool(self) -> UvTool:
        @uvtool
        def search(query: str) -> str:
            """Search for information."""
            return call_api(query, self.api_key)

        return search

    def get_tools(self) -> List[UvTool]:
        return [self._search_tool]

    def get_system_prompt(self) -> str:
        return "You are a helpful assistant."


@plugin_settings([
    {"key": "api_key", "type": "str", "description": "API key", "sensitive": True, "required": True},
    {"key": "timeout", "type": "int", "description": "Request timeout in seconds", "default": 30},
])
class MyPlugin(BasePlugin):
    @staticmethod
    def get_metadata() -> PluginMetadata:
        return PluginMetadata(
            pid="com.example.my_plugin",
            name="My Plugin",
            version="1.0.0",
            description="Does something useful",
        )

    @staticmethod
    def create_agent() -> MyAgent:
        return MyAgent()

Cadence auto-discovers any BasePlugin subclass in a plugin.py file — no manual registration needed.

Package:

zip -r my_plugin.zip my_plugin/ -x "**/__pycache__/*" "**/*.pyc"

How to Use

Agents

Every agent must implement two methods:

Method Purpose
get_tools() Return a list of UvTool instances
get_system_prompt() Return the system prompt string

Optional lifecycle hooks:

Method Purpose
initialize(config) Set up state when the agent is created; config comes from @plugin_settings
cleanup() Async teardown — close connections, release resources

Choose which base class to extend:

  • BaseSpecializedAgent — tool-focused agent for any multi-agent mode (supervisor, coordinator, handoff)
  • BaseScopedAgent — context-anchored agent for grounded mode; requires load_anchor(resource_id) and build_scope_rules(context)
  • Both — extend both classes to support grounded and standard modes in one plugin

Plugins

A plugin is a stateless factory. Implement two static methods:

Method Purpose
get_metadata() Return a PluginMetadata (pid, name, version, description)
create_agent() Return a fresh agent instance

Optional static methods: validate_dependencies(), get_settings_schema(), health_check().

Tools

Use @uvtool to wrap any sync or async function as a framework-agnostic tool:

@uvtool
def search(query: str) -> str:
    """Search for information."""
    return do_search(query)


@uvtool(stream=True, validate=True)
async def fetch(url: str) -> dict:
    """Fetch URL content."""
    return await do_fetch(url)

@uvtool accepts: name, description, args_schema (Pydantic model), stream, stream_filter, validate.

Settings

Use @plugin_settings on your plugin class to declare config shown in the Cadence UI:

@plugin_settings([
    {"key": "api_key", "type": "str", "description": "API key", "sensitive": True, "required": True},
    {"key": "max_results", "type": "int", "description": "Max results", "default": 10},
])
class MyPlugin(BasePlugin): ...

Each entry requires: key, type ("str" "int" "float" "bool" "list" "dict"), description.
Optional: name (display label), default, required, sensitive.

Settings are passed to agent.initialize(config) as a dict.


Best Practices

  • Tools as closures — tools that need agent state should be closures inside a _make_* factory method so they capture self
  • Stateless plugins — set stateless=True (the default) when agents carry no mutable state; this enables instance sharing across orchestrators
  • Declare dependencies — list pip requirements in PluginMetadata.dependencies so the platform auto-installs them on load
  • Async cleanup — implement async cleanup() on agents that hold connections or file handles
  • Configurable system prompt — add system_prompt to @plugin_settings and return config.get("system_prompt") or default from get_system_prompt()
  • Validate in CI — use validate_plugin_structure(MyPlugin) to catch structural issues before deployment

Examples

Example Description
web_search_agent Web search via Serper.dev
recommendation_agent Product recommendations via Qdrant
helpdesk_agent Helpdesk support agent
webpage_reader_agent Web page content reader

Development

git clone https://github.com/jonaskahn/cadence.git
cd cadence/sdk
poetry install --with dev

# Run tests
PYTHONPATH=src python -m pytest tests/ -v

MIT Licensed

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

cadence_sdk-2.0.11.tar.gz (22.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

cadence_sdk-2.0.11-py3-none-any.whl (27.9 kB view details)

Uploaded Python 3

File details

Details for the file cadence_sdk-2.0.11.tar.gz.

File metadata

  • Download URL: cadence_sdk-2.0.11.tar.gz
  • Upload date:
  • Size: 22.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.3.2 CPython/3.14.3 Darwin/25.3.0

File hashes

Hashes for cadence_sdk-2.0.11.tar.gz
Algorithm Hash digest
SHA256 eb91a9a7328d68b2090fde4ca0b4dc96a4ca1e2623b30df3ed1a57ed093dd92a
MD5 9341d3082e2efd4b6bf351811129d2d9
BLAKE2b-256 af132d3fd7f8e80782a64592e9fcad72353c5135c797cd17c974cbbc7ad97ab2

See more details on using hashes here.

File details

Details for the file cadence_sdk-2.0.11-py3-none-any.whl.

File metadata

  • Download URL: cadence_sdk-2.0.11-py3-none-any.whl
  • Upload date:
  • Size: 27.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.3.2 CPython/3.14.3 Darwin/25.3.0

File hashes

Hashes for cadence_sdk-2.0.11-py3-none-any.whl
Algorithm Hash digest
SHA256 163a7e97a42964ec5deeafab5e2f612e91c576c367800c5c6317e6c5eaffca37
MD5 8f450562f49b164d78fd40750883f744
BLAKE2b-256 6da6f93dfb34f2ebb8b2514fcb04a7ef8c226837a145a59a021ca73c8d2288a6

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page