Skip to content

feat(providers): add Cohere provider#581

Merged
SantiagoDePolonia merged 7 commits into
mainfrom
feat/cohera
Jul 24, 2026
Merged

feat(providers): add Cohere provider#581
SantiagoDePolonia merged 7 commits into
mainfrom
feat/cohera

Conversation

@SantiagoDePolonia

@SantiagoDePolonia SantiagoDePolonia commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Summary

  • add a native Cohere v2 provider for OpenAI-compatible chat completions, Responses, embeddings, and model discovery
  • translate streaming content, thinking, tool calls, citations, usage, finish reasons, multimodal messages, and provider-native extensions
  • support API-key rotation, passthrough routes, environment and YAML configuration, Helm deployment, and provider documentation
  • integrate the Cohere documentation link into the Svelte 5 dashboard and rebuild the embedded frontend bundle

Validation

  • all pre-commit hooks, including race tests, lint, fix-check, dashboard tests, dist synchronization, performance guards, and Mintlify validation
  • go test ./...
  • focused Cohere race tests
  • E2E and contract test suites
  • npm test, npm run check, and npm run build
  • Helm lint and rendered Cohere secret/environment configuration

Summary by CodeRabbit

  • New Features
    • Added Cohere support for chat, /responses, streaming, embeddings, model discovery, audio transcription, and Cohere-native passthrough.
    • Enabled Cohere in environment/config/Helm defaults and documentation, including opt-in passthrough setup; added kilo to default passthrough providers.
  • Bug Fixes
    • Improved mid-stream error handling to emit response.failed instead of completing.
    • Made provider error parsing more tolerant and information-preserving.
  • Documentation
    • Updated environment templates, README, provider docs, Helm values/schema/notes, and dashboard provider links for Cohere.
  • Tests
    • Added/expanded Cohere and streaming-error/passthrough coverage, plus updated expectations.

Copilot AI review requested due to automatic review settings July 24, 2026 15:52

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@coderabbitai

coderabbitai Bot commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds Cohere as a built-in provider with chat, streaming, embeddings, audio transcription, model discovery, Responses translation, and native passthrough. It updates registration, configuration, Helm support, documentation, dashboard links, and stream-error handling.

Changes

Cohere provider

