Skip to content

Commit 3e12417

Browse files
Add additional specs to test improved JSON pre-processing
1 parent d553a04 commit 3e12417

5 files changed

+855
-0
lines changed

spec/anthropic/client/messages/streaming_spec.rb

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,165 @@
227227
end
228228
end
229229

230+
context "streaming empty preprocessed JSON array" do
231+
let(:model) { "claude-3-haiku-20240307" }
232+
let(:messages) do
233+
[
234+
{
235+
role: "user",
236+
content: <<~TXT.strip
237+
Return this empty JSON array:
238+
239+
[]
240+
241+
CRITICAL: Don't output anything else, only this empty JSON array.
242+
TXT
243+
},
244+
{
245+
role: "assistant",
246+
content: ""
247+
}
248+
]
249+
end
250+
let(:max_tokens) { 4096 }
251+
let(:response_objects) { [] }
252+
253+
let(:stream) do
254+
proc do |json_object|
255+
response_objects << json_object
256+
end
257+
end
258+
259+
let(:response) do
260+
Anthropic::Client.new(access_token: ENV.fetch("ANTHROPIC_API_KEY", nil)).messages(
261+
parameters: {
262+
model: model,
263+
messages: messages,
264+
max_tokens: max_tokens,
265+
stream: stream,
266+
preprocess_stream: :json
267+
}
268+
)
269+
end
270+
271+
let(:cassette) { "#{model} streaming json #{messages[0][:content]}".downcase }
272+
273+
it "succeeds" do
274+
VCR.use_cassette(cassette) do
275+
expect(response["content"].empty?).to eq(false)
276+
expect(response_objects.count).to be(0)
277+
expect(response_objects).to eq([])
278+
end
279+
end
280+
end
281+
282+
context "streaming preprocessed single small JSON object" do
283+
let(:model) { "claude-3-haiku-20240307" }
284+
let(:messages) do
285+
[
286+
{
287+
role: "user",
288+
content: <<~TXT.strip
289+
Return this JSON object exactly as it is:
290+
291+
{"name": "Mountain Name", "height": "height in km"}
292+
293+
CRITICAL: Don't output anything else, only this JSON object.
294+
TXT
295+
},
296+
{
297+
role: "assistant",
298+
content: ""
299+
}
300+
]
301+
end
302+
let(:max_tokens) { 4096 }
303+
let(:response_objects) { [] }
304+
305+
let(:stream) do
306+
proc do |json_object|
307+
response_objects << json_object
308+
end
309+
end
310+
311+
let(:response) do
312+
Anthropic::Client.new(access_token: ENV.fetch("ANTHROPIC_API_KEY", nil)).messages(
313+
parameters: {
314+
model: model,
315+
messages: messages,
316+
max_tokens: max_tokens,
317+
stream: stream,
318+
preprocess_stream: :json
319+
}
320+
)
321+
end
322+
323+
let(:cassette) { "#{model} streaming json #{messages[0][:content]}".downcase }
324+
325+
it "succeeds" do
326+
VCR.use_cassette(cassette) do
327+
expect(response["content"].empty?).to eq(false)
328+
expect(response_objects.count).to be(1)
329+
expect(response_objects)
330+
.to eq([{ "name" => "Mountain Name", "height" => "height in km" }])
331+
end
332+
end
333+
end
334+
335+
context "streaming preprocessed single large JSON object" do
336+
let(:model) { "claude-3-haiku-20240307" }
337+
let(:messages) do
338+
[
339+
{
340+
role: "user",
341+
content: <<~TXT.strip
342+
Return a single JSON object with a large text in the "text" field.
343+
The text should be at least 1000 characters long.
344+
345+
{"text": "large text"}
346+
347+
CRITICAL: Don't output anything else, only this JSON object.
348+
TXT
349+
},
350+
{
351+
role: "assistant",
352+
content: ""
353+
}
354+
]
355+
end
356+
let(:max_tokens) { 4096 }
357+
let(:response_objects) { [] }
358+
359+
let(:stream) do
360+
proc do |json_object|
361+
response_objects << json_object
362+
end
363+
end
364+
365+
let(:response) do
366+
Anthropic::Client.new(access_token: ENV.fetch("ANTHROPIC_API_KEY", nil)).messages(
367+
parameters: {
368+
model: model,
369+
messages: messages,
370+
max_tokens: max_tokens,
371+
stream: stream,
372+
preprocess_stream: :json
373+
}
374+
)
375+
end
376+
377+
let(:cassette) { "#{model} streaming json #{messages[0][:content]}".downcase }
378+
379+
it "succeeds" do
380+
VCR.use_cassette(cassette) do
381+
expect(response["content"].empty?).to eq(false)
382+
expect(response_objects.count).to be(1)
383+
expect(response_objects)
384+
.to eq(fixture_json("preprocessed_single_long_json.json"))
385+
end
386+
end
387+
end
388+
230389
context "malformed streaming preprocessed JSON" do
231390
let(:model) { "claude-3-haiku-20240307" }
232391
let(:messages) do

0 commit comments

Comments
 (0)