Skip to content

Commit

Permalink
Added ui changes to make it work even better for handling errors
Browse files Browse the repository at this point in the history
  • Loading branch information
Sanger2000 committed Mar 29, 2023
1 parent f38fd4e commit 7b6ab8c
Show file tree
Hide file tree
Showing 6 changed files with 137 additions and 48 deletions.
26 changes: 26 additions & 0 deletions src/components/settingsPane.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import { useAppDispatch, useAppSelector } from '../app/hooks'

import { Switch} from '@headlessui/react'

import * as ssel from '../features/settings/settingsSelectors'
import {
changeSettings,
Expand Down Expand Up @@ -182,6 +185,27 @@ export function SettingsPopup() {
}}
value={settings.openAIKey || ""}
/>
<div className="flex items-center">
<Switch
checked={settings.useOpenAIKey}
onChange={(value) => dispatch(changeSettings({useOpenAIKey: value}))}
className={`${settings.useOpenAIKey ? 'bg-green-500' : 'bg-red-500'}
mt-2 relative inline-flex h-[38px] w-[74px] shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors duration-200 ease-in-out focus:outline-none focus-visible:ring-2 focus-visible:ring-white focus-visible:ring-opacity-75`}
>
<span className="sr-only">Use setting</span>
<span
aria-hidden="true"
className={`${settings.useOpenAIKey ? 'translate-x-9' : 'translate-x-0'}
pointer-events-none inline-block h-[34px] w-[34px] transform rounded-full bg-white shadow-lg ring-0 transition duration-200 ease-in-out`}
/>
</Switch>
{settings.useOpenAIKey ? (

<span className="ml-2">Enabled</span>
) : (
<span className="ml-2">Disabled</span>
)}
</div>
</div>

