main
1# frozen_string_literal: true
2
3RSpec.describe Net::Llm::VertexAI do
4 subject(:client) do
5 described_class.new(
6 project_id: ENV.fetch("GOOGLE_CLOUD_PROJECT", "test-project"),
7 region: ENV.fetch("GOOGLE_CLOUD_REGION", "us-east5")
8 )
9 end
10
11 describe "#initialize" do
12 it "sets default model" do
13 expect(client.model).to eq("claude-opus-4-5@20251101")
14 end
15
16 it "allows custom model" do
17 custom = described_class.new(
18 project_id: "test-project",
19 region: "us-east5",
20 model: "claude-haiku-4-5@20251022"
21 )
22 expect(custom.model).to eq("claude-haiku-4-5@20251022")
23 end
24 end
25
26 describe "#messages" do
27 let(:messages) { [{ role: "user", content: "Hello" }] }
28
29 context "without streaming", :vcr do
30 it "POST rawPredict" do
31 result = client.messages(messages)
32
33 expect(result["content"]).not_to be_empty
34 expect(result["role"]).to eq("assistant")
35 end
36 end
37
38 context "with streaming", :vcr do
39 it "yields SSE events to the block" do
40 results = []
41 client.messages(messages) { |event| results << event }
42
43 expect(results).not_to be_empty
44 expect(results.last["type"]).to eq("message_stop")
45 end
46 end
47
48 context "with tools", :vcr do
49 let(:tools) do
50 [{
51 name: "get_weather",
52 description: "Get weather for a city",
53 input_schema: {
54 type: "object",
55 properties: { city: { type: "string" } },
56 required: ["city"]
57 }
58 }]
59 end
60
61 it "POST rawPredict with tools" do
62 messages = [{ role: "user", content: "What is the weather in Tokyo?" }]
63 result = client.messages(messages, tools: tools)
64
65 expect(result["content"]).not_to be_empty
66 expect(result["stop_reason"]).to eq("tool_use")
67 end
68 end
69
70 context "with system prompt", :vcr do
71 it "includes system in request" do
72 result = client.messages(messages, system: "You are a helpful assistant.")
73
74 expect(result["content"]).not_to be_empty
75 end
76 end
77
78 context "error handling" do
79 it "returns error hash on HTTP failure" do
80 stub_request(:post, %r{aiplatform\.googleapis\.com})
81 .to_return(status: 401, body: "Unauthorized")
82
83 result = client.messages(messages)
84 expect(result["code"]).to eq("401")
85 expect(result["body"]).to eq("Unauthorized")
86 end
87 end
88 end
89end