artificial 0.0.1

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.
@@ -0,0 +1,72 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Artificial
4
+ module Validators
5
+ class MessageValidator
6
+ VALID_ROLES = %w[system user assistant].freeze
7
+
8
+ attr_reader :messages, :errors
9
+
10
+ def initialize(messages)
11
+ @messages = messages
12
+ @errors = []
13
+ end
14
+
15
+ def validate
16
+ @errors.clear
17
+
18
+ return add_error('Messages must be an array') unless @messages.is_a?(Array)
19
+ return add_error('Messages array cannot be empty') if @messages.empty?
20
+
21
+ @messages.each_with_index do |message, index|
22
+ validate_message(message, index)
23
+ end
24
+
25
+ self
26
+ end
27
+
28
+ def valid?
29
+ validate if @errors.empty?
30
+ @errors.empty?
31
+ end
32
+
33
+ def error_messages
34
+ @errors
35
+ end
36
+
37
+ private
38
+
39
+ def validate_message(message, index)
40
+ return add_error("Message at index #{index} must be a hash") unless message.is_a?(Hash)
41
+
42
+ validate_role(message, index)
43
+ validate_content(message, index)
44
+ end
45
+
46
+ def validate_role(message, index)
47
+ role = message[:role] || message['role']
48
+
49
+ if role.nil?
50
+ add_error("Message at index #{index} must have a 'role' key")
51
+ elsif !VALID_ROLES.include?(role.to_s)
52
+ add_error("Message at index #{index} has invalid role '#{role}'. Must be one of: #{VALID_ROLES.join(', ')}")
53
+ end
54
+ end
55
+
56
+ def validate_content(message, index)
57
+ content = message[:content] || message['content']
58
+
59
+ if content.nil?
60
+ add_error("Message at index #{index} must have a 'content' key")
61
+ elsif !content.is_a?(String) || content.strip.empty?
62
+ add_error("Message at index #{index} must have non-empty string content")
63
+ end
64
+ end
65
+
66
+ def add_error(message)
67
+ @errors << message
68
+ false
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,128 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Artificial
4
+ module Validators
5
+ class RoleValidator
6
+ VALID_SYSTEM_ROLES = %w[
7
+ expert assistant helper instructor teacher guide analyst
8
+ specialist consultant advisor reviewer critic evaluator
9
+ researcher scientist engineer developer programmer
10
+ writer editor translator interpreter
11
+ ].freeze
12
+
13
+ ROLE_PATTERNS = {
14
+ domain_expert: /^you are (?:a|an) (.+) expert/i,
15
+ professional: /^you are (?:a|an) (.+) professional/i,
16
+ specialist: /^you are (?:a|an) (.+) specialist/i,
17
+ assistant: /^you are (?:a|an) (?:helpful|knowledgeable|.+) assistant/i
18
+ }.freeze
19
+
20
+ attr_reader :system_prompt, :role_type, :errors, :suggestions
21
+
22
+ def initialize(system_prompt)
23
+ @system_prompt = system_prompt
24
+ @role_type = nil
25
+ @errors = []
26
+ @suggestions = []
27
+ end
28
+
29
+ def validate
30
+ @errors.clear
31
+ @suggestions.clear
32
+
33
+ return add_error('System prompt cannot be empty') if @system_prompt.nil? || @system_prompt.strip.empty?
34
+
35
+ analyze_role_effectiveness
36
+ check_role_clarity
37
+ provide_optimization_suggestions
38
+
39
+ self
40
+ end
41
+
42
+ def valid?
43
+ validate if @errors.empty?
44
+ @errors.empty?
45
+ end
46
+
47
+ def effective?
48
+ validate unless @role_type
49
+ @role_type != :generic
50
+ end
51
+
52
+ def error_messages
53
+ @errors
54
+ end
55
+
56
+ def optimization_suggestions
57
+ @suggestions
58
+ end
59
+
60
+ private
61
+
62
+ def analyze_role_effectiveness
63
+ @role_type = determine_role_type
64
+
65
+ case @role_type
66
+ when :domain_expert
67
+ add_suggestion('Excellent! Domain expert roles typically improve response quality by 20-30%')
68
+ when :professional
69
+ add_suggestion('Good! Professional roles help establish expertise and context')
70
+ when :specialist
71
+ add_suggestion('Good! Specialist roles provide focused domain knowledge')
72
+ when :assistant
73
+ add_suggestion('Adequate. Consider making the assistant role more specific for better performance')
74
+ when :generic
75
+ add_suggestion('Generic roles may reduce AI performance. Consider specifying domain expertise')
76
+ else
77
+ add_suggestion('Consider using established role patterns for optimal performance')
78
+ end
79
+ end
80
+
81
+ def determine_role_type
82
+ ROLE_PATTERNS.each do |type, pattern|
83
+ return type if @system_prompt.match?(pattern)
84
+ end
85
+
86
+ return :generic if @system_prompt.downcase.include?('you are')
87
+
88
+ :undefined
89
+ end
90
+
91
+ def check_role_clarity
92
+ unless @system_prompt.downcase.start_with?('you are')
93
+ add_suggestion("Consider starting with 'You are...' for clearer role definition")
94
+ end
95
+
96
+ if @system_prompt.length < 10
97
+ add_error('System prompt too short. Add more context about the role and capabilities')
98
+ elsif @system_prompt.length > 500
99
+ add_suggestion("Consider shortening system prompt for better focus (current: #{@system_prompt.length} chars)")
100
+ end
101
+ end
102
+
103
+ def provide_optimization_suggestions
104
+ if @role_type == :generic || @role_type == :undefined
105
+ add_suggestion("Try: 'You are a [domain] expert with [X] years of experience in [specialization]'")
106
+ end
107
+
108
+ unless @system_prompt.include?('expert') || @system_prompt.include?('specialist')
109
+ add_suggestion("Adding 'expert' or 'specialist' can improve response authority")
110
+ end
111
+
112
+ return unless @system_prompt.count('.') < 2
113
+
114
+ add_suggestion('Consider adding specific capabilities or constraints to the role')
115
+ end
116
+
117
+ def add_error(message)
118
+ @errors << message
119
+ false
120
+ end
121
+
122
+ def add_suggestion(message)
123
+ @suggestions << message
124
+ true
125
+ end
126
+ end
127
+ end
128
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Artificial
4
+ VERSION = '0.0.1'
5
+ end
data/lib/artificial.rb ADDED
@@ -0,0 +1,68 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'artificial/version'
4
+ require_relative 'artificial/prompt'
5
+
6
+ # Load parsers
7
+ require_relative 'artificial/parsers/string_parser'
8
+ require_relative 'artificial/parsers/xml_parser'
9
+ require_relative 'artificial/parsers/yaml_parser'
10
+ require_relative 'artificial/parsers/json_parser'
11
+
12
+ # Load validators
13
+ require_relative 'artificial/validators/message_validator'
14
+ require_relative 'artificial/validators/role_validator'
15
+
16
+ module Artificial
17
+ class Error < StandardError; end
18
+
19
+ # Factory method for creating prompts
20
+ def self.create_prompt(input = nil, **options)
21
+ Prompt.new(input, **options)
22
+ end
23
+
24
+ # Parse input using appropriate parser
25
+ def self.parse(input, format: :auto)
26
+ case format
27
+ when :auto
28
+ auto_parse(input)
29
+ when :string
30
+ Parsers::StringParser.new(input).parse
31
+ when :xml
32
+ Parsers::XMLParser.new(input).parse
33
+ when :yaml
34
+ Parsers::YAMLParser.new(input).parse
35
+ when :json
36
+ Parsers::JSONParser.new(input).parse
37
+ else
38
+ raise ArgumentError, "Unknown format: #{format}"
39
+ end
40
+ end
41
+
42
+ # Validate messages
43
+ def self.validate_messages(messages)
44
+ Validators::MessageValidator.new(messages).validate
45
+ end
46
+
47
+ # Validate role
48
+ def self.validate_role(system_prompt)
49
+ Validators::RoleValidator.new(system_prompt).validate
50
+ end
51
+
52
+ def self.auto_parse(input)
53
+ return Parsers::StringParser.new(input).parse unless input.is_a?(String)
54
+
55
+ # Try to detect format from string content
56
+ input_trimmed = input.strip
57
+
58
+ if input_trimmed.start_with?('<') && input_trimmed.end_with?('>')
59
+ Parsers::XMLParser.new(input).parse
60
+ elsif input_trimmed.start_with?('{') && input_trimmed.end_with?('}')
61
+ Parsers::JSONParser.new(input).parse
62
+ elsif input_trimmed.include?(':') && (input_trimmed.include?('-') || input_trimmed.include?('|') || input_trimmed.include?("\n"))
63
+ Parsers::YAMLParser.new(input).parse
64
+ else
65
+ Parsers::StringParser.new(input).parse
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,4 @@
1
+ module Artificial
2
+ VERSION: String
3
+ # See the writing guide of rbs: https://github.com/ruby/rbs#guides
4
+ end
metadata ADDED
@@ -0,0 +1,155 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: artificial
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Matt Solt
8
+ bindir: exe
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: json
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - "~>"
17
+ - !ruby/object:Gem::Version
18
+ version: '2.6'
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - "~>"
24
+ - !ruby/object:Gem::Version
25
+ version: '2.6'
26
+ - !ruby/object:Gem::Dependency
27
+ name: psych
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - "~>"
31
+ - !ruby/object:Gem::Version
32
+ version: '5.0'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '5.0'
40
+ - !ruby/object:Gem::Dependency
41
+ name: rexml
42
+ requirement: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: '3.2'
47
+ type: :runtime
48
+ prerelease: false
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: '3.2'
54
+ - !ruby/object:Gem::Dependency
55
+ name: minitest
56
+ requirement: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: '5.0'
61
+ type: :development
62
+ prerelease: false
63
+ version_requirements: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - "~>"
66
+ - !ruby/object:Gem::Version
67
+ version: '5.0'
68
+ - !ruby/object:Gem::Dependency
69
+ name: rake
70
+ requirement: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: '13.0'
75
+ type: :development
76
+ prerelease: false
77
+ version_requirements: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "~>"
80
+ - !ruby/object:Gem::Version
81
+ version: '13.0'
82
+ - !ruby/object:Gem::Dependency
83
+ name: rubocop
84
+ requirement: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - "~>"
87
+ - !ruby/object:Gem::Version
88
+ version: '1.21'
89
+ type: :development
90
+ prerelease: false
91
+ version_requirements: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - "~>"
94
+ - !ruby/object:Gem::Version
95
+ version: '1.21'
96
+ - !ruby/object:Gem::Dependency
97
+ name: yard
98
+ requirement: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - "~>"
101
+ - !ruby/object:Gem::Version
102
+ version: '0.9'
103
+ type: :development
104
+ prerelease: false
105
+ version_requirements: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - "~>"
108
+ - !ruby/object:Gem::Version
109
+ version: '0.9'
110
+ description: Artificial intelligence library for prompting - not production-ready.
111
+ email:
112
+ - mattsolt@gmail.com
113
+ executables: []
114
+ extensions: []
115
+ extra_rdoc_files: []
116
+ files:
117
+ - README.md
118
+ - Rakefile
119
+ - examples/demo.rb
120
+ - lib/artificial.rb
121
+ - lib/artificial/parsers/json_parser.rb
122
+ - lib/artificial/parsers/string_parser.rb
123
+ - lib/artificial/parsers/xml_parser.rb
124
+ - lib/artificial/parsers/yaml_parser.rb
125
+ - lib/artificial/prompt.rb
126
+ - lib/artificial/validators/message_validator.rb
127
+ - lib/artificial/validators/role_validator.rb
128
+ - lib/artificial/version.rb
129
+ - sig/artificial.rbs
130
+ homepage: https://github.com/roboruby/artificial
131
+ licenses: []
132
+ metadata:
133
+ allowed_push_host: https://rubygems.org
134
+ homepage_uri: https://github.com/roboruby/artificial
135
+ source_code_uri: https://github.com/roboruby/artificial
136
+ changelog_uri: https://github.com/roboruby/artificial/blob/main/CHANGELOG.md
137
+ documentation_uri: https://rubydoc.info/gems/artificial
138
+ rdoc_options: []
139
+ require_paths:
140
+ - lib
141
+ required_ruby_version: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: 3.1.0
146
+ required_rubygems_version: !ruby/object:Gem::Requirement
147
+ requirements:
148
+ - - ">="
149
+ - !ruby/object:Gem::Version
150
+ version: '0'
151
+ requirements: []
152
+ rubygems_version: 3.6.7
153
+ specification_version: 4
154
+ summary: Artificial intelligence library for prompting
155
+ test_files: []