ruby_llm 1.16.0 → 2.0.0.rc4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rdoc_options +25 -0
- data/README.md +108 -44
- data/exe/ruby_llm +8 -0
- data/lib/generators/ruby_llm/agent/templates/agent.rb.tt +0 -1
- data/lib/generators/ruby_llm/chat_ui/chat_ui_generator.rb +3 -43
- data/lib/generators/ruby_llm/chat_ui/templates/controllers/chats_controller.rb.tt +11 -3
- data/lib/generators/ruby_llm/chat_ui/templates/controllers/messages_controller.rb.tt +8 -0
- data/lib/generators/ruby_llm/chat_ui/templates/controllers/models_controller.rb.tt +4 -4
- data/lib/generators/ruby_llm/chat_ui/templates/tailwind/views/chats/_chat.html.erb.tt +1 -1
- data/lib/generators/ruby_llm/chat_ui/templates/tailwind/views/chats/_form.html.erb.tt +1 -1
- data/lib/generators/ruby_llm/chat_ui/templates/tailwind/views/chats/index.html.erb.tt +1 -1
- data/lib/generators/ruby_llm/chat_ui/templates/tailwind/views/chats/show.html.erb.tt +2 -2
- data/lib/generators/ruby_llm/chat_ui/templates/tailwind/views/messages/_assistant.html.erb.tt +1 -1
- data/lib/generators/ruby_llm/chat_ui/templates/tailwind/views/messages/_system.html.erb.tt +1 -1
- data/lib/generators/ruby_llm/chat_ui/templates/tailwind/views/messages/_tool.html.erb.tt +1 -1
- data/lib/generators/ruby_llm/chat_ui/templates/tailwind/views/messages/_tool_calls.html.erb.tt +6 -4
- data/lib/generators/ruby_llm/chat_ui/templates/tailwind/views/messages/_user.html.erb.tt +1 -1
- data/lib/generators/ruby_llm/chat_ui/templates/tailwind/views/messages/tool_calls/_default.html.erb.tt +2 -2
- data/lib/generators/ruby_llm/chat_ui/templates/tailwind/views/models/_model.html.erb.tt +5 -6
- data/lib/generators/ruby_llm/chat_ui/templates/tailwind/views/models/index.html.erb.tt +2 -2
- data/lib/generators/ruby_llm/chat_ui/templates/tailwind/views/models/show.html.erb.tt +5 -5
- data/lib/generators/ruby_llm/chat_ui/templates/views/chats/_chat.html.erb.tt +1 -1
- data/lib/generators/ruby_llm/chat_ui/templates/views/chats/_form.html.erb.tt +1 -1
- data/lib/generators/ruby_llm/chat_ui/templates/views/chats/index.html.erb.tt +1 -1
- data/lib/generators/ruby_llm/chat_ui/templates/views/chats/show.html.erb.tt +2 -2
- data/lib/generators/ruby_llm/chat_ui/templates/views/messages/_assistant.html.erb.tt +1 -1
- data/lib/generators/ruby_llm/chat_ui/templates/views/messages/_system.html.erb.tt +1 -1
- data/lib/generators/ruby_llm/chat_ui/templates/views/messages/_tool.html.erb.tt +1 -1
- data/lib/generators/ruby_llm/chat_ui/templates/views/messages/_tool_calls.html.erb.tt +6 -4
- data/lib/generators/ruby_llm/chat_ui/templates/views/messages/_user.html.erb.tt +1 -1
- data/lib/generators/ruby_llm/chat_ui/templates/views/messages/create.turbo_stream.erb.tt +4 -6
- data/lib/generators/ruby_llm/chat_ui/templates/views/messages/tool_calls/_default.html.erb.tt +2 -2
- data/lib/generators/ruby_llm/chat_ui/templates/views/models/_model.html.erb.tt +5 -6
- data/lib/generators/ruby_llm/chat_ui/templates/views/models/index.html.erb.tt +2 -2
- data/lib/generators/ruby_llm/chat_ui/templates/views/models/show.html.erb.tt +3 -3
- data/lib/generators/ruby_llm/generator_helpers.rb +106 -62
- data/lib/generators/ruby_llm/install/install_generator.rb +3 -11
- data/lib/generators/ruby_llm/install/templates/create_chats_migration.rb.tt +2 -0
- data/lib/generators/ruby_llm/install/templates/create_messages_migration.rb.tt +14 -8
- data/lib/generators/ruby_llm/install/templates/create_ruby_llm_records_migration.rb.tt +117 -0
- data/lib/generators/ruby_llm/install/templates/initializer.rb.tt +0 -8
- data/lib/generators/ruby_llm/provider/cli.rb +175 -0
- data/lib/generators/ruby_llm/provider/scaffold.rb +323 -0
- data/lib/generators/ruby_llm/provider/templates/core/provider.rb.erb +37 -0
- data/lib/generators/ruby_llm/provider/templates/core/provider_spec.rb.erb +34 -0
- data/lib/generators/ruby_llm/provider/templates/gem/archspec.rb.erb +14 -0
- data/lib/generators/ruby_llm/provider/templates/gem/bin/console.erb +15 -0
- data/lib/generators/ruby_llm/provider/templates/gem/bin/setup.erb +5 -0
- data/lib/generators/ruby_llm/provider/templates/gem/chat_schema_spec.rb.erb +30 -0
- data/lib/generators/ruby_llm/provider/templates/gem/chat_spec.rb.erb +35 -0
- data/lib/generators/ruby_llm/provider/templates/gem/chat_streaming_spec.rb.erb +22 -0
- data/lib/generators/ruby_llm/provider/templates/gem/chat_tools_spec.rb.erb +30 -0
- data/lib/generators/ruby_llm/provider/templates/gem/ci.yml.erb +32 -0
- data/lib/generators/ruby_llm/provider/templates/gem/embedding_spec.rb.erb +49 -0
- data/lib/generators/ruby_llm/provider/templates/gem/env.erb +2 -0
- data/lib/generators/ruby_llm/provider/templates/gem/fixtures_gitkeep.erb +1 -0
- data/lib/generators/ruby_llm/provider/templates/gem/flayignore.erb +1 -0
- data/lib/generators/ruby_llm/provider/templates/gem/gemfile.erb +23 -0
- data/lib/generators/ruby_llm/provider/templates/gem/gemspec.erb +28 -0
- data/lib/generators/ruby_llm/provider/templates/gem/gitignore.erb +7 -0
- data/lib/generators/ruby_llm/provider/templates/gem/gitleaks.yml.erb +22 -0
- data/lib/generators/ruby_llm/provider/templates/gem/image_spec.rb.erb +23 -0
- data/lib/generators/ruby_llm/provider/templates/gem/license.erb +21 -0
- data/lib/generators/ruby_llm/provider/templates/gem/models.rb.erb +19 -0
- data/lib/generators/ruby_llm/provider/templates/gem/models_spec.rb.erb +17 -0
- data/lib/generators/ruby_llm/provider/templates/gem/moderation_spec.rb.erb +22 -0
- data/lib/generators/ruby_llm/provider/templates/gem/overcommit.yml.erb +31 -0
- data/lib/generators/ruby_llm/provider/templates/gem/provider.rb.erb +52 -0
- data/lib/generators/ruby_llm/provider/templates/gem/provider_spec.rb.erb +38 -0
- data/lib/generators/ruby_llm/provider/templates/gem/rakefile.erb +38 -0
- data/lib/generators/ruby_llm/provider/templates/gem/readme.md.erb +50 -0
- data/lib/generators/ruby_llm/provider/templates/gem/release.yml.erb +36 -0
- data/lib/generators/ruby_llm/provider/templates/gem/rerank_spec.rb.erb +23 -0
- data/lib/generators/ruby_llm/provider/templates/gem/rspec.erb +2 -0
- data/lib/generators/ruby_llm/provider/templates/gem/rubocop.yml.erb +29 -0
- data/lib/generators/ruby_llm/provider/templates/gem/rubyllm_configuration.rb.erb +14 -0
- data/lib/generators/ruby_llm/provider/templates/gem/spec_helper.rb.erb +26 -0
- data/lib/generators/ruby_llm/provider/templates/gem/speech_spec.rb.erb +25 -0
- data/lib/generators/ruby_llm/provider/templates/gem/vcr_configuration.rb.erb +16 -0
- data/lib/generators/ruby_llm/provider/templates/gem/video_spec.rb.erb +27 -0
- data/lib/generators/ruby_llm/schema/schema_generator.rb +5 -1
- data/lib/generators/ruby_llm/schema/templates/schema.rb.tt +1 -1
- data/lib/generators/ruby_llm/tool/templates/tailwind/tool_call.html.erb.tt +13 -0
- data/lib/generators/ruby_llm/tool/templates/tailwind/tool_result.html.erb.tt +21 -0
- data/lib/generators/ruby_llm/tool/templates/tool.rb.tt +3 -3
- data/lib/generators/ruby_llm/tool/templates/tool_call.html.erb.tt +7 -12
- data/lib/generators/ruby_llm/tool/templates/tool_result.html.erb.tt +5 -2
- data/lib/generators/ruby_llm/tool/tool_generator.rb +25 -59
- data/lib/generators/ruby_llm/upgrade/legacy_content_sql.rb +34 -0
- data/lib/generators/ruby_llm/upgrade/online_copy_migration/data.rb +341 -0
- data/lib/generators/ruby_llm/upgrade/online_copy_migration/journal.rb +171 -0
- data/lib/generators/ruby_llm/upgrade/online_copy_migration/verification.rb +197 -0
- data/lib/generators/ruby_llm/upgrade/online_copy_migration.rb +174 -0
- data/lib/generators/ruby_llm/upgrade/templates/backfill_v2_data.rb.tt +468 -0
- data/lib/generators/ruby_llm/upgrade/templates/cleanup_v2_upgrade.rb.tt +101 -0
- data/lib/generators/ruby_llm/upgrade/templates/finish_v2_upgrade.rb.tt +247 -0
- data/lib/generators/ruby_llm/upgrade/templates/prepare_v2_upgrade.rb.tt +662 -0
- data/lib/generators/ruby_llm/upgrade/templates/ruby_llm_upgrade.rb.tt +251 -0
- data/lib/generators/ruby_llm/upgrade/templates/upgrade_initializer.rb.tt +13 -0
- data/lib/generators/ruby_llm/upgrade/upgrade_generator.rb +188 -0
- data/lib/generators/ruby_llm/upgrade/upgrade_migration.rb +359 -0
- data/lib/ruby_llm/accounting/usage.rb +254 -0
- data/lib/ruby_llm/active_record/acts_as.rb +94 -111
- data/lib/ruby_llm/active_record/attachment_helpers.rb +186 -0
- data/lib/ruby_llm/active_record/batch.rb +97 -0
- data/lib/ruby_llm/active_record/chat_methods.rb +828 -305
- data/lib/ruby_llm/active_record/message_methods.rb +113 -136
- data/lib/ruby_llm/active_record/model.rb +135 -0
- data/lib/ruby_llm/active_record/payload_helpers.rb +1 -2
- data/lib/ruby_llm/active_record/tool_call.rb +33 -0
- data/lib/ruby_llm/active_record/usage.rb +61 -0
- data/lib/ruby_llm/agent.rb +1066 -151
- data/lib/ruby_llm/aliases.json +291 -101
- data/lib/ruby_llm/attachment.rb +192 -48
- data/lib/ruby_llm/batch.rb +432 -0
- data/lib/ruby_llm/cached_content.rb +112 -0
- data/lib/ruby_llm/chat/tool_concurrency.rb +111 -0
- data/lib/ruby_llm/chat.rb +1131 -198
- data/lib/ruby_llm/chunk.rb +10 -0
- data/lib/ruby_llm/citation.rb +105 -0
- data/lib/ruby_llm/configuration.rb +261 -24
- data/lib/ruby_llm/context.rb +128 -6
- data/lib/ruby_llm/cost.rb +217 -80
- data/lib/ruby_llm/downloaded_file.rb +33 -0
- data/lib/ruby_llm/embedding.rb +121 -17
- data/lib/ruby_llm/embedding_request.rb +53 -0
- data/lib/ruby_llm/error.rb +159 -23
- data/lib/ruby_llm/fallback.rb +133 -0
- data/lib/ruby_llm/files/mime_type.rb +97 -0
- data/lib/ruby_llm/image.rb +153 -32
- data/lib/ruby_llm/message.rb +242 -54
- data/lib/ruby_llm/model/modalities.rb +17 -4
- data/lib/ruby_llm/model/pricing.rb +24 -5
- data/lib/ruby_llm/model/pricing_category.rb +103 -14
- data/lib/ruby_llm/model/pricing_tier.rb +55 -15
- data/lib/ruby_llm/model.rb +244 -2
- data/lib/ruby_llm/models/aliases.rb +41 -0
- data/lib/ruby_llm/models/registry.rb +165 -0
- data/lib/ruby_llm/models/schema.rb +99 -0
- data/lib/ruby_llm/models.json +76038 -34173
- data/lib/ruby_llm/models.rb +477 -215
- data/lib/ruby_llm/moderation.rb +139 -26
- data/lib/ruby_llm/ocr.rb +112 -0
- data/lib/ruby_llm/prompt.rb +79 -0
- data/lib/ruby_llm/protocol/binary_streaming.rb +65 -0
- data/lib/ruby_llm/protocol/stream_accumulator.rb +214 -0
- data/lib/ruby_llm/protocol/streaming.rb +230 -0
- data/lib/ruby_llm/protocol.rb +662 -0
- data/lib/ruby_llm/protocols/anthropic/batches.rb +73 -0
- data/lib/ruby_llm/protocols/anthropic/chat.rb +543 -0
- data/lib/ruby_llm/protocols/anthropic/embeddings.rb +14 -0
- data/lib/ruby_llm/protocols/anthropic/files.rb +38 -0
- data/lib/ruby_llm/protocols/anthropic/media.rb +141 -0
- data/lib/ruby_llm/protocols/anthropic/models.rb +129 -0
- data/lib/ruby_llm/protocols/anthropic/streaming.rb +167 -0
- data/lib/ruby_llm/{providers → protocols}/anthropic/tools.rb +24 -41
- data/lib/ruby_llm/protocols/anthropic.rb +101 -0
- data/lib/ruby_llm/protocols/azure/files.rb +16 -0
- data/lib/ruby_llm/protocols/bedrock/async_videos.rb +110 -0
- data/lib/ruby_llm/protocols/bedrock/batches.rb +129 -0
- data/lib/ruby_llm/protocols/bedrock/files.rb +110 -0
- data/lib/ruby_llm/protocols/bedrock/guardrails.rb +122 -0
- data/lib/ruby_llm/protocols/bedrock/rerank.rb +95 -0
- data/lib/ruby_llm/protocols/chat_completions/batches.rb +32 -0
- data/lib/ruby_llm/protocols/chat_completions/chat.rb +484 -0
- data/lib/ruby_llm/protocols/chat_completions/embedding_batches.rb +35 -0
- data/lib/ruby_llm/protocols/chat_completions/embeddings.rb +60 -0
- data/lib/ruby_llm/protocols/chat_completions/images.rb +127 -0
- data/lib/ruby_llm/{providers/openai → protocols/chat_completions}/media.rb +30 -17
- data/lib/ruby_llm/protocols/chat_completions/models.rb +39 -0
- data/lib/ruby_llm/protocols/chat_completions/moderation.rb +52 -0
- data/lib/ruby_llm/protocols/chat_completions/rerank.rb +63 -0
- data/lib/ruby_llm/protocols/chat_completions/speech.rb +40 -0
- data/lib/ruby_llm/protocols/chat_completions/streaming.rb +69 -0
- data/lib/ruby_llm/{providers/openai → protocols/chat_completions}/tools.rb +15 -17
- data/lib/ruby_llm/protocols/chat_completions/transcription.rb +150 -0
- data/lib/ruby_llm/protocols/chat_completions.rb +21 -0
- data/lib/ruby_llm/protocols/cohere/batch_requests.rb +75 -0
- data/lib/ruby_llm/protocols/cohere/batches.rb +98 -0
- data/lib/ruby_llm/protocols/cohere/chat.rb +227 -0
- data/lib/ruby_llm/protocols/cohere/datasets.rb +102 -0
- data/lib/ruby_llm/protocols/cohere/embeddings.rb +68 -0
- data/lib/ruby_llm/protocols/cohere/media.rb +77 -0
- data/lib/ruby_llm/protocols/cohere/models.rb +92 -0
- data/lib/ruby_llm/protocols/cohere/ocr.rb +63 -0
- data/lib/ruby_llm/protocols/cohere/rerank.rb +59 -0
- data/lib/ruby_llm/protocols/cohere/streaming.rb +105 -0
- data/lib/ruby_llm/protocols/cohere/tokenization.rb +22 -0
- data/lib/ruby_llm/protocols/cohere/tools.rb +132 -0
- data/lib/ruby_llm/protocols/cohere/transcription.rb +41 -0
- data/lib/ruby_llm/protocols/cohere.rb +21 -0
- data/lib/ruby_llm/protocols/converse/batches.rb +55 -0
- data/lib/ruby_llm/protocols/converse/chat.rb +694 -0
- data/lib/ruby_llm/protocols/converse/media.rb +178 -0
- data/lib/ruby_llm/protocols/converse/streaming.rb +432 -0
- data/lib/ruby_llm/protocols/converse/thinking_stream.rb +56 -0
- data/lib/ruby_llm/protocols/converse.rb +54 -0
- data/lib/ruby_llm/protocols/deepgram/models.rb +74 -0
- data/lib/ruby_llm/protocols/deepgram/speech.rb +93 -0
- data/lib/ruby_llm/protocols/deepgram/streaming_transcription.rb +89 -0
- data/lib/ruby_llm/protocols/deepgram/transcription.rb +96 -0
- data/lib/ruby_llm/protocols/deepgram.rb +19 -0
- data/lib/ruby_llm/protocols/deepseek/files.rb +31 -0
- data/lib/ruby_llm/protocols/elevenlabs/assets.rb +36 -0
- data/lib/ruby_llm/protocols/elevenlabs/flows/images.rb +74 -0
- data/lib/ruby_llm/protocols/elevenlabs/flows/media.rb +42 -0
- data/lib/ruby_llm/protocols/elevenlabs/flows/videos.rb +93 -0
- data/lib/ruby_llm/protocols/elevenlabs/flows.rb +14 -0
- data/lib/ruby_llm/protocols/elevenlabs/models.rb +64 -0
- data/lib/ruby_llm/protocols/elevenlabs/speech.rb +67 -0
- data/lib/ruby_llm/protocols/elevenlabs/streaming_transcription.rb +127 -0
- data/lib/ruby_llm/protocols/elevenlabs/transcription.rb +61 -0
- data/lib/ruby_llm/protocols/elevenlabs.rb +15 -0
- data/lib/ruby_llm/protocols/files.rb +119 -0
- data/lib/ruby_llm/protocols/gemini/batches.rb +162 -0
- data/lib/ruby_llm/protocols/gemini/caches.rb +59 -0
- data/lib/ruby_llm/protocols/gemini/chat.rb +453 -0
- data/lib/ruby_llm/protocols/gemini/embedding_batches.rb +91 -0
- data/lib/ruby_llm/protocols/gemini/embeddings.rb +70 -0
- data/lib/ruby_llm/protocols/gemini/file_transcription.rb +32 -0
- data/lib/ruby_llm/protocols/gemini/files.rb +115 -0
- data/lib/ruby_llm/protocols/gemini/images.rb +183 -0
- data/lib/ruby_llm/protocols/gemini/live_transcription.rb +140 -0
- data/lib/ruby_llm/{providers → protocols}/gemini/media.rb +17 -11
- data/lib/ruby_llm/protocols/gemini/models.rb +71 -0
- data/lib/ruby_llm/protocols/gemini/speech.rb +56 -0
- data/lib/ruby_llm/protocols/gemini/streaming.rb +96 -0
- data/lib/ruby_llm/protocols/gemini/tools.rb +157 -0
- data/lib/ruby_llm/{providers → protocols}/gemini/transcription.rb +22 -22
- data/lib/ruby_llm/protocols/gemini/videos.rb +103 -0
- data/lib/ruby_llm/protocols/gemini.rb +35 -0
- data/lib/ruby_llm/protocols/gpustack/responses.rb +111 -0
- data/lib/ruby_llm/protocols/gpustack/tokenization.rb +22 -0
- data/lib/ruby_llm/protocols/gpustack/videos.rb +96 -0
- data/lib/ruby_llm/protocols/interactions/chat.rb +145 -0
- data/lib/ruby_llm/protocols/interactions/content.rb +90 -0
- data/lib/ruby_llm/protocols/interactions/streaming.rb +91 -0
- data/lib/ruby_llm/protocols/interactions/tools.rb +53 -0
- data/lib/ruby_llm/protocols/interactions/transcription.rb +58 -0
- data/lib/ruby_llm/protocols/interactions.rb +29 -0
- data/lib/ruby_llm/protocols/invoke_model/cohere_embeddings.rb +51 -0
- data/lib/ruby_llm/protocols/invoke_model/embedding_batches.rb +111 -0
- data/lib/ruby_llm/protocols/invoke_model/nova_embeddings.rb +50 -0
- data/lib/ruby_llm/protocols/invoke_model/stability_images.rb +103 -0
- data/lib/ruby_llm/protocols/invoke_model/titan_multimodal_embeddings.rb +33 -0
- data/lib/ruby_llm/protocols/invoke_model/titan_text_embeddings.rb +44 -0
- data/lib/ruby_llm/protocols/invoke_model.rb +57 -0
- data/lib/ruby_llm/protocols/mistral/content.rb +49 -0
- data/lib/ruby_llm/protocols/mistral/conversations/chat.rb +160 -0
- data/lib/ruby_llm/protocols/mistral/conversations/images.rb +43 -0
- data/lib/ruby_llm/protocols/mistral/conversations/streaming.rb +83 -0
- data/lib/ruby_llm/protocols/mistral/conversations.rb +30 -0
- data/lib/ruby_llm/protocols/mistral/files.rb +36 -0
- data/lib/ruby_llm/protocols/mistral/multi_completion.rb +160 -0
- data/lib/ruby_llm/protocols/openai/batches.rb +126 -0
- data/lib/ruby_llm/protocols/openai/files.rb +42 -0
- data/lib/ruby_llm/protocols/openrouter/batches.rb +147 -0
- data/lib/ruby_llm/protocols/openrouter/files.rb +24 -0
- data/lib/ruby_llm/protocols/openrouter/responses.rb +53 -0
- data/lib/ruby_llm/protocols/openrouter/transcription.rb +51 -0
- data/lib/ruby_llm/protocols/perplexity/files.rb +48 -0
- data/lib/ruby_llm/protocols/perplexity/router.rb +59 -0
- data/lib/ruby_llm/protocols/responses/approvals.rb +32 -0
- data/lib/ruby_llm/protocols/responses/batches.rb +32 -0
- data/lib/ruby_llm/protocols/responses/chat.rb +466 -0
- data/lib/ruby_llm/protocols/responses/compaction.rb +29 -0
- data/lib/ruby_llm/protocols/responses/media.rb +61 -0
- data/lib/ruby_llm/protocols/responses/streaming.rb +117 -0
- data/lib/ruby_llm/protocols/responses/token_counting.rb +26 -0
- data/lib/ruby_llm/protocols/responses/tools.rb +39 -0
- data/lib/ruby_llm/protocols/responses.rb +35 -0
- data/lib/ruby_llm/protocols/vertexai/batch_prediction.rb +155 -0
- data/lib/ruby_llm/protocols/vertexai/embedding_prediction/requests.rb +85 -0
- data/lib/ruby_llm/protocols/vertexai/embedding_prediction/results.rb +74 -0
- data/lib/ruby_llm/protocols/vertexai/embedding_prediction.rb +56 -0
- data/lib/ruby_llm/protocols/vertexai/files.rb +101 -0
- data/lib/ruby_llm/protocols/vertexai/ranking.rb +69 -0
- data/lib/ruby_llm/protocols/vertexai/research.rb +193 -0
- data/lib/ruby_llm/protocols/xai/files.rb +30 -0
- data/lib/ruby_llm/protocols/xai/streaming_transcription.rb +120 -0
- data/lib/ruby_llm/protocols/xai/tokenization.rb +23 -0
- data/lib/ruby_llm/provider.rb +560 -128
- data/lib/ruby_llm/providers/anthropic/capabilities.rb +5 -7
- data/lib/ruby_llm/providers/anthropic.rb +4 -6
- data/lib/ruby_llm/providers/azure/audio.rb +18 -0
- data/lib/ruby_llm/providers/azure/capabilities.rb +16 -0
- data/lib/ruby_llm/providers/azure/chat.rb +2 -9
- data/lib/ruby_llm/providers/azure/chat_completions/batches.rb +29 -0
- data/lib/ruby_llm/providers/azure/chat_completions.rb +80 -0
- data/lib/ruby_llm/providers/azure/cohere.rb +33 -0
- data/lib/ruby_llm/providers/azure/embeddings.rb +3 -2
- data/lib/ruby_llm/providers/azure/images.rb +22 -0
- data/lib/ruby_llm/providers/azure/media.rb +5 -14
- data/lib/ruby_llm/providers/azure/models.rb +35 -0
- data/lib/ruby_llm/providers/azure/responses.rb +26 -0
- data/lib/ruby_llm/providers/azure/videos.rb +64 -0
- data/lib/ruby_llm/providers/azure.rb +77 -78
- data/lib/ruby_llm/providers/bedrock/auth.rb +60 -41
- data/lib/ruby_llm/providers/bedrock/capabilities.rb +18 -0
- data/lib/ruby_llm/providers/bedrock/mantle/anthropic.rb +39 -0
- data/lib/ruby_llm/providers/bedrock/mantle/chat_completions.rb +23 -0
- data/lib/ruby_llm/providers/bedrock/mantle/responses.rb +24 -0
- data/lib/ruby_llm/providers/bedrock/mantle/voxtral.rb +96 -0
- data/lib/ruby_llm/providers/bedrock/mantle.rb +57 -0
- data/lib/ruby_llm/providers/bedrock/models.rb +193 -41
- data/lib/ruby_llm/providers/bedrock.rb +216 -45
- data/lib/ruby_llm/providers/cohere.rb +31 -0
- data/lib/ruby_llm/providers/deepgram.rb +37 -0
- data/lib/ruby_llm/providers/deepseek/capabilities.rb +4 -51
- data/lib/ruby_llm/providers/deepseek/chat.rb +49 -2
- data/lib/ruby_llm/providers/deepseek/responses.rb +67 -0
- data/lib/ruby_llm/providers/deepseek.rb +9 -2
- data/lib/ruby_llm/providers/elevenlabs.rb +35 -0
- data/lib/ruby_llm/providers/gemini/capabilities.rb +8 -107
- data/lib/ruby_llm/providers/gemini.rb +15 -8
- data/lib/ruby_llm/providers/gpustack/chat.rb +2 -16
- data/lib/ruby_llm/providers/gpustack/embeddings.rb +28 -0
- data/lib/ruby_llm/providers/gpustack/media.rb +17 -16
- data/lib/ruby_llm/providers/gpustack/models.rb +72 -62
- data/lib/ruby_llm/providers/gpustack/speech.rb +15 -0
- data/lib/ruby_llm/providers/gpustack/transcription.rb +29 -0
- data/lib/ruby_llm/providers/gpustack.rb +35 -11
- data/lib/ruby_llm/providers/mistral/capabilities.rb +7 -155
- data/lib/ruby_llm/providers/mistral/chat.rb +37 -61
- data/lib/ruby_llm/providers/mistral/chat_completions/batches.rb +120 -0
- data/lib/ruby_llm/providers/mistral/chat_completions.rb +21 -0
- data/lib/ruby_llm/providers/mistral/conversations.rb +12 -0
- data/lib/ruby_llm/providers/mistral/embeddings.rb +6 -4
- data/lib/ruby_llm/providers/mistral/media.rb +6 -18
- data/lib/ruby_llm/providers/mistral/models.rb +57 -23
- data/lib/ruby_llm/providers/mistral/ocr.rb +51 -0
- data/lib/ruby_llm/providers/mistral/speech.rb +51 -0
- data/lib/ruby_llm/providers/mistral/transcription.rb +62 -0
- data/lib/ruby_llm/providers/mistral.rb +16 -4
- data/lib/ruby_llm/providers/ollama/chat.rb +7 -13
- data/lib/ruby_llm/providers/ollama/media.rb +6 -15
- data/lib/ruby_llm/providers/ollama/models.rb +50 -9
- data/lib/ruby_llm/providers/ollama.rb +9 -8
- data/lib/ruby_llm/providers/ollama_cloud/models.rb +14 -0
- data/lib/ruby_llm/providers/ollama_cloud.rb +40 -0
- data/lib/ruby_llm/providers/openai/capabilities.rb +54 -259
- data/lib/ruby_llm/providers/openai/models.rb +23 -23
- data/lib/ruby_llm/providers/openai/responses.rb +13 -0
- data/lib/ruby_llm/providers/openai.rb +92 -11
- data/lib/ruby_llm/providers/openrouter/chat.rb +126 -108
- data/lib/ruby_llm/providers/openrouter/embeddings.rb +51 -0
- data/lib/ruby_llm/providers/openrouter/images.rb +44 -43
- data/lib/ruby_llm/providers/openrouter/media.rb +34 -0
- data/lib/ruby_llm/providers/openrouter/models.rb +50 -11
- data/lib/ruby_llm/providers/openrouter/speech.rb +32 -0
- data/lib/ruby_llm/providers/openrouter/streaming.rb +31 -38
- data/lib/ruby_llm/providers/openrouter/videos.rb +81 -0
- data/lib/ruby_llm/providers/openrouter.rb +78 -20
- data/lib/ruby_llm/providers/perplexity/chat.rb +2 -9
- data/lib/ruby_llm/providers/perplexity/embeddings.rb +32 -0
- data/lib/ruby_llm/providers/perplexity/media.rb +5 -21
- data/lib/ruby_llm/providers/perplexity/models.rb +80 -13
- data/lib/ruby_llm/providers/perplexity.rb +28 -20
- data/lib/ruby_llm/providers/vertexai/anthropic/batches.rb +52 -0
- data/lib/ruby_llm/providers/vertexai/anthropic.rb +34 -0
- data/lib/ruby_llm/providers/vertexai/capabilities.rb +19 -0
- data/lib/ruby_llm/providers/vertexai/chat_completions/batches.rb +54 -0
- data/lib/ruby_llm/providers/vertexai/chat_completions.rb +15 -0
- data/lib/ruby_llm/providers/vertexai/embed_content.rb +42 -0
- data/lib/ruby_llm/providers/vertexai/embeddings.rb +22 -7
- data/lib/ruby_llm/providers/vertexai/gemini/batches.rb +42 -0
- data/lib/ruby_llm/providers/vertexai/gemini.rb +69 -0
- data/lib/ruby_llm/providers/vertexai/live_transcription.rb +24 -0
- data/lib/ruby_llm/providers/vertexai/mistral.rb +28 -0
- data/lib/ruby_llm/providers/vertexai/models.rb +145 -43
- data/lib/ruby_llm/providers/vertexai/transcription.rb +49 -4
- data/lib/ruby_llm/providers/vertexai/videos.rb +61 -0
- data/lib/ruby_llm/providers/vertexai.rb +160 -17
- data/lib/ruby_llm/providers/xai/capabilities.rb +18 -0
- data/lib/ruby_llm/providers/xai/chat.rb +3 -2
- data/lib/ruby_llm/providers/xai/chat_completions/batches.rb +108 -0
- data/lib/ruby_llm/providers/xai/chat_completions.rb +19 -0
- data/lib/ruby_llm/providers/xai/images.rb +91 -0
- data/lib/ruby_llm/providers/xai/models.rb +32 -36
- data/lib/ruby_llm/providers/xai/reported_cost.rb +18 -0
- data/lib/ruby_llm/providers/xai/responses.rb +52 -0
- data/lib/ruby_llm/providers/xai/speech.rb +45 -0
- data/lib/ruby_llm/providers/xai/transcription.rb +48 -0
- data/lib/ruby_llm/providers/xai/videos.rb +87 -0
- data/lib/ruby_llm/providers/xai.rb +15 -5
- data/lib/ruby_llm/railtie.rb +7 -16
- data/lib/ruby_llm/rerank.rb +105 -0
- data/lib/ruby_llm/research_job.rb +241 -0
- data/lib/ruby_llm/search_results.rb +68 -0
- data/lib/ruby_llm/server_tool_call.rb +73 -0
- data/lib/ruby_llm/speech.rb +159 -0
- data/lib/ruby_llm/speech_chunk.rb +33 -0
- data/lib/ruby_llm/support/deprecator.rb +22 -0
- data/lib/ruby_llm/support/inspectable.rb +49 -0
- data/lib/ruby_llm/support/instrumentation.rb +41 -0
- data/lib/ruby_llm/support/utils.rb +147 -0
- data/lib/ruby_llm/thinking.rb +127 -20
- data/lib/ruby_llm/tokenization.rb +59 -0
- data/lib/ruby_llm/tokens.rb +103 -33
- data/lib/ruby_llm/tool.rb +266 -91
- data/lib/ruby_llm/tool_call.rb +36 -3
- data/lib/ruby_llm/tools/server_tools.rb +109 -0
- data/lib/ruby_llm/transcription/wav_audio.rb +62 -0
- data/lib/ruby_llm/transcription.rb +138 -13
- data/lib/ruby_llm/transcription_chunk.rb +68 -0
- data/lib/ruby_llm/transport/connection.rb +193 -0
- data/lib/ruby_llm/transport/error_middleware.rb +131 -0
- data/lib/ruby_llm/transport/usage_middleware.rb +28 -0
- data/lib/ruby_llm/transport/websocket_connection.rb +220 -0
- data/lib/ruby_llm/uploaded_file.rb +144 -0
- data/lib/ruby_llm/version.rb +2 -1
- data/lib/ruby_llm/video.rb +136 -0
- data/lib/ruby_llm/video_job.rb +150 -0
- data/lib/ruby_llm/workflow.rb +91 -0
- data/lib/ruby_llm.rb +380 -6
- data/lib/tasks/ruby_llm.rake +21 -16
- data/skills/rubyllm/SKILL.md +81 -0
- data/skills/rubyllm/agents/openai.yaml +4 -0
- metadata +344 -97
- data/lib/generators/ruby_llm/install/templates/add_references_to_chats_tool_calls_and_messages_migration.rb.tt +0 -9
- data/lib/generators/ruby_llm/install/templates/create_models_migration.rb.tt +0 -39
- data/lib/generators/ruby_llm/install/templates/create_tool_calls_migration.rb.tt +0 -21
- data/lib/generators/ruby_llm/install/templates/model_model.rb.tt +0 -3
- data/lib/generators/ruby_llm/install/templates/tool_call_model.rb.tt +0 -3
- data/lib/generators/ruby_llm/upgrade_to_v1_10/templates/add_v1_10_message_columns.rb.tt +0 -19
- data/lib/generators/ruby_llm/upgrade_to_v1_10/upgrade_to_v1_10_generator.rb +0 -50
- data/lib/generators/ruby_llm/upgrade_to_v1_14/templates/add_v1_14_tool_call_columns.rb.tt +0 -7
- data/lib/generators/ruby_llm/upgrade_to_v1_14/upgrade_to_v1_14_generator.rb +0 -49
- data/lib/generators/ruby_llm/upgrade_to_v1_7/templates/migration.rb.tt +0 -145
- data/lib/generators/ruby_llm/upgrade_to_v1_7/upgrade_to_v1_7_generator.rb +0 -122
- data/lib/generators/ruby_llm/upgrade_to_v1_9/templates/add_v1_9_message_columns.rb.tt +0 -15
- data/lib/generators/ruby_llm/upgrade_to_v1_9/upgrade_to_v1_9_generator.rb +0 -49
- data/lib/ruby_llm/active_record/acts_as_legacy.rb +0 -597
- data/lib/ruby_llm/active_record/model_methods.rb +0 -82
- data/lib/ruby_llm/active_record/tool_call_methods.rb +0 -18
- data/lib/ruby_llm/aliases.rb +0 -41
- data/lib/ruby_llm/connection.rb +0 -159
- data/lib/ruby_llm/content.rb +0 -91
- data/lib/ruby_llm/deprecator.rb +0 -24
- data/lib/ruby_llm/error_middleware.rb +0 -81
- data/lib/ruby_llm/instrumentation.rb +0 -36
- data/lib/ruby_llm/mime_type.rb +0 -96
- data/lib/ruby_llm/model/info.rb +0 -164
- data/lib/ruby_llm/model_registry.rb +0 -39
- data/lib/ruby_llm/models_schema.json +0 -171
- data/lib/ruby_llm/providers/anthropic/chat.rb +0 -291
- data/lib/ruby_llm/providers/anthropic/content.rb +0 -44
- data/lib/ruby_llm/providers/anthropic/embeddings.rb +0 -20
- data/lib/ruby_llm/providers/anthropic/media.rb +0 -92
- data/lib/ruby_llm/providers/anthropic/models.rb +0 -59
- data/lib/ruby_llm/providers/anthropic/streaming.rb +0 -71
- data/lib/ruby_llm/providers/bedrock/chat.rb +0 -405
- data/lib/ruby_llm/providers/bedrock/media.rb +0 -108
- data/lib/ruby_llm/providers/bedrock/streaming.rb +0 -328
- data/lib/ruby_llm/providers/gemini/chat.rb +0 -542
- data/lib/ruby_llm/providers/gemini/embeddings.rb +0 -37
- data/lib/ruby_llm/providers/gemini/images.rb +0 -47
- data/lib/ruby_llm/providers/gemini/models.rb +0 -38
- data/lib/ruby_llm/providers/gemini/streaming.rb +0 -98
- data/lib/ruby_llm/providers/gemini/tools.rb +0 -234
- data/lib/ruby_llm/providers/gpustack/capabilities.rb +0 -20
- data/lib/ruby_llm/providers/ollama/capabilities.rb +0 -20
- data/lib/ruby_llm/providers/openai/chat.rb +0 -236
- data/lib/ruby_llm/providers/openai/embeddings.rb +0 -33
- data/lib/ruby_llm/providers/openai/images.rb +0 -90
- data/lib/ruby_llm/providers/openai/moderation.rb +0 -34
- data/lib/ruby_llm/providers/openai/streaming.rb +0 -55
- data/lib/ruby_llm/providers/openai/temperature.rb +0 -28
- data/lib/ruby_llm/providers/openai/transcription.rb +0 -71
- data/lib/ruby_llm/providers/perplexity/capabilities.rb +0 -72
- data/lib/ruby_llm/providers/vertexai/chat.rb +0 -14
- data/lib/ruby_llm/providers/vertexai/streaming.rb +0 -14
- data/lib/ruby_llm/stream_accumulator.rb +0 -218
- data/lib/ruby_llm/streaming.rb +0 -179
- data/lib/ruby_llm/tool_concurrency.rb +0 -105
- data/lib/ruby_llm/utils.rb +0 -130
- data/lib/tasks/models.rake +0 -593
- data/lib/tasks/release.rake +0 -94
- data/lib/tasks/vcr.rake +0 -124
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c047801a2b7a5a642296f0ae84e81ab29b641353ffe8618b3ece44db0b0a3849
|
|
4
|
+
data.tar.gz: 05e4624f14a8e2045408dd21007758612f0644522bae4e250902fd60d66955e1
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 6e73e5f6818e70c607c3cabfc6e0dfb19f9271491375b71279e0a205f2ecff8fe0051c691c51230644d32f7ad8f377b8f8bddfcae919e33ff64015ccd9a942e7
|
|
7
|
+
data.tar.gz: fd4285734764621dc2cab77579b8c713aaff907930c1b6849472c470839b2a75e6975832baf4e43adeedd1d3326b92af816af4a63242bdfa2585fab2b72fdc58
|
data/.rdoc_options
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: RubyLLM
|
|
3
|
+
exclude:
|
|
4
|
+
- lib/ruby_llm/providers/
|
|
5
|
+
- lib/ruby_llm/protocols/
|
|
6
|
+
- lib/ruby_llm/protocol/
|
|
7
|
+
- lib/ruby_llm/transport/
|
|
8
|
+
- lib/ruby_llm/support/
|
|
9
|
+
- lib/ruby_llm/accounting/
|
|
10
|
+
- lib/ruby_llm/files/
|
|
11
|
+
- lib/ruby_llm/tools/
|
|
12
|
+
- lib/ruby_llm/models/
|
|
13
|
+
- lib/ruby_llm/chat/tool_concurrency\.rb$
|
|
14
|
+
- lib/ruby_llm/transcription/wav_audio\.rb$
|
|
15
|
+
- lib/tasks/
|
|
16
|
+
- lib/generators/
|
|
17
|
+
- \.json$
|
|
18
|
+
footer_content:
|
|
19
|
+
Documentation:
|
|
20
|
+
Guides: https://rubyllm.com/
|
|
21
|
+
Upgrading: https://rubyllm.com/upgrading/
|
|
22
|
+
Resources:
|
|
23
|
+
GitHub: https://github.com/crmne/ruby_llm
|
|
24
|
+
Issues: https://github.com/crmne/ruby_llm/issues
|
|
25
|
+
Releases: https://github.com/crmne/ruby_llm/releases
|
data/README.md
CHANGED
|
@@ -5,8 +5,11 @@
|
|
|
5
5
|
<img src="/docs/assets/images/logotype.svg" alt="RubyLLM" height="120" width="250">
|
|
6
6
|
</picture>
|
|
7
7
|
|
|
8
|
-
<strong>
|
|
9
|
-
|
|
8
|
+
<strong>Build AI features the Ruby way</strong>
|
|
9
|
+
|
|
10
|
+
<p>RubyLLM is the Ruby-native AI framework. Work with models, tools, and agents through one consistent API, in plain Ruby or Rails.</p>
|
|
11
|
+
|
|
12
|
+
[Website](https://rubyllm.com/) · [Getting Started](https://rubyllm.com/getting-started/) · [What's New in 2.0](https://rubyllm.com/whats-new-in-2-0/)
|
|
10
13
|
|
|
11
14
|
Battle tested at [<picture><source media="(prefers-color-scheme: dark)" srcset="https://chatwithwork.com/logotype-dark.svg"><img src="https://chatwithwork.com/logotype.svg" alt="Chat with Work" height="30" align="absmiddle"></picture>](https://chatwithwork.com) - *Fully private work AI*
|
|
12
15
|
|
|
@@ -23,28 +26,24 @@ Battle tested at [<picture><source media="(prefers-color-scheme: dark)" srcset="
|
|
|
23
26
|
|
|
24
27
|
---
|
|
25
28
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
## Build a working Ruby AI chat in two minutes
|
|
29
|
-
|
|
30
|
-
https://github.com/user-attachments/assets/65422091-9338-47da-a303-92b918bd1345
|
|
29
|
+
## 17 providers. One Ruby API.
|
|
31
30
|
|
|
32
|
-
|
|
31
|
+
Build with the models you want. Move between hosted and local providers without rewriting your application, or connect an OpenAI-compatible endpoint.
|
|
33
32
|
|
|
34
|
-
|
|
33
|
+
[Browse models and pricing](https://rubyllm.com/available-models/) · [Connect a provider](https://rubyllm.com/configuration-providers/)
|
|
35
34
|
|
|
36
|
-
|
|
35
|
+
## Start with one line. Add files, tools, and agents
|
|
37
36
|
|
|
38
|
-
|
|
37
|
+
These examples use **2.0.0.rc4 (prerelease)**. Follow [Getting Started](https://rubyllm.com/getting-started/) to install it and configure the providers you want to try. For 1.x, use the [stable-version docs](https://rubyllm.com/v1/).
|
|
39
38
|
|
|
40
39
|
```ruby
|
|
41
|
-
# Just ask
|
|
42
|
-
chat
|
|
43
|
-
chat.ask "What's the best way to learn Ruby?"
|
|
40
|
+
# Just ask
|
|
41
|
+
RubyLLM.chat.ask "What's the best way to learn Ruby?"
|
|
44
42
|
```
|
|
45
43
|
|
|
46
44
|
```ruby
|
|
47
|
-
#
|
|
45
|
+
# Ask about files with a model that supports their input types
|
|
46
|
+
chat = RubyLLM.chat(model: "gemini-3.7-flash")
|
|
48
47
|
chat.ask "What's in this image?", with: "ruby_conf.jpg"
|
|
49
48
|
chat.ask "What's happening in this video?", with: "video.mp4"
|
|
50
49
|
chat.ask "Describe this meeting", with: "meeting.wav"
|
|
@@ -66,28 +65,56 @@ end
|
|
|
66
65
|
|
|
67
66
|
```ruby
|
|
68
67
|
# Generate images
|
|
69
|
-
RubyLLM.paint "a sunset over mountains in watercolor style"
|
|
68
|
+
image = RubyLLM.paint "a sunset over mountains in watercolor style"
|
|
69
|
+
image.save "sunset.png"
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
```ruby
|
|
73
|
+
# Generate videos
|
|
74
|
+
video = RubyLLM.animate "a paper boat sailing down a rainy gutter"
|
|
75
|
+
video.save "paper_boat.mp4"
|
|
70
76
|
```
|
|
71
77
|
|
|
72
78
|
```ruby
|
|
73
79
|
# Create embeddings
|
|
74
|
-
RubyLLM.embed "Ruby is elegant and expressive"
|
|
80
|
+
embedding = RubyLLM.embed "Ruby is elegant and expressive"
|
|
81
|
+
embedding.vectors
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
```ruby
|
|
85
|
+
# Rank search results
|
|
86
|
+
documents = ["Reset your password in Settings.", "Invoices arrive by email."]
|
|
87
|
+
ranked = RubyLLM.rerank("How do I reset my password?", documents, model: "rerank-v3.5")
|
|
88
|
+
ranked.results.first.document
|
|
75
89
|
```
|
|
76
90
|
|
|
77
91
|
```ruby
|
|
78
92
|
# Transcribe audio to text
|
|
79
|
-
RubyLLM.transcribe "meeting.wav"
|
|
93
|
+
transcript = RubyLLM.transcribe "meeting.wav"
|
|
94
|
+
puts transcript.text
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
```ruby
|
|
98
|
+
# Turn text into speech
|
|
99
|
+
speech = RubyLLM.speak "Hello, welcome to RubyLLM!"
|
|
100
|
+
speech.save "welcome.mp3"
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
```ruby
|
|
104
|
+
# Extract document text as markdown
|
|
105
|
+
document = RubyLLM.ocr "contract.pdf"
|
|
106
|
+
puts document.markdown
|
|
80
107
|
```
|
|
81
108
|
|
|
82
109
|
```ruby
|
|
83
|
-
#
|
|
84
|
-
RubyLLM.moderate
|
|
110
|
+
# Check whether a moderation model flags content
|
|
111
|
+
RubyLLM.moderate("Some user-generated content").flagged?
|
|
85
112
|
```
|
|
86
113
|
|
|
87
114
|
```ruby
|
|
88
115
|
# Let AI use your code
|
|
89
116
|
class Weather < RubyLLM::Tool
|
|
90
|
-
|
|
117
|
+
description "Get current weather"
|
|
91
118
|
|
|
92
119
|
def execute(latitude:, longitude:)
|
|
93
120
|
url = "https://api.open-meteo.com/v1/forecast?latitude=#{latitude}&longitude=#{longitude}¤t=temperature_2m,wind_speed_10m"
|
|
@@ -95,13 +122,13 @@ class Weather < RubyLLM::Tool
|
|
|
95
122
|
end
|
|
96
123
|
end
|
|
97
124
|
|
|
98
|
-
chat.
|
|
125
|
+
chat.with_tools(Weather).ask "What's the weather in Berlin?"
|
|
99
126
|
```
|
|
100
127
|
|
|
101
128
|
```ruby
|
|
102
129
|
# Define an agent with instructions + tools
|
|
103
130
|
class WeatherAssistant < RubyLLM::Agent
|
|
104
|
-
model "gpt-5-
|
|
131
|
+
model "gpt-5.6-luna"
|
|
105
132
|
instructions "Be concise and always use tools for weather."
|
|
106
133
|
tools Weather
|
|
107
134
|
end
|
|
@@ -111,7 +138,7 @@ WeatherAssistant.new.ask "What's the weather in Berlin?"
|
|
|
111
138
|
|
|
112
139
|
```ruby
|
|
113
140
|
# Get structured output
|
|
114
|
-
class ProductSchema <
|
|
141
|
+
class ProductSchema < Schematist::Schema
|
|
115
142
|
string :name
|
|
116
143
|
number :price
|
|
117
144
|
array :features do
|
|
@@ -120,50 +147,77 @@ class ProductSchema < RubyLLM::Schema
|
|
|
120
147
|
end
|
|
121
148
|
|
|
122
149
|
response = chat.with_schema(ProductSchema).ask "Analyze this product", with: "product.txt"
|
|
150
|
+
response.parsed
|
|
123
151
|
```
|
|
124
152
|
|
|
125
|
-
##
|
|
153
|
+
## A complete AI framework for Ruby
|
|
154
|
+
|
|
155
|
+
Agents, workflows, RAG, images, audio, and video. Built in, with usage tracking and Rails integration to bring them into your app.
|
|
126
156
|
|
|
127
157
|
* **Chat:** Conversational AI with `RubyLLM.chat`
|
|
128
158
|
* **Vision:** Analyze images and videos
|
|
129
|
-
* **Audio:** Transcribe and
|
|
130
|
-
* **Documents:**
|
|
159
|
+
* **Audio:** Transcribe speech with `RubyLLM.transcribe` and generate it with `RubyLLM.speak`
|
|
160
|
+
* **Documents:** Ask questions about PDFs, text files, and other supported formats
|
|
161
|
+
* **OCR:** Turn documents into markdown with `RubyLLM.ocr`
|
|
131
162
|
* **Image generation:** Create images with `RubyLLM.paint`
|
|
163
|
+
* **Video generation:** Create videos with `RubyLLM.animate`
|
|
132
164
|
* **Embeddings:** Generate embeddings with `RubyLLM.embed`
|
|
133
|
-
* **
|
|
165
|
+
* **Reranking:** Order retrieval candidates by relevance with `RubyLLM.rerank`
|
|
166
|
+
* **Moderation:** Content flags, categories, and scores with `RubyLLM.moderate`
|
|
134
167
|
* **Tools:** Let AI call your Ruby methods
|
|
168
|
+
* **Tool approval:** Park a run until a human approves with `requires_approval`
|
|
169
|
+
* **The agentic loop:** Drive it yourself with `ask_later`, `step`, and `complete?`
|
|
170
|
+
* **Server tools:** Web search, code execution, and MCP connectors with `with_server_tools`
|
|
135
171
|
* **Agents:** Reusable assistants with `RubyLLM::Agent`
|
|
136
|
-
* **
|
|
172
|
+
* **Prompt templates:** ERB prompts in `app/prompts`, rendered with `RubyLLM.render_prompt`
|
|
173
|
+
* **Workflows:** Correlate multi-agent runs in your telemetry with `RubyLLM.workflow`
|
|
174
|
+
* **Structured output:** Define a Ruby schema and read the result with `response.parsed`
|
|
137
175
|
* **Streaming:** Real-time responses with blocks
|
|
138
|
-
* **Rails:**
|
|
176
|
+
* **Rails:** Active Record persistence, Active Storage attachments, Hotwire streaming, and generators
|
|
177
|
+
* **Files:** Upload once and reuse across chats with `RubyLLM.upload`
|
|
178
|
+
* **Prompt caching:** Turn on the provider's cache with `with_caching` and `cache_until_here`
|
|
179
|
+
* **Fallbacks and cancellation:** Retry on backup models with `with_fallbacks`, stop a run with `cancel`
|
|
180
|
+
* **Cost tracking:** A per-attempt usage ledger behind `chat.tokens` and `chat.cost`
|
|
139
181
|
* **Async:** Fiber-based concurrency
|
|
140
|
-
* **Model registry:**
|
|
182
|
+
* **Model registry:** Browse capabilities, limits, and pricing across providers
|
|
141
183
|
* **Extended thinking:** Control, view, and persist model deliberation
|
|
142
|
-
* **
|
|
184
|
+
* **Citations:** Normalized source citations from documents, search, and grounding
|
|
185
|
+
* **Batches:** Provider-side batch processing with provider-specific discounts via `RubyLLM.batch`
|
|
186
|
+
* **Compaction:** Let providers condense long conversations with `with_compaction`
|
|
187
|
+
* **Token counting:** Count a request before you send it with `count_tokens`
|
|
188
|
+
* **Providers:** OpenAI, Azure, xAI, Anthropic, Gemini, VertexAI, Bedrock, Cohere, DeepSeek, Mistral, Ollama, Ollama Cloud, OpenRouter, Perplexity, GPUStack, ElevenLabs, Deepgram, and any OpenAI-compatible API
|
|
143
189
|
|
|
144
190
|
## Installation
|
|
145
191
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
192
|
+
Install the 2.0 release candidate:
|
|
193
|
+
|
|
194
|
+
```bash
|
|
195
|
+
bundle add ruby_llm --version 2.0.0.rc4
|
|
149
196
|
```
|
|
150
|
-
Then `bundle install`.
|
|
151
197
|
|
|
152
|
-
Configure your
|
|
198
|
+
Configure a provider in your script, or in `config/initializers/ruby_llm.rb` in Rails:
|
|
199
|
+
|
|
153
200
|
```ruby
|
|
154
|
-
|
|
201
|
+
require 'ruby_llm'
|
|
202
|
+
|
|
155
203
|
RubyLLM.configure do |config|
|
|
156
|
-
config.openai_api_key = ENV
|
|
204
|
+
config.openai_api_key = ENV.fetch('OPENAI_API_KEY')
|
|
157
205
|
end
|
|
158
206
|
```
|
|
159
207
|
|
|
160
|
-
|
|
208
|
+
Configure the other providers used by the examples as needed: Gemini for files, xAI for video, Mistral for OCR, and Cohere for reranking. [Getting Started](https://rubyllm.com/getting-started/) shows each setup beside its example. If your app uses 1.16, follow the [upgrade guide](https://rubyllm.com/upgrading/) before deploying 2.0.
|
|
209
|
+
|
|
210
|
+
## Feels at home in Rails
|
|
211
|
+
|
|
212
|
+
Save conversations with Active Record and stream replies with Hotwire. The generators give you a working chat UI. Watch the two-minute demo.
|
|
213
|
+
|
|
214
|
+
https://github.com/user-attachments/assets/65422091-9338-47da-a303-92b918bd1345
|
|
161
215
|
|
|
162
216
|
```bash
|
|
163
217
|
# Install Rails Integration
|
|
164
218
|
bin/rails generate ruby_llm:install
|
|
165
219
|
bin/rails db:migrate
|
|
166
|
-
bin/rails ruby_llm:load_models
|
|
220
|
+
bin/rails ruby_llm:load_models
|
|
167
221
|
|
|
168
222
|
# Add Chat UI (optional)
|
|
169
223
|
bin/rails generate ruby_llm:chat_ui
|
|
@@ -174,15 +228,25 @@ class Chat < ApplicationRecord
|
|
|
174
228
|
acts_as_chat
|
|
175
229
|
end
|
|
176
230
|
|
|
177
|
-
chat = Chat.create! model: "
|
|
231
|
+
chat = Chat.create! model: "gpt-5.6-luna"
|
|
178
232
|
chat.ask "What's in this file?", with: "report.pdf"
|
|
179
233
|
```
|
|
180
234
|
|
|
181
|
-
|
|
235
|
+
Start your Rails server and visit `http://localhost:3000/chats` to try the chat interface. See the [Rails guide](https://rubyllm.com/rails/) for persistence, streaming, and background jobs.
|
|
236
|
+
|
|
237
|
+
## AI coding assistants
|
|
238
|
+
|
|
239
|
+
Give your coding assistant the RubyLLM API and documentation that match your application. From your application directory, install the skill packaged with your gem:
|
|
240
|
+
|
|
241
|
+
```bash
|
|
242
|
+
npx skills add "$(bundle show ruby_llm)" --skill rubyllm
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
Choose your coding assistant and installation scope when prompted. See [AI Coding Assistants](https://rubyllm.com/ai-coding-assistants/) for setup and updates.
|
|
182
246
|
|
|
183
247
|
## Documentation
|
|
184
248
|
|
|
185
|
-
[rubyllm.com](https://rubyllm.com)
|
|
249
|
+
[Guides](https://rubyllm.com/getting-started/) · [API reference](https://rubyllm.com/api/) · [Models](https://rubyllm.com/available-models/) · [Upgrading](https://rubyllm.com/upgrading/) · [1.x docs](https://rubyllm.com/v1/)
|
|
186
250
|
|
|
187
251
|
## Contributing
|
|
188
252
|
|
data/exe/ruby_llm
ADDED
|
@@ -28,8 +28,6 @@ module RubyLLM
|
|
|
28
28
|
args = []
|
|
29
29
|
args << "chat:#{chat_model_name}" if chat_model_name != 'Chat'
|
|
30
30
|
args << "message:#{message_model_name}" if message_model_name != 'Message'
|
|
31
|
-
args << "model:#{model_model_name}" if model_model_name != 'Model'
|
|
32
|
-
args << "tool_call:#{tool_call_model_name}" if tool_call_model_name != 'ToolCall'
|
|
33
31
|
arg_string = args.any? ? " #{args.join(' ')}" : ''
|
|
34
32
|
|
|
35
33
|
raise Thor::Error, <<~ERROR
|
|
@@ -37,9 +35,6 @@ module RubyLLM
|
|
|
37
35
|
|
|
38
36
|
Please run the install generator first:
|
|
39
37
|
bin/rails generate ruby_llm:install#{arg_string}
|
|
40
|
-
|
|
41
|
-
Or if upgrading from <= 1.6.x, run the upgrade generator:
|
|
42
|
-
bin/rails generate ruby_llm:upgrade_to_v1_7#{arg_string}
|
|
43
38
|
ERROR
|
|
44
39
|
end
|
|
45
40
|
|
|
@@ -114,6 +109,7 @@ module RubyLLM
|
|
|
114
109
|
return if application_controller.include?('def available_chat_models')
|
|
115
110
|
|
|
116
111
|
inject_into_file path, <<-RUBY, before: /^end\s*\z/
|
|
112
|
+
|
|
117
113
|
private
|
|
118
114
|
|
|
119
115
|
def available_chat_models
|
|
@@ -133,7 +129,7 @@ module RubyLLM
|
|
|
133
129
|
|
|
134
130
|
routes_content = <<~ROUTES.strip
|
|
135
131
|
namespace :#{namespace} do
|
|
136
|
-
resources :#{model_resource}, only: [ :index, :show ] do
|
|
132
|
+
resources :#{model_resource}, only: [ :index, :show ], constraints: { id: /[^\\/]+/ } do
|
|
137
133
|
collection do
|
|
138
134
|
post :refresh
|
|
139
135
|
end
|
|
@@ -146,7 +142,7 @@ module RubyLLM
|
|
|
146
142
|
route routes_content
|
|
147
143
|
else
|
|
148
144
|
model_routes = <<~ROUTES.strip
|
|
149
|
-
resources :#{
|
|
145
|
+
resources :#{model_resource_name}, only: [ :index, :show ], constraints: { id: /[^\\/]+/ } do
|
|
150
146
|
collection do
|
|
151
147
|
post :refresh
|
|
152
148
|
end
|
|
@@ -208,26 +204,6 @@ module RubyLLM
|
|
|
208
204
|
|
|
209
205
|
private
|
|
210
206
|
|
|
211
|
-
def ui_variant
|
|
212
|
-
@ui_variant ||= case options[:ui]
|
|
213
|
-
when 'tailwind'
|
|
214
|
-
:tailwind
|
|
215
|
-
when 'auto'
|
|
216
|
-
tailwind_available? ? :tailwind : :scaffold
|
|
217
|
-
else
|
|
218
|
-
:scaffold
|
|
219
|
-
end
|
|
220
|
-
end
|
|
221
|
-
|
|
222
|
-
def ui_template(template_path)
|
|
223
|
-
return template_path unless ui_variant == :tailwind
|
|
224
|
-
|
|
225
|
-
# Keep Tailwind templates as a separate set so we can mirror Rails/Tailwind
|
|
226
|
-
# scaffold conventions without complicating scaffold templates.
|
|
227
|
-
tailwind_template = "tailwind/#{template_path}"
|
|
228
|
-
File.exist?(File.join(self.class.source_root, "#{tailwind_template}.tt")) ? tailwind_template : template_path
|
|
229
|
-
end
|
|
230
|
-
|
|
231
207
|
def message_helper_module_name
|
|
232
208
|
if message_model_name.include?('::')
|
|
233
209
|
"#{message_model_name.deconstantize}::#{message_model_name.demodulize.pluralize}Helper"
|
|
@@ -235,22 +211,6 @@ module RubyLLM
|
|
|
235
211
|
"#{message_model_name.pluralize}Helper"
|
|
236
212
|
end
|
|
237
213
|
end
|
|
238
|
-
|
|
239
|
-
def tailwind_available?
|
|
240
|
-
Rails.root.join('app/assets/tailwind/application.css').exist? ||
|
|
241
|
-
Rails.root.join('config/tailwind.config.js').exist? ||
|
|
242
|
-
gem_in_bundle?('tailwindcss-rails') ||
|
|
243
|
-
gem_in_bundle?('cssbundling-rails')
|
|
244
|
-
end
|
|
245
|
-
|
|
246
|
-
def gem_in_bundle?(gem_name)
|
|
247
|
-
gemfile_path = Rails.root.join('Gemfile')
|
|
248
|
-
lockfile_path = Rails.root.join('Gemfile.lock')
|
|
249
|
-
|
|
250
|
-
[gemfile_path, lockfile_path].any? do |path|
|
|
251
|
-
path.exist? && path.read.include?(gem_name)
|
|
252
|
-
end
|
|
253
|
-
end
|
|
254
214
|
end
|
|
255
215
|
end
|
|
256
216
|
end
|
|
@@ -7,22 +7,30 @@ class <%= chat_controller_class_name %> < ApplicationController
|
|
|
7
7
|
|
|
8
8
|
def new
|
|
9
9
|
@<%= chat_variable_name %> = <%= chat_model_name %>.new
|
|
10
|
-
@selected_model = params[:model]
|
|
10
|
+
@selected_model = params[:provider] ? [ params[:provider], params[:model] ].join(":") : params[:model]
|
|
11
11
|
@chat_models = available_chat_models
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
def create
|
|
15
15
|
prompt = params.dig(:<%= chat_variable_name %>, :prompt)
|
|
16
16
|
if prompt.present?
|
|
17
|
-
|
|
17
|
+
provider, model = params.dig(:<%= chat_variable_name %>, :model).to_s.split(":", 2)
|
|
18
|
+
@<%= chat_variable_name %> = <%= chat_model_name %>.create!(model: model.presence, provider: provider.presence)
|
|
18
19
|
<%= chat_job_class_name %>.perform_later(@<%= chat_variable_name %>.id, prompt)
|
|
19
20
|
|
|
20
21
|
redirect_to @<%= chat_variable_name %>, notice: "<%= chat_model_name.humanize %> was successfully created."
|
|
22
|
+
else
|
|
23
|
+
@<%= chat_variable_name %> = <%= chat_model_name %>.new
|
|
24
|
+
@<%= chat_variable_name %>.errors.add(:prompt, "can't be blank")
|
|
25
|
+
@selected_model = params.dig(:<%= chat_variable_name %>, :model)
|
|
26
|
+
@chat_models = available_chat_models
|
|
27
|
+
|
|
28
|
+
render :new, status: <%= unprocessable_content_status.inspect %>
|
|
21
29
|
end
|
|
22
30
|
end
|
|
23
31
|
|
|
24
32
|
def show
|
|
25
|
-
@<%= message_variable_name %> =
|
|
33
|
+
@<%= message_variable_name %> = <%= message_model_name %>.new
|
|
26
34
|
end
|
|
27
35
|
|
|
28
36
|
def destroy
|
|
@@ -10,6 +10,14 @@ class <%= message_controller_class_name %> < ApplicationController
|
|
|
10
10
|
format.turbo_stream
|
|
11
11
|
format.html { redirect_to @<%= chat_variable_name %> }
|
|
12
12
|
end
|
|
13
|
+
else
|
|
14
|
+
@<%= message_variable_name %> = @<%= chat_variable_name %>.<%= message_table_name %>.build
|
|
15
|
+
@<%= message_variable_name %>.errors.add(:content, "can't be blank")
|
|
16
|
+
|
|
17
|
+
respond_to do |format|
|
|
18
|
+
format.turbo_stream { render :create, status: <%= unprocessable_content_status.inspect %> }
|
|
19
|
+
format.html { render "<%= chat_model_name.underscore.pluralize %>/show", status: <%= unprocessable_content_status.inspect %> }
|
|
20
|
+
end
|
|
13
21
|
end
|
|
14
22
|
end
|
|
15
23
|
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
class <%= model_controller_class_name %> < ApplicationController
|
|
2
2
|
def index
|
|
3
|
-
@<%=
|
|
3
|
+
@<%= model_resource_name %> = available_chat_models
|
|
4
4
|
end
|
|
5
5
|
|
|
6
6
|
def show
|
|
7
|
-
@<%= model_variable_name %> =
|
|
7
|
+
@<%= model_variable_name %> = RubyLLM.models.find(params[:id], params[:provider])
|
|
8
8
|
end
|
|
9
9
|
|
|
10
10
|
def refresh
|
|
11
|
-
|
|
12
|
-
redirect_to <%=
|
|
11
|
+
RubyLLM.models.refresh
|
|
12
|
+
redirect_to <%= model_resource_name %>_path, notice: "<%= model_model_name.pluralize %> refreshed successfully"
|
|
13
13
|
end
|
|
14
14
|
end
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<div id="<%%= dom_id <%= chat_model_name.demodulize.underscore %> %>" class="w-full sm:w-auto my-5 space-y-3">
|
|
2
2
|
<div>
|
|
3
3
|
<strong class="block font-medium mb-1">Model:</strong>
|
|
4
|
-
<%%= <%= chat_model_name.demodulize.underscore
|
|
4
|
+
<%%= <%= chat_model_name.demodulize.underscore %>.model&.label || default_model_display_name %>
|
|
5
5
|
</div>
|
|
6
6
|
|
|
7
7
|
<div>
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
<div class="my-5">
|
|
15
15
|
<%%= form.label :model, "Select AI model:" %>
|
|
16
16
|
<%%= form.select :model,
|
|
17
|
-
options_for_select(@chat_models.map { |model| [model.label, model.id] }.unshift([default_model_display_name, nil]), @selected_model),
|
|
17
|
+
options_for_select(@chat_models.map { |model| [model.label, [model.provider, model.id].join(":")] }.unshift([default_model_display_name, nil]), @selected_model),
|
|
18
18
|
{},
|
|
19
19
|
class: ["block shadow-sm rounded-md border px-3 py-2 mt-2 w-full", {"border-gray-400 focus:outline-blue-600": <%= chat_variable_name %>.errors[:model].none?, "border-red-400 focus:outline-red-600": <%= chat_variable_name %>.errors[:model].any?}] %>
|
|
20
20
|
</div>
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
<div class="flex justify-between items-center">
|
|
9
9
|
<h1 class="font-bold text-4xl"><%= chat_model_name.pluralize %></h1>
|
|
10
10
|
<div class="flex items-center gap-2">
|
|
11
|
-
<%%= link_to "<%= model_model_name.pluralize %>", <%=
|
|
11
|
+
<%%= link_to "<%= model_model_name.pluralize %>", <%= model_resource_name %>_path, class: "rounded-md px-3.5 py-2.5 bg-gray-100 hover:bg-gray-50 text-gray-900 block font-medium" %>
|
|
12
12
|
<%%= link_to "New <%= chat_table_name.singularize.humanize.downcase %>", new_<%= chat_variable_name %>_path, class: "rounded-md px-3.5 py-2.5 bg-blue-600 hover:bg-blue-500 text-white block font-medium" %>
|
|
13
13
|
</div>
|
|
14
14
|
</div>
|
|
@@ -12,11 +12,11 @@
|
|
|
12
12
|
|
|
13
13
|
<div class="my-5">
|
|
14
14
|
<strong class="block font-medium mb-1">Model:</strong>
|
|
15
|
-
<%%= @<%= chat_variable_name
|
|
15
|
+
<%%= @<%= chat_variable_name %>.model&.label || default_model_display_name %>
|
|
16
16
|
</div>
|
|
17
17
|
|
|
18
18
|
<div id="<%= message_table_name %>" class="min-w-full divide-y divide-gray-200 space-y-5 my-5">
|
|
19
|
-
<%% @<%= chat_variable_name %>.<%= message_table_name %>.
|
|
19
|
+
<%% @<%= chat_variable_name %>.<%= message_table_name %>.each do |<%= message_variable_name %>| %>
|
|
20
20
|
<%%= render <%= message_variable_name %> %>
|
|
21
21
|
<%% end %>
|
|
22
22
|
</div>
|
data/lib/generators/ruby_llm/chat_ui/templates/tailwind/views/messages/_assistant.html.erb.tt
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<%% assistant ||= local_assigns[
|
|
1
|
+
<%% assistant ||= local_assigns[:<%= message_model_name.demodulize.underscore %>] %>
|
|
2
2
|
<div id="<%= message_variable_name %>_<%%= assistant.id %>" class="w-full sm:w-auto my-5 space-y-3 rounded-md px-3 py-2 bg-green-50">
|
|
3
3
|
<div>
|
|
4
4
|
<span class="inline-block rounded px-2 py-0.5 text-xs font-medium bg-green-100 text-green-700">
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<%% system ||= local_assigns[
|
|
1
|
+
<%% system ||= local_assigns[:<%= message_model_name.demodulize.underscore %>] %>
|
|
2
2
|
<div id="<%= message_variable_name %>_<%%= system.id %>" class="w-full sm:w-auto my-5 space-y-3 rounded-md px-3 py-2 bg-gray-50 border border-gray-200">
|
|
3
3
|
<div>
|
|
4
4
|
<span class="inline-block rounded px-2 py-0.5 text-xs font-medium bg-gray-200 text-gray-700">
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
<%% tool ||= local_assigns[
|
|
1
|
+
<%% tool ||= local_assigns[:<%= message_model_name.demodulize.underscore %>] %>
|
|
2
2
|
<%%= render tool_result_partial(tool), tool: tool %>
|
data/lib/generators/ruby_llm/chat_ui/templates/tailwind/views/messages/_tool_calls.html.erb.tt
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
<%%
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
<%% message = local_assigns[:<%= message_model_name.demodulize.underscore %>] || tool_calls %>
|
|
2
|
+
<div id="<%= message_variable_name %>_<%%= message.id %>">
|
|
3
|
+
<%% message.<%= tool_call_variable_name.pluralize %>.each_value do |tool_call| %>
|
|
4
|
+
<%%= render tool_call_partial(tool_call), message: message, tool_call: tool_call %>
|
|
5
|
+
<%% end %>
|
|
6
|
+
</div>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<%% user ||= local_assigns[
|
|
1
|
+
<%% user ||= local_assigns[:<%= message_model_name.demodulize.underscore %>] %>
|
|
2
2
|
<div id="<%= message_variable_name %>_<%%= user.id %>" class="w-full sm:w-auto my-5 space-y-3 rounded-md px-3 py-2 bg-blue-50">
|
|
3
3
|
<div>
|
|
4
4
|
<span class="inline-block rounded px-2 py-0.5 text-xs font-medium bg-blue-100 text-blue-700">
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<div id="<%= message_variable_name %>
|
|
1
|
+
<div id="<%= message_variable_name %>_tool_call_<%%= tool_call.id %>" class="w-full sm:w-auto my-5 space-y-3 rounded-md px-3 py-2 bg-gray-50 border border-gray-200">
|
|
2
2
|
<div>
|
|
3
3
|
<span class="inline-block rounded px-2 py-0.5 text-xs font-medium bg-gray-200 text-gray-700">
|
|
4
4
|
Tool Call
|
|
@@ -8,6 +8,6 @@
|
|
|
8
8
|
<pre class="whitespace-pre-wrap text-gray-700 text-sm overflow-x-auto"><%%= tool_call.name %>(<%%= tool_call.arguments.map { |k, v| "#{k}: #{v.inspect}" }.join(", ") %>)</pre>
|
|
9
9
|
|
|
10
10
|
<div>
|
|
11
|
-
<span class="text-sm text-gray-600"><%%=
|
|
11
|
+
<span class="text-sm text-gray-600"><%%= message.created_at&.strftime("%I:%M %p") %></span>
|
|
12
12
|
</div>
|
|
13
13
|
</div>
|
|
@@ -1,17 +1,16 @@
|
|
|
1
|
-
<%%
|
|
2
|
-
<%% row_id = [<%= model_model_name.demodulize.underscore %>.provider, model_id].join("_").parameterize(separator: "_") %>
|
|
1
|
+
<%% row_id = [<%= model_model_name.demodulize.underscore %>.provider, <%= model_model_name.demodulize.underscore %>.id].join("_").parameterize(separator: "_") %>
|
|
3
2
|
<tr id="model_<%%= row_id %>">
|
|
4
3
|
<td class="px-3 py-2 text-sm text-gray-700"><%%= <%= model_model_name.demodulize.underscore %>.provider_class&.name || <%= model_model_name.demodulize.underscore %>.provider %></td>
|
|
5
|
-
<td class="px-3 py-2 text-sm text-gray-900"><%%= <%= model_model_name.demodulize.underscore %>.
|
|
4
|
+
<td class="px-3 py-2 text-sm text-gray-900"><%%= <%= model_model_name.demodulize.underscore %>.name %></td>
|
|
6
5
|
<td class="px-3 py-2 text-sm text-gray-700"><%%= number_with_delimiter(<%= model_model_name.demodulize.underscore %>.context_window) if <%= model_model_name.demodulize.underscore %>.context_window %></td>
|
|
7
6
|
<td class="px-3 py-2 text-sm text-gray-700">
|
|
8
|
-
<%% input = <%= model_model_name.demodulize.underscore %>.
|
|
9
|
-
<%% output = <%= model_model_name.demodulize.underscore %>.
|
|
7
|
+
<%% input = <%= model_model_name.demodulize.underscore %>.price(:input) %>
|
|
8
|
+
<%% output = <%= model_model_name.demodulize.underscore %>.price(:output) %>
|
|
10
9
|
<%% if input && output %>
|
|
11
10
|
$<%%= "%.2f" % input %> / $<%%= "%.2f" % output %>
|
|
12
11
|
<%% end %>
|
|
13
12
|
</td>
|
|
14
13
|
<td class="px-3 py-2 text-sm">
|
|
15
|
-
<%%= link_to "Start <%= chat_table_name.singularize.humanize.downcase %>", new_<%= chat_variable_name %>_path(model:
|
|
14
|
+
<%%= link_to "Start <%= chat_table_name.singularize.humanize.downcase %>", new_<%= chat_variable_name %>_path(model: [<%= model_model_name.demodulize.underscore %>.provider, <%= model_model_name.demodulize.underscore %>.id].join(":")), class: "text-blue-600 hover:text-blue-500" %>
|
|
16
15
|
</td>
|
|
17
16
|
</tr>
|
|
@@ -9,11 +9,11 @@
|
|
|
9
9
|
<h1 class="font-bold text-4xl"><%= model_model_name.pluralize %></h1>
|
|
10
10
|
<div class="flex items-center gap-2">
|
|
11
11
|
<%%= link_to "<%= chat_model_name.pluralize %>", <%= chat_table_name %>_path, class: "rounded-md px-3.5 py-2.5 bg-gray-100 hover:bg-gray-50 text-gray-900 block font-medium" %>
|
|
12
|
-
<%%= button_to "Refresh <%= model_model_name.pluralize %>", refresh_<%=
|
|
12
|
+
<%%= button_to "Refresh <%= model_model_name.pluralize %>", refresh_<%= model_resource_name %>_path, method: :post, class: "rounded-md px-3.5 py-2.5 bg-blue-600 hover:bg-blue-500 text-white block font-medium cursor-pointer" %>
|
|
13
13
|
</div>
|
|
14
14
|
</div>
|
|
15
15
|
|
|
16
|
-
<div id="<%=
|
|
16
|
+
<div id="<%= model_resource_name %>" class="mt-5 overflow-x-auto">
|
|
17
17
|
<%% if @<%= model_variable_name.pluralize %>.any? %>
|
|
18
18
|
<table class="min-w-full divide-y divide-gray-300 border border-gray-300">
|
|
19
19
|
<thead class="bg-gray-50">
|