llm.rb 16.0.0.pre.5 → 16.0.0.pre.6
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 +45 -6
- data/data/bedrock.json +140 -0
- data/data/deepinfra.json +4 -0
- data/data/openai.json +106 -0
- data/data/openrouter.json +206 -77
- data/docs/deepdive/reference/tracer.md +18 -5
- data/lib/llm/context.rb +8 -0
- data/lib/llm/tracer.rb +31 -0
- data/lib/llm/transport/execution.rb +31 -2
- data/lib/llm/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 0f5c0f9cb6f92099cec46e8c7a83e02498d375458a50b8b3f19a94ac2385dc8f
|
|
4
|
+
data.tar.gz: 11929258bad683f946ded02b7b2621fcfae30cf1ed11c57007e4b4cfbac05b5d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 5b32ee2a9301958487a808705f63895b1cd89898730e8b0bdcabcee06be62eef6a724795ccd0f6053227f0577380019436eab3b19ba3a15459560bcc78a505af
|
|
7
|
+
data.tar.gz: 7839665a301ee3ab68716737daaddc7f384308b6b24548efcb33699a3463de83efa638aa060293a27ced6145907dee6ddabb7b63d11d5cb5f1e1a0239b2e209f
|
data/CHANGELOG.md
CHANGED
|
@@ -196,14 +196,17 @@
|
|
|
196
196
|
Update `data/` with current model listings, limits, and pricing. Alibaba adds
|
|
197
197
|
`qwen3.5-flash`, `qwen3.7-flash`, and `qwen3.8-omni-flash`, and gives
|
|
198
198
|
`qwen3.7-plus` attachments, structured output, and a lower price; OpenAI adds
|
|
199
|
-
`gpt-daybreak-blue-latest
|
|
200
|
-
`
|
|
201
|
-
`global.anthropic.claude-sonnet-5-5
|
|
202
|
-
and the
|
|
199
|
+
`gpt-daybreak-blue-latest`, `gpt-daybreak-red-latest`, and `gpt-6.1-sol`, and
|
|
200
|
+
gives `gpt-6-astra` an `ultrafast` mode; Bedrock adds `openai.gpt-6-sol`,
|
|
201
|
+
`openai.gpt-6-luna`, `global.anthropic.claude-sonnet-5-5`,
|
|
202
|
+
`anthropic.claude-sonnet-5-5`, and the Grok 4.7 entries in both the global
|
|
203
|
+
and US regions; DeepInfra adds `tencent/Hy4-preview` and the Xiaomi MiMo
|
|
204
|
+
V2.6 Pro and V2.6 Flash models, and marks four older entries deprecated.
|
|
203
205
|
Bedrock also corrects the context and output limits of fifteen models, Google
|
|
204
206
|
lowers the limits of `gemini-2.5-computer-use-preview-10-2025` and
|
|
205
|
-
`gemini-3-pro-image`, and OpenRouter adds
|
|
206
|
-
|
|
207
|
+
`gemini-3-pro-image`, and OpenRouter adds seven models, `openai/gpt-6.1-sol`
|
|
208
|
+
and `openai/gpt-6.1-sol-pro` among them, drops six, and reprices or corrects
|
|
209
|
+
the limits of many of the DeepSeek, Z.ai, Qwen, and Tencent entries.
|
|
207
210
|
|
|
208
211
|
### Schema
|
|
209
212
|
|
|
@@ -230,6 +233,42 @@
|
|
|
230
233
|
rate limit or a timeout calls it when it lands and not once per attempt, and
|
|
231
234
|
it fires even when the stream is disabled.
|
|
232
235
|
|
|
236
|
+
### Tracers
|
|
237
|
+
|
|
238
|
+
* **tracer: report a request that failed** <br>
|
|
239
|
+
[`LLM::Tracer#on_request_error`](https://r.uby.dev/api-docs/llm.rb/LLM/Tracer.html#on_request_error-instance_method)
|
|
240
|
+
is now called wherever a request ends without a response, so a span that
|
|
241
|
+
[`LLM::Tracer#on_request_start`](https://r.uby.dev/api-docs/llm.rb/LLM/Tracer.html#on_request_start-instance_method)
|
|
242
|
+
returned is closed. Before this, a request was reported only when a provider
|
|
243
|
+
turned an error response into an exception, so a dropped connection or a
|
|
244
|
+
socket read that failed left the tracer holding a span it had opened and never
|
|
245
|
+
closed, which in a trace reads the same as a process that died. A failure that
|
|
246
|
+
surfaces as one of the transport's own error classes is reported the same way
|
|
247
|
+
unless the request was interrupted, and the exception the caller receives is
|
|
248
|
+
unchanged.
|
|
249
|
+
|
|
250
|
+
* **tracer: add `on_interrupt`, called when a request is interrupted** <br>
|
|
251
|
+
[`LLM::Tracer#on_interrupt`](https://r.uby.dev/api-docs/llm.rb/LLM/Tracer.html#on_interrupt-instance_method)
|
|
252
|
+
is a new hook, called with a `scope:` of `:request` or `:tool` before
|
|
253
|
+
`LLM::Interrupt` reaches the caller, so a tracer that has to record what
|
|
254
|
+
happened to a turn does it while the work is still in flight. An interrupt is
|
|
255
|
+
the third ending a scope can have, beside `on_request_finish` and
|
|
256
|
+
`on_request_error`, and it is not reported as a failure. Unlike the other
|
|
257
|
+
request and tool hooks it does nothing by default, because an interrupt is
|
|
258
|
+
delivered to whatever tracer happens to be bound, and a hook that raised would
|
|
259
|
+
replace the interrupt every caller is written against. A request is announced
|
|
260
|
+
with the span that `on_request_start` returned and its `request_id`; a tool
|
|
261
|
+
pass has neither, so both arrive as `nil`.
|
|
262
|
+
|
|
263
|
+
* **tracer: announce an interrupted tool phase once** <br>
|
|
264
|
+
[`LLM::Context#wait`](https://r.uby.dev/api-docs/llm.rb/LLM/Context.html#wait-instance_method)
|
|
265
|
+
now calls the hook once when an interrupt unwinds through it, rather than once
|
|
266
|
+
per tool, because a cancel reaches every tool that is running and the caller
|
|
267
|
+
hears a single exception, so the announcement belongs to the phase rather than
|
|
268
|
+
to a tool. The hook runs before the caller is given the interrupt. A `:ractor`
|
|
269
|
+
call that answers `cancelled: true` instead of raising is not announced,
|
|
270
|
+
because the phase was not interrupted; one call was retired.
|
|
271
|
+
|
|
233
272
|
## v15.5.0
|
|
234
273
|
|
|
235
274
|
Changes since `v15.4.1`.
|
data/data/bedrock.json
CHANGED
|
@@ -777,6 +777,54 @@
|
|
|
777
777
|
},
|
|
778
778
|
"canonical_model_id": "anthropic/claude-opus-5-5"
|
|
779
779
|
},
|
|
780
|
+
"anthropic.claude-sonnet-5-5": {
|
|
781
|
+
"id": "anthropic.claude-sonnet-5-5",
|
|
782
|
+
"name": "Claude Sonnet 5.5",
|
|
783
|
+
"description": "Fast Claude model for everyday coding, agents, and knowledge work",
|
|
784
|
+
"family": "claude-sonnet",
|
|
785
|
+
"attachment": true,
|
|
786
|
+
"reasoning": true,
|
|
787
|
+
"reasoning_options": [
|
|
788
|
+
{
|
|
789
|
+
"type": "effort",
|
|
790
|
+
"values": [
|
|
791
|
+
"low",
|
|
792
|
+
"medium",
|
|
793
|
+
"high",
|
|
794
|
+
"xhigh",
|
|
795
|
+
"max"
|
|
796
|
+
]
|
|
797
|
+
}
|
|
798
|
+
],
|
|
799
|
+
"tool_call": true,
|
|
800
|
+
"structured_output": false,
|
|
801
|
+
"temperature": false,
|
|
802
|
+
"knowledge": "2026-06",
|
|
803
|
+
"release_date": "2026-09-28",
|
|
804
|
+
"last_updated": "2026-09-28",
|
|
805
|
+
"modalities": {
|
|
806
|
+
"input": [
|
|
807
|
+
"text",
|
|
808
|
+
"image",
|
|
809
|
+
"pdf"
|
|
810
|
+
],
|
|
811
|
+
"output": [
|
|
812
|
+
"text"
|
|
813
|
+
]
|
|
814
|
+
},
|
|
815
|
+
"open_weights": false,
|
|
816
|
+
"limit": {
|
|
817
|
+
"context": 1000000,
|
|
818
|
+
"output": 128000
|
|
819
|
+
},
|
|
820
|
+
"cost": {
|
|
821
|
+
"input": 2,
|
|
822
|
+
"output": 10,
|
|
823
|
+
"cache_read": 0.2,
|
|
824
|
+
"cache_write": 2.5
|
|
825
|
+
},
|
|
826
|
+
"canonical_model_id": "anthropic/claude-sonnet-5-5"
|
|
827
|
+
},
|
|
780
828
|
"global.anthropic.claude-sonnet-5-5": {
|
|
781
829
|
"id": "global.anthropic.claude-sonnet-5-5",
|
|
782
830
|
"name": "Claude Sonnet 5.5 (Global)",
|
|
@@ -3717,6 +3765,52 @@
|
|
|
3717
3765
|
},
|
|
3718
3766
|
"canonical_model_id": "anthropic/claude-opus-5"
|
|
3719
3767
|
},
|
|
3768
|
+
"global.xai.grok-4.7": {
|
|
3769
|
+
"id": "global.xai.grok-4.7",
|
|
3770
|
+
"name": "Grok 4.7 (Global)",
|
|
3771
|
+
"description": "xAI's frontier model for long-running agents, coding, knowledge work, and visual projects",
|
|
3772
|
+
"family": "grok",
|
|
3773
|
+
"attachment": true,
|
|
3774
|
+
"reasoning": true,
|
|
3775
|
+
"reasoning_options": [
|
|
3776
|
+
{
|
|
3777
|
+
"type": "effort",
|
|
3778
|
+
"values": [
|
|
3779
|
+
"low",
|
|
3780
|
+
"medium",
|
|
3781
|
+
"high",
|
|
3782
|
+
"xhigh"
|
|
3783
|
+
]
|
|
3784
|
+
}
|
|
3785
|
+
],
|
|
3786
|
+
"tool_call": true,
|
|
3787
|
+
"structured_output": true,
|
|
3788
|
+
"temperature": true,
|
|
3789
|
+
"knowledge": "2026-05",
|
|
3790
|
+
"release_date": "2026-09-21",
|
|
3791
|
+
"last_updated": "2026-09-28",
|
|
3792
|
+
"modalities": {
|
|
3793
|
+
"input": [
|
|
3794
|
+
"text",
|
|
3795
|
+
"image",
|
|
3796
|
+
"pdf"
|
|
3797
|
+
],
|
|
3798
|
+
"output": [
|
|
3799
|
+
"text"
|
|
3800
|
+
]
|
|
3801
|
+
},
|
|
3802
|
+
"open_weights": false,
|
|
3803
|
+
"limit": {
|
|
3804
|
+
"context": 500000,
|
|
3805
|
+
"output": 500000
|
|
3806
|
+
},
|
|
3807
|
+
"cost": {
|
|
3808
|
+
"input": 2,
|
|
3809
|
+
"output": 6,
|
|
3810
|
+
"cache_read": 0.5
|
|
3811
|
+
},
|
|
3812
|
+
"canonical_model_id": "xai/grok-4.7"
|
|
3813
|
+
},
|
|
3720
3814
|
"us.openai.gpt-5.6-sol": {
|
|
3721
3815
|
"id": "us.openai.gpt-5.6-sol",
|
|
3722
3816
|
"name": "GPT-5.6 Sol (US)",
|
|
@@ -4229,6 +4323,52 @@
|
|
|
4229
4323
|
},
|
|
4230
4324
|
"canonical_model_id": "mistral/ministral-3-3b-instruct-2512"
|
|
4231
4325
|
},
|
|
4326
|
+
"us.xai.grok-4.7": {
|
|
4327
|
+
"id": "us.xai.grok-4.7",
|
|
4328
|
+
"name": "Grok 4.7 (US)",
|
|
4329
|
+
"description": "xAI's frontier model for long-running agents, coding, knowledge work, and visual projects",
|
|
4330
|
+
"family": "grok",
|
|
4331
|
+
"attachment": true,
|
|
4332
|
+
"reasoning": true,
|
|
4333
|
+
"reasoning_options": [
|
|
4334
|
+
{
|
|
4335
|
+
"type": "effort",
|
|
4336
|
+
"values": [
|
|
4337
|
+
"low",
|
|
4338
|
+
"medium",
|
|
4339
|
+
"high",
|
|
4340
|
+
"xhigh"
|
|
4341
|
+
]
|
|
4342
|
+
}
|
|
4343
|
+
],
|
|
4344
|
+
"tool_call": true,
|
|
4345
|
+
"structured_output": true,
|
|
4346
|
+
"temperature": true,
|
|
4347
|
+
"knowledge": "2026-05",
|
|
4348
|
+
"release_date": "2026-09-21",
|
|
4349
|
+
"last_updated": "2026-09-28",
|
|
4350
|
+
"modalities": {
|
|
4351
|
+
"input": [
|
|
4352
|
+
"text",
|
|
4353
|
+
"image",
|
|
4354
|
+
"pdf"
|
|
4355
|
+
],
|
|
4356
|
+
"output": [
|
|
4357
|
+
"text"
|
|
4358
|
+
]
|
|
4359
|
+
},
|
|
4360
|
+
"open_weights": false,
|
|
4361
|
+
"limit": {
|
|
4362
|
+
"context": 500000,
|
|
4363
|
+
"output": 500000
|
|
4364
|
+
},
|
|
4365
|
+
"cost": {
|
|
4366
|
+
"input": 2.2,
|
|
4367
|
+
"output": 6.6,
|
|
4368
|
+
"cache_read": 0.55
|
|
4369
|
+
},
|
|
4370
|
+
"canonical_model_id": "xai/grok-4.7"
|
|
4371
|
+
},
|
|
4232
4372
|
"us.openai.gpt-6-luna": {
|
|
4233
4373
|
"id": "us.openai.gpt-6-luna",
|
|
4234
4374
|
"name": "GPT-6 Luna (US)",
|
data/data/deepinfra.json
CHANGED
|
@@ -246,6 +246,7 @@
|
|
|
246
246
|
"context": 1048576,
|
|
247
247
|
"output": 16384
|
|
248
248
|
},
|
|
249
|
+
"status": "deprecated",
|
|
249
250
|
"cost": {
|
|
250
251
|
"input": 1,
|
|
251
252
|
"output": 3,
|
|
@@ -330,6 +331,7 @@
|
|
|
330
331
|
"context": 262144,
|
|
331
332
|
"output": 16384
|
|
332
333
|
},
|
|
334
|
+
"status": "deprecated",
|
|
333
335
|
"cost": {
|
|
334
336
|
"input": 0.14,
|
|
335
337
|
"output": 0.28,
|
|
@@ -1712,6 +1714,7 @@
|
|
|
1712
1714
|
"context": 163840,
|
|
1713
1715
|
"output": 163840
|
|
1714
1716
|
},
|
|
1717
|
+
"status": "deprecated",
|
|
1715
1718
|
"cost": {
|
|
1716
1719
|
"input": 0.24,
|
|
1717
1720
|
"output": 0.9,
|
|
@@ -2022,6 +2025,7 @@
|
|
|
2022
2025
|
"context": 262144,
|
|
2023
2026
|
"output": 262144
|
|
2024
2027
|
},
|
|
2028
|
+
"status": "deprecated",
|
|
2025
2029
|
"cost": {
|
|
2026
2030
|
"input": 0.68,
|
|
2027
2031
|
"output": 3.4,
|
data/data/openai.json
CHANGED
|
@@ -1121,6 +1121,99 @@
|
|
|
1121
1121
|
"cache_read": 0.175
|
|
1122
1122
|
}
|
|
1123
1123
|
},
|
|
1124
|
+
"gpt-6.1-sol": {
|
|
1125
|
+
"id": "gpt-6.1-sol",
|
|
1126
|
+
"name": "GPT-6.1 Sol",
|
|
1127
|
+
"description": "Near-Astra performance for complex coding, computer use, and professional work at a lower cost.",
|
|
1128
|
+
"family": "gpt-sol",
|
|
1129
|
+
"attachment": true,
|
|
1130
|
+
"reasoning": true,
|
|
1131
|
+
"reasoning_options": [
|
|
1132
|
+
{
|
|
1133
|
+
"type": "effort",
|
|
1134
|
+
"values": [
|
|
1135
|
+
"low",
|
|
1136
|
+
"medium",
|
|
1137
|
+
"high",
|
|
1138
|
+
"xhigh",
|
|
1139
|
+
"max"
|
|
1140
|
+
]
|
|
1141
|
+
}
|
|
1142
|
+
],
|
|
1143
|
+
"tool_call": true,
|
|
1144
|
+
"structured_output": true,
|
|
1145
|
+
"temperature": false,
|
|
1146
|
+
"knowledge": "2026-04-30",
|
|
1147
|
+
"release_date": "2026-09-29",
|
|
1148
|
+
"last_updated": "2026-09-29",
|
|
1149
|
+
"modalities": {
|
|
1150
|
+
"input": [
|
|
1151
|
+
"text",
|
|
1152
|
+
"image",
|
|
1153
|
+
"pdf"
|
|
1154
|
+
],
|
|
1155
|
+
"output": [
|
|
1156
|
+
"text"
|
|
1157
|
+
]
|
|
1158
|
+
},
|
|
1159
|
+
"open_weights": false,
|
|
1160
|
+
"limit": {
|
|
1161
|
+
"context": 1050000,
|
|
1162
|
+
"input": 922000,
|
|
1163
|
+
"output": 128000
|
|
1164
|
+
},
|
|
1165
|
+
"experimental": {
|
|
1166
|
+
"modes": {
|
|
1167
|
+
"fast": {
|
|
1168
|
+
"cost": {
|
|
1169
|
+
"input": 4,
|
|
1170
|
+
"output": 20,
|
|
1171
|
+
"cache_read": 0.2,
|
|
1172
|
+
"cache_write": 5
|
|
1173
|
+
},
|
|
1174
|
+
"provider": {
|
|
1175
|
+
"body": {
|
|
1176
|
+
"service_tier": "priority"
|
|
1177
|
+
}
|
|
1178
|
+
}
|
|
1179
|
+
},
|
|
1180
|
+
"pro": {
|
|
1181
|
+
"provider": {
|
|
1182
|
+
"body": {
|
|
1183
|
+
"reasoning": {
|
|
1184
|
+
"mode": "pro"
|
|
1185
|
+
}
|
|
1186
|
+
}
|
|
1187
|
+
}
|
|
1188
|
+
}
|
|
1189
|
+
}
|
|
1190
|
+
},
|
|
1191
|
+
"cost": {
|
|
1192
|
+
"input": 2,
|
|
1193
|
+
"output": 10,
|
|
1194
|
+
"cache_read": 0.1,
|
|
1195
|
+
"cache_write": 2.5,
|
|
1196
|
+
"tiers": [
|
|
1197
|
+
{
|
|
1198
|
+
"input": 4,
|
|
1199
|
+
"output": 15,
|
|
1200
|
+
"cache_read": 0.2,
|
|
1201
|
+
"cache_write": 5,
|
|
1202
|
+
"tier": {
|
|
1203
|
+
"type": "context",
|
|
1204
|
+
"size": 272000
|
|
1205
|
+
}
|
|
1206
|
+
}
|
|
1207
|
+
],
|
|
1208
|
+
"context_over_200k": {
|
|
1209
|
+
"input": 4,
|
|
1210
|
+
"output": 15,
|
|
1211
|
+
"cache_read": 0.2,
|
|
1212
|
+
"cache_write": 5
|
|
1213
|
+
}
|
|
1214
|
+
},
|
|
1215
|
+
"canonical_model_id": "openai/gpt-6.1-sol"
|
|
1216
|
+
},
|
|
1124
1217
|
"text-embedding-3-large": {
|
|
1125
1218
|
"id": "text-embedding-3-large",
|
|
1126
1219
|
"name": "text-embedding-3-large",
|
|
@@ -1248,6 +1341,19 @@
|
|
|
1248
1341
|
}
|
|
1249
1342
|
}
|
|
1250
1343
|
}
|
|
1344
|
+
},
|
|
1345
|
+
"ultrafast": {
|
|
1346
|
+
"cost": {
|
|
1347
|
+
"input": 60,
|
|
1348
|
+
"output": 300,
|
|
1349
|
+
"cache_read": 6,
|
|
1350
|
+
"cache_write": 75
|
|
1351
|
+
},
|
|
1352
|
+
"provider": {
|
|
1353
|
+
"body": {
|
|
1354
|
+
"service_tier": "ultrafast"
|
|
1355
|
+
}
|
|
1356
|
+
}
|
|
1251
1357
|
}
|
|
1252
1358
|
}
|
|
1253
1359
|
},
|
data/data/openrouter.json
CHANGED
|
@@ -518,9 +518,9 @@
|
|
|
518
518
|
"output": 943718
|
|
519
519
|
},
|
|
520
520
|
"cost": {
|
|
521
|
-
"input": 0.
|
|
522
|
-
"output":
|
|
523
|
-
"cache_read": 0.
|
|
521
|
+
"input": 0.29,
|
|
522
|
+
"output": 9,
|
|
523
|
+
"cache_read": 0.28
|
|
524
524
|
}
|
|
525
525
|
},
|
|
526
526
|
"poolside/laguna-s-2.1:free": {
|
|
@@ -1859,13 +1859,13 @@
|
|
|
1859
1859
|
},
|
|
1860
1860
|
"open_weights": true,
|
|
1861
1861
|
"limit": {
|
|
1862
|
-
"context":
|
|
1862
|
+
"context": 1048576,
|
|
1863
1863
|
"output": 943718
|
|
1864
1864
|
},
|
|
1865
1865
|
"cost": {
|
|
1866
|
-
"input": 0.
|
|
1867
|
-
"output":
|
|
1868
|
-
"cache_read": 0.
|
|
1866
|
+
"input": 0.01,
|
|
1867
|
+
"output": 1.28,
|
|
1868
|
+
"cache_read": 0.01
|
|
1869
1869
|
},
|
|
1870
1870
|
"canonical_model_id": "deepseek/deepseek-v4-flash-0731"
|
|
1871
1871
|
},
|
|
@@ -1910,9 +1910,9 @@
|
|
|
1910
1910
|
"output": 943718
|
|
1911
1911
|
},
|
|
1912
1912
|
"cost": {
|
|
1913
|
-
"input": 0.
|
|
1914
|
-
"output":
|
|
1915
|
-
"cache_read": 0.
|
|
1913
|
+
"input": 0.0198,
|
|
1914
|
+
"output": 0.396,
|
|
1915
|
+
"cache_read": 0.00291
|
|
1916
1916
|
},
|
|
1917
1917
|
"canonical_model_id": "deepseek/deepseek-v4.1-flash"
|
|
1918
1918
|
},
|
|
@@ -2067,12 +2067,12 @@
|
|
|
2067
2067
|
"open_weights": true,
|
|
2068
2068
|
"limit": {
|
|
2069
2069
|
"context": 1048576,
|
|
2070
|
-
"output":
|
|
2070
|
+
"output": 393216
|
|
2071
2071
|
},
|
|
2072
2072
|
"cost": {
|
|
2073
|
-
"input": 0.
|
|
2074
|
-
"output":
|
|
2075
|
-
"cache_read": 0.
|
|
2073
|
+
"input": 0.66,
|
|
2074
|
+
"output": 1.98,
|
|
2075
|
+
"cache_read": 0.022
|
|
2076
2076
|
},
|
|
2077
2077
|
"canonical_model_id": "deepseek/deepseek-v4-pro-0813"
|
|
2078
2078
|
},
|
|
@@ -2219,9 +2219,9 @@
|
|
|
2219
2219
|
"output": 384000
|
|
2220
2220
|
},
|
|
2221
2221
|
"cost": {
|
|
2222
|
-
"input": 0.
|
|
2223
|
-
"output": 1.
|
|
2224
|
-
"cache_read": 0.
|
|
2222
|
+
"input": 0.783,
|
|
2223
|
+
"output": 1.566,
|
|
2224
|
+
"cache_read": 0.06525
|
|
2225
2225
|
},
|
|
2226
2226
|
"canonical_model_id": "deepseek/deepseek-v4-pro"
|
|
2227
2227
|
},
|
|
@@ -2335,12 +2335,12 @@
|
|
|
2335
2335
|
"open_weights": true,
|
|
2336
2336
|
"limit": {
|
|
2337
2337
|
"context": 1048576,
|
|
2338
|
-
"output":
|
|
2338
|
+
"output": 384000
|
|
2339
2339
|
},
|
|
2340
2340
|
"cost": {
|
|
2341
|
-
"input": 0.
|
|
2342
|
-
"output": 0.
|
|
2343
|
-
"cache_read": 0.
|
|
2341
|
+
"input": 0.07854,
|
|
2342
|
+
"output": 0.15708,
|
|
2343
|
+
"cache_read": 0.015708
|
|
2344
2344
|
},
|
|
2345
2345
|
"canonical_model_id": "deepseek/deepseek-v4-flash"
|
|
2346
2346
|
},
|
|
@@ -2551,9 +2551,9 @@
|
|
|
2551
2551
|
"output": 128000
|
|
2552
2552
|
},
|
|
2553
2553
|
"cost": {
|
|
2554
|
-
"input": 0.
|
|
2555
|
-
"output": 0.
|
|
2556
|
-
"cache_read": 0.
|
|
2554
|
+
"input": 0.0825,
|
|
2555
|
+
"output": 0.33,
|
|
2556
|
+
"cache_read": 0.020625
|
|
2557
2557
|
},
|
|
2558
2558
|
"canonical_model_id": "tencent/hy3"
|
|
2559
2559
|
},
|
|
@@ -2623,9 +2623,9 @@
|
|
|
2623
2623
|
"output": 64000
|
|
2624
2624
|
},
|
|
2625
2625
|
"cost": {
|
|
2626
|
-
"input": 0.
|
|
2627
|
-
"output": 2.
|
|
2628
|
-
"cache_read": 0.
|
|
2626
|
+
"input": 0.7506,
|
|
2627
|
+
"output": 2.2509,
|
|
2628
|
+
"cache_read": 0.0378
|
|
2629
2629
|
},
|
|
2630
2630
|
"canonical_model_id": "tencent/hy4-preview"
|
|
2631
2631
|
},
|
|
@@ -3142,7 +3142,7 @@
|
|
|
3142
3142
|
"cost": {
|
|
3143
3143
|
"input": 0.3,
|
|
3144
3144
|
"output": 0.9,
|
|
3145
|
-
"cache_read": 0.
|
|
3145
|
+
"cache_read": 0.055
|
|
3146
3146
|
},
|
|
3147
3147
|
"canonical_model_id": "zhipuai/glm-4.6v"
|
|
3148
3148
|
},
|
|
@@ -3298,7 +3298,7 @@
|
|
|
3298
3298
|
},
|
|
3299
3299
|
"open_weights": true,
|
|
3300
3300
|
"limit": {
|
|
3301
|
-
"context":
|
|
3301
|
+
"context": 1048576,
|
|
3302
3302
|
"output": 943717
|
|
3303
3303
|
},
|
|
3304
3304
|
"cost": {
|
|
@@ -3590,9 +3590,9 @@
|
|
|
3590
3590
|
"output": 943718
|
|
3591
3591
|
},
|
|
3592
3592
|
"cost": {
|
|
3593
|
-
"input": 0.
|
|
3594
|
-
"output":
|
|
3595
|
-
"cache_read": 0.
|
|
3593
|
+
"input": 0.432,
|
|
3594
|
+
"output": 3.99,
|
|
3595
|
+
"cache_read": 0.26
|
|
3596
3596
|
},
|
|
3597
3597
|
"canonical_model_id": "zhipuai/glm-5.2"
|
|
3598
3598
|
},
|
|
@@ -3630,9 +3630,9 @@
|
|
|
3630
3630
|
"output": 131072
|
|
3631
3631
|
},
|
|
3632
3632
|
"cost": {
|
|
3633
|
-
"input":
|
|
3634
|
-
"output":
|
|
3635
|
-
"cache_read": 0.
|
|
3633
|
+
"input": 0.9646,
|
|
3634
|
+
"output": 3.0316,
|
|
3635
|
+
"cache_read": 0.17914
|
|
3636
3636
|
},
|
|
3637
3637
|
"canonical_model_id": "zhipuai/glm-5.1"
|
|
3638
3638
|
},
|
|
@@ -3746,7 +3746,7 @@
|
|
|
3746
3746
|
},
|
|
3747
3747
|
"open_weights": true,
|
|
3748
3748
|
"limit": {
|
|
3749
|
-
"context":
|
|
3749
|
+
"context": 1048576,
|
|
3750
3750
|
"output": 943717
|
|
3751
3751
|
},
|
|
3752
3752
|
"cost": {
|
|
@@ -4430,11 +4430,11 @@
|
|
|
4430
4430
|
"open_weights": true,
|
|
4431
4431
|
"limit": {
|
|
4432
4432
|
"context": 131072,
|
|
4433
|
-
"output":
|
|
4433
|
+
"output": 117964
|
|
4434
4434
|
},
|
|
4435
4435
|
"cost": {
|
|
4436
|
-
"input": 0.
|
|
4437
|
-
"output": 1.
|
|
4436
|
+
"input": 0.35,
|
|
4437
|
+
"output": 1.5,
|
|
4438
4438
|
"cache_read": 0.04
|
|
4439
4439
|
},
|
|
4440
4440
|
"canonical_model_id": "meta/muse-glimmer-30b"
|
|
@@ -4758,12 +4758,12 @@
|
|
|
4758
4758
|
},
|
|
4759
4759
|
"open_weights": false,
|
|
4760
4760
|
"limit": {
|
|
4761
|
-
"context":
|
|
4761
|
+
"context": 1048576,
|
|
4762
4762
|
"output": 943718
|
|
4763
4763
|
},
|
|
4764
4764
|
"cost": {
|
|
4765
4765
|
"input": 0.02,
|
|
4766
|
-
"output": 0.
|
|
4766
|
+
"output": 0.2475,
|
|
4767
4767
|
"cache_read": 0.01
|
|
4768
4768
|
}
|
|
4769
4769
|
},
|
|
@@ -4799,13 +4799,13 @@
|
|
|
4799
4799
|
},
|
|
4800
4800
|
"open_weights": false,
|
|
4801
4801
|
"limit": {
|
|
4802
|
-
"context":
|
|
4802
|
+
"context": 1048576,
|
|
4803
4803
|
"output": 131072
|
|
4804
4804
|
},
|
|
4805
4805
|
"cost": {
|
|
4806
|
-
"input": 0.
|
|
4806
|
+
"input": 0.13,
|
|
4807
4807
|
"output": 4,
|
|
4808
|
-
"cache_read": 0.
|
|
4808
|
+
"cache_read": 0.13
|
|
4809
4809
|
}
|
|
4810
4810
|
},
|
|
4811
4811
|
"arcee-ai/trinity-large-thinking": {
|
|
@@ -4984,7 +4984,6 @@
|
|
|
4984
4984
|
{
|
|
4985
4985
|
"type": "effort",
|
|
4986
4986
|
"values": [
|
|
4987
|
-
"none",
|
|
4988
4987
|
"low",
|
|
4989
4988
|
"medium",
|
|
4990
4989
|
"high",
|
|
@@ -5017,13 +5016,13 @@
|
|
|
5017
5016
|
"cost": {
|
|
5018
5017
|
"input": 2,
|
|
5019
5018
|
"output": 10,
|
|
5020
|
-
"cache_read": 0.
|
|
5019
|
+
"cache_read": 0.1,
|
|
5021
5020
|
"cache_write": 2.5,
|
|
5022
5021
|
"tiers": [
|
|
5023
5022
|
{
|
|
5024
5023
|
"input": 4,
|
|
5025
5024
|
"output": 15,
|
|
5026
|
-
"cache_read": 0.
|
|
5025
|
+
"cache_read": 0.2,
|
|
5027
5026
|
"cache_write": 5,
|
|
5028
5027
|
"tier": {
|
|
5029
5028
|
"type": "context",
|
|
@@ -5034,7 +5033,7 @@
|
|
|
5034
5033
|
"context_over_200k": {
|
|
5035
5034
|
"input": 4,
|
|
5036
5035
|
"output": 15,
|
|
5037
|
-
"cache_read": 0.
|
|
5036
|
+
"cache_read": 0.2,
|
|
5038
5037
|
"cache_write": 5
|
|
5039
5038
|
}
|
|
5040
5039
|
}
|
|
@@ -6072,9 +6071,9 @@
|
|
|
6072
6071
|
"output": 943718
|
|
6073
6072
|
},
|
|
6074
6073
|
"cost": {
|
|
6075
|
-
"input": 0.
|
|
6076
|
-
"output": 0.
|
|
6077
|
-
"cache_read": 0.
|
|
6074
|
+
"input": 0.0198,
|
|
6075
|
+
"output": 0.396,
|
|
6076
|
+
"cache_read": 0.00291
|
|
6078
6077
|
}
|
|
6079
6078
|
},
|
|
6080
6079
|
"~deepseek/deepseek-pro-latest": {
|
|
@@ -6113,12 +6112,12 @@
|
|
|
6113
6112
|
"open_weights": false,
|
|
6114
6113
|
"limit": {
|
|
6115
6114
|
"context": 1048576,
|
|
6116
|
-
"output":
|
|
6115
|
+
"output": 393216
|
|
6117
6116
|
},
|
|
6118
6117
|
"cost": {
|
|
6119
|
-
"input": 0.
|
|
6120
|
-
"output":
|
|
6121
|
-
"cache_read": 0.
|
|
6118
|
+
"input": 0.123,
|
|
6119
|
+
"output": 3.5,
|
|
6120
|
+
"cache_read": 0.123
|
|
6122
6121
|
}
|
|
6123
6122
|
},
|
|
6124
6123
|
"~deepseek/deepseek-v4-flash-latest": {
|
|
@@ -6156,13 +6155,13 @@
|
|
|
6156
6155
|
},
|
|
6157
6156
|
"open_weights": false,
|
|
6158
6157
|
"limit": {
|
|
6159
|
-
"context":
|
|
6158
|
+
"context": 1048576,
|
|
6160
6159
|
"output": 943718
|
|
6161
6160
|
},
|
|
6162
6161
|
"cost": {
|
|
6163
|
-
"input": 0.
|
|
6164
|
-
"output": 0.
|
|
6165
|
-
"cache_read": 0.
|
|
6162
|
+
"input": 0.0099,
|
|
6163
|
+
"output": 0.13068,
|
|
6164
|
+
"cache_read": 0.001386
|
|
6166
6165
|
}
|
|
6167
6166
|
},
|
|
6168
6167
|
"~x-ai/grok-latest": {
|
|
@@ -6666,9 +6665,9 @@
|
|
|
6666
6665
|
"output": 235929
|
|
6667
6666
|
},
|
|
6668
6667
|
"cost": {
|
|
6669
|
-
"input": 0.
|
|
6670
|
-
"output": 0.
|
|
6671
|
-
"cache_read": 0.
|
|
6668
|
+
"input": 0.09,
|
|
6669
|
+
"output": 0.3,
|
|
6670
|
+
"cache_read": 0.05
|
|
6672
6671
|
},
|
|
6673
6672
|
"canonical_model_id": "google/gemma-4-26b-a4b-it"
|
|
6674
6673
|
},
|
|
@@ -9041,8 +9040,8 @@
|
|
|
9041
9040
|
"output": 235929
|
|
9042
9041
|
},
|
|
9043
9042
|
"cost": {
|
|
9044
|
-
"input": 0.
|
|
9045
|
-
"output": 3.
|
|
9043
|
+
"input": 0.6712,
|
|
9044
|
+
"output": 3.35,
|
|
9046
9045
|
"cache_read": 0.18
|
|
9047
9046
|
},
|
|
9048
9047
|
"canonical_model_id": "moonshotai/kimi-k2.7-code"
|
|
@@ -9212,7 +9211,7 @@
|
|
|
9212
9211
|
},
|
|
9213
9212
|
"open_weights": true,
|
|
9214
9213
|
"limit": {
|
|
9215
|
-
"context":
|
|
9214
|
+
"context": 262144,
|
|
9216
9215
|
"output": 32768
|
|
9217
9216
|
},
|
|
9218
9217
|
"cost": {
|
|
@@ -9717,7 +9716,7 @@
|
|
|
9717
9716
|
},
|
|
9718
9717
|
"open_weights": true,
|
|
9719
9718
|
"limit": {
|
|
9720
|
-
"context":
|
|
9719
|
+
"context": 1050000,
|
|
9721
9720
|
"output": 131072
|
|
9722
9721
|
},
|
|
9723
9722
|
"cost": {
|
|
@@ -10865,9 +10864,9 @@
|
|
|
10865
10864
|
"output": 235929
|
|
10866
10865
|
},
|
|
10867
10866
|
"cost": {
|
|
10868
|
-
"input": 0.
|
|
10869
|
-
"output": 4.
|
|
10870
|
-
"cache_read": 0.
|
|
10867
|
+
"input": 0.0249,
|
|
10868
|
+
"output": 4.35,
|
|
10869
|
+
"cache_read": 0.0199
|
|
10871
10870
|
},
|
|
10872
10871
|
"canonical_model_id": "alibaba/qwen3.8-27b"
|
|
10873
10872
|
},
|
|
@@ -11500,7 +11499,7 @@
|
|
|
11500
11499
|
"open_weights": true,
|
|
11501
11500
|
"limit": {
|
|
11502
11501
|
"context": 262144,
|
|
11503
|
-
"output":
|
|
11502
|
+
"output": 65536
|
|
11504
11503
|
},
|
|
11505
11504
|
"cost": {
|
|
11506
11505
|
"input": 0.26,
|
|
@@ -12242,11 +12241,11 @@
|
|
|
12242
12241
|
"open_weights": true,
|
|
12243
12242
|
"limit": {
|
|
12244
12243
|
"context": 131072,
|
|
12245
|
-
"output":
|
|
12244
|
+
"output": 16384
|
|
12246
12245
|
},
|
|
12247
12246
|
"cost": {
|
|
12248
|
-
"input": 0.
|
|
12249
|
-
"output": 0.
|
|
12247
|
+
"input": 0.12,
|
|
12248
|
+
"output": 0.5
|
|
12250
12249
|
},
|
|
12251
12250
|
"canonical_model_id": "alibaba/qwen3-30b-a3b"
|
|
12252
12251
|
},
|
|
@@ -14148,6 +14147,73 @@
|
|
|
14148
14147
|
"output": 2
|
|
14149
14148
|
}
|
|
14150
14149
|
},
|
|
14150
|
+
"openai/gpt-6.1-sol": {
|
|
14151
|
+
"id": "openai/gpt-6.1-sol",
|
|
14152
|
+
"name": "GPT-6.1 Sol",
|
|
14153
|
+
"description": "Near-Astra performance for complex coding, computer use, and professional work at a lower cost.",
|
|
14154
|
+
"family": "gpt-sol",
|
|
14155
|
+
"attachment": true,
|
|
14156
|
+
"reasoning": true,
|
|
14157
|
+
"reasoning_options": [
|
|
14158
|
+
{
|
|
14159
|
+
"type": "effort",
|
|
14160
|
+
"values": [
|
|
14161
|
+
"low",
|
|
14162
|
+
"medium",
|
|
14163
|
+
"high",
|
|
14164
|
+
"xhigh",
|
|
14165
|
+
"max"
|
|
14166
|
+
]
|
|
14167
|
+
}
|
|
14168
|
+
],
|
|
14169
|
+
"tool_call": true,
|
|
14170
|
+
"structured_output": true,
|
|
14171
|
+
"temperature": false,
|
|
14172
|
+
"knowledge": "2026-04-30",
|
|
14173
|
+
"release_date": "2026-09-29",
|
|
14174
|
+
"last_updated": "2026-09-29",
|
|
14175
|
+
"modalities": {
|
|
14176
|
+
"input": [
|
|
14177
|
+
"text",
|
|
14178
|
+
"image",
|
|
14179
|
+
"pdf"
|
|
14180
|
+
],
|
|
14181
|
+
"output": [
|
|
14182
|
+
"text"
|
|
14183
|
+
]
|
|
14184
|
+
},
|
|
14185
|
+
"open_weights": false,
|
|
14186
|
+
"limit": {
|
|
14187
|
+
"context": 1050000,
|
|
14188
|
+
"input": 922000,
|
|
14189
|
+
"output": 128000
|
|
14190
|
+
},
|
|
14191
|
+
"cost": {
|
|
14192
|
+
"input": 2,
|
|
14193
|
+
"output": 10,
|
|
14194
|
+
"cache_read": 0.1,
|
|
14195
|
+
"cache_write": 2.5,
|
|
14196
|
+
"tiers": [
|
|
14197
|
+
{
|
|
14198
|
+
"input": 4,
|
|
14199
|
+
"output": 15,
|
|
14200
|
+
"cache_read": 0.2,
|
|
14201
|
+
"cache_write": 5,
|
|
14202
|
+
"tier": {
|
|
14203
|
+
"type": "context",
|
|
14204
|
+
"size": 272000
|
|
14205
|
+
}
|
|
14206
|
+
}
|
|
14207
|
+
],
|
|
14208
|
+
"context_over_200k": {
|
|
14209
|
+
"input": 4,
|
|
14210
|
+
"output": 15,
|
|
14211
|
+
"cache_read": 0.2,
|
|
14212
|
+
"cache_write": 5
|
|
14213
|
+
}
|
|
14214
|
+
},
|
|
14215
|
+
"canonical_model_id": "openai/gpt-6.1-sol"
|
|
14216
|
+
},
|
|
14151
14217
|
"openai/gpt-4o-2024-08-06": {
|
|
14152
14218
|
"id": "openai/gpt-4o-2024-08-06",
|
|
14153
14219
|
"name": "GPT-4o (2024-08-06)",
|
|
@@ -15311,6 +15377,70 @@
|
|
|
15311
15377
|
},
|
|
15312
15378
|
"canonical_model_id": "openai/gpt-6-luna"
|
|
15313
15379
|
},
|
|
15380
|
+
"openai/gpt-6.1-sol-pro": {
|
|
15381
|
+
"id": "openai/gpt-6.1-sol-pro",
|
|
15382
|
+
"name": "GPT-6.1 Sol Pro",
|
|
15383
|
+
"description": "Frontier GPT model for professional reasoning, coding, and multimodal work",
|
|
15384
|
+
"family": "gpt",
|
|
15385
|
+
"attachment": true,
|
|
15386
|
+
"reasoning": true,
|
|
15387
|
+
"reasoning_options": [
|
|
15388
|
+
{
|
|
15389
|
+
"type": "effort",
|
|
15390
|
+
"values": [
|
|
15391
|
+
"low",
|
|
15392
|
+
"medium",
|
|
15393
|
+
"high",
|
|
15394
|
+
"xhigh",
|
|
15395
|
+
"max"
|
|
15396
|
+
]
|
|
15397
|
+
}
|
|
15398
|
+
],
|
|
15399
|
+
"tool_call": true,
|
|
15400
|
+
"structured_output": true,
|
|
15401
|
+
"temperature": false,
|
|
15402
|
+
"release_date": "2026-09-29",
|
|
15403
|
+
"last_updated": "2026-09-29",
|
|
15404
|
+
"modalities": {
|
|
15405
|
+
"input": [
|
|
15406
|
+
"pdf",
|
|
15407
|
+
"image",
|
|
15408
|
+
"text"
|
|
15409
|
+
],
|
|
15410
|
+
"output": [
|
|
15411
|
+
"text"
|
|
15412
|
+
]
|
|
15413
|
+
},
|
|
15414
|
+
"open_weights": false,
|
|
15415
|
+
"limit": {
|
|
15416
|
+
"context": 1050000,
|
|
15417
|
+
"output": 128000
|
|
15418
|
+
},
|
|
15419
|
+
"cost": {
|
|
15420
|
+
"input": 2,
|
|
15421
|
+
"output": 10,
|
|
15422
|
+
"cache_read": 0.1,
|
|
15423
|
+
"cache_write": 2.5,
|
|
15424
|
+
"tiers": [
|
|
15425
|
+
{
|
|
15426
|
+
"input": 4,
|
|
15427
|
+
"output": 15,
|
|
15428
|
+
"cache_read": 0.2,
|
|
15429
|
+
"cache_write": 5,
|
|
15430
|
+
"tier": {
|
|
15431
|
+
"type": "context",
|
|
15432
|
+
"size": 272000
|
|
15433
|
+
}
|
|
15434
|
+
}
|
|
15435
|
+
],
|
|
15436
|
+
"context_over_200k": {
|
|
15437
|
+
"input": 4,
|
|
15438
|
+
"output": 15,
|
|
15439
|
+
"cache_read": 0.2,
|
|
15440
|
+
"cache_write": 5
|
|
15441
|
+
}
|
|
15442
|
+
}
|
|
15443
|
+
},
|
|
15314
15444
|
"openai/o4-mini-high": {
|
|
15315
15445
|
"id": "openai/o4-mini-high",
|
|
15316
15446
|
"name": "o4 Mini High",
|
|
@@ -15552,12 +15682,11 @@
|
|
|
15552
15682
|
"open_weights": true,
|
|
15553
15683
|
"limit": {
|
|
15554
15684
|
"context": 131072,
|
|
15555
|
-
"output":
|
|
15685
|
+
"output": 117964
|
|
15556
15686
|
},
|
|
15557
15687
|
"cost": {
|
|
15558
|
-
"input": 0.
|
|
15559
|
-
"output": 0.
|
|
15560
|
-
"cache_read": 0.075
|
|
15688
|
+
"input": 0.037,
|
|
15689
|
+
"output": 0.17
|
|
15561
15690
|
},
|
|
15562
15691
|
"canonical_model_id": "openai/gpt-oss-120b"
|
|
15563
15692
|
},
|
|
@@ -156,6 +156,15 @@ Three more hooks cover a local tool call. `on_tool_start` fires before
|
|
|
156
156
|
the tool runs and returns the span that `on_tool_finish` and
|
|
157
157
|
`on_tool_error` receive.
|
|
158
158
|
|
|
159
|
+
An interrupt is neither a finish nor an error, and it is reported to a
|
|
160
|
+
hook of its own. `on_interrupt` is called with a `scope:` of `:request`
|
|
161
|
+
or `:tool` before the caller is given the exception, so a tracer that
|
|
162
|
+
records what happened to a turn records it while the work is still in
|
|
163
|
+
flight. The hook receives the span that `on_request_start` returned and
|
|
164
|
+
its `request_id`; a tool pass carries neither, because a tool's span
|
|
165
|
+
belongs to the call. A cancel reaches every tool that is running, so the
|
|
166
|
+
tool phase is announced once rather than once per tool.
|
|
167
|
+
|
|
159
168
|
A tracer's own lifetime is bracketed as well. `on_exit` fires once,
|
|
160
169
|
when the last scope that is open for that tracer ends. That scope can
|
|
161
170
|
belong to a different thread than the one that opened the first: a tool
|
|
@@ -214,11 +223,15 @@ as hooks gain parameters.
|
|
|
214
223
|
|
|
215
224
|
#### Notes
|
|
216
225
|
|
|
217
|
-
The base class raises `NotImplementedError` for
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
226
|
+
The base class raises `NotImplementedError` for the six request and tool
|
|
227
|
+
hooks above, so a tracer has to answer for each of them. The remaining
|
|
228
|
+
hooks do nothing by default. `on_exit` does nothing because most tracers
|
|
229
|
+
hold nothing that needs releasing, and `start_trace` and `stop_trace`
|
|
230
|
+
are no-ops too. `on_interrupt` does nothing because an interrupt is
|
|
231
|
+
delivered to whatever tracer happens to be bound, and a hook that raised
|
|
232
|
+
would replace the interrupt every caller is written against. Accept `**`
|
|
233
|
+
to absorb keywords you do not read, as the built-in tracers do, so a
|
|
234
|
+
hook that gains a parameter does not break your subclass.
|
|
222
235
|
|
|
223
236
|
### PrettyLogger
|
|
224
237
|
|
data/lib/llm/context.rb
CHANGED
|
@@ -343,6 +343,14 @@ module LLM
|
|
|
343
343
|
@queue = stream.queue
|
|
344
344
|
@queue.wait
|
|
345
345
|
end
|
|
346
|
+
rescue LLM::Interrupt
|
|
347
|
+
##
|
|
348
|
+
# Once, not once per tool. A cancel reaches every tool that is
|
|
349
|
+
# running, and the caller hears one exception, so the phase is
|
|
350
|
+
# announced here - the frame every strategy's interrupt unwinds
|
|
351
|
+
# through - and before the caller is given it.
|
|
352
|
+
tracer.on_interrupt(scope: :tool)
|
|
353
|
+
raise
|
|
346
354
|
ensure
|
|
347
355
|
@queue = nil
|
|
348
356
|
@stream = nil
|
data/lib/llm/tracer.rb
CHANGED
|
@@ -194,6 +194,37 @@ module LLM
|
|
|
194
194
|
raise NotImplementedError, "#{self.class} does not implement '#{__method__}'"
|
|
195
195
|
end
|
|
196
196
|
|
|
197
|
+
##
|
|
198
|
+
# Called when a request or a tool is interrupted.
|
|
199
|
+
#
|
|
200
|
+
# An interrupt is not a failure, so this is not {#on_request_error} or
|
|
201
|
+
# {#on_tool_error} under another name: it is the third ending either
|
|
202
|
+
# scope can have, and it is called before {LLM::Interrupt} reaches the
|
|
203
|
+
# caller, so a tracer that has to record what happened to a turn does it
|
|
204
|
+
# while the work is still the work in flight.
|
|
205
|
+
#
|
|
206
|
+
# A request is announced once, by the transport. A tool is announced
|
|
207
|
+
# once for the phase rather than once per tool: a cancel reaches every
|
|
208
|
+
# tool that is running and the caller hears one exception, so there is
|
|
209
|
+
# no one tool the announcement belongs to.
|
|
210
|
+
#
|
|
211
|
+
# The default does nothing, which is the difference from the rest of the
|
|
212
|
+
# lifecycle. Every other hook raises, because a tracer that means to draw
|
|
213
|
+
# a request has to answer for it - but an interrupt is delivered to
|
|
214
|
+
# whatever tracer happens to be bound, and a hook that raised here would
|
|
215
|
+
# replace the interrupt every caller is written against.
|
|
216
|
+
# @param [Symbol] scope
|
|
217
|
+
# :request for a request, :tool for a tool
|
|
218
|
+
# @param [Object, nil] span
|
|
219
|
+
# The span that {#on_request_start} returned. A tool pass has none:
|
|
220
|
+
# a tool's span belongs to the call, and the announcement is not one
|
|
221
|
+
# tool's to make.
|
|
222
|
+
# @param [String, nil] request_id
|
|
223
|
+
# The id, as passed to {#on_request_start}, when the scope is a request
|
|
224
|
+
# @return [void]
|
|
225
|
+
def on_interrupt(scope:, span: nil, request_id: nil)
|
|
226
|
+
end
|
|
227
|
+
|
|
197
228
|
##
|
|
198
229
|
# Opens a trace group so subsequent LLM spans share the same OpenTelemetry
|
|
199
230
|
# trace_id (and appear as one trace in backends like Langfuse).
|
|
@@ -38,8 +38,37 @@ class LLM::Transport
|
|
|
38
38
|
res = transport.request(request, owner:, stream:, &b)
|
|
39
39
|
res = LLM::Transport::Response.from(res)
|
|
40
40
|
[handle_response(res, tracer, span, request_id), span, tracer, request_id]
|
|
41
|
-
rescue
|
|
42
|
-
|
|
41
|
+
rescue LLM::Interrupt
|
|
42
|
+
##
|
|
43
|
+
# Curb raises this itself, from the chunk it is reading,
|
|
44
|
+
# which is the curb shape rather than something raised
|
|
45
|
+
# ordinarily: the other transports fail, and reach the
|
|
46
|
+
# rescue below.
|
|
47
|
+
#
|
|
48
|
+
# An interrupt is not a failure, so it is not reported as
|
|
49
|
+
# one - `on_interrupt` is the hook for it - and it is called
|
|
50
|
+
# before the caller is given the exception.
|
|
51
|
+
tracer.on_interrupt(scope: :request, span:, request_id:)
|
|
52
|
+
raise
|
|
53
|
+
rescue *transport.interrupt_errors => ex
|
|
54
|
+
##
|
|
55
|
+
# Where a Net::HTTP interrupt becomes the exception the
|
|
56
|
+
# caller gets: the socket is closed from another thread
|
|
57
|
+
# and the read fails as one of these classes. The owner
|
|
58
|
+
# is what tells the two apart.
|
|
59
|
+
if transport.interrupted?(owner)
|
|
60
|
+
tracer.on_interrupt(scope: :request, span:, request_id:)
|
|
61
|
+
raise LLM::Interrupt, "request interrupted"
|
|
62
|
+
else
|
|
63
|
+
tracer.on_request_error(ex:, span:, request_id:)
|
|
64
|
+
raise
|
|
65
|
+
end
|
|
66
|
+
rescue => ex
|
|
67
|
+
##
|
|
68
|
+
# Everything else ends the request, so the tracer is told:
|
|
69
|
+
# a span that was opened and never closed draws a request
|
|
70
|
+
# that never ended.
|
|
71
|
+
tracer.on_request_error(ex:, span:, request_id:)
|
|
43
72
|
raise
|
|
44
73
|
end
|
|
45
74
|
|
data/lib/llm/version.rb
CHANGED