Skip to content
This repository has been archived by the owner on Apr 28, 2024. It is now read-only.

Commit

Permalink
Merge pull request #139 from slashbaseide/develop
Browse files Browse the repository at this point in the history
Release v.0.10.2
  • Loading branch information
paraswaykole committed Nov 12, 2023
2 parents bbde969 + 7ee7aec commit 5b98bc1
Show file tree
Hide file tree
Showing 30 changed files with 341 additions and 164 deletions.
117 changes: 80 additions & 37 deletions frontend/desktop/src/components/settingfragments/advanced.tsx
Original file line number Diff line number Diff line change
@@ -1,51 +1,94 @@
import React, { FunctionComponent, useEffect, useState } from 'react'
import Constants from '../../constants'
import eventService from '../../events/eventService'
import toast from 'react-hot-toast'

const AdvancedSettings: FunctionComponent<{}> = () => {

const [openAIKey, setOpenAIKey] = useState<string>("")
const [openAIModel, setOpenAIModel] = useState<string>("")
const [modelOptions, setModelOptions] = useState<{ value: string }[]>([])

const [openAIKey, setOpenAIKey] = useState<string>("")
useEffect(() => {
(async () => {
const result = await eventService.listSupportedAIModels()
setModelOptions(result.data.map(model => ({ value: model })))
})();
(async () => {
const result = await eventService.getSingleSetting(Constants.SETTING_KEYS.OPENAI_KEY)
setOpenAIKey(result.data)
})();
(async () => {
const result = await eventService.getSingleSetting(Constants.SETTING_KEYS.OPENAI_MODEL)
setOpenAIModel(result.data)
})();
}, [])

useEffect(() => {
(async () => {
let result = await eventService.getSingleSetting(Constants.SETTING_KEYS.OPENAI_KEY)
setOpenAIKey(result.data)
})()
}, [])

const updateOpenAIKey = async () => {
const result = await eventService.updateSingleSetting(Constants.SETTING_KEYS.OPENAI_KEY, openAIKey)
if (result.success)
setOpenAIKey(openAIKey)
const updateOpenAIKey = async () => {
const result = await eventService.updateSingleSetting(Constants.SETTING_KEYS.OPENAI_KEY, openAIKey)
if (result.success) {
setOpenAIKey(openAIKey)
toast.success("saved")
}
}

return (
<React.Fragment>
<h1>Advanced Settings</h1>
<br />
<h2>OpenAI Key</h2>
<p>Update OpenAI API key to enable Generate SQL tool.</p>
<div className="buttons has-addons">
<div className="field has-addons">
<p className="control is-expanded">
<input
className="input"
type="text"
value={openAIKey}
onChange={(e: React.ChangeEvent<HTMLInputElement>) => { setOpenAIKey(e.target.value) }}
placeholder="Enter API key" />
</p>
<p className="control">
<a className="button" onClick={updateOpenAIKey}>
<i className="fas fa-check" />
</a>
</p>
</div>
</div>
<br />
</React.Fragment>
)
const updateOpenAIModel = async () => {
const result = await eventService.updateSingleSetting(Constants.SETTING_KEYS.OPENAI_MODEL, openAIModel)
if (result.success)
setOpenAIModel(openAIModel)
toast.success("saved")
}

const handleModelChange = (e: React.ChangeEvent<HTMLInputElement | HTMLSelectElement>) => {
const value = e.target.value
setOpenAIModel(value)
}

return (
<React.Fragment>
<h1>Advanced Settings</h1>
<br />
<h2>OpenAI Key</h2>
<p>Update OpenAI API key to enable Generate SQL tool.</p>
<div className="buttons has-addons">
<div className="field has-addons" style={{ minWidth: 550 }}>
<p className="control is-expanded">
<input
className="input"
type="text"
value={openAIKey}
onChange={(e: React.ChangeEvent<HTMLInputElement>) => { setOpenAIKey(e.target.value) }}
placeholder="Enter API key" />
</p>
<p className="control">
<a className="button" onClick={updateOpenAIKey}>
<i className="fas fa-check" />
</a>
</p>
</div>
</div>
<h2>OpenAI Model</h2>
<p>Update OpenAI Model to enable Generate SQL tool.</p>
<div className="field has-addons">
<p className="control">
<span className="select">
<select value={openAIModel} onChange={e => handleModelChange(e)}>
{modelOptions.map((e, idx) => {
return <option value={e.value} key={idx}> {e.value} </option>
})}
</select>
</span>
</p>
<p className="control">
<button className="button" onClick={() => updateOpenAIModel()}>
<i className="fas fa-check" />
</button>
</p>
</div>
<br />
</React.Fragment>
)
}

export default AdvancedSettings
1 change: 1 addition & 0 deletions frontend/desktop/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ const Constants: ConstantsType = {
TELEMETRY_ENABLED: "TELEMETRY_ENABLED",
LOGS_EXPIRE: "LOGS_EXPIRE",
OPENAI_KEY: "OPENAI_KEY",
OPENAI_MODEL:"OPENAI_MODEL"
},
}

