refactor: Google models go through LiteLLM; the Vertex SDK is gone
Some checks failed
Forgejo Android APK / Root app tests (push) Successful in 49s
Forgejo Docker Build / Root app tests (push) Successful in 58s
Forgejo Android APK / Build signed APK (push) Successful in 2m9s
Forgejo Docker Build / Build Docker image (push) Successful in 12s
Forgejo Docker Build / Deploy to the host (push) Failing after 0s
Some checks failed
Forgejo Android APK / Root app tests (push) Successful in 49s
Forgejo Docker Build / Root app tests (push) Successful in 58s
Forgejo Android APK / Build signed APK (push) Successful in 2m9s
Forgejo Docker Build / Build Docker image (push) Successful in 12s
Forgejo Docker Build / Deploy to the host (push) Failing after 0s
npm audit reports 0 vulnerabilities. It reported 2 high and 2 moderate this
morning.
@google-cloud/vertexai was the last source of findings — gaxios and a uuid with
a missing buffer bounds check, neither reachable in this deployment because
GOOGLE_VERTEX_PROJECT is unset and the require sits inside that check. Dormant
is not the same as gone, and the provider is available through the gateway
anyway, so the direct path has been removed rather than left to rot:
- the SDK client and callVertex, which without the package could never run
- the dispatch and discovery branches that reached them
- VERTEX_MODELS, a list of ids nothing could route any more, and the two
places in adminConfig that concatenated it into the built-in set
- the health endpoint's vertex line, and the env vars documented for it
AI_PROVIDER=vertex now says where to configure the model instead of quietly
becoming something else. The Google STT and TTS paths keyed off the same
variable are untouched; neither ever used this SDK.
Verified after deploy: provider litellm, the assistant answers with 8 sources,
/api/models returns 10, and @aws-sdk/s3-request-presigner — which documents.js
needs for presigned MinIO URLs — is still declared and resolvable.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Dv6sqaY6Vq3ChZHMem3cnU
This commit is contained in:
parent
689e9bc6c7
commit
1d031af5d6
9 changed files with 23 additions and 626 deletions
|
|
@ -39,8 +39,9 @@ OPENROUTER_API_KEY=sk-or-v1-your-key
|
|||
|
||||
# Option 4: Google Vertex AI (HIPAA compliant with BAA)
|
||||
# AI_PROVIDER=vertex
|
||||
# GOOGLE_VERTEX_PROJECT=your-gcp-project-id
|
||||
# GOOGLE_VERTEX_LOCATION=us-central1
|
||||
# Google models (Gemini and friends) are reached through LiteLLM, not the
|
||||
# Google SDK — that dependency was removed. Configure them on the gateway
|
||||
# and select them by their LiteLLM model id.
|
||||
# GOOGLE_APPLICATION_CREDENTIALS=/path/to/service-account.json
|
||||
# (Or use default credentials if running on GCE/GKE/Cloud Run)
|
||||
#
|
||||
|
|
|
|||
481
package-lock.json
generated
481
package-lock.json
generated
|
|
@ -55,8 +55,7 @@
|
|||
"@aws-sdk/client-bedrock-runtime": "^3.700.0",
|
||||
"@aws-sdk/client-s3": "^3.700.0",
|
||||
"@aws-sdk/client-transcribe-streaming": "^3.1017.0",
|
||||
"@aws-sdk/s3-request-presigner": "^3.700.0",
|
||||
"@google-cloud/vertexai": "^1.9.0"
|
||||
"@aws-sdk/s3-request-presigner": "^3.700.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@asamuzakjp/css-color": {
|
||||
|
|
@ -1577,131 +1576,6 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@google-cloud/vertexai": {
|
||||
"version": "1.10.3",
|
||||
"resolved": "https://registry.npmjs.org/@google-cloud/vertexai/-/vertexai-1.10.3.tgz",
|
||||
"integrity": "sha512-YcEaYPyUVVRz4adNiR4jQQeq/XSOUwH6SERL7NGdZlCXKY+7BofFQpcd71HgdSkzTgERcVQ3TZquNwXNqlTQXQ==",
|
||||
"license": "Apache-2.0",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"@google/genai": "^1.45.0",
|
||||
"google-auth-library": "^9.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@google/genai": {
|
||||
"version": "1.47.0",
|
||||
"resolved": "https://registry.npmjs.org/@google/genai/-/genai-1.47.0.tgz",
|
||||
"integrity": "sha512-0VV7AaXm5rQu3oRHNZNEubRAOL2lv5u+YA72eWnDwcOx3B1jFRbvtgL4drRHlocRHOnludvr3xmbQGbR+/RQAQ==",
|
||||
"license": "Apache-2.0",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"google-auth-library": "^10.3.0",
|
||||
"p-retry": "^4.6.2",
|
||||
"protobufjs": "^7.5.4",
|
||||
"ws": "^8.18.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@modelcontextprotocol/sdk": "^1.25.2"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@modelcontextprotocol/sdk": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@google/genai/node_modules/data-uri-to-buffer": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz",
|
||||
"integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==",
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"engines": {
|
||||
"node": ">= 12"
|
||||
}
|
||||
},
|
||||
"node_modules/@google/genai/node_modules/gaxios": {
|
||||
"version": "7.1.4",
|
||||
"resolved": "https://registry.npmjs.org/gaxios/-/gaxios-7.1.4.tgz",
|
||||
"integrity": "sha512-bTIgTsM2bWn3XklZISBTQX7ZSddGW+IO3bMdGaemHZ3tbqExMENHLx6kKZ/KlejgrMtj8q7wBItt51yegqalrA==",
|
||||
"license": "Apache-2.0",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"extend": "^3.0.2",
|
||||
"https-proxy-agent": "^7.0.1",
|
||||
"node-fetch": "^3.3.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@google/genai/node_modules/gcp-metadata": {
|
||||
"version": "8.1.2",
|
||||
"resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-8.1.2.tgz",
|
||||
"integrity": "sha512-zV/5HKTfCeKWnxG0Dmrw51hEWFGfcF2xiXqcA3+J90WDuP0SvoiSO5ORvcBsifmx/FoIjgQN3oNOGaQ5PhLFkg==",
|
||||
"license": "Apache-2.0",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"gaxios": "^7.0.0",
|
||||
"google-logging-utils": "^1.0.0",
|
||||
"json-bigint": "^1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@google/genai/node_modules/google-auth-library": {
|
||||
"version": "10.6.2",
|
||||
"resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-10.6.2.tgz",
|
||||
"integrity": "sha512-e27Z6EThmVNNvtYASwQxose/G57rkRuaRbQyxM2bvYLLX/GqWZ5chWq2EBoUchJbCc57eC9ArzO5wMsEmWftCw==",
|
||||
"license": "Apache-2.0",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"base64-js": "^1.3.0",
|
||||
"ecdsa-sig-formatter": "^1.0.11",
|
||||
"gaxios": "^7.1.4",
|
||||
"gcp-metadata": "8.1.2",
|
||||
"google-logging-utils": "1.1.3",
|
||||
"jws": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@google/genai/node_modules/google-logging-utils": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/google-logging-utils/-/google-logging-utils-1.1.3.tgz",
|
||||
"integrity": "sha512-eAmLkjDjAFCVXg7A1unxHsLf961m6y17QFqXqAXGj/gVkKFrEICfStRfwUlGNfeCEjNRa32JEWOUTlYXPyyKvA==",
|
||||
"license": "Apache-2.0",
|
||||
"optional": true,
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
}
|
||||
},
|
||||
"node_modules/@google/genai/node_modules/node-fetch": {
|
||||
"version": "3.3.2",
|
||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz",
|
||||
"integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==",
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"data-uri-to-buffer": "^4.0.0",
|
||||
"fetch-blob": "^3.1.4",
|
||||
"formdata-polyfill": "^4.0.10"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/node-fetch"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/colour": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@img/colour/-/colour-1.1.0.tgz",
|
||||
|
|
@ -2308,72 +2182,6 @@
|
|||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/@protobufjs/aspromise": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz",
|
||||
"integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==",
|
||||
"license": "BSD-3-Clause",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/@protobufjs/base64": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz",
|
||||
"integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==",
|
||||
"license": "BSD-3-Clause",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/@protobufjs/codegen": {
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.5.tgz",
|
||||
"integrity": "sha512-zgXFLzW3Ap33e6d0Wlj4MGIm6Ce8O89n/apUaGNB/jx+hw+ruWEp7EwGUshdLKVRCxZW12fp9r40E1mQrf/34g==",
|
||||
"license": "BSD-3-Clause",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/@protobufjs/eventemitter": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.1.tgz",
|
||||
"integrity": "sha512-vW1GmwMZNnL+gMRaovlh9yZX74kc+TTU3FObkkurpMaRtBfLP3ldjS9KQWlwZgraRE0+dheEEoAxdzcJQ8eXZg==",
|
||||
"license": "BSD-3-Clause",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/@protobufjs/fetch": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.1.tgz",
|
||||
"integrity": "sha512-GpptLrs57adMSuHi3VNj0mAF8dwh36LMaYF6XyJ6JMWlVsc+t42tm1HSEDmOs3A8fC9yyeisgLhsTVQokOZ0zw==",
|
||||
"license": "BSD-3-Clause",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"@protobufjs/aspromise": "^1.1.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@protobufjs/float": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz",
|
||||
"integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==",
|
||||
"license": "BSD-3-Clause",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/@protobufjs/path": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz",
|
||||
"integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==",
|
||||
"license": "BSD-3-Clause",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/@protobufjs/pool": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz",
|
||||
"integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==",
|
||||
"license": "BSD-3-Clause",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/@protobufjs/utf8": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.2.tgz",
|
||||
"integrity": "sha512-b1UQwcEZ4yCnMCD8DAL1VlbvBJE9/IX4FTIp7BG1xYpf29SLazLSrqUkj4w7Y5y7cCVP6E5tcqqcI0xemPkHug==",
|
||||
"license": "BSD-3-Clause",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/@redis/bloom": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@redis/bloom/-/bloom-1.2.0.tgz",
|
||||
|
|
@ -3644,13 +3452,6 @@
|
|||
"form-data": "^4.0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/retry": {
|
||||
"version": "0.12.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz",
|
||||
"integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==",
|
||||
"license": "MIT",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/@types/trusted-types": {
|
||||
"version": "2.0.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz",
|
||||
|
|
@ -3692,16 +3493,6 @@
|
|||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/agent-base": {
|
||||
"version": "7.1.4",
|
||||
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz",
|
||||
"integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==",
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"engines": {
|
||||
"node": ">= 14"
|
||||
}
|
||||
},
|
||||
"node_modules/agentkeepalive": {
|
||||
"version": "4.6.0",
|
||||
"resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.6.0.tgz",
|
||||
|
|
@ -3897,16 +3688,6 @@
|
|||
"require-from-string": "^2.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/bignumber.js": {
|
||||
"version": "9.3.1",
|
||||
"resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.3.1.tgz",
|
||||
"integrity": "sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==",
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"engines": {
|
||||
"node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/bintrees": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/bintrees/-/bintrees-1.0.2.tgz",
|
||||
|
|
@ -4616,47 +4397,6 @@
|
|||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/extend": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
|
||||
"integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
|
||||
"license": "MIT",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/fetch-blob": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz",
|
||||
"integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/jimmywarting"
|
||||
},
|
||||
{
|
||||
"type": "paypal",
|
||||
"url": "https://paypal.me/jimmywarting"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"node-domexception": "^1.0.0",
|
||||
"web-streams-polyfill": "^3.0.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^12.20 || >= 14.13"
|
||||
}
|
||||
},
|
||||
"node_modules/fetch-blob/node_modules/web-streams-polyfill": {
|
||||
"version": "3.3.3",
|
||||
"resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz",
|
||||
"integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==",
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"engines": {
|
||||
"node": ">= 8"
|
||||
}
|
||||
},
|
||||
"node_modules/finalhandler": {
|
||||
"version": "1.3.2",
|
||||
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.2.tgz",
|
||||
|
|
@ -4759,19 +4499,6 @@
|
|||
"node": ">= 12.20"
|
||||
}
|
||||
},
|
||||
"node_modules/formdata-polyfill": {
|
||||
"version": "4.0.10",
|
||||
"resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz",
|
||||
"integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==",
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"fetch-blob": "^3.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12.20.0"
|
||||
}
|
||||
},
|
||||
"node_modules/forwarded": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
|
||||
|
|
@ -4799,38 +4526,6 @@
|
|||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/gaxios": {
|
||||
"version": "6.7.1",
|
||||
"resolved": "https://registry.npmjs.org/gaxios/-/gaxios-6.7.1.tgz",
|
||||
"integrity": "sha512-LDODD4TMYx7XXdpwxAVRAIAuB0bzv0s+ywFonY46k126qzQHT9ygyoa9tncmOiQmmDrik65UYsEkv3lbfqQ3yQ==",
|
||||
"license": "Apache-2.0",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"extend": "^3.0.2",
|
||||
"https-proxy-agent": "^7.0.1",
|
||||
"is-stream": "^2.0.0",
|
||||
"node-fetch": "^2.6.9",
|
||||
"uuid": "^9.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
}
|
||||
},
|
||||
"node_modules/gcp-metadata": {
|
||||
"version": "6.1.1",
|
||||
"resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-6.1.1.tgz",
|
||||
"integrity": "sha512-a4tiq7E0/5fTjxPAaH4jpjkSv/uCaU2p5KC6HVGrvl0cDjA8iBZv4vv1gyzlmK0ZUKqwpOyQMKzZQe3lTit77A==",
|
||||
"license": "Apache-2.0",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"gaxios": "^6.1.1",
|
||||
"google-logging-utils": "^0.0.2",
|
||||
"json-bigint": "^1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
}
|
||||
},
|
||||
"node_modules/generic-pool": {
|
||||
"version": "3.9.0",
|
||||
"resolved": "https://registry.npmjs.org/generic-pool/-/generic-pool-3.9.0.tgz",
|
||||
|
|
@ -4910,34 +4605,6 @@
|
|||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/google-auth-library": {
|
||||
"version": "9.15.1",
|
||||
"resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.15.1.tgz",
|
||||
"integrity": "sha512-Jb6Z0+nvECVz+2lzSMt9u98UsoakXxA2HGHMCxh+so3n90XgYWkq5dur19JAJV7ONiJY22yBTyJB1TSkvPq9Ng==",
|
||||
"license": "Apache-2.0",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"base64-js": "^1.3.0",
|
||||
"ecdsa-sig-formatter": "^1.0.11",
|
||||
"gaxios": "^6.1.1",
|
||||
"gcp-metadata": "^6.1.0",
|
||||
"gtoken": "^7.0.0",
|
||||
"jws": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
}
|
||||
},
|
||||
"node_modules/google-logging-utils": {
|
||||
"version": "0.0.2",
|
||||
"resolved": "https://registry.npmjs.org/google-logging-utils/-/google-logging-utils-0.0.2.tgz",
|
||||
"integrity": "sha512-NEgUnEcBiP5HrPzufUkBzJOD/Sxsco3rLNo1F1TNf7ieU8ryUzBhqba8r756CjLX7rn3fHl6iLEwPYuqpoKgQQ==",
|
||||
"license": "Apache-2.0",
|
||||
"optional": true,
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
}
|
||||
},
|
||||
"node_modules/gopd": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
|
||||
|
|
@ -4950,20 +4617,6 @@
|
|||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/gtoken": {
|
||||
"version": "7.1.0",
|
||||
"resolved": "https://registry.npmjs.org/gtoken/-/gtoken-7.1.0.tgz",
|
||||
"integrity": "sha512-pCcEwRi+TKpMlxAQObHDQ56KawURgyAf6jtIY046fJ5tIv3zDe/LEIubckAO8fj6JnAxLdmWkUfNyulQ2iKdEw==",
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"gaxios": "^6.0.0",
|
||||
"jws": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/has-symbols": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
|
||||
|
|
@ -5054,45 +4707,6 @@
|
|||
"url": "https://opencollective.com/express"
|
||||
}
|
||||
},
|
||||
"node_modules/https-proxy-agent": {
|
||||
"version": "7.0.6",
|
||||
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz",
|
||||
"integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==",
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"agent-base": "^7.1.2",
|
||||
"debug": "4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 14"
|
||||
}
|
||||
},
|
||||
"node_modules/https-proxy-agent/node_modules/debug": {
|
||||
"version": "4.4.3",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
|
||||
"integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"ms": "^2.1.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"supports-color": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/https-proxy-agent/node_modules/ms": {
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
|
||||
"license": "MIT",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/humanize-ms": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz",
|
||||
|
|
@ -5151,19 +4765,6 @@
|
|||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/is-stream": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
|
||||
"integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/isarray": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
|
||||
|
|
@ -5311,16 +4912,6 @@
|
|||
"node": "^20.19.0 || ^22.12.0 || >=24.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/json-bigint": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz",
|
||||
"integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==",
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"bignumber.js": "^9.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/jsonwebtoken": {
|
||||
"version": "9.0.3",
|
||||
"resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.3.tgz",
|
||||
|
|
@ -5492,13 +5083,6 @@
|
|||
"integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/long": {
|
||||
"version": "5.3.2",
|
||||
"resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz",
|
||||
"integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==",
|
||||
"license": "Apache-2.0",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/lop": {
|
||||
"version": "0.4.2",
|
||||
"resolved": "https://registry.npmjs.org/lop/-/lop-0.4.2.tgz",
|
||||
|
|
@ -6094,20 +5678,6 @@
|
|||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/p-retry": {
|
||||
"version": "4.6.2",
|
||||
"resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz",
|
||||
"integrity": "sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==",
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"@types/retry": "0.12.0",
|
||||
"retry": "^0.13.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/p-try": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
|
||||
|
|
@ -6619,30 +6189,6 @@
|
|||
"prosemirror-transform": "^1.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/protobufjs": {
|
||||
"version": "7.6.6",
|
||||
"resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.6.6.tgz",
|
||||
"integrity": "sha512-dYDWdjSl5RNb7SgPxGQcRU+GtvP7s2fpkrY0r432PcOIaZ0/rBcxEZnQN67iJhFuQiVw754JDoPruPCNdGsbjg==",
|
||||
"hasInstallScript": true,
|
||||
"license": "BSD-3-Clause",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"@protobufjs/aspromise": "^1.1.2",
|
||||
"@protobufjs/base64": "^1.1.2",
|
||||
"@protobufjs/codegen": "^2.0.5",
|
||||
"@protobufjs/eventemitter": "^1.1.1",
|
||||
"@protobufjs/fetch": "^1.1.1",
|
||||
"@protobufjs/float": "^1.0.2",
|
||||
"@protobufjs/path": "^1.1.2",
|
||||
"@protobufjs/pool": "^1.1.0",
|
||||
"@protobufjs/utf8": "^1.1.1",
|
||||
"@types/node": ">=13.7.0",
|
||||
"long": "^5.3.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/proxy-addr": {
|
||||
"version": "2.0.7",
|
||||
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
|
||||
|
|
@ -6779,16 +6325,6 @@
|
|||
"integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/retry": {
|
||||
"version": "0.13.1",
|
||||
"resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz",
|
||||
"integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==",
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"engines": {
|
||||
"node": ">= 4"
|
||||
}
|
||||
},
|
||||
"node_modules/rope-sequence": {
|
||||
"version": "1.3.4",
|
||||
"resolved": "https://registry.npmjs.org/rope-sequence/-/rope-sequence-1.3.4.tgz",
|
||||
|
|
@ -7322,20 +6858,6 @@
|
|||
"node": ">= 0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/uuid": {
|
||||
"version": "9.0.1",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz",
|
||||
"integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==",
|
||||
"funding": [
|
||||
"https://github.com/sponsors/broofa",
|
||||
"https://github.com/sponsors/ctavan"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"bin": {
|
||||
"uuid": "dist/bin/uuid"
|
||||
}
|
||||
},
|
||||
"node_modules/vary": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
|
||||
|
|
@ -7446,6 +6968,7 @@
|
|||
"integrity": "sha512-201TZ/kPWxoPr/OKWjquZR1SWKXcvxdH+e1xrx89b3YbmzLMFCLfnaG1HFIgWzJOEWZ7MvpK++odZufgYR50Rw==",
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=10.0.0"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -57,8 +57,7 @@
|
|||
"@aws-sdk/client-bedrock-runtime": "^3.700.0",
|
||||
"@aws-sdk/client-s3": "^3.700.0",
|
||||
"@aws-sdk/client-transcribe-streaming": "^3.1017.0",
|
||||
"@aws-sdk/s3-request-presigner": "^3.700.0",
|
||||
"@google-cloud/vertexai": "^1.9.0"
|
||||
"@aws-sdk/s3-request-presigner": "^3.700.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"jsdom": "^29.0.2"
|
||||
|
|
|
|||
|
|
@ -290,7 +290,6 @@ app.get('/api/health/detailed', _hcAuth, _hcAdmin, (req, res) => {
|
|||
openrouter: process.env.OPENROUTER_API_KEY ? 'configured' : 'missing',
|
||||
bedrock: process.env.AWS_BEDROCK_REGION ? 'configured' : 'not configured',
|
||||
azure: process.env.AZURE_OPENAI_ENDPOINT ? 'configured' : 'not configured',
|
||||
vertex: process.env.GOOGLE_VERTEX_PROJECT ? 'configured' : 'not configured',
|
||||
litellm: process.env.LITELLM_API_BASE ? 'configured' : 'not configured',
|
||||
whisper: process.env.OPENAI_API_KEY ? 'configured' : 'missing',
|
||||
tts: process.env.LITELLM_API_BASE ? 'litellm' : (process.env.ELEVENLABS_API_KEY ? 'elevenlabs' : 'none')
|
||||
|
|
|
|||
|
|
@ -321,12 +321,11 @@ router.delete('/config/smtp', async function(req, res) {
|
|||
// ── GET models config ────────────────────────────────────────────────────
|
||||
router.get('/config/models', async function(req, res) {
|
||||
try {
|
||||
var { OPENROUTER_MODELS, BEDROCK_MODELS, AZURE_MODELS, VERTEX_MODELS, activeProvider } = require('../utils/models');
|
||||
var { OPENROUTER_MODELS, BEDROCK_MODELS, AZURE_MODELS, activeProvider } = require('../utils/models');
|
||||
var providerModels;
|
||||
switch (activeProvider) {
|
||||
case 'bedrock': providerModels = BEDROCK_MODELS; break;
|
||||
case 'azure': providerModels = AZURE_MODELS; break;
|
||||
case 'vertex': providerModels = VERTEX_MODELS; break;
|
||||
case 'litellm': providerModels = []; break; // LiteLLM: no built-ins — use discover
|
||||
default: providerModels = OPENROUTER_MODELS;
|
||||
}
|
||||
|
|
@ -409,8 +408,8 @@ router.post('/config/models/custom', async function(req, res) {
|
|||
}
|
||||
|
||||
// Check if model ID conflicts with a built-in model (all providers)
|
||||
var { OPENROUTER_MODELS, BEDROCK_MODELS, AZURE_MODELS, VERTEX_MODELS } = require('../utils/models');
|
||||
var allBuiltIn = [].concat(OPENROUTER_MODELS, BEDROCK_MODELS, AZURE_MODELS, VERTEX_MODELS);
|
||||
var { OPENROUTER_MODELS, BEDROCK_MODELS, AZURE_MODELS } = require('../utils/models');
|
||||
var allBuiltIn = [].concat(OPENROUTER_MODELS, BEDROCK_MODELS, AZURE_MODELS);
|
||||
if (allBuiltIn.find(function(m) { return m.id === trimmedId; })) {
|
||||
return res.status(400).json({ error: 'Model ID conflicts with a built-in model. Use the toggle to enable/disable built-in models.' });
|
||||
}
|
||||
|
|
|
|||
|
|
@ -72,25 +72,6 @@ if (process.env.AZURE_OPENAI_ENDPOINT) {
|
|||
}
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// GOOGLE VERTEX AI CLIENT (optional, HIPAA compliant with BAA)
|
||||
// ============================================================
|
||||
var vertexClient = null;
|
||||
if (process.env.GOOGLE_VERTEX_PROJECT) {
|
||||
try {
|
||||
var VertexAI = require('@google-cloud/vertexai');
|
||||
vertexClient = new VertexAI.VertexAI({
|
||||
project: process.env.GOOGLE_VERTEX_PROJECT,
|
||||
location: process.env.GOOGLE_VERTEX_LOCATION || 'us-central1'
|
||||
});
|
||||
activeProvider = 'vertex';
|
||||
console.log('✅ Google Vertex AI: configured (project: ' + process.env.GOOGLE_VERTEX_PROJECT + ', location: ' + (process.env.GOOGLE_VERTEX_LOCATION || 'us-central1') + ')');
|
||||
} catch (e) {
|
||||
console.log('⚠️ Google Vertex AI: SDK not installed. Install with: npm install @google-cloud/vertexai');
|
||||
console.log('⚠️ Falling back to OpenRouter');
|
||||
activeProvider = 'openrouter';
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// LITELLM CLIENT (optional — OpenAI-compatible proxy)
|
||||
|
|
@ -125,8 +106,12 @@ if (activeProvider === 'azure' && !azureClient) {
|
|||
console.log('⚠️ Azure selected but not available. Falling back to OpenRouter.');
|
||||
activeProvider = 'openrouter';
|
||||
}
|
||||
if (activeProvider === 'vertex' && !vertexClient) {
|
||||
console.log('⚠️ Vertex AI selected but not available. Falling back to OpenRouter.');
|
||||
// Vertex is reached through LiteLLM now, not through the Google SDK, which was
|
||||
// removed along with the two advisories it carried. AI_PROVIDER=vertex is
|
||||
// therefore not a thing this app can be; point the operator at the gateway
|
||||
// rather than silently doing something else.
|
||||
if (activeProvider === 'vertex') {
|
||||
console.log('⚠️ AI_PROVIDER=vertex is no longer supported directly. Configure the model through LiteLLM instead. Falling back to OpenRouter.');
|
||||
activeProvider = 'openrouter';
|
||||
}
|
||||
if (activeProvider === 'litellm' && !litellmClient) {
|
||||
|
|
@ -367,66 +352,6 @@ async function callBedrock(messages, model, temperature, maxTokens) {
|
|||
}
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// CALL GOOGLE VERTEX AI
|
||||
// Uses the Gemini generateContent API
|
||||
// ============================================================
|
||||
async function callVertex(messages, model, temperature, maxTokens) {
|
||||
if (!vertexClient) throw new Error('Google Vertex AI not configured');
|
||||
|
||||
// Map model ID to Vertex model name
|
||||
var { getVertexModelId } = require('./models');
|
||||
var vertexModelId = getVertexModelId(model);
|
||||
|
||||
var generativeModel = vertexClient.getGenerativeModel({
|
||||
model: vertexModelId,
|
||||
generationConfig: {
|
||||
temperature: temperature,
|
||||
maxOutputTokens: maxTokens,
|
||||
},
|
||||
});
|
||||
|
||||
// Convert OpenAI-style messages to Vertex AI format
|
||||
var systemInstruction = '';
|
||||
var contents = [];
|
||||
messages.forEach(function(m) {
|
||||
if (m.role === 'system') {
|
||||
systemInstruction += (systemInstruction ? '\n' : '') + m.content;
|
||||
} else {
|
||||
contents.push({
|
||||
role: m.role === 'assistant' ? 'model' : 'user',
|
||||
parts: [{ text: m.content }]
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
var request = { contents: contents };
|
||||
if (systemInstruction) {
|
||||
request.systemInstruction = { parts: [{ text: systemInstruction }] };
|
||||
}
|
||||
|
||||
var result = await generativeModel.generateContent(request);
|
||||
var response = result.response;
|
||||
|
||||
var textContent = '';
|
||||
if (response.candidates && response.candidates[0] && response.candidates[0].content) {
|
||||
response.candidates[0].content.parts.forEach(function(part) {
|
||||
if (part.text) textContent += part.text;
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
content: textContent,
|
||||
finishReason: normalizeFinishReason(response.candidates && response.candidates[0] && response.candidates[0].finishReason),
|
||||
model: vertexModelId,
|
||||
provider: 'vertex',
|
||||
usage: response.usageMetadata ? {
|
||||
prompt_tokens: response.usageMetadata.promptTokenCount || 0,
|
||||
completion_tokens: response.usageMetadata.candidatesTokenCount || 0
|
||||
} : null
|
||||
};
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// CALL LITELLM (OpenAI-compatible proxy)
|
||||
|
|
@ -570,8 +495,6 @@ async function callAI(messages, options) {
|
|||
result = await callBedrock(messages, model, temperature, maxTokens);
|
||||
} else if (activeProvider === 'azure' && azureClient) {
|
||||
result = await callAzure(messages, model, temperature, maxTokens, generation);
|
||||
} else if (activeProvider === 'vertex' && vertexClient) {
|
||||
result = await callVertex(messages, model, temperature, maxTokens);
|
||||
} else if (activeProvider === 'litellm' && litellmClient) {
|
||||
result = await callLiteLLM(messages, model, temperature, maxTokens, generation);
|
||||
} else if (openrouter) {
|
||||
|
|
@ -678,13 +601,6 @@ async function discoverModels() {
|
|||
}
|
||||
}
|
||||
|
||||
if (activeProvider === 'vertex' && vertexClient) {
|
||||
// Vertex AI doesn't have a simple list API, return known Gemini models
|
||||
var { VERTEX_MODELS } = require('./models');
|
||||
VERTEX_MODELS.forEach(function(m) {
|
||||
discovered.push(Object.assign({}, m, { source: 'vertex-builtin' }));
|
||||
});
|
||||
}
|
||||
|
||||
if (activeProvider === 'openrouter' && openrouter) {
|
||||
try {
|
||||
|
|
@ -766,4 +682,4 @@ async function discoverModels() {
|
|||
return discovered;
|
||||
}
|
||||
|
||||
module.exports = { callAI, callAIStream, activeProvider, discoverModels, vertexClient, litellmClient, applyImageAttachments };
|
||||
module.exports = { callAI, callAIStream, activeProvider, discoverModels, litellmClient, applyImageAttachments };
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
// ============================================================
|
||||
// MODELS.JS — Provider-aware model list
|
||||
// Supports: OpenRouter, AWS Bedrock, Azure OpenAI, Google Vertex AI, LiteLLM
|
||||
// Supports: OpenRouter, AWS Bedrock, Azure OpenAI, LiteLLM.
|
||||
// Vertex and anything else Google is reached through LiteLLM, not directly.
|
||||
// ============================================================
|
||||
|
||||
var activeProvider = process.env.AI_PROVIDER || (process.env.LITELLM_API_BASE ? 'litellm' : 'openrouter');
|
||||
|
|
@ -88,27 +89,6 @@ var AZURE_MODELS = [
|
|||
deploymentNote: 'Set AZURE_DEPLOYMENT_NAME in .env' }
|
||||
];
|
||||
|
||||
// ============================================================
|
||||
// GOOGLE VERTEX AI MODELS
|
||||
// vertexId = the model name used in Vertex AI API calls
|
||||
// ============================================================
|
||||
var VERTEX_MODELS = [
|
||||
{ id: 'gemini-2.5-flash', name: 'Gemini 2.5 Flash',
|
||||
vertexId: 'gemini-2.5-flash-preview-05-20' },
|
||||
{ id: 'gemini-2.5-pro', name: 'Gemini 2.5 Pro',
|
||||
vertexId: 'gemini-2.5-pro-preview-05-06' },
|
||||
{ id: 'gemini-2.0-flash', name: 'Gemini 2.0 Flash',
|
||||
vertexId: 'gemini-2.0-flash' },
|
||||
{ id: 'gemini-2.0-flash-lite', name: 'Gemini 2.0 Flash Lite',
|
||||
vertexId: 'gemini-2.0-flash-lite' },
|
||||
{ id: 'gemini-1.5-pro', name: 'Gemini 1.5 Pro',
|
||||
vertexId: 'gemini-1.5-pro-002' },
|
||||
{ id: 'gemini-1.5-flash', name: 'Gemini 1.5 Flash',
|
||||
vertexId: 'gemini-1.5-flash-002' },
|
||||
{ id: 'llama-3.1-405b@vertex', name: 'Llama 3.1 405B (Vertex)',
|
||||
vertexId: 'meta/llama-3.1-405b-instruct-maas' },
|
||||
];
|
||||
|
||||
// LiteLLM has NO built-in models — everything is discovered from the proxy via admin panel.
|
||||
// This array is intentionally empty. Do not add models here.
|
||||
var LITELLM_MODELS = [];
|
||||
|
|
@ -121,7 +101,6 @@ function getAvailableModels() {
|
|||
return !m.regions || m.regions.indexOf(region) !== -1;
|
||||
});
|
||||
case 'azure': return AZURE_MODELS;
|
||||
case 'vertex': return VERTEX_MODELS;
|
||||
case 'litellm': return LITELLM_MODELS;
|
||||
case 'openrouter':
|
||||
default: return OPENROUTER_MODELS;
|
||||
|
|
@ -132,7 +111,6 @@ function getDefaultModel() {
|
|||
switch (activeProvider) {
|
||||
case 'bedrock': return 'amazon/nova-pro';
|
||||
case 'azure': return process.env.AZURE_DEPLOYMENT_NAME || 'gpt-4o-mini';
|
||||
case 'vertex': return 'gemini-2.5-flash';
|
||||
case 'litellm': return process.env.LITELLM_DEFAULT_MODEL || process.env.OPENAI_MODEL || ''; // OpenAI-compatible base: set admin default or env.
|
||||
case 'openrouter':
|
||||
default: return 'google/gemini-2.5-flash';
|
||||
|
|
@ -143,7 +121,6 @@ function getFallbackModel() {
|
|||
switch (activeProvider) {
|
||||
case 'bedrock': return 'amazon/nova-lite';
|
||||
case 'azure': return process.env.AZURE_DEPLOYMENT_NAME || 'gpt-4o-mini';
|
||||
case 'vertex': return 'gemini-2.0-flash';
|
||||
case 'litellm': return process.env.LITELLM_FALLBACK_MODEL || ''; // No implicit cross-provider fallback.
|
||||
case 'openrouter':
|
||||
default: return 'deepseek/deepseek-chat-v3-0324';
|
||||
|
|
@ -160,10 +137,6 @@ function getBedrockMaxOut(modelId) {
|
|||
return found && found.maxOut ? found.maxOut : null;
|
||||
}
|
||||
|
||||
function getVertexModelId(modelId) {
|
||||
var found = VERTEX_MODELS.find(function(m) { return m.id === modelId; });
|
||||
return found ? found.vertexId : modelId;
|
||||
}
|
||||
|
||||
var AVAILABLE_MODELS = getAvailableModels();
|
||||
var DEFAULT_MODEL = getDefaultModel();
|
||||
|
|
@ -233,7 +206,6 @@ module.exports = {
|
|||
OPENROUTER_MODELS,
|
||||
BEDROCK_MODELS,
|
||||
AZURE_MODELS,
|
||||
VERTEX_MODELS,
|
||||
LITELLM_MODELS,
|
||||
getAvailableModels,
|
||||
getAvailableModelsWithOverrides,
|
||||
|
|
@ -245,6 +217,5 @@ module.exports = {
|
|||
getFallbackModel,
|
||||
getBedrockModelId,
|
||||
getBedrockMaxOut,
|
||||
getVertexModelId,
|
||||
activeProvider
|
||||
};
|
||||
|
|
|
|||
|
|
@ -233,9 +233,6 @@ test('legacy direct provider adapters refuse image attachments with 400 before c
|
|||
'@aws-sdk/client-bedrock-runtime': {
|
||||
InvokeModelCommand, ConverseCommand,
|
||||
BedrockRuntimeClient: class { async send(command) { sdkCalls.push(command); return { body: Buffer.from('{}') }; } }
|
||||
},
|
||||
'@google-cloud/vertexai': {
|
||||
VertexAI: class { getGenerativeModel() { return { async generateContent(request) { sdkCalls.push(request); return { response: { candidates: [] } }; } }; } }
|
||||
}
|
||||
};
|
||||
const module = { exports: {} };
|
||||
|
|
@ -254,13 +251,16 @@ test('legacy direct provider adapters refuse image attachments with 400 before c
|
|||
await assert.rejects(module.exports.callAIStream(messages, { model: 'anthropic.claude-synthetic', images: [png] }, () => {}), error => error.statusCode === 400);
|
||||
assert.equal(sdkCalls.length, 0, 'refused before any provider contact');
|
||||
|
||||
// AI_PROVIDER=vertex used to select a direct Google SDK adapter. That adapter
|
||||
// and its dependency are gone — Google models are reached through LiteLLM now —
|
||||
// so asking for it must fall back rather than half-configure something.
|
||||
const vertexModule = { exports: {} };
|
||||
vm.runInNewContext(read('src/utils/ai.js'), {
|
||||
module: vertexModule, exports: vertexModule.exports, console: quiet, TextDecoder,
|
||||
process: { env: { AI_PROVIDER: 'vertex', GOOGLE_VERTEX_PROJECT: 'synthetic' } },
|
||||
require(name) { assert.ok(Object.hasOwn(mocks, name), 'Unexpected adapter import: ' + name); return mocks[name]; }
|
||||
});
|
||||
await assert.rejects(vertexModule.exports.callAI(messages, { model: 'google/gemini-2.5-flash', images: [png] }), error => error.statusCode === 400);
|
||||
assert.equal(vertexModule.exports.activeProvider, 'openrouter', 'vertex is no longer selectable');
|
||||
assert.equal(sdkCalls.length, 0);
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -315,16 +315,6 @@ function directAdapter(provider, mode, reason) {
|
|||
return { output: { message: { content: [{ text: 'Synthetic handoff.' }] } }, stopReason: reason };
|
||||
}
|
||||
}
|
||||
},
|
||||
'@google-cloud/vertexai': {
|
||||
VertexAI: class {
|
||||
getGenerativeModel() {
|
||||
return { async generateContent(request) {
|
||||
sdkCalls.push(request);
|
||||
return { response: { candidates: [{ content: { parts: [{ text: 'Synthetic handoff.' }] }, finishReason: reason }] } };
|
||||
} };
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
const module = { exports: {} };
|
||||
|
|
@ -342,8 +332,7 @@ function directAdapter(provider, mode, reason) {
|
|||
test('actual direct AI adapters propagate completion status without any route (fake SDK only)', async () => {
|
||||
for (const [provider, mode, model] of [
|
||||
['bedrock', 'invoke', 'anthropic.claude-synthetic'],
|
||||
['bedrock', 'converse', 'amazon/nova-lite'],
|
||||
['vertex', 'vertex', 'google/gemini-2.5-flash']
|
||||
['bedrock', 'converse', 'amazon/nova-lite']
|
||||
]) {
|
||||
for (const [reason, normalized] of [
|
||||
['max_tokens', 'length'], ['MAX_TOKENS', 'length'],
|
||||
|
|
|
|||
Loading…
Reference in a new issue