durable-llm 0.1.3 → 0.1.5

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.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/.envrc +7 -0
  3. data/CHANGELOG.md +5 -0
  4. data/CONFIGURE.md +132 -0
  5. data/Gemfile +7 -9
  6. data/Gemfile.lock +3 -3
  7. data/README.md +1 -0
  8. data/Rakefile +6 -6
  9. data/devenv.lock +103 -0
  10. data/devenv.nix +9 -0
  11. data/devenv.yaml +15 -0
  12. data/durable-llm.gemspec +44 -0
  13. data/examples/openai_quick_complete.rb +3 -1
  14. data/lib/durable/llm/cli.rb +247 -60
  15. data/lib/durable/llm/client.rb +92 -11
  16. data/lib/durable/llm/configuration.rb +174 -23
  17. data/lib/durable/llm/errors.rb +185 -0
  18. data/lib/durable/llm/providers/anthropic.rb +246 -36
  19. data/lib/durable/llm/providers/azure_openai.rb +347 -0
  20. data/lib/durable/llm/providers/base.rb +106 -9
  21. data/lib/durable/llm/providers/cohere.rb +227 -0
  22. data/lib/durable/llm/providers/deepseek.rb +233 -0
  23. data/lib/durable/llm/providers/fireworks.rb +278 -0
  24. data/lib/durable/llm/providers/google.rb +301 -0
  25. data/lib/durable/llm/providers/groq.rb +108 -29
  26. data/lib/durable/llm/providers/huggingface.rb +122 -18
  27. data/lib/durable/llm/providers/mistral.rb +431 -0
  28. data/lib/durable/llm/providers/openai.rb +162 -25
  29. data/lib/durable/llm/providers/opencode.rb +253 -0
  30. data/lib/durable/llm/providers/openrouter.rb +256 -0
  31. data/lib/durable/llm/providers/perplexity.rb +273 -0
  32. data/lib/durable/llm/providers/together.rb +346 -0
  33. data/lib/durable/llm/providers/xai.rb +355 -0
  34. data/lib/durable/llm/providers.rb +103 -15
  35. data/lib/durable/llm/version.rb +5 -1
  36. data/lib/durable/llm.rb +143 -3
  37. data/lib/durable.rb +29 -4
  38. data/sig/durable/llm.rbs +302 -1
  39. metadata +50 -36
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1e531cd0c24bb1c3d7a2c5490b3d268694827c08d831955219d5fa32884b1a51
4
- data.tar.gz: dd4bedf9b3a9a09addef7306fe51bcad5082a75163d0d383eff449df5c1ebf54
3
+ metadata.gz: f8e6cc177ffcd7ac3cdd67678a2cb0bfbd97944470a88a90ca82c7e02ea40845
4
+ data.tar.gz: 0e595c60949cfa309e2b72aa5ab417c31966e91df76188f7c3a722ea052e16d2
5
5
  SHA512:
6
- metadata.gz: d5bf3a883a62807f86b578169eda22074a8d30e8b7005f9177dd16b04a2be26af5625e26b5b963f6ece166b81c8082d18da2fb9851a03edec3e2388ce2443dce
7
- data.tar.gz: 03d93aeb004df8d6bf0cfbf945734565d7e5b4d7fe4b98a5b3f4b2a622202b7f907d51730cbcbf37ec9dbed9c0098844c7272ff6a6a00be7c3aeea9e19531607
6
+ metadata.gz: b8fed0d23edcc73a48613681f528f5a7fe8575ef7faf7be34a897d91cfcded505df1de1723becd420394269f11856ea857df09872423c529361d06995e19bcbe
7
+ data.tar.gz: 6e1a7db706eced060c26f1bbbd48a2dd57103195b633971a52df48d0fae6345080b4b70b91dc41662c19dd61c67c39718423a8b96589ea1fb34083278a6b6f02
data/.envrc ADDED
@@ -0,0 +1,7 @@
1
+ export DIRENV_WARN_TIMEOUT=20s
2
+
3
+ eval "$(devenv direnvrc)"
4
+
5
+ # The use_devenv function supports passing flags to the devenv command
6
+ # For example: use devenv --impure --option services.postgres.enable:bool true
7
+ use devenv
data/CHANGELOG.md CHANGED
@@ -1,5 +1,10 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.1.4] - 2024-10-13
4
+
5
+ - Enhanced version.rb with Version class for semantic version parsing and comparison
6
+ - Added comprehensive tests for version functionality
7
+
3
8
  ## [0.1.0] - 2024-10-09
4
9
 
5
10
  - Initial release