Expand Down
4 changes: 4 additions & 0 deletions frontend/desktop/src/events/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,10 @@ const Events: EventType = {
REQUEST: "event:ai:gensql",
RESPONSE: "response:ai:gensql"
},
AI_LIST_SUPPORTEDMODELS: {
REQUEST: "event:ai:listmodels",
RESPONSE: "response:ai:listmodels"
},
}

export default Events
9 changes: 8 additions & 1 deletion frontend/desktop/src/events/eventService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,12 @@ const runGenerateSQL = async function (dbConnId: string, text: string): Promise<
return response
}

const listSupportedAIModels = async function (): Promise<ApiResult<string[]>> {
const response = responseEvent<ApiResult<string[]>>(Events.AI_LIST_SUPPORTEDMODELS.RESPONSE)
EventsEmit(Events.AI_LIST_SUPPORTEDMODELS.REQUEST, Events.AI_LIST_SUPPORTEDMODELS.RESPONSE)
return response
}

export default {
getHealthCheck,
getProjects,
Expand Down Expand Up @@ -244,5 +250,6 @@ export default {
closeTab,
runConsoleCommand,
checkConnection,
runGenerateSQL
runGenerateSQL,
listSupportedAIModels
}
48 changes: 44 additions & 4 deletions frontend/server/src/components/settingfragments/advanced.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,27 @@
import React, { FunctionComponent, useEffect, useState } from 'react'
import Constants from '../../constants'
import apiService from '../../network/apiService'
import toast from 'react-hot-toast'

const AdvancedSettings: FunctionComponent<{}> = () => {


const [openAIKey, setOpenAIKey] = useState<string>("")
const [openAIModel, setOpenAIModel] = useState<string>("")
const [modelOptions, setModelOptions] = useState<{ value: string }[]>([])

useEffect(() => {
(async () => {
let result = await apiService.getSingleSetting(Constants.SETTING_KEYS.OPENAI_KEY)
const result = await apiService.listSupportedAIModels()
setModelOptions(result.data.map(model => ({ value: model })))
})();
(async () => {
const result = await apiService.getSingleSetting(Constants.SETTING_KEYS.OPENAI_KEY)
setOpenAIKey(result.data)
})()
})();
(async () => {
const result = await apiService.getSingleSetting(Constants.SETTING_KEYS.OPENAI_MODEL)
setOpenAIModel(result.data)
})();
}, [])