Layer / File(s) Summary
Provider contracts and registration
internal/providers/cohere/types.go, internal/providers/cohere/cohere.go, run/providers.go, internal/providers/config_test.go
Defines Cohere payload types, constructors, headers, discovery metadata, and default registration.
Chat and streaming translation
internal/providers/cohere/chat.go, internal/providers/cohere/stream.go, internal/providers/cohere/cohere_test.go
Translates chat requests, tools, reasoning, responses, usage, and streaming events into gateway-compatible formats.
Embeddings, audio, and provider capabilities
internal/providers/cohere/embeddings.go, internal/providers/cohere/audio.go, internal/providers/cohere/cohere.go, internal/providers/cohere/*_test.go
Adds embedding and transcription translation, model filtering, Responses forwarding, and native passthrough handling.
Responses stream failure propagation
internal/providers/responses_converter.go, internal/providers/responses_converter_test.go, internal/providers/cohere/cohere_test.go
Emits terminal response.failed events for upstream stream errors and prevents subsequent response.completed events.
Configuration and Helm support
.env.template, config/*, helm/*, internal/server/passthrough_support.go
Adds Cohere environment variables, YAML configuration, passthrough enablement, Helm schema values, secrets, provider reporting, and the kilo default passthrough entry.
Documentation and dashboard discovery
README.md, docs/*, web/dashboard/*
Documents Cohere support and adds provider navigation, overview metadata, and dashboard documentation URL mapping.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant Gateway
  participant CohereProvider
  participant CohereAPI
  Client->>Gateway: Send chat, embeddings, audio, or Responses request
  Gateway->>CohereProvider: Route request to cohere
  CohereProvider->>CohereAPI: Translate and send API request
  CohereAPI-->>CohereProvider: Return response or stream
  CohereProvider-->>Gateway: Convert response or failure event
  Gateway-->>Client: Return compatible response
Loading

Possibly related PRs

Suggested reviewers: copilot

Poem

I’m a rabbit with Cohere in my burrow,
Streaming words in a bright little furrow.
Tools hop along, embeddings take flight,
New routes welcome Cohere tonight!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 11.11% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise and clearly summarizes the main change: adding the Cohere provider.
Description check ✅ Passed The description covers the main change and validation steps, so it is mostly complete despite using different headings than the template.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/cohera

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@mintlify

mintlify Bot commented Jul 24, 2026

Copy link
Copy Markdown

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated (UTC)
gomodel 🟢 Ready View Preview Jul 24, 2026, 3:53 PM

💡 Tip: Enable Workflows to automatically generate PRs for you.

@codecov-commenter

codecov-commenter commented Jul 24, 2026

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 5

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@config/config.example.yaml`:
- Line 16: Update the ENABLED_PASSTHROUGH_PROVIDERS entry in .env.template to
include cohere, matching config/config.example.yaml and ensuring
environment-only deployments expose consistent passthrough behavior.

In `@docs/providers/cohere.mdx`:
- Around line 35-36: Update both curl examples in the Cohere provider
documentation to use the documented default port 8080 instead of 8090, keeping
the remaining command paths and options unchanged.

In `@internal/providers/cohere/chat.go`:
- Around line 411-422: Update normalizeFinishReason so Cohere’s ERROR and
TIMEOUT outcomes are propagated as provider/gateway errors instead of being
mapped to "stop"; if the existing contract requires a finish reason rather than
an error, map TIMEOUT to "length" while retaining "stop" only for genuine
content-stopped reasons such as COMPLETE and STOP_SEQUENCE.
- Around line 293-313: The response_format handling in copyChatExtraFields must
normalize OpenAI’s json_schema shape to Cohere’s schema shape before forwarding.
Add a provider-local helper such as cohereResponseFormat and use it when
assigning out.ResponseFormat, mapping the nested json_schema schema into
response_format.schema while preserving supported fields and existing behavior
for already-Cohere-formatted values.

In `@internal/providers/cohere/stream.go`:
- Around line 106-163: Update the event switch in the stream consumer to handle
Cohere citation-start and citation-end events instead of dropping them through
default. Emit citation-start data in the OpenAI-compatible delta format, and
reuse the non-streaming citation mapping for citation-end when the configured
citation mode requires it, while preserving existing content, tool, and finish
handling.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 6c1da995-5da1-4ace-9991-dac13bf5a1db

📥 Commits

Reviewing files that changed from the base of the PR and between 3e22d93 and 972282d.

⛔ Files ignored due to path filters (2)
  • internal/admin/dashboard/static/dist/assets/index-Dx5V1Ah5.js is excluded by !**/dist/**
  • internal/admin/dashboard/static/dist/index.html is excluded by !**/dist/**
📒 Files selected for processing (26)
  • .env.template
  • README.md
  • config/config.example.yaml
  • config/config_test.go
  • docs/about/roadmap.mdx
  • docs/advanced/configuration.mdx
  • docs/docs.json
  • docs/providers/cohere.mdx
  • docs/providers/overview.mdx
  • docs/snippets/provider-credentials-note.mdx
  • helm/Chart.yaml
  • helm/README.md
  • helm/templates/NOTES.txt
  • helm/values.schema.json
  • helm/values.yaml
  • internal/providers/cohere/chat.go
  • internal/providers/cohere/cohere.go
  • internal/providers/cohere/cohere_test.go
  • internal/providers/cohere/embeddings.go
  • internal/providers/cohere/stream.go
  • internal/providers/cohere/types.go
  • internal/providers/config_test.go
  • run/providers.go
  • run/providers_test.go
  • web/dashboard/src/pages/overview/providersLogic.js
  • web/dashboard/tests/overview-providers.test.js

Comment thread config/config.example.yaml
Comment thread docs/providers/cohere.mdx Outdated
Comment thread internal/providers/cohere/chat.go Outdated
Comment thread internal/providers/cohere/chat.go
Comment thread internal/providers/cohere/stream.go
@greptile-apps

greptile-apps Bot commented Jul 24, 2026

Copy link
Copy Markdown

Confidence Score: 4/5

The PR is not yet safe to merge because Cohere stream read and decoding failures can truncate a Responses stream without emitting response.failed.

Scanner and JSON event-decoding failures are propagated as raw pipe errors, bypassing the structured error chunk that the Responses converter requires to produce a terminal failed event.

internal/providers/cohere/stream.go

T-Rex T-Rex Logs

What T-Rex did

  • Reproduced, via a Go harness, that the Cohere stream path emits partial text and surfaces a parse error when given malformed JSON, and does not set response.failed in those error paths.
  • Compared current and baseline revisions; both passed their race-detector tests with exit code 0, and no broad, unrelated suites were executed.

View all artifacts

T-Rex Ran code and verified through T-Rex

Sequence Diagram

sequenceDiagram
  participant C as Client
  participant R as Responses converter
  participant A as Cohere stream adapter
  participant P as Cohere
  C->>R: Streaming Responses request
  R->>A: StreamResponsesViaChat
  A->>P: "POST /v2/chat (stream=true)"
  P-->>A: SSE events
  A-->>R: OpenAI chat chunks
  R-->>C: Responses SSE events
  alt Cohere terminal provider error
    A-->>R: provider_error chunk
    R-->>C: response.failed
  else Scanner or JSON decoding failure
    A--xR: Raw pipe error
    R--xC: Truncated stream without response.failed
  end
Loading

Reviews (2): Last reviewed commit: "fix(providers): address follow-up review..." | Re-trigger Greptile

Comment thread internal/providers/cohere/stream.go Outdated
Comment thread internal/providers/cohere/chat.go Outdated
Copilot AI review requested due to automatic review settings July 24, 2026 16:55

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Copilot AI review requested due to automatic review settings July 24, 2026 16:58

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.env.template:
- Around line 51-53: Align the `.env.template` passthrough provider
documentation with the `defaultEnabledPassthroughProviders` runtime value by
removing `kilo` from the documented default, or add it to the runtime default if
that is the intended behavior; ensure both defaults match.

In `@internal/providers/responses_converter.go`:
- Around line 359-365: Update the upstream error decoding in
internal/providers/responses_converter.go lines 359-365 to fall back to a JSON
string when object unmarshalling fails, and represent the object’s code with
json.RawMessage before extracting its string value. Add table-driven coverage in
internal/providers/responses_converter_test.go lines 326-364 for object and
scalar string error payloads, including a malformed non-error member that
exercises processChunkTolerant.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: fc9bef80-1e78-4577-9c6d-77908b17b18a

📥 Commits

Reviewing files that changed from the base of the PR and between 972282d and ada0c70.

📒 Files selected for processing (8)
  • .env.template
  • docs/providers/cohere.mdx
  • internal/providers/cohere/chat.go
  • internal/providers/cohere/cohere_test.go
  • internal/providers/cohere/stream.go
  • internal/providers/cohere/types.go
  • internal/providers/responses_converter.go
  • internal/providers/responses_converter_test.go

Comment thread .env.template
Comment thread internal/providers/responses_converter.go Outdated
Copilot AI review requested due to automatic review settings July 24, 2026 17:05

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Comment on lines +71 to +73
if err := scanner.Err(); err != nil {
_ = out.CloseWithError(err)
return

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Stream failures bypass response.failed

When a Cohere stream encounters a read failure or malformed JSON event after streaming begins, this closes the pipe with a raw error instead of emitting the provider-error chunk consumed by the Responses converter. The client consequently receives a truncated Responses SSE stream without a terminal response.failed event.

Artifacts

Repro: Go harness covering malformed JSON and scanner failure through the Cohere adapter and Responses converter

  • Evidence file captured while the check ran.

Repro: verbose failing test output showing truncated Responses SSE and raw stream errors

  • The full command output behind this check.

View artifacts

T-Rex Ran code and verified through T-Rex

Copilot AI review requested due to automatic review settings July 24, 2026 18:03

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
internal/providers/cohere/cohere_test.go (1)

184-226: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Use table-driven cases for repeated provider mappings.

The ERROR/TIMEOUT and invalid-request scenarios should be expressed as table-driven tests so each mapping is enumerated consistently and remains easy to extend.

Also applies to: 514-536

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/providers/cohere/cohere_test.go` around lines 184 - 226, Extend the
table-driven test in TestChatCompletionReturnsCohereGenerationFailures to
include the invalid-request finish reason scenario currently covered separately.
Add its expected GatewayError status and message to the shared test cases,
preserving the existing ERROR and TIMEOUT mappings and assertions.

Source: Coding guidelines

internal/providers/cohere/chat.go (2)

298-383: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Reject unsupported response_format when tools are requested.

Cohere does not allow response_format together with tools or documents. Since _convertToCohereRequest builds and forwards both fields, add validation there to return an InvalidRequestError before calling the upstream API, and split the Coheretest fixture so the successful translation test does not include this invalid combination.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/providers/cohere/chat.go` around lines 298 - 383, Update
_convertToCohereRequest to return an InvalidRequestError before the upstream
call when response_format is present together with tools or documents; keep
valid response_format translations unchanged. In
internal/providers/cohere/cohere_test.go lines 82-104, split the fixture so the
successful translation case no longer includes tools or documents, and add
coverage for rejecting those combinations.

101-109: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Reject unsupported Cohere message roles instead of treating them as user messages.

toCohereMessage converts unknown roles to user, which can change request semantics and be serialized into an invalid Cohere request. Return an invalid-request error; conversion errors are already wrapped by toCohereChatRequest.

Proposed fix
  case "system", "user", "assistant", "tool":
  default:
-   role = "user"
+   return chatMessage{}, fmt.Errorf("unsupported message role %q", message.Role)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/providers/cohere/chat.go` around lines 101 - 109, Update
toCohereMessage so unsupported normalized roles return an invalid-request error
instead of being reassigned to "user". Preserve the existing developer-to-system
mapping and accepted system, user, assistant, and tool roles; rely on
toCohereChatRequest’s existing error wrapping.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@internal/core/errors_test.go`:
- Around line 344-352: Extend the table-driven Cohere cases in the
ParseProviderError tests to assert the normalized message exactly as "invalid
tool generation", rather than only checking that it is non-empty. Add cases
covering nested, scalar, and null error payloads, verifying each response’s
normalized message and preserving the existing provider-specific type, status,
and code mappings.

---

Outside diff comments:
In `@internal/providers/cohere/chat.go`:
- Around line 298-383: Update _convertToCohereRequest to return an
InvalidRequestError before the upstream call when response_format is present
together with tools or documents; keep valid response_format translations
unchanged. In internal/providers/cohere/cohere_test.go lines 82-104, split the
fixture so the successful translation case no longer includes tools or
documents, and add coverage for rejecting those combinations.
- Around line 101-109: Update toCohereMessage so unsupported normalized roles
return an invalid-request error instead of being reassigned to "user". Preserve
the existing developer-to-system mapping and accepted system, user, assistant,
and tool roles; rely on toCohereChatRequest’s existing error wrapping.

In `@internal/providers/cohere/cohere_test.go`:
- Around line 184-226: Extend the table-driven test in
TestChatCompletionReturnsCohereGenerationFailures to include the invalid-request
finish reason scenario currently covered separately. Add its expected
GatewayError status and message to the shared test cases, preserving the
existing ERROR and TIMEOUT mappings and assertions.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 74822cf6-98b4-43f3-ba05-afcc2e231c59

📥 Commits

Reviewing files that changed from the base of the PR and between e92db11 and db20e64.

📒 Files selected for processing (6)
  • internal/core/errors.go
  • internal/core/errors_test.go
  • internal/providers/cohere/chat.go
  • internal/providers/cohere/cohere_test.go
  • internal/providers/cohere/stream.go
  • internal/providers/cohere/types.go

Comment thread internal/core/errors_test.go
Copilot AI review requested due to automatic review settings July 24, 2026 18:14

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Copilot AI review requested due to automatic review settings July 24, 2026 18:16

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@SantiagoDePolonia
SantiagoDePolonia merged commit 10797eb into main Jul 24, 2026
18 checks passed
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.

3 participants