<CopilotPanel />
Expand Down Expand Up @@ -224,6 +248,7 @@ function CursorLogin() {
currentPanel = (
<div className="copilot__signin">
<button onClick={signIn}>Sign in</button>
<br/>
<button onClick={signIn}>Sign up</button>
</div>
)
Expand All @@ -238,6 +263,7 @@ function CursorLogin() {
currentPanel = (
<div className="copilot__signin">
<button onClick={upgrade}>Upgrade to Pro</button>
<br/>
<button onClick={signOut}>Log out</button>
</div>
)
Expand Down
83 changes: 55 additions & 28 deletions src/features/chat/chatThunks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ import {
import {
API_ROOT,
AuthRateLimitError,
BadModelError,
BadOpenAIAPIKeyError,
NoAuthGlobalNewRateLimitError,
NoAuthGlobalOldRateLimitError,
NoAuthLocalRateLimitError,
NoAuthRateLimitError,
streamSource,
} from '../../utils'
Expand Down Expand Up @@ -275,7 +280,8 @@ export async function getPayload({
dispatch(updateLastUserMessageMsgType(null))

let oaiKey : string | undefined | null = state.settingsState.settings.openAIKey;
if (oaiKey == null || oaiKey === '') {
let useOpenAI = state.settingsState.settings.useOpenAIKey;
if (oaiKey == null || oaiKey === '' || !useOpenAI) {
oaiKey = null;
}
const userRequest = {
Expand Down Expand Up @@ -383,16 +389,23 @@ export const continueGeneration = createAsyncThunk(
//credentials: 'include',
body: JSON.stringify(data),
}).then(async (resp) => {
console.log('CAUGHT e', resp)
if (resp.status === 429) {
if (resp.status != 200) {
const text = await resp.json()
console.log('message', text)
if (text.detail.includes('NO_AUTH')) {
console.log('THROWING THIS ERROR')
throw new NoAuthRateLimitError()
} else if (text.detail === 'AUTH') {
console.log('THROWING THIS OTHER ERROR')
throw new AuthRateLimitError()
switch (text.detail) {
case 'NO_AUTH_LOCAL':
throw new NoAuthLocalRateLimitError()
case 'NO_AUTH_GLOBAL_NEW':
throw new NoAuthGlobalOldRateLimitError()
case 'NO_AUTH_GLOBAL_OLD':
throw new NoAuthGlobalNewRateLimitError()
case 'AUTH':
throw new AuthRateLimitError()
case 'BAD_API_KEY':
throw new BadOpenAIAPIKeyError()
case 'BAD_MODEL':
throw new BadModelError()
default:
break
}
}
return resp
Expand Down Expand Up @@ -600,16 +613,23 @@ export const streamResponse = createAsyncThunk(
//credentials: 'include',
body: JSON.stringify(data),
}).then(async (resp) => {
console.log('CAUGHT e', resp)
if (resp.status === 429) {
if (resp.status != 200) {
const text = await resp.json()
console.log('message', text)
if (text.detail.includes('NO_AUTH')) {
console.log('THROWING THIS ERROR')
throw new NoAuthRateLimitError()
} else if (text.detail === 'AUTH') {
console.log('THROWING THIS OTHER ERROR')
throw new AuthRateLimitError()
switch (text.detail) {
case 'NO_AUTH_LOCAL':
throw new NoAuthLocalRateLimitError()
case 'NO_AUTH_GLOBAL_NEW':
throw new NoAuthGlobalOldRateLimitError()
case 'NO_AUTH_GLOBAL_OLD':
throw new NoAuthGlobalNewRateLimitError()
case 'AUTH':
throw new AuthRateLimitError()
case 'BAD_API_KEY':
throw new BadOpenAIAPIKeyError()
case 'BAD_MODEL':
throw new BadModelError()
default:
break
}
}
return resp
Expand Down Expand Up @@ -1030,16 +1050,23 @@ export const diffResponse = createAsyncThunk(
//credentials: 'include',
body: JSON.stringify(data),
}).then(async (resp) => {
console.log('CAUGHT e', resp)
if (resp.status === 429) {
if (resp.status != 200) {
const text = await resp.json()
console.log('message', text)
if (text.detail.includes('NO_AUTH')) {
console.log('THROWING THIS ERROR')
throw new NoAuthRateLimitError()
} else if (text.detail === 'AUTH') {
console.log('THROWING THIS OTHER ERROR')
throw new AuthRateLimitError()
switch (text.detail) {
case 'NO_AUTH_LOCAL':
throw new NoAuthLocalRateLimitError()
case 'NO_AUTH_GLOBAL_NEW':
throw new NoAuthGlobalOldRateLimitError()
case 'NO_AUTH_GLOBAL_OLD':
throw new NoAuthGlobalNewRateLimitError()
case 'AUTH':
throw new AuthRateLimitError()
case 'BAD_API_KEY':
throw new BadOpenAIAPIKeyError()
case 'BAD_MODEL':
throw new BadModelError()
default:
break
}
}
return resp
Expand Down
1 change: 1 addition & 0 deletions src/features/window/state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,7 @@ export interface Settings {
contextType: string
textWrapping: string
openAIKey?: string
useOpenAIKey?: boolean
tabSize?: string
}

Expand Down
2 changes: 1 addition & 1 deletion src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -1683,7 +1683,7 @@ cm-diff-cancel > div {
cursor: pointer;
}

.settings button {
.copilot__signin button {
background-color: var(--vscode-blue);
padding: 4px 12px;
border-radius: 5px;
Expand Down
27 changes: 8 additions & 19 deletions src/main/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,14 @@ const store = new Store()

let win: BrowserWindow | null = null

const auth0Domain = 'cursor.us.auth0.com'
const clientId = 'KbZUR41cY7W6zRSdpSUJ7I7mLYBKOCmB'
const cursorHome = 'https://cursor.so'
// const auth0Domain = 'cursor.us.auth0.com'
// const clientId = 'KbZUR41cY7W6zRSdpSUJ7I7mLYBKOCmB'
// const cursorHome = 'https://cursor.so'

// Test domain/client
// const auth0Domain = 'dev-27d5cph2nbetfllb.us.auth0.com'
// const clientId = 'OzaBXLClY5CAGxNzUhQ2vlknpi07tGuE'
// const cursorHome = 'http://localhost:4000'
const auth0Domain = 'dev-27d5cph2nbetfllb.us.auth0.com'
const clientId = 'OzaBXLClY5CAGxNzUhQ2vlknpi07tGuE'
const cursorHome = 'http://localhost:4000'

let accessToken: string | null = null
let profile: any | null = null
Expand All @@ -46,11 +46,12 @@ const API_AUDIENCE = `https://${auth0Domain}/api/v2/`
const loginUrl = `${cursorHome}/api/auth/loginDeep`
const signUpUrl = `${cursorHome}/api/auth/loginDeep`
const settingsUrl = `${cursorHome}/settings`
const payUrl = `${cursorHome}/api/auth/checkoutDeep`

const supportUrl = `${API_ROOT}/auth/support`

// These are api routes
const logoutUrl = `${API_ROOT}/api/auth/logout`
const payUrl = `${API_ROOT}/api/auth/checkoutDeep`

const storeWrapper = {
get: async (key: string) => {
Expand Down Expand Up @@ -99,13 +100,11 @@ export async function stripeUrlRequest(window: BrowserWindow) {
})

const newUrl = (await response.json()) as string
console.log('GOT NEW URL', { newUrl })
window.loadURL(newUrl)
}

export async function refreshTokens(event?: IpcMainInvokeEvent) {
const refreshToken = await storeWrapper.get('refreshToken')
console.log('retrieving refreshToken', refreshToken)

if (refreshToken) {
const refreshOptions = {
Expand All @@ -124,17 +123,13 @@ export async function refreshTokens(event?: IpcMainInvokeEvent) {
`https://${auth0Domain}/oauth/token`,
refreshOptions
)
console.log('resp', response)
console.log(response.status)
const origData = await response.json()
console.log('Orig data', origData)
const data = origData as {
access_token: string
id_token: string
}

accessToken = data.access_token
console.log('GETTING BACK PROFILE', data.id_token)
profile = jwtDecode(data.id_token)
} catch (error) {
// await logout(parentWindow)
Expand All @@ -145,7 +140,6 @@ export async function refreshTokens(event?: IpcMainInvokeEvent) {
//throw new Error('No available refresh token.')
}

console.log('UPDATING AUTH STATUS IN refresh tokens')
if (event) {
event.sender.send('updateAuthStatus', { accessToken, profile })
}
Expand All @@ -160,10 +154,8 @@ export async function setupTokens(
const host = urlParts.host
//
if (host?.toLowerCase() === 'changetokens') {
console.log('settings access and refresh')
accessToken = query.accessToken as string
refreshToken = query.refreshToken as string
console.log('storing refreshToken', refreshToken)

await storeWrapper.set('refreshToken', refreshToken)
}
Expand All @@ -187,7 +179,6 @@ export async function loadStripeProfile() {
},
})
let resp = await response.json()
console.log('GOT STRIPE PROFILE', resp)
if (resp) {
stripeProfile = resp as string
}
Expand Down Expand Up @@ -243,15 +234,13 @@ export async function support() {
}

export function createLogoutWindow(event: IpcMainInvokeEvent) {
console.log('LOGGING OUT')
const logoutWindow = new BrowserWindow({
show: false,
})

logoutWindow.loadURL(getLogOutUrl())

logoutWindow.on('ready-to-show', async () => {
console.log('CLOSING LOGOUT WINDOW')
await logoutEvent(event)
logoutWindow.close()
})
Expand Down
46 changes: 46 additions & 0 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,52 @@ export class AuthRateLimitError extends Error {
this.name = 'AuthRateLimitError'
}
}

export class NoAuthLocalRateLimitError extends Error {
constructor(
message = 'You have reached the rate limit for unauthenticated local requests. Please authenticate to continue.'
) {
super(message)
this.name = 'NoAuthLocalRateLimitError'
}
}

export class NoAuthGlobalOldRateLimitError extends Error {
constructor(
message = 'You have reached the rate limit for unauthenticated global requests. Please wait before making more requests.'
) {
super(message)
this.name = 'NoAuthGlobalOldRateLimitError'
}
}

export class NoAuthGlobalNewRateLimitError extends Error {
constructor(
message = 'You have reached the rate limit for unauthenticated global requests. Please wait before making more requests.'
) {
super(message)
this.name = 'NoAuthGlobalNewRateLimitError'
}
}

export class BadOpenAIAPIKeyError extends Error {
constructor(
message = 'The provided OpenAI API key is invalid. Please provide a valid API key.'
) {
super(message)
this.name = 'BadOpenAIAPIKeyError'
}
}

export class BadModelError extends Error {
constructor(
message = 'The provided model ID is invalid. Please provide a valid model ID.'
) {
super(message)
this.name = 'BADModelError'
}
}

export async function fetchWithCookies(url: string, options: RequestInit = {}) {
const response = await fetch(url, options)
// Get the cookies
Expand Down

0 comments on commit 7b6ab8c

Please sign in to comment.