Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions apps/webapp/app/api/internal-proxy/steer-chat/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { NextRequest, NextResponse } from 'next/server';

export async function POST(request: NextRequest) {
try {
const originalPayload = await request.json();
const apiKey = request.headers.get('X-Forwarded-Client-API-Key');

const targetUrl = 'https://www.neuronpedia.org/api/steer-chat';
const externalHeaders: HeadersInit = {
'Content-Type': 'application/json',
};

if (apiKey) {
externalHeaders['X-API-Key'] = apiKey;
}

const externalResponse = await fetch(targetUrl, {
method: 'POST',
headers: externalHeaders,
body: JSON.stringify(originalPayload),
});

// Try to parse JSON, but if it fails, it might be a non-JSON error response
let data;
try {
data = await externalResponse.json();
} catch (e) {
// If JSON parsing fails, try to get text, it might be an HTML error page or plain text
const textError = await externalResponse.text();
// If the original request was not ok, and we couldn't parse JSON, return the text error
if (!externalResponse.ok) {
return NextResponse.json({ error: 'Failed to proxy request', details: textError }, { status: externalResponse.status || 500 });
}
// If it was ok, but not JSON (unlikely for an API), this is an unexpected situation
return NextResponse.json({ error: 'Unexpected response format from external API', details: textError }, { status: 500 });
}

if (!externalResponse.ok) {
// Forward the error response from the external API (already parsed as JSON)
return NextResponse.json(data, { status: externalResponse.status });
}

return NextResponse.json(data, { status: externalResponse.status });

} catch (error: any) {
console.error('Proxy error:', error);
// Check if the error is a TypeError from request.json() failing (e.g. empty body for GET)
// Though for POST, a body is expected. This is more a general guard.
if (error instanceof TypeError && error.message.includes('body stream already read') || error.message.includes('JSON Parse error')) {
return NextResponse.json({ error: 'Invalid request payload' }, { status: 400 });
}
return NextResponse.json({ error: 'Internal Server Error during proxying' }, { status: 500 });
}
}
38 changes: 38 additions & 0 deletions apps/webapp/app/api/proxy-steer-chat/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { NextRequest, NextResponse } from 'next/server';

export async function POST(request: NextRequest) {
try {
const body = await request.json();
const apiKey = request.headers.get('X-API-Key');

const targetUrl = 'https://www.neuronpedia.org/api/steer-chat';

const headers: HeadersInit = {
'Content-Type': 'application/json',
};

if (apiKey) {
headers['X-API-Key'] = apiKey;
}

const externalResponse = await fetch(targetUrl, {
method: 'POST',
headers,
body: JSON.stringify(body),
});

const responseData = await externalResponse.json();

if (!externalResponse.ok) {
return NextResponse.json(responseData, { status: externalResponse.status });
}

return NextResponse.json(responseData, { status: externalResponse.status });
} catch (error) {
console.error('Proxy error:', error);
if (error instanceof Error) {
return NextResponse.json({ error: error.message }, { status: 500 });
}
return NextResponse.json({ error: 'An unknown error occurred' }, { status: 500 });
}
}
9 changes: 9 additions & 0 deletions apps/webapp/app/embed/feature-discovery/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import FeatureDiscoveryAssistant from '../../../components/tools/feature-discovery-assistant';

export default function Page() {
return (
<div className="flex h-full w-full flex-col items-center overflow-y-scroll bg-white px-0">
<FeatureDiscoveryAssistant />
</div>
);
}
12 changes: 8 additions & 4 deletions apps/webapp/components/feature-selector/model-selector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,15 @@ export default function ModelSelector({
filterToRelease,
showUnlisted = false,
overrideModels,
id,
}: {
modelId: string;
modelIdChangedCallback: (modelId: string) => void;
filterToInferenceEnabled?: boolean;
filterToRelease?: string | undefined;
showUnlisted?: boolean;
overrideModels?: string[];
id?: string;
}) {
const { globalModels, getSourceSetsForModelId, getInferenceEnabledForModel } = useGlobalContext();

Expand All @@ -33,7 +35,10 @@ export default function ModelSelector({
modelIdChangedCallback(newVal);
}}
>
<Select.Trigger className="flex h-10 max-h-[40px] min-h-[40px] w-full flex-1 flex-row items-center justify-center gap-x-1 whitespace-pre rounded border border-slate-300 bg-white px-2 font-mono text-[10px] font-medium text-sky-700 hover:bg-slate-50 focus:outline-none sm:pl-4 sm:pr-2 sm:text-xs">
<Select.Trigger
id={id}
className="flex h-10 max-h-[40px] min-h-[40px] w-full flex-1 flex-row items-center justify-center gap-x-1 whitespace-pre rounded border border-slate-300 bg-white px-2 font-mono text-[10px] font-medium text-sky-700 hover:bg-slate-50 focus:outline-none sm:pl-4 sm:pr-2 sm:text-xs"
>
<div className="flex flex-col gap-y-0">
<Select.Value />
<div className="mt-0.5 text-center text-[8px] font-medium leading-none text-slate-400">MODEL</div>
Expand Down Expand Up @@ -88,9 +93,8 @@ export default function ModelSelector({
<Select.Item
key={mId}
value={mId}
className={`flex flex-col items-start gap-y-0.5 overflow-hidden border-b border-b-slate-100 px-3 py-2.5 text-xs ${
mId === modelId ? 'bg-sky-100 text-sky-700' : 'text-slate-600'
} hover:bg-slate-100 focus:outline-none`}
className={`flex flex-col items-start gap-y-0.5 overflow-hidden border-b border-b-slate-100 px-3 py-2.5 text-xs ${mId === modelId ? 'bg-sky-100 text-sky-700' : 'text-slate-600'
} hover:bg-slate-100 focus:outline-none`}
>
<div className="flex w-full flex-row items-center justify-between gap-x-3">
<Select.ItemText>
Expand Down
Loading