fixed the issue that the drop down was too small, and fixed the issue where the route was not displayed on the screen

This commit is contained in:
Salman Paracha 2025-07-02 18:35:00 -07:00
parent bb2eb02030
commit 0520293b24
6 changed files with 72 additions and 14 deletions

View file

@ -17,7 +17,7 @@
},
"web_accessible_resources": [
{
"resources": ["index.html"],
"resources": ["index.html", "logo.png"],
"matches": ["https://chatgpt.com/*"]
},
{

View file

@ -5,11 +5,22 @@ export default function App() {
return (
<div className="bg-gray-100 min-h-screen flex items-center justify-center p-4">
<div className="w-full max-w-6xl">
<div className="text-center mb-8">
<h1 className="text-3xl font-bold text-gray-800">RouteGPT</h1>
<p className="text-gray-600 mt-2">Dynamically route to GPT models based on usage preferences.</p>
<a target="_blank" href="https://github.com/katanemo/archgw" className="text-blue-500 hover:underline">powered by Arch Router</a>
<div className="text-center mb-8">
<div className="flex justify-center items-center gap-3 -ml-12">
<img src="/logo.png" alt="RouteGPT Logo" className="w-10 h-10" />
<h1 className="text-3xl font-bold text-gray-800">RouteGPT</h1>
</div>
<p className="text-gray-600 mt-2">
Dynamically route to GPT models based on usage preferences.
</p>
<a
target="_blank"
href="https://github.com/katanemo/archgw"
className="text-blue-500 hover:underline"
>
powered by Arch Router
</a>
</div>
<PreferenceBasedModelSelector />
</div>
</div>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

View file

@ -44,4 +44,21 @@ try {
process.exit(1);
}
// 4⃣ Copy logo.png from src/assets to build root
try {
const logoSource = path.join(reactAppDir, 'src', 'assets', 'logo.png');
const logoDest = path.join(buildDir, 'logo.png');
if (!fs.existsSync(logoSource)) {
throw new Error(`Missing logo.png at ${logoSource}`);
}
fs.copyFileSync(logoSource, logoDest);
console.log(`Copied logo.png → ${logoDest}`);
} catch (err) {
console.error('Failed to copy logo.png:', err);
process.exit(1);
}
console.log('Extension build process finished successfully!');

View file

@ -8,12 +8,8 @@ const MODEL_LIST = [
'gpt-4.1-mini',
'gpt-4.5-preview',
'o3',
'o3-pro',
'o4-mini',
'o4-mini-high',
'o1',
'o1-mini',
'o1-pro'
'o4-mini-high'
];
// --- Mocked lucide-react icons as SVG components ---
@ -185,9 +181,9 @@ export default function PreferenceBasedModelSelector() {
{routingEnabled && (
<div className="pt-4 mt-4 space-y-3 border-t border-gray-200">
{preferences.map((pref) => (
<div key={pref.id} className="grid grid-cols-[3fr_1fr_auto] gap-4 items-center">
<div key={pref.id} className="grid grid-cols-[3fr_1.5fr_auto] gap-4 items-center">
<Input
placeholder="Usage (e.g. generate tests)"
placeholder="(e.g. generating fictional stories or poems)"
value={pref.usage}
onChange={(e) => updatePreference(pref.id, 'usage', e.target.value)}
/>
@ -219,7 +215,7 @@ export default function PreferenceBasedModelSelector() {
</Card>
<Card className="w-full">
<CardContent>
<Label>Default Model on Page Load</Label>
<Label>Default Model</Label>
<select
value={defaultModel}
onChange={(e) => setDefaultModel(e.target.value)}

View file

@ -1,6 +1,6 @@
(() => {
const TAG = '[ModelSelector]';
// Content script to intercept fetch requests and modify them based on user preferences
async function streamToPort(response, port) {
const reader = response.body?.getReader();
if (!reader) {
@ -17,6 +17,7 @@
}
}
// Extract messages from the DOM, falling back to requestMessages if DOM is empty
function getMessagesFromDom(requestMessages = null) {
const bubbles = [...document.querySelectorAll('[data-message-author-role]')];
@ -46,8 +47,40 @@
return domMessages;
}
// Insert a route label for the last user message in the chat
function insertRouteLabelForLastUserMessage(routeName) {
chrome.storage.sync.get(['preferences'], ({ preferences }) => {
if (!Array.isArray(preferences)) return;
const match = preferences.find(p => p.name === routeName);
if (!match || !match.usage) {
console.warn('[RouteLabel] No usage found for route:', routeName);
return;
}
const bubbles = [...document.querySelectorAll('[data-message-author-role="user"]')];
const lastBubble = bubbles[bubbles.length - 1];
if (!lastBubble) return;
if (lastBubble.querySelector('.arch-route-label')) {
console.log('[RouteLabel] Label already exists, skipping');
return;
}
const label = document.createElement('span');
label.textContent = `RouteGPT preference >> ${match.usage}`;
label.className = 'arch-route-label';
label.style.fontWeight = '100';
label.style.fontSize = '0.85rem';
label.style.marginTop = '4px';
lastBubble.appendChild(label);
console.log('[RouteLabel] Inserted label:', label.textContent);
});
}
// Prepare the system prompt for the proxy request
function prepareProxyRequest(messages, routes, maxTokenLength = 2048) {
const SYSTEM_PROMPT_TEMPLATE = `
You are a helpful assistant designed to find the best suited route.
@ -219,6 +252,7 @@ Based on your analysis, provide your response in the following JSON formats if y
if (selectedRoute) {
targetModel = await getModelIdForRoute(selectedRoute);
console.log(`${TAG} Resolved model for route "${selectedRoute}" →`, targetModel);
insertRouteLabelForLastUserMessage(selectedRoute);
}
const modifiedBody = { ...originalBody };