data/CONFIGURE.md ADDED
@@ -0,0 +1,132 @@
1
+ # Configuring Durable-LLM
2
+
3
+ ## Introduction
4
+
5
+ Durable-LLM supports multiple LLM providers and can be configured using environment variables or a configuration block. This document outlines the various configuration options available.
6
+
7
+ ## General Configuration
8
+
9
+ You can configure Durable-LLM using a configuration block:
10
+
11
+ ```ruby
12
+ Durable::Llm.configure do |config|
13
+ # Configuration options go here
14
+ end
15
+ ```
16
+
17
+ ## Provider-specific Configuration
18
+
19
+ ### OpenAI
20
+
21
+ To configure the OpenAI provider, you can set the following environment variables:
22
+
23
+ - `OPENAI_API_KEY`: Your OpenAI API key
24
+ - `OPENAI_ORGANIZATION`: (Optional) Your OpenAI organization ID
25
+
26
+ Alternatively, you can configure it in the configuration block:
27
+
28
+ ```ruby
29
+ Durable::Llm.configure do |config|
30
+ config.openai.api_key = 'your-api-key'
31
+ config.openai.organization = 'your-organization-id' # Optional
32
+ end
33
+ ```
34
+
35
+ ### Anthropic
36
+
37
+ To configure the Anthropic provider, you can set the following environment variable:
38
+
39
+ - `ANTHROPIC_API_KEY`: Your Anthropic API key
40
+
41
+ Alternatively, you can configure it in the configuration block:
42
+
43
+ ```ruby
44
+ Durable::Llm.configure do |config|
45
+ config.anthropic.api_key = 'your-api-key'
46
+ end
47
+ ```
48
+
49
+ ### Hugging Face
50
+
51
+ To configure the Hugging Face provider, you can set the following environment variable:
52
+
53
+ - `HUGGINGFACE_API_KEY`: Your Hugging Face API key
54
+
55
+ Alternatively, you can configure it in the configuration block:
56
+
57
+ ```ruby
58
+ Durable::Llm.configure do |config|
59
+ config.huggingface.api_key = 'your-api-key'
60
+ end
61
+ ```
62
+
63
+ ### Groq
64
+
65
+ To configure the Groq provider, you can set the following environment variable:
66
+
67
+ - `GROQ_API_KEY`: Your Groq API key
68
+
69
+ Alternatively, you can configure it in the configuration block:
70
+
71
+ ```ruby
72
+ Durable::Llm.configure do |config|
73
+ config.groq.api_key = 'your-api-key'
74
+ end
75
+ ```
76
+
77
+ ## Using Environment Variables
78
+
79
+ You can also use environment variables configure any provider. The format is:
80
+
81
+ ```
82
+ DLLM__PROVIDER__SETTING
83
+ ```
84
+
85
+ For example:
86
+
87
+ ```
88
+ DLLM__OPENAI__API_KEY=your-openai-api-key
89
+ DLLM__ANTHROPIC__API_KEY=your-anthropic-api-key
90
+ ```
91
+
92
+ ## Loading Configuration from Datasette
93
+
94
+ Durable-LLM can load configuration from a io.datasette.llm configuration file located at `~/.config/io.datasette.llm/keys.json`. If this file exists, it will be parsed and used to set API keys for the supported providers.
95
+
96
+ ## Default Provider
97
+
98
+ You can set a default provider in the configuration:
99
+
100
+ ```ruby
101
+ Durable::Llm.configure do |config|
102
+ config.default_provider = 'openai'
103
+ end
104
+ ```
105
+
106
+ The default provider is set to 'openai' if not specified.
107
+
108
+ ## Supported Models
109
+
110
+ Each provider supports a set of models. You can get the list of supported models for a provider using the `models` method:
111
+
112
+ ```ruby
113
+ Durable::Llm::Providers::OpenAI.models
114
+ Durable::Llm::Providers::Anthropic.models
115
+ Durable::Llm::Providers::Huggingface.models
116
+ Durable::Llm::Providers::Groq.models
117
+ ```
118
+
119
+ Note that some services (Anthropic, for example) don't offer a models endpoint, so they are hardcoded; others (Huggingface) have a inordinately long list, so also have a hardcoded list, at least for now.
120
+
121
+ ## Streaming Support
122
+
123
+ Some providers support streaming responses. You can check if a provider supports streaming:
124
+
125
+ ```ruby
126
+ Durable::Llm::Providers::OpenAI.stream?
127
+ ```
128
+
129
+ ## Conclusion
130
+
131
+ By properly configuring Durable-LLM, you can easily switch between different LLM providers and models in your application. Remember to keep your API keys secure and never commit them to version control.
132
+
data/Gemfile CHANGED
@@ -1,20 +1,18 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- source "https://rubygems.org"
3
+ source 'https://rubygems.org'
4
4
 
5
5
  # Specify your gem's dependencies in durable-llm.gemspec
6
6
  gemspec
7
7
 
8
- gem "rake", "~> 13.0"
8
+ gem 'rake', '~> 13.0'
9
9
 
