Add Codex JSON sessions and usage limits

This commit is contained in:
iris committed 2026-09-07 23:29:15 -04:00
1 parent 0862b47f76
commit 6a0202b1b5
14 files changed
+1173 -52

No files matched your search

@@ -150,7 +150,7 @@ data class SessionSummary(
*/
val effort: String?,
/**
* Whether a thinking level does anything here -- a Claude CLI session, not a llama or echo one.
* Whether a thinking level does anything here -- a coding CLI session, not llama or echo.
*
* Asked of the server rather than worked out from the provider's name, because this is a
* property of the driver's *kind* and the phone only has the name.
@@ -1084,9 +1084,9 @@ fun setSessionModel(settings: ServerSettings, sessionId: String, model: String)
}
/**
* The permission modes the Claude CLI accepts, in the order they give up asking. "manual" asks for
* everything (each ask arrives on the phone as a question card); the others are the CLI's own
* escalating levels of autonomy.
* Common permission intents, in the order they give up asking. Each coding CLI maps these onto its
* own flags: "manual" asks, "acceptEdits" and "auto" allow ordinary work, "bypassPermissions"
* accepts everything, and "plan" makes no changes.
*
* One list for every screen that offers them -- spawn, import, and the session's own picker --
* because three copies had already drifted: the import screen was missing "plan".
@@ -1115,7 +1115,7 @@ fun setDefaultEffort(settings: ServerSettings, level: String?) {
}
/**
* How hard the model thinks, as `claude --effort` takes them, cheapest first.
* How hard a coding model thinks, cheapest first.
*
* Not offered alongside the model and the permission mode on the session's own bar, because it does
* not behave like them: the CLI has a control request for those two and none for this (checked
@@ -137,10 +137,12 @@ fun SpawnScreen(
.getOrDefault(emptyList())
}
val current = setup?.providers?.firstOrNull { it.name == providerName }
// Only the Claude CLI has models, a working directory and permission modes; keying the
// extra fields on the kind rather than the provider name keeps a second Claude provider
// Coding CLIs take a working directory, model, permission mode and thinking level. Keying
// the extra fields on the kind rather than the provider name keeps a second installation
// from needing anything here.
val isClaude = current?.kind == "claude_cli"
val isCodex = current?.kind == "codex_cli"
val isCodingCli = isClaude || isCodex
val isLlama = current?.kind == "llama_cpp"
// The machine first, because it decides what can be run at all.
@@ -237,7 +239,7 @@ fun SpawnScreen(
Spacer(Modifier.height(16.dp))
}
if (isClaude) {
if (isCodingCli) {
if (current.models.isNotEmpty()) {
Spacer(Modifier.height(16.dp))
ChipGroup(
@@ -307,7 +309,7 @@ fun SpawnScreen(
// an intent about new sessions in general, so a spawn that then
// fails must not also lose the choice. Non-fatal for the same
// reason the fetch above is -- the session is what was asked for.
if (isClaude) {
if (isCodingCli) {
runCatching { setDefaultEffort(settings, effort) }
}
spawnSession(
@@ -319,10 +321,11 @@ fun SpawnScreen(
provider = chosen.name,
title = title.trim(),
model =
if (isLlama) modelKey else model.trim().takeIf { isClaude },
cwd = cwd.trim().takeIf { isClaude },
permissionMode = permissionMode.takeIf { isClaude },
effort = effort.takeIf { isClaude },
if (isLlama) modelKey
else model.trim().takeIf { isCodingCli },
cwd = cwd.trim().takeIf { isCodingCli },
permissionMode = permissionMode.takeIf { isCodingCli },
effort = effort.takeIf { isCodingCli },
// Sent only when set, so blank means "whatever llama.cpp does
// by default" rather than a zero.
params =