Skip to content
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

Adding XefMobile project #745

Open
wants to merge 43 commits into
base: features/assistant-create-form
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
cb9d0c4
Revert "Merge branch 'features/mobiles' into features/assistant-creat…
JoseP3r32 May 27, 2024
7314692
added missing project
JoseP3r32 May 27, 2024
8576e72
Upload files, settings OpenAiKey, auth fixes
JoseP3r32 May 27, 2024
e8e3228
Apply spotless formatting
JoseP3r32 May 28, 2024
419c8af
Merge branch 'refs/heads/features/assistant-create-form' into feature…
JoseP3r32 May 28, 2024
a5bbd20
Merge remote-tracking branch 'origin/features/xef-mobiles' into featu…
JoseP3r32 May 28, 2024
36fd41f
Merge branch 'refs/heads/features/assistant-create-form' into feature…
JoseP3r32 May 28, 2024
7b5cdda
OpenAi token UI and assistant list
JoseP3r32 May 28, 2024
171d8f2
Apply spotless formatting
JoseP3r32 May 28, 2024
f2bd552
Android project
JoseP3r32 May 28, 2024
18a1ba0
Merge branch 'refs/heads/features/assistant-create-form' into feature…
JoseP3r32 May 28, 2024
7433a6d
Apply spotless formatting
JoseP3r32 May 28, 2024
5d78474
List assistants and create new assistant
JoseP3r32 May 29, 2024
5674a1f
Apply spotless formatting
JoseP3r32 May 29, 2024
7cc4f94
Create assistant updates
JoseP3r32 May 30, 2024
4d3801c
fmt
JoseP3r32 May 30, 2024
401116f
Merge branch 'refs/heads/features/assistant-create-form' into feature…
JoseP3r32 Jun 3, 2024
3263e29
Create assistant functionality
JoseP3r32 Jun 3, 2024
6ee9b03
Apply spotless formatting
JoseP3r32 Jun 3, 2024
97160fc
Update assistant list after creating
JoseP3r32 Jun 3, 2024
3169933
Populate assistant data into form
JoseP3r32 Jun 4, 2024
7468956
Apply spotless formatting
JoseP3r32 Jun 4, 2024
e1de33b
Registration validations and ui updates
JoseP3r32 Jun 5, 2024
c5748e9
Merge remote-tracking branch 'origin/features/xef-mobiles' into featu…
JoseP3r32 Jun 5, 2024
d6fcceb
Registration validations and ui updates
JoseP3r32 Jun 5, 2024
0b6f2f3
Merge branch 'refs/heads/features/assistant-create-form' into feature…
JoseP3r32 Jun 5, 2024
056fb9e
Delete assistant
JoseP3r32 Jun 5, 2024
4025180
Merge branch 'refs/heads/features/assistant-create-form' into feature…
JoseP3r32 Jun 5, 2024
e108a93
Apply spotless formatting
JoseP3r32 Jun 5, 2024
3b34bf7
Delete assistant endpoint
JoseP3r32 Jun 5, 2024
3efe737
Merge remote-tracking branch 'origin/features/xef-mobiles' into featu…
JoseP3r32 Jun 5, 2024
8b8ea20
Apply spotless formatting
JoseP3r32 Jun 5, 2024
6ebe743
Add file paths to file search and code interpreter
JoseP3r32 Jun 6, 2024
09d52b7
Merge remote-tracking branch 'origin/features/xef-mobiles' into featu…
JoseP3r32 Jun 6, 2024
548456a
Apply spotless formatting
JoseP3r32 Jun 6, 2024
fc4b786
Showing path files from selected files
JoseP3r32 Jun 6, 2024
30f41e9
Merge remote-tracking branch 'origin/features/xef-mobiles' into featu…
JoseP3r32 Jun 6, 2024
32e9a56
Apply spotless formatting
JoseP3r32 Jun 6, 2024
fbd9161
Load files on code interpreter
JoseP3r32 Jun 10, 2024
d567e52
Merge remote-tracking branch 'origin/features/xef-mobiles' into featu…
JoseP3r32 Jun 10, 2024
1bca4e6
Merge branch 'refs/heads/features/assistant-create-form' into feature…
JoseP3r32 Jun 10, 2024
3012027
Update assistant succesfull
JoseP3r32 Jun 10, 2024
a63042a
Apply spotless formatting
JoseP3r32 Jun 10, 2024
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
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ object Server {
requestTimeout = 0 // disabled
}
install(Auth)
install(Logging) { level = LogLevel.ALL }
install(Logging) { level = LogLevel.INFO }
install(ClientContentNegotiation)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,15 @@ fun Routing.assistantRoutes(logger: KLogger) {
val assistantsApi = openAI.assistants
val response =
assistantsApi.listAssistants(configure = { header("OpenAI-Beta", "assistants=v2") })

call.respond(HttpStatusCode.OK, response)
} catch (e: SerializationException) {
val trace = e.stackTraceToString()
logger.error { "Serialization error: $trace" }
call.respond(HttpStatusCode.BadRequest, "Serialization error: $trace")
} catch (e: Exception) {
val trace = e.stackTraceToString()
logger.error { "Error listing assistants: $trace" }
logger.error { "Error retrieving assistants: $trace" }
call.respond(HttpStatusCode.BadRequest, "Invalid request: $trace")
}
}
Expand All @@ -76,7 +81,12 @@ fun Routing.assistantRoutes(logger: KLogger) {
call.respond(HttpStatusCode.BadRequest, "Invalid assistant id")
return@put
}
val assistant = Assistant(id)