10
- gem "minitest", "~> 5.0"
10
+ gem 'minitest', '~> 5.0'
11
11
 
12
- gem "rubocop", "~> 1.21"
12
+ gem 'rubocop', '~> 1.21'
13
13
 
14
- gem "ruby-openai", "~> 7.1"
14
+ gem 'ruby-openai', '~> 7.1'
15
15
 
16
- gem "thor", "~> 1.3"
16
+ gem 'thor', '~> 1.3'
17
17
 
18
-
19
-
20
- gem "webmock", "~> 3.24"
18
+ gem 'webmock', '~> 3.24'
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- durable-llm (0.1.2)
4
+ durable-llm (0.1.5)
5
5
  event_stream_parser (~> 1.0)
6
6
  faraday (> 1.0)
7
7
  highline (~> 3.1)
@@ -93,11 +93,11 @@ DEPENDENCIES
93
93
  minitest (~> 5.0)
94
94
  mocha (~> 2.1)
95
95
  rake (~> 13.0)
96
- rubocop (~> 1.21)
96
+ rubocop (~> 1.21, ~> 1.0)
97
97
  ruby-openai (~> 7.1)
98
98
  thor (~> 1.3)
99
99
  vcr (~> 6.0)
100
100
  webmock (~> 3.24)
101
101
 
102
102
  BUNDLED WITH
103
- 2.4.10
103
+ 2.7.1
data/README.md CHANGED
@@ -54,6 +54,7 @@ puts response.choices.first.message.content
54
54
  - Anthropic
55
55
  - Grok
56
56
  - Huggingface
57
+ - Cohere
57
58
 
58
59
  ## Configuration
59
60
 
data/Rakefile CHANGED
@@ -1,15 +1,15 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "bundler/gem_tasks"
4
- require "rake/testtask"
3
+ require 'bundler/gem_tasks'
4
+ require 'rake/testtask'
5
5
 
6
6
  Rake::TestTask.new(:test) do |t|
7
- t.libs << "test"
8
- t.libs << "lib"
9
- t.test_files = FileList["test/**/test_*.rb"]
7
+ t.libs << 'test'
8
+ t.libs << 'lib'
9
+ t.test_files = FileList['test/**/test_*.rb']
10
10
  end
11
11
 
12
- require "rubocop/rake_task"
12
+ require 'rubocop/rake_task'
13
13
 
14
14
  RuboCop::RakeTask.new
15
15
 
