tiktoken_ruby 0.0.16 → 0.0.17
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/CHANGELOG.md +10 -0
- data/Cargo.lock +8 -14
- data/Gemfile.lock +11 -11
- data/README.md +23 -4
- data/ext/tiktoken_ruby/Cargo.toml +1 -1
- data/ext/tiktoken_ruby/src/core_bpe_wrapper.rs +58 -6
- data/ext/tiktoken_ruby/src/lib.rs +6 -1
- data/lib/tiktoken_ruby/encoding.rb +34 -4
- data/lib/tiktoken_ruby/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b04168b5f23957815c4f9a7139d0629c29236befaaeab12deaa1e0fee2c3b814
|
|
4
|
+
data.tar.gz: aa8af07c52ba013e0e7d7ad0aa569db6419a3330eaace2d3401963c7f4f9d2cf
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0bf109e1ab9191f06bf7450cfa32589c5dc4fcff41084c3682694b9ddd03f5595151e3ba2e376916c85f5ea1ce8e0866743556ec2c0f778309ac3aad216caf8a
|
|
7
|
+
data.tar.gz: b105c5871dde75b05274e830f1b40c0a4a05364c2cb6947f1223c128af4c1564dfc573c8c6e3b521ccf11b4eb6eb0592882af734deeba39251f8a1eab619e4a5
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,13 @@
|
|
|
1
|
+
# [v0.0.17] - 18-07-2026
|
|
2
|
+
## What's Changed
|
|
3
|
+
* Bump the github-actions group with 2 updates by @dependabot[bot] in https://github.com/IAPark/tiktoken_ruby/pull/119
|
|
4
|
+
* Bump the bundler-dependencies group across 1 directory with 2 updates by @dependabot[bot] in https://github.com/IAPark/tiktoken_ruby/pull/121
|
|
5
|
+
* Bump the cargo group across 1 directory with 2 updates by @dependabot[bot] in https://github.com/IAPark/tiktoken_ruby/pull/120
|
|
6
|
+
* feat(decode): Add opt-in lossy mode and decode_bytes by @gjtorikian in https://github.com/IAPark/tiktoken_ruby/pull/123
|
|
7
|
+
* Bump version to 0.0.17 by @gjtorikian in https://github.com/IAPark/tiktoken_ruby/pull/124
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
**Full Changelog**: https://github.com/IAPark/tiktoken_ruby/compare/v0.0.16...v0.0.17
|
|
1
11
|
# [v0.0.16] - 02-05-2026
|
|
2
12
|
## What's Changed
|
|
3
13
|
* Bump rb-sys from 0.9.123 to 0.9.124 in the cargo group by @dependabot[bot] in https://github.com/IAPark/tiktoken_ruby/pull/107
|
data/Cargo.lock
CHANGED
|
@@ -36,7 +36,7 @@ dependencies = [
|
|
|
36
36
|
"proc-macro2",
|
|
37
37
|
"quote",
|
|
38
38
|
"regex",
|
|
39
|
-
"rustc-hash
|
|
39
|
+
"rustc-hash",
|
|
40
40
|
"shlex",
|
|
41
41
|
"syn",
|
|
42
42
|
]
|
|
@@ -218,18 +218,18 @@ dependencies = [
|
|
|
218
218
|
|
|
219
219
|
[[package]]
|
|
220
220
|
name = "rb-sys"
|
|
221
|
-
version = "0.9.
|
|
221
|
+
version = "0.9.128"
|
|
222
222
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
223
|
-
checksum = "
|
|
223
|
+
checksum = "45ca28513560e56cfb79a62b1fce363c73af170a182024ce880c77ee9429920a"
|
|
224
224
|
dependencies = [
|
|
225
225
|
"rb-sys-build",
|
|
226
226
|
]
|
|
227
227
|
|
|
228
228
|
[[package]]
|
|
229
229
|
name = "rb-sys-build"
|
|
230
|
-
version = "0.9.
|
|
230
|
+
version = "0.9.128"
|
|
231
231
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
232
|
-
checksum = "
|
|
232
|
+
checksum = "ce04b2c55eff3a21aaa623fcc655d94373238e72cac6b3e1a3641ff31649f99a"
|
|
233
233
|
dependencies = [
|
|
234
234
|
"bindgen",
|
|
235
235
|
"lazy_static",
|
|
@@ -275,12 +275,6 @@ version = "0.8.8"
|
|
|
275
275
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
276
276
|
checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58"
|
|
277
277
|
|
|
278
|
-
[[package]]
|
|
279
|
-
name = "rustc-hash"
|
|
280
|
-
version = "1.1.0"
|
|
281
|
-
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
282
|
-
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
|
|
283
|
-
|
|
284
278
|
[[package]]
|
|
285
279
|
name = "rustc-hash"
|
|
286
280
|
version = "2.1.2"
|
|
@@ -347,9 +341,9 @@ dependencies = [
|
|
|
347
341
|
|
|
348
342
|
[[package]]
|
|
349
343
|
name = "tiktoken-rs"
|
|
350
|
-
version = "0.
|
|
344
|
+
version = "0.12.0"
|
|
351
345
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
352
|
-
checksum = "
|
|
346
|
+
checksum = "027853bbf8c7763b77c5c595f1c271c7d536ced7d6f83452911b944621e57fc2"
|
|
353
347
|
dependencies = [
|
|
354
348
|
"anyhow",
|
|
355
349
|
"base64",
|
|
@@ -357,7 +351,7 @@ dependencies = [
|
|
|
357
351
|
"fancy-regex",
|
|
358
352
|
"lazy_static",
|
|
359
353
|
"regex",
|
|
360
|
-
"rustc-hash
|
|
354
|
+
"rustc-hash",
|
|
361
355
|
]
|
|
362
356
|
|
|
363
357
|
[[package]]
|
data/Gemfile.lock
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
tiktoken_ruby (0.0.
|
|
4
|
+
tiktoken_ruby (0.0.17)
|
|
5
5
|
rb_sys (~> 0.9)
|
|
6
6
|
|
|
7
7
|
GEM
|
|
@@ -9,13 +9,13 @@ GEM
|
|
|
9
9
|
specs:
|
|
10
10
|
ast (2.4.3)
|
|
11
11
|
diff-lcs (1.6.2)
|
|
12
|
-
json (2.
|
|
12
|
+
json (2.20.0)
|
|
13
13
|
language_server-protocol (3.17.0.5)
|
|
14
14
|
lint_roller (1.1.0)
|
|
15
15
|
minitest (6.0.1)
|
|
16
16
|
prism (~> 1.5)
|
|
17
|
-
parallel (1.
|
|
18
|
-
parser (3.3.
|
|
17
|
+
parallel (1.28.0)
|
|
18
|
+
parser (3.3.11.1)
|
|
19
19
|
ast (~> 2.4.1)
|
|
20
20
|
racc
|
|
21
21
|
prism (1.9.0)
|
|
@@ -25,9 +25,9 @@ GEM
|
|
|
25
25
|
rake-compiler (1.3.1)
|
|
26
26
|
rake
|
|
27
27
|
rake-compiler-dock (1.12.0)
|
|
28
|
-
rb_sys (0.9.
|
|
28
|
+
rb_sys (0.9.128)
|
|
29
29
|
rake-compiler-dock (= 1.12.0)
|
|
30
|
-
regexp_parser (2.
|
|
30
|
+
regexp_parser (2.12.0)
|
|
31
31
|
rspec (3.13.2)
|
|
32
32
|
rspec-core (~> 3.13.0)
|
|
33
33
|
rspec-expectations (~> 3.13.0)
|
|
@@ -41,18 +41,18 @@ GEM
|
|
|
41
41
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
42
42
|
rspec-support (~> 3.13.0)
|
|
43
43
|
rspec-support (3.13.6)
|
|
44
|
-
rubocop (1.
|
|
44
|
+
rubocop (1.87.0)
|
|
45
45
|
json (~> 2.3)
|
|
46
46
|
language_server-protocol (~> 3.17.0.2)
|
|
47
47
|
lint_roller (~> 1.1.0)
|
|
48
|
-
parallel (
|
|
48
|
+
parallel (>= 1.10)
|
|
49
49
|
parser (>= 3.3.0.2)
|
|
50
50
|
rainbow (>= 2.2.2, < 4.0)
|
|
51
51
|
regexp_parser (>= 2.9.3, < 3.0)
|
|
52
52
|
rubocop-ast (>= 1.49.0, < 2.0)
|
|
53
53
|
ruby-progressbar (~> 1.7)
|
|
54
54
|
unicode-display_width (>= 2.4.0, < 4.0)
|
|
55
|
-
rubocop-ast (1.49.
|
|
55
|
+
rubocop-ast (1.49.1)
|
|
56
56
|
parser (>= 3.3.7.2)
|
|
57
57
|
prism (~> 1.7)
|
|
58
58
|
rubocop-performance (1.26.1)
|
|
@@ -60,10 +60,10 @@ GEM
|
|
|
60
60
|
rubocop (>= 1.75.0, < 2.0)
|
|
61
61
|
rubocop-ast (>= 1.47.1, < 2.0)
|
|
62
62
|
ruby-progressbar (1.13.0)
|
|
63
|
-
standard (1.
|
|
63
|
+
standard (1.55.0)
|
|
64
64
|
language_server-protocol (~> 3.17.0.2)
|
|
65
65
|
lint_roller (~> 1.0)
|
|
66
|
-
rubocop (~> 1.
|
|
66
|
+
rubocop (~> 1.87.0)
|
|
67
67
|
standard-custom (~> 1.0.0)
|
|
68
68
|
standard-performance (~> 1.8)
|
|
69
69
|
standard-custom (1.0.2)
|
data/README.md
CHANGED
|
@@ -17,9 +17,7 @@ If bundler is not being used to manage dependencies, install the gem by executin
|
|
|
17
17
|
|
|
18
18
|
## Usage
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
Encode and decode text
|
|
20
|
+
Encode and decode text:
|
|
23
21
|
|
|
24
22
|
```ruby
|
|
25
23
|
require 'tiktoken_ruby'
|
|
@@ -27,7 +25,7 @@ enc = Tiktoken.get_encoding("cl100k_base")
|
|
|
27
25
|
enc.decode(enc.encode("hello world")) #=> "hello world"
|
|
28
26
|
```
|
|
29
27
|
|
|
30
|
-
Encoders can also be retrieved by model name
|
|
28
|
+
Encoders can also be retrieved by model name:
|
|
31
29
|
|
|
32
30
|
```ruby
|
|
33
31
|
require 'tiktoken_ruby'
|
|
@@ -69,6 +67,27 @@ enc.encode_with_special_tokens(text)
|
|
|
69
67
|
|
|
70
68
|
All methods round-trip correctly through `decode`.
|
|
71
69
|
|
|
70
|
+
### Decoding methods
|
|
71
|
+
|
|
72
|
+
- `decode(tokens, errors: :strict)` - Decodes tokens back into a UTF-8 string
|
|
73
|
+
- `decode_bytes(tokens)` - Decodes tokens into their raw bytes (an `ASCII-8BIT` string), without UTF-8 validation
|
|
74
|
+
|
|
75
|
+
Because BPE tokens are byte-level, a single character (an emoji, or non-Latin scripts) can span multiple tokens. Truncating a token array (like, "trim text to N tokens") can leave a prefix that is not valid UTF-8. The `errors:` option controls how those invalid sequences are handled.
|
|
76
|
+
|
|
77
|
+
```ruby
|
|
78
|
+
enc = Tiktoken.encoding_for_model("gpt-4o")
|
|
79
|
+
tokens = enc.encode("🦄") # the emoji spans multiple tokens
|
|
80
|
+
|
|
81
|
+
# :strict (default) - raise Tiktoken::UnicodeError on invalid UTF-8
|
|
82
|
+
enc.decode(tokens.first(2)) #=> raises Tiktoken::UnicodeError
|
|
83
|
+
|
|
84
|
+
# :replace - substitute invalid sequences with "�" (matches Python tiktoken's default)
|
|
85
|
+
enc.decode(tokens.first(2), errors: :replace) #=> "�"
|
|
86
|
+
|
|
87
|
+
# decode_bytes - get the raw bytes and handle them yourself
|
|
88
|
+
enc.decode_bytes(tokens.first(2)) #=> "\xF0\x9F\xA6" (ASCII-8BIT)
|
|
89
|
+
```
|
|
90
|
+
|
|
72
91
|
## Development
|
|
73
92
|
|
|
74
93
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
|
@@ -3,7 +3,7 @@ use std::ffi::c_void;
|
|
|
3
3
|
|
|
4
4
|
use tiktoken_rs::Rank;
|
|
5
5
|
|
|
6
|
-
use crate::
|
|
6
|
+
use crate::unicode_error;
|
|
7
7
|
|
|
8
8
|
#[magnus::wrap(class = "Tiktoken::Ext::CoreBPE")]
|
|
9
9
|
pub struct CoreBPEWrapper {
|
|
@@ -20,7 +20,7 @@ struct EncodeData {
|
|
|
20
20
|
core_bpe: *const tiktoken_rs::CoreBPE,
|
|
21
21
|
text: String,
|
|
22
22
|
allowed_special: HashSet<String>,
|
|
23
|
-
result: Vec<Rank>,
|
|
23
|
+
result: Result<Vec<Rank>, String>,
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
struct EncodeSpecialData {
|
|
@@ -35,6 +35,12 @@ struct DecodeData {
|
|
|
35
35
|
result: Result<String, String>,
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
+
struct DecodeBytesData {
|
|
39
|
+
core_bpe: *const tiktoken_rs::CoreBPE,
|
|
40
|
+
ids: Vec<Rank>,
|
|
41
|
+
result: Result<Vec<u8>, String>,
|
|
42
|
+
}
|
|
43
|
+
|
|
38
44
|
unsafe extern "C" fn encode_ordinary_without_gvl(data: *mut c_void) -> *mut c_void {
|
|
39
45
|
let data = &mut *(data as *mut EncodeOrdinaryData);
|
|
40
46
|
let core_bpe = &*data.core_bpe;
|
|
@@ -46,7 +52,11 @@ unsafe extern "C" fn encode_without_gvl(data: *mut c_void) -> *mut c_void {
|
|
|
46
52
|
let data = &mut *(data as *mut EncodeData);
|
|
47
53
|
let core_bpe = &*data.core_bpe;
|
|
48
54
|
let allowed_special: HashSet<&str> = data.allowed_special.iter().map(|s| s.as_str()).collect();
|
|
49
|
-
|
|
55
|
+
// Keep only the token vector and surface any tokenization failure to Ruby.
|
|
56
|
+
data.result = core_bpe
|
|
57
|
+
.encode(&data.text, &allowed_special)
|
|
58
|
+
.map(|(tokens, _last_piece_token_len)| tokens)
|
|
59
|
+
.map_err(|e| e.to_string());
|
|
50
60
|
std::ptr::null_mut()
|
|
51
61
|
}
|
|
52
62
|
|
|
@@ -64,6 +74,13 @@ unsafe extern "C" fn decode_without_gvl(data: *mut c_void) -> *mut c_void {
|
|
|
64
74
|
std::ptr::null_mut()
|
|
65
75
|
}
|
|
66
76
|
|
|
77
|
+
unsafe extern "C" fn decode_bytes_without_gvl(data: *mut c_void) -> *mut c_void {
|
|
78
|
+
let data = &mut *(data as *mut DecodeBytesData);
|
|
79
|
+
let core_bpe = &*data.core_bpe;
|
|
80
|
+
data.result = core_bpe.decode_bytes(&data.ids).map_err(|e| e.to_string());
|
|
81
|
+
std::ptr::null_mut()
|
|
82
|
+
}
|
|
83
|
+
|
|
67
84
|
impl CoreBPEWrapper {
|
|
68
85
|
pub fn new(core_bpe: tiktoken_rs::CoreBPE) -> Self {
|
|
69
86
|
Self { core_bpe }
|
|
@@ -99,7 +116,7 @@ impl CoreBPEWrapper {
|
|
|
99
116
|
core_bpe: &self.core_bpe as *const _,
|
|
100
117
|
text,
|
|
101
118
|
allowed_special: HashSet::from_iter(allowed_special),
|
|
102
|
-
result: Vec::new(),
|
|
119
|
+
result: Ok(Vec::new()),
|
|
103
120
|
};
|
|
104
121
|
|
|
105
122
|
unsafe {
|
|
@@ -111,7 +128,9 @@ impl CoreBPEWrapper {
|
|
|
111
128
|
);
|
|
112
129
|
}
|
|
113
130
|
|
|
114
|
-
|
|
131
|
+
data.result.map_err(|e| {
|
|
132
|
+
magnus::Error::new(magnus::Ruby::get().unwrap().exception_runtime_error(), e)
|
|
133
|
+
})
|
|
115
134
|
}
|
|
116
135
|
|
|
117
136
|
pub fn encode_with_special_tokens(&self, text: String) -> Vec<Rank> {
|
|
@@ -150,7 +169,7 @@ impl CoreBPEWrapper {
|
|
|
150
169
|
}
|
|
151
170
|
|
|
152
171
|
data.result.map_err(|e| {
|
|
153
|
-
let error = match
|
|
172
|
+
let error = match unicode_error() {
|
|
154
173
|
Ok(error) => error,
|
|
155
174
|
Err(e) => return e,
|
|
156
175
|
};
|
|
@@ -158,4 +177,37 @@ impl CoreBPEWrapper {
|
|
|
158
177
|
magnus::Error::new(error, e)
|
|
159
178
|
})
|
|
160
179
|
}
|
|
180
|
+
|
|
181
|
+
pub fn decode_bytes(&self, ids: Vec<Rank>) -> Result<magnus::RString, magnus::Error> {
|
|
182
|
+
let mut data = DecodeBytesData {
|
|
183
|
+
core_bpe: &self.core_bpe as *const _,
|
|
184
|
+
ids,
|
|
185
|
+
result: Err(String::new()),
|
|
186
|
+
};
|
|
187
|
+
|
|
188
|
+
unsafe {
|
|
189
|
+
rb_sys::rb_thread_call_without_gvl(
|
|
190
|
+
Some(decode_bytes_without_gvl),
|
|
191
|
+
&mut data as *mut _ as *mut c_void,
|
|
192
|
+
None,
|
|
193
|
+
std::ptr::null_mut(),
|
|
194
|
+
);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// Build the Ruby string only after the GVL has been re-acquired.
|
|
198
|
+
// `str_from_slice` yields an ASCII-8BIT (binary) string, so the bytes
|
|
199
|
+
// are handed back verbatim without any UTF-8 validation. We hold the
|
|
200
|
+
// GVL here (this is called from Ruby), so `Ruby::get` cannot fail.
|
|
201
|
+
let ruby = magnus::Ruby::get().unwrap();
|
|
202
|
+
data.result
|
|
203
|
+
.map(|bytes| ruby.str_from_slice(&bytes))
|
|
204
|
+
.map_err(|e| {
|
|
205
|
+
let error = match unicode_error() {
|
|
206
|
+
Ok(error) => error,
|
|
207
|
+
Err(e) => return e,
|
|
208
|
+
};
|
|
209
|
+
|
|
210
|
+
magnus::Error::new(error, e)
|
|
211
|
+
})
|
|
212
|
+
}
|
|
161
213
|
}
|
|
@@ -34,7 +34,7 @@ fn module() -> Result<RModule, magnus::Error> {
|
|
|
34
34
|
Ruby::get().unwrap().define_module("Tiktoken")
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
fn
|
|
37
|
+
fn unicode_error() -> Result<ExceptionClass, magnus::Error> {
|
|
38
38
|
module()?.define_error(
|
|
39
39
|
"UnicodeError",
|
|
40
40
|
Ruby::get().unwrap().exception_standard_error(),
|
|
@@ -45,6 +45,10 @@ fn uncicode_error() -> Result<ExceptionClass, magnus::Error> {
|
|
|
45
45
|
fn init() -> Result<(), Error> {
|
|
46
46
|
let module = module()?;
|
|
47
47
|
|
|
48
|
+
// Define Tiktoken::UnicodeError eagerly so the constant exists as soon as
|
|
49
|
+
// the extension is loaded, rather than only after the first decode error.
|
|
50
|
+
unicode_error()?;
|
|
51
|
+
|
|
48
52
|
let factory_module = module.define_module("BpeFactory")?;
|
|
49
53
|
factory_module.define_singleton_method("r50k_base", function!(r50k_base, 0))?;
|
|
50
54
|
factory_module.define_singleton_method("p50k_base", function!(p50k_base, 0))?;
|
|
@@ -67,5 +71,6 @@ fn init() -> Result<(), Error> {
|
|
|
67
71
|
)?;
|
|
68
72
|
|
|
69
73
|
bpe_class.define_method("decode", method!(CoreBPEWrapper::decode, 1))?;
|
|
74
|
+
bpe_class.define_method("decode_bytes", method!(CoreBPEWrapper::decode_bytes, 1))?;
|
|
70
75
|
Ok(())
|
|
71
76
|
}
|
|
@@ -47,11 +47,41 @@ class Tiktoken::Encoding
|
|
|
47
47
|
@ext_base_bpe.encode_with_special_tokens(text)
|
|
48
48
|
end
|
|
49
49
|
|
|
50
|
-
# Decodes the tokens back into text
|
|
50
|
+
# Decodes the tokens back into text.
|
|
51
|
+
#
|
|
52
|
+
# BPE tokens are byte-level, so a single character (an emoji, non-Latin
|
|
53
|
+
# scripts) can span multiple tokens. Truncating a token array to a limit can
|
|
54
|
+
# therefore leave a prefix that is not valid UTF-8. The +errors+ option
|
|
55
|
+
# controls how those invalid byte sequences are handled:
|
|
56
|
+
#
|
|
57
|
+
# * +:strict+ (default) - raise Tiktoken::UnicodeError on invalid UTF-8.
|
|
58
|
+
# * +:replace+ - substitute each invalid sequence with the Unicode replacement
|
|
59
|
+
# character (U+FFFD, +�+), matching Python tiktoken's default behavior.
|
|
60
|
+
#
|
|
51
61
|
# @param tokens [Array<Integer>] The tokens to decode
|
|
52
|
-
# @
|
|
53
|
-
|
|
54
|
-
|
|
62
|
+
# @param errors [Symbol] How to handle invalid UTF-8 (:strict or :replace)
|
|
63
|
+
# @return [String] The decoded text (UTF-8)
|
|
64
|
+
def decode(tokens, errors: :strict)
|
|
65
|
+
case errors
|
|
66
|
+
when :strict
|
|
67
|
+
@ext_base_bpe.decode(tokens)
|
|
68
|
+
when :replace
|
|
69
|
+
decode_bytes(tokens).force_encoding(Encoding::UTF_8).scrub("\u{FFFD}")
|
|
70
|
+
else
|
|
71
|
+
raise ArgumentError, "errors must be :strict or :replace, got #{errors.inspect}"
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# Decodes the tokens back into their raw bytes, without any UTF-8 validation.
|
|
76
|
+
#
|
|
77
|
+
# The returned string has ASCII-8BIT (binary) encoding and is not guaranteed
|
|
78
|
+
# to be valid UTF-8 — useful when you want to handle invalid sequences
|
|
79
|
+
# yourself. Matches Python tiktoken's +decode_bytes+.
|
|
80
|
+
#
|
|
81
|
+
# @param tokens [Array<Integer>] The tokens to decode
|
|
82
|
+
# @return [String] The decoded bytes (ASCII-8BIT)
|
|
83
|
+
def decode_bytes(tokens)
|
|
84
|
+
@ext_base_bpe.decode_bytes(tokens)
|
|
55
85
|
end
|
|
56
86
|
|
|
57
87
|
private
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: tiktoken_ruby
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.0.
|
|
4
|
+
version: 0.0.17
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- IAPark
|
|
@@ -74,7 +74,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
74
74
|
- !ruby/object:Gem::Version
|
|
75
75
|
version: 3.4.0
|
|
76
76
|
requirements: []
|
|
77
|
-
rubygems_version: 4.0.
|
|
77
|
+
rubygems_version: 4.0.10
|
|
78
78
|
specification_version: 4
|
|
79
79
|
summary: Ruby wrapper for Tiktoken
|
|
80
80
|
test_files: []
|