val token = call.getToken().value
val openAI = OpenAI(Config(token = token), logRequests = true)
val assistantsApi = openAI.assistants
val assistant = Assistant(id, assistantsApi = assistantsApi)

val response = assistant.modify(request).get()
logger.info { "Modified assistant: ${response.name} with id: ${response.id}" }
call.respond(HttpStatusCode.OK, response)
Expand All @@ -103,7 +113,8 @@ fun Routing.assistantRoutes(logger: KLogger) {
}
val openAI = OpenAI(Config(token = token.value), logRequests = true)
val assistantsApi = openAI.assistants
val response = assistantsApi.deleteAssistant(id, configure = { header("OpenAI-Beta", "assistants=v2") })
val response =
assistantsApi.deleteAssistant(id, configure = { header("OpenAI-Beta", "assistants=v2") })
logger.info { "Deleted assistant: with id: ${response.id}" }
call.respond(status = HttpStatusCode.NoContent, response)
} catch (e: Exception) {
Expand Down
2 changes: 1 addition & 1 deletion server/web/src/utils/api/chatCompletions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ export function openai (settings: Settings): OpenAI {
dangerouslyAllowBrowser: true,
apiKey: settings.apiKey, // defaults to process.env["OPENAI_API_KEY"]
});
}
}
5 changes: 5 additions & 0 deletions server/xefMobile/composeApp/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,11 @@ kotlin {
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json-jvm:1.6.3")
implementation("io.ktor:ktor-client-serialization-jvm:2.3.11")
implementation("com.google.accompanist:accompanist-permissions:0.34.0")
implementation("androidx.compose.runtime:runtime:1.6.7")
implementation("io.ktor:ktor-client-cio-jvm:2.3.11")
implementation("io.ktor:ktor-client-cio:2.3.11")
implementation("io.ktor:ktor-client-core-jvm:2.3.11")
implementation("androidx.compose.material3:material3:1.2.1")
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />

<application
android:icon="@drawable/xef_brand_icon"
android:label="xefMobile"
Expand All @@ -20,3 +25,4 @@
</activity>
</application>
</manifest>

Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,21 @@ import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import com.server.movile.xef.android.ui.viewmodels.AuthViewModel
import com.xef.xefMobile.services.ApiService
import com.xef.xefMobile.ui.viewmodels.SettingsViewModel

class MainActivity : ComponentActivity() {
private lateinit var authViewModel: AuthViewModel
private lateinit var settingsViewModel: SettingsViewModel

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
authViewModel = AuthViewModel(this, ApiService())
settingsViewModel = SettingsViewModel(this)

setContent { XefAndroidApp(authViewModel = authViewModel) }
authViewModel.logout()

setContent {
XefAndroidApp(authViewModel = authViewModel, settingsViewModel = settingsViewModel)
}
}
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
package com.xef.xefMobile

import android.annotation.SuppressLint
import android.widget.Toast
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.rounded.Menu
import androidx.compose.material3.*
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
Expand Down Expand Up @@ -38,6 +40,14 @@ fun MainLayout(
val CustomTextBlue = Color(0xFF0199D7)
val context = LocalContext.current

val authToken by authViewModel.authToken.observeAsState()

LaunchedEffect(authToken) {
if (authToken == null) {
navController.navigate(Screens.Login.screen) { popUpTo(0) { inclusive = true } }
}
}

ModalNavigationDrawer(
drawerState = drawerState,
gesturesEnabled = true,
Expand Down Expand Up @@ -178,10 +188,11 @@ fun MainLayout(
)
},
onClick = {
coroutineScope.launch { drawerState.close() }
authViewModel.logout()
Toast.makeText(context, "Logged out", Toast.LENGTH_SHORT).show()
navController.navigate(Screens.Login.screen) { popUpTo(0) { inclusive = true } }
coroutineScope.launch {
drawerState.close()
authViewModel.logout()
navController.navigate(Screens.Login.screen) { popUpTo(0) { inclusive = true } }
}
}
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,57 +8,94 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.navigation.NavType
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import com.server.movile.xef.android.ui.screens.*
import androidx.navigation.navArgument
import com.server.movile.xef.android.ui.screens.LoginScreen
import com.server.movile.xef.android.ui.screens.RegisterScreen
import com.server.movile.xef.android.ui.screens.menu.AssistantScreen
import com.server.movile.xef.android.ui.screens.menu.CreateAssistantScreen
import com.server.movile.xef.android.ui.screens.navigationdrawercompose.HomeScreen
import com.server.movile.xef.android.ui.viewmodels.IAuthViewModel
import com.xef.xefMobile.ui.screens.Screens
import com.xef.xefMobile.ui.screens.SettingsScreen
import com.xef.xefMobile.ui.viewmodels.SettingsViewModel

@OptIn(ExperimentalMaterial3Api::class)
@SuppressLint("UnusedMaterial3ScaffoldPaddingParameter")
@Composable
fun XefAndroidApp(authViewModel: IAuthViewModel) {
val navigationController = rememberNavController()
fun XefAndroidApp(authViewModel: IAuthViewModel, settingsViewModel: SettingsViewModel) {
val navController = rememberNavController()
val userName by authViewModel.userName.observeAsState("")

NavHost(
navController = navigationController,
navController = navController,
startDestination = Screens.Login.screen,
modifier = Modifier.padding(top = 16.dp)
) {
composable(Screens.Login.screen) { LoginScreen(authViewModel, navigationController) }
composable(Screens.Register.screen) { RegisterScreen(authViewModel, navigationController) }
composable(Screens.Login.screen) { LoginScreen(authViewModel, navController) }
composable(Screens.Register.screen) { RegisterScreen(authViewModel, navController) }
composable(Screens.Home.screen) {
MainLayout(
navController = navigationController,
navController = navController,
authViewModel = authViewModel,
userName = userName.orEmpty()
) {
HomeScreen(authViewModel, navigationController)
HomeScreen(authViewModel, navController)
}
}
composable(Screens.Assistants.screen) {
MainLayout(
navController = navigationController,
navController = navController,
authViewModel = authViewModel,
userName = userName.orEmpty()
) {
AssistantScreen(navigationController, authViewModel)
AssistantScreen(navController, authViewModel, settingsViewModel)
}
}
composable(
route = Screens.CreateAssistantWithArgs.screen,
arguments = listOf(navArgument("assistantId") { type = NavType.StringType })
) { backStackEntry ->
val assistantId = backStackEntry.arguments?.getString("assistantId")
MainLayout(
navController = navController,
authViewModel = authViewModel,
userName = userName.orEmpty()
) {
CreateAssistantScreen(
navController = navController,
authViewModel = authViewModel,
settingsViewModel = settingsViewModel,
assistantId = assistantId
)
}
}
composable(Screens.CreateAssistant.screen) {
MainLayout(
navController = navigationController,
navController = navController,
authViewModel = authViewModel,
userName = userName.orEmpty()
) {
CreateAssistantScreen(
navController = navController,
authViewModel = authViewModel,
settingsViewModel = settingsViewModel,
assistantId = null
)
}
}
composable(Screens.Settings.screen) {
MainLayout(
navController = navController,
authViewModel = authViewModel,
userName = userName.orEmpty()
) {
CreateAssistantScreen(navigationController)
SettingsScreen(navController, settingsViewModel)
}
}
// ... other composable screens ...
// Add other composable screens here...
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,21 @@
package com.xef.xefMobile.model

import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

@Serializable data class Assistant(val id: String, val name: String)
@Serializable
data class Assistant(
val id: String,
val name: String,
@SerialName("created_at") val createdAt: Long,
val description: String?,
val model: String,
val instructions: String,
val tools: List<Tool>,
val temperature: Float,
@SerialName("top_p") val topP: Float
)

@Serializable data class Tool(val type: String)

@Serializable data class AssistantsResponse(val data: List<Assistant>)
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package com.xef.xefMobile.services

import android.util.Log
import com.server.movile.xef.android.ui.viewmodels.CreateAssistantRequest
import com.server.movile.xef.android.ui.viewmodels.ModifyAssistantRequest
import com.xef.xefMobile.model.*
import com.xef.xefMobile.network.client.HttpClientProvider
import io.ktor.client.call.*
Expand All @@ -14,7 +16,7 @@ class ApiService {
return try {
HttpClientProvider.client
.post {
url("http://10.0.2.2:8081/register")
url("https://ace-asp-ghastly.ngrok-free.app/register")
contentType(ContentType.Application.Json)
setBody(request)
}
Expand All @@ -29,7 +31,7 @@ class ApiService {
return try {
val response: HttpResponse =
HttpClientProvider.client.post {
url("http://10.0.2.2:8081/login")
url("https://ace-asp-ghastly.ngrok-free.app/login")
contentType(ContentType.Application.Json)
setBody(request)
}
Expand All @@ -48,18 +50,62 @@ class ApiService {
return try {
val response: HttpResponse =
HttpClientProvider.client.get {
url("http://10.0.2.2:8081/v1/settings/assistants")
url("https://ace-asp-ghastly.ngrok-free.app/v1/settings/assistants")
header(HttpHeaders.Authorization, "Bearer $authToken")
header("OpenAI-Beta", "assistants=v1")
header("OpenAI-Beta", "assistants=v2")
}

val responseBody: String = response.bodyAsText()
Log.d("ApiService", "Assistants response body: $responseBody")

response.body()
} catch (e: Exception) {
Log.e("ApiService", "Fetching assistants failed: ${e.message}", e)
throw e
}
}

suspend fun createAssistant(authToken: String, request: CreateAssistantRequest): HttpResponse {
return try {
HttpClientProvider.client.post {
url("https://ace-asp-ghastly.ngrok-free.app/v1/settings/assistants")
contentType(ContentType.Application.Json)
header(HttpHeaders.Authorization, "Bearer $authToken")
setBody(request)
}
} catch (e: Exception) {
Log.e("ApiService", "Creating assistant failed: ${e.message}", e)
throw e
}
}

suspend fun deleteAssistant(authToken: String, assistantId: String): HttpResponse {
return try {
HttpClientProvider.client.delete {
url("https://ace-asp-ghastly.ngrok-free.app/v1/settings/assistants/$assistantId")
header(HttpHeaders.Authorization, "Bearer $authToken")
header("OpenAI-Beta", "assistants=v2")
}
} catch (e: Exception) {
Log.e("ApiService", "Deleting assistant failed: ${e.message}", e)
throw e
}
}

suspend fun updateAssistant(
authToken: String,
id: String,
request: ModifyAssistantRequest
): HttpResponse {
return try {
HttpClientProvider.client.put {
url("https://ace-asp-ghastly.ngrok-free.app/v1/settings/assistants/$id")
contentType(ContentType.Application.Json)
header(HttpHeaders.Authorization, "Bearer $authToken")
setBody(request)
}
} catch (e: Exception) {
Log.e("ApiService", "Updating assistant failed: ${e.message}", e)
throw e
}
}
}
Loading