chore: default context window to 200k
This commit is contained in:
@@ -329,7 +329,7 @@ The example below uses a generic OpenAI-compatible `custom` provider so the comp
|
||||
"provider": "custom",
|
||||
"model": "model-id-from-your-provider",
|
||||
"maxTokens": 8192,
|
||||
"contextWindowTokens": 65536,
|
||||
"contextWindowTokens": 200000,
|
||||
"temperature": 0.1
|
||||
}
|
||||
},
|
||||
|
||||
@@ -993,7 +993,7 @@ def _try_auto_fill_context_window(model: BaseModel, new_model_name: str) -> None
|
||||
|
||||
current_context = getattr(model, "context_window_tokens", None)
|
||||
|
||||
# Check if current value is the default (65536)
|
||||
# Check if current value is the default
|
||||
# We only auto-fill if the user hasn't changed it from default
|
||||
from nanobot.config.schema import AgentDefaults
|
||||
|
||||
|
||||
@@ -100,7 +100,7 @@ class ModelPresetConfig(Base):
|
||||
model: str
|
||||
provider: str = "auto"
|
||||
max_tokens: int = 8192
|
||||
context_window_tokens: int = 65_536
|
||||
context_window_tokens: int = 200_000
|
||||
temperature: float = 0.1
|
||||
reasoning_effort: str | None = None
|
||||
|
||||
@@ -123,7 +123,7 @@ class AgentDefaults(Base):
|
||||
"auto" # Provider name (e.g. "anthropic", "openrouter") or "auto" for auto-detection
|
||||
)
|
||||
max_tokens: int = 8192
|
||||
context_window_tokens: int = 65_536
|
||||
context_window_tokens: int = 200_000
|
||||
context_block_limit: int | None = None
|
||||
temperature: float = 0.1
|
||||
fallback_models: list[FallbackCandidate] = Field(default_factory=list)
|
||||
|
||||
@@ -33,9 +33,9 @@ Concrete scenarios showing when and how to use the my tool effectively.
|
||||
### Large codebase analysis
|
||||
```
|
||||
→ my(action="check")
|
||||
→ context_window_tokens: 65536
|
||||
→ context_window_tokens: 200000
|
||||
→ my(action="set", key="context_window_tokens", value=131072)
|
||||
→ "Set context_window_tokens = 131072 (was 65536)"
|
||||
→ "Set context_window_tokens = 131072 (was 200000)"
|
||||
→ "I've expanded my context window to handle this large codebase."
|
||||
```
|
||||
|
||||
|
||||
@@ -106,7 +106,7 @@ _IMAGE_GENERATION_ASPECT_RATIOS = {
|
||||
"2:3",
|
||||
"21:9",
|
||||
}
|
||||
_CONTEXT_WINDOW_TOKEN_OPTIONS = {65_536, 262_144}
|
||||
_CONTEXT_WINDOW_TOKEN_OPTIONS = {65_536, 200_000, 262_144}
|
||||
_MODEL_CONFIGURATION_SLUG_RE = re.compile(r"[^a-z0-9_-]+")
|
||||
_ENV_REF_RE = re.compile(r"\$\{([A-Za-z_][A-Za-z0-9_]*)\}")
|
||||
|
||||
@@ -606,7 +606,7 @@ def _parse_context_window_tokens(value: str | None) -> int | None:
|
||||
except ValueError:
|
||||
raise WebUISettingsError("context_window_tokens must be an integer") from None
|
||||
if parsed not in _CONTEXT_WINDOW_TOKEN_OPTIONS:
|
||||
raise WebUISettingsError("context_window_tokens must be 65536 or 262144")
|
||||
raise WebUISettingsError("context_window_tokens must be 65536, 200000, or 262144")
|
||||
return parsed
|
||||
|
||||
|
||||
|
||||
@@ -183,7 +183,7 @@ class TestRestartCommand:
|
||||
assert response is not None
|
||||
assert "Model: test-model" in response.content
|
||||
assert "Tokens: 0 in / 0 out" in response.content
|
||||
assert "Context: 20k/65k (31% of input budget)" in response.content
|
||||
assert "Context: 20k/200k (10% of input budget)" in response.content
|
||||
assert "Session: 3 messages" in response.content
|
||||
assert "Uptime: 2m 5s" in response.content
|
||||
assert "Tasks: 0 active" in response.content
|
||||
@@ -256,7 +256,7 @@ class TestRestartCommand:
|
||||
|
||||
assert response is not None
|
||||
assert "Tokens: 1200 in / 34 out" in response.content
|
||||
assert "Context: 1k/65k (1% of input budget)" in response.content
|
||||
assert "Context: 1k/200k (0% of input budget)" in response.content
|
||||
assert "Tasks: 0 active" in response.content
|
||||
|
||||
@pytest.mark.asyncio
|
||||
|
||||
@@ -34,7 +34,7 @@ def test_load_config_keeps_max_tokens_and_ignores_legacy_memory_window(tmp_path)
|
||||
config = load_config(config_path)
|
||||
|
||||
assert config.agents.defaults.max_tokens == 1234
|
||||
assert config.agents.defaults.context_window_tokens == 65_536
|
||||
assert config.agents.defaults.context_window_tokens == 200_000
|
||||
assert not hasattr(config.agents.defaults, "memory_window")
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ def test_save_config_writes_context_window_tokens_but_not_memory_window(tmp_path
|
||||
defaults = saved["agents"]["defaults"]
|
||||
|
||||
assert defaults["maxTokens"] == 2222
|
||||
assert defaults["contextWindowTokens"] == 65_536
|
||||
assert defaults["contextWindowTokens"] == 200_000
|
||||
assert "memoryWindow" not in defaults
|
||||
|
||||
|
||||
@@ -85,6 +85,7 @@ def test_onboard_does_not_crash_with_legacy_memory_window(tmp_path, monkeypatch)
|
||||
monkeypatch.setattr("nanobot.cli.commands.get_workspace_path", lambda _workspace=None: workspace)
|
||||
|
||||
from typer.testing import CliRunner
|
||||
|
||||
from nanobot.cli.commands import app
|
||||
runner = CliRunner()
|
||||
result = runner.invoke(app, ["onboard"], input="n\n")
|
||||
@@ -131,6 +132,7 @@ def test_onboard_refresh_backfills_missing_channel_fields(tmp_path, monkeypatch)
|
||||
)
|
||||
|
||||
from typer.testing import CliRunner
|
||||
|
||||
from nanobot.cli.commands import app
|
||||
runner = CliRunner()
|
||||
result = runner.invoke(app, ["onboard"], input="n\n")
|
||||
|
||||
@@ -233,11 +233,11 @@ def test_update_agent_settings_accepts_context_window_options(
|
||||
save_config(config, config_path)
|
||||
monkeypatch.setattr("nanobot.config.loader._current_config_path", config_path)
|
||||
|
||||
payload = update_agent_settings({"context_window_tokens": ["262144"]})
|
||||
payload = update_agent_settings({"context_window_tokens": ["200000"]})
|
||||
|
||||
assert payload["agent"]["context_window_tokens"] == 262144
|
||||
assert payload["agent"]["context_window_tokens"] == 200000
|
||||
saved = load_config(config_path)
|
||||
assert saved.agents.defaults.context_window_tokens == 262144
|
||||
assert saved.agents.defaults.context_window_tokens == 200000
|
||||
|
||||
|
||||
def test_update_model_configuration_accepts_context_window_options(
|
||||
@@ -274,7 +274,10 @@ def test_update_context_window_rejects_unknown_values(
|
||||
save_config(Config(), config_path)
|
||||
monkeypatch.setattr("nanobot.config.loader._current_config_path", config_path)
|
||||
|
||||
with pytest.raises(WebUISettingsError, match="context_window_tokens must be 65536 or 262144"):
|
||||
with pytest.raises(
|
||||
WebUISettingsError,
|
||||
match="context_window_tokens must be 65536, 200000, or 262144",
|
||||
):
|
||||
update_agent_settings({"context_window_tokens": ["128000"]})
|
||||
|
||||
|
||||
|
||||
@@ -195,7 +195,7 @@ type ProviderApiType = "auto" | "chat_completions" | "responses";
|
||||
type ProviderForm = { apiKey: string; apiBase: string; apiType: ProviderApiType };
|
||||
type CustomMcpTransport = "stdio" | "streamableHttp" | "sse";
|
||||
|
||||
const CONTEXT_WINDOW_TOKEN_OPTIONS = [65_536, 262_144] as const;
|
||||
const CONTEXT_WINDOW_TOKEN_OPTIONS = [65_536, 200_000, 262_144] as const;
|
||||
const DEFERRED_MODEL_LIST_PROVIDERS = new Set([
|
||||
"aihubmix",
|
||||
"atomic_chat",
|
||||
@@ -335,7 +335,7 @@ function defaultPreset(payload: SettingsPayload): SettingsPayload["model_presets
|
||||
}
|
||||
|
||||
function normalizeContextWindowTokens(value: number | null | undefined): number {
|
||||
return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : 65_536;
|
||||
return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : 200_000;
|
||||
}
|
||||
|
||||
function editableDefaultProvider(payload: SettingsPayload): string {
|
||||
@@ -372,7 +372,7 @@ const DEFAULT_AGENT_SETTINGS_DRAFT: AgentSettingsDraft = {
|
||||
provider: "",
|
||||
modelPreset: "default",
|
||||
presetLabel: "Default",
|
||||
contextWindowTokens: 65_536,
|
||||
contextWindowTokens: 200_000,
|
||||
timezone: "UTC",
|
||||
botName: "nanobot",
|
||||
botIcon: "",
|
||||
@@ -2552,7 +2552,8 @@ function ModelsSettings({
|
||||
value={String(form.contextWindowTokens)}
|
||||
options={CONTEXT_WINDOW_TOKEN_OPTIONS.map((tokens) => ({
|
||||
value: String(tokens),
|
||||
label: tokens === 262_144 ? "256K" : "64K",
|
||||
label:
|
||||
tokens === 262_144 ? "256K" : tokens === 200_000 ? "200K" : "64K",
|
||||
}))}
|
||||
onChange={(value) =>
|
||||
setForm((prev) => ({
|
||||
|
||||
@@ -22,7 +22,7 @@ function settingsPayload(): SettingsPayload {
|
||||
has_api_key: true,
|
||||
model_preset: "default",
|
||||
max_tokens: 8192,
|
||||
context_window_tokens: 65536,
|
||||
context_window_tokens: 200000,
|
||||
temperature: 0.1,
|
||||
reasoning_effort: null,
|
||||
timezone: "UTC",
|
||||
@@ -38,7 +38,7 @@ function settingsPayload(): SettingsPayload {
|
||||
model: "openai/gpt-4o",
|
||||
provider: "auto",
|
||||
max_tokens: 8192,
|
||||
context_window_tokens: 65536,
|
||||
context_window_tokens: 200000,
|
||||
temperature: 0.1,
|
||||
reasoning_effort: null,
|
||||
}],
|
||||
@@ -421,6 +421,7 @@ describe("SettingsView Apps catalog", () => {
|
||||
|
||||
expect(await screen.findByText("Context window")).toBeInTheDocument();
|
||||
expect(screen.getByRole("button", { name: "64K" })).toBeInTheDocument();
|
||||
expect(screen.getByRole("button", { name: "200K" })).toBeInTheDocument();
|
||||
expect(screen.getByRole("button", { name: "256K" })).toBeInTheDocument();
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user