sorbet-baml 0.1.0 → 0.3.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 +4 -4
- data/CLAUDE.md +94 -0
- data/README.md +315 -122
- data/Rakefile +2 -2
- data/docs-site/.gitignore +48 -0
- data/docs-site/Gemfile +5 -0
- data/docs-site/Gemfile.lock +140 -0
- data/docs-site/Rakefile +3 -0
- data/docs-site/bridgetown.config.yml +15 -0
- data/docs-site/config/initializers.rb +9 -0
- data/docs-site/config/puma.rb +9 -0
- data/docs-site/config.ru +5 -0
- data/docs-site/esbuild.config.js +11 -0
- data/docs-site/frontend/javascript/index.js +22 -0
- data/docs-site/frontend/styles/index.css +61 -0
- data/docs-site/package.json +18 -0
- data/docs-site/postcss.config.js +6 -0
- data/docs-site/server/roda_app.rb +9 -0
- data/docs-site/src/_components/head.liquid +26 -0
- data/docs-site/src/_components/nav.liquid +68 -0
- data/docs-site/src/_layouts/default.liquid +27 -0
- data/docs-site/src/_layouts/doc.liquid +39 -0
- data/docs-site/src/advanced-usage.md +598 -0
- data/docs-site/src/getting-started.md +170 -0
- data/docs-site/src/index.md +183 -0
- data/docs-site/src/troubleshooting.md +317 -0
- data/docs-site/src/type-mapping.md +236 -0
- data/docs-site/tailwind.config.js +85 -0
- data/examples/description_parameters.rb +49 -0
- data/lib/sorbet_baml/comment_extractor.rb +51 -54
- data/lib/sorbet_baml/converter.rb +69 -35
- data/lib/sorbet_baml/dependency_resolver.rb +11 -11
- data/lib/sorbet_baml/description_extension.rb +34 -0
- data/lib/sorbet_baml/description_extractor.rb +34 -0
- data/lib/sorbet_baml/dspy_tool_converter.rb +97 -0
- data/lib/sorbet_baml/dspy_tool_extensions.rb +23 -0
- data/lib/sorbet_baml/enum_extensions.rb +2 -2
- data/lib/sorbet_baml/struct_extensions.rb +2 -2
- data/lib/sorbet_baml/tool_extensions.rb +23 -0
- data/lib/sorbet_baml/type_mapper.rb +35 -37
- data/lib/sorbet_baml/version.rb +1 -1
- data/lib/sorbet_baml.rb +41 -10
- data/sorbet/config +2 -0
- data/sorbet/rbi/gems/anthropic@1.5.0.rbi +21252 -0
- data/sorbet/rbi/gems/async@2.27.3.rbi +9 -0
- data/sorbet/rbi/gems/bigdecimal@3.2.2.rbi +9 -0
- data/sorbet/rbi/gems/concurrent-ruby@1.3.5.rbi +424 -0
- data/sorbet/rbi/gems/connection_pool@2.5.3.rbi +9 -0
- data/sorbet/rbi/gems/console@1.33.0.rbi +9 -0
- data/sorbet/rbi/gems/dry-configurable@1.3.0.rbi +672 -0
- data/sorbet/rbi/gems/dry-core@1.1.0.rbi +1729 -0
- data/sorbet/rbi/gems/dry-logger@1.1.0.rbi +1317 -0
- data/sorbet/rbi/gems/dspy@0.19.1.rbi +6677 -0
- data/sorbet/rbi/gems/ffi@1.17.2.rbi +2174 -0
- data/sorbet/rbi/gems/fiber-annotation@0.2.0.rbi +9 -0
- data/sorbet/rbi/gems/fiber-local@1.1.0.rbi +9 -0
- data/sorbet/rbi/gems/fiber-storage@1.0.1.rbi +9 -0
- data/sorbet/rbi/gems/google-protobuf@4.32.0.rbi +9 -0
- data/sorbet/rbi/gems/googleapis-common-protos-types@1.20.0.rbi +9 -0
- data/sorbet/rbi/gems/informers@1.2.1.rbi +1875 -0
- data/sorbet/rbi/gems/io-event@1.12.1.rbi +9 -0
- data/sorbet/rbi/gems/metrics@0.13.0.rbi +9 -0
- data/sorbet/rbi/gems/onnxruntime@0.10.0.rbi +304 -0
- data/sorbet/rbi/gems/openai@0.16.0.rbi +68055 -0
- data/sorbet/rbi/gems/opentelemetry-api@1.6.0.rbi +9 -0
- data/sorbet/rbi/gems/opentelemetry-common@0.22.0.rbi +9 -0
- data/sorbet/rbi/gems/opentelemetry-exporter-otlp@0.30.0.rbi +9 -0
- data/sorbet/rbi/gems/opentelemetry-registry@0.4.0.rbi +9 -0
- data/sorbet/rbi/gems/opentelemetry-sdk@1.8.1.rbi +9 -0
- data/sorbet/rbi/gems/opentelemetry-semantic_conventions@1.11.0.rbi +9 -0
- data/sorbet/rbi/gems/polars-df@0.20.0.rbi +9 -0
- data/sorbet/rbi/gems/sorbet-result@1.4.0.rbi +242 -0
- data/sorbet/rbi/gems/sorbet-schema@0.9.2.rbi +743 -0
- data/sorbet/rbi/gems/sorbet-struct-comparable@1.3.0.rbi +48 -0
- data/sorbet/rbi/gems/tokenizers@0.5.5.rbi +754 -0
- data/sorbet/rbi/gems/traces@0.17.0.rbi +9 -0
- data/sorbet/rbi/gems/zeitwerk@2.7.3.rbi +1429 -0
- metadata +67 -7
- data/docs/README.md +0 -117
- data/docs/advanced-usage.md +0 -427
- data/docs/getting-started.md +0 -91
- data/docs/troubleshooting.md +0 -291
- data/docs/type-mapping.md +0 -192
data/docs/getting-started.md
DELETED
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
# Getting Started
|
|
2
|
-
|
|
3
|
-
## Prerequisites
|
|
4
|
-
|
|
5
|
-
- Ruby 3.2+
|
|
6
|
-
- Sorbet installed in your project
|
|
7
|
-
- Basic familiarity with T::Struct
|
|
8
|
-
|
|
9
|
-
## Quick Start
|
|
10
|
-
|
|
11
|
-
### 1. Define your Sorbet types
|
|
12
|
-
|
|
13
|
-
```ruby
|
|
14
|
-
class User < T::Struct
|
|
15
|
-
const :id, Integer
|
|
16
|
-
const :name, String
|
|
17
|
-
const :email, T.nilable(String)
|
|
18
|
-
end
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
### 2. Convert to BAML
|
|
22
|
-
|
|
23
|
-
```ruby
|
|
24
|
-
require 'sorbet-baml'
|
|
25
|
-
|
|
26
|
-
# Ruby-idiomatic API (recommended)
|
|
27
|
-
User.to_baml
|
|
28
|
-
|
|
29
|
-
# Legacy API (still supported)
|
|
30
|
-
baml = SorbetBaml.from_struct(User)
|
|
31
|
-
puts baml
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
**Generated BAML:**
|
|
35
|
-
```baml
|
|
36
|
-
class User {
|
|
37
|
-
id int
|
|
38
|
-
name string
|
|
39
|
-
email string?
|
|
40
|
-
}
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
### 3. Add field descriptions (optional)
|
|
44
|
-
|
|
45
|
-
Document your fields with comments for better LLM understanding:
|
|
46
|
-
|
|
47
|
-
```ruby
|
|
48
|
-
class User < T::Struct
|
|
49
|
-
# Unique identifier for the user account
|
|
50
|
-
const :id, Integer
|
|
51
|
-
|
|
52
|
-
# User's display name, visible to other users
|
|
53
|
-
const :name, String
|
|
54
|
-
|
|
55
|
-
# Optional email for notifications and login
|
|
56
|
-
const :email, T.nilable(String)
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
# Generate BAML (descriptions included by default!)
|
|
60
|
-
User.to_baml
|
|
61
|
-
```
|
|
62
|
-
|
|
63
|
-
**Generated BAML with descriptions:**
|
|
64
|
-
```baml
|
|
65
|
-
class User {
|
|
66
|
-
id int @description("Unique identifier for the user account")
|
|
67
|
-
name string @description("User's display name, visible to other users")
|
|
68
|
-
email string? @description("Optional email for notifications and login")
|
|
69
|
-
}
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
### 4. Use with your LLM
|
|
73
|
-
|
|
74
|
-
Include the BAML definition in your prompt:
|
|
75
|
-
|
|
76
|
-
```ruby
|
|
77
|
-
baml = User.to_baml
|
|
78
|
-
prompt = <<~PROMPT
|
|
79
|
-
Generate sample data matching this schema:
|
|
80
|
-
|
|
81
|
-
#{baml}
|
|
82
|
-
|
|
83
|
-
Return 3 realistic examples.
|
|
84
|
-
PROMPT
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
## Next Steps
|
|
88
|
-
|
|
89
|
-
- [Type Mapping Reference](./type-mapping.md)
|
|
90
|
-
- [Advanced Usage](./advanced-usage.md)
|
|
91
|
-
- [Troubleshooting](./troubleshooting.md)
|
data/docs/troubleshooting.md
DELETED
|
@@ -1,291 +0,0 @@
|
|
|
1
|
-
# Troubleshooting
|
|
2
|
-
|
|
3
|
-
## Common Issues
|
|
4
|
-
|
|
5
|
-
### "undefined method `props' for Class"
|
|
6
|
-
|
|
7
|
-
**Problem**: The class you're trying to convert is not a T::Struct.
|
|
8
|
-
|
|
9
|
-
**Solution**: Ensure your class inherits from `T::Struct`:
|
|
10
|
-
|
|
11
|
-
```ruby
|
|
12
|
-
# ❌ Wrong
|
|
13
|
-
class User
|
|
14
|
-
attr_reader :name
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
# ✅ Correct
|
|
18
|
-
class User < T::Struct
|
|
19
|
-
const :name, String
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
# Generate BAML
|
|
23
|
-
User.to_baml
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
**Generated BAML:**
|
|
27
|
-
```baml
|
|
28
|
-
class User {
|
|
29
|
-
name string
|
|
30
|
-
}
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
### Empty output
|
|
34
|
-
|
|
35
|
-
**Problem**: The struct has no properties defined.
|
|
36
|
-
|
|
37
|
-
**Solution**: Define at least one property using `const` or `prop`:
|
|
38
|
-
|
|
39
|
-
```ruby
|
|
40
|
-
class User < T::Struct
|
|
41
|
-
const :name, String # Add properties
|
|
42
|
-
const :age, Integer
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
User.to_baml
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
**Generated BAML:**
|
|
49
|
-
```baml
|
|
50
|
-
class User {
|
|
51
|
-
name string
|
|
52
|
-
age int
|
|
53
|
-
}
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
### Self-referential types work fine
|
|
57
|
-
|
|
58
|
-
**Problem**: You think self-referential types aren't supported.
|
|
59
|
-
|
|
60
|
-
**Solution**: They actually work perfectly! Self-referential types are fully supported:
|
|
61
|
-
|
|
62
|
-
```ruby
|
|
63
|
-
class Category < T::Struct
|
|
64
|
-
const :name, String
|
|
65
|
-
const :parent, T.nilable(Category)
|
|
66
|
-
const :children, T::Array[Category]
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
Category.to_baml
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
**Generated BAML:**
|
|
73
|
-
```baml
|
|
74
|
-
class Category {
|
|
75
|
-
name string
|
|
76
|
-
parent Category?
|
|
77
|
-
children Category[]
|
|
78
|
-
}
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
## Type-Specific Issues
|
|
82
|
-
|
|
83
|
-
### Arrays not converting correctly
|
|
84
|
-
|
|
85
|
-
Ensure you're using the Sorbet array syntax:
|
|
86
|
-
|
|
87
|
-
```ruby
|
|
88
|
-
# ❌ Wrong
|
|
89
|
-
class User < T::Struct
|
|
90
|
-
const :items, Array # Generic Array won't work
|
|
91
|
-
end
|
|
92
|
-
|
|
93
|
-
# ✅ Correct
|
|
94
|
-
class User < T::Struct
|
|
95
|
-
const :items, T::Array[String]
|
|
96
|
-
end
|
|
97
|
-
|
|
98
|
-
User.to_baml
|
|
99
|
-
```
|
|
100
|
-
|
|
101
|
-
**Generated BAML:**
|
|
102
|
-
```baml
|
|
103
|
-
class User {
|
|
104
|
-
items string[]
|
|
105
|
-
}
|
|
106
|
-
```
|
|
107
|
-
|
|
108
|
-
### Optional fields showing as required
|
|
109
|
-
|
|
110
|
-
Make sure to use `T.nilable`:
|
|
111
|
-
|
|
112
|
-
```ruby
|
|
113
|
-
# ❌ Wrong - will be required
|
|
114
|
-
class User < T::Struct
|
|
115
|
-
const :email, String
|
|
116
|
-
end
|
|
117
|
-
|
|
118
|
-
# ✅ Correct - will be optional
|
|
119
|
-
class User < T::Struct
|
|
120
|
-
const :email, T.nilable(String)
|
|
121
|
-
end
|
|
122
|
-
|
|
123
|
-
User.to_baml
|
|
124
|
-
```
|
|
125
|
-
|
|
126
|
-
**Generated BAML:**
|
|
127
|
-
```baml
|
|
128
|
-
class User {
|
|
129
|
-
email string?
|
|
130
|
-
}
|
|
131
|
-
```
|
|
132
|
-
|
|
133
|
-
### Union types not working
|
|
134
|
-
|
|
135
|
-
Ensure you're using `T.any` for union types:
|
|
136
|
-
|
|
137
|
-
```ruby
|
|
138
|
-
# ❌ Wrong
|
|
139
|
-
class Config < T::Struct
|
|
140
|
-
const :value, String || Integer # Ruby OR, not Sorbet union
|
|
141
|
-
end
|
|
142
|
-
|
|
143
|
-
# ✅ Correct
|
|
144
|
-
class Config < T::Struct
|
|
145
|
-
const :value, T.any(String, Integer)
|
|
146
|
-
end
|
|
147
|
-
|
|
148
|
-
Config.to_baml
|
|
149
|
-
```
|
|
150
|
-
|
|
151
|
-
**Generated BAML:**
|
|
152
|
-
```baml
|
|
153
|
-
class Config {
|
|
154
|
-
value string | int
|
|
155
|
-
}
|
|
156
|
-
```
|
|
157
|
-
|
|
158
|
-
### Hash types not mapping correctly
|
|
159
|
-
|
|
160
|
-
Use the full `T::Hash[K, V]` syntax:
|
|
161
|
-
|
|
162
|
-
```ruby
|
|
163
|
-
# ❌ Wrong
|
|
164
|
-
class User < T::Struct
|
|
165
|
-
const :metadata, Hash # Generic Hash won't work
|
|
166
|
-
end
|
|
167
|
-
|
|
168
|
-
# ✅ Correct
|
|
169
|
-
class User < T::Struct
|
|
170
|
-
const :metadata, T::Hash[String, T.any(String, Integer)]
|
|
171
|
-
end
|
|
172
|
-
|
|
173
|
-
User.to_baml
|
|
174
|
-
```
|
|
175
|
-
|
|
176
|
-
**Generated BAML:**
|
|
177
|
-
```baml
|
|
178
|
-
class User {
|
|
179
|
-
metadata map<string, string | int>
|
|
180
|
-
}
|
|
181
|
-
```
|
|
182
|
-
|
|
183
|
-
## Dependency Issues
|
|
184
|
-
|
|
185
|
-
### Missing dependencies in output
|
|
186
|
-
|
|
187
|
-
Use `include_dependencies: true` to automatically include all referenced types:
|
|
188
|
-
|
|
189
|
-
```ruby
|
|
190
|
-
class Address < T::Struct
|
|
191
|
-
const :street, String
|
|
192
|
-
const :city, String
|
|
193
|
-
end
|
|
194
|
-
|
|
195
|
-
class User < T::Struct
|
|
196
|
-
const :name, String
|
|
197
|
-
const :address, Address
|
|
198
|
-
end
|
|
199
|
-
|
|
200
|
-
# ❌ Only outputs User class
|
|
201
|
-
User.to_baml
|
|
202
|
-
|
|
203
|
-
# ✅ Outputs both Address and User in correct order
|
|
204
|
-
User.to_baml(include_dependencies: true)
|
|
205
|
-
```
|
|
206
|
-
|
|
207
|
-
**Generated BAML (with dependencies):**
|
|
208
|
-
```baml
|
|
209
|
-
class Address {
|
|
210
|
-
street string
|
|
211
|
-
city string
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
class User {
|
|
215
|
-
name string
|
|
216
|
-
address Address
|
|
217
|
-
}
|
|
218
|
-
```
|
|
219
|
-
|
|
220
|
-
### Wrong dependency order
|
|
221
|
-
|
|
222
|
-
The gem automatically handles dependency ordering using topological sorting. Dependencies always come before the types that reference them.
|
|
223
|
-
|
|
224
|
-
## Enum Issues
|
|
225
|
-
|
|
226
|
-
### Enums not converting
|
|
227
|
-
|
|
228
|
-
Ensure you're using the correct T::Enum syntax:
|
|
229
|
-
|
|
230
|
-
```ruby
|
|
231
|
-
# ❌ Wrong
|
|
232
|
-
class Status
|
|
233
|
-
ACTIVE = 'active'
|
|
234
|
-
INACTIVE = 'inactive'
|
|
235
|
-
end
|
|
236
|
-
|
|
237
|
-
# ✅ Correct
|
|
238
|
-
class Status < T::Enum
|
|
239
|
-
enums do
|
|
240
|
-
Active = new('active')
|
|
241
|
-
Inactive = new('inactive')
|
|
242
|
-
end
|
|
243
|
-
end
|
|
244
|
-
|
|
245
|
-
Status.to_baml
|
|
246
|
-
```
|
|
247
|
-
|
|
248
|
-
**Generated BAML:**
|
|
249
|
-
```baml
|
|
250
|
-
enum Status {
|
|
251
|
-
"active"
|
|
252
|
-
"inactive"
|
|
253
|
-
}
|
|
254
|
-
```
|
|
255
|
-
|
|
256
|
-
## Getting Help
|
|
257
|
-
|
|
258
|
-
1. Check the [Type Mapping Reference](./type-mapping.md) for complete type support
|
|
259
|
-
2. Review examples in [Getting Started](./getting-started.md) and [Advanced Usage](./advanced-usage.md)
|
|
260
|
-
3. File an issue at https://github.com/vicentereig/sorbet-baml/issues
|
|
261
|
-
|
|
262
|
-
## Advanced Debugging
|
|
263
|
-
|
|
264
|
-
### Inspect Sorbet type information
|
|
265
|
-
|
|
266
|
-
```ruby
|
|
267
|
-
# See what Sorbet sees for your struct
|
|
268
|
-
MyStruct.props
|
|
269
|
-
# => {name: String, age: Integer, ...}
|
|
270
|
-
|
|
271
|
-
# Check if a class is a T::Struct
|
|
272
|
-
MyStruct < T::Struct
|
|
273
|
-
# => true
|
|
274
|
-
|
|
275
|
-
# See enum values
|
|
276
|
-
MyEnum.values
|
|
277
|
-
# => [#<MyEnum:0x... @serialize="value1">, ...]
|
|
278
|
-
```
|
|
279
|
-
|
|
280
|
-
### Testing your BAML output
|
|
281
|
-
|
|
282
|
-
```ruby
|
|
283
|
-
# Verify the output looks correct
|
|
284
|
-
baml = User.to_baml(include_dependencies: true)
|
|
285
|
-
puts baml
|
|
286
|
-
|
|
287
|
-
# Check that all expected types are included
|
|
288
|
-
expected_types = ['class User', 'class Address', 'enum Status']
|
|
289
|
-
expected_types.all? { |type| baml.include?(type) }
|
|
290
|
-
# => true
|
|
291
|
-
```
|
data/docs/type-mapping.md
DELETED
|
@@ -1,192 +0,0 @@
|
|
|
1
|
-
# Type Mapping Reference
|
|
2
|
-
|
|
3
|
-
Complete mapping between Sorbet types and BAML output. All listed types are **fully supported**.
|
|
4
|
-
|
|
5
|
-
## Basic Types
|
|
6
|
-
|
|
7
|
-
| Sorbet Type | BAML Output | Example |
|
|
8
|
-
|-------------|-------------|---------|
|
|
9
|
-
| `String` | `string` | `name string` |
|
|
10
|
-
| `Integer` | `int` | `age int` |
|
|
11
|
-
| `Float` | `float` | `price float` |
|
|
12
|
-
| `T::Boolean` | `bool` | `active bool` |
|
|
13
|
-
| `NilClass` | `null` | `null` |
|
|
14
|
-
| `Symbol` | `string` | `status string` |
|
|
15
|
-
| `Date/DateTime/Time` | `string` | `created_at string` |
|
|
16
|
-
|
|
17
|
-
## Optional Types (T.nilable)
|
|
18
|
-
|
|
19
|
-
| Sorbet Type | BAML Output | Example |
|
|
20
|
-
|-------------|-------------|---------|
|
|
21
|
-
| `T.nilable(String)` | `string?` | `email string?` |
|
|
22
|
-
| `T.nilable(Integer)` | `int?` | `age int?` |
|
|
23
|
-
| `T.nilable(MyStruct)` | `MyStruct?` | `address Address?` |
|
|
24
|
-
|
|
25
|
-
## Collection Types
|
|
26
|
-
|
|
27
|
-
| Sorbet Type | BAML Output | Example |
|
|
28
|
-
|-------------|-------------|---------|
|
|
29
|
-
| `T::Array[String]` | `string[]` | `tags string[]` |
|
|
30
|
-
| `T::Array[Integer]` | `int[]` | `scores int[]` |
|
|
31
|
-
| `T::Array[MyStruct]` | `MyStruct[]` | `addresses Address[]` |
|
|
32
|
-
|
|
33
|
-
## Hash/Map Types
|
|
34
|
-
|
|
35
|
-
| Sorbet Type | BAML Output | Example |
|
|
36
|
-
|-------------|-------------|---------|
|
|
37
|
-
| `T::Hash[String, String]` | `map<string, string>` | `metadata map<string, string>` |
|
|
38
|
-
| `T::Hash[String, Integer]` | `map<string, int>` | `counts map<string, int>` |
|
|
39
|
-
| `T::Hash[Symbol, String]` | `map<string, string>` | `config map<string, string>` |
|
|
40
|
-
|
|
41
|
-
## Union Types (T.any)
|
|
42
|
-
|
|
43
|
-
| Sorbet Type | BAML Output | Example |
|
|
44
|
-
|-------------|-------------|---------|
|
|
45
|
-
| `T.any(String, Integer)` | `string \| int` | `value string \| int` |
|
|
46
|
-
| `T.any(String, Integer, Float)` | `string \| int \| float` | `mixed string \| int \| float` |
|
|
47
|
-
| `T.nilable(T.any(String, Integer))` | `(string \| int)?` | `optional (string \| int)?` |
|
|
48
|
-
|
|
49
|
-
## Complex Collection Types
|
|
50
|
-
|
|
51
|
-
| Sorbet Type | BAML Output | Example |
|
|
52
|
-
|-------------|-------------|---------|
|
|
53
|
-
| `T::Array[T.any(String, Integer)]` | `(string \| int)[]` | `mixed_array (string \| int)[]` |
|
|
54
|
-
| `T::Hash[String, T.any(String, Integer)]` | `map<string, string \| int>` | `settings map<string, string \| int>` |
|
|
55
|
-
| `T::Hash[String, T::Array[String]]` | `map<string, string[]>` | `labels map<string, string[]>` |
|
|
56
|
-
|
|
57
|
-
## Structured Types
|
|
58
|
-
|
|
59
|
-
### T::Struct to BAML Classes
|
|
60
|
-
|
|
61
|
-
```ruby
|
|
62
|
-
class Address < T::Struct
|
|
63
|
-
const :street, String
|
|
64
|
-
const :city, String
|
|
65
|
-
const :postal_code, T.nilable(String)
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
class User < T::Struct
|
|
69
|
-
const :name, String
|
|
70
|
-
const :age, Integer
|
|
71
|
-
const :address, Address
|
|
72
|
-
const :tags, T::Array[String]
|
|
73
|
-
end
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
```ruby
|
|
77
|
-
User.to_baml
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
**Generated BAML:**
|
|
81
|
-
```baml
|
|
82
|
-
class User {
|
|
83
|
-
name string
|
|
84
|
-
age int
|
|
85
|
-
address Address
|
|
86
|
-
tags string[]
|
|
87
|
-
}
|
|
88
|
-
```
|
|
89
|
-
|
|
90
|
-
### T::Enum to BAML Enums
|
|
91
|
-
|
|
92
|
-
```ruby
|
|
93
|
-
class Status < T::Enum
|
|
94
|
-
enums do
|
|
95
|
-
Active = new('active')
|
|
96
|
-
Inactive = new('inactive')
|
|
97
|
-
Pending = new('pending')
|
|
98
|
-
end
|
|
99
|
-
end
|
|
100
|
-
|
|
101
|
-
class User < T::Struct
|
|
102
|
-
const :name, String
|
|
103
|
-
const :status, Status
|
|
104
|
-
end
|
|
105
|
-
```
|
|
106
|
-
|
|
107
|
-
```ruby
|
|
108
|
-
[Status, User].map(&:to_baml).join("\n\n")
|
|
109
|
-
```
|
|
110
|
-
|
|
111
|
-
**Generated BAML:**
|
|
112
|
-
```baml
|
|
113
|
-
enum Status {
|
|
114
|
-
"active"
|
|
115
|
-
"inactive"
|
|
116
|
-
"pending"
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
class User {
|
|
120
|
-
name string
|
|
121
|
-
status Status
|
|
122
|
-
}
|
|
123
|
-
```
|
|
124
|
-
|
|
125
|
-
### Complex Real-World Example
|
|
126
|
-
|
|
127
|
-
```ruby
|
|
128
|
-
class Priority < T::Enum
|
|
129
|
-
enums do
|
|
130
|
-
Low = new('low')
|
|
131
|
-
Medium = new('medium')
|
|
132
|
-
High = new('high')
|
|
133
|
-
end
|
|
134
|
-
end
|
|
135
|
-
|
|
136
|
-
class Task < T::Struct
|
|
137
|
-
const :title, String
|
|
138
|
-
const :description, T.nilable(String)
|
|
139
|
-
const :priority, Priority
|
|
140
|
-
const :tags, T::Array[String]
|
|
141
|
-
const :metadata, T::Hash[String, T.any(String, Integer)]
|
|
142
|
-
const :subtasks, T::Array[Task]
|
|
143
|
-
end
|
|
144
|
-
```
|
|
145
|
-
|
|
146
|
-
```ruby
|
|
147
|
-
[Priority, Task].map(&:to_baml).join("\n\n")
|
|
148
|
-
```
|
|
149
|
-
|
|
150
|
-
**Generated BAML:**
|
|
151
|
-
```baml
|
|
152
|
-
enum Priority {
|
|
153
|
-
"low"
|
|
154
|
-
"medium"
|
|
155
|
-
"high"
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
class Task {
|
|
159
|
-
title string
|
|
160
|
-
description string?
|
|
161
|
-
priority Priority
|
|
162
|
-
tags string[]
|
|
163
|
-
metadata map<string, string | int>
|
|
164
|
-
subtasks Task[]
|
|
165
|
-
}
|
|
166
|
-
```
|
|
167
|
-
|
|
168
|
-
## Advanced Features
|
|
169
|
-
|
|
170
|
-
### Dependency Management
|
|
171
|
-
|
|
172
|
-
```ruby
|
|
173
|
-
# Dependencies automatically included with smart defaults
|
|
174
|
-
User.to_baml
|
|
175
|
-
# Outputs Address, then User in correct order
|
|
176
|
-
```
|
|
177
|
-
|
|
178
|
-
### Custom Formatting
|
|
179
|
-
|
|
180
|
-
```ruby
|
|
181
|
-
# Smart defaults include dependencies automatically
|
|
182
|
-
User.to_baml(indent_size: 4)
|
|
183
|
-
```
|
|
184
|
-
|
|
185
|
-
## Future Enhancements (Optional)
|
|
186
|
-
|
|
187
|
-
These are nice-to-have features for future versions:
|
|
188
|
-
|
|
189
|
-
- `T.type_alias` → `type Name = ...`
|
|
190
|
-
- Field descriptions from comments
|
|
191
|
-
- Custom naming strategies (snake_case ↔ camelCase)
|
|
192
|
-
- Self-referential type handling
|