diff --git a/dist/buildinfo.json b/dist/buildinfo.json index 89851f0f..8dd6e4dd 100644 --- a/dist/buildinfo.json +++ b/dist/buildinfo.json @@ -1 +1 @@ -{"sha":"2e649eb","timestamp":1730180242} \ No newline at end of file +{"sha":"5ff2ee1","timestamp":1730359461} \ No newline at end of file diff --git a/dist/index.js b/dist/index.js index c45b9ef7..f6cea018 100644 --- a/dist/index.js +++ b/dist/index.js @@ -106,7 +106,7 @@ class MistralConfig { } class CohereConfig { COHERE_API_KEY = null; - COHERE_API_BASE = "https://api.cohere.com/v1"; + COHERE_API_BASE = "https://api.cohere.com/v2"; COHERE_CHAT_MODEL = "command-r-plus"; } class AnthropicConfig { @@ -211,8 +211,8 @@ const ENV_KEY_MAPPER = { WORKERS_AI_MODEL: "WORKERS_CHAT_MODEL" }; class Environment extends EnvironmentConfig { - BUILD_TIMESTAMP = 1730180242 ; - BUILD_VERSION = "2e649eb" ; + BUILD_TIMESTAMP = 1730359461 ; + BUILD_VERSION = "5ff2ee1" ; I18N = loadI18n(); PLUGINS_ENV = {}; USER_CONFIG = createAgentUserConfig(); @@ -958,7 +958,7 @@ function defaultSSEJsonParser(sse) { if (sse.data?.startsWith("[DONE]")) { return { finish: true }; } - if (sse.event === null && sse.data) { + if (sse.data) { try { return { data: JSON.parse(sse.data) }; } catch (e) { @@ -1417,39 +1417,12 @@ class AzureImageAI extends AzureBase { class Cohere { name = "cohere"; modelKey = "COHERE_CHAT_MODEL"; - static COHERE_ROLE_MAP = { - assistant: "CHATBOT", - user: "USER" - }; enable = (context) => { return !!context.COHERE_API_KEY; }; model = (ctx) => { return ctx.COHERE_CHAT_MODEL; }; - render = (item) => { - return { - role: Cohere.COHERE_ROLE_MAP[item.role] || "USER", - content: item.content - }; - }; - static parser(sse) { - switch (sse.event) { - case "text-generation": - try { - return { data: JSON.parse(sse.data || "") }; - } catch (e) { - console.error(e, sse.data); - return {}; - } - case "stream-start": - return {}; - case "stream-end": - return { finish: true }; - default: - return {}; - } - } request = async (params, context, onStream) => { const { message, prompt, history } = params; const url = `${context.COHERE_API_BASE}/chat`; @@ -1459,25 +1432,20 @@ class Cohere { "Accept": onStream !== null ? "text/event-stream" : "application/json" }; const messages = [...history || [], { role: "user", content: message }]; + if (prompt) { + messages.unshift({ role: "assistant", content: prompt }); + } const body = { - message, + messages, model: context.COHERE_CHAT_MODEL, - stream: onStream != null, - preamble: prompt, - chat_history: messages.map(this.render) + stream: onStream != null }; - if (!body.preamble) { - delete body.preamble; - } const options = {}; - options.streamBuilder = function(r, c) { - return new Stream(r, c, Cohere.parser); - }; options.contentExtractor = function(data) { - return data?.text; + return data?.delta?.message?.content?.text; }; options.fullContentExtractor = function(data) { - return data?.text; + return data?.messages[0].content; }; options.errorExtractor = function(data) { return data?.message; diff --git a/dist/timestamp b/dist/timestamp index 31e68c49..ff5f01a3 100644 --- a/dist/timestamp +++ b/dist/timestamp @@ -1 +1 @@ -1730180242 \ No newline at end of file +1730359461 \ No newline at end of file diff --git a/package.json b/package.json index 138c319d..012f4cd0 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,7 @@ "start:debug": "wrangler dev --local", "prepare:vercel": "tsx ./scripts/plugins/vercel/setenv.ts", "wrangler": "wrangler", - "test": "tsx ./src/config/env.test.ts" + "test": "tsx ./src/agent/index.test.ts" }, "dependencies": { "cloudflare-worker-adapter": "^1.3.3" diff --git a/src/agent/cohere.ts b/src/agent/cohere.ts index b2bddb1a..3085c971 100644 --- a/src/agent/cohere.ts +++ b/src/agent/cohere.ts @@ -1,19 +1,12 @@ import type { AgentUserConfig } from '../config/env'; import type { SseChatCompatibleOptions } from './request'; -import type { SSEMessage, SSEParserResult } from './stream'; -import type { ChatAgent, ChatStreamTextHandler, HistoryItem, LLMChatParams } from './types'; +import type { ChatAgent, ChatStreamTextHandler, LLMChatParams } from './types'; import { requestChatCompletions } from './request'; -import { Stream } from './stream'; export class Cohere implements ChatAgent { readonly name = 'cohere'; readonly modelKey = 'COHERE_CHAT_MODEL'; - static COHERE_ROLE_MAP: Record = { - assistant: 'CHATBOT', - user: 'USER', - }; - readonly enable = (context: AgentUserConfig): boolean => { return !!(context.COHERE_API_KEY); }; @@ -22,37 +15,6 @@ export class Cohere implements ChatAgent { return ctx.COHERE_CHAT_MODEL; }; - private render = (item: HistoryItem): any => { - return { - role: Cohere.COHERE_ROLE_MAP[item.role] || 'USER', - content: item.content, - }; - }; - - static parser(sse: SSEMessage): SSEParserResult { - // example: - // event: text-generation - // data: {"is_finished":false,"event_type":"text-generation","text":"?"} - // - // event: stream-end - // data: {"is_finished":true,...} - switch (sse.event) { - case 'text-generation': - try { - return { data: JSON.parse(sse.data || '') }; - } catch (e) { - console.error(e, sse.data); - return {}; - } - case 'stream-start': - return {}; - case 'stream-end': - return { finish: true }; - default: - return {}; - } - } - readonly request = async (params: LLMChatParams, context: AgentUserConfig, onStream: ChatStreamTextHandler | null): Promise => { const { message, prompt, history } = params; const url = `${context.COHERE_API_BASE}/chat`; @@ -63,27 +25,22 @@ export class Cohere implements ChatAgent { }; const messages = [...history || [], { role: 'user', content: message }]; + if (prompt) { + messages.unshift({ role: 'assistant', content: prompt }); + } const body = { - message, + messages, model: context.COHERE_CHAT_MODEL, stream: onStream != null, - preamble: prompt, - chat_history: messages.map(this.render), }; - if (!body.preamble) { - delete body.preamble; - } const options: SseChatCompatibleOptions = {}; - options.streamBuilder = function (r, c) { - return new Stream(r, c, Cohere.parser); - }; options.contentExtractor = function (data: any) { - return data?.text; + return data?.delta?.message?.content?.text; }; options.fullContentExtractor = function (data: any) { - return data?.text; + return data?.messages[0].content; }; options.errorExtractor = function (data: any) { return data?.message; diff --git a/src/agent/index.test.ts b/src/agent/index.test.ts index 4ed2d6b2..ffe7724f 100644 --- a/src/agent/index.test.ts +++ b/src/agent/index.test.ts @@ -6,7 +6,7 @@ import '../config/env.test'; { const agent = loadChatLLM({ ...ENV.USER_CONFIG, - AI_PROVIDER: 'anthropic', + AI_PROVIDER: 'cohere', }); const params: LLMChatParams = { prompt: 'You are a useful assistant.', diff --git a/src/agent/stream.ts b/src/agent/stream.ts index fd75a92a..43ccce66 100644 --- a/src/agent/stream.ts +++ b/src/agent/stream.ts @@ -138,7 +138,7 @@ function defaultSSEJsonParser(sse: SSEMessage): SSEParserResult { if (sse.data?.startsWith('[DONE]')) { return { finish: true }; } - if (sse.event === null && sse.data) { + if (sse.data) { try { return { data: JSON.parse(sse.data) }; } catch (e) { diff --git a/src/config/config.ts b/src/config/config.ts index 7fc98f10..041f7d63 100644 --- a/src/config/config.ts +++ b/src/config/config.ts @@ -169,7 +169,7 @@ export class CohereConfig { // cohere api key COHERE_API_KEY: string | null = null; // cohere api base - COHERE_API_BASE = 'https://api.cohere.com/v1'; + COHERE_API_BASE = 'https://api.cohere.com/v2'; // cohere api model COHERE_CHAT_MODEL = 'command-r-plus'; }