mirror of
https://github.com/openai/codex.git
synced 2026-04-24 06:35:50 +00:00
Improve Android session detail panels
Co-authored-by: Codex <noreply@openai.com>
This commit is contained in:
@@ -7,11 +7,15 @@ import android.content.Intent
|
||||
import android.graphics.Typeface
|
||||
import android.os.Binder
|
||||
import android.os.Bundle
|
||||
import android.text.SpannableStringBuilder
|
||||
import android.text.Spanned
|
||||
import android.text.style.StyleSpan
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
import android.widget.Button
|
||||
import android.widget.EditText
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.ScrollView
|
||||
import android.widget.TextView
|
||||
import android.widget.Toast
|
||||
import kotlin.concurrent.thread
|
||||
@@ -210,21 +214,26 @@ class SessionDetailActivity : Activity() {
|
||||
append("\nThinking depth: ${executionSettings.reasoningEffort}")
|
||||
}
|
||||
}
|
||||
findViewById<TextView>(R.id.session_detail_summary).text = summary.trimEnd()
|
||||
findViewById<TextView>(R.id.session_detail_summary).text = formatDetailSummary(summary.trimEnd())
|
||||
renderChildSessions(viewState.childSessions, selectedChildSession?.sessionId)
|
||||
findViewById<TextView>(R.id.session_detail_child_summary).text =
|
||||
selectedChildSession?.let { child ->
|
||||
SessionUiFormatter.detailSummary(
|
||||
val childSummaryText = selectedChildSession?.let { child ->
|
||||
SessionUiFormatter.detailSummary(
|
||||
context = this,
|
||||
session = child,
|
||||
parentSession = topLevelSession,
|
||||
)
|
||||
} ?: if (topLevelSession.anchor == AgentSessionInfo.ANCHOR_AGENT && viewState.childSessions.isEmpty()) {
|
||||
"No child sessions yet. The Agent is still planning targets or waiting to start them."
|
||||
} else {
|
||||
"Select a child session to inspect it."
|
||||
}
|
||||
findViewById<TextView>(R.id.session_detail_timeline).text = renderTimeline(topLevelSession, selectedChildSession)
|
||||
} ?: if (topLevelSession.anchor == AgentSessionInfo.ANCHOR_AGENT && viewState.childSessions.isEmpty()) {
|
||||
"No child sessions yet. The Agent is still planning targets or waiting to start them."
|
||||
} else {
|
||||
"Select a child session to inspect it. Tap the same child again to collapse it."
|
||||
}
|
||||
findViewById<TextView>(R.id.session_detail_child_summary).text = formatDetailSummary(childSummaryText)
|
||||
findViewById<ScrollView>(R.id.session_detail_child_summary_container).scrollTo(0, 0)
|
||||
findViewById<TextView>(R.id.session_detail_timeline).text = formatTimeline(
|
||||
topLevelSession,
|
||||
selectedChildSession,
|
||||
)
|
||||
findViewById<ScrollView>(R.id.session_detail_timeline_container).scrollTo(0, 0)
|
||||
|
||||
val isWaitingForUser = actionableSession.state == AgentSessionInfo.STATE_WAITING_FOR_USER &&
|
||||
!actionableSession.latestQuestion.isNullOrBlank()
|
||||
@@ -342,11 +351,13 @@ class SessionDetailActivity : Activity() {
|
||||
}
|
||||
this.layoutParams = layoutParams
|
||||
setOnClickListener {
|
||||
if (session.sessionId != selectedChildSessionId) {
|
||||
selectedChildSessionId = session.sessionId
|
||||
requestedSessionId = topLevelSessionId
|
||||
updateUi(latestSnapshot)
|
||||
selectedChildSessionId = if (session.sessionId == selectedChildSessionId) {
|
||||
null
|
||||
} else {
|
||||
session.sessionId
|
||||
}
|
||||
requestedSessionId = topLevelSessionId
|
||||
updateUi(latestSnapshot)
|
||||
}
|
||||
}
|
||||
val title = TextView(this).apply {
|
||||
@@ -378,6 +389,63 @@ class SessionDetailActivity : Activity() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun formatDetailSummary(summary: String): CharSequence {
|
||||
val trimmed = summary.trim()
|
||||
if (trimmed.isEmpty()) {
|
||||
return ""
|
||||
}
|
||||
val builder = SpannableStringBuilder()
|
||||
trimmed.lines().forEachIndexed { index, line ->
|
||||
if (index > 0) {
|
||||
builder.append("\n\n")
|
||||
}
|
||||
val separatorIndex = line.indexOf(':')
|
||||
if (separatorIndex <= 0) {
|
||||
builder.append(line)
|
||||
return@forEachIndexed
|
||||
}
|
||||
val label = line.substring(0, separatorIndex)
|
||||
val value = line.substring(separatorIndex + 1).trim()
|
||||
appendBoldLine(builder, label)
|
||||
if (value.isNotEmpty()) {
|
||||
builder.append('\n')
|
||||
builder.append(value)
|
||||
}
|
||||
}
|
||||
return builder
|
||||
}
|
||||
|
||||
private fun formatTimeline(
|
||||
topLevelSession: AgentSessionDetails,
|
||||
selectedChildSession: AgentSessionDetails?,
|
||||
): CharSequence {
|
||||
val builder = SpannableStringBuilder()
|
||||
appendBoldLine(builder, "Top-level session ${topLevelSession.sessionId}")
|
||||
builder.append('\n')
|
||||
builder.append(topLevelSession.timeline.ifBlank { "No framework events yet." })
|
||||
selectedChildSession?.let { child ->
|
||||
builder.append("\n\n")
|
||||
appendBoldLine(builder, "Selected child ${child.sessionId}")
|
||||
builder.append('\n')
|
||||
builder.append(child.timeline.ifBlank { "No framework events yet." })
|
||||
}
|
||||
return builder
|
||||
}
|
||||
|
||||
private fun appendBoldLine(
|
||||
builder: SpannableStringBuilder,
|
||||
text: String,
|
||||
) {
|
||||
val start = builder.length
|
||||
builder.append(text)
|
||||
builder.setSpan(
|
||||
StyleSpan(Typeface.BOLD),
|
||||
start,
|
||||
builder.length,
|
||||
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE,
|
||||
)
|
||||
}
|
||||
|
||||
private fun answerQuestion() {
|
||||
val selectedSession = currentActionableSession(latestSnapshot) ?: return
|
||||
val answerInput = findViewById<EditText>(R.id.session_detail_answer_input)
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<solid android:color="#FFFAFBFC" />
|
||||
<stroke
|
||||
android:width="1dp"
|
||||
android:color="#FFD5D9DD" />
|
||||
<corners android:radius="14dp" />
|
||||
</shape>
|
||||
@@ -1,6 +1,7 @@
|
||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
android:layout_height="match_parent"
|
||||
android:fillViewport="true">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
@@ -80,11 +81,26 @@
|
||||
android:text="Selected Child Session"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/session_detail_child_summary"
|
||||
<ScrollView
|
||||
android:id="@+id/session_detail_child_summary_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Select a child session to inspect it." />
|
||||
android:layout_marginTop="8dp"
|
||||
android:maxHeight="220dp"
|
||||
android:background="@drawable/session_detail_panel_background"
|
||||
android:fadeScrollbars="false"
|
||||
android:overScrollMode="ifContentScrolls"
|
||||
android:scrollbarStyle="insideInset"
|
||||
android:scrollbars="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/session_detail_child_summary"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="14dp"
|
||||
android:text="Select a child session to inspect it."
|
||||
android:textIsSelectable="true" />
|
||||
</ScrollView>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/session_detail_child_actions"
|
||||
@@ -187,12 +203,26 @@
|
||||
android:text="Timeline"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/session_detail_timeline"
|
||||
<ScrollView
|
||||
android:id="@+id/session_detail_timeline_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:text="No framework events yet."
|
||||
android:textIsSelectable="true" />
|
||||
android:maxHeight="280dp"
|
||||
android:background="@drawable/session_detail_panel_background"
|
||||
android:fadeScrollbars="false"
|
||||
android:overScrollMode="ifContentScrolls"
|
||||
android:scrollbarStyle="insideInset"
|
||||
android:scrollbars="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/session_detail_timeline"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="14dp"
|
||||
android:text="No framework events yet."
|
||||
android:textIsSelectable="true"
|
||||
android:typeface="monospace" />
|
||||
</ScrollView>
|
||||
</LinearLayout>
|
||||
</ScrollView>
|
||||
|
||||
Reference in New Issue
Block a user