mirror of
https://github.com/HKUDS/nanobot.git
synced 2026-08-04 08:28:36 +00:00
chore: default context window to 200k
This commit is contained in:
parent
991422a328
commit
0db9fbe250
@ -329,7 +329,7 @@ The example below uses a generic OpenAI-compatible `custom` provider so the comp
|
|||||||
"provider": "custom",
|
"provider": "custom",
|
||||||
"model": "model-id-from-your-provider",
|
"model": "model-id-from-your-provider",
|
||||||
"maxTokens": 8192,
|
"maxTokens": 8192,
|
||||||
"contextWindowTokens": 65536,
|
"contextWindowTokens": 200000,
|
||||||
"temperature": 0.1
|
"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)
|
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
|
# We only auto-fill if the user hasn't changed it from default
|
||||||
from nanobot.config.schema import AgentDefaults
|
from nanobot.config.schema import AgentDefaults
|
||||||
|
|
||||||
|
|||||||
@ -100,7 +100,7 @@ class ModelPresetConfig(Base):
|
|||||||
model: str
|
model: str
|
||||||
provider: str = "auto"
|
provider: str = "auto"
|
||||||
max_tokens: int = 8192
|
max_tokens: int = 8192
|
||||||
context_window_tokens: int = 65_536
|
context_window_tokens: int = 200_000
|
||||||
temperature: float = 0.1
|
temperature: float = 0.1
|
||||||
reasoning_effort: str | None = None
|
reasoning_effort: str | None = None
|
||||||
|
|
||||||
@ -123,7 +123,7 @@ class AgentDefaults(Base):
|
|||||||
"auto" # Provider name (e.g. "anthropic", "openrouter") or "auto" for auto-detection
|
"auto" # Provider name (e.g. "anthropic", "openrouter") or "auto" for auto-detection
|
||||||
)
|
)
|
||||||
max_tokens: int = 8192
|
max_tokens: int = 8192
|
||||||
context_window_tokens: int = 65_536
|
context_window_tokens: int = 200_000
|
||||||
context_block_limit: int | None = None
|
context_block_limit: int | None = None
|
||||||
temperature: float = 0.1
|
temperature: float = 0.1
|
||||||
fallback_models: list[FallbackCandidate] = Field(default_factory=list)
|
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
|
### Large codebase analysis
|
||||||
```
|
```
|
||||||
→ my(action="check")
|
→ my(action="check")
|
||||||
→ context_window_tokens: 65536
|
→ context_window_tokens: 200000
|
||||||
→ my(action="set", key="context_window_tokens", value=131072)
|
→ 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."
|
→ "I've expanded my context window to handle this large codebase."
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@ -106,7 +106,7 @@ _IMAGE_GENERATION_ASPECT_RATIOS = {
|
|||||||
"2:3",
|
"2:3",
|
||||||
"21:9",
|
"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_-]+")
|
_MODEL_CONFIGURATION_SLUG_RE = re.compile(r"[^a-z0-9_-]+")
|
||||||
_ENV_REF_RE = re.compile(r"\$\{([A-Za-z_][A-Za-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:
|
except ValueError:
|
||||||
raise WebUISettingsError("context_window_tokens must be an integer") from None
|
raise WebUISettingsError("context_window_tokens must be an integer") from None
|
||||||
if parsed not in _CONTEXT_WINDOW_TOKEN_OPTIONS:
|
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
|
return parsed
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -183,7 +183,7 @@ class TestRestartCommand:
|
|||||||
assert response is not None
|
assert response is not None
|
||||||
assert "Model: test-model" in response.content
|
assert "Model: test-model" in response.content
|
||||||
assert "Tokens: 0 in / 0 out" 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 "Session: 3 messages" in response.content
|
||||||
assert "Uptime: 2m 5s" in response.content
|
assert "Uptime: 2m 5s" in response.content
|
||||||
assert "Tasks: 0 active" in response.content
|
assert "Tasks: 0 active" in response.content
|
||||||
@ -256,7 +256,7 @@ class TestRestartCommand:
|
|||||||
|
|
||||||
assert response is not None
|
assert response is not None
|
||||||
assert "Tokens: 1200 in / 34 out" in response.content
|
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
|
assert "Tasks: 0 active" in response.content
|
||||||
|
|
||||||
@pytest.mark.asyncio
|
@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)
|
config = load_config(config_path)
|
||||||
|
|
||||||
assert config.agents.defaults.max_tokens == 1234
|
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")
|
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"]
|
defaults = saved["agents"]["defaults"]
|
||||||
|
|
||||||
assert defaults["maxTokens"] == 2222
|
assert defaults["maxTokens"] == 2222
|
||||||
assert defaults["contextWindowTokens"] == 65_536
|
assert defaults["contextWindowTokens"] == 200_000
|
||||||
assert "memoryWindow" not in defaults
|
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)
|
monkeypatch.setattr("nanobot.cli.commands.get_workspace_path", lambda _workspace=None: workspace)
|
||||||
|
|
||||||
from typer.testing import CliRunner
|
from typer.testing import CliRunner
|
||||||
|
|
||||||
from nanobot.cli.commands import app
|
from nanobot.cli.commands import app
|
||||||
runner = CliRunner()
|
runner = CliRunner()
|
||||||
result = runner.invoke(app, ["onboard"], input="n\n")
|
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 typer.testing import CliRunner
|
||||||
|
|
||||||
from nanobot.cli.commands import app
|
from nanobot.cli.commands import app
|
||||||
runner = CliRunner()
|
runner = CliRunner()
|
||||||
result = runner.invoke(app, ["onboard"], input="n\n")
|
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)
|
save_config(config, config_path)
|
||||||
monkeypatch.setattr("nanobot.config.loader._current_config_path", 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)
|
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(
|
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)
|
save_config(Config(), config_path)
|
||||||
monkeypatch.setattr("nanobot.config.loader._current_config_path", 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"]})
|
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 ProviderForm = { apiKey: string; apiBase: string; apiType: ProviderApiType };
|
||||||
type CustomMcpTransport = "stdio" | "streamableHttp" | "sse";
|
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([
|
const DEFERRED_MODEL_LIST_PROVIDERS = new Set([
|
||||||
"aihubmix",
|
"aihubmix",
|
||||||
"atomic_chat",
|
"atomic_chat",
|
||||||
@ -335,7 +335,7 @@ function defaultPreset(payload: SettingsPayload): SettingsPayload["model_presets
|
|||||||
}
|
}
|
||||||
|
|
||||||
function normalizeContextWindowTokens(value: number | null | undefined): number {
|
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 {
|
function editableDefaultProvider(payload: SettingsPayload): string {
|
||||||
@ -372,7 +372,7 @@ const DEFAULT_AGENT_SETTINGS_DRAFT: AgentSettingsDraft = {
|
|||||||
provider: "",
|
provider: "",
|
||||||
modelPreset: "default",
|
modelPreset: "default",
|
||||||
presetLabel: "Default",
|
presetLabel: "Default",
|
||||||
contextWindowTokens: 65_536,
|
contextWindowTokens: 200_000,
|
||||||
timezone: "UTC",
|
timezone: "UTC",
|
||||||
botName: "nanobot",
|
botName: "nanobot",
|
||||||
botIcon: "",
|
botIcon: "",
|
||||||
@ -2552,7 +2552,8 @@ function ModelsSettings({
|
|||||||
value={String(form.contextWindowTokens)}
|
value={String(form.contextWindowTokens)}
|
||||||
options={CONTEXT_WINDOW_TOKEN_OPTIONS.map((tokens) => ({
|
options={CONTEXT_WINDOW_TOKEN_OPTIONS.map((tokens) => ({
|
||||||
value: String(tokens),
|
value: String(tokens),
|
||||||
label: tokens === 262_144 ? "256K" : "64K",
|
label:
|
||||||
|
tokens === 262_144 ? "256K" : tokens === 200_000 ? "200K" : "64K",
|
||||||
}))}
|
}))}
|
||||||
onChange={(value) =>
|
onChange={(value) =>
|
||||||
setForm((prev) => ({
|
setForm((prev) => ({
|
||||||
|
|||||||
@ -22,7 +22,7 @@ function settingsPayload(): SettingsPayload {
|
|||||||
has_api_key: true,
|
has_api_key: true,
|
||||||
model_preset: "default",
|
model_preset: "default",
|
||||||
max_tokens: 8192,
|
max_tokens: 8192,
|
||||||
context_window_tokens: 65536,
|
context_window_tokens: 200000,
|
||||||
temperature: 0.1,
|
temperature: 0.1,
|
||||||
reasoning_effort: null,
|
reasoning_effort: null,
|
||||||
timezone: "UTC",
|
timezone: "UTC",
|
||||||
@ -38,7 +38,7 @@ function settingsPayload(): SettingsPayload {
|
|||||||
model: "openai/gpt-4o",
|
model: "openai/gpt-4o",
|
||||||
provider: "auto",
|
provider: "auto",
|
||||||
max_tokens: 8192,
|
max_tokens: 8192,
|
||||||
context_window_tokens: 65536,
|
context_window_tokens: 200000,
|
||||||
temperature: 0.1,
|
temperature: 0.1,
|
||||||
reasoning_effort: null,
|
reasoning_effort: null,
|
||||||
}],
|
}],
|
||||||
@ -421,6 +421,7 @@ describe("SettingsView Apps catalog", () => {
|
|||||||
|
|
||||||
expect(await screen.findByText("Context window")).toBeInTheDocument();
|
expect(await screen.findByText("Context window")).toBeInTheDocument();
|
||||||
expect(screen.getByRole("button", { name: "64K" })).toBeInTheDocument();
|
expect(screen.getByRole("button", { name: "64K" })).toBeInTheDocument();
|
||||||
|
expect(screen.getByRole("button", { name: "200K" })).toBeInTheDocument();
|
||||||
expect(screen.getByRole("button", { name: "256K" })).toBeInTheDocument();
|
expect(screen.getByRole("button", { name: "256K" })).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user