Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
32 changes: 31 additions & 1 deletion bin/ultracode
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,37 @@ PORT="${UC_LISTEN_PORT:-$("$PY" -c 'import json,sys;c=json.load(open(sys.argv[1]
UPSTREAM="${UC_UPSTREAM:-$("$PY" -c 'import json,sys;c=json.load(open(sys.argv[1]));print((c.get("proxy") or {}).get("anthropic_upstream") or "https://api.anthropic.com")' "$CONFIG" 2>/dev/null || echo https://api.anthropic.com)}"
BASE_URL="http://127.0.0.1:${PORT}"

# 1M context window enablement ------------------------------------------------
# Claude Code only switches its context meter AND auto-compaction to the 1M
# window (and sends the context-1m beta) when the model id carries the [1m]
# suffix. The selector and config advertise bare ids (e.g. claude-opus-4-8), so
# without this the client sizes context at 200k -- the meter fills ~5x too fast
# and pins at 100% -- even though Opus 4.8 / Sonnet 4.6 serve 1M natively. We
# append [1m] to 1M-capable Claude base ids before launch. Disable with
# UC_FORCE_1M=0; override the capable set with UC_1M_MODELS (comma-separated).
UC_FORCE_1M="${UC_FORCE_1M:-1}"
UC_1M_MODELS="${UC_1M_MODELS:-claude-opus-4-8,claude-opus-4-7,claude-opus-4-6,claude-sonnet-4-6}"
uc_add_1m() {
# Echo $1 with a [1m] suffix iff it is a bare, 1M-capable Claude id. Anything
# else (Auto Router, Gemini/GPT/Composer, Haiku, already-suffixed, empty) is
# passed through untouched.
local m="$1" id
if [[ "$UC_FORCE_1M" == "0" || -z "$m" || "$m" == *"[1m]"* ]]; then
printf '%s' "$m"; return
fi
IFS=',' read -ra _uc_1m_ids <<< "$UC_1M_MODELS"
for id in "${_uc_1m_ids[@]}"; do
if [[ "$m" == "$id" ]]; then printf '%s[1m]' "$m"; return; fi
done
printf '%s' "$m"
}
DEFAULT_MODEL="$(uc_add_1m "claude-opus-4-8")"

