@tanstack/ai-cohere 0.1.1 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -72,7 +72,13 @@ var CohereRerankAdapter = class extends BaseRerankAdapter {
72
72
  promptTokens: 0,
73
73
  completionTokens: 0,
74
74
  totalTokens: 0,
75
- ...searchUnits !== void 0 ? { unitsBilled: searchUnits } : {}
75
+ ...searchUnits !== void 0 ? {
76
+ billed: {
77
+ quantity: searchUnits,
78
+ unit: "units"
79
+ },
80
+ unitsBilled: searchUnits
81
+ } : {}
76
82
  };
77
83
  return {
78
84
  id: json.id ?? this.generateId(),
@@ -1 +1 @@
1
- {"version":3,"file":"rerank.js","names":[],"sources":["../../../src/adapters/rerank.ts"],"sourcesContent":["import { BaseRerankAdapter } from '@tanstack/ai/adapters'\nimport {\n COHERE_DEFAULT_BASE_URL,\n getCohereApiKeyFromEnv,\n} from '../utils/client'\nimport type { CohereClientConfig } from '../utils/client'\nimport type {\n CohereRerankModel,\n InferCohereRerankProviderOptions,\n} from '../model-meta'\nimport type {\n RerankAdapterResult,\n RerankOptions,\n TokenUsage,\n} from '@tanstack/ai'\n\n/** Shape of the Cohere `/v2/rerank` response we depend on. */\ninterface CohereRerankResponse {\n id?: string\n results: Array<{ index: number; relevance_score: number }>\n meta?: { billed_units?: { search_units?: number } }\n}\n\nfunction isCohereRerankResponse(value: unknown): value is CohereRerankResponse {\n if (typeof value !== 'object' || value === null) return false\n const results = (value as { results?: unknown }).results\n return (\n Array.isArray(results) &&\n results.every(\n (r) =>\n typeof r === 'object' &&\n r !== null &&\n typeof (r as { index?: unknown }).index === 'number' &&\n typeof (r as { relevance_score?: unknown }).relevance_score ===\n 'number',\n )\n )\n}\n\n/**\n * Cohere rerank adapter.\n *\n * Talks to Cohere's `/v2/rerank` endpoint over raw `fetch` — no SDK. Returns\n * scored indices into the submitted documents; the `rerank()` activity maps\n * those back to the caller's original documents.\n */\nexport class CohereRerankAdapter<\n TModel extends CohereRerankModel,\n> extends BaseRerankAdapter<TModel, InferCohereRerankProviderOptions<TModel>> {\n readonly name = 'cohere' as const\n\n private readonly apiKey: string\n private readonly baseUrl: string\n private readonly headers: Record<string, string>\n\n constructor(config: CohereClientConfig, model: TModel) {\n super({}, model)\n this.apiKey = config.apiKey\n this.baseUrl = (config.baseUrl ?? COHERE_DEFAULT_BASE_URL).replace(\n /\\/+$/,\n '',\n )\n this.headers = config.headers ?? {}\n }\n\n async rerank(\n options: RerankOptions<InferCohereRerankProviderOptions<TModel>>,\n ): Promise<RerankAdapterResult> {\n const { model, query, documents, topN, modelOptions, abortSignal, logger } =\n options\n\n const body: Record<string, unknown> = { model, query, documents }\n if (topN !== undefined) body['top_n'] = topN\n if (modelOptions?.maxTokensPerDoc !== undefined) {\n body['max_tokens_per_doc'] = modelOptions.maxTokensPerDoc\n }\n\n logger.request(\n `activity=rerank provider=${this.name} model=${model} documents=${documents.length}`,\n { provider: this.name, model },\n )\n\n let response: Response\n try {\n response = await fetch(`${this.baseUrl}/v2/rerank`, {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${this.apiKey}`,\n 'Content-Type': 'application/json',\n ...this.headers,\n },\n body: JSON.stringify(body),\n ...(abortSignal ? { signal: abortSignal } : {}),\n })\n } catch (error) {\n logger.errors(`${this.name}.rerank fatal`, {\n error,\n source: `${this.name}.rerank`,\n })\n throw error\n }\n\n if (!response.ok) {\n const detail = await response.text().catch(() => '')\n const error = new Error(\n `Cohere rerank request failed: ${response.status} ${response.statusText}${\n detail ? ` — ${detail}` : ''\n }`,\n )\n logger.errors(`${this.name}.rerank fatal`, {\n error,\n source: `${this.name}.rerank`,\n })\n throw error\n }\n\n const json: unknown = await response.json()\n if (!isCohereRerankResponse(json)) {\n throw new Error('Cohere rerank response had an unexpected shape')\n }\n\n const searchUnits = json.meta?.billed_units?.search_units\n const usage: TokenUsage = {\n promptTokens: 0,\n completionTokens: 0,\n totalTokens: 0,\n ...(searchUnits !== undefined ? { unitsBilled: searchUnits } : {}),\n }\n\n return {\n id: json.id ?? this.generateId(),\n ranking: json.results.map((r) => ({\n index: r.index,\n score: r.relevance_score,\n })),\n usage,\n }\n }\n}\n\n/**\n * Creates a Cohere rerank adapter with an explicit API key. Type resolution\n * (per-model provider options) happens here at the call site.\n *\n * @example\n * ```typescript\n * const adapter = createCohereRerank('rerank-v3.5', 'co-...')\n * ```\n */\nexport function createCohereRerank<TModel extends CohereRerankModel>(\n model: TModel,\n apiKey: string,\n config?: Omit<CohereClientConfig, 'apiKey'>,\n): CohereRerankAdapter<TModel> {\n return new CohereRerankAdapter({ apiKey, ...config }, model)\n}\n\n/**\n * Creates a Cohere rerank adapter, reading `COHERE_API_KEY` from the\n * environment.\n *\n * @throws Error if `COHERE_API_KEY` is not found.\n *\n * @example\n * ```typescript\n * import { rerank } from '@tanstack/ai'\n * import { cohereRerank } from '@tanstack/ai-cohere'\n *\n * const { rerankedDocuments } = await rerank({\n * adapter: cohereRerank('rerank-v3.5'),\n * query: 'talk about rain',\n * documents: ['sunny day', 'rainy afternoon'],\n * })\n * ```\n */\nexport function cohereRerank<TModel extends CohereRerankModel>(\n model: TModel,\n config?: Omit<CohereClientConfig, 'apiKey'>,\n): CohereRerankAdapter<TModel> {\n return createCohereRerank(model, getCohereApiKeyFromEnv(), config)\n}\n"],"mappings":";;;AAuBA,SAAS,uBAAuB,OAA+C;CAC7E,IAAI,OAAO,UAAU,YAAY,UAAU,MAAM,OAAO;CACxD,MAAM,UAAW,MAAgC;CACjD,OACE,MAAM,QAAQ,OAAO,KACrB,QAAQ,OACL,MACC,OAAO,MAAM,YACb,MAAM,QACN,OAAQ,EAA0B,UAAU,YAC5C,OAAQ,EAAoC,oBAC1C,QACN;AAEJ;;;;;;;;AASA,IAAa,sBAAb,cAEU,kBAAoE;CAC5E,OAAgB;CAEhB;CACA;CACA;CAEA,YAAY,QAA4B,OAAe;EACrD,MAAM,CAAC,GAAG,KAAK;EACf,KAAK,SAAS,OAAO;EACrB,KAAK,WAAW,OAAO,WAAA,yBAAA,CAAoC,QACzD,QACA,EACF;EACA,KAAK,UAAU,OAAO,WAAW,CAAC;CACpC;CAEA,MAAM,OACJ,SAC8B;EAC9B,MAAM,EAAE,OAAO,OAAO,WAAW,MAAM,cAAc,aAAa,WAChE;EAEF,MAAM,OAAgC;GAAE;GAAO;GAAO;EAAU;EAChE,IAAI,SAAS,KAAA,GAAW,KAAK,WAAW;EACxC,IAAI,cAAc,oBAAoB,KAAA,GACpC,KAAK,wBAAwB,aAAa;EAG5C,OAAO,QACL,4BAA4B,KAAK,KAAK,SAAS,MAAM,aAAa,UAAU,UAC5E;GAAE,UAAU,KAAK;GAAM;EAAM,CAC/B;EAEA,IAAI;EACJ,IAAI;GACF,WAAW,MAAM,MAAM,GAAG,KAAK,QAAQ,aAAa;IAClD,QAAQ;IACR,SAAS;KACP,eAAe,UAAU,KAAK;KAC9B,gBAAgB;KAChB,GAAG,KAAK;IACV;IACA,MAAM,KAAK,UAAU,IAAI;IACzB,GAAI,cAAc,EAAE,QAAQ,YAAY,IAAI,CAAC;GAC/C,CAAC;EACH,SAAS,OAAO;GACd,OAAO,OAAO,GAAG,KAAK,KAAK,gBAAgB;IACzC;IACA,QAAQ,GAAG,KAAK,KAAK;GACvB,CAAC;GACD,MAAM;EACR;EAEA,IAAI,CAAC,SAAS,IAAI;GAChB,MAAM,SAAS,MAAM,SAAS,KAAK,CAAC,CAAC,YAAY,EAAE;GACnD,MAAM,wBAAQ,IAAI,MAChB,iCAAiC,SAAS,OAAO,GAAG,SAAS,aAC3D,SAAS,MAAM,WAAW,IAE9B;GACA,OAAO,OAAO,GAAG,KAAK,KAAK,gBAAgB;IACzC;IACA,QAAQ,GAAG,KAAK,KAAK;GACvB,CAAC;GACD,MAAM;EACR;EAEA,MAAM,OAAgB,MAAM,SAAS,KAAK;EAC1C,IAAI,CAAC,uBAAuB,IAAI,GAC9B,MAAM,IAAI,MAAM,gDAAgD;EAGlE,MAAM,cAAc,KAAK,MAAM,cAAc;EAC7C,MAAM,QAAoB;GACxB,cAAc;GACd,kBAAkB;GAClB,aAAa;GACb,GAAI,gBAAgB,KAAA,IAAY,EAAE,aAAa,YAAY,IAAI,CAAC;EAClE;EAEA,OAAO;GACL,IAAI,KAAK,MAAM,KAAK,WAAW;GAC/B,SAAS,KAAK,QAAQ,KAAK,OAAO;IAChC,OAAO,EAAE;IACT,OAAO,EAAE;GACX,EAAE;GACF;EACF;CACF;AACF;;;;;;;;;;AAWA,SAAgB,mBACd,OACA,QACA,QAC6B;CAC7B,OAAO,IAAI,oBAAoB;EAAE;EAAQ,GAAG;CAAO,GAAG,KAAK;AAC7D;;;;;;;;;;;;;;;;;;;AAoBA,SAAgB,aACd,OACA,QAC6B;CAC7B,OAAO,mBAAmB,OAAO,uBAAuB,GAAG,MAAM;AACnE"}
1
+ {"version":3,"file":"rerank.js","names":[],"sources":["../../../src/adapters/rerank.ts"],"sourcesContent":["import { BaseRerankAdapter } from '@tanstack/ai/adapters'\nimport {\n COHERE_DEFAULT_BASE_URL,\n getCohereApiKeyFromEnv,\n} from '../utils/client'\nimport type { CohereClientConfig } from '../utils/client'\nimport type {\n CohereRerankModel,\n InferCohereRerankProviderOptions,\n} from '../model-meta'\nimport type {\n RerankAdapterResult,\n RerankOptions,\n TokenUsage,\n} from '@tanstack/ai'\n\n/** Shape of the Cohere `/v2/rerank` response we depend on. */\ninterface CohereRerankResponse {\n id?: string\n results: Array<{ index: number; relevance_score: number }>\n meta?: { billed_units?: { search_units?: number } }\n}\n\nfunction isCohereRerankResponse(value: unknown): value is CohereRerankResponse {\n if (typeof value !== 'object' || value === null) return false\n const results = (value as { results?: unknown }).results\n return (\n Array.isArray(results) &&\n results.every(\n (r) =>\n typeof r === 'object' &&\n r !== null &&\n typeof (r as { index?: unknown }).index === 'number' &&\n typeof (r as { relevance_score?: unknown }).relevance_score ===\n 'number',\n )\n )\n}\n\n/**\n * Cohere rerank adapter.\n *\n * Talks to Cohere's `/v2/rerank` endpoint over raw `fetch` — no SDK. Returns\n * scored indices into the submitted documents; the `rerank()` activity maps\n * those back to the caller's original documents.\n */\nexport class CohereRerankAdapter<\n TModel extends CohereRerankModel,\n> extends BaseRerankAdapter<TModel, InferCohereRerankProviderOptions<TModel>> {\n readonly name = 'cohere' as const\n\n private readonly apiKey: string\n private readonly baseUrl: string\n private readonly headers: Record<string, string>\n\n constructor(config: CohereClientConfig, model: TModel) {\n super({}, model)\n this.apiKey = config.apiKey\n this.baseUrl = (config.baseUrl ?? COHERE_DEFAULT_BASE_URL).replace(\n /\\/+$/,\n '',\n )\n this.headers = config.headers ?? {}\n }\n\n async rerank(\n options: RerankOptions<InferCohereRerankProviderOptions<TModel>>,\n ): Promise<RerankAdapterResult> {\n const { model, query, documents, topN, modelOptions, abortSignal, logger } =\n options\n\n const body: Record<string, unknown> = { model, query, documents }\n if (topN !== undefined) body['top_n'] = topN\n if (modelOptions?.maxTokensPerDoc !== undefined) {\n body['max_tokens_per_doc'] = modelOptions.maxTokensPerDoc\n }\n\n logger.request(\n `activity=rerank provider=${this.name} model=${model} documents=${documents.length}`,\n { provider: this.name, model },\n )\n\n let response: Response\n try {\n response = await fetch(`${this.baseUrl}/v2/rerank`, {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${this.apiKey}`,\n 'Content-Type': 'application/json',\n ...this.headers,\n },\n body: JSON.stringify(body),\n ...(abortSignal ? { signal: abortSignal } : {}),\n })\n } catch (error) {\n logger.errors(`${this.name}.rerank fatal`, {\n error,\n source: `${this.name}.rerank`,\n })\n throw error\n }\n\n if (!response.ok) {\n const detail = await response.text().catch(() => '')\n const error = new Error(\n `Cohere rerank request failed: ${response.status} ${response.statusText}${\n detail ? ` — ${detail}` : ''\n }`,\n )\n logger.errors(`${this.name}.rerank fatal`, {\n error,\n source: `${this.name}.rerank`,\n })\n throw error\n }\n\n const json: unknown = await response.json()\n if (!isCohereRerankResponse(json)) {\n throw new Error('Cohere rerank response had an unexpected shape')\n }\n\n const searchUnits = json.meta?.billed_units?.search_units\n const usage: TokenUsage = {\n promptTokens: 0,\n completionTokens: 0,\n totalTokens: 0,\n ...(searchUnits !== undefined\n ? {\n billed: { quantity: searchUnits, unit: 'units' },\n unitsBilled: searchUnits,\n }\n : {}),\n }\n\n return {\n id: json.id ?? this.generateId(),\n ranking: json.results.map((r) => ({\n index: r.index,\n score: r.relevance_score,\n })),\n usage,\n }\n }\n}\n\n/**\n * Creates a Cohere rerank adapter with an explicit API key. Type resolution\n * (per-model provider options) happens here at the call site.\n *\n * @example\n * ```typescript\n * const adapter = createCohereRerank('rerank-v3.5', 'co-...')\n * ```\n */\nexport function createCohereRerank<TModel extends CohereRerankModel>(\n model: TModel,\n apiKey: string,\n config?: Omit<CohereClientConfig, 'apiKey'>,\n): CohereRerankAdapter<TModel> {\n return new CohereRerankAdapter({ apiKey, ...config }, model)\n}\n\n/**\n * Creates a Cohere rerank adapter, reading `COHERE_API_KEY` from the\n * environment.\n *\n * @throws Error if `COHERE_API_KEY` is not found.\n *\n * @example\n * ```typescript\n * import { rerank } from '@tanstack/ai'\n * import { cohereRerank } from '@tanstack/ai-cohere'\n *\n * const { rerankedDocuments } = await rerank({\n * adapter: cohereRerank('rerank-v3.5'),\n * query: 'talk about rain',\n * documents: ['sunny day', 'rainy afternoon'],\n * })\n * ```\n */\nexport function cohereRerank<TModel extends CohereRerankModel>(\n model: TModel,\n config?: Omit<CohereClientConfig, 'apiKey'>,\n): CohereRerankAdapter<TModel> {\n return createCohereRerank(model, getCohereApiKeyFromEnv(), config)\n}\n"],"mappings":";;;AAuBA,SAAS,uBAAuB,OAA+C;CAC7E,IAAI,OAAO,UAAU,YAAY,UAAU,MAAM,OAAO;CACxD,MAAM,UAAW,MAAgC;CACjD,OACE,MAAM,QAAQ,OAAO,KACrB,QAAQ,OACL,MACC,OAAO,MAAM,YACb,MAAM,QACN,OAAQ,EAA0B,UAAU,YAC5C,OAAQ,EAAoC,oBAC1C,QACN;AAEJ;;;;;;;;AASA,IAAa,sBAAb,cAEU,kBAAoE;CAC5E,OAAgB;CAEhB;CACA;CACA;CAEA,YAAY,QAA4B,OAAe;EACrD,MAAM,CAAC,GAAG,KAAK;EACf,KAAK,SAAS,OAAO;EACrB,KAAK,WAAW,OAAO,WAAA,yBAAA,CAAoC,QACzD,QACA,EACF;EACA,KAAK,UAAU,OAAO,WAAW,CAAC;CACpC;CAEA,MAAM,OACJ,SAC8B;EAC9B,MAAM,EAAE,OAAO,OAAO,WAAW,MAAM,cAAc,aAAa,WAChE;EAEF,MAAM,OAAgC;GAAE;GAAO;GAAO;EAAU;EAChE,IAAI,SAAS,KAAA,GAAW,KAAK,WAAW;EACxC,IAAI,cAAc,oBAAoB,KAAA,GACpC,KAAK,wBAAwB,aAAa;EAG5C,OAAO,QACL,4BAA4B,KAAK,KAAK,SAAS,MAAM,aAAa,UAAU,UAC5E;GAAE,UAAU,KAAK;GAAM;EAAM,CAC/B;EAEA,IAAI;EACJ,IAAI;GACF,WAAW,MAAM,MAAM,GAAG,KAAK,QAAQ,aAAa;IAClD,QAAQ;IACR,SAAS;KACP,eAAe,UAAU,KAAK;KAC9B,gBAAgB;KAChB,GAAG,KAAK;IACV;IACA,MAAM,KAAK,UAAU,IAAI;IACzB,GAAI,cAAc,EAAE,QAAQ,YAAY,IAAI,CAAC;GAC/C,CAAC;EACH,SAAS,OAAO;GACd,OAAO,OAAO,GAAG,KAAK,KAAK,gBAAgB;IACzC;IACA,QAAQ,GAAG,KAAK,KAAK;GACvB,CAAC;GACD,MAAM;EACR;EAEA,IAAI,CAAC,SAAS,IAAI;GAChB,MAAM,SAAS,MAAM,SAAS,KAAK,CAAC,CAAC,YAAY,EAAE;GACnD,MAAM,wBAAQ,IAAI,MAChB,iCAAiC,SAAS,OAAO,GAAG,SAAS,aAC3D,SAAS,MAAM,WAAW,IAE9B;GACA,OAAO,OAAO,GAAG,KAAK,KAAK,gBAAgB;IACzC;IACA,QAAQ,GAAG,KAAK,KAAK;GACvB,CAAC;GACD,MAAM;EACR;EAEA,MAAM,OAAgB,MAAM,SAAS,KAAK;EAC1C,IAAI,CAAC,uBAAuB,IAAI,GAC9B,MAAM,IAAI,MAAM,gDAAgD;EAGlE,MAAM,cAAc,KAAK,MAAM,cAAc;EAC7C,MAAM,QAAoB;GACxB,cAAc;GACd,kBAAkB;GAClB,aAAa;GACb,GAAI,gBAAgB,KAAA,IAChB;IACE,QAAQ;KAAE,UAAU;KAAa,MAAM;IAAQ;IAC/C,aAAa;GACf,IACA,CAAC;EACP;EAEA,OAAO;GACL,IAAI,KAAK,MAAM,KAAK,WAAW;GAC/B,SAAS,KAAK,QAAQ,KAAK,OAAO;IAChC,OAAO,EAAE;IACT,OAAO,EAAE;GACX,EAAE;GACF;EACF;CACF;AACF;;;;;;;;;;AAWA,SAAgB,mBACd,OACA,QACA,QAC6B;CAC7B,OAAO,IAAI,oBAAoB;EAAE;EAAQ,GAAG;CAAO,GAAG,KAAK;AAC7D;;;;;;;;;;;;;;;;;;;AAoBA,SAAgB,aACd,OACA,QAC6B;CAC7B,OAAO,mBAAmB,OAAO,uBAAuB,GAAG,MAAM;AACnE"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tanstack/ai-cohere",
3
- "version": "0.1.1",
3
+ "version": "0.2.0",
4
4
  "description": "Cohere adapter for TanStack AI — multimodal embeddings and document reranking.",
5
5
  "author": "Tanner Linsley",
6
6
  "license": "MIT",
@@ -49,12 +49,12 @@
49
49
  "retrieval"
50
50
  ],
51
51
  "peerDependencies": {
52
- "@tanstack/ai": "^0.45.0"
52
+ "@tanstack/ai": "^0.46.0"
53
53
  },
54
54
  "devDependencies": {
55
55
  "@vitest/coverage-v8": "4.1.10",
56
56
  "vite": "^8.2.1",
57
- "@tanstack/ai": "0.45.0"
57
+ "@tanstack/ai": "0.46.0"
58
58
  },
59
59
  "dependencies": {
60
60
  "@tanstack/ai-utils": "^0.4.0"
@@ -124,7 +124,12 @@ export class CohereRerankAdapter<
124
124
  promptTokens: 0,
125
125
  completionTokens: 0,
126
126
  totalTokens: 0,
127
- ...(searchUnits !== undefined ? { unitsBilled: searchUnits } : {}),
127
+ ...(searchUnits !== undefined
128
+ ? {
129
+ billed: { quantity: searchUnits, unit: 'units' },
130
+ unitsBilled: searchUnits,
131
+ }
132
+ : {}),
128
133
  }
129
134
 
130
135
  return {