The @astack-tech/tools package provides the foundational abstractions and utilities for creating, managing, and invoking tools within the AStack framework. Tools are discrete units of functionality that can be called by agents to perform specific tasks like file I/O, web searches, calculations, or any custom operation. This package defines the Tool interface contract, provides the createTool() utility for simple function-based tools, implements ComponentTool for wrapping AStack Components as tools, and offers ToolSet for managing tool collections.
For information about how agents use tools for ReAct-style reasoning, see Agent System. For details on the ToolInvoker component that executes tool calls, see Components Package.
The Tool interface defines the standard contract that all tools must implement. A tool consists of a name, description, optional JSON Schema parameters, and an invoke() method for execution.
Tool Interface Properties:
| Property | Type | Description |
|---|---|---|
name | string | Unique identifier for the tool |
description | string | Human-readable description for LLM context |
parameters | ToolParameters | JSON Schema defining expected arguments |
invoke() | (args: Record<string, unknown>) => Promise<unknown> | Executes the tool with provided arguments |
The ToolParameters type follows JSON Schema format, specifying the structure of arguments the tool expects. This schema is provided to language models to enable function calling.
Sources: The Tool interface is referenced in packages/components/src/agents/index.ts41-58 packages/tools/src/component-tool.ts2
Tools are invoked when an agent receives a response from an LLM containing tool_calls. The agent extracts the tool name and arguments, calls the corresponding tool's invoke() method, and returns results to the conversation context.
Sources: packages/components/src/agents/index.ts397-549
The createTool() utility provides the simplest way to create function-based tools. It wraps an async function with metadata to conform to the Tool interface.
The agent-with-tools example demonstrates creating file I/O tools:
Example from the codebase at examples/agent-with-tools/index.ts26-61:
readFile Tool:
'readFile''读取指定路径的文件内容'filePath property (string, required)writeFile Tool:
'writeFile''将内容写入指定路径的文件'filePath and content properties (both strings, required)Both tools include security checks (preventing .. in paths) and comprehensive error handling.
Sources: examples/agent-with-tools/index.ts26-103
The parameters argument follows JSON Schema format:
| Schema Field | Purpose | Example |
|---|---|---|
type | Root type (typically 'object') | type: 'object' |
properties | Defines each parameter | properties: { filePath: { type: 'string', description: '...' } } |
required | Array of required parameter names | required: ['filePath'] |
This schema is converted to OpenAI function calling format when passed to model providers at packages/integrations/src/model-provider/deepseek/index.ts156-163
Sources: examples/agent-with-tools/index.ts54-60 packages/integrations/src/model-provider/deepseek/index.ts154-167
ComponentTool enables any AStack Component to be exposed as a tool, bridging the component architecture with the tool system. This allows reusing existing components in agent workflows.
The configuration object passed to ComponentTool constructor at packages/tools/src/component-tool.ts7-51:
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Tool identifier |
description | string | Yes | Tool description for LLM |
component | Component | Yes | Component instance to wrap |
parameters | ToolParameters | No | JSON Schema for arguments |
transformArgs | (args) => unknown | No | Maps tool args to component input |
transformResult | (result) => unknown | No | Maps component output to tool result |
inputPort | string | No | Input port name (default: 'in') |
outputPort | string | No | Output port name (default: 'out') |
The ComponentTool.invoke() method at packages/tools/src/component-tool.ts93-105:
Record<string, unknown>transformArgs() to convert to component input formatcomponent.run() in standalone modetransformResult() to convert component output to tool resultIf the component doesn't support standalone run() mode, an error is thrown.
The createComponentTool() factory function at packages/tools/src/component-tool.ts113-115 provides a convenient wrapper:
This factory simply instantiates and returns a ComponentTool instance.
Sources: packages/tools/src/component-tool.ts1-116
ToolSet provides a registry pattern for managing multiple tools, enabling dynamic tool discovery and organization.
The DefaultToolSet class at packages/tools/src/tool-set.ts45-100 provides the standard implementation:
Constructor:
Map<string, Tool>Key Methods:
| Method | Implementation | Complexity |
|---|---|---|
getTools() | Returns Array.from(this.tools.values()) | O(n) |
getTool(name) | Returns this.tools.get(name) | O(1) |
addTool(tool) | this.tools.set(tool.name, tool) (with duplicate check) | O(1) |
removeTool(name) | this.tools.delete(name) | O(1) |
size() | Returns this.tools.size | O(1) |
The addTool() method at packages/tools/src/tool-set.ts78-82 includes a duplicate name check to prevent accidentally overwriting existing tools.
The createToolSet() function at packages/tools/src/tool-set.ts107-109 provides a convenience wrapper:
The ToolInvoker component accepts either format at packages/components/src/tool-invoker/index.ts106-114:
This design allows flexibility in how tools are provided while maintaining internal efficiency with Map-based storage.
Sources: packages/tools/src/tool-set.ts1-110 packages/components/src/tool-invoker/index.ts99-127
When an LLM requests tool execution, it returns messages with tool_calls arrays. The structure used in agent communication:
ToolCall Interface (from packages/components/src/agents/index.ts143-152):
id: Unique identifier for tracking this specific calltype: Always 'function' for OpenAI compatibilityfunction.name: The tool name to invokefunction.arguments: JSON string of argumentstool_name: Internal field for simplified accessarguments: Parsed object form for direct useThe Deepseek model provider converts tools to OpenAI function calling format at packages/integrations/src/model-provider/deepseek/index.ts154-167:
Transformation Pipeline:
name, description, parameters)type: 'function', function: {...})tools parametertool_calls arraytool.invoke()Sources: packages/integrations/src/model-provider/deepseek/index.ts49-60 packages/integrations/src/model-provider/deepseek/index.ts154-167 packages/components/src/agents/index.ts143-152
The Agent component orchestrates multi-turn tool execution at packages/components/src/agents/index.ts397-549:
Key Implementation Details:
Iteration Loop (packages/components/src/agents/index.ts411-529):
maxIterations confighasMoreToolsToCall is truetool_callsTool Discovery (packages/components/src/agents/index.ts444-448):
tool_name from call.function.nametools array by nameArgument Parsing (packages/components/src/agents/index.ts451-465):
call.function.argumentsTool Invocation (packages/components/src/agents/index.ts468-513):
tool.execute() method firsttool.invoke() methodResult Integration (packages/components/src/agents/index.ts518-528):
tool_callsFor more granular control, the ToolInvoker component at packages/components/src/tool-invoker/index.ts1-279 provides standalone tool execution:
Configuration:
tools: Array or ToolSet of available toolsparallel: Execute tool calls concurrently (default: false)timeout: Maximum execution time per tool (default: 30000ms)verbose: Enable debug loggingExecution Modes:
| Mode | Behavior | Use Case |
|---|---|---|
| Sequential | Executes tool calls one at a time | Tools with shared state or ordering requirements |
| Parallel | Executes all tool calls concurrently | Independent tools, faster throughput |
Timeout Handling (packages/components/src/tool-invoker/index.ts158-163):
Sources: packages/components/src/agents/index.ts397-549 packages/components/src/tool-invoker/index.ts142-182 packages/components/src/tool-invoker/index.ts214-226
The agent-with-tools example demonstrates the complete tool lifecycle:
Implementation at examples/agent-with-tools/index.ts1-231:
Tool Creation (lines 26-103):
readFile with path validation and error handlingwriteFile with directory creation and content writingcreateTool() with JSON Schema parametersAgent Setup (lines 117-134):
Execution (lines 144-155):
agent.run(userRequest)Result Handling (lines 214-225):
Output Structure:
Sources: examples/agent-with-tools/index.ts1-231
The @astack-tech/tools package provides the foundation for extensible, composable tool systems in AStack. Tools can be created from functions, wrapped from components, managed in collections, and executed by agents or standalone invokers. This architecture enables ReAct-style reasoning patterns where LLMs can iteratively use tools to solve complex problems.
Sources: packages/tools/src/tool-set.ts packages/tools/src/component-tool.ts packages/components/src/agents/index.ts packages/components/src/tool-invoker/index.ts examples/agent-with-tools/index.ts
Refresh this wiki