Files
view-mate/app-phone/build.gradle.kts
T
Hermes Agent a434d5bb12 feat: потоковый локальный ассистент — фраза → LLM → ответ на очки
- agent/Assistant.kt: оркестратор диалога (SQLite-история + Koog), таймаут 30с,
  сессия одна живая, история — последние 20 сообщений
- ChatDao.latestSessionId(); SYSTEM_PROMPT нейтральный (TODO: персона)
- PhoneApp: очередь фраз (Channel UNLIMITED), assistantLoop (THINKING/ShowText/IDLE),
  ensureAssistant ленивый; ключ/модель из BuildConfig (local.properties)
- Очки: assistantText StateFlow, ShowText → оверлей (белый текст речи + серый ответ),
  оверлей остаётся после Click до новой сессии
- AssistantTest (androidTest, 3 теста: сессия/история/таймаут) — OK (6 tests всего)
- README: строка про ассистента
2026-08-20 12:35:49 +03:00

120 lines
4.3 KiB
Kotlin

import java.util.Properties
plugins {
alias(libs.plugins.android.application)
alias(libs.plugins.kotlin.android)
alias(libs.plugins.kotlinx.serialization)
alias(libs.plugins.compose.compiler)
}
// LLM-ключ из local.properties (llm.apiKey) — файл вне git; пустой = ещё не задан.
// providers.gradleProperty не читает local.properties, поэтому грузим файл вручную.
val llmApiKey: String = run {
val props = Properties()
val local = rootProject.file("local.properties")
if (local.exists()) local.inputStream().use(props::load)
props.getProperty("llm.apiKey", "")
.replace("\\", "\\\\")
.replace("\"", "\\\"")
}
// Модель для ассистента — из local.properties (llm.model), вне git.
// Дефолт — быстрая дешёвая (пользователь укажет боевую).
val llmModel: String = run {
val props = Properties()
val local = rootProject.file("local.properties")
if (local.exists()) local.inputStream().use(props::load)
props.getProperty("llm.model", "Routerai/deepseek/deepseek-v4-flash-0731")
.replace("\\", "\\\\")
.replace("\"", "\\\"")
}
android {
namespace = "pw.binom.viewmate.phone"
compileSdk = 35
defaultConfig {
applicationId = "pw.binom.viewmate.phone"
minSdk = 26
targetSdk = 34
versionCode = 1
versionName = "0.1.0"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
// LLM-ключ из local.properties (llm.apiKey) — вне git; пустой = ещё не задан
buildConfigField("String", "LLM_API_KEY", "\"$llmApiKey\"")
// Модель ассистента — из local.properties (llm.model), вне git
buildConfigField("String", "LLM_MODEL", "\"$llmModel\"")
}
buildTypes {
release {
isMinifyEnabled = false
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
kotlin {
compilerOptions {
jvmTarget.set(org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_17)
}
}
buildFeatures {
compose = true
buildConfig = true
}
packaging {
resources {
// okhttp-sse 5.x и jspecify оба кладут этот OSGI-manifest
excludes += "META-INF/versions/9/OSGI-INF/MANIFEST.MF"
}
}
}
dependencies {
implementation("androidx.appcompat:appcompat:1.3.0")
implementation("androidx.core:core-ktx:1.7.0")
implementation(libs.androidx.activity.compose)
implementation(platform(libs.androidx.compose.bom))
implementation(libs.android.material3)
implementation("androidx.compose.ui:ui")
implementation("androidx.compose.foundation:foundation")
implementation("io.coil-kt:coil-compose:2.6.0")
implementation("com.squareup.okhttp3:okhttp:4.12.0")
implementation(libs.exoplayer)
implementation(libs.media3.exoplayer)
implementation(libs.kotlinx.coroutines.android)
implementation(libs.kotlinx.serialization.json)
implementation(project(":lib-core"))
// Koog (JetBrains) — LLM-клиент (OpenAI-совместимый)
implementation(libs.koog.openai.client)
implementation(libs.koog.http.client.okhttp)
// Офлайн-распознавание речи (sherpa-onnx + Whisper), JitPack
implementation("com.github.k2-fsa.sherpa-onnx:sherpa-onnx:v1.13.6")
// WS-сервер телефона (CIO — работает на Android)
implementation("io.ktor:ktor-server-core:3.3.0")
implementation("io.ktor:ktor-server-cio:3.3.0")
implementation("io.ktor:ktor-server-websockets:3.3.0")
implementation("io.ktor:ktor-serialization-kotlinx-json:3.3.0")
testImplementation(kotlin("test"))
testImplementation("io.ktor:ktor-server-test-host:3.3.0")
testImplementation("io.ktor:ktor-client-websockets:3.3.0")
testImplementation("io.ktor:ktor-client-content-negotiation:3.3.0")
testImplementation("io.ktor:ktor-serialization-kotlinx-json:3.3.0")
testImplementation(libs.kotlinx.coroutines.test)
androidTestImplementation("androidx.test.ext:junit:1.2.1")
androidTestImplementation("androidx.test:runner:1.6.2")
}