Skip to content

feat: add gemini (ai studio) and gemini enterprise (vertex ai) providers with vertex model-family routing#154

Merged
Colin Francis (colifran) merged 2 commits into
langchain-ai:mainfrom
ppsplus-bradh:feat/gemini-provider
Jul 16, 2026
Merged

feat: add gemini (ai studio) and gemini enterprise (vertex ai) providers with vertex model-family routing#154
Colin Francis (colifran) merged 2 commits into
langchain-ai:mainfrom
ppsplus-bradh:feat/gemini-provider

Conversation

@ppsplus-bradh

@ppsplus-bradh Brad Huffman (ppsplus-bradh) commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Adds native support for two Google Gemini providers via the official @langchain/google package, and routes the enterprise provider across every Vertex AI Model Garden surface:

  • gemini (Google AI Studio) — developer setups using GEMINI_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 current main (#36 was based on the 0.0.1 release, 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

  • Unified dependency: @langchain/google, covering both providers under one SDK (platformType: "gai" for AI Studio, "gcp" for Vertex).
  • Explicit Vertex project via googleAuthOptions: { projectId } (from the @langchain/google/node entrypoint, since the default entrypoint types authOptions as never) rather than relying on ambient process.env.
  • No setup-time network ping — the original onboarding validation call (which mutated process.env.GOOGLE_CLOUD_PROJECT and added a round-trip no other provider performs) is dropped.
  • ADC hardening: the enterprise path passes apiKey: "" so a stray GOOGLE_API_KEY in the environment can't silently hijack it into Vertex Express mode (the node client resolves apiKey ?? GOOGLE_API_KEY and prefers the API-key header over ADC; hasApiKey() treats "" as "no key").
  • Optional region step: interactive onboarding collects GOOGLE_CLOUD_LOCATION for gemini-enterprise (blank → defaults to us-central1). Kept out of needsCredentialSetup so it never nags on later runs.
  • Current model defaults: gemini-3.5-flash (default), gemini-3.1-pro, gemini-3-flash, gemini-3.1-flash-lite.
  • Tidy-up: the invalid-provider CLI message is now derived from SELECTABLE_OPENWIKI_PROVIDERS instead of a hand-maintained list.

Vertex model-family routing (5655b26)

Vertex Model Garden serves different model families over different API surfaces, and ChatGoogle only speaks the native generateContent surface. This commit lets gemini-enterprise reach 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 a BaseChatModel):

Model family Vertex surface Client
Gemini, Gemma generateContent ChatGoogle (existing)
Anthropic Claude rawPredict ChatAnthropic + AnthropicVertex (@anthropic-ai/vertex-sdk)
Llama, Mistral, DeepSeek, Qwen (MaaS) OpenAI-compatible /endpoints/openapi/chat/completions ChatOpenAI + per-request ADC bearer-token fetch

The 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:

  • No JS-native Claude-on-Vertex class exists (langchain-google-vertexai's ChatAnthropicVertex is Python-only), so Claude is bridged via ChatAnthropic's createClient hook + the Anthropic Vertex SDK.
  • Anthropic env-leak fix: AnthropicVertex extends the base Anthropic SDK, which reads ANTHROPIC_API_KEY / ANTHROPIC_AUTH_TOKEN from the environment and would send them as an Authorization header — clobbering the Google OAuth token (ACCESS_TOKEN_TYPE_UNSUPPORTED). Those options are Omitted by the Vertex client, so they're neutralized around its (synchronous) constructor. This matters when a user previously configured the anthropic provider and left ANTHROPIC_API_KEY in ~/.openwiki/.env.
  • MaaS auth: the OpenAI-compatible endpoint authenticates via a fetch wrapper that injects a fresh ADC bearer token per request (GoogleAuth.getAccessToken() caches/refreshes), keeping createModel synchronous and surviving token expiry.
  • Fail-fast + validation: gemini-enterprise now errors clearly if GOOGLE_CLOUD_PROJECT is unset, and model-ID validation permits @ for versioned Vertex Claude IDs (e.g. claude-sonnet-4-5@20250929).

Verification

pnpm typecheck, pnpm lint, and pnpm 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):

  • Geminigemini-2.5-pro
  • Claudeclaude-sonnet-4-5@20250929 ✅ (env-leak fix confirmed with ANTHROPIC_AUTH_TOKEN present)
  • Llama 3.3 70B MaaSmeta/llama-3.3-70b-instruct-maas

