easy_talk 0.1.7 → 0.1.9
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/.rubocop.yml +17 -1
- data/CHANGELOG.md +13 -0
- data/README.md +21 -5
- data/Rakefile +1 -2
- data/easy_talk.gemspec +7 -1
- data/lib/easy_talk/builders/object_builder.rb +40 -24
- data/lib/easy_talk/property.rb +33 -9
- data/lib/easy_talk/schema_definition.rb +12 -3
- data/lib/easy_talk/tools/function_builder.rb +6 -0
- data/lib/easy_talk/version.rb +1 -1
- metadata +89 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cac3597b203d800e1c15c79ea019a6d81080dd5c5ed669dc96500e262a32a505
|
4
|
+
data.tar.gz: 626bb67445db8ffa2d41df7a0b82ceba30db827ed0cb610f4d1b382d161a5191
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e58629e7e0b4aff314f04d0a0d14f3129e0af8b54c23c1d061d57464648aa97caaf2db514353fcf34713d1d14113eb13c599ccc28b6106a3c5f06cd4197671af
|
7
|
+
data.tar.gz: f3ba1ec6c87ff2028a5bd26f22ebade4446717c8d9e27702c94f5e4080fd951885dd033a0d4f88078d44849cb7b251fc1dbb303f9da84b2a592bf85c1daaf9ef
|
data/.rubocop.yml
CHANGED
@@ -1,5 +1,17 @@
|
|
1
|
+
require:
|
2
|
+
- rubocop-rake
|
3
|
+
- rubocop-rspec
|
4
|
+
|
1
5
|
AllCops:
|
2
6
|
TargetRubyVersion: 3.2
|
7
|
+
|
8
|
+
RSpec/FilePath:
|
9
|
+
SpecSuffixOnly: true
|
10
|
+
|
11
|
+
RSpec/ExampleLength:
|
12
|
+
Max: 10
|
13
|
+
Exclude:
|
14
|
+
- 'spec/easy_talk/examples/**/*'
|
3
15
|
|
4
16
|
Metrics/BlockLength:
|
5
17
|
Exclude:
|
@@ -11,4 +23,8 @@ Lint/ConstantDefinitionInBlock:
|
|
11
23
|
|
12
24
|
Layout/LineLength:
|
13
25
|
Exclude:
|
14
|
-
- 'spec/**/*'
|
26
|
+
- 'spec/**/*'
|
27
|
+
|
28
|
+
RSpec/DescribeClass:
|
29
|
+
Exclude:
|
30
|
+
- 'spec/easy_talk/examples/**/*'
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,16 @@
|
|
1
|
+
## [0.1.9] - 2024-04-29
|
2
|
+
- Added the ability to describe an object schema withing the define_schema block. Example:
|
3
|
+
```ruby
|
4
|
+
...
|
5
|
+
property :email, :object do
|
6
|
+
property :address, :string
|
7
|
+
property :verified, :boolean
|
8
|
+
end
|
9
|
+
```
|
10
|
+
|
11
|
+
## [0.1.8] - 2024-04-24
|
12
|
+
- mostly refactoring without changes to the public API.
|
13
|
+
|
1
14
|
## [0.1.7] - 2024-04-16
|
2
15
|
- general cleanup and refactoring.
|
3
16
|
|
data/README.md
CHANGED
@@ -12,7 +12,10 @@ class User
|
|
12
12
|
title "User"
|
13
13
|
description "A user of the system"
|
14
14
|
property :name, String, description: "The user's name", title: "Full Name"
|
15
|
-
property :email,
|
15
|
+
property :email, :object do
|
16
|
+
property :address, String, format: "email", description: "The user's email", title: "Email Address"
|
17
|
+
property :verified, T::Boolean, description: "Whether the email is verified"
|
18
|
+
end
|
16
19
|
property :group, String, enum: [1, 2, 3], default: 1, description: "The user's group"
|
17
20
|
property :age, Integer, minimum: 18, maximum: 100, description: "The user's age"
|
18
21
|
property :tags, T::Array[String], min_items: 1, unique_item: true, description: "The user's tags"
|
@@ -34,10 +37,23 @@ Calling `User.json_schema` will return the JSON Schema for the User class:
|
|
34
37
|
"type": "string"
|
35
38
|
},
|
36
39
|
"email": {
|
37
|
-
"
|
38
|
-
"
|
39
|
-
|
40
|
-
|
40
|
+
"type": "object",
|
41
|
+
"properties": {
|
42
|
+
"address": {
|
43
|
+
"title": "Email Address",
|
44
|
+
"description": "The user's email",
|
45
|
+
"type": "string",
|
46
|
+
"format": "email"
|
47
|
+
},
|
48
|
+
"verified": {
|
49
|
+
"type": "boolean",
|
50
|
+
"description": "Whether the email is verified"
|
51
|
+
}
|
52
|
+
},
|
53
|
+
"required": [
|
54
|
+
"address",
|
55
|
+
"verified"
|
56
|
+
]
|
41
57
|
},
|
42
58
|
"group": {
|
43
59
|
"type": "number",
|
data/Rakefile
CHANGED
data/easy_talk.gemspec
CHANGED
@@ -34,6 +34,12 @@ Gem::Specification.new do |spec|
|
|
34
34
|
spec.add_dependency 'activesupport', '~> 7.0'
|
35
35
|
spec.add_dependency 'json-schema', '~> 4'
|
36
36
|
spec.add_dependency 'sorbet-runtime', '~> 0.5'
|
37
|
-
spec.add_development_dependency 'pry-byebug', '>= 3.10
|
37
|
+
spec.add_development_dependency 'pry-byebug', '>= 3.10'
|
38
38
|
spec.add_development_dependency 'rake', '~> 13.1'
|
39
|
+
spec.add_development_dependency 'rspec', '~> 3.0'
|
40
|
+
spec.add_development_dependency 'rspec-json_expectations', '~> 2.0'
|
41
|
+
spec.add_development_dependency 'rspec-mocks', '~> 3.13'
|
42
|
+
spec.add_development_dependency 'rubocop', '~> 1.21'
|
43
|
+
spec.add_development_dependency 'rubocop-rake', '~> 0.6'
|
44
|
+
spec.add_development_dependency 'rubocop-rspec', '~> 2.29'
|
39
45
|
end
|
@@ -8,10 +8,10 @@ module EasyTalk
|
|
8
8
|
class ObjectBuilder < BaseBuilder
|
9
9
|
extend T::Sig
|
10
10
|
|
11
|
-
attr_reader :
|
11
|
+
attr_reader :schema
|
12
12
|
|
13
13
|
VALID_OPTIONS = {
|
14
|
-
properties: { type: T::Hash[Symbol, T.untyped], key: :properties },
|
14
|
+
properties: { type: T::Hash[T.any(Symbol, String), T.untyped], key: :properties },
|
15
15
|
additional_properties: { type: T::Boolean, key: :additionalProperties },
|
16
16
|
subschemas: { type: T::Array[T.untyped], key: :subschemas },
|
17
17
|
required: { type: T::Array[Symbol], key: :required },
|
@@ -33,42 +33,58 @@ module EasyTalk
|
|
33
33
|
|
34
34
|
private
|
35
35
|
|
36
|
-
def properties_from_schema_definition
|
36
|
+
def properties_from_schema_definition
|
37
|
+
properties = schema.delete(:properties) || {}
|
37
38
|
properties.each_with_object({}) do |(property_name, options), context|
|
38
|
-
|
39
|
-
context[property_name] =
|
39
|
+
add_required_property(property_name, options)
|
40
|
+
context[property_name] = build_property(property_name, options)
|
40
41
|
end
|
41
42
|
end
|
42
43
|
|
43
|
-
def
|
44
|
+
def add_required_property(property_name, options)
|
45
|
+
return unless options.is_a?(Hash) && !(options[:type].respond_to?(:nilable?) && options[:type].nilable?)
|
46
|
+
|
47
|
+
@required_properties << property_name
|
48
|
+
end
|
49
|
+
|
50
|
+
def build_property(property_name, options)
|
51
|
+
if options.is_a?(EasyTalk::SchemaDefinition)
|
52
|
+
ObjectBuilder.new(options).build
|
53
|
+
else
|
54
|
+
Property.new(property_name, options[:type], options[:constraints])
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def subschemas_from_schema_definition
|
59
|
+
subschemas = schema.delete(:subschemas) || []
|
44
60
|
subschemas.each do |subschema|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
61
|
+
add_definitions(subschema)
|
62
|
+
add_references(subschema)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def add_definitions(subschema)
|
67
|
+
definitions = subschema.items.each_with_object({}) do |item, hash|
|
68
|
+
hash[item.name] = item.schema
|
69
|
+
end
|
70
|
+
schema[:defs] = definitions
|
71
|
+
end
|
72
|
+
|
73
|
+
def add_references(subschema)
|
74
|
+
references = subschema.items.map do |item|
|
75
|
+
{ '$ref': item.ref_template }
|
53
76
|
end
|
77
|
+
schema[subschema.name] = references
|
54
78
|
end
|
55
79
|
|
56
80
|
def options
|
57
|
-
subschemas_from_schema_definition(subschemas)
|
58
81
|
@options = schema
|
59
|
-
|
82
|
+
subschemas_from_schema_definition
|
83
|
+
@options[:properties] = properties_from_schema_definition
|
60
84
|
@options[:required] = @required_properties
|
61
85
|
@options.reject! { |_key, value| [nil, [], {}].include?(value) }
|
62
86
|
@options
|
63
87
|
end
|
64
|
-
|
65
|
-
def properties
|
66
|
-
schema.delete(:properties) || {}
|
67
|
-
end
|
68
|
-
|
69
|
-
def subschemas
|
70
|
-
schema.delete(:subschemas) || []
|
71
|
-
end
|
72
88
|
end
|
73
89
|
end
|
74
90
|
end
|
data/lib/easy_talk/property.rb
CHANGED
@@ -17,6 +17,16 @@ require_relative 'builders/union_builder'
|
|
17
17
|
|
18
18
|
# frozen_string_literal: true
|
19
19
|
|
20
|
+
# EasyTalk module provides classes for building JSON schema properties.
|
21
|
+
#
|
22
|
+
# This module contains the `Property` class, which is used to build a JSON schema property.
|
23
|
+
# It also defines a constant `TYPE_TO_BUILDER` which maps property types to their respective builders.
|
24
|
+
#
|
25
|
+
# Example usage:
|
26
|
+
# property = EasyTalk::Property.new(:name, 'String', minLength: 3, maxLength: 50)
|
27
|
+
# property.build
|
28
|
+
#
|
29
|
+
# @see EasyTalk::Property
|
20
30
|
module EasyTalk
|
21
31
|
# Property class for building a JSON schema property.
|
22
32
|
class Property
|
@@ -56,22 +66,36 @@ module EasyTalk
|
|
56
66
|
raise ArgumentError, 'property type is missing' if type.blank?
|
57
67
|
end
|
58
68
|
|
69
|
+
# Builds the property based on the specified type, constraints, and builder.
|
70
|
+
#
|
71
|
+
# If the type responds to the `schema` method, it returns the schema of the type.
|
72
|
+
# Otherwise, it returns 'object'.
|
73
|
+
#
|
74
|
+
# If a builder is specified, it uses the builder to build the property.
|
75
|
+
# The arguments passed to the builder depend on whether the builder is a collection type or not.
|
76
|
+
#
|
77
|
+
# @return [Object] The built property.
|
59
78
|
def build
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
builder.new(name, constraints).build
|
65
|
-
end
|
66
|
-
else
|
67
|
-
type.respond_to?(:schema) ? type.schema : 'object'
|
68
|
-
end
|
79
|
+
return type.respond_to?(:schema) ? type.schema : 'object' unless builder
|
80
|
+
|
81
|
+
args = builder.collection_type? ? [name, type, constraints] : [name, constraints]
|
82
|
+
builder.new(*args).build
|
69
83
|
end
|
70
84
|
|
85
|
+
# Converts the object to a JSON representation.
|
86
|
+
#
|
87
|
+
# @param _args [Array] Optional arguments
|
88
|
+
# @return [Hash] The JSON representation of the object
|
71
89
|
def as_json(*_args)
|
72
90
|
build.as_json
|
73
91
|
end
|
74
92
|
|
93
|
+
# Returns the builder associated with the property type.
|
94
|
+
#
|
95
|
+
# The builder is responsible for constructing the property based on its type.
|
96
|
+
# It looks up the builder based on the type's class name or name.
|
97
|
+
#
|
98
|
+
# @return [Builder] The builder associated with the property type.
|
75
99
|
def builder
|
76
100
|
TYPE_TO_BUILDER[type.class.name.to_s] || TYPE_TO_BUILDER[type.name.to_s]
|
77
101
|
end
|
@@ -32,10 +32,19 @@ module EasyTalk
|
|
32
32
|
@schema[:subschemas] += subschemas
|
33
33
|
end
|
34
34
|
|
35
|
-
sig
|
36
|
-
|
35
|
+
sig do
|
36
|
+
params(name: T.any(Symbol, String), type: T.untyped, constraints: T.untyped, blk: T.nilable(T.proc.void)).void
|
37
|
+
end
|
38
|
+
def property(name, type, **constraints, &blk)
|
37
39
|
@schema[:properties] ||= {}
|
38
|
-
|
40
|
+
|
41
|
+
if block_given?
|
42
|
+
property_schema = SchemaDefinition.new(name)
|
43
|
+
property_schema.instance_eval(&blk)
|
44
|
+
@schema[:properties][name] = property_schema
|
45
|
+
else
|
46
|
+
@schema[:properties][name] = { type:, constraints: }
|
47
|
+
end
|
39
48
|
end
|
40
49
|
end
|
41
50
|
end
|
@@ -2,7 +2,13 @@
|
|
2
2
|
|
3
3
|
module EasyTalk
|
4
4
|
module Tools
|
5
|
+
# FunctionBuilder is a module that builds a hash with the function type and function details.
|
6
|
+
# The return value is typically passed as argument to LLM function calling APIs.
|
5
7
|
module FunctionBuilder
|
8
|
+
# Creates a new function object based on the given model.
|
9
|
+
#
|
10
|
+
# @param [Model] model The EasyTalk model containing the function details.
|
11
|
+
# @return [Hash] The function object.
|
6
12
|
def self.new(model)
|
7
13
|
{
|
8
14
|
type: 'function',
|
data/lib/easy_talk/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: easy_talk
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.9
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sergio Bayona
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-04-
|
11
|
+
date: 2024-04-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -58,14 +58,14 @@ dependencies:
|
|
58
58
|
requirements:
|
59
59
|
- - ">="
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: 3.10
|
61
|
+
version: '3.10'
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: 3.10
|
68
|
+
version: '3.10'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: rake
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -80,6 +80,90 @@ dependencies:
|
|
80
80
|
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '13.1'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rspec
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '3.0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '3.0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: rspec-json_expectations
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '2.0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '2.0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: rspec-mocks
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '3.13'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '3.13'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: rubocop
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - "~>"
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '1.21'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - "~>"
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '1.21'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: rubocop-rake
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - "~>"
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0.6'
|
146
|
+
type: :development
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - "~>"
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '0.6'
|
153
|
+
- !ruby/object:Gem::Dependency
|
154
|
+
name: rubocop-rspec
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - "~>"
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: '2.29'
|
160
|
+
type: :development
|
161
|
+
prerelease: false
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - "~>"
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: '2.29'
|
83
167
|
description: Generate json-schema from plain Ruby classes.
|
84
168
|
email:
|
85
169
|
- bayona.sergio@gmail.com
|
@@ -146,7 +230,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
146
230
|
- !ruby/object:Gem::Version
|
147
231
|
version: '0'
|
148
232
|
requirements: []
|
149
|
-
rubygems_version: 3.5.
|
233
|
+
rubygems_version: 3.5.9
|
150
234
|
signing_key:
|
151
235
|
specification_version: 4
|
152
236
|
summary: Generate json-schema from Ruby classes.
|