const updateOpenAIKey = async () => {
Expand All @@ -20,14 +30,26 @@ const AdvancedSettings: FunctionComponent<{}> = () => {
setOpenAIKey(openAIKey)
}

const updateOpenAIModel = async () => {
const result = await apiService.updateSingleSetting(Constants.SETTING_KEYS.OPENAI_MODEL, openAIModel)
if (result.success)
setOpenAIModel(openAIModel)
toast.success("saved")
}

const handleModelChange = (e: React.ChangeEvent<HTMLInputElement | HTMLSelectElement>) => {
const value = e.target.value
setOpenAIModel(value)
}

return (
<React.Fragment>
<h1>Advanced Settings</h1>
<br />
<h2>OpenAI Key</h2>
<p>Update OpenAI API key to enable Generate SQL tool.</p>
<div className="buttons has-addons">
<div className="field has-addons">
<div className="field has-addons" style={{ minWidth: 550 }}>
<p className="control is-expanded">
<input
className="input"
Expand All @@ -43,6 +65,24 @@ const AdvancedSettings: FunctionComponent<{}> = () => {
</p>
</div>
</div>
<h2>OpenAI Model</h2>
<p>Update OpenAI Model to enable Generate SQL tool.</p>
<div className="field has-addons">
<p className="control">
<span className="select">
<select value={openAIModel} onChange={e => handleModelChange(e)}>
{modelOptions.map((e, idx) => {
return <option value={e.value} key={idx}> {e.value} </option>
})}
</select>
</span>
</p>
<p className="control">
<button className="button" onClick={() => updateOpenAIModel()}>
<i className="fas fa-check" />
</button>
</p>
</div>
<br />
</React.Fragment>
)
Expand Down
1 change: 1 addition & 0 deletions frontend/server/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ const Constants: ConstantsType = {
TELEMETRY_ENABLED: "TELEMETRY_ENABLED",
LOGS_EXPIRE: "LOGS_EXPIRE",
OPENAI_KEY: "OPENAI_KEY",
OPENAI_MODEL: "OPENAI_MODEL"
},
ROLES: {
ADMIN: "Admin"
Expand Down
9 changes: 7 additions & 2 deletions frontend/server/src/network/apiService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,11 @@ const generateSQL = async function (dbConnectionId: string, text: string): Promi
.then(res => res.data)
}


const listSupportedAIModels = async function (): Promise<ApiResult<string[]>> {
return await Request.apiInstance
.get<any, AxiosResponse<ApiResult<string[]>>>(`/ai/listmodels`)
.then(res => res.data)
}

export default {
getHealthCheck,
Expand Down Expand Up @@ -356,5 +360,6 @@ export default {
addRole,
deleteRole,
updateRolePermission,
generateSQL
generateSQL,
listSupportedAIModels
}
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ require (
github.com/jackc/pgx/v4 v4.17.2
github.com/joho/godotenv v1.4.0
github.com/posthog/posthog-go v0.0.0-20221221115252-24dfed35d71a
github.com/sashabaranov/go-openai v1.9.4
github.com/sashabaranov/go-openai v1.17.2
github.com/tdewolff/parse/v2 v2.6.5
github.com/wailsapp/wails/v2 v2.4.1
github.com/xwb1989/sqlparser v0.0.0-20180606152119-120387863bf2
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -355,8 +355,8 @@ github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQD
github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
github.com/samber/lo v1.27.1 h1:sTXwkRiIFIQG+G0HeAvOEnGjqWeWtI9cg5/n51KrxPg=
github.com/samber/lo v1.27.1/go.mod h1:it33p9UtPMS7z72fP4gw/EIfQB2eI8ke7GR2wc6+Rhg=
github.com/sashabaranov/go-openai v1.9.4 h1:KanoCEoowAI45jVXlenMCckutSRr39qOmSi9MyPBfZM=
github.com/sashabaranov/go-openai v1.9.4/go.mod h1:lj5b/K+zjTSFxVLijLSTDZuP7adOgerWeFyZLUhAKRg=
github.com/sashabaranov/go-openai v1.17.2 h1:Uj1Msqh43S9XhjUXYyOqOHMiRQtgQXCo5O0FeWZz7tU=
github.com/sashabaranov/go-openai v1.17.2/go.mod h1:lj5b/K+zjTSFxVLijLSTDZuP7adOgerWeFyZLUhAKRg=
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
github.com/savsgio/dictpool v0.0.0-20221023140959-7bf2e61cea94 h1:rmMl4fXJhKMNWl+K+r/fq4FbbKI+Ia2m9hYBLm2h4G4=
github.com/savsgio/dictpool v0.0.0-20221023140959-7bf2e61cea94/go.mod h1:90zrgN3D/WJsDd1iXHT96alCoN2KJo6/4x1DZC3wZs8=
Expand Down
4 changes: 4 additions & 0 deletions internal/common/controllers/ai.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,7 @@ func (AIController) GenerateSQL(dbConnectionID, text string) (string, error) {

return ai.GenerateSQL(dbConn.Type, text, datamodels)
}

func (AIController) GetModels() []string {
return ai.ListSupportedOpenAiModels()
}
19 changes: 18 additions & 1 deletion internal/common/controllers/setting.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,21 @@ type SettingController struct{}

func (SettingController) GetSingleSetting(name string) (interface{}, error) {
setting, err := dao.Setting.GetSingleSetting(name)

switch name {
case models.SETTING_NAME_OPENAI_KEY:
return setting.Value, nil
case models.SETTING_NAME_OPENAI_MODEL:
if setting.Value == "" {
return ai.GetOpenAiModel(), nil
}
return setting.Value, nil
}

if err != nil {
return "", errors.New("there was some problem")
return "", errors.New("setting not found")
}

switch setting.Name {
case models.SETTING_NAME_APP_ID:
return setting.UUID().String(), nil
Expand All @@ -44,6 +56,11 @@ func (SettingController) UpdateSingleSetting(name string, value string) error {
}
case models.SETTING_NAME_OPENAI_KEY:
ai.InitClient(value)
case models.SETTING_NAME_OPENAI_MODEL:
err := ai.SetOpenAiModel(value)
if err != nil {
return err
}
default:
return errors.New("invalid setting name: " + name)
}
Expand Down
1 change: 1 addition & 0 deletions internal/common/models/setting.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ const (
SETTING_NAME_TELEMETRY_ENABLED = "TELEMETRY_ENABLED"
SETTING_NAME_LOGS_EXPIRE = "LOGS_EXPIRE"
SETTING_NAME_OPENAI_KEY = "OPENAI_KEY"
SETTING_NAME_OPENAI_MODEL = "OPENAI_MODEL"
)

func NewSetting(name string, value string) *Setting {
Expand Down
1 change: 1 addition & 0 deletions internal/desktop/app/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,5 +62,6 @@ func setupEvents(ctx context.Context) {
}
if aiEventListeners := new(events.AIEventListeners); true {
aiEventListeners.GenSQLEvent(ctx)
aiEventListeners.ListSupportedAIModelsEvent(ctx)
}
}
15 changes: 14 additions & 1 deletion internal/desktop/events/ai.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ type AIEventListeners struct{}
var aiController controllers.AIController

const (
eventAIGenSQL = "event:ai:gensql"
eventAIGenSQL = "event:ai:gensql"
eventAIListModels = "event:ai:listmodels"
)

func (AIEventListeners) GenSQLEvent(ctx context.Context) {
Expand All @@ -37,3 +38,15 @@ func (AIEventListeners) GenSQLEvent(ctx context.Context) {
})
})
}

func (AIEventListeners) ListSupportedAIModelsEvent(ctx context.Context) {
runtime.EventsOn(ctx, eventAIListModels, func(args ...interface{}) {
responseEventName := args[0].(string)
defer recovery(ctx, responseEventName)
output := aiController.GetModels()
runtime.EventsEmit(ctx, responseEventName, map[string]interface{}{
"success": true,
"data": output,
})
})
}

0 comments on commit 5b98bc1

Please sign in to comment.