A full openwiki --update documentation 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 with GOOGLE_API_KEY set.

Closes #29.

🤖 Generated with Claude Code

@ppsplus-bradh Brad Huffman (ppsplus-bradh) changed the title feat: add Gemini (AI Studio) and Gemini Enterprise (Vertex AI) providers feat: add Gemini (AI Studio) and Gemini Enterprise (Vertex AI) providers with Vertex model-family routing Jul 12, 2026
@ppsplus-bradh

Copy link
Copy Markdown
Contributor Author

Flagging overlap with other in-flight Gemini/Vertex PRs to help maintainers coordinate a direction:

All of these touch the same provider/config surface (src/constants.ts, src/agent/index.ts), so whichever lands first will likely conflict with the rest. Raising it so a single approach can be chosen rather than merging overlapping ones — happy to rebase/adjust #154 to fit whatever direction you prefer.

@ppsplus-bradh

Copy link
Copy Markdown
Contributor Author

Brace Sproul (@bracesproul) - Thoughts on any of the various GCP/Vertex AI related implementations?

@avidspartan1

Paul (avidspartan1) commented Jul 13, 2026

Copy link
Copy Markdown

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 thought_signature from the model’s functionCall is not preserved in conversation history:

Function call is missing a thought_signature in functionCall parts.
Additional data, function call `default_api:ls`

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.

@ppsplus-bradh

Copy link
Copy Markdown
Contributor Author

Paul (@avidspartan1) - Taking a look. Thanks!

@SadriG91

Copy link
Copy Markdown
Contributor

Reciprocating the cross-reference from your comment above — I took a proper look at #154 from the #179 side:

The resolveVertexSurface() routing is a genuinely nice design — one ADC credential reaching every Model Garden surface with uniform tracing, and the per-request ADC bearer fetch for the MaaS path is the right way to survive token expiry. We also independently hit the same ANTHROPIC_AUTH_TOKEN-clobbers-Vertex-OAuth bug you reported on #179 — both PRs now neutralize it, which is good mutual confirmation the guard is needed.

One thing you may want to fix regardless of how consolidation shakes out: the blank-region default of us-central1 won't serve the Claude models (nor most MaaS partner models). Verified live with both claude-haiku-4-5@20251001 and claude-sonnet-5: in us-central1 both fail with 400 FAILED_PRECONDITION: Publisher Model ... is not servable in region us-central1, while the same calls through global succeed. Claude on Vertex is served from global, us-east5, and europe-west1 — which is why #179 defaults to global.

On consolidation: #179's apiKeyEnvKey?-optional + getMissingProviderEnvKey() abstraction now coexists with upstream's new authMethod discriminant from the ChatGPT OAuth work, so the "keyless provider" plumbing (gates, onboarding steps, diagnostics) is generic rather than Claude-specific. If maintainers take that base first, your surface routing should drop on top cleanly — your project-as-credential handling collapses into the shared helpers. Happy to coordinate the rebase either direction.

Brad Huffman (ppsplus-bradh) added a commit to ppsplus-bradh/openwiki that referenced this pull request Jul 13, 2026
…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>
@ppsplus-bradh

Copy link
Copy Markdown
Contributor Author

Paul (@avidspartan1) — fix is in place on this branch (commit f47d876) if you'd like to validate. 🙏