# Session settings (ultracode + discovery env).
cat > "$SETTINGS" <<JSON
{
"ultracode": true,
"model": "claude-opus-4-8",
"model": "$DEFAULT_MODEL",
"env": {
"ANTHROPIC_BASE_URL": "$BASE_URL",
"CLAUDE_CODE_WORKFLOWS": "1",
Expand Down Expand Up @@ -160,6 +186,10 @@ if [[ "${UC_SELECTOR:-1}" != "0" && -f "$SELECTOR" ]]; then
echo "Selector unavailable; launching with default model."
SELECTED_MODEL=""
fi
# Upgrade a 1M-capable Claude pick to its [1m] variant so the client uses the
# full 1M context window (meter + auto-compaction), not the 200k default.
SELECTED_MODEL="$(uc_add_1m "$SELECTED_MODEL")"
[[ -n "$SELECTED_MODEL" ]] && echo "Orchestrator model id: $SELECTED_MODEL"
fi

HAS_MODEL_ARG=0
Expand Down
28 changes: 28 additions & 0 deletions docs/TROUBLESHOOTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,34 @@ side — here, all on Windows). The cleanest way to make any model follow the ru
above automatically is to drop them into a `CLAUDE.md` (project root, or the global
`~/.claude/CLAUDE.md`).

### Context fills up too fast / `/context` shows `200k` for a 1M model

**Symptom.** You picked Opus 4.8 (or Sonnet 4.6) — models with a 1M context
window — but the status-line meter climbs ~5× faster than expected and pins at
100%, auto-compaction fires early or not at all, and `/context` shows the limit
as `… / 200k` instead of `/ 1M`.

**Cause.** Claude Code only switches its context meter **and** auto-compaction to
the 1M window (and sends the `context-1m` beta) when the session's model id
carries the **`[1m]`** suffix (e.g. `claude-opus-4-8[1m]`). The selector and
`config.json` advertise *bare* ids (`claude-opus-4-8`), so the client defaults to
the 200k window even though Opus 4.8 / Opus 4.7 / Opus 4.6 / Sonnet 4.6 serve 1M
natively on the Anthropic API. Nothing is actually lost upstream — the window is
just mis-sized in the client.

**Fix.** The launcher now appends `[1m]` automatically when the chosen
orchestrator is a 1M-capable Claude model. Relaunch, pick the model, and confirm
`/context` reads `/ 1M`.

- **Disable it** (back to bare ids): set `UC_FORCE_1M=0`.
- **Change the capable set:** set `UC_1M_MODELS` to a comma-separated list of base
ids (default `claude-opus-4-8,claude-opus-4-7,claude-opus-4-6,claude-sonnet-4-6`).
- **Not affected:** Haiku 4.5 (200k only), `claude-auto`, and non-Claude routes
(Gemini / GPT / Composer) are never given a `[1m]` suffix.
- **Caveat:** if your Anthropic-passthrough hop can fall back to a backend that
only supports 200k, a conversation that grows past 200k may then fail there —
make sure that fallback also honors 1M.

### Did I break my normal Claude Code?

No — this project never edits your global `~/.claude` config or credentials; it
Expand Down
28 changes: 27 additions & 1 deletion windows/Start-UltraCode.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,31 @@ $StateDir = Join-Path $env:LOCALAPPDATA "UltraCode-Shim"
New-Item -ItemType Directory -Force -Path $StateDir | Out-Null
$Settings = Join-Path $StateDir "ultracode_settings.json"
$BaseUrl = "http://127.0.0.1:$Port"

# 1M context window enablement: Claude Code only switches its context meter AND
# auto-compaction to the 1M window (and sends the context-1m beta) when the model
# id carries the [1m] suffix. The selector/config advertise bare ids (e.g.
# claude-opus-4-8), so without this the client sizes context at 200k -- the meter
# fills ~5x too fast and pins at 100% -- even though Opus 4.8 / Sonnet 4.6 serve
# 1M natively. We append [1m] to 1M-capable Claude base ids before launch.
# Disable with UC_FORCE_1M=0; override the capable set with UC_1M_MODELS.
function Add-Uc1m {
param([string]$ModelId)
if ($env:UC_FORCE_1M -eq "0") { return $ModelId }
if ([string]::IsNullOrEmpty($ModelId)) { return $ModelId }
if ($ModelId.Contains("[1m]")) { return $ModelId }
$set = if ($env:UC_1M_MODELS) { $env:UC_1M_MODELS }
else { "claude-opus-4-8,claude-opus-4-7,claude-opus-4-6,claude-sonnet-4-6" }
foreach ($id in $set.Split(",")) {
if ($ModelId -eq $id.Trim()) { return "${ModelId}[1m]" }
}
return $ModelId
}
$DefaultModel = Add-Uc1m "claude-opus-4-8"

@{
ultracode = $true
model = "claude-opus-4-8"
model = $DefaultModel
env = @{
ANTHROPIC_BASE_URL = $BaseUrl
CLAUDE_CODE_WORKFLOWS = "1"
Expand Down Expand Up @@ -231,6 +253,10 @@ if (($env:UC_SELECTOR -ne "0") -and (Test-Path $Selector)) {
Write-Host "Selector unavailable; launching with default model: $_" -ForegroundColor Yellow
$SelectedModel = ""
}
# Upgrade a 1M-capable Claude pick to its [1m] variant so the client uses the
# full 1M context window (meter + auto-compaction), not the 200k default.
$SelectedModel = Add-Uc1m $SelectedModel
if ($SelectedModel) { Write-Host "Orchestrator model id: $SelectedModel" -ForegroundColor Green }
}

$HasModelArg = $false
Expand Down
Loading