Skip to content

feat: Allow instance-level customization of tool parameters#572

Open
psdaniel wants to merge 2 commits intocrmne:mainfrom
psdaniel:feature/customizable-tool-parameters
Open

feat: Allow instance-level customization of tool parameters#572
psdaniel wants to merge 2 commits intocrmne:mainfrom
psdaniel:feature/customizable-tool-parameters

Conversation

@psdaniel
Copy link

@psdaniel psdaniel commented Jan 16, 2026

Summary

Enable instance-level customization of tools, allowing different instances of the same tool class to have unique configurations:

  • Customize name, description, parameters, and provider_params at the instance level
  • Instance values take precedence, with automatic fallback to class-level definitions
  • Instance setters for post-initialization customization
  • Documentation for instance-level customization patterns

Motivation

Closes #418

Currently, RubyLLM tools define descriptions and parameters at the class level only, meaning all instances share the same configuration. This limits flexibility for use cases like:

  • Using multiple instances of the same tool with unique names (avoiding name collisions)
  • Creating similar tools with different parameters for different contexts
  • Allowing end-users to customize tool descriptions
  • Supporting dynamic tool configurations without creating multiple classes

Usage

# Create instances with unique names to avoid collisions
berlin_tool = Weather.new(
  name: 'berlin_weather',
  description: 'Get Berlin weather'
)
paris_tool = Weather.new(
  name: 'paris_weather',
  description: 'Get Paris weather'
)

# Both tools available with unique names
chat = RubyLLM.chat.with_tools(berlin_tool, paris_tool)
chat.tools.keys  # => [:berlin_weather, :paris_weather]

# Or set after initialization
tool = Weather.new
tool.name = 'custom_weather'
tool.description = 'Custom description'

Test plan

  • Unit tests for initialize with optional parameters (name, description, parameters, provider_params)
  • Unit tests for fallback to class-level definitions
  • Unit tests for instance setters
  • Unit tests for params_schema with instance parameters
  • Unit tests for multiple instances with different configurations
  • Integration test for multiple tools with unique names
  • Integration tests for instance-customized tools with Chat
  • All existing tests continue to pass

Add support for customizing tool description, parameters, and
provider_params at the instance level, with fallback to class-level
definitions when not overridden.

- Add initialize method with optional description, parameters, and
  provider_params arguments
- Modify instance getters to check instance values first, then
  fall back to class-level definitions
- Add instance setters for post-initialization customization
- Update params_schema to generate schema from instance parameters
- Add comprehensive unit tests for instance-level customization
- Add integration tests for customized tools with Chat

Closes crmne#418
Allow users to explicitly set unique names for tool instances, solving
the name collision issue where multiple instances of the same tool class
would overwrite each other in the chat's tools hash.

- Add name: parameter to Tool#initialize
- Update name getter to check @instance_name first
- Add name= setter for post-initialization customization
- Add unit and integration tests
- Document instance-level customization in tools.md
@psdaniel psdaniel marked this pull request as ready for review January 17, 2026 01:33
Comment on lines +260 to +261
berlin_weather = Weather.new(description: "Get current weather in Berlin")
paris_weather = Weather.new(description: "Get current weather in Paris")
Copy link

@SpaYco SpaYco Jan 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With the current implementation, this would fail without giving a name, as both would have the same name and get overwritten.

I think the current name approach is great, as this won't break the overwriting functionality, but we need to be clear in the docs.

Comment on lines +121 to +125
if @instance_parameters
return SchemaDefinition.from_parameters(@instance_parameters)&.json_schema if @instance_parameters.any?

return nil
end
Copy link

@SpaYco SpaYco Jan 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if @instance_parameters
return SchemaDefinition.from_parameters(@instance_parameters)&.json_schema if @instance_parameters.any?
return nil
end
if @instance_parameters
return SchemaDefinition.from_parameters(@instance_parameters)&.json_schema
end

return nil if parameters.nil? || parameters.empty?

SchemaDefinition.from_parameters would return nil if the value is nil or empty.

we can also just one line it

Suggested change
if @instance_parameters
return SchemaDefinition.from_parameters(@instance_parameters)&.json_schema if @instance_parameters.any?
return nil
end
return SchemaDefinition.from_parameters(@instance_parameters)&.json_schema if @instance_parameters

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEATURE] Allow for customizable tools parameters/description

2 participants