asimov-openai-module 0.0.0 → 0.1.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 91b9765c48186ce806f5d55a2682fe781ca606ceac54eff2806ac483a7f16482
4
- data.tar.gz: f74d23e6024b35f51e5e67d392212b52ecdedcab99d985c1eb66877a7a6da8ff
3
+ metadata.gz: 16074fac10acec8384d4e663e1dfd5222489516daf586c2cd9f589618f8d1533
4
+ data.tar.gz: 28556b39e6b2b441e09d8cfa647b60907b2469180031bf6da2456b145a39eb53
5
5
  SHA512:
6
- metadata.gz: 3fc2b7db0dbdff7edad88e38cd82890adae7004435c1d3c51c30fba1831d028ad86aa75295145dcb6b3ac931132c12005f3980195a24adfd01d0a5b6b32c5245
7
- data.tar.gz: 8c2d9565a10c3bf741e24c8a61a1336e9c7996f201da929bc5a469fba11e6a8ca18fe2cdfbaa43d2803d664e3fd4a4343da8823b0f93df27aef98776df5c0802
6
+ metadata.gz: 6cbdb1f157186fce6e138078f79034fe03706c28eb8de8aeae0aa82c3a1c7e1a16d19b789940940b94055f0e126dc85d9ced73f1a02de52d68a070f46dd5ebfe
7
+ data.tar.gz: 8c99e3b72b3ea8b443469c25543fe5cb2f4264212e3abb986db29b5a5c0a9cb6fac6489dcf8a6757669ae5108289d8e0415c77776525a01e9788c131e140c77f
data/CHANGES.md CHANGED
@@ -5,4 +5,6 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## 0.1.0 - 2025-02-19
9
+
8
10
  ## 0.0.0 - 2025-02-16
