Skip to main content
This page is about publishing whole ToolSource implementations — a lower-level extensibility point for the resolver itself. If you just want to publish an individual tool so agents can call it by name, use the canonical praisonai.tools entry-point group instead (see Tool Discovery Order).
ToolSourceRegistry lets a Python package expose new tool-resolution sources through the praisonai.tool_sources entry-point group — no subclassing, no monkey-patching.
The user asks to pay an invoice; the plugin entry point resolves corporate tools without extra wiring.

Quick Start

1

Simple usage

Install a plugin package, then use tool names from that source on any agent:
2

Direct Python (DI)

Construct a ToolResolver with source_registry= to isolate a tenant or a test:

How It Works

Resolution walks the built-in chain first (local tools.py, wrapper registry, praisonaiagents.tools, praisonai-tools, core SDK registry), then each ToolSource from ToolSourceRegistry. Entry-point sources are appended to the built-in chain — they extend rather than replace it. When you pass sources= explicitly, entry-point sources are not appended; you fully own the chain.
Built-in names win. ToolSourceRegistry subclasses the base PluginRegistry, so since PraisonAI PR #4176 publishing a praisonai.tool_sources entry point whose name (case-insensitive) matches an already-shipped built-in source has no effect — the entry point is skipped, the shipped source resolves, and a DEBUG line notes the collision. Use runtime register(...) for a deliberate override. See Plugin Precedence.

Building a Tool Source Plugin

Implement the ToolSource protocol

Register the entry point in pyproject.toml

The entry-point value may be:
  • a ToolSource class (instantiated once — CorpToolsSource),
  • a factory function returning a ToolSource instance, or
  • an already-constructed ToolSource instance.
Factory example:

Ship it

After pip install, the source is live in every ToolResolver that uses the process-default registry (or any resolver you construct with a registry that discovers entry points). To verify from the CLI immediately after pip install, run praisonai tools add <package> --dry-run — it constructs a fresh resolver and prints exactly which tools now resolve. See tools add.

Configuration Options


Common Patterns


Safety

  • A plugin that raises during loading is logged and skipped — resolution never breaks for other callers.
  • A plugin that resolves to an object not matching the ToolSource protocol (missing name: str or callable lookup) is rejected with a TypeError inside _coerce_source and skipped — it never gets appended to the chain.
  • Behaviour is covered by test_misbehaving_plugin_is_skipped and test_invalid_shape_plugin_is_skipped in the SDK test suite.

Best Practices

Use a prefix like corp. so plugin tools do not collide with built-in names.
lookup() runs in chain order; bail out quickly when a name is not yours.
Raise only for genuine errors — the registry logs and skips your source on failure, so a raise looks like a broken plugin.
Avoids stale process-wide state in long-running services.

Tool Resolver

Single source of truth for loading tools

Persistence Backend Plugins

Same PluginRegistry pattern for stores

Framework Adapter Plugins

Entry-point plugins for execution frameworks

Registry Dependency Injection

Registry DI pattern across the wrapper