From 6497f760bd8c1d264d8fd51f39df328fc5486f0c Mon Sep 17 00:00:00 2001 From: sanpinapipi <154422356+sanpinapipi@users.noreply.github.com> Date: Wed, 29 Jan 2025 00:58:33 +0100 Subject: [PATCH 1/6] Add files via upload Integrates You.com chatbot using session cookie. Supports conversation history + "create" chatMode (image generation). --- src/services/apis/you-web.mjs | 114 ++++++++++++++++++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100644 src/services/apis/you-web.mjs diff --git a/src/services/apis/you-web.mjs b/src/services/apis/you-web.mjs new file mode 100644 index 00000000..3a7475d1 --- /dev/null +++ b/src/services/apis/you-web.mjs @@ -0,0 +1,114 @@ +// path/to/services/apis/you-web.mjs + +import { pushRecord, setAbortController } from '../../services/apis/shared.mjs' +import { fetchSSE } from '../../utils/fetch-sse.mjs' +import { getUserConfig, youWebModelKeys } from '../../config/index.mjs' +import { getConversationPairs } from '../../utils/get-conversation-pairs.mjs' +import { getModelValue, isUsingModelName } from '../../utils/model-name-convert.mjs' + +/** + * @param {Runtime.Port} port + * @param {string} question + * @param {Session} session + * @param {string} sessionCookie + */ +export async function generateAnswersWithYouWebApi(port, question, session, sessionCookie) { + const { controller, cleanController } = setAbortController(port) + const config = await getUserConfig() + const model = getModelValue(session) + + const apiUrl = 'https://you.com/api/streamingSearch' + + // Use the existing chatId from the session or generate a new one + if (!session.chatId) { + session.chatId = generateUUID() // You need a function to generate UUIDs + } + + // Always include the conversation history + const conversationContext = getConversationPairs(session.conversationRecords, false) + + const traceId = `${session.chatId}|${session.messageId}|${new Date().toISOString()}` + + const params = new URLSearchParams() + params.append('page', '1') + params.append('count', '10') + params.append('safeSearch', 'Off') + params.append('q', question) + params.append('chatId', session.chatId) // Use the existing or new chatId + params.append('traceId', traceId) + params.append('conversationTurnId', session.messageId) + params.append('selectedAiModel', model) + + // Conditional chatMode based on modelName + let chatMode = 'custom' + if (isUsingModelName('create', session)) { + chatMode = 'create' + } + params.append('selectedChatMode', chatMode) + + params.append('pastChatLength', session.conversationRecords.length.toString()) + params.append('queryTraceId', traceId) + params.append('use_personalization_extraction', 'false') + params.append('domain', 'youchat') + params.append('mkt', 'en-US') + params.append('chat', JSON.stringify(conversationContext)) + + const url = `${apiUrl}?${params.toString()}` + + let answer = '' + + await fetchSSE(url, { + method: 'GET', + signal: controller.signal, + headers: { + 'Content-Type': 'text/event-stream;charset=utf-8', + Cookie: `sessionKey=${sessionCookie}`, + 'User-Agent': navigator.userAgent, + }, + onMessage(message) { + if (message.trim() === '[DONE]') { + finishMessage() + return + } + + let data + try { + data = JSON.parse(message) + } catch (error) { + console.error('SSE message parse error:', error) + return + } + + if (data.youChatToken) { + answer += data.youChatToken + port.postMessage({ answer: answer, done: false, session: null }) + } + }, + onStart() { + // Handle start if needed + }, + onEnd() { + finishMessage() + port.postMessage({ done: true }) + cleanController() + }, + onError(error) { + cleanController() + port.postMessage({ error: error.message, done: true }) + }, + }) + + function finishMessage() { + pushRecord(session, question, answer) + port.postMessage({ answer: answer, done: true, session: session }) + } +} + +// Helper function to generate UUIDs (you can use a library for this if you prefer) +function generateUUID() { + return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { + var r = (Math.random() * 16) | 0, + v = c == 'x' ? r : (r & 0x3) | 0x8 + return v.toString(16) + }) +} From 837499fb76ec4ace2ead0708d7088a373d99500d Mon Sep 17 00:00:00 2001 From: sanpinapipi <154422356+sanpinapipi@users.noreply.github.com> Date: Wed, 29 Jan 2025 01:32:25 +0100 Subject: [PATCH 2/6] Integrates You.com chatbot using session cookie. Integrates You.com chatbot using session cookie. Supports conversation history + "create" chatMode (image generation). --- src/services/wrappers.mjs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/services/wrappers.mjs b/src/services/wrappers.mjs index c828f903..315ba0fb 100644 --- a/src/services/wrappers.mjs +++ b/src/services/wrappers.mjs @@ -1,4 +1,5 @@ import { +import { getYouSessionKey } from "../utils/wrappers.mjs"; clearOldAccessToken, getUserConfig, isUsingBingWebModel, @@ -7,7 +8,9 @@ import { } from '../config/index.mjs' import Browser from 'webextension-polyfill' import { t } from 'i18next' +import { getYouSessionKey } from "../utils/wrappers.mjs"; import { apiModeToModelName, modelNameToDesc } from '../utils/model-name-convert.mjs' +import { getYouSessionKey } from "../utils/wrappers.mjs"; export async function getChatGptAccessToken() { await clearOldAccessToken() @@ -71,6 +74,10 @@ export function handlePortError(session, port, err) { port.postMessage({ error: 'UNAUTHORIZED' }) else if ( isUsingClaudeWebModel(session) && + else if (isUsingYouWebModel(session) && ['Invalid sessionKey', 'sessionKey is required'].some((m) => err.message.includes(m))) + port.postMessage({ + error: t('Please login at https://you.com first, and then click the retry button'), + }) ['Invalid authorization', 'Session key required'].some((m) => err.message.includes(m)) ) port.postMessage({ @@ -127,3 +134,7 @@ export function registerPortListener(executor) { port.onDisconnect.addListener(onDisconnect) }) } + +export async function getYouSessionKey() { + return (await Browser.cookies.get({ url: 'https://you.com/', name: 'sessionKey' }))?.value; +} From 25317c56d8c176cb145a609f6350fad52864d71d Mon Sep 17 00:00:00 2001 From: sanpinapipi <154422356+sanpinapipi@users.noreply.github.com> Date: Wed, 29 Jan 2025 01:34:14 +0100 Subject: [PATCH 3/6] Integrates You.com chatbot using session cookie. Integrates You.com chatbot using session cookie. Supports conversation history + "create" chatMode (image generation). --- src/background/index.mjs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/background/index.mjs b/src/background/index.mjs index 6fde2d48..6c5d678d 100644 --- a/src/background/index.mjs +++ b/src/background/index.mjs @@ -27,6 +27,7 @@ import { isUsingOllamaApiModel, isUsingAzureOpenAiApiModel, isUsingClaudeApiModel, + isUsingYouWebModel, isUsingChatGLMApiModel, isUsingGithubThirdPartyApiModel, isUsingGeminiWebModel, @@ -41,8 +42,10 @@ import { getBingAccessToken, getChatGptAccessToken, getClaudeSessionKey, + getYouSessionKey, registerPortListener, } from '../services/wrappers.mjs' +import { generateAnswersWithYouWebApi } from '../services/apis/you-web.mjs' import { refreshMenu } from './menus.mjs' import { registerCommands } from './commands.mjs' import { generateAnswersWithBardWebApi } from '../services/apis/bard-web.mjs' @@ -117,6 +120,9 @@ async function executeApi(session, port, config) { await generateAnswersWithChatgptWebApi(port, session.question, session, accessToken) } } else if (isUsingClaudeWebModel(session)) { + } else if (isUsingYouWebModel(session)) { + const sessionKey = await getYouSessionKey(); + await generateAnswersWithYouWebApi(port, session.question, session, sessionKey); const sessionKey = await getClaudeSessionKey() await generateAnswersWithClaudeWebApi(port, session.question, session, sessionKey) } else if (isUsingMoonshotWebModel(session)) { From 5e460e4ad0c5571fa094a99546eae3f2d876f307 Mon Sep 17 00:00:00 2001 From: sanpinapipi <154422356+sanpinapipi@users.noreply.github.com> Date: Wed, 29 Jan 2025 02:13:06 +0100 Subject: [PATCH 4/6] Integrates You.com chatbot using session cookie. Supports conversation history + "create" chatMode (image generation). Integrates You.com chatbot using session cookie. Supports conversation history + "create" chatMode (image generation).1 --- src/background/index.mjs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/background/index.mjs b/src/background/index.mjs index 6c5d678d..601afa90 100644 --- a/src/background/index.mjs +++ b/src/background/index.mjs @@ -120,11 +120,11 @@ async function executeApi(session, port, config) { await generateAnswersWithChatgptWebApi(port, session.question, session, accessToken) } } else if (isUsingClaudeWebModel(session)) { - } else if (isUsingYouWebModel(session)) { - const sessionKey = await getYouSessionKey(); - await generateAnswersWithYouWebApi(port, session.question, session, sessionKey); const sessionKey = await getClaudeSessionKey() await generateAnswersWithClaudeWebApi(port, session.question, session, sessionKey) + } else if (isUsingYouWebModel(session)) { + const sessionKey = await getYouSessionKey() + await generateAnswersWithYouWebApi(port, session.question, session, sessionKey) } else if (isUsingMoonshotWebModel(session)) { await generateAnswersWithMoonshotWebApi(port, session.question, session, config) } else if (isUsingBingWebModel(session)) { From cfaba62c7b4b097dec29a33a95580eaea0feed6a Mon Sep 17 00:00:00 2001 From: sanpinapipi <154422356+sanpinapipi@users.noreply.github.com> Date: Wed, 29 Jan 2025 02:13:43 +0100 Subject: [PATCH 5/6] Integrates You.com chatbot using session cookie. Supports conversation history + "create" chatMode (image generation). Integrates You.com chatbot using session cookie. Supports conversation history + "create" chatMode (image generation). --- src/services/wrappers.mjs | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/src/services/wrappers.mjs b/src/services/wrappers.mjs index 315ba0fb..7cfd36ac 100644 --- a/src/services/wrappers.mjs +++ b/src/services/wrappers.mjs @@ -1,5 +1,4 @@ import { -import { getYouSessionKey } from "../utils/wrappers.mjs"; clearOldAccessToken, getUserConfig, isUsingBingWebModel, @@ -8,9 +7,7 @@ import { getYouSessionKey } from "../utils/wrappers.mjs"; } from '../config/index.mjs' import Browser from 'webextension-polyfill' import { t } from 'i18next' -import { getYouSessionKey } from "../utils/wrappers.mjs"; import { apiModeToModelName, modelNameToDesc } from '../utils/model-name-convert.mjs' -import { getYouSessionKey } from "../utils/wrappers.mjs"; export async function getChatGptAccessToken() { await clearOldAccessToken() @@ -54,6 +51,10 @@ export async function getClaudeSessionKey() { return (await Browser.cookies.get({ url: 'https://claude.ai/', name: 'sessionKey' }))?.value } +export async function getYouSessionKey() { + return (await Browser.cookies.get({ url: 'https://you.com/', name: 'sessionKey' }))?.value +} + export function handlePortError(session, port, err) { console.error(err) if (err.message) { @@ -74,10 +75,6 @@ export function handlePortError(session, port, err) { port.postMessage({ error: 'UNAUTHORIZED' }) else if ( isUsingClaudeWebModel(session) && - else if (isUsingYouWebModel(session) && ['Invalid sessionKey', 'sessionKey is required'].some((m) => err.message.includes(m))) - port.postMessage({ - error: t('Please login at https://you.com first, and then click the retry button'), - }) ['Invalid authorization', 'Session key required'].some((m) => err.message.includes(m)) ) port.postMessage({ @@ -134,7 +131,3 @@ export function registerPortListener(executor) { port.onDisconnect.addListener(onDisconnect) }) } - -export async function getYouSessionKey() { - return (await Browser.cookies.get({ url: 'https://you.com/', name: 'sessionKey' }))?.value; -} From 2a5c650e3f736068661691b2d8df33f608de252f Mon Sep 17 00:00:00 2001 From: sanpinapipi <154422356+sanpinapipi@users.noreply.github.com> Date: Wed, 29 Jan 2025 02:15:08 +0100 Subject: [PATCH 6/6] Integrates You.com chatbot using session cookie. Supports conversation history + "create" chatMode (image generation). Integrates You.com chatbot using session cookie. Supports conversation history + "create" chatMode (image generation). --- src/config/index.mjs | 103 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 90 insertions(+), 13 deletions(-) diff --git a/src/config/index.mjs b/src/config/index.mjs index ecc1620e..a2766ef8 100644 --- a/src/config/index.mjs +++ b/src/config/index.mjs @@ -39,6 +39,33 @@ export const chatgptWebModelKeys = [ export const bingWebModelKeys = ['bingFree4', 'bingFreeSydney'] export const bardWebModelKeys = ['bardWebFree'] export const claudeWebModelKeys = ['claude2WebFree'] +export const youWebModelKeys = [ + 'create', + 'openai_o1', + 'openai_o1_preview', + 'openai_o1_mini', + 'gpt_4o_mini', + 'gpt_4o', + 'gpt_4_turbo', + 'gpt_4', + 'grok_2', + 'claude_3_5_sonnet', + 'claude_3_opus', + 'claude_3_sonnet', + 'claude_3_5_haiku', + 'llama3_3_70b', + 'llama3_2_90b', + 'llama3_1_405b', + 'mistral_large_2', + 'gemini_1_5_flash', + 'gemini_1_5_pro', + 'databricks_dbrx_instruct', + 'qwen2p5_72b', + 'qwen2p5_coder_32b', + 'command_r_plus', + 'solar_1_mini', + 'dolphin_2_5', +] export const moonshotWebModelKeys = ['moonshotWebFree'] export const gptApiModelKeys = ['gptApiInstruct', 'gptApiDavinci'] export const chatgptApiModelKeys = [ @@ -100,10 +127,14 @@ export const ModelGroups = { value: chatgptWebModelKeys, desc: 'ChatGPT (Web)', }, - claudeWebModelKeys: { + claudeWebModelKeys: { value: claudeWebModelKeys, desc: 'Claude.ai (Web)', }, + youWebModelKeys: { + value: youWebModelKeys, + desc: 'You.com (Web)', + }, moonshotWebModelKeys: { value: moonshotWebModelKeys, desc: 'Kimi.Moonshot (Web)', @@ -217,6 +248,8 @@ export const Models = { moonshotWebFree: { value: '', desc: 'Kimi.Moonshot (Web, 100k)' }, bardWebFree: { value: '', desc: 'Gemini (Web)' }, + youWebFree: { value: "", desc: "You.com (Web)" }, // Added You.com model + create: { value: "create", desc: "You.com (Web, Create Mode)" }, // Added You.com create model chatglmTurbo: { value: 'GLM-4-Air', desc: 'ChatGLM (GLM-4-Air, 128k)' }, chatglm4: { value: 'GLM-4-0520', desc: 'ChatGLM (GLM-4-0520, 128k)' }, @@ -233,6 +266,33 @@ export const Models = { gptApiInstruct: { value: 'gpt-3.5-turbo-instruct', desc: 'GPT-3.5-turbo Instruct' }, gptApiDavinci: { value: 'text-davinci-003', desc: 'GPT-3.5' }, + + create: { value: 'create', desc: 'YouWeb create' }, + openai_o1: { value: 'openai_o1', desc: 'YouWeb openai_o1' }, + openai_o1_preview: { value: 'openai_o1_preview', desc: 'YouWeb openai_o1_preview' }, + openai_o1_mini: { value: 'openai_o1_mini', desc: 'YouWeb openai_o1_mini' }, + gpt_4o_mini: { value: 'gpt_4o_mini', desc: 'YouWeb gpt_4o_mini' }, + gpt_4o: { value: 'gpt_4o', desc: 'YouWeb gpt_4o' }, + gpt_4_turbo: { value: 'gpt_4_turbo', desc: 'YouWeb gpt_4_turbo' }, + gpt_4: { value: 'gpt_4', desc: 'YouWeb gpt_4' }, + grok_2: { value: 'grok_2', desc: 'YouWeb grok_2' }, + claude_3_5_sonnet: { value: 'claude_3_5_sonnet', desc: 'YouWeb claude_3_5_sonnet' }, + claude_3_opus: { value: 'claude_3_opus', desc: 'YouWeb claude_3_opus' }, + claude_3_sonnet: { value: 'claude_3_sonnet', desc: 'YouWeb claude_3_sonnet' }, + claude_3_5_haiku: { value: 'claude_3_5_haiku', desc: 'YouWeb claude_3_5_haiku' }, + llama3_3_70b: { value: 'llama3_3_70b', desc: 'YouWeb llama3_3_70b' }, + llama3_2_90b: { value: 'llama3_2_90b', desc: 'YouWeb llama3_2_90b' }, + llama3_1_405b: { value: 'llama3_1_405b', desc: 'YouWeb llama3_1_405b' }, + mistral_large_2: { value: 'mistral_large_2', desc: 'YouWeb mistral_large_2' }, + gemini_1_5_flash: { value: 'gemini_1_5_flash', desc: 'YouWeb gemini_1_5_flash' }, + gemini_1_5_pro: { value: 'gemini_1_5_pro', desc: 'YouWeb gemini_1_5_pro' }, + databricks_dbrx_instruct: { value: 'databricks_dbrx_instruct', desc: 'YouWeb databricks_dbrx_instruct' }, + qwen2p5_72b: { value: 'qwen2p5_72b', desc: 'YouWeb qwen2p5_72b' }, + qwen2p5_coder_32b: { value: 'qwen2p5_coder_32b', desc: 'YouWeb qwen2p5_coder_32b' }, + command_r_plus: { value: 'command_r_plus', desc: 'YouWeb command_r_plus' }, + solar_1_mini: { value: 'solar_1_mini', desc: 'YouWeb solar_1_mini' }, + dolphin_2_5: { value: 'dolphin_2_5', desc: 'YouWeb dolphin_2_5' }, + customModel: { value: '', desc: 'Custom Model' }, ollamaModel: { value: '', desc: 'Ollama API' }, @@ -355,18 +415,31 @@ export const defaultConfig = { // It allows the content of activeApiModes to change with version updates when the user has not customized ApiModes. // If it were directly written into customApiModes, the value would become fixed, even if the user has not made any customizations. activeApiModes: [ - 'chatgptFree35', - 'chatgptFree4o', - 'chatgptApi35', - 'chatgptApi4o_128k', - 'claude2WebFree', - 'claude35SonnetApi', - 'bingFree4', - 'moonshotWebFree', - 'moonshot_v1_8k', - 'chatglmTurbo', - 'customModel', - 'azureOpenAi', + 'create', + 'openai_o1', + 'openai_o1_preview', + 'openai_o1_mini', + 'gpt_4o_mini', + 'gpt_4o', + 'gpt_4_turbo', + 'gpt_4', + 'grok_2', + 'claude_3_5_sonnet', + 'claude_3_opus', + 'claude_3_sonnet', + 'claude_3_5_haiku', + 'llama3_3_70b', + 'llama3_2_90b', + 'llama3_1_405b', + 'mistral_large_2', + 'gemini_1_5_flash', + 'gemini_1_5_pro', + 'databricks_dbrx_instruct', + 'qwen2p5_72b', + 'qwen2p5_coder_32b', + 'command_r_plus', + 'solar_1_mini', + 'dolphin_2_5', ], customApiModes: [ { @@ -470,6 +543,10 @@ export function isUsingClaudeWebModel(configOrSession) { return isInApiModeGroup(claudeWebModelKeys, configOrSession) } +export function isUsingYouWebModel(configOrSession) { + return isInApiModeGroup(youWebModelKeys, configOrSession) +} + export function isUsingMoonshotWebModel(configOrSession) { return isInApiModeGroup(moonshotWebModelKeys, configOrSession) }