llm.rb 16.0.0.pre.4 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a83847d3c33a48980bd9740d7aff397db757ec91224440a97c10240c0ae3a290
4
- data.tar.gz: 402d6ea4a68fc987e3597d1b6dd84089f2804c7774ef35e38fb8fc424b0e62b0
3
+ metadata.gz: 0f5c0f9cb6f92099cec46e8c7a83e02498d375458a50b8b3f19a94ac2385dc8f
4
+ data.tar.gz: 11929258bad683f946ded02b7b2621fcfae30cf1ed11c57007e4b4cfbac05b5d
5
5
  SHA512:
6
- metadata.gz: f75dda6e725c6aa48748a407e744c94c006d3db4973cf45064f7f0252fc2bc818ee7a99b564e66c4bad6ad4066bf5214b912a637b3b25b8b9f335d45d226c7e2
7
- data.tar.gz: ea3e7fe4a32687c7a34f4b85a0bd4aeee5b7b68387452dd1ac98a3572f1b1f74b4f19ac3ee32b10cf6f53563b9eceb5a8e9292e6001b90728e4997c7b9a301a2
6
+ metadata.gz: 5b32ee2a9301958487a808705f63895b1cd89898730e8b0bdcabcee06be62eef6a724795ccd0f6053227f0577380019436eab3b19ba3a15459560bcc78a505af
7
+ data.tar.gz: 7839665a301ee3ab68716737daaddc7f384308b6b24548efcb33699a3463de83efa638aa060293a27ced6145907dee6ddabb7b63d11d5cb5f1e1a0239b2e209f
data/CHANGELOG.md CHANGED
@@ -56,6 +56,29 @@
56
56
  has not been saved, where `#messages` reads the column. The Sequel plugin
57
57
  answers to `#messages!` too, where it is the same call as `#messages`.
58
58
 
59
+ ### Agent
60
+
61
+ * **agent: keep the instructions it injected in step** <br>
62
+ [`LLM::Agent`](https://r.uby.dev/api-docs/llm.rb/LLM/Agent.html) now brings
63
+ the instructions it injected up to date before a request goes out, so a
64
+ conversation restored from saved state runs on the agent's current
65
+ instructions rather than on the ones it was saved with. The message is
66
+ found by a mark the agent puts on it, so a message the caller composed is
67
+ never replaced, and the mark is written by
68
+ [`LLM::Message#to_h`](https://r.uby.dev/api-docs/llm.rb/LLM/Message.html#to_h-instance_method)
69
+ and read back on a restore, which is the conversation the refresh exists
70
+ for. Before this, the instructions were injected once and the message
71
+ stayed as it was for the life of the conversation.
72
+
73
+ * **agent: identify its own instructions by the mark, not by the role** <br>
74
+ Fix a bug where the agent decided whether it had already injected its
75
+ instructions by looking for a message with the `system` role. Google gives
76
+ instructions the `user` role, so the agent did not recognise the message it
77
+ had already injected and added another copy of the instructions on every
78
+ turn. It now asks the provider which role instructions are given, and
79
+ identifies the message it wrote by its mark, because on Google the message
80
+ a caller seeds a conversation with is a user message too.
81
+
59
82
  ### Console
60
83
 
61
84
  * **console: erase with the backspace key on OpenBSD** <br>
@@ -142,6 +165,18 @@
142
165
  once, when the whole turn had finished, so an interrupted turn persisted
143
166
  nothing.
144
167
 
168
+ ### Prompt
169
+
170
+ * **prompt: let a message carry fields a caller attaches to it** <br>
171
+ [`LLM::Prompt#system`](https://r.uby.dev/api-docs/llm.rb/LLM/Prompt.html#system-instance_method),
172
+ [`#user`](https://r.uby.dev/api-docs/llm.rb/LLM/Prompt.html#user-instance_method),
173
+ [`#developer`](https://r.uby.dev/api-docs/llm.rb/LLM/Prompt.html#developer-instance_method),
174
+ and [`#talk`](https://r.uby.dev/api-docs/llm.rb/LLM/Prompt.html#talk-instance_method),
175
+ along with its `#chat` alias, now take an `extra:` keyword, so a message a
176
+ caller composes can carry fields of its own. The runtime reads those fields
177
+ back rather than inferring provenance from a role, which is how an agent
178
+ tells the instructions it injected from a message the caller wrote.
179
+
145
180
  ### Provider
146
181
 
147
182
  * **deepseek: support image attachments in chat completions** <br>
@@ -161,14 +196,17 @@
161
196
  Update `data/` with current model listings, limits, and pricing. Alibaba adds
162
197
  `qwen3.5-flash`, `qwen3.7-flash`, and `qwen3.8-omni-flash`, and gives
163
198
  `qwen3.7-plus` attachments, structured output, and a lower price; OpenAI adds
164
- `gpt-daybreak-blue-latest` and `gpt-daybreak-red-latest`; Bedrock adds
165
- `openai.gpt-6-sol`, `openai.gpt-6-luna`, and
166
- `global.anthropic.claude-sonnet-5-5`; and DeepInfra adds `tencent/Hy4-preview`
167
- and the Xiaomi MiMo V2.6 Pro and V2.6 Flash models.
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.
168
205
  Bedrock also corrects the context and output limits of fifteen models, Google
169
206
  lowers the limits of `gemini-2.5-computer-use-preview-10-2025` and
170
- `gemini-3-pro-image`, and OpenRouter adds five models, drops six, and reprices
171
- many of the DeepSeek, Z.ai, and Qwen entries.
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.
172
210
 
173
211
  ### Schema
174
212
 
@@ -195,6 +233,42 @@
195
233
  rate limit or a timeout calls it when it lands and not once per attempt, and
196
234
  it fires even when the stream is disabled.
197
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
+
198
272
  ## v15.5.0
199
273
 
200
274
  Changes since `v15.4.1`.
data/README.md CHANGED
@@ -78,7 +78,8 @@ agent.talk "hello world"
78
78
  Streams can be simple IO objects or subclasses of
79
79
  [`LLM::Stream`](https://r.uby.dev/api-docs/llm.rb/LLM/Stream.html)
80
80
  with structured callbacks for content,
81
- reasoning, tool calls, tool returns, and compaction.
81
+ reasoning, tool calls, tool returns, the boundary a completed
82
+ request marks, and compaction.
82
83
  Streams can also observe message transformers, which rewrite
83
84
  outgoing messages before they reach the provider.
84
85
 
@@ -102,6 +103,11 @@ class MyStream < LLM::Stream
102
103
  def on_tool_return(tool, result)
103
104
  end
104
105
 
106
+ # A request has completed: the response is in the conversation, and
107
+ # any tools it asked for run after this.
108
+ def on_step(ctx, res)
109
+ end
110
+
105
111
  # Before a transformer rewrites an outgoing message.
106
112
  def on_transform(transformer)
107
113
  end
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
  },