From c9539d21f768129cca47ce8395bb512067822b21 Mon Sep 17 00:00:00 2001 From: Salman Paracha Date: Tue, 1 Jul 2025 09:43:29 -0700 Subject: [PATCH] converting conversation into messages object --- .../src/App.js | 4 +- .../src/scripts/content.js | 46 +++++++++++++++++-- .../src/scripts/pageFetchOverride.js | 34 ++++++++++++-- 3 files changed, 73 insertions(+), 11 deletions(-) diff --git a/demos/use_cases/chatgpt-preference-model-selector/src/App.js b/demos/use_cases/chatgpt-preference-model-selector/src/App.js index 3617e554..f0e2522b 100644 --- a/demos/use_cases/chatgpt-preference-model-selector/src/App.js +++ b/demos/use_cases/chatgpt-preference-model-selector/src/App.js @@ -6,8 +6,8 @@ export default function App() {
-

ChatGPT Usage Preferences

-

Define your usage preferences for each type of ChatGPT model.

+

ChatGPT Model Selector

+

Define usage preferences to optimize model selection.

diff --git a/demos/use_cases/chatgpt-preference-model-selector/src/scripts/content.js b/demos/use_cases/chatgpt-preference-model-selector/src/scripts/content.js index 4fba5b28..9a34d691 100644 --- a/demos/use_cases/chatgpt-preference-model-selector/src/scripts/content.js +++ b/demos/use_cases/chatgpt-preference-model-selector/src/scripts/content.js @@ -28,14 +28,51 @@ /**─────────────────────── 2️⃣ Handle proxied fetch from the page ───────────────────────**/ window.addEventListener('message', ev => { console.log('[ModelSelector] page→content message', ev.data, ev.ports); + if (ev.source !== window || ev.data?.type !== 'ARCHGW_FETCH') return; - const { url, init } = ev.data; + + const { url, init, originalRequestUrl } = ev.data; const port = ev.ports[0]; (async () => { try { - const res = await fetch(url, init); - const reader = res.body.getReader(); + console.log('[ModelSelector] Fetching model recommendation from local proxy...'); + //const res = await fetch(url, init); + //const json = await res.json(); + + //console.log('[ModelSelector] Proxy responded with:', json); + + const targetModel = 'o4-mini-high'; + if (!targetModel) { + console.warn('[ModelSelector] No model returned from proxy, using default fetch'); + port.postMessage({ done: true }); + return; + } + + // ✅ Extract the original fetch request body from init.body + let originalBody = {}; + try { + originalBody = JSON.parse(init.body); + } catch { + console.warn('[ModelSelector] Could not parse original fetch body'); + } + + // ✅ Patch the model in the request + originalBody.model = targetModel; + + console.log(`[ModelSelector] Updating model in request → ${targetModel}`); + + // ✅ Resume the request to the real backend + const upstreamRes = await fetch('/backend-api/conversation', { + method: init.method, + headers: init.headers, + credentials: init.credentials, + body: JSON.stringify(originalBody) + }); + + // ✅ Stream the upstream response back to the page + const reader = upstreamRes.body.getReader(); + while (true) { const { done, value } = await reader.read(); if (done) { @@ -46,12 +83,13 @@ } } } catch (err) { - console.error(`${TAG} proxy fetch error`, err); + console.error('[ModelSelector] proxy fetch error', err); port.postMessage({ done: true }); } })(); }); + /**─────────────────────── 3️⃣ DOM patch for model selector label ───────────────────────**/ let desiredModel = null; function patchDom() { diff --git a/demos/use_cases/chatgpt-preference-model-selector/src/scripts/pageFetchOverride.js b/demos/use_cases/chatgpt-preference-model-selector/src/scripts/pageFetchOverride.js index 56c6c002..f27a0ee2 100644 --- a/demos/use_cases/chatgpt-preference-model-selector/src/scripts/pageFetchOverride.js +++ b/demos/use_cases/chatgpt-preference-model-selector/src/scripts/pageFetchOverride.js @@ -4,6 +4,7 @@ console.log(`${TAG} installing fetch override`); window.archgwSettings = window.archgwSettings || { preferences: [], defaultModel: null }; + window.addEventListener('message', ev => { if (ev.source === window && ev.data?.type === 'PBMS_SETTINGS') { window.archgwSettings = ev.data.settings; @@ -11,6 +12,24 @@ } }); + // New function: scrape current messages from the DOM + function get_messages() { + const bubbles = [...document.querySelectorAll('[data-message-author-role]')]; + + const messages = bubbles + .map(b => { + const role = b.getAttribute('data-message-author-role'); // "user" | "assistant" + const content = + role === 'assistant' + ? (b.querySelector('.markdown')?.innerText ?? b.innerText ?? '').trim() + : (b.innerText ?? '').trim(); + return content ? { role, content } : null; + }) + .filter(Boolean); + + return { messages }; + } + const origFetch = window.fetch; window.fetch = async function(input, init = {}) { const urlString = typeof input === 'string' ? input : input.url; @@ -26,17 +45,24 @@ if (pathname === '/backend-api/conversation') { console.log(`${TAG} matched conversation → proxy via content script`); - // patch metadata let body = {}; try { body = JSON.parse(init.body); } catch {} + + const currentMessages = get_messages(); + console.log(`${TAG} scraped messages →`, currentMessages); + + // Patch metadata with current preferences body.metadata = { archgw_preference_config: window.archgwSettings.preferences .map(p => `- name: ${p.name}\n model: ${p.model}\n usage: ${p.usage}`) - .join('\n') + .join('\n'), + + // Add current messages dynamically + archgw_current_messages: JSON.stringify(currentMessages) }; + init.body = JSON.stringify(body); - // send only the serializable parts of `init` const safeInit = { method: init.method, headers: init.headers, @@ -44,7 +70,6 @@ credentials: init.credentials }; - // set up MessageChannel const { port1, port2 } = new MessageChannel(); window.postMessage({ type: 'ARCHGW_FETCH', @@ -52,7 +77,6 @@ init: safeInit }, '*', [port2]); - // return streaming response return new Response(new ReadableStream({ start(controller) { port1.onmessage = ({ data }) => {