data/devenv.lock ADDED
@@ -0,0 +1,103 @@
1
+ {
2
+ "nodes": {
3
+ "devenv": {
4
+ "locked": {
5
+ "dir": "src/modules",
6
+ "lastModified": 1760162706,
7
+ "owner": "cachix",
8
+ "repo": "devenv",
9
+ "rev": "0d5ad578728fe4bce66eb4398b8b1e66deceb4e4",
10
+ "type": "github"
11
+ },
12
+ "original": {
13
+ "dir": "src/modules",
14
+ "owner": "cachix",
15
+ "repo": "devenv",
16
+ "type": "github"
17
+ }
18
+ },
19
+ "flake-compat": {
20
+ "flake": false,
21
+ "locked": {
22
+ "lastModified": 1747046372,
23
+ "owner": "edolstra",
24
+ "repo": "flake-compat",
25
+ "rev": "9100a0f413b0c601e0533d1d94ffd501ce2e7885",
26
+ "type": "github"
27
+ },
28
+ "original": {
29
+ "owner": "edolstra",
30
+ "repo": "flake-compat",
31
+ "type": "github"
32
+ }
33
+ },
34
+ "git-hooks": {
35
+ "inputs": {
36
+ "flake-compat": "flake-compat",
37
+ "gitignore": "gitignore",
38
+ "nixpkgs": [
39
+ "nixpkgs"
40
+ ]
41
+ },
42
+ "locked": {
43
+ "lastModified": 1759523803,
44
+ "owner": "cachix",
45
+ "repo": "git-hooks.nix",
46
+ "rev": "cfc9f7bb163ad8542029d303e599c0f7eee09835",
47
+ "type": "github"
48
+ },
49
+ "original": {
50
+ "owner": "cachix",
51
+ "repo": "git-hooks.nix",
52
+ "type": "github"
53
+ }
54
+ },
55
+ "gitignore": {
56
+ "inputs": {
57
+ "nixpkgs": [
58
+ "git-hooks",
59
+ "nixpkgs"
60
+ ]
61
+ },
62
+ "locked": {
63
+ "lastModified": 1709087332,
64
+ "owner": "hercules-ci",
65
+ "repo": "gitignore.nix",
66
+ "rev": "637db329424fd7e46cf4185293b9cc8c88c95394",
67
+ "type": "github"
68
+ },
69
+ "original": {
70
+ "owner": "hercules-ci",
71
+ "repo": "gitignore.nix",
72
+ "type": "github"
73
+ }
74
+ },
75
+ "nixpkgs": {
76
+ "locked": {
77
+ "lastModified": 1758532697,
78
+ "owner": "cachix",
79
+ "repo": "devenv-nixpkgs",
80
+ "rev": "207a4cb0e1253c7658c6736becc6eb9cace1f25f",
81
+ "type": "github"
82
+ },
83
+ "original": {
84
+ "owner": "cachix",
85
+ "ref": "rolling",
86
+ "repo": "devenv-nixpkgs",
87
+ "type": "github"
88
+ }
89
+ },
90
+ "root": {
91
+ "inputs": {
92
+ "devenv": "devenv",
93
+ "git-hooks": "git-hooks",
94
+ "nixpkgs": "nixpkgs",
95
+ "pre-commit-hooks": [
96
+ "git-hooks"
97
+ ]
98
+ }
99
+ }
100
+ },
101
+ "root": "root",
102
+ "version": 7
103
+ }
data/devenv.nix ADDED
@@ -0,0 +1,9 @@
1
+ { pkgs, lib, config, inputs, ... }:
2
+
3
+ {
4
+
5
+ packages = [ pkgs.git ];
6
+
7
+ languages.ruby.enable = true;
8
+
9
+ }
data/devenv.yaml ADDED
@@ -0,0 +1,15 @@
1
+ # yaml-language-server: $schema=https://devenv.sh/devenv.schema.json
2
+ inputs:
3
+ nixpkgs:
4
+ url: github:cachix/devenv-nixpkgs/rolling
5
+
6
+ # If you're using non-OSS software, you can set allowUnfree to true.
7
+ # allowUnfree: true
8
+
9
+ # If you're willing to use a package that's vulnerable
10
+ # permittedInsecurePackages:
11
+ # - "openssl-1.1.1w"
12
+
13
+ # If you have more than one devenv you can merge them
14
+ #imports:
15
+ # - ./backend
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'lib/durable/llm/version'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = 'durable-llm'
7
+ spec.version = Durable::Llm::VERSION
8
+ spec.authors = ['Durable Programming Team']
9
+ spec.email = ['djberube@durableprogramming.com']
10
+
11
+ spec.summary = 'A Ruby gem providing access to LLM APIs from various vendors'
12
+ spec.description = 'Durable-LLM is a unified interface for interacting with multiple Large Language Model APIs, simplifying integration of AI capabilities into Ruby applications.'
13
+ spec.homepage = 'https://github.com/durableprogramming/durable-llm'
14
+ spec.license = 'MIT'
15
+ spec.required_ruby_version = '>= 2.6.0'
16
+
17
+ spec.metadata['allowed_push_host'] = 'https://rubygems.org'
18
+
19
+ spec.metadata['homepage_uri'] = spec.homepage
20
+ spec.metadata['source_code_uri'] = 'https://github.com/durableprogramming/durable-llm'
21
+ spec.metadata['changelog_uri'] = 'https://github.com/durableprogramming/durable-llm/blob/main/CHANGELOG.md'
22
+
23
+ spec.files = Dir.chdir(__dir__) do
24
+ `git ls-files -z`.split("\x0").reject do |f|
25
+ (File.expand_path(f) == __FILE__) || f.start_with?(*%w[bin/ test/ spec/ features/ .git .circleci appveyor])
26
+ end
27
+ end
28
+ spec.bindir = 'exe'
29
+ spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
30
+ spec.require_paths = ['lib']
31
+
32
+ spec.add_dependency 'event_stream_parser', '~> 1.0'
33
+ spec.add_dependency 'faraday', '> 1.0'
34
+ spec.add_dependency 'highline', '~> 3.1'
35
+ spec.add_dependency 'json', '~> 2.6'
36
+ spec.add_dependency 'thor', '~> 1.3'
37
+ spec.add_dependency 'zeitwerk', '~> 2.6'
38
+
39
+ spec.add_development_dependency 'dotenv', '~> 2.8'
40
+ spec.add_development_dependency 'minitest', '~> 5.0'
41
+ spec.add_development_dependency 'mocha', '~> 2.1'
42
+ spec.add_development_dependency 'rubocop', '~> 1.0'
43
+ spec.add_development_dependency 'vcr', '~> 6.0'
44
+ end
@@ -1,7 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'durable/llm'
2
4
  require 'durable/llm/client'
3
5
 
4
- client = Durable::Llm::Client.new(:openai, :model=> 'gpt-4')
6
+ client = Durable::Llm::Client.new(:openai, model: 'gpt-4')
5
7
 
6
8
  response = client.quick_complete("What's the capital of California?")
7
9