thebird 1.2.1
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/.codeinsight +73 -0
- package/.github/workflows/publish.yml +42 -0
- package/README.md +176 -0
- package/examples/basic-chat.js +34 -0
- package/examples/multi-turn.js +45 -0
- package/examples/streaming.js +81 -0
- package/examples/tool-use.js +77 -0
- package/examples/vision.js +84 -0
- package/index.d.ts +98 -0
- package/index.js +173 -0
- package/lib/client.js +10 -0
- package/lib/config.js +24 -0
- package/lib/convert.js +86 -0
- package/lib/errors.js +35 -0
- package/lib/providers/openai.js +127 -0
- package/lib/router.js +51 -0
- package/lib/transformers.js +93 -0
- package/package.json +44 -0
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
function removeCacheControl(obj) {
|
|
2
|
+
if (!obj || typeof obj !== 'object') return obj;
|
|
3
|
+
if (Array.isArray(obj)) return obj.map(removeCacheControl);
|
|
4
|
+
const out = {};
|
|
5
|
+
for (const [k, v] of Object.entries(obj)) {
|
|
6
|
+
if (k === 'cache_control') continue;
|
|
7
|
+
out[k] = removeCacheControl(v);
|
|
8
|
+
}
|
|
9
|
+
return out;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const BUILT_IN = {
|
|
13
|
+
cleancache: {
|
|
14
|
+
request(req) { return { ...req, messages: removeCacheControl(req.messages), system: removeCacheControl(req.system) }; }
|
|
15
|
+
},
|
|
16
|
+
deepseek: {
|
|
17
|
+
request(req) {
|
|
18
|
+
const r = removeCacheControl(req);
|
|
19
|
+
if (r.system && typeof r.system !== 'string') {
|
|
20
|
+
r.system = (Array.isArray(r.system) ? r.system : [r.system]).map(b => b.text || '').join('\n');
|
|
21
|
+
}
|
|
22
|
+
return r;
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
openrouter: {
|
|
26
|
+
options: {},
|
|
27
|
+
request(req, opts) {
|
|
28
|
+
const headers = { 'HTTP-Referer': 'https://github.com/AnEntrypoint/thebird', 'X-Title': 'thebird', ...(opts || {}).headers };
|
|
29
|
+
if ((opts || {}).provider) req = { ...req, provider: (opts || {}).provider };
|
|
30
|
+
return { ...req, _extraHeaders: { ...(req._extraHeaders || {}), ...headers } };
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
maxtoken: {
|
|
34
|
+
request(req, opts) { return { ...req, max_tokens: (opts || {}).max_tokens || req.max_tokens }; }
|
|
35
|
+
},
|
|
36
|
+
tooluse: {
|
|
37
|
+
request(req) {
|
|
38
|
+
if (req.tools && req.tools.length > 0) return { ...req, tool_choice: { type: 'required' } };
|
|
39
|
+
return req;
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
reasoning: {
|
|
43
|
+
request(req) { return req; },
|
|
44
|
+
response(res) {
|
|
45
|
+
if (!res.choices) return res;
|
|
46
|
+
return {
|
|
47
|
+
...res,
|
|
48
|
+
choices: res.choices.map(c => {
|
|
49
|
+
if (!c.message) return c;
|
|
50
|
+
const msg = { ...c.message };
|
|
51
|
+
if (msg.reasoning_content) { msg._reasoning = msg.reasoning_content; delete msg.reasoning_content; }
|
|
52
|
+
return { ...c, message: msg };
|
|
53
|
+
})
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
sampling: {
|
|
58
|
+
request(req) {
|
|
59
|
+
const r = { ...req };
|
|
60
|
+
delete r.top_k;
|
|
61
|
+
delete r.repetition_penalty;
|
|
62
|
+
return r;
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
groq: {
|
|
66
|
+
request(req) {
|
|
67
|
+
const r = { ...req };
|
|
68
|
+
delete r.top_k;
|
|
69
|
+
return r;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
function resolveTransformers(useList, customMap) {
|
|
75
|
+
if (!useList) return [];
|
|
76
|
+
return useList.map(entry => {
|
|
77
|
+
const name = Array.isArray(entry) ? entry[0] : entry;
|
|
78
|
+
const opts = Array.isArray(entry) ? entry[1] : undefined;
|
|
79
|
+
const t = (customMap && customMap[name]) || BUILT_IN[name];
|
|
80
|
+
if (!t) { console.warn('[thebird] unknown transformer:', name); return null; }
|
|
81
|
+
return { transformer: t, opts };
|
|
82
|
+
}).filter(Boolean);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function applyRequestTransformers(req, transformers) {
|
|
86
|
+
return transformers.reduce((r, { transformer, opts }) => transformer.request ? transformer.request(r, opts) : r, req);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function applyResponseTransformers(res, transformers) {
|
|
90
|
+
return transformers.reduce((r, { transformer, opts }) => transformer.response ? transformer.response(r, opts) : r, res);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
module.exports = { resolveTransformers, applyRequestTransformers, applyResponseTransformers, BUILT_IN };
|
package/package.json
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "thebird",
|
|
3
|
+
"version": "1.2.1",
|
|
4
|
+
"description": "Anthropic SDK to Gemini streaming bridge — drop-in proxy that translates Anthropic message format and tool calls to Google Gemini",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"types": "index.d.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"types": "./index.d.ts",
|
|
10
|
+
"require": "./index.js",
|
|
11
|
+
"import": "./index.js",
|
|
12
|
+
"default": "./index.js"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"keywords": [
|
|
16
|
+
"anthropic",
|
|
17
|
+
"gemini",
|
|
18
|
+
"google",
|
|
19
|
+
"ai",
|
|
20
|
+
"streaming",
|
|
21
|
+
"proxy",
|
|
22
|
+
"bridge",
|
|
23
|
+
"tool-use",
|
|
24
|
+
"vision",
|
|
25
|
+
"multimodal",
|
|
26
|
+
"router",
|
|
27
|
+
"openai",
|
|
28
|
+
"deepseek",
|
|
29
|
+
"multi-provider"
|
|
30
|
+
],
|
|
31
|
+
"author": "AnEntrypoint",
|
|
32
|
+
"license": "MIT",
|
|
33
|
+
"repository": {
|
|
34
|
+
"type": "git",
|
|
35
|
+
"url": "https://github.com/AnEntrypoint/thebird.git"
|
|
36
|
+
},
|
|
37
|
+
"dependencies": {
|
|
38
|
+
"@google/genai": "^1.0.0"
|
|
39
|
+
},
|
|
40
|
+
"peerDependencies": {},
|
|
41
|
+
"engines": {
|
|
42
|
+
"node": ">=18"
|
|
43
|
+
}
|
|
44
|
+
}
|