Root cause (matches upstream langchain-ai/langchainjs#11181): LangChain core's streaming aggregator (ChatModelStream._assembleMessage) rebuilds the streamed model message as v1 standard content blocks and drops Gemini's provider-specific thoughtSignature — on both the thought parts and the functionCall parts. @langchain/google's v1 outbound converter also does not re-emit it. So on the next turn Gemini 3.x 400s with "Function call is missing a thought_signature." Gemini 2.5 tolerated the missing signature, which is why it looked fine there.

Fix here: set disableStreaming: true + outputVersion: "v0" on the Gemini ChatGoogle clients (native gemini and the gemini-enterprise Gemini surface). That routes calls through invoke()/generate, which honors v0 and preserves the raw Gemini content parts (signature intact) that the v0 converter round-trips correctly. Tradeoff: intra-message token streaming is disabled for Gemini models (graph/tool/step events still stream); Claude and OpenAI-compatible MaaS surfaces are unaffected.

Verified end-to-end against Vertex gemini-3.1-flash-lite across 5+ tool turns — no more thought_signature errors.

This is a workaround pending the upstream streaming fix (langchain-ai/langchainjs#11149 / #10480, both open); once that lands and releases, we can drop disableStreaming and get token streaming back. To try it, run this branch with OPENWIKI_MODEL_ID=gemini-3.1-flash-lite. Thanks again for the clean repro!

Brad Huffman (ppsplus-bradh) added a commit to ppsplus-bradh/openwiki that referenced this pull request Jul 13, 2026
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>
@ppsplus-bradh

Copy link
Copy Markdown
Contributor Author

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 global (commit 7db41f9) instead of us-central1, since global serves both Gemini and the Vertex Anthropic (Claude) surface. MaaS partner models stay region-specific, so those users set GOOGLE_CLOUD_LOCATION explicitly. Good catch.

Env neutralization: confirming #154 already handles the ANTHROPIC_AUTH_TOKEN/ANTHROPIC_API_KEY-clobbers-Vertex-OAuth problem — withAnthropicAuthEnvNeutralized() in vertex-surface.ts saves/deletes those env vars around the synchronous AnthropicVertex construction and restores them in finally, so the base Anthropic SDK can't send them as Authorization over the Google OAuth token. Happy to align on whichever implementation we keep.

Consolidation — I think a stack beats folding. Per CONTRIBUTING ("one PR = one change"), bundling the generic keyless/project-credential base (getMissingProviderEnvKey(), optional apiKeyEnvKey, the env-neutralize gate) together with the Vertex multi-surface routing (resolveVertexSurface() → Gemini/Claude/MaaS) in a single PR risks a split-request. They layer cleanly instead:

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:

  1. True stack: I host both branches in my fork — base branch = your keyless-provider work (with you as co-author), top branch = the Vertex routing based on it — and open the two stacked PRs. You keep authorship credit on the base.
  2. Sequential: feat: add google vertex ai (claude) provider #179 merges to main first, then I rebase feat: add gemini (ai studio) and gemini enterprise (vertex ai) providers with vertex model-family routing #154 on top and drop the overlap. Less coordination, but no parallel review and feat: add gemini (ai studio) and gemini enterprise (vertex ai) providers with vertex model-family routing #154 waits on feat: add google vertex ai (claude) provider #179.

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?

@SadriG91

Copy link
Copy Markdown
Contributor

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.

@avidspartan1

Copy link
Copy Markdown

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 gemini-3.1-flash-lite: Gemini returned a 429 requesting a retry in ~23 seconds, but OpenWiki exited with code 1 after ~1.8 seconds. Manually retrying after the requested cooldown succeeded.

createModel() builds retryOptions from OPENWIKI_PROVIDER_RETRY_ATTEMPTS, but neither the gemini ChatGoogle constructor nor the gemini-enterprise path receives those options.

Could the Gemini constructors pass through ...retryOptions and include a test confirming that 429 responses back off and retry—ideally honoring Gemini’s server-provided retry delay?

@colifran

Copy link
Copy Markdown
Contributor

Hey all - thanks for the in depth review of everything open. I'd like to prioritize these. Is my read of #179 first followed by this one correct? If so, I'll dig into #179 now.

cc: Brad Huffman (@ppsplus-bradh) SadriG91

@colifran

Copy link
Copy Markdown
Contributor

and sorry for the delay!

@SadriG91

Copy link
Copy Markdown
Contributor

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 main (55d868f) with your retryOptions fix applied, so it's ready for your pass. Thanks for picking these up!

@colifran

Copy link
Copy Markdown
Contributor

#179 has been merged. This one is next on my list once it gets rebased!

@ppsplus-bradh

Copy link
Copy Markdown
Contributor Author

#179 has been merged. This one is next on my list once it gets rebased!

On it.

@ppsplus-bradh

Copy link
Copy Markdown
Contributor Author

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 vertex base, #154 on top," Google retired the Vertex AI product name — at Cloud Next 2026 it was folded into the Gemini Enterprise Agent Platform, and Claude is now a partner model in the Gemini Enterprise Model Garden (Google's Claude-on-Gemini-Enterprise docs). The plumbing is unchanged — same *-aiplatform.googleapis.com endpoints, same rawPredict surface via the Anthropic Vertex SDK — and "Vertex" still shows up in hostnames, SDK class names, and doc URLs, so it's not gone by any means. But the umbrella product users now see is "Gemini Enterprise."

The proposal. Rather than land a second Claude-on-Vertex path next to #179's vertex provider, consolidate both under a single gemini-enterprise provider that routes by model family — Claude → Anthropic Vertex SDK, Gemini/Gemma → ChatGoogle, partner/open-weight → the OpenAI-compatible MaaS surface. #154's router already covers all three surfaces, using the same AnthropicVertex construction and ANTHROPIC_API_KEY/ANTHROPIC_AUTH_TOKEN env-neutralization as #179's Claude path, plus publisher-path stripping — so consolidating loses no capability. It would mean dropping the discrete vertex provider #179 just added.

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: createModel never wires maxRetries into the Gemini constructors (the gemini ChatGoogle and all three gemini-enterprise surfaces are the only ones that omit ...retryOptions), so OPENWIKI_PROVIDER_RETRY_ATTEMPTS is silently ignored on those paths and a 429 fails fast. Good news on the "honor the server-provided delay" part: @langchain/core's AsyncCaller already parses Retry-After and waits max(exponential backoff, Retry-After) for hints ≤ 60s — so simply wiring maxRetries through should let that existing handling engage (your 429 asked for ~23s, well under the cap). I'll wire it into both Gemini paths, add a test that the constructor receives the configured retry count, and validate the live 429 back-off; if the header turns out not to reach AsyncCaller on the Google client, honoring the delay explicitly becomes a follow-up.

The alternative is the lower-touch hybrid: keep vertex for Claude and narrow gemini-enterprise to Gemini + MaaS only. That avoids removing anything you just merged, at the cost of the retired name sitting alongside the current one and two overlapping Claude paths.

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?

@colifran

Copy link
Copy Markdown
Contributor

Brad Huffman (@ppsplus-bradh) love this! great suggestion. let's do it

Brad Huffman (ppsplus-bradh) added a commit to ppsplus-bradh/openwiki that referenced this pull request Jul 15, 2026
…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>
Brad Huffman (ppsplus-bradh) added a commit to ppsplus-bradh/openwiki that referenced this pull request Jul 15, 2026
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>
@ppsplus-bradh

Copy link
Copy Markdown
Contributor Author

Rebased onto latest main (7bd512f) and pushed — the PR is green-mergeable again. I went ahead with the consolidation approach from my note above; happy to revisit if you'd prefer the hybrid, but this felt like the cleaner end state.

Colin Francis (@colifran) — heads up: this force-push replaced your Merge branch 'main' into feat/gemini-provider (f4f3335). Nothing was lost — its only real content was #279 (0c0639e), which is already in main and so is in the rebase. I swapped the merge for a rebase since that's what we'd agreed the branch needed.

What's in the two commits:

  1. feat: add Gemini providers and consolidate Vertex Claude into gemini-enterprise — adds gemini (AI Studio, single API key) and gemini-enterprise (keyless, ADC). gemini-enterprise routes each model ID to the right Model Garden surface — Gemini/Gemma → ChatGoogle, Claude → Anthropic Vertex SDK, partner/open-weight → OpenAI-compatible MaaS. It supersedes the vertex provider from feat: add google vertex ai (claude) provider #179: it reaches Claude through the same AnthropicVertex construction and ANTHROPIC_* env-neutralization (plus publisher-path stripping), so no capability is lost, and it builds on your feat: add google vertex ai (claude) provider #179 keyless plumbing and gcp-project/gcp-location onboarding rather than feat: add gemini (ai studio) and gemini enterprise (vertex ai) providers with vertex model-family routing #154's old apiKeyEnvKey-overload. The rename tracks Google's Cloud Next 2026 rebrand while keeping the unchanged API surface.

  2. test: verify provider retry attempts reach the Gemini constructors — the Paul (@avidspartan1) 429 fix. createModel now spreads ...retryOptions into every Gemini surface (they were the only constructors omitting it), so OPENWIKI_PROVIDER_RETRY_ATTEMPTS is honored. Once maxRetries is wired through, @langchain/core's AsyncCaller already respects a server-provided Retry-After (≤ 60s), which covers the ~23s hint you saw, Paul (@avidspartan1) — worth a re-test when you get a chance.

Verification: pnpm typecheck clean and full pnpm test green (284 tests, incl. new surface-dispatch and retry-passthrough tests).

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 (roles/aiplatform.user) call it — the provider is branded Gemini Enterprise but the resource names users navigate to are still Vertex. Happy to change if you'd rather it read purely "Gemini Enterprise."

@SadriG91

Copy link
Copy Markdown
Contributor

Brad Huffman (@ppsplus-bradh) nice touch the consolidation under gemini-enterprise is a clean way forward.

@ppsplus-bradh

Copy link
Copy Markdown
Contributor Author

Running some reviews. Identified a gap on the MaaS path. Fix forthcoming.

Brad Huffman (ppsplus-bradh) added a commit to ppsplus-bradh/openwiki that referenced this pull request Jul 15, 2026
…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>
Brad Huffman (ppsplus-bradh) added a commit to ppsplus-bradh/openwiki that referenced this pull request Jul 15, 2026
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>
…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>
@ppsplus-bradh

Copy link
Copy Markdown
Contributor Author

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 — prettier --check, eslint, tsc --noEmit, and vitest (297 tests, up from 284).

Bug — MaaS on the default global location hit an invalid host. vertexOpenAIBaseUrl interpolated the location as a host prefix (https://global-aiplatform.googleapis.com/…), but the global endpoint is served from the unprefixed aiplatform.googleapis.com (regional locations keep the ${location}- prefix). Since global is the default, any MaaS model would have failed out of the box. The Claude and Gemini surfaces were already fine — their SDKs special-case global internally — so I mirrored that in vertexOpenAIBaseUrl. Same trap cline #10287 and pipecat #2710 hit.

Hardening:

  • The Gemini surface now strips a publisher-pathed ID (publishers/google/models/gemini-3-progemini-3-pro) the same way the Claude and MaaS branches normalize theirs — otherwise ChatGoogle built a malformed model path.
  • resolveVertexSurface now lists codellama explicitly, so a bare codellama-* ID routes to MaaS instead of falling through to the Gemini default (the (^|/) boundary meant the llama token didn't match after the code prefix).
  • Removed a dead ANTHROPIC_API_KEY_ENV_KEY import (was tripping no-unused-vars), extracted the shared Gemini thought-signature options into one constant so the two ChatGoogle surfaces can't drift, and reused the env-key constant in the neutralizer.

New test coverage for the above plus gaps the review flagged: AI Studio gemini construction, the Claude surface's env-neutralization + project/region passthrough (asserts ANTHROPIC_* are actually hidden during AnthropicVertex construction and restored after), global vs regional URL building, resolveConfiguredProvider for the new providers, and the classifier boundary cases.

Diff vs main is 14 files, +988/−69.

@colifran

Copy link
Copy Markdown
Contributor

Thanks Brad Huffman (@ppsplus-bradh)! I'm taking a look!

@colifran Colin Francis (colifran) changed the title feat: add Gemini (AI Studio) and Gemini Enterprise (Vertex AI) providers with Vertex model-family routing feat: add gemini (ai studio) and gemini enterprise (vertex ai) providers with vertex model-family routing Jul 16, 2026

@colifran Colin Francis (colifran) left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great - great work on this one!

@colifran

Copy link
Copy Markdown
Contributor

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!

@colifran
Colin Francis (colifran) merged commit e1a2fea into langchain-ai:main Jul 16, 2026
9 checks passed
Colin Francis (colifran) added a commit that referenced this pull request Jul 16, 2026
…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>
@dcorto

D. Corto (dcorto) commented Jul 16, 2026

Copy link
Copy Markdown

amazing work here! <3

@ernani

Copy link
Copy Markdown

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!

@SadriG91

Copy link
Copy Markdown
Contributor

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.

@ppsplus-bradh

Copy link
Copy Markdown
Contributor Author

Colin Francis (@colifran) - X is Brad Huffman (@bradhuffman) Awesome work, all involved. Excited to see the continued evolution of this project.

Brace Sproul (bracesproul) added a commit that referenced this pull request Jul 16, 2026
* 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>
@realtusharnargunde

Copy link
Copy Markdown

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.

@ppsplus-bradh
Brad Huffman (ppsplus-bradh) deleted the feat/gemini-provider branch July 18, 2026 12:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add support for gemini

7 participants