@@ -2,6 +2,7 @@ import { createLogger } from '@sim/logger'
22import { getBYOKKey } from '@/lib/api-key/byok'
33import { getRotatingApiKey } from '@/lib/core/config/api-keys'
44import { env } from '@/lib/core/config/env'
5+ import { isHosted } from '@/lib/core/config/feature-flags'
56import { isRetryableError , retryWithExponentialBackoff } from '@/lib/knowledge/documents/utils'
67import {
78 DEFAULT_RERANKER_MODEL ,
@@ -56,8 +57,18 @@ class RerankAPIError extends Error {
5657}
5758
5859async function resolveCohereKey (
59- workspaceId ?: string | null
60+ workspaceId ?: string | null ,
61+ userApiKey ?: string
6062) : Promise < { apiKey : string ; isBYOK : boolean } > {
63+ /**
64+ * Mirrors the agent block hosted-key pattern (`injectHostedKeyIfNeeded`):
65+ * on self-hosted the user-supplied key from the block field flows through
66+ * unchanged; on hosted Sim we always source the key from workspace BYOK or
67+ * platform env, so any user-supplied value is ignored.
68+ */
69+ if ( ! isHosted && userApiKey ) {
70+ return { apiKey : userApiKey , isBYOK : false }
71+ }
6172 if ( workspaceId ) {
6273 const byokResult = await getBYOKKey ( workspaceId , 'cohere' )
6374 if ( byokResult ) {
@@ -77,8 +88,19 @@ async function resolveCohereKey(
7788 }
7889}
7990
91+ /**
92+ * Subset of Cohere v2/rerank response fields we read.
93+ * Reference: https://docs.cohere.com/v2/reference/rerank
94+ * - `results[].index` maps back to the position in the documents we sent.
95+ * - `results[].relevance_score` is normalized 0–1.
96+ * - `meta.warnings` is documented as an array of strings; we surface them in logs
97+ * so issues like document truncation don't disappear silently.
98+ */
8099interface CohereRerankResponse {
81100 results : Array < { index : number ; relevance_score : number } >
101+ meta ?: {
102+ warnings ?: string [ ]
103+ }
82104}
83105
84106/**
@@ -92,6 +114,8 @@ export async function rerank<T extends RerankItem>(
92114 model : string
93115 topN ?: number
94116 workspaceId ?: string | null
117+ /** User-supplied Cohere key from the Knowledge block field. Honored only on self-hosted. */
118+ apiKey ?: string
95119 }
96120) : Promise < RerankResponse < T > > {
97121 if ( items . length === 0 ) return { results : [ ] , isBYOK : false }
@@ -100,7 +124,7 @@ export async function rerank<T extends RerankItem>(
100124 throw new Error ( `Unsupported reranker model: ${ options . model } ` )
101125 }
102126
103- const { apiKey, isBYOK } = await resolveCohereKey ( options . workspaceId )
127+ const { apiKey, isBYOK } = await resolveCohereKey ( options . workspaceId , options . apiKey )
104128 const cappedItems =
105129 items . length > MAX_DOCUMENTS_PER_RERANK ? items . slice ( 0 , MAX_DOCUMENTS_PER_RERANK ) : items
106130 if ( items . length > MAX_DOCUMENTS_PER_RERANK ) {
@@ -151,6 +175,13 @@ export async function rerank<T extends RerankItem>(
151175 }
152176 )
153177
178+ if ( response . meta ?. warnings && response . meta . warnings . length > 0 ) {
179+ logger . warn ( 'Cohere rerank returned warnings' , {
180+ model : options . model ,
181+ warnings : response . meta . warnings ,
182+ } )
183+ }
184+
154185 return {
155186 results : response . results
156187 . filter ( ( r ) => r . index >= 0 && r . index < cappedItems . length )
0 commit comments