feat: add gemini (ai studio) and gemini enterprise (vertex ai) providers with vertex model-family routing#154
Conversation
|
Flagging overlap with other in-flight Gemini/Vertex PRs to help maintainers coordinate a direction:
All of these touch the same provider/config surface ( |
|
Brace Sproul (@bracesproul) - Thoughts on any of the various GCP/Vertex AI related implementations? |
|
Hey Brad Huffman (@ppsplus-bradh) - love the PR and I gave it a whirl. Native Gemini works through the first tool call, but Gemini 3.1 fails on the next turn because the Reproduced with gemini-3.1-flash-lite, @langchain/google@0.2.1, and OpenWiki’s DeepAgents flow. Switching to gemini-2.5-flash-lite, where signature validation is not strict, works as a temporary workaround for me. |
|
Paul (@avidspartan1) - Taking a look. Thanks! |
|
Reciprocating the cross-reference from your comment above — I took a proper look at #154 from the #179 side: The One thing you may want to fix regardless of how consolidation shakes out: the blank-region default of On consolidation: #179's |
…l calls
Gemini 3.x rejects the next turn of a tool-calling conversation when a
prior functionCall part is missing its thoughtSignature ('Function call
is missing a thought_signature in functionCall parts'). LangChain core's
streaming aggregator (stream.js) unconditionally rebuilds the streamed
message as v1 standard content blocks, which drop that provider-specific
signature; the signature is also not re-emitted by @langchain/google's v1
outbound converter. Either way the next request 400s.
Disable streaming and pin outputVersion to v0 on the Gemini ChatGoogle
clients (native gemini + the gemini-enterprise Gemini surface). This
routes calls through invoke()/generate, which honors v0 and preserves the
raw Gemini content parts (signature intact) that the v0 converter
round-trips correctly. Verified end-to-end against Vertex
gemini-3.1-flash-lite across 5+ tool turns.
Reported by @avidspartan1 on langchain-ai#154.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Paul (@avidspartan1) — fix is in place on this branch (commit Root cause (matches upstream langchain-ai/langchainjs#11181): LangChain core's streaming aggregator ( Fix here: set Verified end-to-end against Vertex This is a workaround pending the upstream streaming fix (langchain-ai/langchainjs#11149 / #10480, both open); once that lands and releases, we can drop |
The blank-region default of us-central1 returns 400 'Model not servable in region' for Anthropic Claude on Vertex. 'global' serves both Gemini and the Claude surface. MaaS partner models remain region-specific, so those users set GOOGLE_CLOUD_LOCATION explicitly. Flagged by @SadriG91 on langchain-ai#154 (also addressed in langchain-ai#179). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
SadriG91 — thanks, this is a great read of how the two PRs fit together, and I agree with the layering. Region: fixed here — the blank-region default is now Env neutralization: confirming #154 already handles the Consolidation — I think a stack beats folding. Per CONTRIBUTING ("one PR = one change"), bundling the generic keyless/project-credential base (
The one wrinkle is that GitHub can't base a PR on a branch in another fork, so a true side-by-side stack needs both branches in one fork. Two ways to do it:
I'm happy to do the hosting for option 1 if you're up for it, or go with option 2 if you'd rather keep #179 as-is — whichever you and the maintainers prefer. Either way I'll rebase the Vertex routing to sit cleanly on your base. WDYT? |
|
Thanks for the quick region fix and for confirming the env-neutralization equivalence — either implementation works for me; whichever PR lands second just drops its copy. On the stack: I'd go with option 2 (sequential). #179 is already rebased onto current main, green, and live-tested, so keeping it as the base PR means zero re-review churn — and reviewers can effectively evaluate the two in parallel today anyway, since your surface-routing commits are cleanly separable from the overlapping base. Once #179 lands I'm glad to help with the rebase of #154 on top if useful. That said, the sequencing question is really Brace Sproul (@bracesproul)'s call — if the maintainers prefer a single stacked series in one fork, I'm fine with option 1 too, with the base commit co-authored as you proposed. |
|
hey Brad Huffman (@ppsplus-bradh) - confirmed the 3.1 fix worked. Thanks! Next issue, may be out of scope of this PR, but thought I'd mention it: Gemini does not currently appear to honor OpenWiki’s provider retry configuration for 429 responses. I reproduced this with
Could the Gemini constructors pass through |
|
and sorry for the delay! |
|
Colin Francis (@colifran) Yes, exactly right — #179 first (the keyless-provider base + Claude on Vertex), then Brad Huffman (@ppsplus-bradh) rebases #154's Gemini + multi-surface routing on top and drops the overlapping base. That's the order we converged on above. #179 is rebased onto today's |
|
#179 has been merged. This one is next on my list once it gets rebased! |
On it. |
|
Colin Francis (@colifran) SadriG91 — thanks for merging #179, and before I push the rebase I want to float one adjustment to the plan we'd converged on, because the ground shifted slightly. The naming. Since we settled on "#179 as the The proposal. Rather than land a second Claude-on-Vertex path next to #179's Concretely, this builds on #179 rather than reverting it — I'd rebase and adopt #179's base where it's cleaner than what #154 has today:
I'd also fold in the fix Paul (@avidspartan1) flagged. The root cause is narrow: The alternative is the lower-touch hybrid: keep I lean toward consolidation for the cleaner end state and the branding alignment, but dropping a provider you merged today is your call — happy to go either way. WDYT? |
|
Brad Huffman (@ppsplus-bradh) love this! great suggestion. let's do it |
f4f3335 to
573c3e4
Compare
…enterprise Add two Google model providers and route the Vertex AI (now Gemini Enterprise) Model Garden through a single provider: - `gemini` (AI Studio): Google's Gemini models via one API key (GEMINI_API_KEY). - `gemini-enterprise` (Vertex AI): keyless, ADC-authenticated provider that routes each model ID to the right Model Garden surface — native Gemini/Gemma over generateContent, Claude over the Anthropic Vertex SDK, and partner/open-weight models over the OpenAI-compatible MaaS endpoint (resolveVertexSurface / createGeminiEnterpriseModel). This supersedes the discrete `vertex` (Claude-only) provider added in langchain-ai#179: `gemini-enterprise` reaches Claude on Vertex through the same AnthropicVertex construction and ANTHROPIC_API_KEY/ANTHROPIC_AUTH_TOKEN env-neutralization, plus publisher-path stripping, so no capability is lost. The rename tracks Google's Cloud Next 2026 rebrand of Vertex AI to the Gemini Enterprise Agent Platform while keeping the unchanged underlying API surface. Builds on langchain-ai#179's keyless-provider plumbing (projectEnvKey/locationEnvKey/ defaultLocation, getMissingProviderEnvKey, resolveProviderLocation, getProviderCredentialHint) and its gcp-project/gcp-location onboarding steps, which gemini-enterprise inherits — dropping langchain-ai#154's earlier approach of overloading apiKeyEnvKey to carry the non-secret GOOGLE_CLOUD_PROJECT. Gemini uses disableStreaming + outputVersion "v0" to preserve Gemini 3.x thought signatures across multi-turn tool calls (see the comment in createGeminiEnterpriseModel). Co-Authored-By: Claude <noreply@anthropic.com>
createModel now spreads ...retryOptions into every Gemini surface (the AI Studio ChatGoogle and all three gemini-enterprise clients), which previously omitted it — so OPENWIKI_PROVIDER_RETRY_ATTEMPTS was silently ignored and a 429 failed fast instead of backing off (reported by @avidspartan1 on langchain-ai#154). maxRetries is not a readable property on the constructed LangChain models, so this asserts it via vi.mock capturing each constructor's options. Once maxRetries is wired through, @langchain/core's AsyncCaller already honors a server-provided Retry-After (up to 60s), so the existing backoff engages. Co-Authored-By: Claude <noreply@anthropic.com>
|
Rebased onto latest Colin Francis (@colifran) — heads up: this force-push replaced your What's in the two commits:
Verification: One open question for reviewers: I kept the onboarding prompt wording as "Vertex AI access / Vertex AI location" since that's still what the GCP console and IAM roles ( |
|
Brad Huffman (@ppsplus-bradh) nice touch the consolidation under gemini-enterprise is a clean way forward. |
|
Running some reviews. Identified a gap on the MaaS path. Fix forthcoming. |
…enterprise Add two Google model providers and route the Vertex AI (now Gemini Enterprise) Model Garden through a single provider: - `gemini` (AI Studio): Google's Gemini models via one API key (GEMINI_API_KEY). - `gemini-enterprise` (Vertex AI): keyless, ADC-authenticated provider that routes each model ID to the right Model Garden surface — native Gemini/Gemma over generateContent, Claude over the Anthropic Vertex SDK, and partner/open-weight models over the OpenAI-compatible MaaS endpoint (resolveVertexSurface / createGeminiEnterpriseModel). This supersedes the discrete `vertex` (Claude-only) provider added in langchain-ai#179: `gemini-enterprise` reaches Claude on Vertex through the same AnthropicVertex construction and ANTHROPIC_API_KEY/ANTHROPIC_AUTH_TOKEN env-neutralization, plus publisher-path stripping, so no capability is lost. The rename tracks Google's Cloud Next 2026 rebrand of Vertex AI to the Gemini Enterprise Agent Platform while keeping the unchanged underlying API surface. Builds on langchain-ai#179's keyless-provider plumbing (projectEnvKey/locationEnvKey/ defaultLocation, getMissingProviderEnvKey, resolveProviderLocation, getProviderCredentialHint) and its gcp-project/gcp-location onboarding steps, which gemini-enterprise inherits — dropping langchain-ai#154's earlier approach of overloading apiKeyEnvKey to carry the non-secret GOOGLE_CLOUD_PROJECT. Gemini uses disableStreaming + outputVersion "v0" to preserve Gemini 3.x thought signatures across multi-turn tool calls (shared GEMINI_THOUGHT_SIGNATURE_OPTIONS across both ChatGoogle surfaces). The MaaS endpoint and the Gemini surface both special-case the `global` location: MaaS uses the unprefixed aiplatform.googleapis.com host, and the Gemini surface strips a publisher-pathed ID to the bare model the generateContent surface expects. resolveVertexSurface lists `codellama` explicitly so bare codellama-* IDs route to MaaS. Co-Authored-By: Claude <noreply@anthropic.com>
createModel now spreads ...retryOptions into every Gemini surface (the AI Studio ChatGoogle and all three gemini-enterprise clients), which previously omitted it — so OPENWIKI_PROVIDER_RETRY_ATTEMPTS was silently ignored and a 429 failed fast instead of backing off (reported by @avidspartan1 on langchain-ai#154). maxRetries is not a readable property on the constructed LangChain models, so this asserts it via vi.mock capturing each constructor's options (including that maxRetries: 0 propagates and the AI Studio API key reaches ChatGoogle). Once maxRetries is wired through, @langchain/core's AsyncCaller already honors a server-provided Retry-After (up to 60s), so the existing backoff engages. Co-Authored-By: Claude <noreply@anthropic.com>
573c3e4 to
7b0d6ef
Compare
…enterprise Add two Google model providers and route the Vertex AI (now Gemini Enterprise) Model Garden through a single provider: - `gemini` (AI Studio): Google's Gemini models via one API key (GEMINI_API_KEY). - `gemini-enterprise` (Vertex AI): keyless, ADC-authenticated provider that routes each model ID to the right Model Garden surface — native Gemini/Gemma over generateContent, Claude over the Anthropic Vertex SDK, and partner/open-weight models over the OpenAI-compatible MaaS endpoint (resolveVertexSurface / createGeminiEnterpriseModel). This supersedes the discrete `vertex` (Claude-only) provider added in langchain-ai#179: `gemini-enterprise` reaches Claude on Vertex through the same AnthropicVertex construction and ANTHROPIC_API_KEY/ANTHROPIC_AUTH_TOKEN env-neutralization, plus publisher-path stripping, so no capability is lost. The rename tracks Google's Cloud Next 2026 rebrand of Vertex AI to the Gemini Enterprise Agent Platform while keeping the unchanged underlying API surface. Builds on langchain-ai#179's keyless-provider plumbing (projectEnvKey/locationEnvKey/ defaultLocation, getMissingProviderEnvKey, resolveProviderLocation, getProviderCredentialHint) and its gcp-project/gcp-location onboarding steps, which gemini-enterprise inherits — dropping langchain-ai#154's earlier approach of overloading apiKeyEnvKey to carry the non-secret GOOGLE_CLOUD_PROJECT. Gemini uses disableStreaming + outputVersion "v0" to preserve Gemini 3.x thought signatures across multi-turn tool calls (shared GEMINI_THOUGHT_SIGNATURE_OPTIONS across both ChatGoogle surfaces). The MaaS endpoint and the Gemini surface both special-case the `global` location: MaaS uses the unprefixed aiplatform.googleapis.com host, and the Gemini surface strips a publisher-pathed ID to the bare model the generateContent surface expects. resolveVertexSurface lists `codellama` explicitly so bare codellama-* IDs route to MaaS. Co-Authored-By: Claude <noreply@anthropic.com>
createModel now spreads ...retryOptions into every Gemini surface (the AI Studio ChatGoogle and all three gemini-enterprise clients), which previously omitted it — so OPENWIKI_PROVIDER_RETRY_ATTEMPTS was silently ignored and a 429 failed fast instead of backing off (reported by @avidspartan1 on langchain-ai#154). maxRetries is not a readable property on the constructed LangChain models, so this asserts it via vi.mock capturing each constructor's options (including that maxRetries: 0 propagates and the AI Studio API key reaches ChatGoogle). Once maxRetries is wired through, @langchain/core's AsyncCaller already honors a server-provided Retry-After (up to 60s), so the existing backoff engages. Co-Authored-By: Claude <noreply@anthropic.com>
7b0d6ef to
79562ae
Compare
|
Pushed a round of self-review fixes (force-push, same 2-commit shape). Ran the change through a few review passes and caught one real default-config bug plus some hardening. All four CI gates pass locally — Bug — MaaS on the default Hardening:
New test coverage for the above plus gaps the review flagged: AI Studio Diff vs |
|
Thanks Brad Huffman (@ppsplus-bradh)! I'm taking a look! |
Colin Francis (colifran)
left a comment
There was a problem hiding this comment.
Looks great - great work on this one!
|
Thank you Brad Huffman (@ppsplus-bradh)! If you have an x account you want to share we'd love to shout you out. Same to you SadriG91! |
…fixes fix (#357) * ci: fix repository posture checks * feat: Add trending repo badge to readme (#347) * chore(deps): bump the major group with 5 updates (#348) Bumps the major group with 5 updates: | Package | From | To | | --- | --- | --- | | [actions/checkout](https://github.com/actions/checkout) | `4` | `7` | | [pnpm/action-setup](https://github.com/pnpm/action-setup) | `4.3.0` | `6.0.9` | | [actions/setup-node](https://github.com/actions/setup-node) | `4` | `7` | | [github/codeql-action](https://github.com/github/codeql-action) | `3` | `4` | | [peter-evans/create-pull-request](https://github.com/peter-evans/create-pull-request) | `7.0.11` | `8.1.1` | Updates `actions/checkout` from 4 to 7 - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](actions/checkout@v4...v7) Updates `pnpm/action-setup` from 4.3.0 to 6.0.9 - [Release notes](https://github.com/pnpm/action-setup/releases) - [Commits](pnpm/action-setup@b906aff...0ebf471) Updates `actions/setup-node` from 4 to 7 - [Release notes](https://github.com/actions/setup-node/releases) - [Commits](actions/setup-node@v4...v7) Updates `github/codeql-action` from 3 to 4 - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](github/codeql-action@v3...v4) Updates `peter-evans/create-pull-request` from 7.0.11 to 8.1.1 - [Release notes](https://github.com/peter-evans/create-pull-request/releases) - [Commits](peter-evans/create-pull-request@22a9089...5f6978f) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: '7' dependency-type: direct:production update-type: version-update:semver-major dependency-group: major - dependency-name: pnpm/action-setup dependency-version: 6.0.9 dependency-type: direct:production update-type: version-update:semver-major dependency-group: major - dependency-name: actions/setup-node dependency-version: '7' dependency-type: direct:production update-type: version-update:semver-major dependency-group: major - dependency-name: github/codeql-action dependency-version: '4' dependency-type: direct:production update-type: version-update:semver-major dependency-group: major - dependency-name: peter-evans/create-pull-request dependency-version: 8.1.1 dependency-type: direct:production update-type: version-update:semver-major dependency-group: major ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Colin Francis <131073567+colifran@users.noreply.github.com> * feat: add gemini (ai studio) and gemini enterprise (vertex ai) providers with vertex model-family routing (#154) * feat: add Gemini providers and consolidate Vertex Claude into gemini-enterprise Add two Google model providers and route the Vertex AI (now Gemini Enterprise) Model Garden through a single provider: - `gemini` (AI Studio): Google's Gemini models via one API key (GEMINI_API_KEY). - `gemini-enterprise` (Vertex AI): keyless, ADC-authenticated provider that routes each model ID to the right Model Garden surface — native Gemini/Gemma over generateContent, Claude over the Anthropic Vertex SDK, and partner/open-weight models over the OpenAI-compatible MaaS endpoint (resolveVertexSurface / createGeminiEnterpriseModel). This supersedes the discrete `vertex` (Claude-only) provider added in #179: `gemini-enterprise` reaches Claude on Vertex through the same AnthropicVertex construction and ANTHROPIC_API_KEY/ANTHROPIC_AUTH_TOKEN env-neutralization, plus publisher-path stripping, so no capability is lost. The rename tracks Google's Cloud Next 2026 rebrand of Vertex AI to the Gemini Enterprise Agent Platform while keeping the unchanged underlying API surface. Builds on #179's keyless-provider plumbing (projectEnvKey/locationEnvKey/ defaultLocation, getMissingProviderEnvKey, resolveProviderLocation, getProviderCredentialHint) and its gcp-project/gcp-location onboarding steps, which gemini-enterprise inherits — dropping #154's earlier approach of overloading apiKeyEnvKey to carry the non-secret GOOGLE_CLOUD_PROJECT. Gemini uses disableStreaming + outputVersion "v0" to preserve Gemini 3.x thought signatures across multi-turn tool calls (shared GEMINI_THOUGHT_SIGNATURE_OPTIONS across both ChatGoogle surfaces). The MaaS endpoint and the Gemini surface both special-case the `global` location: MaaS uses the unprefixed aiplatform.googleapis.com host, and the Gemini surface strips a publisher-pathed ID to the bare model the generateContent surface expects. resolveVertexSurface lists `codellama` explicitly so bare codellama-* IDs route to MaaS. Co-Authored-By: Claude <noreply@anthropic.com> * test: verify provider retry attempts reach the Gemini constructors createModel now spreads ...retryOptions into every Gemini surface (the AI Studio ChatGoogle and all three gemini-enterprise clients), which previously omitted it — so OPENWIKI_PROVIDER_RETRY_ATTEMPTS was silently ignored and a 429 failed fast instead of backing off (reported by @avidspartan1 on #154). maxRetries is not a readable property on the constructed LangChain models, so this asserts it via vi.mock capturing each constructor's options (including that maxRetries: 0 propagates and the AI Studio API key reaches ChatGoogle). Once maxRetries is wired through, @langchain/core's AsyncCaller already honors a server-provided Retry-After (up to 60s), so the existing backoff engages. Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com> * bump deepagents to 1.11.0 to restore execute tool via routePrefixes fix --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: John Kennedy <65985482+jkennedyvz@users.noreply.github.com> Co-authored-by: Brace Sproul <braceasproul@gmail.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Brad Huffman <brad.huffman@wellsky.com> Co-authored-by: Claude <noreply@anthropic.com>
|
amazing work here! <3 |
|
Hello Colin Francis (@colifran) I am glad to see that this evolved in such a rapid pace! I've had some 10 days vacation and I can see how far this went through! Glad to collaborate and benefit all Gemini users with Openwiki! Thanks for catching up this PR! |
|
Thanks Colin Francis (@colifran)! It's @sadrig91 — same as my GitHub handle. Would be honored. Great collaborating with you and Brad Huffman (@ppsplus-bradh) on this one; the way #179 and #154 converged is open source working exactly as it should. |
|
Colin Francis (@colifran) - X is Brad Huffman (@bradhuffman) Awesome work, all involved. Excited to see the continued evolution of this project. |
* feat: Add support for OKF via prompting (#321) * feat: Add support for OKF via prompting * Apply suggestions from code review Co-authored-by: Brace Sproul <braceasproul@gmail.com> * cr * feat: OKF index.md files (#323) * feat: Add support for OKF via prompting * feat: OKF index.md files * Apply suggestions from code review Co-authored-by: Brace Sproul <braceasproul@gmail.com> * cr * cr * cr * docs: document index middleware helpers * Update src/agent/prompt.ts * cr * make interface * drop unnecc type * feat: Add OKF front matter validator (#324) * feat: Add support for OKF via prompting * feat: OKF index.md files * Apply suggestions from code review Co-authored-by: Brace Sproul <braceasproul@gmail.com> * cr * feat: Add OKF front matter validator * cr * cr * docs: document frontmatter validator helpers * docs: document index middleware helpers * Update src/agent/prompt.ts * cr * make interface * drop unnecc type * cr * cr * interfaces * cr * cr * feat: OKF update wiki skill (#339) * feat: Add support for OKF via prompting * feat: OKF index.md files * Apply suggestions from code review Co-authored-by: Brace Sproul <braceasproul@gmail.com> * cr * feat: Add OKF front matter validator * cr * cr * docs: document frontmatter validator helpers * docs: document index middleware helpers * Update src/agent/prompt.ts * cr * make interface * drop unnecc type * cr * cr * interfaces * cr * feat: OKF update wiki skill * update version * fix: Writing skills (#351) * fix: prompt agent to write one to two sentence desc instead of just one (#353) * fix: Better description prompting (#354) * fix: Better description prompting * cr * cr * feat: implement cli telemetry (#325) * feat: implement anonymous cli telemetry for run events * lock file * chore: bump deepagents to 1.11.0 to restore execute tool via routePrefixes fix (#357) * ci: fix repository posture checks * feat: Add trending repo badge to readme (#347) * chore(deps): bump the major group with 5 updates (#348) Bumps the major group with 5 updates: | Package | From | To | | --- | --- | --- | | [actions/checkout](https://github.com/actions/checkout) | `4` | `7` | | [pnpm/action-setup](https://github.com/pnpm/action-setup) | `4.3.0` | `6.0.9` | | [actions/setup-node](https://github.com/actions/setup-node) | `4` | `7` | | [github/codeql-action](https://github.com/github/codeql-action) | `3` | `4` | | [peter-evans/create-pull-request](https://github.com/peter-evans/create-pull-request) | `7.0.11` | `8.1.1` | Updates `actions/checkout` from 4 to 7 - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](actions/checkout@v4...v7) Updates `pnpm/action-setup` from 4.3.0 to 6.0.9 - [Release notes](https://github.com/pnpm/action-setup/releases) - [Commits](pnpm/action-setup@b906aff...0ebf471) Updates `actions/setup-node` from 4 to 7 - [Release notes](https://github.com/actions/setup-node/releases) - [Commits](actions/setup-node@v4...v7) Updates `github/codeql-action` from 3 to 4 - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](github/codeql-action@v3...v4) Updates `peter-evans/create-pull-request` from 7.0.11 to 8.1.1 - [Release notes](https://github.com/peter-evans/create-pull-request/releases) - [Commits](peter-evans/create-pull-request@22a9089...5f6978f) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: '7' dependency-type: direct:production update-type: version-update:semver-major dependency-group: major - dependency-name: pnpm/action-setup dependency-version: 6.0.9 dependency-type: direct:production update-type: version-update:semver-major dependency-group: major - dependency-name: actions/setup-node dependency-version: '7' dependency-type: direct:production update-type: version-update:semver-major dependency-group: major - dependency-name: github/codeql-action dependency-version: '4' dependency-type: direct:production update-type: version-update:semver-major dependency-group: major - dependency-name: peter-evans/create-pull-request dependency-version: 8.1.1 dependency-type: direct:production update-type: version-update:semver-major dependency-group: major ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Colin Francis <131073567+colifran@users.noreply.github.com> * feat: add gemini (ai studio) and gemini enterprise (vertex ai) providers with vertex model-family routing (#154) * feat: add Gemini providers and consolidate Vertex Claude into gemini-enterprise Add two Google model providers and route the Vertex AI (now Gemini Enterprise) Model Garden through a single provider: - `gemini` (AI Studio): Google's Gemini models via one API key (GEMINI_API_KEY). - `gemini-enterprise` (Vertex AI): keyless, ADC-authenticated provider that routes each model ID to the right Model Garden surface — native Gemini/Gemma over generateContent, Claude over the Anthropic Vertex SDK, and partner/open-weight models over the OpenAI-compatible MaaS endpoint (resolveVertexSurface / createGeminiEnterpriseModel). This supersedes the discrete `vertex` (Claude-only) provider added in #179: `gemini-enterprise` reaches Claude on Vertex through the same AnthropicVertex construction and ANTHROPIC_API_KEY/ANTHROPIC_AUTH_TOKEN env-neutralization, plus publisher-path stripping, so no capability is lost. The rename tracks Google's Cloud Next 2026 rebrand of Vertex AI to the Gemini Enterprise Agent Platform while keeping the unchanged underlying API surface. Builds on #179's keyless-provider plumbing (projectEnvKey/locationEnvKey/ defaultLocation, getMissingProviderEnvKey, resolveProviderLocation, getProviderCredentialHint) and its gcp-project/gcp-location onboarding steps, which gemini-enterprise inherits — dropping #154's earlier approach of overloading apiKeyEnvKey to carry the non-secret GOOGLE_CLOUD_PROJECT. Gemini uses disableStreaming + outputVersion "v0" to preserve Gemini 3.x thought signatures across multi-turn tool calls (shared GEMINI_THOUGHT_SIGNATURE_OPTIONS across both ChatGoogle surfaces). The MaaS endpoint and the Gemini surface both special-case the `global` location: MaaS uses the unprefixed aiplatform.googleapis.com host, and the Gemini surface strips a publisher-pathed ID to the bare model the generateContent surface expects. resolveVertexSurface lists `codellama` explicitly so bare codellama-* IDs route to MaaS. Co-Authored-By: Claude <noreply@anthropic.com> * test: verify provider retry attempts reach the Gemini constructors createModel now spreads ...retryOptions into every Gemini surface (the AI Studio ChatGoogle and all three gemini-enterprise clients), which previously omitted it — so OPENWIKI_PROVIDER_RETRY_ATTEMPTS was silently ignored and a 429 failed fast instead of backing off (reported by @avidspartan1 on #154). maxRetries is not a readable property on the constructed LangChain models, so this asserts it via vi.mock capturing each constructor's options (including that maxRetries: 0 propagates and the AI Studio API key reaches ChatGoogle). Once maxRetries is wired through, @langchain/core's AsyncCaller already honors a server-provided Retry-After (up to 60s), so the existing backoff engages. Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com> * bump deepagents to 1.11.0 to restore execute tool via routePrefixes fix --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: John Kennedy <65985482+jkennedyvz@users.noreply.github.com> Co-authored-by: Brace Sproul <braceasproul@gmail.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Brad Huffman <brad.huffman@wellsky.com> Co-authored-by: Claude <noreply@anthropic.com> * fix: Better relationship prompting (#359) * chore: Update openwiki to be OKF compliant (#355) * chore: Update openwiki to be OKF compliant * add index files * cr --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: Colin Francis <131073567+colifran@users.noreply.github.com> Co-authored-by: John Kennedy <65985482+jkennedyvz@users.noreply.github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Brad Huffman <brad.huffman@wellsky.com> Co-authored-by: Claude <noreply@anthropic.com>
|
Kudos guys, this is a useful addition. Cheers and hope to collaborate on this project in future. Closed the related PR author'd by me. |
Adds native support for two Google Gemini providers via the official
@langchain/googlepackage, and routes the enterprise provider across every Vertex AI Model Garden surface:gemini(Google AI Studio) — developer setups usingGEMINI_API_KEY.gemini-enterprise(Gemini Enterprise Agent Platform / Vertex AI) — enterprise setups using Application Default Credentials (ADC) +GOOGLE_CLOUD_PROJECT, reaching Gemini/Gemma and partner models (Claude, Llama, Mistral, DeepSeek, Qwen) through one provider.Background
This revives Ernani Joppert Pontes Martins (@ernani)'s #36 (which addresses #29) and folds in the follow-up fix from
ernani/openwiki#1, rebased onto currentmain(#36 was based on the0.0.1release, before #110/#54/#57/#113 landed in the same files). Full credit to Ernani Joppert Pontes Martins (@ernani) for the original implementation — co-authored on the commit.What's here
@langchain/google, covering both providers under one SDK (platformType: "gai"for AI Studio,"gcp"for Vertex).googleAuthOptions: { projectId }(from the@langchain/google/nodeentrypoint, since the default entrypoint typesauthOptionsasnever) rather than relying on ambientprocess.env.process.env.GOOGLE_CLOUD_PROJECTand added a round-trip no other provider performs) is dropped.apiKey: ""so a strayGOOGLE_API_KEYin the environment can't silently hijack it into Vertex Express mode (the node client resolvesapiKey ?? GOOGLE_API_KEYand prefers the API-key header over ADC;hasApiKey()treats""as "no key").GOOGLE_CLOUD_LOCATIONforgemini-enterprise(blank → defaults tous-central1). Kept out ofneedsCredentialSetupso it never nags on later runs.gemini-3.5-flash(default),gemini-3.1-pro,gemini-3-flash,gemini-3.1-flash-lite.SELECTABLE_OPENWIKI_PROVIDERSinstead of a hand-maintained list.Vertex model-family routing (
5655b26)Vertex Model Garden serves different model families over different API surfaces, and
ChatGoogleonly speaks the nativegenerateContentsurface. This commit letsgemini-enterprisereach any Model Garden model by dispatching on the model ID to the correct LangChain client — one provider, one ADC credential, and uniform LangSmith tracing (every path stays aBaseChatModel):generateContentChatGoogle(existing)rawPredictChatAnthropic+AnthropicVertex(@anthropic-ai/vertex-sdk)/endpoints/openapi/chat/completionsChatOpenAI+ per-request ADC bearer-tokenfetchThe surface is resolved from the model ID by
resolveVertexSurface()(src/agent/vertex-surface.ts); publisher-pathed IDs (publishers/…/models/…) are normalized per surface. Users pick any of these through the existing Custom model ID step — no onboarding-flow changes.Additional details:
langchain-google-vertexai'sChatAnthropicVertexis Python-only), so Claude is bridged viaChatAnthropic'screateClienthook + the Anthropic Vertex SDK.AnthropicVertexextends the base Anthropic SDK, which readsANTHROPIC_API_KEY/ANTHROPIC_AUTH_TOKENfrom the environment and would send them as anAuthorizationheader — clobbering the Google OAuth token (ACCESS_TOKEN_TYPE_UNSUPPORTED). Those options areOmitted by the Vertex client, so they're neutralized around its (synchronous) constructor. This matters when a user previously configured theanthropicprovider and leftANTHROPIC_API_KEYin~/.openwiki/.env.fetchwrapper that injects a fresh ADC bearer token per request (GoogleAuth.getAccessToken()caches/refreshes), keepingcreateModelsynchronous and surviving token expiry.gemini-enterprisenow errors clearly ifGOOGLE_CLOUD_PROJECTis unset, and model-ID validation permits@for versioned Vertex Claude IDs (e.g.claude-sonnet-4-5@20250929).Verification
pnpm typecheck,pnpm lint, andpnpm test(107/107) pass. Unit tests cover the surface resolver, model-ID normalization, the project-id guard, auth-env neutralization, and the bearer-token fetch wrapper. All three surfaces were also live-verified against real Vertex (construction + streaming + tool-calling + token usage):gemini-2.5-pro✅claude-sonnet-4-5@20250929✅ (env-leak fix confirmed withANTHROPIC_AUTH_TOKENpresent)meta/llama-3.3-70b-instruct-maas✅A full
openwiki --updatedocumentation run also completed end-to-end driving Claude-on-Vertex. Earlier runtime smoke tests confirm both providers construct and that the enterprise path stays on proper Vertex + ADC even withGOOGLE_API_KEYset.Closes #29.
🤖 Generated with Claude Code