Run models in the CMF (.cmf) format locally, via the native `cortiq` CLI from crates.io — no Python and no external model server. - cmf_runtime: install/update `cortiq-cli` from crates.io, spawn and health-check `cortiq serve` as a managed local backend. - import: model-import jobs shell out to the native `cortiq convert` (HF repo -> .cmf, quant mapped Q8_2F->q8_2f / Q8_ROW->q8 / Q4->q4); the Python converter is used only for advanced/exotic options. - pipeline: local-first routing — serve from the local CMF model when the router is disabled/unreachable, with a "local only" hard switch. - registry/state: register the local CMF server as an OpenAI provider and track local candidates. - config: data-dir resolution + CmfCfg (auto-install/update, managed server, host/port/model) and relaxed validation for the managed model. - admin + settings UI (en/ru): "Local models (CMF)" settings card.
343 lines
14 KiB
JavaScript
Vendored
343 lines
14 KiB
JavaScript
Vendored
// English — source of truth. Other languages override per key; missing keys fall
|
||
// back to English. Keep keys identical across all language files.
|
||
export default {
|
||
// brand / common
|
||
"brand.sub": "Gateway",
|
||
"common.loading": "Loading…",
|
||
"common.save": "Save",
|
||
"common.saving": "Saving…",
|
||
"common.cancel": "Cancel",
|
||
"common.add": "Add",
|
||
"common.edit": "Edit",
|
||
"common.delete": "Delete",
|
||
"common.close": "Close",
|
||
"common.test": "Test",
|
||
"common.copy": "Copy",
|
||
"common.copied": "Copied",
|
||
"common.confirm": "Confirm",
|
||
"common.none": "none",
|
||
"common.saved": "Saved",
|
||
"common.error": "Error",
|
||
"common.ok": "OK",
|
||
"common.refresh": "Refresh",
|
||
"common.actions": "Actions",
|
||
"common.optional": "optional",
|
||
"common.search": "Search",
|
||
"common.all": "all",
|
||
|
||
// nav
|
||
"nav.dashboard": "Dashboard",
|
||
"nav.models": "Models",
|
||
"nav.import": "Import model",
|
||
"nav.routing": "Routing",
|
||
"nav.protocols": "Protocols",
|
||
"nav.keys": "API keys",
|
||
"nav.playground": "Playground",
|
||
"nav.settings": "Settings",
|
||
"nav.foot": "Gateway · v{v}",
|
||
"nav.billing": "Router key & billing",
|
||
|
||
// topbar / status
|
||
"status.router": "Router",
|
||
"status.gateway": "Gateway",
|
||
"status.online": "online",
|
||
"status.offline": "offline",
|
||
"status.checking": "checking…",
|
||
"status.noKey": "no key",
|
||
"theme.toggle": "Theme",
|
||
"logout": "Log out",
|
||
|
||
// login
|
||
"login.title": "allaigate Gateway",
|
||
"login.subtitle": "Enter the admin token to manage this gateway.",
|
||
"login.token": "Admin token",
|
||
"login.tokenPlaceholder": "paste admin token",
|
||
"login.submit": "Open console",
|
||
"login.hint": "The token is printed in the gateway log on startup, or set via [admin].token_env.",
|
||
"login.failed": "Invalid admin token.",
|
||
|
||
// dashboard
|
||
"dash.title": "Dashboard",
|
||
"dash.subtitle": "Live traffic, cost and routing analytics for your model pool.",
|
||
"dash.range": "Range",
|
||
"dash.range.1h": "1h",
|
||
"dash.range.24h": "24h",
|
||
"dash.range.7d": "7d",
|
||
"dash.kpi.requests": "Requests",
|
||
"dash.kpi.tokens": "Tokens",
|
||
"dash.kpi.cost": "Cost",
|
||
"dash.kpi.latency": "Avg latency",
|
||
"dash.kpi.success": "Success rate",
|
||
"dash.kpi.failovers": "Failovers",
|
||
"dash.series.title": "Requests over time",
|
||
"dash.series.cost": "Cost over time",
|
||
"dash.series.empty": "No traffic yet in this range.",
|
||
"dash.breakdown.title": "Breakdown",
|
||
"dash.groupby.model": "by model",
|
||
"dash.groupby.tier": "by tier",
|
||
"dash.groupby.label": "by task",
|
||
"dash.groupby.account": "by account",
|
||
"dash.recent.title": "Recent requests",
|
||
"dash.recent.empty": "No requests recorded yet. Try the Playground.",
|
||
"dash.col.time": "Time",
|
||
"dash.col.model": "Model",
|
||
"dash.col.tier": "Tier",
|
||
"dash.col.task": "Task",
|
||
"dash.col.tokens": "Tokens",
|
||
"dash.col.cost": "Cost",
|
||
"dash.col.latency": "Latency",
|
||
"dash.col.outcome": "Outcome",
|
||
"dash.col.requests": "Requests",
|
||
"dash.col.errors": "Errors",
|
||
"dash.health.title": "Health",
|
||
"dash.health.reachable": "reachable",
|
||
"dash.health.unreachable": "unreachable",
|
||
"dash.health.getKey": "Get a router key",
|
||
|
||
// models
|
||
"models.title": "Models",
|
||
"models.subtitle": "Your model pool — mix cheap local models with cloud APIs.",
|
||
"models.add": "Add model",
|
||
"models.empty": "No models yet. Add your first model to get started.",
|
||
"models.col.id": "ID",
|
||
"models.col.provider": "Provider",
|
||
"models.col.model": "Model",
|
||
"models.col.tier": "Cost tier",
|
||
"models.col.key": "Key",
|
||
"models.col.caps": "Capabilities",
|
||
"models.col.price": "Price (in/out)",
|
||
"models.probe": "Probe",
|
||
"models.probe.ok": "Reachable ({ms} ms)",
|
||
"models.probe.fail": "Failed: {err}",
|
||
"models.form.addTitle": "Add model",
|
||
"models.form.editTitle": "Edit model",
|
||
"models.form.id": "ID",
|
||
"models.form.idHint": "Unique id used in routing, e.g. local-qwen",
|
||
"models.form.provider": "Provider",
|
||
"models.form.baseUrl": "Base URL",
|
||
"models.form.model": "Model name",
|
||
"models.form.kind": "Kind",
|
||
"models.form.costTier": "Cost tier",
|
||
"models.form.priceIn": "Price in ($/1M)",
|
||
"models.form.priceOut": "Price out ($/1M)",
|
||
"models.form.apiKeyEnv": "API key env name",
|
||
"models.form.apiKeyEnvHint": "Name of the env var / stored secret holding this provider's key.",
|
||
"models.form.caps": "Capabilities",
|
||
"models.form.secret": "Secret value",
|
||
"models.form.secretStored": "stored",
|
||
"models.form.secretEnv": "from env",
|
||
"models.form.secretMissing": "not set",
|
||
"models.form.secretPlaceholder": "set or replace key (write-only)",
|
||
"models.deleteConfirm": "Delete model \"{id}\"?",
|
||
|
||
// routing
|
||
"routing.title": "Routing",
|
||
"routing.subtitle": "Map complexity tiers to an ordered list of models (priority = fallback).",
|
||
"routing.default": "Default model",
|
||
"routing.defaultHint": "Used when the router is unreachable.",
|
||
"routing.tiers": "Tiers",
|
||
"routing.tierHint": "Drag chips to reorder; first is preferred, the rest are fallbacks.",
|
||
"routing.addModel": "+ add",
|
||
"routing.addTier": "Add tier",
|
||
"routing.tierName": "Tier name",
|
||
"routing.policy": "Policy",
|
||
"routing.policy.mode": "Mode",
|
||
"routing.policy.fixed": "Fixed table",
|
||
"routing.policy.costAware": "Cost-aware",
|
||
"routing.policy.maxCost": "Max cost per request ($)",
|
||
"routing.policy.minClass": "Minimum class per tier",
|
||
"routing.empty": "No models available — add models first.",
|
||
|
||
// protocols
|
||
"protocols.title": "Protocols",
|
||
"protocols.subtitle": "Enable only the inbound API surfaces you need. Toggles apply live.",
|
||
"protocols.implemented": "implemented",
|
||
"protocols.planned": "planned",
|
||
"protocols.openai_chat": "OpenAI Chat Completions",
|
||
"protocols.openai_chat.d": "POST /v1/chat/completions — works with OpenAI SDK, LangChain, crewAI.",
|
||
"protocols.openai_completions": "OpenAI Completions (legacy)",
|
||
"protocols.openai_completions.d": "POST /v1/completions — legacy integrations.",
|
||
"protocols.openai_embeddings": "OpenAI Embeddings",
|
||
"protocols.openai_embeddings.d": "POST /v1/embeddings — RAG pipelines.",
|
||
"protocols.openai_models": "OpenAI Models",
|
||
"protocols.openai_models.d": "GET /v1/models — client auto-discovery.",
|
||
"protocols.anthropic_messages": "Anthropic Messages",
|
||
"protocols.anthropic_messages.d": "POST /v1/messages — Claude-native agents.",
|
||
"protocols.mcp": "MCP (Model Context Protocol)",
|
||
"protocols.mcp.d": "JSON-RPC / SSE — MCP-native orchestrators.",
|
||
"protocols.native_passthrough": "Native passthrough",
|
||
"protocols.native_passthrough.d": "POST /route — direct access to the routing decision.",
|
||
|
||
// keys
|
||
"keys.title": "API keys",
|
||
"keys.subtitle": "Virtual gateway keys for your agents. Provider keys never leave the gateway.",
|
||
"keys.add": "New key",
|
||
"keys.empty": "No keys configured — the gateway is in open mode (no auth).",
|
||
"keys.openMode": "Open mode: any request is accepted (no key required).",
|
||
"keys.col.key": "Key",
|
||
"keys.col.account": "Account",
|
||
"keys.col.rate": "Rate / min",
|
||
"keys.col.models": "Allowed models",
|
||
"keys.form.title": "New API key",
|
||
"keys.form.account": "Account",
|
||
"keys.form.rate": "Rate limit / min",
|
||
"keys.form.allow": "Allowed models",
|
||
"keys.form.allowHint": "Leave empty to allow all models.",
|
||
"keys.form.custom": "Custom key (optional)",
|
||
"keys.form.customHint": "Leave empty to auto-generate sk-gw-…",
|
||
"keys.created": "Key created — copy it now, it won't be shown again:",
|
||
"keys.revoke": "Revoke",
|
||
"keys.revokeConfirm": "Revoke this key?",
|
||
"keys.allowAll": "all",
|
||
|
||
// playground
|
||
"pg.title": "Playground",
|
||
"pg.subtitle": "Send a prompt through the live pipeline and inspect the routing decision.",
|
||
"pg.system": "System prompt",
|
||
"pg.systemPlaceholder": "optional system message",
|
||
"pg.prompt": "Prompt",
|
||
"pg.promptPlaceholder": "Ask something…",
|
||
"pg.mode": "Mode",
|
||
"pg.mode.auto": "Auto (route)",
|
||
"pg.mode.pinned": "Pinned model",
|
||
"pg.profile": "Profile",
|
||
"pg.model": "Model",
|
||
"pg.temp": "Temperature",
|
||
"pg.maxTokens": "Max tokens",
|
||
"pg.send": "Send",
|
||
"pg.stream": "Stream",
|
||
"pg.sending": "Sending…",
|
||
"pg.answer": "Answer",
|
||
"pg.empty": "The answer and routing decision will appear here.",
|
||
"pg.decision": "Routing decision",
|
||
"pg.task": "Task",
|
||
"pg.tier": "Tier",
|
||
"pg.score": "Complexity",
|
||
"pg.selected": "Selected model",
|
||
"pg.source": "Route source",
|
||
"pg.cost": "Cost",
|
||
"pg.latency": "Latency",
|
||
"pg.tokens": "Tokens (in/out)",
|
||
"pg.failover": "Failover",
|
||
"pg.error": "Request failed",
|
||
|
||
// settings
|
||
"settings.title": "Settings",
|
||
"settings.subtitle": "Gateway connection, routing input, reliability and observability.",
|
||
"settings.router": "Router connection",
|
||
"settings.router.url": "Router URL",
|
||
"settings.router.keyEnv": "Router key env name",
|
||
"settings.router.timeout": "Timeout (ms)",
|
||
"settings.router.verifyTls": "Verify TLS certificate",
|
||
"settings.router.enabled": "Use the router (off = local models only)",
|
||
"settings.cmf": "Local models (CMF)",
|
||
"settings.cmf.localOnly": "Use only local models",
|
||
"settings.cmf.manage": "Run a local model server",
|
||
"settings.cmf.autoInstall": "Auto-install cortiq (crates.io)",
|
||
"settings.cmf.autoUpdate": "Auto-update cortiq",
|
||
"settings.cmf.model": "Local .cmf model path",
|
||
"settings.cmf.port": "Local server port",
|
||
"settings.cmf.modelId": "Model id in the pool",
|
||
"settings.cmf.note": "Serves a local .cmf via cortiq (github.com/infosave2007/cmf). Works even when the router is unavailable.",
|
||
"settings.router.taxonomy": "Taxonomy id",
|
||
"settings.router.getKey": "Get or top up a router key at",
|
||
"settings.router.secret": "Router key (value)",
|
||
"settings.router.saveKey": "Save key",
|
||
"settings.router.keySaved": "Router key saved",
|
||
"settings.router.keyEmpty": "Paste the key first",
|
||
"settings.router.secretHelp": "Paste the key from your api.allaigate.com email, then Save key. This is NOT a “Keys” value — those are for clients calling your gateway.",
|
||
"settings.router.keyStoredMask": "•••••••••••• — key saved (paste again to replace)",
|
||
"settings.router.test": "Test router",
|
||
"router.probe.ok": "Router OK ({ms} ms)",
|
||
"router.probe.noKey": "Router key is not set",
|
||
"router.probe.auth": "Key rejected — invalid or revoked",
|
||
"router.probe.payment": "Payment required — plan expired or quota exhausted",
|
||
"router.probe.quota": "Rate limit exceeded",
|
||
"router.probe.timeout": "Router timed out",
|
||
"router.probe.unreachable": "Router unreachable",
|
||
"router.probe.error": "Router error",
|
||
"router.usage": "Usage",
|
||
"settings.route": "Routing input",
|
||
"settings.route.strategy": "Text strategy",
|
||
"settings.route.maxChars": "Max chars",
|
||
"settings.route.cacheTtl": "Cache TTL",
|
||
"settings.route.profile": "Default profile",
|
||
"settings.breaker": "Circuit breaker",
|
||
"settings.breaker.threshold": "Error threshold",
|
||
"settings.breaker.cooldown": "Cooldown",
|
||
"settings.log": "Logging",
|
||
"settings.log.level": "Log level",
|
||
"settings.log.bodies": "Log message bodies (privacy off)",
|
||
"settings.telemetry": "Telemetry",
|
||
"settings.telemetry.metrics": "Expose Prometheus /metrics",
|
||
"settings.cortiq": "Response metadata",
|
||
"settings.cortiq.echo": "Echo cortiq routing block in responses",
|
||
"settings.stats": "Statistics",
|
||
"settings.stats.enabled": "Record request statistics",
|
||
"settings.stats.file": "Stats file (JSONL)",
|
||
"settings.stats.retention": "Retention",
|
||
"settings.listen": "Listen address",
|
||
"settings.export": "Export config",
|
||
"settings.import": "Import config",
|
||
"settings.needsRestart": "Saved. Some changes (listen address) require a restart.",
|
||
|
||
// toasts / misc
|
||
"toast.saved": "Changes saved",
|
||
"toast.deleted": "Deleted",
|
||
"toast.probing": "Probing…",
|
||
"toast.imported": "Config imported",
|
||
"dash.cache": "Semantic cache",
|
||
"dash.cache.hitRate": "Hit rate",
|
||
"dash.cache.hits": "Hits",
|
||
"dash.cache.saved": "Saved",
|
||
"dash.cache.disabled": "Semantic cache is disabled — enable it in Settings.",
|
||
"settings.cache": "Semantic cache",
|
||
"settings.cache.enabled": "Enable semantic cache",
|
||
"settings.cache.threshold": "Similarity threshold",
|
||
"settings.cache.ttl": "Entry TTL",
|
||
"settings.cache.embed": "Embedding model",
|
||
"settings.cache.note": "Cache settings take effect after a restart.",
|
||
|
||
// import (HuggingFace → CMF)
|
||
"import.subtitle": "Search HuggingFace, convert to a local .cmf, and serve it.",
|
||
"import.searchPlaceholder": "Search HuggingFace models (e.g. qwen3, llama)…",
|
||
"import.searching": "Searching…",
|
||
"import.noResults": "No models found.",
|
||
"import.configure": "Configure conversion",
|
||
"import.outName": "Output name",
|
||
"import.outNameHint": "The .cmf file name (letters, digits, - and _).",
|
||
"import.quant": "Quantization",
|
||
"import.convert": "Convert & load",
|
||
"import.converting": "Converting",
|
||
"import.started": "Conversion started",
|
||
"import.failed": "Conversion failed — see the log.",
|
||
"import.register": "Register as local model",
|
||
"import.registered": "Registered as '{id}'. Run cortiq-server to serve it.",
|
||
"import.jobs": "Conversions",
|
||
"import.cancel": "Cancel",
|
||
"import.cancelling": "Cancelling — cleaning up partial output…",
|
||
"import.delete": "Delete",
|
||
"import.deleteConfirm": "Delete this model and its converted .cmf file from disk?",
|
||
"import.deleted": "Deleted with its files",
|
||
"import.state.running": "running",
|
||
"import.state.done": "done",
|
||
"import.state.error": "error",
|
||
"import.state.cancelled": "cancelled",
|
||
"import.q.q8_2f": "8-bit two-field (𝒲×θ) — recommended: best quality/size.",
|
||
"import.q.q8_row": "8-bit per-row — simple, robust.",
|
||
"import.q.q4": "4-bit block — smallest, lower quality.",
|
||
"import.q.vbit": "Variable 3–8 bit — per-expert bit budgets.",
|
||
"import.q.f16": "16-bit — no quantization.",
|
||
"import.q.f32": "32-bit — full precision (large file).",
|
||
"import.adv.title": "Advanced settings",
|
||
"import.adv.auto": "auto",
|
||
"import.adv.linearCore": "Linear core",
|
||
"import.adv.linearHint": "How linear-attention layers are carried/folded.",
|
||
"import.adv.nphase": "vmf_phase phases/head",
|
||
"import.adv.vbitShape": "VBIT budget shape",
|
||
"import.adv.meanBits": "VBIT mean bits",
|
||
"import.adv.shard": "Shard max (GB)",
|
||
"import.adv.noShard": "no sharding",
|
||
"import.adv.skipMtp": "skip MTP head",
|
||
};
|