import { renderPageHeader, renderSegmentedField, renderTabStrip, bindTabStrip } from './page_header.js';
import { PAGE_ICONS } from './page_icons.js';
import { renderAgentAccountsSection, renderAgentsServiceBanner } from './harness_accounts.js';
import { renderReviewerSlotsSection } from './reviewer_slots.js';
import { renderSubagentsSection } from './subagents_settings.js';
import { modelRolesHost } from './model_roles.js';
// Reads as a sequence: keys → secrets → which API models → who among the agents
// does what → behavior → technical. "Agents", not "Coding agents" (D-10): the
// same subscriptions build presentations and run arbitrary tasks, so the
// narrower word named only one of their uses.
const SETTINGS_TABS = [
{ value: 'providers', label: 'Accounts' },
{ value: 'secrets', label: 'Secrets' },
{ value: 'models', label: 'Models' },
{ value: 'agents', label: 'Agents' },
{ value: 'behavior', label: 'Behavior' },
{ value: 'appearance', label: 'Appearance' },
{ value: 'advanced', label: 'Advanced' },
{ value: 'about', label: 'About' },
];
// Guard markers: renderTabStrip emits behavior/advanced tabs at runtime.
// 6.3: Review and Scope Review efforts moved to per-slot dropdowns in
// Agents → Review lanes. Behavior keeps the surface-level lanes.
const EFFORT_FIELDS = [
['s-effort-task', 'Task / Chat', 'medium'],
['s-effort-evolution', 'Evolution', 'high'],
['s-effort-deep-self-review', 'Deep Self-Review', 'high'],
['s-effort-consciousness', 'Consciousness', ''], // '' = the Task / Chat effort (a wake-up is a Main turn)
];
// Runtime mode is one axis of the owner policy contract. Keep the Settings
// presentation in the same vocabulary as the onboarding setup contract; the
// saved value is still handled by settings.js and the owner endpoint.
const RUNTIME_MODE_OPTIONS = [
{ value: 'light', label: 'Light' },
{ value: 'advanced', label: 'Advanced' },
{ value: 'pro', label: 'Pro' },
{ value: 'cyber_pro', label: 'Cyber Pro' },
];
function providerCard({ id, title, icon, hint, body, open = false }) {
return `
` : ''}
${title}
OPENAI_BASE_URL empty when you want web_search.',
},
{
// advanced: rendered inside the collapsed "More providers" section.
// Inputs stay mounted either way — settings.js applyInputValue has no
// null guard, so every input id must always exist in the DOM.
id: 'cloudru', title: 'Cloud.ru Foundation Models', icon: '/static/providers/cloudru.svg', hint: 'Cloud.ru OpenAI-compatible runtime', advanced: true,
fields: [
{ id: 's-cloudru-key', settingKey: 'CLOUDRU_FOUNDATION_MODELS_API_KEY', label: 'API Key', placeholder: 'Cloud.ru Foundation Models API key' },
{ id: 's-cloudru-base-url', label: 'Base URL', placeholder: 'https://foundation-models.api.cloud.ru/v1' },
],
testProvider: 'cloudru',
testInputs: {
's-cloudru-key': 'CLOUDRU_FOUNDATION_MODELS_API_KEY',
's-cloudru-base-url': 'CLOUDRU_FOUNDATION_MODELS_BASE_URL',
},
},
{
id: 'minimax', title: 'MiniMax', icon: '', hint: 'Direct regional OpenAI-compatible runtime', advanced: true,
fields: [
{ id: 's-minimax-key', settingKey: 'MINIMAX_API_KEY', label: 'API Key', placeholder: 'MiniMax API key' },
{ id: 's-minimax-region', label: 'Region', placeholder: 'global_en or cn_zh' },
],
testProvider: 'minimax',
testInputs: { 's-minimax-key': 'MINIMAX_API_KEY', 's-minimax-region': 'MINIMAX_REGION' },
note: 'Pick MiniMax as the source in Models or Agents, then choose MiniMax-M3 or MiniMax-M2.7. Leave Region empty for global_en; use cn_zh for the China endpoint.',
},
{
id: 'deepseek', title: 'DeepSeek', icon: '', hint: 'Direct OpenAI-compatible runtime (v4 family)', advanced: true,
fields: [
{ id: 's-deepseek-key', settingKey: 'DEEPSEEK_API_KEY', label: 'API Key', placeholder: 'sk-...' },
],
testProvider: 'deepseek',
testInputs: { 's-deepseek-key': 'DEEPSEEK_API_KEY' },
note: 'Pick DeepSeek as the source in Models or Agents, then choose deepseek-v4-pro or deepseek-v4-flash.',
},
{
id: 'gigachat', title: 'GigaChat', icon: '/static/providers/gigachat.svg', hint: 'Sber GigaChat via the gigachat library', advanced: true,
fields: [
{ id: 's-gigachat-credentials', settingKey: 'GIGACHAT_CREDENTIALS', label: 'Authorization Key', placeholder: 'Base64 client_id:secret (OAuth)' },
{ id: 's-gigachat-scope', label: 'Scope', placeholder: 'GIGACHAT_API_PERS' },
{ id: 's-gigachat-user', label: 'User (basic auth, optional)', placeholder: 'username' },
{ id: 's-gigachat-password', settingKey: 'GIGACHAT_PASSWORD', label: 'Password (basic auth, optional)', placeholder: 'password' },
{ id: 's-gigachat-base-url', label: 'Base URL', placeholder: 'https://api.giga.chat/v1' },
{ id: 's-gigachat-verify-ssl', label: 'Verify SSL Certs', placeholder: 'true / false' },
],
testProvider: 'gigachat',
testInputs: {
's-gigachat-credentials': 'GIGACHAT_CREDENTIALS',
's-gigachat-scope': 'GIGACHAT_SCOPE',
's-gigachat-user': 'GIGACHAT_USER',
's-gigachat-password': 'GIGACHAT_PASSWORD',
's-gigachat-base-url': 'GIGACHAT_BASE_URL',
's-gigachat-verify-ssl': 'GIGACHAT_VERIFY_SSL_CERTS',
},
note: 'Pick GigaChat as the source in Models or Agents to route a role through this account. Authenticate with either an Authorization Key (OAuth, scope GIGACHAT_API_PERS, GIGACHAT_API_B2B, or GIGACHAT_API_CORP) or User + Password.',
},
{
id: 'anthropic', title: 'Anthropic', icon: '/static/providers/anthropic.png', hint: 'Direct Anthropic API access',
fields: [{ id: 's-anthropic', settingKey: 'ANTHROPIC_API_KEY', label: 'Anthropic API Key', placeholder: 'sk-ant-...' }],
testProvider: 'anthropic', testInputs: { 's-anthropic': 'ANTHROPIC_API_KEY' },
note: 'Pick Anthropic as the source in Models or Agents to route a role directly through this key.',
},
];
// {backend provider id: {DOM input id: settings key}} — settings.js reads the
// live input values through this map to build the unsaved-credential overrides.
export const PROVIDER_TEST_INPUTS = Object.fromEntries(
PROVIDER_CARDS.filter((card) => card.testProvider).map((card) => [card.testProvider, card.testInputs]),
);
function providerSettingsCard(spec) {
const fields = (spec.fields || [])
.map((field) => {
const named = { ...field, label: field.label === "API Key" || field.label === "Base URL"
? `${spec.title} ${field.label}` : field.label };
return field.settingKey ? secretField(named) : plainField(named);
})
.join('');
const test = spec.testProvider ? `
SLACK_WEBHOOK_URL.
OpenAI Compatible card instead.127.0.0.1 for this machine only. Use 0.0.0.0 for LAN/Docker access with a Network Password in the same save. Specific LAN IP binds are manual/env-only.web_search. Requires OPENAI_API_KEY and an empty Legacy Base URL.Advisory keeps review visible but non-blocking. Blocking stops commits and reviewed-skill activation when critical findings remain unresolved.∞ removes the count cap, while deadlines, budgets and lifecycle limits still apply.Max inlines ARCHITECTURE and DEVELOPMENT in full — for ~1M-context models (today's behavior).
Nano is the compact owner window. Low fits ~200K / local models: ARCHITECTURE becomes a navigation map (read full sections on demand), DEVELOPMENT stays full for normal runnable tasks unless a structured non-development caller opts out, and memory compacts sooner. It governs Ouroboros's own working window: it never changes the model or reasoning effort, and scope review runs in every mode.
1h keeps the large stable prefix cached across long waits and review cycles — cache writes bill at 2× base input instead of 1.25×, but one wait longer than 5 minutes already pays that back on big contexts.
5m is the provider default tier as an explicit value; Default sends bare markers (provider default, callers may still declare their own TTL).
One honest global: it applies to every lane, including review and safety prompts.
Full — every guarded tool call gets the LLM safety check.
Light keeps the LLM check only for integration-policy tools; conditional shell/verify fall to the deterministic guards. Light is the default for new DESKTOP setups (authored by the first-run wizard); existing installs, web and Docker keep Full.
Off makes no LLM safety calls. In every mode the deterministic registry sandbox, protected-path policy, and light-mode guards STAY ON — the LLM supervisor is a layer, not the floor. Lowering coverage emits a durable audit event per waved-through call.
ouroboros.
Stable follows released code on main (default),
QA follows ouroboros-stable, and
Development follows ouroboros.
Light blocks repo self-modification but allows reviewed + enabled skills to run.
Advanced is the default — self-modify the evolutionary layer; protected core/contract/release files stay guarded by the shared runtime-mode policy.
Pro can edit protected core/contract/release surfaces, but commits still go through the normal triad + scope review gate; Advanced remains limited to the evolutionary layer.
Cyber Pro grants the full host and configuration authority, including credentials, models, Supervisor configuration and protected rewrites. Review scope and enforcement stay owner-controlled. Review Enforcement remains independent, so Blocking stays available in Cyber Pro.
Every N=1 means Ouroboros considers self-improvement after every task, then runs the actual cycle later on an idle supervisor tick.0 = rely on the normal gates. Running cycles still inherit the global per-task hard cost cap and the supervisor's reserved-budget floor.0 = consciousness may not spend.0 = it never starts tasks.data/skills/{native,clawhub,external}/ tree.
Ouroboros scans this for additional skill packages without
cloning or pulling them. Leave empty to use only the data plane.
~-prefixed path. Ouroboros never clones/pulls this directory — you manage it yourself.clawhub.ai or localhost.System follows this device's OS appearance and is the default for a new client.
Light and Dark pin the palette regardless of the OS.
mcp_<server>__<tool> tools after refresh. Changes are hot-reloadable.
Treat server descriptions and results as untrusted third-party data.
unlimited for none (the fresh-install default). Budget limits control runtime cost thresholds. How many subagents a task may run, and how deep they may nest, live in Agents.Agents.
A self-creating AI agent. Not a tool, but a becoming digital personality with its own constitution, persistent identity, and background consciousness. Born February 16, 2026.