symfonic.core.tools¶
tools ¶
symfonic.core.tools — Tool registry, metadata, and the @symfonic_tool decorator.
SafetyLevel ¶
Bases: str, Enum
Safety classification for tools.
SymfonicToolMetadata
dataclass
¶
SymfonicToolMetadata(
scope: ScopeLiteral = "public",
routing_mode: RoutingMode = "observe",
visibility: Visibility = "visible",
)
Symfonic-specific tool metadata.
Attached to the decorated tool as _symfonic_metadata. The
registry reads this attribute, raises SymfonicAgentError if
the experimental flag is off, and otherwise lifts the metadata into
its own :class:~symfonic.core.tools.registry.ToolRegistration
fields (visibility="hidden" -> visible_to_agents=False).
Future Symfonic versions may add fields here; consumers should
treat the object as read-only and prefer
:func:get_symfonic_metadata over poking the attribute directly.
ToolCategory ¶
Bases: str, Enum
Categories for tool classification.
ToolRegistration
dataclass
¶
ToolRegistration(
tool: BaseTool,
category: ToolCategory = ToolCategory.CUSTOM,
safety_level: SafetyLevel = SafetyLevel.RESTRICTED,
max_calls_per_invocation: int | None = None,
visible_to_agents: bool = True,
cost_usd: float | None = None,
requires: type | None = None,
)
Metadata for a registered tool.
ToolRegistry ¶
Tool registration, filtering, cost estimation, and freeze.
Frozen automatically by AgentGraph.compile(). After freeze, register() raises RuntimeError.
Source code in src/symfonic/core/tools/registry.py
all_tools ¶
cost_usd_for_invocation ¶
Calculate total cost for a set of tool invocations.
Returns None if any tool has unknown cost.
Source code in src/symfonic/core/tools/registry.py
filter ¶
filter(
allowed_names: list[str] | None = None,
categories: list[ToolCategory] | None = None,
max_safety_level: SafetyLevel = SafetyLevel.DANGEROUS,
agent_visible_only: bool = False,
available_capabilities: set[type] | None = None,
debug: bool = False,
) -> list[BaseTool]
Filter tools by criteria.
When debug=True, each excluded tool emits a logger.debug() message.
Source code in src/symfonic/core/tools/registry.py
freeze ¶
get_registration ¶
register ¶
Register a single tool with optional metadata. Returns self for chaining.
Raises SymfonicAgentError(code='bad_request') if tool was
produced by @symfonic_tool and the experimental flag is off.
Source code in src/symfonic/core/tools/registry.py
register_many ¶
Register multiple tools with default metadata. Returns self for chaining.
set_experimental_tool_decorator ¶
Deprecated no-op. @symfonic_tool is GA and needs no gate.
Retained so existing engine wiring and adopter code that toggled
the former experimental gate keep working. The enabled value
is ignored — decorator-produced tools always register.
Source code in src/symfonic/core/tools/registry.py
tools_within_budget ¶
Return tools whose cost is within budget.
If include_unknown_cost is True, tools with no cost info are included.
Source code in src/symfonic/core/tools/registry.py
get_symfonic_metadata ¶
Return the :class:SymfonicToolMetadata attached to obj, or None.
Source code in src/symfonic/core/tools/decorator.py
is_symfonic_tool ¶
Return True if obj was produced by :func:symfonic_tool.
symfonic_tool ¶
symfonic_tool(
*,
scope: ScopeLiteral = "public",
routing_mode: RoutingMode = "observe",
visibility: Visibility = "visible",
name: str | None = None,
description: str | None = None,
) -> Callable[[Callable[..., Any]], StructuredTool]
Decorate a Python callable into a symfonic-compatible tool.
The resulting object is a :class:~langchain_core.tools.StructuredTool
accepted by :meth:~symfonic.core.tools.registry.ToolRegistry.register
without any further plumbing.
Parameters¶
scope:
Logical visibility scope. "public" (default), "internal",
or "admin". Symfonic does not yet enforce scope at the
invocation tier; the field is captured today so policy code can
consume it without a future signature change.
routing_mode:
Per-tool override for the framework's dynamic tool-routing
verdict. Defaults to "observe"; "enforce" causes the
router to actually narrow the manifest, "off" opts out of
routing entirely.
visibility:
"visible" (default) keeps the tool in the agent-visible
manifest; "hidden" flips the registry's
visible_to_agents field to False so the tool is bound
to the LangGraph runtime but never offered to the LLM in the
manifest. Useful for system-level tools (telemetry emitters,
feature-flag readers) that should be callable by orchestration
code but never selected by the model.
name:
Override the tool name. Defaults to fn.__name__.
description:
Override the description. Defaults to the function's docstring.
Returns¶
Callable
A decorator that, applied to a callable, returns a
:class:StructuredTool with the symfonic metadata attached.
Notes¶
- The decorated callable's async / sync / async-generator
semantics are preserved on the underlying tool's
func/coroutineslots.inspect.isasyncgenfunctioncontinues to returnTruefor generator tools so Phase 3's :func:~symfonic.core.tools.streaming.wrap_async_gen_toolworks unchanged. - Registration requires no flag (GA). The resulting tool registers
through
ToolRegistry.registerlike any LangChain tool; itsscope/routing_mode/visibilitymetadata is lifted into theToolRegistrationautomatically.
Source code in src/symfonic/core/tools/decorator.py
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 | |