Skip to content

Use Parsera LLM Specs API instead of capabilities.rb #132

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 27 commits into from

Conversation

crmne
Copy link
Owner

@crmne crmne commented Apr 22, 2025

  • Removed the OpenAI capabilities module and related methods.
  • Simplified model parsing for OpenAI and Gemini providers, focusing on essential attributes.
  • Introduced a new utility method for deep key symbolization in hashes.
  • Updated OpenRouter model parsing to enhance data extraction and structure.
  • Deleted obsolete browser and CLI helper tasks to streamline the codebase.
  • Consolidated model updater logic into the Rake task for better maintainability.
  • Improved error handling and logging throughout the model update process.

- Removed the OpenAI capabilities module and related methods.
- Simplified model parsing for OpenAI and Gemini providers, focusing on essential attributes.
- Introduced a new utility method for deep key symbolization in hashes.
- Updated OpenRouter model parsing to enhance data extraction and structure.
- Deleted obsolete browser and CLI helper tasks to streamline the codebase.
- Consolidated model updater logic into the Rake task for better maintainability.
- Improved error handling and logging throughout the model update process.
@crmne crmne marked this pull request as draft April 22, 2025 10:34
@crmne crmne changed the title Refactor RubyLLM provider capabilities and model parsing to use Parsera Use Parsera LLM Specs API instead of capabilities.rb Apr 22, 2025
module Utils
module_function

def symbolize_keys_deep(hash)

Choose a reason for hiding this comment

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

This is like ActiveSupport's deep_symbolize_keys, which I also needed in 2 PRs here and here

You'll want to cover Array child items though, so I recommend just taking my/ActiveSupport's implementation and putting it here, then I'll refactor my PRs to use your Util method instead.

end

def fetch_parsera_models
response = Faraday.new('https://api.parsera.org/v1/llm-specs', request: { timeout: 60 })

Choose a reason for hiding this comment

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

I don't like the idea of a core dependency on a commercial 3rd party's API, though very much appreciate the value that Parsera is doing by standardizing LLM capabilities into a JSON.

I know the code isn't called during any main runtime functions and also appreciate the support from Parsera (seems like great company).

Maybe just move this code to the rake task? Don't feel strongly about this so if you don't want to that's fine.

@jayelkaake
Copy link

jayelkaake commented Apr 22, 2025

Love this - the initiative by Parsera to standarize capabilities of models is fantastic!

Although, I'm not confident that the LLMs are going to follow the same configs within the same capabilities so I question whether the capabilities should just be implemented in the provider classes (and if they're not implemented it means they aren't supported).

For example, structured output is supported by Gemini but it is a vastly different implementation than the other LLMs.

Anyways, still prob good to do this since it's just a better implementation of how the gem already works today.

crmne and others added 24 commits May 6, 2025 19:00
This PR implements the ability to specify custom dimensions when
generating embeddings, as requested in issue #47.

### What's included
- Added support for passing a dimensions parameter to the embed method
- Implemented dimensions handling in both OpenAI and Gemini providers
- Added tests to verify dimension param works correctly
- Optimized the Gemini provider's `embed` method to reduce unnecessary
API calls when embedding texts, resulting in lower token usage. From now
on, it uses `batchEmbedContents` endpoint within one request, for both
single and multiple text embeddings.
- Modernize Gemini embeddings following DIP principle, as implemented in
`openai/embeddings.rb`.
- The Gemini embeddings API response does not contain the
promptTokenCount attribute, so I have removed it.

### Implementation notes
I've decided to only implement the per-request dimension configuration
and not the global configuration option that was initially proposed in
the issue. This is because each embedding model has its own default
dimensions, making a global setting potentially confusing.

With this implementation, users can set the embedding dimensions like:
```ruby
embedding = RubyLLM.embed(
  "Ruby is a programmer's best friend",
  model: "text-embedding-3-small",
  dimensions: 512
)
```

### References
- OpenAI API docs:
https://platform.openai.com/docs/api-reference/embeddings
- Gemini API docs: https://ai.google.dev/api/embeddings

Resolves #47

---------

Co-authored-by: Carmine Paolino <[email protected]>
…s_chat

Previously, API errors during a chat turn would leave an orphaned, empty assistant message record. This caused issues, notably with Gemini rejecting subsequent requests containing empty messages.

Fixes #118
…lution in chat, embedding, and image methods

Now `assume_model_exists` can be used in `paint` and `embed` methods too.
Now uses POROs and simplifies implementation of providers.

Fixes #143
…llama provider

- Introduced `RubyLLM::Providers::Ollama::Media` module to manage media content formatting for OpenAI APIs.
- Implemented `format_content` method to process text and attachments, including images, PDFs, and audio.
- Added `format_image` method to convert image attachments into the required format.
…#151)

This updates the acts_as_message, acts_as_chat and acts_as_tool class
methods to use Rails-style foreign keys whenever custom class names are
used as options. For example:

```
class FooMessage < ActiveRecord::Base
  acts_as_message chat_class: 'FooChat', tool_call_class: 'FooToolCall'
end
```

will now set the foreign key on the `belongs_to :chat` association to be
`foo_chat_id`, instead of `chat_id`, and will set the foreign key on
`belongs_to :parent_tool_call` association to `foo_tool_call_id` instead
of just `tool_call_id`.

This is consistent with Rails' naming conventions for class names and
foreign keys. Changes are backwards-compatible with existing
code/behavior, and don't require a major or minor version bump.

Updated test cases to ensure that the associations are working, but
didn't re-record VCR tests, since I don't have an OpenAPI key.

Closes #150

Co-authored-by: Carmine Paolino <[email protected]>
## Purpose

Introduces some basic configuration for the logging capabilities,
allowing users to specify a custom log file and log level. This feature
enhances debugging and monitoring capabilities by providing more control
over where and how logs are recorded.

## Implementation Details

- Added log_file configuration option (default: STDOUT)
- Added log_level configuration option (default: INFO, or DEBUG if
RUBYLLM_DEBUG env var is set)
- Updated logger initialisation to use the configured log file and level
- Added documentation for logging configuration
- Maintained backward compatibility with existing logging behaviour

## Usage Example

```ruby
# Global configuration
RubyLLM.configure do |config|
  config.log_file = '/logs/ruby_llm.log'  # Custom log file location
  config.log_level = :debug  # Set log level
end
```

## Testing

Manual
- Verified logger initialisation with custom log file
- Confirmed log level changes based on configuration
- Tested environment variable override for debug level
- Validated default behaviour (STDOUT logging)

## Documentation

Added a new section in configuration.md for logging settings

Co-authored-by: Carmine Paolino <[email protected]>
crmne added 2 commits May 6, 2025 19:03
- Removed the OpenAI capabilities module and related methods.
- Simplified model parsing for OpenAI and Gemini providers, focusing on essential attributes.
- Introduced a new utility method for deep key symbolization in hashes.
- Updated OpenRouter model parsing to enhance data extraction and structure.
- Deleted obsolete browser and CLI helper tasks to streamline the codebase.
- Consolidated model updater logic into the Rake task for better maintainability.
- Improved error handling and logging throughout the model update process.
@crmne crmne closed this May 6, 2025
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.

5 participants