Standalone SDK for developing Solace Agent Mesh Python tools
Project description
SAM Tool SDK
Python SDK for building tools that run in Solace Agent Mesh (SAM).
What it does
Write a Python function (or class) and expose it as a SAM tool. Type
annotations become the tool's parameter schema, the docstring supplies the
descriptions the LLM sees, and you return structured results and artifacts.
The SAM runtime discovers the tool and invokes it per call. The only
dependency is pydantic.
Installation
pip install sam-tool-sdk
Quick Start
Function-based tool with tool_cli
The canonical pattern: author a function, wrap it with tool_cli, and expose
the resulting callable as a console script via pyproject.toml.
# greet_tool.py
from sam_tool_sdk import tool_cli, ToolResult, SandboxToolContextFacade
async def greet(name: str, excited: bool = False, ctx: SandboxToolContextFacade = None) -> ToolResult:
"""Greet someone by name.
Args:
name: who to greet
excited: add an exclamation mark
"""
if ctx is not None:
ctx.send_status(f"Greeting {name}...")
suffix = "!" if excited else "."
return ToolResult.ok(message=f"Hello, {name}{suffix}", data={"greeted": name})
cli = tool_cli(greet)
# pyproject.toml
[project]
name = "sam-tool-greet"
version = "0.1.0"
dependencies = ["sam-tool-sdk>=0.1,<0.2"]
[project.scripts]
greet = "greet_tool:cli"
Parameter type annotations (str, bool, int, Artifact,
SandboxToolContextFacade, …) and the docstring's Args: block produce the
JSON Schema the LLM sees. The SandboxToolContextFacade-annotated parameter is
injected at runtime; everything else becomes a tool argument.
Class-based tool (DynamicTool)
For more control over the tool's schema and behavior:
from sam_tool_sdk import DynamicTool, ToolResult
class WordCounter(DynamicTool):
@property
def tool_name(self):
return "count_words"
@property
def tool_description(self):
return "Counts the number of words in the given text."
@property
def parameters_schema(self):
return {
"type": "object",
"properties": {
"text": {"type": "string", "description": "The text to count words in"},
},
"required": ["text"],
}
async def _run_async_impl(self, args, tool_context=None, credential=None):
count = len(args["text"].split())
return ToolResult.ok(f"Found {count} words", data={"count": count}).model_dump()
Provider-based tools (DynamicToolProvider)
When you want to define multiple related tools from a single class:
from sam_tool_sdk import DynamicToolProvider
class MathTools(DynamicToolProvider):
@MathTools.register_tool
async def add(self, a: float, b: float) -> dict:
"""Add two numbers."""
return {"text": str(a + b)}
@MathTools.register_tool
async def multiply(self, a: float, b: float) -> dict:
"""Multiply two numbers."""
return {"text": str(a * b)}
def create_tools(self, tool_config=None):
return [] # All tools defined via @register_tool
Declaring operator config (config_schema)
Tools that need operator-supplied configuration (API keys, endpoints, default
channels, …) declare it with @with_config_schema so the platform can render a
config form, validate per-agent overrides, and enforce required fields at
deploy time.
from sam_tool_sdk import ConfigSchemaField, with_config_schema
@with_config_schema([
ConfigSchemaField(
key="slack_bot_token",
type="string",
description="Slack Bot OAuth token (xoxb-...).",
required=True,
secret=True,
),
ConfigSchemaField(key="default_channel", type="string"),
ConfigSchemaField(key="api_url", type="string"),
])
async def post_message(tool_config, channel: str, text: str):
token = tool_config["slack_bot_token"]
...
Values are resolved at deploy time with precedence: agent override > toolset
default > schema default > 422 if a required field is unset. Fields marked
secret=True are redacted on API responses and rendered with a password input
in the UI.
For DynamicTool subclasses, override the config_schema property to return a
list of ConfigSchemaField(...).to_dict() entries.
Working with artifacts
Tools can receive and produce artifacts using type annotations:
from sam_tool_sdk import Artifact, ToolResult, DataObject, DataDisposition
async def summarize_file(doc: Artifact) -> ToolResult:
"""Summarize the contents of an uploaded document."""
text = doc.as_text()
summary = text[:200] + "..." # placeholder for real summarization
return ToolResult.ok(
message=f"Summarized {doc.filename}",
data={"summary": summary},
data_objects=[
DataObject(
name="summary.txt",
content=summary,
mime_type="text/plain",
disposition=DataDisposition.ARTIFACT,
description="Document summary",
)
],
)
Per-tool sandbox options
Decorate a tool_cli function (or override the matching DynamicTool
properties) to declare timeouts and volume requirements honored at execution
time:
from sam_tool_sdk import tool_cli, tool_timeout, with_volume_params, VolumeParam, ToolResult
@tool_timeout(seconds=120)
@with_volume_params([
VolumeParam(name="workspace", mount_path="/workspace", mode="readwrite"),
])
async def transform(input_path: str, ctx=None) -> ToolResult:
"""Long-running transformation that needs scratch space."""
...
cli = tool_cli(transform)
tool_timeout overrides the per-invocation timeout; with_volume_params
declares mount points provisioned before the tool runs (paths surface via
ctx.volume_mounts / ctx.get_volume_mount_path("/workspace"), keyed by mount
path).
Packaging
A SAM tool ships as an
AWS-Lambda-Layer-style
directory: a python/bin/<console-script> entry point plus all dependencies
pre-extracted under python/. Build that layout with a single
pip install --target invocation:
pip install --target dist/python \
--platform manylinux2014_x86_64 \
--python-version 3.13 \
--only-binary=:all: \
.
The directory then contains dist/python/bin/<your-script>,
dist/python/sam_tool_sdk/, dist/python/pydantic/, and your own package.
Pair it with a manifest.yaml declaring executable: python/bin/<your-script>.
License
Apache-2.0
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file sam_tool_sdk-0.1.2.tar.gz.
File metadata
- Download URL: sam_tool_sdk-0.1.2.tar.gz
- Upload date:
- Size: 57.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
630ff51b9954ba854c9715f4849d83d8923e5bfbf097914bbad433ae6182d19d
|
|
| MD5 |
359a5eeed2c61de1c8cff29b2acd2c1b
|
|
| BLAKE2b-256 |
8de5e4b0171881b6c23e0417019b10229e1c72ac51f6ac19d768e0ce2cdd7587
|
Provenance
The following attestation bundles were made for sam_tool_sdk-0.1.2.tar.gz:
Publisher:
python-sdk-release.yml on SolaceDev/solace-agent-mesh-go
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
sam_tool_sdk-0.1.2.tar.gz -
Subject digest:
630ff51b9954ba854c9715f4849d83d8923e5bfbf097914bbad433ae6182d19d - Sigstore transparency entry: 1759394339
- Sigstore integration time:
-
Permalink:
SolaceDev/solace-agent-mesh-go@136aca07e51c68c5e4b1543ae67de173a63d144c -
Branch / Tag:
refs/heads/main - Owner: https://github.com/SolaceDev
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-sdk-release.yml@136aca07e51c68c5e4b1543ae67de173a63d144c -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file sam_tool_sdk-0.1.2-py3-none-any.whl.
File metadata
- Download URL: sam_tool_sdk-0.1.2-py3-none-any.whl
- Upload date:
- Size: 52.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b6f9f9c3791a0212dd44182ed5e2b5bc24139086c2dfeb5e4d042ffcf37eedb9
|
|
| MD5 |
d4db412db51969548c025ea7556408e7
|
|
| BLAKE2b-256 |
c6c30dfd2dfbd4aff586be4cb7c7117a3f6cb0cc261af1aa3fd6ed2e4d4732e4
|
Provenance
The following attestation bundles were made for sam_tool_sdk-0.1.2-py3-none-any.whl:
Publisher:
python-sdk-release.yml on SolaceDev/solace-agent-mesh-go
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
sam_tool_sdk-0.1.2-py3-none-any.whl -
Subject digest:
b6f9f9c3791a0212dd44182ed5e2b5bc24139086c2dfeb5e4d042ffcf37eedb9 - Sigstore transparency entry: 1759394470
- Sigstore integration time:
-
Permalink:
SolaceDev/solace-agent-mesh-go@136aca07e51c68c5e4b1543ae67de173a63d144c -
Branch / Tag:
refs/heads/main - Owner: https://github.com/SolaceDev
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-sdk-release.yml@136aca07e51c68c5e4b1543ae67de173a63d144c -
Trigger Event:
workflow_dispatch
-
Statement type: