From d53b00dc5649690ac45043b1a5e2bf9b8230fa4f Mon Sep 17 00:00:00 2001 From: Marcelo Trylesinski Date: Thu, 11 Sep 2025 12:08:54 +0200 Subject: [PATCH] Add test for Anthropic Vertex --- deploy/package.json | 1 + deploy/test.config.ts | 17 ++++++++--------- deploy/test/index.spec.ts | 22 ++++++++++++++++++++++ deploy/vitest.config.mts | 3 ++- package-lock.json | 22 ++++++++++++++++++++++ proxy-vcr/proxy_vcr/main.py | 1 + 6 files changed, 56 insertions(+), 10 deletions(-) diff --git a/deploy/package.json b/deploy/package.json index 4aaef18..a1ba184 100644 --- a/deploy/package.json +++ b/deploy/package.json @@ -22,6 +22,7 @@ }, "_": "@cloudflare/vitest-pool-workers is pinned because of https://github.com/cloudflare/workers-sdk/issues/10506", "devDependencies": { + "@anthropic-ai/vertex-sdk": "^0.13.2", "@cloudflare/vitest-pool-workers": "0.8.44", "@cloudflare/workers-types": "^4.20250712.0", "groq-sdk": "^0.30.0", diff --git a/deploy/test.config.ts b/deploy/test.config.ts index ac2b276..bfb0370 100644 --- a/deploy/test.config.ts +++ b/deploy/test.config.ts @@ -1,7 +1,7 @@ import { env } from 'cloudflare:workers' import type { Config } from '@deploy/types' -type ProviderKeys = 'openai' | 'groq' +type ProviderKeys = 'openai' | 'groq' | 'google' export const config: Config = { // the name of the organization, doesn't matter in this case @@ -45,13 +45,12 @@ export const config: Config = { injectCost: true, credentials: env.GROQ_API_KEY, }, - // google: { - // baseUrl: - // 'https://us-central1-aiplatform.googleapis.com/v1beta1/projects/{gcp-project-name}/locations/us-central1/publishers/google/models', - // providerId: 'google', - // injectCost: true, - // credentials: env.GOOGLE_SERVICE_ACCOUNT_KEY, - // }, + google: { + baseUrl: 'http://localhost:8005/google', + providerID: 'google-vertex', + injectCost: true, + credentials: env.GOOGLE_SERVICE_ACCOUNT_KEY, + }, }, // individual apiKeys apiKeys: { @@ -61,7 +60,7 @@ export const config: Config = { // user is optional user: 'testberto', // providers is required and identifies which providers this apiKey is allowed to use - providers: ['openai', 'groq'], + providers: ['openai', 'groq', 'google'], // you can also optionally add limits to a single key here spendingLimitDaily: 1, spendingLimitWeekly: 5, diff --git a/deploy/test/index.spec.ts b/deploy/test/index.spec.ts index 5662afc..54a0633 100644 --- a/deploy/test/index.spec.ts +++ b/deploy/test/index.spec.ts @@ -1,4 +1,7 @@ import OpenAI from 'openai' +import { AnthropicVertex } from '@anthropic-ai/vertex-sdk' +import { GoogleAuth } from 'google-auth-library' + import Groq from 'groq-sdk' import { SELF, env, fetchMock } from 'cloudflare:test' import { describe, it, expect, beforeAll, afterEach, beforeEach } from 'vitest' @@ -115,3 +118,22 @@ describe('groq', () => { expect(completion).toMatchSnapshot('llm') }) }) + +describe('anthropic', () => { + it('should call anthropic via gateway', async () => { + const client = new AnthropicVertex({ + baseURL: 'https://example.com/anthropic', + fetch: SELF.fetch.bind(SELF), + googleAuth: new GoogleAuth({ + apiKey: 'o-QBrunFudqD99879C5jkFZgZrueCLlCJGSMAbzFGFY', + }), + }) + + const completion = await client.messages.create({ + model: 'claude-sonnet-4-20250514', + max_tokens: 1024, + messages: [{ role: 'user', content: 'What is the capital of France?' }], + }) + expect(completion).toMatchSnapshot('llm') + }) +}) diff --git a/deploy/vitest.config.mts b/deploy/vitest.config.mts index 9175eb9..773b13d 100644 --- a/deploy/vitest.config.mts +++ b/deploy/vitest.config.mts @@ -19,13 +19,14 @@ export default defineWorkersConfig({ poolOptions: { workers: { wrangler: { + isolatedStorage: true, configPath: './wrangler.jsonc', }, miniflare: { bindings: { - // put variables here OPENAI_API_KEY: `${process.env.OPENAI_API_KEY}`, GROQ_API_KEY: `${process.env.GROQ_API_KEY}`, + GOOGLE_SERVICE_ACCOUNT_KEY: `${process.env.GOOGLE_SERVICE_ACCOUNT_KEY}`, }, }, }, diff --git a/package-lock.json b/package-lock.json index b63ecdd..bdd8c77 100644 --- a/package-lock.json +++ b/package-lock.json @@ -31,6 +31,7 @@ "@pydantic/logfire-cf-workers": "^0.6.0" }, "devDependencies": { + "@anthropic-ai/vertex-sdk": "^0.13.2", "@cloudflare/vitest-pool-workers": "0.8.44", "@cloudflare/workers-types": "^4.20250712.0", "groq-sdk": "^0.30.0", @@ -926,6 +927,27 @@ "@opentelemetry/api": ">=1.9.0 <1.10.0" } }, + "node_modules/@anthropic-ai/sdk": { + "version": "0.62.0", + "resolved": "https://registry.npmjs.org/@anthropic-ai/sdk/-/sdk-0.62.0.tgz", + "integrity": "sha512-gT2VFKX0gSp7KJNlav/vzRFjJOPYDZxCJRx7MYUc+fqURc5aS6OI/UJeD2KytJkjsIWv0OOwH1ePc1S5QE2GZw==", + "dev": true, + "license": "MIT", + "bin": { + "anthropic-ai-sdk": "bin/cli" + } + }, + "node_modules/@anthropic-ai/vertex-sdk": { + "version": "0.13.2", + "resolved": "https://registry.npmjs.org/@anthropic-ai/vertex-sdk/-/vertex-sdk-0.13.2.tgz", + "integrity": "sha512-1Oh25XovRh/dCeUmQboBDHYephNNKIrlaETtjFdznmiSS+i5obwDW/YG+5K3wKPkp6oZ+uWMHu74k13oY40JyQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@anthropic-ai/sdk": ">=0.50.3 <1", + "google-auth-library": "^9.4.2" + } + }, "node_modules/@cloudflare/kv-asset-handler": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/@cloudflare/kv-asset-handler/-/kv-asset-handler-0.4.0.tgz", diff --git a/proxy-vcr/proxy_vcr/main.py b/proxy-vcr/proxy_vcr/main.py index 69bf614..9b1f447 100644 --- a/proxy-vcr/proxy_vcr/main.py +++ b/proxy-vcr/proxy_vcr/main.py @@ -17,6 +17,7 @@ OPENAI_BASE_URL = 'https://api.openai.com/v1/' GROQ_BASE_URL = 'https://api.groq.com' +GOOGLE_VERTEX_BASE_URL = 'https://us-central1-aiplatform.googleapis.com/v1beta1/projects/pydantic-ai/locations/us-central1/publishers/google/models' current_file_dir = pathlib.Path(__file__).parent