mirror of
https://github.com/openai/codex.git
synced 2026-04-24 14:45:27 +00:00
Show Agent runtime status in session UI
Expose the embedded codexd runtime state directly in the Agent session screen so authentication, effective model, provider, client count, and base URL issues are visible without digging through fallback results or logcat. Co-authored-by: Codex <noreply@openai.com>
This commit is contained in:
@@ -41,6 +41,8 @@ class MainActivity : Activity() {
|
||||
private var statusRefreshInFlight = false
|
||||
@Volatile
|
||||
private var agentRefreshInFlight = false
|
||||
@Volatile
|
||||
private var latestRuntimeStatus: RuntimeStatus? = null
|
||||
|
||||
private val refreshHandler = Handler(Looper.getMainLooper())
|
||||
private val agentSessionController by lazy { AgentSessionController(this) }
|
||||
@@ -106,6 +108,7 @@ class MainActivity : Activity() {
|
||||
findViewById<TextView>(R.id.socket_path).text = defaultSocketPath()
|
||||
findViewById<TextView>(R.id.codex_home).text = defaultCodexHome()
|
||||
isServiceRunning = false
|
||||
latestRuntimeStatus = null
|
||||
updateAuthUi("Auth status: unknown", false, null, emptyList())
|
||||
updateAgentUi(AgentSnapshot.unavailable)
|
||||
}
|
||||
@@ -400,8 +403,10 @@ class MainActivity : Activity() {
|
||||
thread {
|
||||
val socketPath = defaultSocketPath()
|
||||
val result = runCatching { fetchAuthStatusWithRetry(socketPath) }
|
||||
val runtimeStatus = runCatching { fetchRuntimeStatusWithRetry(socketPath) }.getOrNull()
|
||||
result.onFailure { err ->
|
||||
isServiceRunning = false
|
||||
latestRuntimeStatus = null
|
||||
updateAuthUi(
|
||||
"Auth status: codexd stopped or unavailable (${err.message})",
|
||||
false,
|
||||
@@ -411,6 +416,7 @@ class MainActivity : Activity() {
|
||||
}
|
||||
result.onSuccess { status ->
|
||||
isServiceRunning = true
|
||||
latestRuntimeStatus = runtimeStatus
|
||||
val message = if (status.authenticated) {
|
||||
val emailSuffix = status.accountEmail?.let { " ($it)" } ?: ""
|
||||
"Auth status: signed in$emailSuffix"
|
||||
@@ -467,6 +473,7 @@ class MainActivity : Activity() {
|
||||
private fun updateAgentUi(snapshot: AgentSnapshot, unavailableMessage: String? = null) {
|
||||
runOnUiThread {
|
||||
val statusView = findViewById<TextView>(R.id.agent_status)
|
||||
val runtimeStatusView = findViewById<TextView>(R.id.agent_runtime_status)
|
||||
val genieView = findViewById<TextView>(R.id.agent_genie_package)
|
||||
val focusView = findViewById<TextView>(R.id.agent_session_focus)
|
||||
val groupView = findViewById<TextView>(R.id.agent_session_group)
|
||||
@@ -485,6 +492,7 @@ class MainActivity : Activity() {
|
||||
statusView.text = unavailableMessage?.let {
|
||||
"Agent framework unavailable ($it)"
|
||||
} ?: "Agent framework unavailable on this build"
|
||||
runtimeStatusView.text = renderAgentRuntimeStatus()
|
||||
genieView.text = "No GENIE role holder configured"
|
||||
focusView.text = "No framework session selected"
|
||||
groupView.text = "No framework sessions available"
|
||||
@@ -508,6 +516,7 @@ class MainActivity : Activity() {
|
||||
snapshot.roleHolders.joinToString(", ")
|
||||
}
|
||||
statusView.text = "Agent framework active. Genie role holders: $roleHolders"
|
||||
runtimeStatusView.text = renderAgentRuntimeStatus()
|
||||
genieView.text = snapshot.selectedGeniePackage ?: "No GENIE role holder configured"
|
||||
focusView.text = renderSelectedSession(snapshot)
|
||||
groupView.text = renderSessionGroup(snapshot)
|
||||
@@ -603,6 +612,28 @@ class MainActivity : Activity() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun renderAgentRuntimeStatus(): String {
|
||||
val runtimeStatus = latestRuntimeStatus
|
||||
if (runtimeStatus == null) {
|
||||
return if (isServiceRunning) {
|
||||
"Agent runtime: probing codexd..."
|
||||
} else {
|
||||
"Agent runtime: codexd unavailable"
|
||||
}
|
||||
}
|
||||
val authSummary = if (runtimeStatus.authenticated) {
|
||||
runtimeStatus.accountEmail?.let { "signed in ($it)" } ?: "signed in"
|
||||
} else {
|
||||
"not signed in"
|
||||
}
|
||||
val configuredModelSuffix = runtimeStatus.configuredModel
|
||||
?.takeIf { it != runtimeStatus.effectiveModel }
|
||||
?.let { ", configured=$it" }
|
||||
?: ""
|
||||
val effectiveModel = runtimeStatus.effectiveModel ?: "unknown"
|
||||
return "Agent runtime: $authSummary, provider=${runtimeStatus.modelProviderId}, effective=$effectiveModel$configuredModelSuffix, clients=${runtimeStatus.clientCount}, base=${runtimeStatus.upstreamBaseUrl}"
|
||||
}
|
||||
|
||||
private fun updateAuthUi(
|
||||
message: String,
|
||||
authenticated: Boolean,
|
||||
@@ -702,6 +733,16 @@ class MainActivity : Activity() {
|
||||
val clients: List<ClientStats>,
|
||||
)
|
||||
|
||||
private data class RuntimeStatus(
|
||||
val authenticated: Boolean,
|
||||
val accountEmail: String?,
|
||||
val clientCount: Int,
|
||||
val modelProviderId: String,
|
||||
val configuredModel: String?,
|
||||
val effectiveModel: String?,
|
||||
val upstreamBaseUrl: String,
|
||||
)
|
||||
|
||||
private data class ClientStats(
|
||||
val id: String,
|
||||
val activeConnections: Int,
|
||||
@@ -777,6 +818,28 @@ class MainActivity : Activity() {
|
||||
)
|
||||
}
|
||||
|
||||
private fun fetchRuntimeStatusWithRetry(socketPath: String): RuntimeStatus {
|
||||
val response = executeSocketRequestWithRetry(
|
||||
socketPath,
|
||||
"GET",
|
||||
"/internal/runtime/status",
|
||||
null,
|
||||
)
|
||||
if (response.statusCode != 200) {
|
||||
throw IOException("HTTP ${response.statusCode}: ${response.body}")
|
||||
}
|
||||
val json = JSONObject(response.body)
|
||||
return RuntimeStatus(
|
||||
authenticated = json.optBoolean("authenticated", false),
|
||||
accountEmail = if (json.isNull("accountEmail")) null else json.optString("accountEmail"),
|
||||
clientCount = json.optInt("clientCount", 0),
|
||||
modelProviderId = json.optString("modelProviderId", "unknown"),
|
||||
configuredModel = if (json.isNull("configuredModel")) null else json.optString("configuredModel"),
|
||||
effectiveModel = if (json.isNull("effectiveModel")) null else json.optString("effectiveModel"),
|
||||
upstreamBaseUrl = json.optString("upstreamBaseUrl", "unknown"),
|
||||
)
|
||||
}
|
||||
|
||||
private fun parseClients(clientsJson: JSONArray?): List<ClientStats> {
|
||||
if (clientsJson == null) {
|
||||
return emptyList()
|
||||
|
||||
@@ -21,6 +21,13 @@
|
||||
android:paddingTop="8dp"
|
||||
android:text="Agent framework unavailable on this build" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/agent_runtime_status"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingTop="4dp"
|
||||
android:text="Agent runtime: unknown" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
|
||||
Reference in New Issue
Block a user