data/README.md CHANGED
@@ -5,3 +5,37 @@
5
5
  [![Package](https://img.shields.io/gem/v/asimov-openai-module)](https://rubygems.org/gems/asimov-openai-module)
6
6
 
7
7
  🚧 _We are building in public. This is presently under heavy construction._
8
+
9
+ ## 🛠️ Prerequisites
10
+
11
+ - [Ruby](https://ruby-lang.org) 3.2+
12
+
13
+ ## ⬇️ Installation
14
+
15
+ ### Installation via RubyGems
16
+
17
+ ```bash
18
+ gem install asimov-openai-module --pre
19
+ ```
20
+
21
+ ## ⚙️ Configuration
22
+
23
+ https://platform.openai.com/docs/quickstart
24
+
25
+ ```bash
26
+ export OPENAI_API_KEY="sk-proj-..."
27
+ ```
28
+
29
+ ## 👨‍💻 Development
30
+
31
+ ```bash
32
+ git clone https://github.com/asimov-modules/asimov-openai-module.git
33
+ ```
34
+
35
+ - - -
36
+
37
+ [![Share on X](https://img.shields.io/badge/share%20on-x-03A9F4?logo=x)](https://x.com/intent/post?url=https://github.com/asimov-modules/asimov-openai-module&text=ASIMOV%20OpenAI%20Module)
38
+ [![Share on Reddit](https://img.shields.io/badge/share%20on-reddit-red?logo=reddit)](https://reddit.com/submit?url=https://github.com/asimov-modules/asimov-openai-module&title=ASIMOV%20OpenAI%20Module)
39
+ [![Share on Hacker News](https://img.shields.io/badge/share%20on-hn-orange?logo=ycombinator)](https://news.ycombinator.com/submitlink?u=https://github.com/asimov-modules/asimov-openai-module&t=ASIMOV%20OpenAI%20Module)
40
+ [![Share on Facebook](https://img.shields.io/badge/share%20on-fb-1976D2?logo=facebook)](https://www.facebook.com/sharer/sharer.php?u=https://github.com/asimov-modules/asimov-openai-module)
41
+ [![Share on LinkedIn](https://img.shields.io/badge/share%20on-linkedin-3949AB?logo=linkedin)](https://www.linkedin.com/sharing/share-offsite/?url=https://github.com/asimov-modules/asimov-openai-module)
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.0
1
+ 0.1.0
@@ -1,2 +1,90 @@
1
1
  #!/usr/bin/env ruby
2
2
  require "bundler/setup"
3
+
4
+ require "asimov/construct"
5
+ require "asimov/module"
6
+ require "mini_mime"
7
+ require "omniai/openai"
8
+ require "optparse"
9
+
10
+ trap(:SIGINT) { abort "" }
11
+
12
+ ARGV0 = File.basename($0).freeze
13
+
14
+ options = {
15
+ model: OmniAI::OpenAI::Chat::DEFAULT_MODEL,
16
+ }
17
+
18
+ option_parser = OptionParser.new do |parser|
19
+ parser.banner = "Usage: #{ARGV0} [OPTIONS] CONSTRUCT PROMPT INPUTS...\n\nOptions:"
20
+ parser.on("-d", "--debug", "Enable debugging output") do
21
+ options[:debug] = true
22
+ end
23
+ parser.on("-m", "--model=ID", "Override the model [default: #{options[:model]}]") do |model_id|
24
+ options[:model] = model_id
25
+ end
26
+ parser.on("-o", "--output=FILE", "Write to file instead of stdout") do |output_path|
27
+ options[:output] = output_path
28
+ end
29
+ parser.on("-v", "--verbose", "Enable verbose output") do
30
+ options[:verbose] = true
31
+ end
32
+ parser.on("-V", "--version", "Print version information") do
33
+ File.read(File.expand_path("../VERSION", __dir__)).strip.tap do |version|
34
+ puts "#{ARGV0} #{version}"; exit
35
+ end
36
+ end
37
+ end
38
+
39
+ begin
40
+ option_parser.parse!(ARGV)
41
+ rescue OptionParser::InvalidOption => error
42
+ abort "#{ARGV0}: invalid option: `#{error.args.join(' ')}`"
43
+ end
44
+
45
+ api_key = ENV["OPENAI_API_KEY"]
46
+ abort "#{ARGV0}: missing OPENAI_API_KEY" if api_key.to_s.empty?
47
+
48
+ construct_id = ARGV.shift
49
+ abort "#{ARGV0}: missing construct ID" unless construct_id
50
+
51
+ construct = ASIMOV::Construct.open(construct_id)
52
+ abort "#{ARGV0}: unknown construct ID" unless construct
53
+
54
+ prompt_text = case ARGV.first
55
+ when nil then abort "#{ARGV0}: missing prompt"
56
+ when "-", "@/dev/stdin" then ARGV.shift; $stdin.read
57
+ when /^@/ then begin
58
+ File.read(ARGV.shift[1..])
59
+ rescue => error
60
+ abort "#{ARGV0}: invalid `@file` prompt: #{error.message}"
61
+ end
62
+ else ARGV.shift
63
+ end
64
+
65
+ prompt = OmniAI::Chat::Prompt.build do |prompt|
66
+ prompt.system(construct.system_prompt)
67
+ prompt.user do |message|
68
+ message.text(prompt_text)
69
+ ARGV.each do |input|
70
+ case input
71
+ when /^https?:\/\// then message.url(input) # TODO: content type
72
+ when /^@/ then message.file(input[1..], MiniMime.lookup_by_filename(input[1..])&.content_type)
73
+ else message.file(input, MiniMime.lookup_by_filename(input)&.content_type)
74
+ end
75
+ end
76
+ end
77
+ end
78
+
79
+ client = OmniAI::OpenAI::Client.new(api_key:)
80
+ model = options[:model]
81
+ stream = case options[:output]
82
+ when nil, "-", "/dev/stdout" then $stdout
83
+ else begin
84
+ File.open(options[:output], "w")
85
+ rescue => error
86
+ abort "#{ARGV0}: invalid `--output` file: #{error.message}"
87
+ end
88
+ end
89
+
90
+ OmniAI::OpenAI::Chat.new(prompt, client:, model:, stream:).process!
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: asimov-openai-module
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.0
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - ASIMOV Protocol
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2025-02-16 00:00:00.000000000 Z
10
+ date: 2025-02-19 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: rake
@@ -23,6 +23,20 @@ dependencies:
23
23
  - - ">="
24
24
  - !ruby/object:Gem::Version
25
25
  version: '13'
26
+ - !ruby/object:Gem::Dependency
27
+ name: asimov-construct
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 25.0.0.dev
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: 25.0.0.dev
26
40
  - !ruby/object:Gem::Dependency
27
41
  name: asimov-module
28
42
  requirement: !ruby/object:Gem::Requirement
@@ -37,6 +51,20 @@ dependencies:
37
51
  - - ">="
38
52
  - !ruby/object:Gem::Version
39
53
  version: 25.0.0.dev
54
+ - !ruby/object:Gem::Dependency
55
+ name: mini_mime
56
+ requirement: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: '1.1'
61
+ type: :runtime
62
+ prerelease: false
63
+ version_requirements: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - "~>"
66
+ - !ruby/object:Gem::Version
67
+ version: '1.1'
40
68
  - !ruby/object:Gem::Dependency
41
69
  name: omniai
42
70
  requirement: !ruby/object:Gem::Requirement