Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
harishmohanraj committed Apr 18, 2024
1 parent f63815d commit e2f24fe
Show file tree
Hide file tree
Showing 6 changed files with 118 additions and 25 deletions.
14 changes: 12 additions & 2 deletions app/main.wasp
Original file line number Diff line number Diff line change
Expand Up @@ -265,8 +265,13 @@ action updateUserById {
entities: [User]
}

action getModels {
fn: import { getModels } from "@src/server/actions.js",
action getAvailableModels {
fn: import { getAvailableModels } from "@src/server/actions.js",
entities: []
}

action updateUserModels {
fn: import { updateUserModels } from "@src/server/actions.js",
entities: []
}

Expand All @@ -287,6 +292,11 @@ query getPaginatedUsers {
entities: [User]
}

query getModels {
fn: import { getModels } from "@src/server/queries.js",
entities: [User]
}

/*
* 📡 These are custom Wasp API Endpoints. Use them for callbacks, webhooks, etc.
* https://wasp-lang.dev/docs/advanced/apis
Expand Down
46 changes: 31 additions & 15 deletions app/src/client/app/ModelsPage.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { useState } from 'react';
import { getModels, useQuery, updateUserModels } from 'wasp/client/operations';

import CustomLayout from './layout/CustomLayout';
import CustomBreadcrumb from '../components/CustomBreadcrumb';
import Button from '../components/Button';
import DynamicFormBuilder from '../components/DynamicFormBuilder';
import Loader from '../admin/common/Loader';
import { getModels } from '../services/modelService';
import { getAvailableModels } from '../services/modelService';
import { ModelSchema, JsonSchema } from '../interfaces/models';
import ModelFormContainer from '../components/ModelFormContainer';
import NotificationBox from '../components/NotificationBox';
Expand All @@ -15,11 +17,14 @@ const ModelsPage = () => {
const [selectedModel, setSelectedModel] = useState<string>('');
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
const [showAddModel, setShowAddModel] = useState(false);
const { data: modelsList, refetch: refetchModels } = useQuery(getModels);

const fetchData = async () => {
setShowAddModel(true);
setIsLoading(true);
try {
const response = await getModels();
const response = await getAvailableModels();
setModelsSchema(response);
setInitialModelSchema(response.schemas[0].json_schema);
setSelectedModel(response.schemas[0].name);
Expand All @@ -42,8 +47,10 @@ const ModelsPage = () => {
}
};

const onSuccessCallback = (data: any) => {
console.log('Form submitted with data:', data);
const onSuccessCallback = async (data: any) => {
await updateUserModels({ data });
refetchModels();
setShowAddModel(false);
};

return (
Expand All @@ -57,17 +64,26 @@ const ModelsPage = () => {
<Button onClick={() => fetchData()} label='Add Model' />
</div>
<div className='flex-col flex w-full'>
{modelsSchema && (
<>
<ModelFormContainer modelsSchema={modelsSchema} onModelChange={handleModelChange} />
{initialModelSchema && (
<DynamicFormBuilder
jsonSchema={initialModelSchema}
validationURL={`models/llms/${selectedModel}/validate`}
onSuccessCallback={onSuccessCallback}
/>
)}
</>
{!showAddModel ? (
modelsList ? (
<div className='flex flex-col gap-3'>
<h2 className='text-lg font-semibold'>Available Models</h2>
<div className='flex flex-col gap-2'>{JSON.stringify(modelsList)}</div>
</div>
) : null
) : (
modelsSchema && (
<>
<ModelFormContainer modelsSchema={modelsSchema} onModelChange={handleModelChange} />
{initialModelSchema && (
<DynamicFormBuilder
jsonSchema={initialModelSchema}
validationURL={`models/llms/${selectedModel}/validate`}
onSuccessCallback={onSuccessCallback}
/>
)}
</>
)
)}
{error && <NotificationBox type={'error'} onClick={() => setError(null)} message={error} />}
</div>
Expand Down
6 changes: 3 additions & 3 deletions app/src/client/services/modelService.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
// services/modelService.ts
import { getModels as apiGetModels } from 'wasp/client/operations';
import { getAvailableModels as apigetAvailableModels } from 'wasp/client/operations';

export const getModels = async () => {
export const getAvailableModels = async () => {
try {
const response = await apiGetModels();
const response = await apigetAvailableModels();
return response;
} catch (error) {
console.error('Failed to fetch models:', error);
Expand Down
44 changes: 40 additions & 4 deletions app/src/server/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,16 @@ import {
type StripePayment,
type UpdateCurrentUser,
type UpdateUserById,
type GetModels,
type GetAvailableModels,
type ValidateForm,
type UpdateUserModels,
} from 'wasp/server/operations';
import Stripe from 'stripe';
import type { StripePaymentResult } from '../shared/types';
import { fetchStripeCustomer, createStripeCheckoutSession } from './payments/stripeUtils.js';
import { TierIds } from '../shared/constants.js';

const FASTAGENCY_SERVER_URL = process.env.FASTAGENCY_SERVER_URL || 'http://127.0.0.1:8000';
import { FASTAGENCY_SERVER_URL } from './common/constants';

export const stripePayment: StripePayment<string, StripePaymentResult> = async (tier, context) => {
if (!context.user || !context.user.email) {
Expand Down Expand Up @@ -91,7 +92,7 @@ export const updateCurrentUser: UpdateCurrentUser<Partial<User>, User> = async (
});
};

export const getModels: GetModels<void, any> = async (user, context) => {
export const getAvailableModels: GetAvailableModels<void, any> = async (user, context) => {
if (!context.user) {
throw new HttpError(401);
}
Expand All @@ -115,6 +116,41 @@ export const getModels: GetModels<void, any> = async (user, context) => {
}
};

type UpdateUserModelsValues = {
userId: number;
model: string;
base_url: string;
api_type: string;
api_version?: string;
};

type UpdateUserModelsPayload = {
data: UpdateUserModelsValues;
};

export const updateUserModels: UpdateUserModels<UpdateUserModelsPayload, void> = async (args, context) => {
if (!context.user) {
throw new HttpError(401);
}

try {
const response = await fetch(`${FASTAGENCY_SERVER_URL}/models/update`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ userId: context.user.id, ...args.data }),
});
const json: any = (await response.json()) as { detail?: string }; // Parse JSON once

if (!response.ok) {
const errorMsg = json.detail || `HTTP error with status code ${response.status}`;
console.error('Server Error:', errorMsg);
throw new Error(errorMsg);
}
} catch (error: any) {
throw new HttpError(500, error.message);
}
};

export const validateForm: ValidateForm<{ data: any; validationURL: string }, any> = async (
{ data, validationURL }: { data: any; validationURL: string },
context: any
Expand All @@ -138,7 +174,7 @@ export const validateForm: ValidateForm<{ data: any; validationURL: string }, an
);
}

return json;
return data;
} catch (error: any) {
throw new HttpError(error.statusCode || 500, error.message || 'Server or network error occurred');
}
Expand Down
1 change: 1 addition & 0 deletions app/src/server/common/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const FASTAGENCY_SERVER_URL = process.env.FASTAGENCY_SERVER_URL || 'http://127.0.0.1:8000';
32 changes: 31 additions & 1 deletion app/src/server/queries.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { type DailyStats, type User, type PageViewSource } from 'wasp/entities';
import { HttpError } from 'wasp/server';
import { type GetDailyStats, type GetPaginatedUsers } from 'wasp/server/operations';
import { type GetDailyStats, type GetPaginatedUsers, type GetModels } from 'wasp/server/operations';
import { FASTAGENCY_SERVER_URL } from './common/constants';

type DailyStatsWithSources = DailyStats & {
sources: PageViewSource[];
Expand Down Expand Up @@ -104,3 +105,32 @@ export const getPaginatedUsers: GetPaginatedUsers<GetPaginatedUsersInput, GetPag
totalPages,
};
};

type GetModelsValues = {
model: string;
base_url: string;
api_type: string;
api_version?: string;
};

export const getModels: GetModels<void, GetModelsValues[]> = async (_args, context) => {
try {
const data = { userId: context.user.id };
const response = await fetch(`${FASTAGENCY_SERVER_URL}/models`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data),
});
const json: any = (await response.json()) as { detail?: string }; // Parse JSON once

if (!response.ok) {
const errorMsg = json.detail || `HTTP error with status code ${response.status}`;
console.error('Server Error:', errorMsg);
throw new Error(errorMsg);
}

return json;
} catch (error: any) {
throw new HttpError(500, error.message);
}
};

0 comments on commit e2f24fe

Please sign in to comment.