thebird 1.2.1 → 1.2.3

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.
package/README.md CHANGED
@@ -2,24 +2,58 @@
2
2
 
3
3
  Anthropic SDK to multi-provider bridge. Drop-in adapter that translates Anthropic-style messages, tool calls, and content blocks to Google Gemini or any OpenAI-compatible API — with routing, transformers, streaming, vision, retry logic, and full TypeScript types.
4
4
 
5
+ ## How It Works
6
+
7
+ thebird accepts **Anthropic SDK message format** — the same `{ role, content }` structure you use with `@anthropic-ai/sdk` — and translates it to Gemini or any OpenAI-compatible API. No proxy server needed. You write Anthropic-format messages, thebird streams them through Gemini.
8
+
9
+ ```
10
+ Anthropic SDK format → thebird → Gemini / OpenAI-compatible API
11
+ (messages) (bridge) (native streaming)
12
+ ```
13
+
14
+ This means you can use `@anthropic-ai/sdk` to build your messages and tool definitions, then pass them directly to thebird for execution against Gemini models.
15
+
5
16
  ## Install
6
17
 
7
18
  ```bash
8
- npm install thebird
19
+ npm install thebird @anthropic-ai/sdk
9
20
  ```
10
21
 
11
22
  ## Quick Start
12
23
 
13
- **Gemini (direct)**
24
+ **Anthropic SDK format → Gemini (streaming)**
25
+
26
+ ```js
27
+ const Anthropic = require('@anthropic-ai/sdk');
28
+ const { streamGemini } = require('thebird');
29
+
30
+ // Build messages using Anthropic SDK format — same structure as client.messages.create()
31
+ const messages = [
32
+ { role: 'user', content: 'Count from 1 to 5.' }
33
+ ];
34
+
35
+ // Stream through Gemini — no server, no proxy
36
+ const { fullStream } = streamGemini({
37
+ model: 'gemini-3-flash-preview',
38
+ system: 'You are a helpful assistant.',
39
+ messages
40
+ });
41
+
42
+ for await (const event of fullStream) {
43
+ if (event.type === 'text-delta') process.stdout.write(event.textDelta);
44
+ }
45
+ ```
46
+
47
+ **Anthropic SDK format → Gemini (non-streaming)**
14
48
 
15
49
  ```js
16
- const { generateGemini, streamGemini } = require('thebird');
17
- // requires GEMINI_API_KEY env var
50
+ const { generateGemini } = require('thebird');
18
51
 
19
52
  const { text } = await generateGemini({
20
- model: 'gemini-2.0-flash',
53
+ model: 'gemini-3-flash-preview',
21
54
  messages: [{ role: 'user', content: 'Hello!' }]
22
55
  });
56
+ console.log(text);
23
57
  ```
24
58
 
25
59
  **Multi-provider router**
package/index.js CHANGED
@@ -7,18 +7,18 @@ const { resolveTransformers, applyRequestTransformers } = require('./lib/transfo
7
7
  const openaiProv = require('./lib/providers/openai');
8
8
 
9
9
  function streamGemini({ model, system, messages, tools, onStepFinish, apiKey,
10
- temperature, maxOutputTokens, topP, topK, safetySettings }) {
10
+ temperature, maxOutputTokens, topP, topK, safetySettings, responseModalities }) {
11
11
  return {
12
- fullStream: createFullStream({ model, system, messages, tools, onStepFinish, apiKey, temperature, maxOutputTokens, topP, topK, safetySettings }),
12
+ fullStream: createFullStream({ model, system, messages, tools, onStepFinish, apiKey, temperature, maxOutputTokens, topP, topK, safetySettings, responseModalities }),
13
13
  warnings: Promise.resolve([])
14
14
  };
15
15
  }
16
16
 
17
- async function* createFullStream({ model, system, messages, tools, onStepFinish, apiKey, temperature, maxOutputTokens, topP, topK, safetySettings }) {
17
+ async function* createFullStream({ model, system, messages, tools, onStepFinish, apiKey, temperature, maxOutputTokens, topP, topK, safetySettings, responseModalities }) {
18
18
  const client = getClient(apiKey);
19
19
  const modelId = extractModelId(model);
20
20
  let contents = convertMessages(messages);
21
- const { config } = buildConfig({ system, tools, temperature, maxOutputTokens, topP, topK, safetySettings });
21
+ const { config } = buildConfig({ system, tools, temperature, maxOutputTokens, topP, topK, safetySettings, responseModalities });
22
22
  while (true) {
23
23
  yield { type: 'start-step' };
24
24
  try {
@@ -66,11 +66,11 @@ async function* createFullStream({ model, system, messages, tools, onStepFinish,
66
66
  }
67
67
  }
68
68
 
69
- async function generateGemini({ model, system, messages, tools, apiKey, temperature, maxOutputTokens, topP, topK, safetySettings }) {
69
+ async function generateGemini({ model, system, messages, tools, apiKey, temperature, maxOutputTokens, topP, topK, safetySettings, responseModalities }) {
70
70
  const client = getClient(apiKey);
71
71
  const modelId = extractModelId(model);
72
72
  let contents = convertMessages(messages);
73
- const { config } = buildConfig({ system, tools, temperature, maxOutputTokens, topP, topK, safetySettings });
73
+ const { config } = buildConfig({ system, tools, temperature, maxOutputTokens, topP, topK, safetySettings, responseModalities });
74
74
  while (true) {
75
75
  const response = await withRetry(() => client.models.generateContent({ model: modelId, contents, config }));
76
76
  const candidate = response.candidates?.[0];
package/lib/convert.js CHANGED
@@ -69,7 +69,7 @@ function extractModelId(model) {
69
69
  return 'gemini-2.0-flash';
70
70
  }
71
71
 
72
- function buildConfig({ system, tools, temperature, maxOutputTokens, topP, topK, safetySettings } = {}) {
72
+ function buildConfig({ system, tools, temperature, maxOutputTokens, topP, topK, safetySettings, responseModalities } = {}) {
73
73
  const geminiTools = convertTools(tools);
74
74
  const config = {
75
75
  maxOutputTokens: maxOutputTokens ?? 8192,
@@ -80,6 +80,7 @@ function buildConfig({ system, tools, temperature, maxOutputTokens, topP, topK,
80
80
  if (system) config.systemInstruction = system;
81
81
  if (geminiTools.length > 0) config.tools = [{ functionDeclarations: geminiTools }];
82
82
  if (safetySettings) config.safetySettings = safetySettings;
83
+ if (responseModalities) config.responseModalities = responseModalities;
83
84
  return { config, geminiTools };
84
85
  }
85
86
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "thebird",
3
- "version": "1.2.1",
3
+ "version": "1.2.3",
4
4
  "description": "Anthropic SDK to Gemini streaming bridge — drop-in proxy that translates Anthropic message format and tool calls to Google Gemini",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",