-
Notifications
You must be signed in to change notification settings - Fork 2.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature/self open ai key #491
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,23 +5,44 @@ import { | |
copilotRuntimeNestEndpoint, | ||
} from '@copilotkit/runtime'; | ||
import { GetOrgFromRequest } from '@gitroom/nestjs-libraries/user/org.from.request'; | ||
import { Organization } from '@prisma/client'; | ||
import { Organization, User } from '@prisma/client'; | ||
import { SubscriptionService } from '@gitroom/nestjs-libraries/database/prisma/subscriptions/subscription.service'; | ||
import { GetUserFromRequest } from '@gitroom/nestjs-libraries/user/user.from.request'; | ||
import { UsersService } from '@gitroom/nestjs-libraries/database/prisma/users/users.service'; | ||
import OpenAI from 'openai'; | ||
|
||
@Controller('/copilot') | ||
export class CopilotController { | ||
constructor(private _subscriptionService: SubscriptionService) {} | ||
constructor( | ||
private _subscriptionService: SubscriptionService, | ||
private _userService: UsersService | ||
) {} | ||
@Post('/chat') | ||
chat(@Req() req: Request, @Res() res: Response) { | ||
if (process.env.OPENAI_API_KEY === undefined || process.env.OPENAI_API_KEY === '') { | ||
async chat( | ||
@Req() req: Request, | ||
@Res() res: Response, | ||
@GetUserFromRequest() user: User | ||
) { | ||
let openAIAPIKey = ''; | ||
|
||
//Check if OPEN AI is enabled for Self tokens. | ||
if (process.env.ENABLE_OPENAI_SELF === 'true') { | ||
const userPersonal = await this._userService.getPersonal(user.id); | ||
openAIAPIKey = userPersonal.openAIAPIKey; | ||
} else { | ||
openAIAPIKey = process.env.OPENAI_API_KEY; | ||
} | ||
|
||
if (openAIAPIKey === undefined || openAIAPIKey === '') { | ||
Logger.warn('OpenAI API key not set, chat functionality will not work'); | ||
return | ||
return; | ||
Comment on lines
+26
to
+38
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Handle missing OpenAI API key by returning an appropriate HTTP response When the OpenAI API key is missing or invalid, the method logs a warning and returns without sending a response to the client. This may cause the client request to hang or receive an unexpected result. It's important to inform the client of the issue. Apply this diff to return a 400 Bad Request response with an error message: if (openAIAPIKey === undefined || openAIAPIKey === '') {
Logger.warn('OpenAI API key not set, chat functionality will not work');
+ res.status(400).json({ error: 'OpenAI API key is not set or invalid.' });
+ return;
}
|
||
} | ||
|
||
const copilotRuntimeHandler = copilotRuntimeNestEndpoint({ | ||
endpoint: '/copilot/chat', | ||
runtime: new CopilotRuntime(), | ||
serviceAdapter: new OpenAIAdapter({ | ||
openai: new OpenAI({ apiKey: openAIAPIKey }), | ||
model: | ||
// @ts-ignore | ||
req?.body?.variables?.data?.metadata?.requestType === | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
import { withProvider } from '@gitroom/frontend/components/launches/providers/high.order.provider'; | ||
export default withProvider( | ||
null, | ||
undefined, | ||
undefined, | ||
async (posts) => { | ||
if (posts.some((p) => p.length > 4)) { | ||
return 'There can be maximum 4 pictures in a post.'; | ||
} | ||
|
||
if ( | ||
posts.some( | ||
(p) => p.some((m) => m.path.indexOf('mp4') > -1) && p.length > 1 | ||
) | ||
) { | ||
return 'There can be maximum 1 video in a post.'; | ||
} | ||
|
||
for (const load of posts.flatMap((p) => p.flatMap((a) => a.path))) { | ||
if (load.indexOf('mp4') > -1) { | ||
const isValid = await checkVideoDuration(load); | ||
if (!isValid) { | ||
return 'Video duration must be less than or equal to 140 seconds.'; | ||
} | ||
} | ||
} | ||
return true; | ||
}, | ||
280 | ||
); | ||
|
||
const checkVideoDuration = async (url: string): Promise<boolean> => { | ||
return new Promise((resolve, reject) => { | ||
const video = document.createElement('video'); | ||
video.src = url; | ||
video.preload = 'metadata'; | ||
|
||
video.onloadedmetadata = () => { | ||
// Check if the duration is less than or equal to 140 seconds | ||
const duration = video.duration; | ||
if (duration <= 140) { | ||
resolve(true); // Video duration is acceptable | ||
} else { | ||
resolve(false); // Video duration exceeds 140 seconds | ||
} | ||
}; | ||
|
||
video.onerror = () => { | ||
reject(new Error('Failed to load video metadata.')); | ||
}; | ||
}); | ||
}; |
Original file line number | Diff line number | Diff line change | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -54,9 +54,11 @@ export class IntegrationService { | |||||||||||||||||
timezone?: number, | ||||||||||||||||||
customInstanceDetails?: string | ||||||||||||||||||
) { | ||||||||||||||||||
console.log('XXXX UPLOADING'); | ||||||||||||||||||
const uploadedPicture = picture | ||||||||||||||||||
? await this.storage.uploadSimple(picture) | ||||||||||||||||||
: undefined; | ||||||||||||||||||
console.log('XXXX UPLOAD DONE'); | ||||||||||||||||||
Comment on lines
+57
to
+61
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove debug console.log statements. Debug console.log statements should not be committed to production code. Consider replacing them with proper logging using a logging service if upload tracking is needed. - console.log('XXXX UPLOADING');
const uploadedPicture = picture
? await this.storage.uploadSimple(picture)
: undefined;
- console.log('XXXX UPLOAD DONE'); 📝 Committable suggestion
Suggested change
|
||||||||||||||||||
return this._integrationRepository.createOrUpdateIntegration( | ||||||||||||||||||
org, | ||||||||||||||||||
name, | ||||||||||||||||||
|
@@ -408,7 +410,7 @@ export class IntegrationService { | |||||||||||||||||
}) { | ||||||||||||||||||
const getPlugById = await this._integrationRepository.getPlug(data.plugId); | ||||||||||||||||||
if (!getPlugById) { | ||||||||||||||||||
return ; | ||||||||||||||||||
return; | ||||||||||||||||||
} | ||||||||||||||||||
|
||||||||||||||||||
const integration = this._integrationManager.getSocialIntegration( | ||||||||||||||||||
|
@@ -434,11 +436,11 @@ export class IntegrationService { | |||||||||||||||||
); | ||||||||||||||||||
|
||||||||||||||||||
if (process) { | ||||||||||||||||||
return ; | ||||||||||||||||||
return; | ||||||||||||||||||
} | ||||||||||||||||||
|
||||||||||||||||||
if (data.totalRuns === data.currentRun) { | ||||||||||||||||||
return ; | ||||||||||||||||||
return; | ||||||||||||||||||
} | ||||||||||||||||||
|
||||||||||||||||||
this._workerServiceProducer.emit('plugs', { | ||||||||||||||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Review the default value and placement of X self-integration toggle.
A few concerns about the
ENABLE_X_SELF
configuration:Consider these changes: