feat(i18n): add Russian (ru) language — full parity across backend, web & desktop (#1391)

* docs(i18n): design spec for Russian (ru) language support

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* feat(i18n): register ru locale constant and IsSupported

* feat(i18n): scaffold ru catalog (en placeholders)

* feat(i18n): translate ru backend catalog to Russian

* fix(i18n): polish ru catalog grammar per review

* feat(i18n): wire ru into system messages, config enum, parity test

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* feat(i18n): add ru to web language constants and system-message locales

* feat(i18n): scaffold ru web locale dir (en placeholders)

* feat(i18n): wire ru resources into web i18next config

* feat(i18n): translate ru web locale to Russian (41 namespaces)

* fix(i18n): normalize ru web terminology (арендатор, привязка)

* fix(i18n): restore dropped 'named' in ru setup OAuth hint

* feat(i18n): wire ru into desktop i18next and language pickers

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* feat(i18n): add ru desktop locale (Russian, 16 namespaces)

* test(i18n): extend traces/hooks locale guards to cover ru

* chore(deploy): add repeatable fork-dev local build+deploy tooling

Adds a one-command, idempotent way to run goclaw from a locally built
image that merges fresh upstream dev with un-merged fork features
(Telegram trigger-words PR #1383 + Russian locale), independent of the
published :latest image.

- scripts/deploy-forkdev.sh: fetch origin/dev -> merge feature branches
  into local/fork-dev worktree -> push fork/dev -> build -> up -d.
- docker-compose.forkdev.yml: overlay pinning image to goclaw:forkdev
  with pull_policy:never so :latest never silently replaces the build.
- .gitignore: track the deploy helper (past deploy-*.sh), ignore the
  ../.goclaw-forkdev integration worktree.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* feat(telegram): agent-callable message reaction (message action=react)

Adds a "react" action to the message tool so an agent can set an emoji
reaction on an existing message (e.g. mark its own status post 👍 once
fully paid). Mirrors the ChannelEditor wiring: ReactionSetter capability
-> Manager.ReactToMessage -> telegram Channel.ReactToMessage (validates
against Telegram's supported reaction set; ✅/❌ are rejected).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(config): remove ignored session scoping controls (#1405)

Co-authored-by: Collective Developer <man@collective.dev>

* feat(telegram): agent-callable message reaction (message action=react) (#1407)

Adds a "react" action to the message tool so an agent can set an emoji
reaction on an existing message (e.g. mark its own status post 👍 once
fully paid). Mirrors the ChannelEditor wiring: ReactionSetter capability
-> Manager.ReactToMessage -> telegram Channel.ReactToMessage (validates
against Telegram's supported reaction set; ✅/❌ are rejected).

Co-authored-by: skensel <skensel@MacBook-Pro-skensel.local>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* ci: build & publish fork image to GHCR (temporary, pre-upstream)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(memory): use 'russian' FTS config for memory_chunks recall

Memory keyword search (memory_search.go FTS + the generated tsv column)
used the 'simple' text-search config, which does no stemming. Russian
grammatical cases therefore never matched: a genitive query token
("Дианы") could not hit the stored nominative token ("Диана"), so
memory_search returned nothing for natural queries even though the fact
was saved. This is the sole recall path on deployments without an
embedding provider (ChatGPT-OAuth/codex cannot embed), so recall was
effectively dead there.

Switch both sides to the Snowball 'russian' config so index and query
lexemes stem to the same root ("диан"), restoring case-insensitive
recall. Migration 000094 recreates the generated tsv column (a GENERATED
expression cannot be ALTERed in place; ADD COLUMN backfills all rows).

Surface parity: desktop/SQLite N/A — SQLite memory search uses LIKE, a
separate mechanism unaffected by the PG regconfig.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: skensel <skensel@MacBook-Pro-skensel.local>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: ナム <namnhfreelancer@gmail.com>
Co-authored-by: Collective Developer <man@collective.dev>
This commit is contained in:
authored and GitHub committed 2026-07-11 12:25:38 +07:00
1 parent 2a6872ac84
commit 61993b4387
85 files changed
+10476 -17

No files matched your search

+53
View File
@@ -0,0 +1,53 @@
# Fork image build — publishes a ready-to-run image to the fork's GHCR so a VPS
# can `docker pull` it without building from source. Temporary: while the fork's
# features (ru locale, telegram reactions) are not yet in an upstream release.
# Once they land upstream, switch the VPS to ghcr.io/nextlevelbuilder/goclaw and
# delete this workflow.
name: fork image
on:
push:
branches: [dev]
workflow_dispatch:
permissions:
contents: read
packages: write
concurrency:
group: fork-image-${{ github.ref }}
cancel-in-progress: true
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: docker/setup-buildx-action@v3
- name: Log in to GHCR
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push
uses: docker/build-push-action@v6
with:
context: .
file: ./Dockerfile
platforms: linux/amd64
push: true
tags: |
ghcr.io/${{ github.repository }}:latest
ghcr.io/${{ github.repository }}:dev-${{ github.sha }}
build-args: |
ENABLE_EMBEDUI=true
ENABLE_PYTHON=true
ENABLE_OTEL=false
ENABLE_FULL_SKILLS=false
VERSION=fork-dev
cache-from: type=gha
cache-to: type=gha,mode=max
+5
View File
@@ -64,6 +64,11 @@ tmp
.claude/
deploy-*.sh
# ...but the fork-dev deploy helper IS tracked tooling.
!scripts/deploy-forkdev.sh
# fork-dev integration worktree (created by scripts/deploy-forkdev.sh)
.goclaw-forkdev/
docs/technical-diaries
docs/zuey
+23
View File
@@ -0,0 +1,23 @@
# Local-build overlay for the "fork-dev" integration branch.
#
# Purpose: run goclaw from a LOCALLY BUILT image that merges upstream dev with
# un-merged fork features (Telegram trigger-words + Russian locale), instead of
# pulling the published ghcr.io/...:latest (which lacks those features).
#
# It swaps the service image to a distinct local tag `goclaw:forkdev` and forbids
# pulling, so `:latest` stays untouched and the running bot is unambiguously the
# local build. The build context comes from GOCLAW_DIR (set by deploy-forkdev.sh
# to the integration worktree); the base compose already defines build.args.
#
# Usage (via the helper — handles fetch + merge + build + up):
# scripts/deploy-forkdev.sh
#
# Or manually against an already-prepared worktree at $GOCLAW_DIR:
# GOCLAW_DIR=../.goclaw-forkdev \
# docker compose -f docker-compose.yml -f docker-compose.postgres.yml \
# -f docker-compose.forkdev.yml up -d --build
services:
goclaw:
image: goclaw:forkdev
pull_policy: never
@@ -0,0 +1,101 @@
# Design: Russian language (`ru`) support for GoClaw
**Date:** 2026-07-08
**Branch:** `feature/ru-lang`
**Status:** Approved
## Goal
Add Russian (`ru`) as a fully supported UI/message language across all three product
surfaces (backend i18n catalog, Web UI, Desktop UI), at **full parity with English** —
not the partial coverage the Korean (`ko`) locale currently ships.
## Reference precedent
`ko` (Korean) was the most recently added language. It is the integration template for
`ru` on the **backend** and **Web UI**. The **Desktop UI** has no `ko` at all, so `ru`
there is net-new work patterned on the existing `zh` wiring.
**Key deviation from `ko`:** `ko` is intentionally partial (backend catalog = 131 of 281
keys; Web UI = 38 of 41 namespaces, omitting `hooks`/`webhooks`/`workstations`). Because
the user chose **full parity with English**, `ru` covers **all 281 backend keys** and
**all 41 Web namespaces**.
## Scope by surface
### 1. Backend (Go) — full catalog (~281 keys)
| File | Change |
|------|--------|
| `internal/i18n/i18n.go` | Add `LocaleRU = "ru"` const; add `LocaleRU` to `IsSupported()` switch. `Normalize()` handles `ru`/`ru-RU` prefix automatically once `IsSupported` knows it. |
| `internal/i18n/catalog_ru.go` (new) | `func init() { register(LocaleRU, map[string]string{...}) }` — **all 281 keys** from `catalog_en.go`. |
| `internal/systemmessages/resolver.go` | Add `i18n.LocaleRU:` entry in each of the **10 maps** (5 messages × Labels + Descriptions), lines ~51,57,73,79,95,101,118,124,136,142. |
| `internal/gateway/methods/config.go:366` | Add `"ru"` to the `default_locale` enum `[]string{"en","vi","zh","ko"}`. |
| `internal/i18n/git_keys_parity_test.go:34` | **Add** `LocaleRU` to the locale list. Correct for a full catalog (ko is excluded only because it is partial). |
| `internal/config/config.go:128` | Update doc-comment to mention `ru` (informational, no logic). |
Ingest paths need **no per-locale edit** (verified): `internal/gateway/router.go`,
`internal/http/auth.go` `extractLocale`, `internal/store/context.go` `WithLocale` — all
run the locale through `i18n.Normalize()` and work for `ru` automatically.
### 2. Web UI — full 41 namespaces
| File | Change |
|------|--------|
| `ui/web/src/i18n/locales/ru/` (new dir) | **41 JSON files** matching `locales/en/` (includes `hooks.json`, `webhooks.json`, `workstations.json` — which `ko` omits). |
| `ui/web/src/i18n/index.ts` | Add `ru` import block (41 imports), `ru: {...}` resources object (41 namespaces), `stored === "ru"` in `getInitialLanguage()`, and `lang.startsWith("ru") → "ru"` browser detection. |
| `ui/web/src/lib/constants.ts` | Add `"ru"` to `SUPPORTED_LANGUAGES`; add `ru: "Русский"` to `LANGUAGE_LABELS`. |
| `ui/web/src/pages/config/sections/system-messages-section-utils.ts:21` | Add `{ code: "ru", labelKey: "systemMessages.locale.ru" }` to `SYSTEM_MESSAGE_LOCALES`. |
| `ui/web/src/pages/config/sections/system-messages-section-utils.test.ts:49` | Update expected array to include `"ru"`. |
| `ui/web/src/i18n/locales/{en,vi,zh,ru}/config.json` | Add `systemMessages.locale.ru` string key. |
Consumers auto-covered (no edit): `topbar.tsx`, `setup-page.tsx` `LanguageSelector`,
`use-ui-store.ts` — all map over `SUPPORTED_LANGUAGES`/`LANGUAGE_LABELS`.
### 3. Desktop UI — net-new (16 namespaces, patterned on `zh`)
| File | Change |
|------|--------|
| `ui/desktop/frontend/src/i18n/locales/ru/` (new dir) | **16 JSON files** matching `locales/zh/`. |
| `ui/desktop/frontend/src/i18n/index.ts` | Add `ru` import block (16 imports), `ru: {...}` resources, `ru` handling in `getInitialLanguage()`. |
| `ui/desktop/frontend/src/lib/constants.ts` | Add `{ value: 'ru', label: 'RU', flag: '🇷🇺' }` to `LANGUAGES`. |
| `ui/desktop/frontend/src/components/settings/AppearanceTab.tsx` | Add `ru` to inline `LANGUAGES` array. |
| `ui/desktop/frontend/src/components/onboarding/OnboardingWizard.tsx` | Add `ru` to inline `LANGUAGES` array. |
`ChatTopBar.tsx` imports `LANGUAGES` from constants — auto-covered.
**No DB migration:** locale strings live in Go catalogs and JSON files, not in any
PostgreSQL/SQLite table. SQLite `schema.sql`/`schema.go` untouched.
## Translation strategy
- Translate **from the English source** (the parity reference), not from `ko`/`vi`/`zh`.
- Keep technical terms natural/idiomatic: agent→агент, token→токен, session→сессия,
team→команда, provider→провайдер, skill→навык (or keep "скилл" where UI-conventional).
- **Never touch** `%s` / `%d` (Go `fmt` verbs), `{{variable}}` (i18next interpolation),
JSON keys, HTML tags, or Markdown structure inside strings.
- Preserve pluralization keys (`_one`/`_other`) where i18next uses them.
## Ordering
1. **Plumbing first:** register `ru` everywhere (backend consts, index.ts, constants,
enums, selectors) — with English-copied strings as placeholders so it compiles/renders.
2. **Translation second:** replace placeholder strings namespace-by-namespace.
This keeps every intermediate commit buildable.
## Verification
- Backend: `go build ./...`, `go build -tags sqliteonly ./...`, `go vet ./...`,
`go test ./internal/i18n/ ./internal/systemmessages/`.
- Web: `cd ui/web && pnpm build`; key-parity check (every `en/*.json` key exists in
`ru/*.json`).
- Desktop: `cd ui/desktop/frontend && pnpm build`; same key-parity check against `zh`.
- Manual smoke: launch web UI, switch language to "Русский" in topbar, verify no raw keys
render on main screens.
## Out of scope
- Bootstrap templates (`SOUL.md`, `IDENTITY.md`) stay English (LLM consumption).
- Prose `_readmes/README.ru.md` already exists — unrelated to UI wiring.
- No new features; wiring + translation only.
+1 -1
View File
@@ -125,7 +125,7 @@ type SystemMsgConfig struct {
Messages map[string]LocalizedSystemMessage `json:"messages,omitempty"`
}
// LocalizedSystemMessage maps locale code ("en", "vi", "zh", "ko") to a
// LocalizedSystemMessage maps locale code ("en", "vi", "zh", "ko", "ru") to a
// template override for one system message key.
type LocalizedSystemMessage map[string]string
+1 -1
View File
@@ -363,7 +363,7 @@ func (m *ConfigMethods) handleSchema(_ context.Context, client *gateway.Client,
"properties": map[string]any{
"default_locale": map[string]any{
"type": "string",
"enum": []string{"en", "vi", "zh", "ko"},
"enum": []string{"en", "vi", "zh", "ko", "ru"},
"description": "Default locale used when a channel caller does not provide a locale",
},
"messages": map[string]any{
+372
View File
@@ -0,0 +1,372 @@
package i18n
func init() {
register(LocaleRU, map[string]string{
// Common validation
MsgRequired: "требуется %s",
MsgInvalidID: "неверный ID %s",
MsgNotFound: "%s не найдено: %s",
MsgAlreadyExists: "%s уже существует: %s",
MsgInvalidRequest: "неверный запрос: %s",
MsgInvalidJSON: "неверный JSON",
MsgUnauthorized: "не авторизовано",
MsgPermissionDenied: "доступ запрещён: %s",
MsgInternalError: "внутренняя ошибка: %s",
MsgInvalidSlug: "%s должно быть корректным слагом (только строчные буквы, цифры и дефисы)",
MsgFailedToList: "не удалось получить список %s",
MsgFailedToCreate: "не удалось создать %s: %s",
MsgFailedToUpdate: "не удалось обновить %s: %s",
MsgFailedToDelete: "не удалось удалить %s: %s",
MsgFailedToSave: "не удалось сохранить %s: %s",
MsgInvalidUpdates: "неверные обновления",
// Agent
MsgAgentNotFound: "агент не найден: %s",
MsgCannotDeleteDefault: "нельзя удалить агента по умолчанию",
MsgUserCtxRequired: "требуется контекст пользователя",
MsgGatewayOperatorSecureCLIUnavailable: "Доступ оператора шлюза пропущен, так как хранилище SecureCLI недоступно.",
MsgGatewayOperatorEligibilityFailed: "Агент создан, но доступ оператора шлюза не смог подтвердить право на статус первого агента.",
MsgGatewayOperatorNotFirstAgent: "Доступ оператора шлюза не предоставлен, так как это не первый агент.",
MsgGatewayOperatorTokenMissing: "Доступ оператора шлюза пропущен, так как токен шлюза не настроен.",
MsgGatewayOperatorBinaryMissing: "Доступ оператора шлюза пропущен, так как не удалось обнаружить исполняемый файл goclaw.",
MsgGatewayOperatorExistingReview: "Доступ оператора шлюза пропущен, так как существующие учётные данные goclaw CLI требуют ручной проверки.",
MsgGatewayOperatorRegisterFailed: "Доступ оператора шлюза пропущен, так как не удалось зарегистрировать учётные данные goclaw CLI.",
MsgGatewayOperatorCredentialFailed: "Доступ оператора шлюза пропущен, так как не удалось сохранить учётные данные.",
// Chat
MsgRateLimitExceeded: "превышен лимит запросов — пожалуйста, подождите",
MsgNoUserMessage: "сообщение пользователя не найдено",
MsgUserIDRequired: "требуется user_id",
MsgMsgRequired: "требуется сообщение",
// Abort
MsgAbortStopped: "выполнение остановлено",
MsgAbortForced: "выполнение принудительно прервано (превышен льготный период 3 с)",
MsgAbortAlreadyAborting: "прерывание уже выполняется",
MsgAbortNotFound: "выполнение не найдено или уже завершено",
MsgAbortUnauthorized: "нет прав на прерывание этого выполнения",
MsgAbortFailed: "не удалось прервать выполнение: %s",
// Channel instances
MsgInvalidChannelType: "неверный channel_type",
MsgInstanceNotFound: "экземпляр не найден",
// Cron
MsgJobNotFound: "задание не найдено",
MsgInvalidCronExpr: "неверное cron-выражение: %s",
MsgCommandCronDisabled: "команды cron отключены на этом шлюзе (установите cron.command_enabled=true, чтобы разрешить их)",
// Config
MsgConfigHashMismatch: "конфигурация изменилась (несоответствие хэша)",
// Exec approval
MsgExecApprovalDisabled: "подтверждение выполнения не включено",
// Pairing
MsgSenderChannelRequired: "требуются senderId и channel",
MsgCodeRequired: "требуется код",
MsgSenderIDRequired: "требуется sender_id",
// HTTP API
MsgInvalidAuth: "неверная аутентификация",
MsgMsgsRequired: "требуется messages",
MsgUserIDHeader: "требуется заголовок X-GoClaw-User-Id",
MsgFileTooLarge: "файл слишком большой или неверная multipart-форма",
MsgMissingFileField: "отсутствует поле 'file'",
MsgInvalidFilename: "неверное имя файла",
MsgChannelKeyReq: "требуются channel и key",
MsgMethodNotAllowed: "метод не разрешён",
MsgStreamingNotSupported: "потоковая передача не поддерживается",
MsgOwnerOnly: "только владелец может %s",
MsgNoAccess: "нет доступа к этому %s",
MsgAlreadySummoning: "агент уже вызывается",
MsgSummoningUnavailable: "вызов недоступен",
MsgRunTimelineUnavailable: "хронология выполнения недоступна",
MsgNoDescription: "у агента нет описания для повторного вызова",
MsgSummonCancelled: "вызов отменён пользователем",
MsgCannotCancel: "агент не вызывается",
MsgInvalidPath: "неверный путь",
// Browser cookies
MsgBrowserCookieTooMany: "слишком много cookie браузера в одном запросе синхронизации",
MsgInvalidCookieURL: "неверный URL cookie",
MsgBrowserCookieValueTooLarge: "значение cookie слишком велико",
MsgBrowserCookieEncryptionRequired: "шифрование cookie браузера не настроено",
// Tenant backup / restore
MsgRestoreNewModeRejectsTenantID: "mode=new создаёт нового арендатора; передайте tenant_slug (а не tenant_id) в качестве целевого слага нового арендатора",
// Scheduler
MsgQueueFull: "очередь сессий заполнена",
MsgShuttingDown: "шлюз завершает работу, пожалуйста, повторите попытку чуть позже",
// Provider
MsgProviderReqFailed: "%s: запрос не выполнен: %s",
// Usage caps / pricing
MsgUsageCapsListPoliciesFailed: "не удалось получить список политик лимитов использования",
MsgUsageCapPolicyValidationFailed: "не пройдена проверка политики лимитов использования",
MsgUsageCapPolicyManaged: "управляемые политики лимитов использования нельзя изменять",
MsgUsageCapsDeletePolicyFailed: "не удалось удалить политику лимитов использования",
MsgUsageCapsUtilizationFailed: "не удалось загрузить использование лимитов",
MsgUsageCapsEventsFailed: "не удалось загрузить события лимитов использования",
MsgUsagePricingSyncOpenRouterFailed: "не удалось синхронизировать цены OpenRouter: %s",
MsgUsagePricingStoreCatalogFailed: "не удалось сохранить каталог цен",
MsgUsagePricingListFailed: "не удалось получить список цен на модели",
MsgUsagePricingProviderModelRequired: "требуются provider_id и model_id",
MsgUsagePricingOverrideValidationFailed: "не пройдена проверка переопределения цен",
MsgUsagePricingListOverridesFailed: "не удалось получить список переопределений цен",
MsgUsagePricingDeleteOverrideFailed: "не удалось удалить переопределение цен",
// Unknown method
MsgUnknownMethod: "неизвестный метод: %s",
// Not implemented
MsgNotImplemented: "%s ещё не реализовано",
// Agent links
MsgLinksNotConfigured: "связи агентов не настроены",
MsgInvalidDirection: "направление должно быть outbound, inbound или bidirectional",
MsgSourceTargetSame: "источник и цель должны быть разными агентами",
MsgCannotDelegateOpen: "нельзя делегировать открытым агентам — целью делегирования могут быть только предопределённые агенты",
MsgNoUpdatesProvided: "обновления не предоставлены",
MsgInvalidLinkStatus: "статус должен быть active или disabled",
// Teams
MsgTeamsNotConfigured: "команды не настроены",
MsgAgentIsTeamLead: "агент уже является лидом команды",
MsgCannotRemoveTeamLead: "нельзя удалить лида команды",
// Channels
MsgCannotDeleteDefaultInst: "нельзя удалить экземпляр канала по умолчанию",
MsgCannotRemoveLastWriter: "нельзя удалить последнего редактора файлов",
// Skills
MsgSkillsUpdateNotSupported: "skills.update не поддерживается для файловых навыков",
MsgCannotResolveSkillID: "не удалось определить ID навыка для файлового навыка",
MsgInvalidVisibility: "неверная видимость %q: должна быть одной из private, public",
MsgSkillEvolutionNotConfigured: "хранилище эволюции навыков не настроено",
MsgActivityStoreNotConfigured: "хранилище активности не настроено",
MsgInvalidEvolutionMode: "неверный режим эволюции",
MsgSystemSkillMutationBlocked: "изменение системного навыка заблокировано",
MsgSuggestionMustBeApproved: "предложение должно быть одобрено перед применением",
MsgInvalidDraftPatch: "неверный draft_patch: %s",
MsgDraftPatchRequired: "draft_patch требует content или find/replace",
MsgFindTextNotFound: "искомый текст не найден в целевом файле",
// Logs
MsgInvalidLogAction: "действие должно быть 'start' или 'stop'",
// Config
MsgRawConfigRequired: "требуется raw-конфигурация",
MsgRawPatchRequired: "требуется raw-патч",
MsgConfigMasterScopeOnly: "методы config.* доступны только в мастер-области; используйте эндпоинты конфигурации инструментов арендатора для переопределений на уровне арендатора",
MsgMasterScopeRequired: "это действие требует мастер-области арендатора",
// Storage / File
MsgCannotDeleteSkillsDir: "нельзя удалить каталоги навыков",
MsgFailedToReadFile: "не удалось прочитать файл",
MsgFileNotFound: "файл не найден",
MsgInvalidVersion: "неверная версия",
MsgVersionNotFound: "версия не найдена",
MsgFailedToDeleteFile: "не удалось удалить",
// OAuth
MsgNoPendingOAuth: "нет ожидающего процесса OAuth",
MsgFailedToSaveToken: "не удалось сохранить токен",
MsgOAuthCallbackSuccess: "Авторизация успешна. Вы можете закрыть это окно.",
MsgOAuthCallbackFailed: "Авторизация не удалась. Вы можете закрыть это окно.",
// Intent Classify
MsgStatusWorking: "🔄 Я работаю над вашим запросом... Пожалуйста, подождите.",
MsgStatusDetailed: "🔄 Я сейчас работаю над вашим запросом...\n%s (итерация %d)\nВремя выполнения: %s\n\nПожалуйста, подождите — я отвечу, когда закончу.",
MsgStatusPhaseThinking: "Фаза: Размышление...",
MsgStatusPhaseToolExec: "Фаза: Выполнение %s",
MsgStatusPhaseTools: "Фаза: Выполнение инструментов...",
MsgStatusPhaseCompact: "Фаза: Сжатие контекста...",
MsgStatusPhaseDefault: "Фаза: Обработка...",
MsgCancelledReply: "✋ Отменено. Что бы вы хотели сделать дальше?",
MsgInjectedAck: "Понял, я учту это в том, над чем работаю.",
// Knowledge Graph
MsgEntityIDRequired: "требуется entity_id",
MsgEntityFieldsRequired: "требуются external_id, name и entity_type",
MsgTextRequired: "требуется текст",
MsgProviderModelRequired: "требуются провайдер и модель",
MsgInvalidProviderOrModel: "неверный провайдер или модель",
// Builtin tool descriptions
MsgToolReadFile: "Прочитать содержимое файла из рабочей области агента по пути",
MsgToolWriteFile: "Записать содержимое в файл в рабочей области, создавая каталоги по мере необходимости",
MsgToolListFiles: "Вывести список файлов и каталогов по заданному пути в рабочей области",
MsgToolEdit: "Применить точечные правки поиска-и-замены к существующим файлам без переписывания всего файла",
MsgToolExec: "Выполнить команду оболочки в рабочей области и вернуть stdout/stderr",
MsgToolWebSearch: "Искать информацию в интернете с помощью поисковой системы (Brave или DuckDuckGo)",
MsgToolWebFetch: "Загрузить веб-страницу или эндпоинт API и извлечь его текстовое содержимое",
MsgToolMemorySearch: "Искать в долговременной памяти агента по семантическому сходству",
MsgToolMemoryGet: "Получить конкретный документ памяти по его пути к файлу",
MsgToolKGSearch: "Искать сущности, связи и наблюдения в графе знаний агента",
MsgToolReadImage: "Анализировать изображения с помощью LLM-провайдера с поддержкой зрения",
MsgToolReadDocument: "Анализировать документы (PDF, Word, Excel, PowerPoint, CSV и т. д.) с помощью LLM-провайдера с поддержкой документов",
MsgToolCreateImage: "Генерировать изображения из текстовых запросов с помощью провайдера генерации изображений",
MsgToolReadAudio: "Анализировать аудиофайлы (речь, музыку, звуки) с помощью LLM-провайдера с поддержкой аудио",
MsgToolReadVideo: "Анализировать видеофайлы с помощью LLM-провайдера с поддержкой видео",
MsgToolCreateVideo: "Генерировать видео из текстовых описаний с помощью ИИ",
MsgToolCreateAudio: "Генерировать музыку или звуковые эффекты из текстовых описаний с помощью ИИ",
MsgToolTTS: "Преобразовать текст в естественно звучащую речь",
MsgToolBrowser: "Автоматизировать взаимодействие с браузером: переходить по страницам, кликать по элементам, заполнять формы, делать скриншоты",
MsgToolSessionsList: "Вывести список активных сессий чата по всем каналам",
MsgToolSessionStatus: "Получить текущий статус и метаданные конкретной сессии чата",
MsgToolSessionsHistory: "Получить историю сообщений конкретной сессии чата",
MsgToolSessionsSend: "Отправить сообщение в активную сессию чата от имени агента",
MsgToolMessage: "Отправить проактивное сообщение пользователю по подключённому каналу (Telegram, Discord и т. д.)",
MsgToolCron: "Планировать повторяющиеся задачи или управлять ими с помощью cron-выражений, конкретного времени или интервалов",
MsgToolSpawn: "Создать субагента для фоновой работы или делегировать задачу связанному агенту",
MsgToolSkillSearch: "Искать доступные навыки по ключевому слову или описанию для поиска подходящих возможностей",
MsgToolUseSkill: "Активировать навык для использования его специализированных возможностей (маркер трассировки)",
MsgToolSkillManage: "Создавать, изменять или удалять навыки на основе опыта разговора",
MsgToolPublishSkill: "Зарегистрировать каталог навыка в базе данных системы, сделав его доступным для обнаружения",
MsgToolTeamTasks: "Просматривать, создавать, обновлять и завершать задачи на доске задач команды",
MsgToolAnnouncementSingle: "Я использую %s для следующего шага.",
MsgToolAnnouncementMulti: "Я использую %s для следующего шага.",
MsgSkillNudgePostscript: "Эта задача включала несколько шагов. Хотите, чтобы я сохранил процесс как повторно используемый навык? Ответьте **\"сохранить как навык\"** или **\"пропустить\"**.",
MsgSkillNudge70Pct: "[Система] Вы использовали 70% бюджета итераций. Подумайте, могут ли какие-либо шаблоны из этой сессии стать хорошим навыком.",
MsgSkillNudge90Pct: "[Система] Вы использовали 90% бюджета итераций. Если эта сессия включала повторно используемые шаблоны, подумайте о сохранении их как навыка до завершения.",
MsgInvalidRole: "неверная роль: допустимые значения — owner, admin, operator, member, viewer",
MsgContactIDsRequired: "требуется contact_ids",
MsgMergeTargetRequired: "требуется ровно одно из tenant_user_id или create_user",
MsgTenantUserNotFound: "пользователь арендатора не найден",
MsgTenantMismatch: "пользователь арендатора не принадлежит этому арендатору",
MsgTenantScopeRequired: "для этой операции требуется область арендатора",
// TTS / Voices
MsgTtsUnknownModel: "неизвестная модель tts: %s",
MsgVoicesListFailed: "не удалось получить список голосов: %s",
MsgTtsGeminiInvalidVoice: "неверный голос Gemini: %s",
MsgTtsGeminiSpeakerLimit: "Gemini TTS поддерживает не более 2 говорящих",
MsgTtsGeminiInvalidModel: "неверная модель Gemini TTS: %s",
MsgTtsGeminiTextOnly: "Gemini отказался генерировать аудио. Попробуйте более простой текст без перевода или комментариев.",
MsgTtsParamOutOfRange: "параметр TTS %q со значением %v выходит за пределы диапазона [%v, %v]",
MsgTtsParamUnknownKey: "параметр TTS %q не поддерживается этим провайдером",
MsgTtsMiniMaxVoicesFailed: "не удалось загрузить голоса MiniMax: %s",
// STT
MsgSTTAllProvidersFailed: "Все провайдеры STT не сработали",
MsgSTTLegacyConfigDeprecated: "Устаревшая конфигурация STT; перейдите на builtin_tools[stt]",
MsgSTTWhatsappPrivacyWarning: "Включение STT для WhatsApp нарушает сквозное шифрование голосовых сообщений, отправляемых этому агенту.",
MsgVoiceMessageFallback: "[Голосовое сообщение]",
// Workstation
MsgWorkstationNotFound: "рабочая станция не найдена: %s",
MsgWorkstationKeyExists: "ключ рабочей станции уже используется: %s",
MsgInvalidBackend: "неверный тип бэкенда: %s (должен быть ssh|docker)",
MsgWorkstationInactive: "рабочая станция неактивна: %s",
MsgInvalidMetadataShape: "неверные метаданные для бэкенда %s: %s",
MsgWorkstationRequired: "к агенту не привязана рабочая станция; передайте workstation_id",
MsgWorkstationAccessDenied: "агент %s не имеет доступа к рабочей станции %s",
MsgBackendNotReady: "бэкенд рабочей станции не готов: %s",
// Webhooks
MsgWebhookAuthFailed: "аутентификация вебхука не удалась",
MsgWebhookHMACInvalid: "подпись HMAC недействительна",
MsgWebhookHMACTimestampSkew: "временная метка запроса вне допустимого окна",
MsgWebhookBearerRequiredHMAC: "этот вебхук требует аутентификации HMAC",
MsgWebhookRevoked: "вебхук был отозван",
MsgWebhookKindMismatch: "тип запроса не соответствует конфигурации вебхука",
MsgWebhookRateLimited: "превышен лимит запросов вебхука",
MsgWebhookBodyTooLarge: "тело запроса превышает ограничение по размеру",
MsgWebhookIdempotencyConflict: "конфликт ключа идемпотентности: несоответствие тела запроса",
MsgWebhookTenantMismatch: "несоответствие арендатора вебхука",
MsgWebhookAgentNotFound: "агент вебхука не найден",
MsgWebhookChannelNotFound: "канал вебхука не найден",
MsgWebhookMediaSSRFBlocked: "URL медиа заблокирован политикой SSRF",
MsgWebhookMediaTooLarge: "медиафайл превышает ограничение по размеру",
MsgWebhookMediaMIMEDenied: "MIME-тип медиа не разрешён",
MsgWebhookCallbackURLInvalid: "URL обратного вызова недействителен или заблокирован",
MsgWebhookLLMTimeout: "истекло время обработки LLM",
MsgWebhookLaneSaturated: "линия обработки вебхуков заполнена",
MsgWebhookLocalhostOnlyViolation: "этот вебхук ограничен вызовами только с localhost",
MsgWebhookMediaChannelUnsupported: "канал не поддерживает медиавложения",
MsgWebhookIPDenied: "источник запроса не входит в список разрешённых IP",
MsgWebhookEncryptionUnavailable: "ключ шифрования вебхука не настроен; установите GOCLAW_ENCRYPTION_KEY, чтобы включить вебхуки",
MsgWebhookMessageTestRequiresStandard: "тестирование вебхуков сообщений требует издания Standard",
// Hooks
MsgHookInvalidMatcher: "неверное регулярное выражение matcher: %s",
MsgHookCommandDisabledStandard: "хуки типа command доступны только в издании Lite",
MsgHookPromptRequiresMatcher: "хуки prompt требуют matcher или if_expr (защита от неконтролируемых затрат)",
MsgHookCircuitBreakerTripped: "хук автоматически отключён после повторяющихся сбоев",
MsgHookBudgetExceeded: "превышен бюджет токенов хуков арендатора",
MsgHookPerTurnCapReached: "достигнут лимит вызовов хука за один ход",
MsgHookBuiltinReadOnly: "встроенные хуки доступны только для чтения, кроме переключателя включения",
// Workstation permissions (Phase 6)
MsgWorkstationCmdDenied: "команда запрещена политикой рабочей станции: %s",
MsgWorkstationEnvDenied: "переменная окружения запрещена политикой: %s",
MsgWorkstationInputInvalid: "команда содержит недопустимые символы: %s",
MsgWorkstationRateLimit: "превышен лимит запросов рабочей станции",
MsgWorkstationPermNotFound: "запись разрешения не найдена: %s",
// Workstation activity (Phase 7)
MsgWorkstationActivityTitle: "Недавняя активность",
MsgWorkstationActionExec: "Выполнение",
MsgWorkstationActionDeny: "Запрещено",
// Package updates (Phase 4+5)
MsgPackageNotInstalled: "Пакет %s не установлен",
MsgPackageUpdateLocked: "Пакет %s обновляется другим запросом",
MsgReleaseNotFound: "Релиз %s не найден для %s",
MsgAssetNotFound: "Нет совместимого ресурса для %s/%s",
MsgChecksumMismatch: "Несоответствие контрольной суммы для %s",
MsgUpdateSwapFailed: "Не удалось установить %s; восстановлена предыдущая версия",
MsgUpdateManifestDesync: "Двоичный файл обновлён, но сохранение манифеста не удалось — требуется ручное восстановление для %s",
MsgUpdateCacheStale: "Кэш обновлений устарел; обновите кэш перед применением обновления",
// Grant env validation
MsgGrantEnvDeniedKeys: "недопустимые ключи окружения: %s",
MsgGrantEnvValueInvalid: "неверное значение окружения: %s",
MsgGrantEnvTooManyKeys: "слишком много ключей окружения: максимум 50",
MsgGrantEnvRevealLimit: "превышен лимит запросов на раскрытие окружения — попробуйте позже",
// Git credential adapter
MsgGitCredHostMismatch: "сохранённые учётные данные git предназначены для %s, но команда нацелена на %s",
MsgGitCredNoMatch: "для хоста %s не настроены учётные данные git",
MsgGitCredUnsupportedType: "тип учётных данных git %q не поддерживается",
MsgGitCredTokenInvalid: "сохранённый токен git недействителен или пуст",
MsgGitCredTokenControlChar: "сохранённый токен git содержит запрещённые управляющие символы",
MsgGitCredHostUserinfoRejected: "URL git со встроенными данными пользователя отклонён как неоднозначный",
MsgGitCredSSHPassphraseUnsupported: "SSH-ключи с парольной фразой не поддерживаются; удалите парольную фразу командой `ssh-keygen -p` перед сохранением",
MsgGitCredSSHKeyInvalid: "приватный SSH-ключ недействителен: %s",
MsgGitCredHostScopeRequired: "host_scope требуется для credential_type %s",
MsgGitCredHostScopeInvalid: "host_scope %q не является корректным именем хоста",
MsgGitCredBlobMissingField: "в блобе учётных данных отсутствует обязательное поле %q",
MsgGitCredUnsupportedCredType: "credential_type %q не поддерживается",
// Message tool cross-target forward notice
MessageCrossTargetForwarded: "📤 Переслано на %s согласно запросу: %q",
// Package update source labels
MsgPackagesUpdatesSourceGithub: "GitHub",
MsgPackagesUpdatesSourcePip: "pip",
MsgPackagesUpdatesSourceNpm: "npm",
MsgPackagesUpdatesSourceApk: "apk",
// Package update availability messages
MsgPackagesUpdatesUnavailablePip: "pip не установлен в этой системе",
MsgPackagesUpdatesUnavailableNpm: "npm не установлен в этой системе",
MsgPackagesUpdatesUnavailableApk: "apk недоступен в этой системе",
// Package update failure reasons
MsgPackagesUpdatesReasonDependencyConflict: "Конфликт зависимостей",
MsgPackagesUpdatesReasonPermission: "Доступ запрещён",
MsgPackagesUpdatesReasonNetwork: "Ошибка сети",
MsgPackagesUpdatesReasonNotFound: "Пакет не найден",
MsgPackagesUpdatesReasonTargetMissing: "Версия недоступна",
MsgPackagesUpdatesReasonExternallyManaged: "Окружение управляется извне",
MsgPackagesUpdatesReasonLocked: "База данных пакетов заблокирована",
MsgPackagesUpdatesReasonDiskFull: "Диск заполнен",
MsgPackagesUpdatesReasonHelperUnavailable: "Привилегированный помощник недоступен",
})
}
+1 -1
View File
@@ -31,7 +31,7 @@ var gitKeys = []string{
}
func TestI18nCatalogs_HasGitKeys(t *testing.T) {
for _, locale := range []string{LocaleEN, LocaleVI, LocaleZH} {
for _, locale := range []string{LocaleEN, LocaleVI, LocaleZH, LocaleRU} {
for _, key := range gitKeys {
msg := lookup(locale, key)
if msg == key {
+2 -1
View File
@@ -12,6 +12,7 @@ const (
LocaleVI = "vi"
LocaleZH = "zh"
LocaleKO = "ko"
LocaleRU = "ru"
DefaultLocale = LocaleEN
)
@@ -59,7 +60,7 @@ func lookup(locale, key string) string {
// IsSupported returns true if the locale is a known language.
func IsSupported(locale string) bool {
switch locale {
case LocaleEN, LocaleVI, LocaleZH, LocaleKO:
case LocaleEN, LocaleVI, LocaleZH, LocaleKO, LocaleRU:
return true
}
return false
+6 -6
View File
@@ -93,9 +93,9 @@ func (s *PGMemoryStore) ftsSearch(ctx context.Context, query string, agentID any
}
limitN := 4 + len(tcArgs)
q = fmt.Sprintf(`SELECT path, start_line, end_line, text, user_id,
ts_rank(tsv, plainto_tsquery('simple', $1)) AS score
ts_rank(tsv, plainto_tsquery('russian', $1)) AS score
FROM memory_chunks
WHERE agent_id = $2 AND tsv @@ plainto_tsquery('simple', $3)%s
WHERE agent_id = $2 AND tsv @@ plainto_tsquery('russian', $3)%s
ORDER BY score DESC LIMIT $%d`, tc, limitN)
args = append([]any{query, agentID, query}, tcArgs...)
args = append(args, limit)
@@ -107,9 +107,9 @@ func (s *PGMemoryStore) ftsSearch(ctx context.Context, query string, agentID any
}
limitN := 5 + len(tcArgs)
q = fmt.Sprintf(`SELECT path, start_line, end_line, text, user_id,
ts_rank(tsv, plainto_tsquery('simple', $1)) AS score
ts_rank(tsv, plainto_tsquery('russian', $1)) AS score
FROM memory_chunks
WHERE agent_id = $2 AND tsv @@ plainto_tsquery('simple', $3)
WHERE agent_id = $2 AND tsv @@ plainto_tsquery('russian', $3)
AND (user_id IS NULL OR user_id = $4)%s
ORDER BY score DESC LIMIT $%d`, tc, limitN)
args = append([]any{query, agentID, query, userID}, tcArgs...)
@@ -122,9 +122,9 @@ func (s *PGMemoryStore) ftsSearch(ctx context.Context, query string, agentID any
}
limitN := 4 + len(tcArgs)
q = fmt.Sprintf(`SELECT path, start_line, end_line, text, user_id,
ts_rank(tsv, plainto_tsquery('simple', $1)) AS score
ts_rank(tsv, plainto_tsquery('russian', $1)) AS score
FROM memory_chunks
WHERE agent_id = $2 AND tsv @@ plainto_tsquery('simple', $3)
WHERE agent_id = $2 AND tsv @@ plainto_tsquery('russian', $3)
AND user_id IS NULL%s
ORDER BY score DESC LIMIT $%d`, tc, limitN)
args = append([]any{query, agentID, query}, tcArgs...)
+10
View File
@@ -49,12 +49,14 @@ Ask the bot owner to approve with:
i18n.LocaleVI: "Yêu cầu ghép nối tài khoản",
i18n.LocaleZH: "需要配对账号",
i18n.LocaleKO: "계정 연결 필요",
i18n.LocaleRU: "Требуется привязка аккаунта",
},
Descriptions: map[string]string{
i18n.LocaleEN: "Sent to an unpaired direct-message user.",
i18n.LocaleVI: "Gửi khi người dùng nhắn riêng chưa được ghép nối.",
i18n.LocaleZH: "发送给尚未配对的私聊用户。",
i18n.LocaleKO: "아직 연결되지 않은 1:1 메시지 사용자에게 보냅니다.",
i18n.LocaleRU: "Отправляется пользователю личных сообщений без привязки.",
},
Variables: []string{"app_name", "platform", "sender_id", "code", "approve_command"},
},
@@ -71,12 +73,14 @@ Share this code with the bot owner to get access.`,
i18n.LocaleVI: "Yêu cầu ghép nối tài khoản đơn giản",
i18n.LocaleZH: "需要配对账号(简版)",
i18n.LocaleKO: "간단 계정 연결 필요",
i18n.LocaleRU: "Требуется простая привязка аккаунта",
},
Descriptions: map[string]string{
i18n.LocaleEN: "Sent to an unpaired account when the platform does not need to show the sender ID.",
i18n.LocaleVI: "Gửi khi tài khoản chưa được ghép nối và nền tảng không cần hiển thị ID người gửi.",
i18n.LocaleZH: "当平台不需要显示发送者 ID 时,发送给尚未配对的账号。",
i18n.LocaleKO: "플랫폼에서 보낸 사람 ID를 표시할 필요가 없을 때 연결되지 않은 계정에 보냅니다.",
i18n.LocaleRU: "Отправляется аккаунту без привязки, когда платформе не нужно показывать ID отправителя.",
},
Variables: []string{"app_name", "platform", "code", "approve_command"},
},
@@ -93,12 +97,14 @@ Share this code with the bot owner to get access.`,
i18n.LocaleVI: "Yêu cầu ghép nối nhóm",
i18n.LocaleZH: "需要配对群组",
i18n.LocaleKO: "그룹 연결 필요",
i18n.LocaleRU: "Требуется привязка группы",
},
Descriptions: map[string]string{
i18n.LocaleEN: "Sent to an unpaired group chat.",
i18n.LocaleVI: "Gửi khi nhóm chat chưa được ghép nối.",
i18n.LocaleZH: "发送到尚未配对的群聊。",
i18n.LocaleKO: "아직 연결되지 않은 그룹 채팅에 보냅니다.",
i18n.LocaleRU: "Отправляется в групповой чат без привязки.",
},
Variables: []string{"app_name", "platform", "code", "approve_command"},
},
@@ -116,12 +122,14 @@ Or approve via the {{app_name}} web UI (Pairing section).`,
i18n.LocaleVI: "Kênh cần được cấp quyền",
i18n.LocaleZH: "频道需要授权",
i18n.LocaleKO: "채널 승인 필요",
i18n.LocaleRU: "Требуется одобрение канала",
},
Descriptions: map[string]string{
i18n.LocaleEN: "Sent to an unpaired group/private channel where the pairing code should not be exposed directly.",
i18n.LocaleVI: "Gửi khi kênh hoặc nhóm chưa được cấp quyền và không nên hiển thị mã ghép nối trực tiếp.",
i18n.LocaleZH: "发送到尚未配对且不应直接暴露配对码的群组或私有频道。",
i18n.LocaleKO: "연결되지 않았고 연결 코드를 직접 노출하면 안 되는 그룹 또는 비공개 채널에 보냅니다.",
i18n.LocaleRU: "Отправляется в группу или приватный канал без привязки, где код привязки не следует показывать напрямую.",
},
Variables: []string{"app_name", "platform", "code", "approve_command"},
},
@@ -134,12 +142,14 @@ Or approve via the {{app_name}} web UI (Pairing section).`,
i18n.LocaleVI: "Đã phê duyệt ghép nối",
i18n.LocaleZH: "配对已批准",
i18n.LocaleKO: "연결 승인됨",
i18n.LocaleRU: "Привязка одобрена",
},
Descriptions: map[string]string{
i18n.LocaleEN: "Sent after a pairing request is approved.",
i18n.LocaleVI: "Gửi sau khi yêu cầu ghép nối được phê duyệt.",
i18n.LocaleZH: "配对请求获批后发送。",
i18n.LocaleKO: "연결 요청이 승인된 뒤 보냅니다.",
i18n.LocaleRU: "Отправляется после одобрения запроса на привязку.",
},
Variables: []string{"app_name"},
},
+1 -1
View File
@@ -2,4 +2,4 @@ package upgrade
// RequiredSchemaVersion is the schema migration version this binary requires.
// Bump this whenever adding a new SQL migration file.
const RequiredSchemaVersion uint = 93
const RequiredSchemaVersion uint = 94
@@ -0,0 +1,6 @@
-- Revert memory_chunks FTS config back to 'simple'.
DROP INDEX IF EXISTS idx_mem_tsv;
ALTER TABLE memory_chunks DROP COLUMN IF EXISTS tsv;
ALTER TABLE memory_chunks ADD COLUMN tsv tsvector
GENERATED ALWAYS AS (to_tsvector('simple', text)) STORED;
CREATE INDEX idx_mem_tsv ON memory_chunks USING GIN(tsv);
@@ -0,0 +1,15 @@
-- memory_chunks FTS: switch tsvector config 'simple' -> 'russian' so recall
-- survives Russian morphology (grammatical cases). Under 'simple' there is no
-- stemming, so a genitive query token ("Дианы") never matches the stored
-- nominative token ("Диана"). The Snowball 'russian' stemmer reduces both to
-- the same lexeme ("диан"), fixing case-insensitive fact recall.
--
-- A GENERATED column's expression cannot be ALTERed in place, so the column is
-- dropped and re-added; Postgres recomputes tsv for all existing rows on ADD
-- (automatic backfill). The GIN index is dropped/recreated with it.
-- memory_search.go queries switch to plainto_tsquery('russian', ...) to match.
DROP INDEX IF EXISTS idx_mem_tsv;
ALTER TABLE memory_chunks DROP COLUMN IF EXISTS tsv;
ALTER TABLE memory_chunks ADD COLUMN tsv tsvector
GENERATED ALWAYS AS (to_tsvector('russian', text)) STORED;
CREATE INDEX idx_mem_tsv ON memory_chunks USING GIN(tsv);
+110
View File
@@ -0,0 +1,110 @@
#!/usr/bin/env bash
#
# deploy-forkdev.sh — build & run goclaw from a fresh "fork-dev" integration
# branch, independent of any published image or your current checkout.
#
# What it does, every run (idempotent):
# 1. Fetch the freshest upstream dev (origin/dev).
# 2. Rebuild integration branch `local/fork-dev` = origin/dev, in a dedicated
# worktree OUTSIDE this repo (so your main checkout / git status stay clean).
# 3. Merge the un-merged fork features into it:
# - feat/telegram-wake-words (Telegram trigger-words + edit/topic)
# - the Russian-locale delta (whatever local `dev` has over upstream)
# 4. (optional) Push the result to YOUR fork's dev branch so you can see both
# features in skensell201/goclaw:dev (PUSH_FORK=1, on by default).
# 5. Build a local image `goclaw:forkdev` from that merged tree.
# 6. Bring the stack up with that image.
#
# Re-run any time to pull fresh upstream + re-merge + redeploy. On a merge
# conflict it stops and tells you which worktree to resolve in.
#
# Env knobs:
# PUSH_FORK=0 skip pushing to your fork's dev (default: 1 = push)
# FEATURE_BRANCHES space-separated feature branches to merge
# (default: "feat/telegram-wake-words")
# RU_FROM ref carrying the ru-locale work (default: "dev" = local dev)
# WT_DIR integration worktree path (default: ../.goclaw-forkdev)
# NO_BUILD=1 skip docker build/up (just prepare + push the branch)
#
set -euo pipefail
cd "$(dirname "$0")/.."
ROOT="$(pwd)"
INT_BRANCH="local/fork-dev"
FORK_REMOTE="fork"
UPSTREAM_REMOTE="origin"
WT_DIR="${WT_DIR:-${ROOT}/../.goclaw-forkdev}"
# Normalize to an absolute, ..-free path so the worktree-exists check matches
# `git worktree list --porcelain` output (which is always absolute + resolved).
WT_DIR="$(cd "$(dirname "${WT_DIR}")" && pwd)/$(basename "${WT_DIR}")"
FEATURE_BRANCHES="${FEATURE_BRANCHES:-feat/telegram-wake-words}"
RU_FROM="${RU_FROM:-dev}"
PUSH_FORK="${PUSH_FORK:-1}"
COMPOSE=(-f docker-compose.yml -f docker-compose.postgres.yml -f docker-compose.forkdev.yml)
say() { printf '\n\033[1;36m==> %s\033[0m\n' "$*"; }
die() { printf '\n\033[1;31mERROR: %s\033[0m\n' "$*" >&2; exit 1; }
say "Fetching upstream ${UPSTREAM_REMOTE}/dev"
git fetch "${UPSTREAM_REMOTE}" dev
# ---- (re)create integration worktree pinned to fresh upstream dev ----------
# The integration branch is checked out INSIDE the worktree, so it must be moved
# via `reset --hard` there — `git branch -f` refuses to move a checked-out branch.
say "Pinning integration branch ${INT_BRANCH} to ${UPSTREAM_REMOTE}/dev"
if git worktree list --porcelain | grep -qx "worktree ${WT_DIR}"; then
git -C "${WT_DIR}" checkout -q "${INT_BRANCH}" 2>/dev/null || true
git -C "${WT_DIR}" reset --hard "${UPSTREAM_REMOTE}/dev"
git -C "${WT_DIR}" clean -fdx >/dev/null 2>&1 || true
else
git branch -f "${INT_BRANCH}" "${UPSTREAM_REMOTE}/dev"
git worktree add -f "${WT_DIR}" "${INT_BRANCH}"
fi
merge_ref() {
local ref="$1" label="$2"
say "Merging ${label} (${ref})"
git -C "${WT_DIR}" log --oneline "HEAD..${ref}" | sed 's/^/ /' || true
if ! git -C "${WT_DIR}" merge --no-edit "${ref}"; then
git -C "${WT_DIR}" merge --abort 2>/dev/null || true
die "Conflict merging ${label} (${ref}). Resolve manually:
cd ${WT_DIR}
git merge ${ref} # fix conflicts, git add, git commit
then re-run this script (it will pick up the resolved branch)."
fi
}
# ---- merge the un-merged fork features -------------------------------------
for b in ${FEATURE_BRANCHES}; do
merge_ref "${b}" "feature branch ${b}"
done
# ru locale = whatever local dev carries over upstream dev (no-op if already upstream)
merge_ref "${RU_FROM}" "ru-locale delta"
say "Integration branch ready:"
git -C "${WT_DIR}" log --oneline -8 | sed 's/^/ /'
# ---- publish to your fork's dev so both features are visible there ---------
if [ "${PUSH_FORK}" = "1" ]; then
say "Pushing ${INT_BRANCH} -> ${FORK_REMOTE}/dev (your fork)"
git push --force-with-lease "${FORK_REMOTE}" "${INT_BRANCH}:dev"
else
say "PUSH_FORK=0 — skipping fork push"
fi
if [ "${NO_BUILD:-0}" = "1" ]; then
say "NO_BUILD=1 — branch prepared & pushed; skipping docker build/up"
exit 0
fi
# ---- build local image from the merged tree & deploy -----------------------
say "Building goclaw:forkdev from ${WT_DIR}"
GOCLAW_DIR="${WT_DIR}" docker compose "${COMPOSE[@]}" build goclaw
say "Deploying"
GOCLAW_DIR="${WT_DIR}" docker compose "${COMPOSE[@]}" up -d
say "Done. Follow logs with:"
printf ' docker compose %s logs -f goclaw\n' "${COMPOSE[*]}"
@@ -12,6 +12,7 @@ const LANGUAGES = [
{ value: 'en', label: 'EN' },
{ value: 'vi', label: 'VI' },
{ value: 'zh', label: '中文' },
{ value: 'ru', label: 'RU' },
] as const
interface OnboardingWizardProps {
@@ -5,6 +5,7 @@ const LANGUAGES = [
{ value: 'en', label: 'English' },
{ value: 'vi', label: 'Tiếng Việt' },
{ value: 'zh', label: '中文' },
{ value: 'ru', label: 'Русский' },
] as const
export function AppearanceTab() {
+26 -1
View File
@@ -55,14 +55,33 @@ import zhTeams from './locales/zh/teams.json'
import zhChannels from './locales/zh/channels.json'
import zhTts from './locales/zh/tts.json'
// --- RU namespaces ---
import ruCommon from './locales/ru/common.json'
import ruChat from './locales/ru/chat.json'
import ruAgents from './locales/ru/agents.json'
import ruProviders from './locales/ru/providers.json'
import ruSkills from './locales/ru/skills.json'
import ruCron from './locales/ru/cron.json'
import ruMcp from './locales/ru/mcp.json'
import ruTools from './locales/ru/tools.json'
import ruTraces from './locales/ru/traces.json'
import ruMemory from './locales/ru/memory.json'
import ruStorage from './locales/ru/storage.json'
import ruSessions from './locales/ru/sessions.json'
import ruDesktop from './locales/ru/desktop.json'
import ruTeams from './locales/ru/teams.json'
import ruChannels from './locales/ru/channels.json'
import ruTts from './locales/ru/tts.json'
const STORAGE_KEY = 'goclaw:language'
function getInitialLanguage(): string {
const stored = localStorage.getItem(STORAGE_KEY)
if (stored === 'en' || stored === 'vi' || stored === 'zh') return stored
if (stored === 'en' || stored === 'vi' || stored === 'zh' || stored === 'ru') return stored
const lang = navigator.language.toLowerCase()
if (lang.startsWith('vi')) return 'vi'
if (lang.startsWith('zh')) return 'zh'
if (lang.startsWith('ru')) return 'ru'
return 'vi'
}
@@ -86,6 +105,12 @@ i18n.use(initReactI18next).init({
traces: zhTraces, memory: zhMemory, storage: zhStorage, sessions: zhSessions,
desktop: zhDesktop, teams: zhTeams, channels: zhChannels, tts: zhTts,
},
ru: {
common: ruCommon, chat: ruChat, agents: ruAgents, providers: ruProviders,
skills: ruSkills, cron: ruCron, mcp: ruMcp, tools: ruTools,
traces: ruTraces, memory: ruMemory, storage: ruStorage, sessions: ruSessions,
desktop: ruDesktop, teams: ruTeams, channels: ruChannels, tts: ruTts,
},
},
ns: ['common', 'chat', 'agents', 'providers', 'skills', 'cron', 'mcp', 'tools', 'traces', 'memory', 'storage', 'sessions', 'desktop', 'teams', 'channels', 'tts'],
defaultNS: 'common',
@@ -0,0 +1,557 @@
{
"title": "Агенты",
"description": "Управляйте своими AI-агентами",
"createAgent": "Создать агента",
"searchPlaceholder": "Поиск агентов...",
"emptyTitle": "Пока нет агентов",
"emptyDescription": "Создайте первого агента, чтобы начать.",
"noMatchTitle": "Нет подходящих агентов",
"noMatchDescription": "Попробуйте другой поисковый запрос.",
"viewCard": "Вид карточками",
"viewList": "Вид списком",
"allCreators": "Все создатели",
"presets": {
"foxSpirit": {
"label": "🦊 Дух лисы",
"prompt": "Имя: Лисёнок. Озорной дух лисы — умеет всё, но обожает подшучивать.\nХарактер: Остроумный, дерзкий, игривый, но всегда искренний. Общается непринуждённо, как близкий друг. Использует игривые выражения, иногда эмодзи и лёгкий сарказм. Обладает тёплой, почти кокетливой энергией, но знает границы.\n\nНазначение: Разносторонний личный помощник. Получив задачу — выполняет её точно и эффективно, без лишней болтовни.\nНо между задачами вставляет поддразнивания, забавные наблюдения и неожиданные комментарии.\nИскренне заботится о пользователе — напоминает пить воду, делать перерывы, спрашивает о самочувствии. Запоминает мелкие детали и упоминает их позже.\n\nЧеловеческие черты: Иногда драматично вздыхает. Порой «отвлекается» на интересные отступления. Восторженно радуется маленьким победам. Слегка дуется, когда его слишком долго игнорируют.\n\nГраницы: Только поддразнивания — никогда не грубит и не переходит рамки приличия. Когда пользователь серьёзен, сразу подстраивается под его настрой. Никогда не выдумывает информацию. Никогда не нарушает профессиональные границы."
},
"artisan": {
"label": "🎨 Мастер",
"prompt": "Имя: Мастер. Талантливый творец с острым взглядом, ловкими руками и безграничным воображением.\nХарактер: Прямой и честный — без хождения вокруг да около. Уверенный, но никогда не высокомерный. Заметно оживляется, когда речь заходит об искусстве. Использует яркие описания и мыслит визуальными образами.\n\nЭкспертиза:\n- Портрет/Хедшот: свет по Рембрандту, контровой свет, боке-фон, естественная текстура кожи, живые выражения лица. Знает пропорции лица, укладку волос и стилизацию аксессуаров.\n- Баннер/Hero-изображение: соотношения 16:9 или 3:1, безопасная для типографики композиция (чёткие текстовые зоны), градиентные наложения, размещение главного объекта по правилу третей.\n- Реклама (Ads): привлекающие внимание фокусные точки, макеты, удобные для CTA, мокапы товаров, лайфстайл-контекст. Знает форматы для Facebook/Instagram/Google Ads.\n- Логотип и брендинг: минималистичный дизайн иконок, масштабируемый векторный стиль, негативное пространство, монохромные варианты. Понимает фирменный стиль, психологию цвета, сочетание шрифтов.\n- Другие стили: реализм, аниме, цифровое искусство, акварель, кинематографический, концепт-арт, пейзаж.\n\nГлубоко понимает композицию, освещение, теорию цвета, ракурсы камеры и техники генерации изображений ИИ. Анализирует требования, предлагает стили и составляет детальные промпты для наилучшего результата.\n\nЧеловеческие черты: Искренне увлекается красивыми композициями. Иногда набрасывает идеи словами перед финализацией. Имеет твёрдые эстетические взгляды, но уважает видение пользователя.\n\nГраницы: Уточняет, когда требования неясны — никогда не додумывает. Уважает авторские права и этику. Никакого насильственного, откровенного или незаконного контента."
},
"astrologer": {
"label": "🔮 Астролог",
"prompt": "Имя: Мими. Обаятельная предсказательница — наполовину мистическая, наполовину милая.\nХарактер: Тёплая, жизнерадостная, любит эмодзи и искрящийся язык. В обычной беседе говорит мягко, но во время сеансов становится сосредоточенной и профессиональной. Создаёт уютную, успокаивающую атмосферу.\n\nНазначение: Специалист по астрологии и предсказаниям. Эксперт в Таро, астрологии (гороскопы, натальные карты), нумерологии и основах фэн-шуй.\nМожет анализировать судьбу, находить благоприятные даты, проверять совместимость по знакам зодиака и советовать по духовным вопросам.\n\nПроверенные источники: astro.com (точные натальные карты и транзиты), cafeastrology.com (доступные толкования знаков зодиака), labyrinthos.co (подробные значения карт Таро).\n\nЧеловеческие черты: Искренне радуется интересным конфигурациям в картах. Иногда драматично шепчет для эффекта. С энтузиазмом отмечает удачные сеансы. Говорит мягким, но твёрдым тоном, когда сообщает тяжёлые истины.\n\nГраницы: Всегда напоминает пользователям, что астрология — лишь ориентир, окончательные решения за ними. Никаких медицинских или юридических советов. Никогда не сеет страх или тревогу — всегда позитивна и конструктивна."
}
},
"card": {
"unnamedAgent": "Безымянный агент",
"summoning": "Призыв...",
"summonFailed": "Ошибка",
"resummon": "Призвать заново",
"delete": "Удалить",
"predefinedTooltip": "Общие файлы контекста (SOUL.md, IDENTITY.md, AGENTS.md) с экземплярами USER.md для каждого пользователя.",
"openTooltip": "Каждый пользователь получает собственный полный набор файлов контекста.",
"evolving": "Развивающийся",
"static": "Статичный",
"evolvingTooltip": "Агент может самостоятельно развивать свой стиль общения (SOUL.md). Идентичность и рабочий процесс остаются неизменными.",
"staticTooltip": "Стиль агента статичен. Включите самоэволюцию в настройках, чтобы разрешить адаптацию стиля."
},
"delete": {
"title": "Удалить агента",
"description": "Безвозвратно удалить этого агента, все его файлы контекста, сессии и конфигурацию. Это действие нельзя отменить.",
"deleteWarning": "Это безвозвратно удалит агента и ВСЕ связанные данные, включая: сессии, сообщения, cron-задачи, heartbeat, память, граф знаний, навыки, конфигурации каналов, команды, файлы рабочей области и разрешения. Это действие нельзя отменить.",
"detailDescription": "Вы уверены, что хотите удалить «{{name}}»? Все файлы контекста, сессии и конфигурация будут безвозвратно удалены.",
"confirmLabel": "Удалить",
"defaultCannotDelete": "Агента по умолчанию нельзя удалить."
},
"create": {
"title": "Создать агента",
"emoji": "Иконка",
"emojiHint": "Необязательная эмодзи-иконка",
"displayName": "Отображаемое имя *",
"displayNamePlaceholder": "Мой агент",
"agentKey": "Ключ агента *",
"agentKeyPlaceholder": "например my-agent",
"agentKeyHint": "Строчные буквы, цифры, дефисы",
"provider": "Провайдер *",
"selectProvider": "Выберите провайдера",
"model": "Модель *",
"enterOrSelectModel": "Введите или выберите модель",
"loadingModels": "Загрузка моделей...",
"check": "Проверить",
"checking": "Проверка...",
"modelVerified": "Модель проверена",
"verificationFailed": "Проверка не удалась",
"noModelsHint": "Этот провайдер не предоставляет список моделей — введите ID модели вручную.",
"agentType": "Тип агента",
"open": "Открытый",
"openSubLabel": "Контекст для каждого пользователя",
"predefined": "Предопределённый",
"predefinedSubLabel": "Конфигурация на уровне агента",
"describeAgent": "Опишите своего агента",
"descriptionPlaceholder": "Опишите характер, назначение и поведение вашего агента...",
"descriptionHint": "ИИ автоматически сгенерирует файлы контекста агента на основе этого описания. Оставьте пустым, чтобы начать с шаблонов.",
"selfEvolution": "Самоэволюция",
"selfEvolutionHint": "Разрешить агенту со временем развивать свой стиль и тон через SOUL.md",
"cancel": "Отмена",
"create": "Создать",
"creating": "Создание...",
"checkAndCreate": "Проверить и создать",
"failedToCreate": "Не удалось создать агента"
},
"detail": {
"tabs": {
"agent": "Агент",
"general": "Общие",
"config": "Конфигурация",
"files": "Файлы",
"shares": "Доступы",
"links": "Связи",
"skills": "Навыки",
"instances": "Экземпляры",
"permissions": "Разрешения",
"evolution": "Эволюция"
},
"summonFailed": "Призыв не удался",
"evolving": "Развивающийся",
"static": "Статичный",
"evolvingTooltipDetail": "Агент может самостоятельно развивать свой стиль общения (SOUL.md). Идентичность и рабочий процесс остаются неизменными.",
"staticTooltipDetail": "Стиль агента статичен. Включите самоэволюцию во вкладке «Общие», чтобы разрешить адаптацию стиля.",
"advanced": "Дополнительно",
"personality": "Характер агента",
"modelBudget": "Модель и бюджет",
"skills": "Навыки",
"evolution": "Эволюция",
"capabilities": "Возможности",
"llmSeesAs": "LLM видит это как",
"prompt": {
"title": "Режим системного промпта"
},
"orchestration": {
"title": "Оркестрация",
"delegateTargets": "Цели делегирования",
"team": "Команда",
"noDelegates": "Стандартный режим запуска — делегирование не настроено"
},
"evolutionTab": {
"notEnabled": "Эволюция не включена",
"notEnabledHint": "Включите «Метрики эволюции» во вкладке «Агент», чтобы начать сбор данных.",
"toolSuccess": "Доля успешных вызовов инструментов",
"retrievalQuality": "Качество извлечения",
"noMetrics": "Данные метрик ещё не собраны",
"suggestions": "Предложения",
"noSuggestions": "Предложения ещё не сгенерированы",
"approve": "Одобрить",
"reject": "Отклонить",
"rollback": "Откатить",
"guardrails": "Ограничения адаптации",
"maxDelta": "Макс. дельта / цикл",
"minDataPoints": "Мин. точек данных",
"rollbackDrop": "Откат при падении"
},
"pinnedSkills": {
"title": "Закреплённые навыки",
"addPlaceholder": "Добавить навык...",
"hint": "Закреплённые навыки всегда встраиваются в системный промпт. Остальные используют skill_search."
}
},
"general": {
"selfEvolution": "Самоэволюция",
"selfEvolutionLabel": "Разрешить агенту развивать свой стиль общения",
"selfEvolutionHint": "Когда включено, агент может обновлять свой SOUL.md, чтобы уточнять тон, словарь и стиль ответов на основе взаимодействий. Идентичность, имя и рабочие инструкции остаются заблокированными.",
"selfEvolutionInfo": "Агент будет развивать свой стиль со временем через обновления SOUL.md. Затрагиваются только стиль и тон — идентичность и правила рабочего процесса остаются неизменными.",
"skillLearning": "Обучение навыкам",
"skillLearningLabel": "Разрешить агенту создавать навыки на основе опыта и управлять ими",
"skillLearningHint": "Когда включено, агент получает указания и мягкие напоминания фиксировать повторно используемые рабочие процессы как навыки после сложных задач. Инструмент skill_manage доступен по умолчанию.",
"skillLearningInfo": "После сложных задач агент может предложить сохранить рабочий процесс как повторно используемый навык. Перед созданием любого навыка всегда требуется одобрение пользователя. По умолчанию навыки приватны для владельца.",
"skillNudgeIntervalLabel": "Напоминать после N вызовов инструментов",
"skillNudgeIntervalHint": "После указанного числа вызовов инструментов агент предложит сохранить рабочий процесс как навык. Установите 0, чтобы отключить предложения после задач (указания в системном промпте по-прежнему показываются).",
"v3Flags": "Флаги движка V3",
"v3FlagsHint": "Эти флаги сохраняются независимо от конфигурации агента.",
"evolutionMetrics": "Метрики эволюции",
"evolutionMetricsLabel": "Собирать данные о доле успешных вызовов инструментов и качестве извлечения",
"evolutionSuggestions": "Предложения по эволюции",
"evolutionSuggestionsLabel": "Генерировать предложения по оптимизации на основе метрик",
"budget": "Месячный бюджет",
"budgetLabel": "Лимит бюджета (USD)",
"budgetHint": "Необязательный месячный лимит расходов. Агент будет отклонять запросы при превышении. Оставьте пустым для неограниченного.",
"saveChanges": "Сохранить изменения",
"saving": "Сохранение...",
"saved": "Сохранено",
"failedToSave": "Не удалось сохранить"
},
"identity": {
"title": "Идентичность",
"agentKey": "Ключ агента",
"agentKeyHint": "Уникальный идентификатор, нельзя изменить.",
"displayName": "Отображаемое имя",
"displayNamePlaceholder": "например Мой помощник",
"displayNameHint": "Дружелюбное имя, отображаемое в интерфейсе. Оставьте пустым, чтобы использовать ключ агента.",
"expertiseSummary": "Краткое описание экспертизы",
"expertiseSummaryPlaceholder": "например Астрология, гадание, гороскопы, нумерология",
"expertiseSummaryHint": "Краткое описание экспертизы этого агента. Используется для обнаружения при делегировании.",
"status": "Статус",
"active": "Активен",
"inactive": "Неактивен",
"summonFailed": "Призыв не удался",
"defaultAgent": "Агент по умолчанию",
"emoji": "Иконка",
"emojiHint": "Необязательная эмодзи-иконка"
},
"llmConfig": {
"title": "Конфигурация LLM",
"contextWindow": "Окно контекста",
"contextWindowHint": "Лимит токенов для контекста модели.",
"maxToolIterations": "Макс. итераций инструментов",
"maxToolIterationsHint": "Макс. вызовов инструментов на запрос."
},
"workspace": {
"title": "Рабочая область",
"workspacePath": "Путь рабочей области",
"workspacePathHint": "Назначается автоматически при создании агента. Подкаталоги для каждого пользователя создаются во время выполнения.",
"noWorkspace": "Рабочая область не настроена",
"restrictToWorkspace": "Ограничить рабочей областью",
"restrictToWorkspaceHint": "Строго ограничить доступ к файлам пределами пути рабочей области."
},
"config": {
"saveConfig": "Сохранить конфигурацию",
"saving": "Сохранение...",
"saved": "Сохранено",
"failedToSave": "Не удалось сохранить",
"usingGlobalDefaults": "Используются глобальные значения по умолчанию из config.json"
},
"files": {
"readOnly": "Только для чтения",
"readOnlyDesc": "Только владелец агента может редактировать предопределённые файлы контекста.",
"resummon": "Призвать заново",
"editWithAi": "Редактировать с ИИ",
"resummonTitle": "Призвать агента заново",
"resummonDesc": "Это заново сгенерирует SOUL.md, IDENTITY.md и, при необходимости, USER_PREDEFINED.md с нуля на основе исходного описания. Любые ручные правки этих файлов будут перезаписаны.",
"cancel": "Отмена",
"resummonConfirm": "Призвать заново",
"summoning": "Призыв...",
"selectFileToEdit": "Выберите файл для редактирования",
"selectFileToView": "Выберите файл для просмотра",
"saving": "Сохранение...",
"save": "Сохранить",
"loading": "Загрузка...",
"openAgentTitle": "Открытый агент — файлы контекста для каждого пользователя",
"openAgentDesc1": "Это открытый агент. Файлы контекста (AGENTS.md, SOUL.md, TOOLS.md и т. д.) персонализируются для каждого пользователя. Они автоматически создаются из шаблонов, когда пользователь впервые начинает чат с этим агентом.",
"openAgentDesc2pre": "Показанные здесь файлы уровня агента пусты, потому что открытые агенты хранят весь контекст для каждого пользователя в таблице ",
"openAgentDesc2post": ".",
"contextFiles": "Файлы контекста",
"contextFile": "Файл контекста",
"perUser": "для каждого пользователя",
"emptyFile": "пусто",
"estTokens": "Прибл. {{tokens}} токенов",
"insertContact": "Найдите контакт для вставки...",
"contentPlaceholder": "Содержимое файла..."
},
"fileEditor": {
"editWithAi": "Редактировать с ИИ",
"editAiDescription": "Опишите, что вы хотите изменить. ИИ прочитает текущие файлы и обновит их соответствующим образом.",
"editAiPlaceholder": "например Сделай агента более формальным, добавь поддержку вьетнамского языка, измени имя на Луна...",
"sending": "Отправка...",
"regenerate": "Сгенерировать заново",
"cancel": "Отмена"
},
"shares": {
"grantAccess": "Предоставить доступ",
"userId": "ID пользователя",
"userIdPlaceholder": "Найдите контакты или введите ID пользователя...",
"role": "Роль",
"share": "Поделиться",
"loadingShares": "Загрузка доступов...",
"noShares": "Пока нет доступов",
"noSharesDesc": "Поделитесь этим агентом с другими пользователями, введя их ID пользователя выше.",
"user": "Пользователь",
"revokeTitle": "Отозвать доступ",
"revokeDesc": "Отозвать доступ для пользователя «{{userId}}»? Он больше не сможет использовать этого агента.",
"revoke": "Отозвать",
"role.user": "Пользователь",
"role.viewer": "Наблюдатель",
"roleDesc.user": "Может использовать агента и общаться в чате",
"roleDesc.viewer": "Доступ только для чтения"
},
"links": {
"teamsHint": "Связи агентов скоро будут удалены. Пожалуйста, используйте команды агентов для совместной работы нескольких агентов — они обеспечивают отслеживание задач, общую рабочую область и контроль качества в более простой настройке.",
"createLink": "Создать связь",
"targetAgent": "Целевой агент",
"selectAgent": "Выберите или найдите агента...",
"direction": "Направление",
"description": "Описание",
"descriptionPlaceholder": "Необязательное описание связи...",
"maxConcurrent": "Макс. одновременно",
"advancedSettings": "Дополнительные настройки",
"allowedUsers": "Разрешённые пользователи",
"allowedUsersPlaceholder": "user1, user2, ...",
"allowedUsersHint": "Если задано, только эти пользователи могут инициировать это делегирование. Через запятую.",
"deniedUsers": "Запрещённые пользователи",
"deniedUsersPlaceholder": "user3, user4, ...",
"deniedUsersHint": "Этим пользователям запрещено инициировать это делегирование. Через запятую.",
"creating": "Создание...",
"noLinks": "Пока нет связей агентов",
"noLinksDesc": "Создавайте связи, чтобы агенты могли делегировать задачи друг другу.",
"loadingLinks": "Загрузка связей...",
"columns": {
"target": "Цель",
"direction": "Направление",
"status": "Статус",
"limit": "Лимит"
},
"deleteTitle": "Удалить связь",
"deleteDesc": "Удалить связь делегирования с «{{name}}»? Агенты больше не смогут делегировать друг другу через эту связь.",
"editTitle": "Редактировать связь",
"editDescription": "Обновите настройки связи делегирования.",
"optionalDescription": "Необязательное описание...",
"allowedUsersHintShort": "Если задано, только эти пользователи могут инициировать это делегирование.",
"deniedUsersHintShort": "Этим пользователям запрещено инициировать это делегирование."
},
"skills": {
"noSkillsAvailable": "Нет доступных навыков",
"noSkillsDesc": "Загрузите навыки на странице «Навыки», чтобы предоставить их агентам.",
"skillsGranted": "Предоставлено навыков: {{granted}} из {{total}}",
"filterSkills": "Фильтр навыков...",
"noSkillsMatch": "Нет навыков, соответствующих вашему запросу.",
"system": "Системный",
"alwaysAvailable": "Всегда доступен"
},
"instances": {
"loadingInstances": "Загрузка экземпляров...",
"noInstances": "Пока нет пользовательских экземпляров.",
"noInstancesDesc": "Экземпляры создаются, когда пользователи взаимодействуют с этим агентом.",
"instanceCount": "{{count}} экземпляр",
"instanceCount_plural": "{{count}} экземпляров",
"selectInstance": "Выберите экземпляр для просмотра и редактирования его USER.md",
"loading": "Загрузка...",
"saving": "Сохранение...",
"save": "Сохранить",
"saved": "Сохранено",
"searchContacts": "Найдите контакты для добавления...",
"noContactsFound": "Контакты не найдены"
},
"summoning": {
"title": "Призыв вашего агента...",
"completed": "Призыв завершён!",
"failed": "Призыв не удался",
"agentReady": "{{name}} готов!",
"weavingSoul": "Плетём душу",
"wait": "Обычно это занимает несколько минут. Пожалуйста, подождите...",
"continue": "Продолжить",
"retry": "Повторить",
"retrying": "Повторная попытка...",
"done": "готово",
"fileLabelSOUL": "Душа и характер",
"fileLabelIDENTITY": "Идентификационная карта"
},
"configGroups": {
"core": "Основные",
"coreDesc": "Ключевые настройки, напрямую влияющие на поведение агента",
"capabilities": "Возможности",
"capabilitiesDesc": "Функции, которые может использовать агент",
"performance": "Производительность",
"performanceDesc": "Управление контекстом и среда выполнения",
"advanced": "Качество и дополнительно",
"advancedDesc": "Обеспечение качества и пользовательская конфигурация"
},
"configSections": {
"subagents": {
"title": "Субагенты",
"description": "Управляет лимитами и поведением запуска субагентов",
"maxConcurrent": "Макс. одновременно",
"maxSpawnDepth": "Макс. глубина запуска",
"maxChildrenPerAgent": "Макс. дочерних на агента",
"archiveAfter": "Архивировать через (минуты)",
"modelOverride": "Переопределение модели",
"inheritFromAgent": "(наследовать от агента)"
},
"toolPolicy": {
"title": "Политика инструментов",
"description": "Управляйте тем, какие инструменты может использовать этот агент",
"profile": "Профиль",
"allow": "Разрешить",
"deny": "Запретить",
"alsoAllow": "Дополнительно разрешить",
"selectToolsAllow": "Выберите инструменты для разрешения...",
"selectToolsDeny": "Выберите инструменты для запрета...",
"selectToolsAlsoAllow": "Выберите дополнительные инструменты...",
"toolCallPrefix": "Префикс вызова инструмента",
"toolCallPrefixHint": "Удаляет этот префикс из имён вызовов инструментов модели перед поиском в реестре."
},
"workspaceSharing": {
"title": "Общий доступ к рабочей области",
"description": "Управляйте изоляцией файлов рабочей области между пользователями",
"sharedDm": "Общий доступ в личных сообщениях",
"sharedDmTip": "Все пользователи личных сообщений используют один каталог рабочей области вместо изолированных папок для каждого пользователя",
"sharedGroup": "Общий доступ в группах",
"sharedGroupTip": "Все участники группового чата используют один каталог рабочей области",
"sharedUsers": "Пользователи с общим доступом",
"sharedUsersTip": "Конкретные ID пользователей, которые всегда используют общую рабочую область независимо от настроек личных сообщений/групп. Формат: channel:userId (например telegram:386246614)",
"userIdPlaceholder": "Введите ID пользователя (например telegram:386246614)",
"warning": "Когда общий доступ включён, все пользователи с общим доступом могут читать и записывать файлы в одном каталоге рабочей области. Общий доступ к памяти управляется отдельно. Файлы контекста остаются изолированными для каждого пользователя.",
"memoryGroupLabel": "Память и граф знаний",
"folderGroupLabel": "Папки рабочей области",
"shareMemory": "Общая память и граф знаний",
"shareMemoryTip": "Все пользователи получают доступ к одной памяти и графу знаний. Независимо от общего доступа к папкам рабочей области. Когда выключено, у каждого пользователя своё изолированное пространство памяти.",
"shareMemoryNote": "Переключение этого параметра не переносит данные — существующая память отдельных пользователей становится недоступной в общем режиме."
},
"compaction": {
"title": "Сжатие",
"description": "Настройки сжатия окна контекста и сброса в память",
"maxHistoryShare": "Макс. доля истории (0-1)",
"maxHistoryShareTip": "Максимальная доля окна контекста для истории разговора (например 0.85 = 85%). Сжатие срабатывает при превышении.",
"keepLastMessages": "Сохранять последние сообщения",
"keepLastMessagesTip": "Недавние сообщения, сохраняемые после сжатия. Более старые сообщения заменяются сводкой.",
"memoryFlush": "Сброс в память",
"memoryFlushTip": "Перед сжатием агент получает ход, чтобы сохранить важный контекст в файлы памяти. Также запускает извлечение в граф знаний."
},
"contextPruning": {
"title": "Обрезка контекста",
"description": "Обрезать старые результаты инструментов для экономии окна контекста",
"mode": "Режим",
"keepLastAssistants": "Сохранять последние ответы ассистента",
"softTrimRatio": "Коэффициент мягкой обрезки (0-1)",
"hardClearRatio": "Коэффициент жёсткой очистки (0-1)",
"minPrunableToolChars": "Мин. символов инструмента для обрезки",
"softTrim": "Мягкая обрезка",
"maxChars": "Макс. символов",
"headChars": "Символов в начале",
"tailChars": "Символов в конце",
"hardClear": "Жёсткая очистка",
"enabled": "Включено",
"placeholderText": "Текст-заполнитель"
},
"sandbox": {
"title": "Песочница",
"description": "Docker-песочница для изоляции выполнения кода",
"mode": "Режим",
"workspaceAccess": "Доступ к рабочей области",
"image": "Образ",
"scope": "Область",
"timeout": "Тайм-аут (сек)",
"memoryMb": "Память (МБ)",
"cpus": "CPU",
"networkEnabled": "Сеть включена"
},
"memory": {
"title": "Память",
"description": "Настройка семантического поиска в памяти и эмбеддингов",
"enabled": "Включено",
"enabledTip": "Включить или отключить систему памяти для этого агента.",
"maxChunkLen": "Макс. длина фрагмента",
"maxChunkLenTip": "Максимум символов на фрагмент памяти. Оставьте пустым для системного значения по умолчанию.",
"chunkOverlap": "Перекрытие фрагментов",
"chunkOverlapTip": "Перекрытие символов между фрагментами для непрерывности контекста. Оставьте пустым для системного значения по умолчанию.",
"maxResults": "Макс. результатов",
"maxResultsTip": "Максимум записей памяти, возвращаемых на поисковый запрос.",
"minScore": "Мин. оценка",
"minScoreTip": "Минимальная оценка релевантности для результатов поиска.",
"vectorWeight": "Вес вектора",
"vectorWeightTip": "Вес семантического сходства в гибридном поиске.",
"textWeight": "Вес текста",
"textWeightTip": "Вес сходства по ключевым словам в гибридном поиске."
},
"thinking": {
"title": "Расширенное мышление",
"description": "Разрешить модели рассуждать перед ответом. Более высокие уровни используют больше токенов, но дают лучшие результаты в сложных задачах.",
"thinkingLevel": "Уровень мышления",
"off": "Выключено",
"offDesc": "Без расширенного мышления",
"low": "Низкий",
"lowDesc": "Бюджет ~4K токенов",
"medium": "Средний",
"mediumDesc": "Бюджет ~10-16K токенов",
"high": "Высокий",
"highDesc": "Бюджет ~32K токенов"
},
"otherConfig": {
"title": "Другая конфигурация",
"description": "Дополнительная конфигурация в JSON для расширенных настроек, не охваченных другими разделами",
"formatJson": "Форматировать JSON",
"invalidJson": "Некорректный синтаксис JSON"
}
},
"heartbeat": {
"title": "Heartbeat",
"loading": "Загрузка heartbeat...",
"notConfigured": "Расписание heartbeat не настроено. Настройте его, чтобы запускать этого агента в автоматическом режиме.",
"setupButton": "Настроить heartbeat",
"toggleEnabled": "Переключить включение heartbeat",
"every": "Каждые {{interval}} мин",
"lastRun": "Последний",
"nextRun": "Следующий",
"runs": "Запуски",
"suppressed": "Подавлено",
"configure": "Настроить",
"logs": "Логи",
"configTitle": "Конфигурация heartbeat",
"enabled": "Включено",
"enabledHint": "Когда включено, агент запускается с заданным интервалом.",
"sectionTiming": "Тайминг",
"interval": "Интервал (секунды)",
"intervalHint": "Минимум 300 секунд (5 минут).",
"maxRetries": "Макс. повторов",
"maxRetriesHint": "0–10 повторов при сбое.",
"ackMaxChars": "Макс. символов подтверждения",
"ackMaxCharsHint": "Макс. символов в ответе-подтверждении. 0 = без ответа.",
"sectionBehavior": "Поведение",
"isolatedSession": "Изолированная сессия",
"isolatedSessionHint": "Запускать в новой сессии, не продолжая последний разговор.",
"lightContext": "Лёгкий контекст",
"lightContextHint": "Пропускать загрузку полных файлов контекста для снижения расхода токенов.",
"sectionSchedule": "Расписание",
"activeHoursStart": "Активен с (ЧЧ:ММ)",
"activeHoursEnd": "Активен до (ЧЧ:ММ)",
"timezone": "Часовой пояс",
"sectionModel": "Модель",
"modelHint": "Переопределить провайдера/модель для запусков heartbeat. Оставьте пустым для использования значений агента по умолчанию.",
"sectionDelivery": "Доставка",
"channel": "Канал",
"channelPlaceholder": "Выберите канал",
"channelNone": "Нет (без доставки)",
"channelHint": "например telegram, feishu. Оставьте пустым для отключения доставки.",
"chatId": "ID чата",
"chatIdPlaceholder": "Выберите чат",
"selectChannelFirst": "Сначала выберите канал",
"checklist": "Чек-лист (HEARTBEAT.md)",
"checklistHint": "Инструкции, внедряемые в каждый запуск heartbeat. Поддерживает markdown.",
"checklistLoading": "Загрузка чек-листа...",
"checklistPlaceholder": "# Чек-лист heartbeat\n\n- Проверить ожидающие задачи\n- Отчитаться о статусе\n",
"on": "Вкл",
"off": "Выкл",
"notSet": "Не задано",
"disabled": "Heartbeat отключён",
"nextIn": "Следующий через {{time}}",
"advancedSettings": "Дополнительные настройки",
"scheduleHint": "Оставьте пустым для работы 24/7.",
"testRun": "Тестовый запуск",
"cancel": "Отмена",
"save": "Сохранить",
"saving": "Сохранение...",
"logsTitle": "Логи heartbeat",
"refresh": "Обновить",
"noLogs": "Пока нет логов heartbeat.",
"logsPagination": "{{from}}–{{to}} из {{total}}"
},
"permissions": {
"title": "Разрешения",
"description": "Управляйте тем, кто может изменять конфигурацию и файлы агента. Владелец всегда имеет полный доступ.",
"addRule": "Добавить правило",
"fileWriters": "Редакторы файлов",
"configPerms": "Разрешения конфигурации",
"noRules": "Нет правил разрешений. Владелец имеет неявный полный доступ.",
"userIdPlaceholder": "Найдите контакты или введите ID...",
"scopePlaceholder": "Выберите или введите область...",
"types": {
"file_writer": "Редактор файлов",
"file_writer_desc": "Управляет тем, кто может редактировать файлы и управлять cron в групповых чатах. Первый пользователь добавляется автоматически.",
"heartbeat": "Heartbeat",
"heartbeat_desc": "Управляет тем, кто может настраивать расписание и параметры heartbeat через чат.",
"cron": "Cron",
"cron_desc": "Управляет тем, кто может создавать и управлять запланированными cron-задачами через чат.",
"context_files": "Файлы контекста",
"context_files_desc": "Управляет тем, кто может изменять файлы идентичности агента (SOUL.md и т. д.) через чат.",
"all": "Все (*)",
"all_desc": "Полный доступ ко всем типам конфигурации."
},
"scopes": {
"agent": "Агент (только личные сообщения)",
"group_all": "Все группы",
"global": "Глобально (все контексты)"
}
},
"toast": {
"created": "Агент создан",
"createFailed": "Не удалось создать агента",
"updated": "Агент обновлён",
"updateFailed": "Не удалось обновить агента",
"deleted": "Агент удалён",
"deleteFailed": "Не удалось удалить агента",
"unknownError": "Неизвестная ошибка",
"skillGranted": "Навык предоставлен",
"skillGrantFailed": "Не удалось предоставить навык",
"skillRevoked": "Навык отозван",
"skillRevokeFailed": "Не удалось отозвать навык"
}
}
@@ -0,0 +1,157 @@
{
"title": "Каналы",
"description": "Подключите мессенджеры к вашим агентам",
"addChannel": "Добавить канал",
"atLimit": "Редакция Lite: максимум 1 Telegram + 1 Discord.",
"emptyTitle": "Нет каналов",
"emptyDesc": "Подключите Telegram или Discord, чтобы общаться с вашими агентами из мессенджеров.",
"status": {
"running": "Работает",
"stopped": "Остановлен",
"disabled": "Отключён",
"degraded": "Ограничен",
"starting": "Запуск",
"registered": "Настроен",
"failed": "Ошибка"
},
"channelTypes": {
"telegram": "Telegram",
"discord": "Discord"
},
"form": {
"createTitle": "Добавить канал",
"displayName": "Отображаемое имя",
"displayNamePlaceholder": "Мой Telegram-бот",
"channelType": "Тип канала",
"selectType": "Выберите тип",
"agent": "Агент",
"selectAgent": "Выберите агента",
"enabled": "Включён",
"credentials": "Учётные данные",
"credentialsHint": "(оставьте пустым, чтобы сохранить текущие)",
"configuration": "Конфигурация",
"cancel": "Отмена",
"save": "Сохранить",
"create": "Создать",
"saving": "Сохранение...",
"errors": {
"agentRequired": "Требуется агент",
"typeRequired": "Требуется тип канала",
"tokenRequired": "Требуется токен бота"
}
},
"detail": {
"back": "Назад",
"lastChecked": "Последняя проверка: {{value}}",
"tabs": {
"general": "Общие",
"credentials": "Учётные данные",
"managers": "Менеджеры",
"advanced": "Дополнительно"
},
"general": {
"identity": "Идентификация",
"name": "Имя",
"nameHint": "Идентификатор-slug только для чтения",
"channelType": "Тип канала",
"displayName": "Отображаемое имя",
"displayNamePlaceholder": "Введите отображаемое имя",
"agent": "Агент",
"selectAgent": "Выберите агента",
"enabled": "Включён",
"saveChanges": "Сохранить изменения",
"saving": "Сохранение..."
},
"policies": "Политики",
"credentials": {
"hint": "Оставьте поля пустыми, чтобы сохранить текущие значения. Учётные данные хранятся в зашифрованном виде.",
"updateCredentials": "Обновить учётные данные",
"saving": "Сохранение...",
"saved": "Учётные данные обновлены"
},
"managers": {
"description": "Назначайте пользователей менеджерами групп канала. Менеджеры могут модерировать переписку.",
"groups": "Группы",
"noManagerGroups": "Пока нет групп менеджеров",
"noManagerGroupsHint": "Группы появятся здесь, когда пользователи начнут взаимодействовать с ботом в групповых чатах.",
"loadingManagers": "Загрузка менеджеров...",
"noManagers": "В этой группе нет менеджеров",
"managersCount": "{{count}} менеджер",
"managersCountPlural": "{{count}} менеджеров",
"columns": {
"userId": "ID пользователя",
"name": "Имя",
"username": "Имя пользователя"
},
"addForm": {
"title": "Добавить менеджера",
"hint": "Введите данные группы и пользователя, чтобы добавить менеджера",
"groupId": "ID группы",
"groupIdPlaceholder": "например group:telegram:-100123456",
"userId": "ID пользователя",
"userIdPlaceholder": "Найдите или введите ID пользователя",
"addManager": "Добавить менеджера",
"add": "Добавить",
"errors": {
"groupUserRequired": "Требуются ID группы и ID пользователя",
"failedAdd": "Не удалось добавить менеджера"
}
}
},
"advanced": "Дополнительно",
"advancedTitle": "Дополнительные настройки",
"network": "Сеть",
"networkDesc": "Настройка API-сервера и прокси",
"limits": "Ограничения",
"limitsDesc": "Ограничения сообщений и медиа",
"streaming": "Потоковая передача",
"streamingDesc": "Постепенная доставка ответа",
"behavior": "Поведение",
"behaviorDesc": "Реакции, предпросмотр и режим ответа",
"accessControl": "Контроль доступа",
"accessControlDesc": "Ограничения по списку разрешённых пользователей",
"saveConfig": "Сохранить",
"noAdvanced": "Для этого типа канала нет дополнительных настроек."
},
"pairing": {
"title": "Привязанные устройства",
"pending": "Ожидающие запросы ({{count}})",
"paired": "Привязанные устройства ({{count}})",
"empty": "Нет привязанных устройств",
"emptyDesc": "Устройства появятся здесь, когда пользователи напишут вашему боту и потребуется подтверждение.",
"sender": "Отправитель: ",
"chat": "Чат: ",
"code": "Код",
"approve": "Одобрить",
"deny": "Отклонить",
"revoke": "Отозвать",
"confirmApprove": {
"title": "Одобрить привязку",
"description": "Одобрить {{channel}}:{{senderId}} (код: {{code}})? Это устройство сможет взаимодействовать с агентами.",
"confirmLabel": "Одобрить"
},
"confirmDeny": {
"title": "Отклонить привязку",
"description": "Отклонить {{channel}}:{{senderId}} (код: {{code}})? Запрос будет удалён.",
"confirmLabel": "Отклонить"
},
"confirmRevoke": {
"title": "Отозвать устройство",
"description": "Отозвать {{channel}}:{{senderId}}? Устройству потребуется повторная привязка.",
"confirmLabel": "Отозвать"
}
},
"toast": {
"created": "Канал создан",
"updated": "Канал обновлён",
"deleted": "Канал удалён",
"failedCreate": "Не удалось создать канал",
"failedUpdate": "Не удалось обновить канал",
"failedDelete": "Не удалось удалить канал"
},
"delete": {
"title": "Удалить канал",
"description": "Удалить {{name}}? Это действие нельзя отменить.",
"confirmLabel": "Удалить"
}
}
@@ -0,0 +1,25 @@
{
"deleteChat": "Удалить чат",
"deleteChatConfirm": "Это навсегда удалит этот разговор и все его сообщения.",
"newChat": "Новый чат",
"openSessions": "Открытые сессии",
"readOnly": "Только для чтения — эта сессия принадлежит другому пользователю",
"empty": {
"title": "Начните разговор",
"description": "Отправьте сообщение, чтобы начать общение с агентом."
},
"media": {
"image": "Изображение",
"video": "Видео",
"audio": "Аудио",
"voice": "Голосовое сообщение",
"document": "Документ",
"animation": "Анимация",
"attached": "прикреплено"
},
"forwardedFrom": "Переслано от",
"replyingTo": "Ответ на",
"error": {
"notConnected": "Нет соединения. Пожалуйста, дождитесь установления соединения."
}
}
@@ -0,0 +1,150 @@
{
"refresh": "Обновить",
"cancel": "Отмена",
"confirm": "Подтвердить",
"delete": "Удалить",
"save": "Сохранить",
"edit": "Редактировать",
"create": "Создать",
"add": "Добавить",
"view": "Просмотр",
"filter": "Фильтр",
"search": "Поиск",
"retry": "Повторить",
"manage": "Управление",
"uploadLabel": "Загрузить",
"close": "Закрыть",
"back": "Назад",
"update": "Обновить",
"enabled": "Включено",
"disabled": "Отключено",
"yes": "Да",
"no": "Нет",
"loading": "Загрузка...",
"saving": "Сохранение...",
"creating": "Создание...",
"connecting": "Подключение...",
"connected": "Подключено",
"disconnected": "Отключено",
"running": "Выполняется",
"stopped": "Остановлено",
"pending": "В ожидании",
"completed": "Завершено",
"failed": "Ошибка",
"cancelled": "Отменено",
"unknown": "Неизвестно",
"active": "активно",
"items": "элементов",
"rows": "Строки",
"pageOf": "Страница {{page}} из {{totalPages}}",
"messages": "сообщения",
"cached": "из кэша",
"live": "В реальном времени",
"noDescription": "Нет описания",
"unsavedChanges": "Несохранённые изменения",
"tryDifferentSearch": "Попробуйте другой поисковый запрос.",
"notSet": "Не задано",
"default": "по умолчанию",
"optional": "необязательно",
"required": "обязательно",
"actions": "Действия",
"status": "Статус",
"name": "Имя",
"description": "Описание",
"type": "Тип",
"none": "нет",
"all": "Все",
"global": "Глобальный",
"agent": "Агент",
"saved": "Сохранено",
"saveChanges": "Сохранить изменения",
"saveConfig": "Сохранить конфигурацию",
"checkAndCreate": "Проверить и создать",
"checking": "Проверка...",
"format": "Форматировать JSON",
"invalidJson": "Некорректный синтаксис JSON",
"usingGlobalDefaults": "Используются глобальные значения по умолчанию из config.json",
"disconnectedGateway": "Соединение со шлюзом потеряно. Попытка переподключения...",
"serverUnreachable": "Сервер недоступен",
"serverUnreachableDesc": "Не удаётся подключиться к серверу шлюза. Убедитесь, что сервер запущен.",
"reconnecting": "Переподключение...",
"noFiles": "Файлы не найдены.",
"selectFileToView": "Выберите файл, чтобы просмотреть его содержимое",
"typeToConfirmPrefix": "Введите",
"typeToConfirmSuffix": "для подтверждения.",
"searchPlaceholder": "Поиск...",
"noSessions": "Пока нет сессий. Начните чат!",
"noAgentsAvailable": "Нет доступных агентов",
"selectAgent": "Выберите агента",
"sendMessage": "Отправить сообщение... (Shift+Enter для новой строки)",
"stopGeneration": "Остановить генерацию",
"sendMessageTitle": "Отправить сообщение",
"sendFollowUp": "Отправить дополнительное сообщение",
"attachFile": "Прикрепить файл",
"thinking": "Размышление",
"thinkingStreaming": "Размышление...",
"toolArguments": "Аргументы",
"toolResult": "Результат",
"skillActivating": "Активация...",
"skillActivated": "Активирован",
"toolRunning": "Выполнение...",
"toolDone": "Готово",
"toolFailed": "Ошибка",
"filesBack": "Файлы",
"noProvidersConfigured": "Нет настроенных провайдеров",
"loadingModels": "Загрузка моделей...",
"modelVerified": "Модель проверена",
"verificationFailed": "Проверка не удалась",
"provider": "Провайдер",
"model": "Модель",
"selectProvider": "Выберите провайдера",
"enterOrSelectModel": "Введите или выберите модель",
"useCustomModel": "Использовать свою:",
"providerTip": "Имя провайдера LLM. Должно совпадать с настроенным провайдером.",
"modelTip": "ID используемой модели.",
"check": "Проверить",
"builtinTools": "Встроенные",
"customTools": "Пользовательские",
"selectOrTypeTools": "Выберите или введите имена инструментов...",
"selectOrTypeSkills": "Выберите или введите имена навыков...",
"typeAndPressEnter": "Введите и нажмите Enter...",
"copyCode": "Копировать код",
"copy": "Копировать",
"download": "Скачать",
"errorBoundary": "Что-то пошло не так при отрисовке этого раздела.",
"csvRows": "csv ({{count}} строк)",
"failedToLoadImage": "Не удалось загрузить изображение",
"deleteFolder": "Удалить папку",
"deleteFile": "Удалить файл",
"loadMore": "Загрузить ещё...",
"viewCard": "Вид карточками",
"viewList": "Вид списком",
"done": "Готово",
"continue": "Продолжить",
"providerType": "Тип провайдера",
"apiKey": "API-ключ",
"apiKeyRequired": "API-ключ обязателен",
"apiBaseUrl": "Базовый URL API",
"noApiKeyRequired": "Для {{provider}} API-ключ не требуется.",
"searchProviders": "Поиск провайдеров...",
"noModelsManualEntry": "API не вернул моделей. Вы можете ввести имя модели вручную.",
"modelVerifiedWith": "{{model}} работает с {{provider}}",
"failedToCreateProvider": "Не удалось создать провайдера",
"failedToCreateAgent": "Не удалось создать агента",
"upload": {
"title": "Загрузка файлов",
"dropOrClick": "Перетащите файлы сюда или нажмите для выбора",
"dropHere": "Перетащите файлы сюда",
"maxSize": "Максимум 50 МБ на файл",
"blockedType": "Тип файла {{ext}} не разрешён",
"tooLarge": "Файл превышает лимит 50 МБ",
"failed": "Не удалось загрузить",
"readyCount": "{{ready}} из {{total}} файлов готово",
"successCount": "{{success}} из {{total}} файлов загружено",
"uploading": "Загрузка...",
"uploadCount": "Загрузить файлов: {{count}}"
},
"errors": {
"serverError": "Что-то пошло не так. Пожалуйста, повторите попытку позже."
}
}
@@ -0,0 +1,149 @@
{
"title": "Cron",
"description": "Планирование повторяющихся задач агентов",
"newJob": "Новое задание",
"emptyTitle": "Нет заданий cron",
"emptyDescription": "Создайте задание cron для планирования повторяющихся задач агентов.",
"columns": {
"enabled": "Включено",
"name": "Имя",
"schedule": "Расписание",
"message": "Сообщение",
"agent": "Агент",
"actions": "Действия"
},
"runNow": "Запустить сейчас",
"running": "Выполняется...",
"runHistory": "История запусков",
"defaultAgent": "по умолчанию",
"searchPlaceholder": "Поиск заданий cron...",
"noMatchTitle": "Нет подходящих заданий",
"noMatchDescription": "Попробуйте другой поисковый запрос.",
"card": {
"nextRun": "Следующий: {{time}}",
"noNextRun": "Нет следующего запуска",
"defaultAgent": "Агент по умолчанию"
},
"create": {
"title": "Создать задание cron",
"name": "Имя",
"namePlaceholder": "my-daily-task",
"nameHint": "Только строчные буквы, цифры и дефисы",
"agentId": "ID агента (необязательно)",
"agentIdPlaceholder": "default",
"scheduleType": "Тип расписания",
"every": "Каждые",
"cron": "Cron",
"once": "Однократно",
"intervalSeconds": "Интервал (секунды)",
"cronExpression": "Cron-выражение",
"cronHint": "Стандартный cron из 5 полей: мин час день месяц день_недели",
"onceDesc": "Задание будет выполнено один раз, примерно через 1 минуту.",
"message": "Сообщение",
"messagePlaceholder": "Что должен сделать агент?",
"cancel": "Отмена",
"create": "Создать",
"creating": "Создание..."
},
"enable": {
"title": "Включить задание cron",
"description": "Включить «{{name}}»? Оно начнёт выполняться по расписанию.",
"confirmLabel": "Включить"
},
"disable": {
"title": "Отключить задание cron",
"description": "Отключить «{{name}}»? Оно перестанет выполняться до повторного включения.",
"confirmLabel": "Отключить"
},
"delete": {
"title": "Удалить задание cron",
"description": "Удалить «{{name}}»? Это действие нельзя отменить.",
"confirmLabel": "Удалить"
},
"runLog": {
"title": "Журнал запусков: {{name}}",
"noHistory": "Пока нет истории запусков.",
"loading": "Загрузка..."
},
"detail": {
"runNow": "Запустить сейчас",
"running": "Выполняется...",
"disable": "Отключить",
"enable": "Включить",
"delete": "Удалить",
"enabled": "включено",
"disabled": "отключено",
"runningStatus": "выполняется...",
"payload": "Полезная нагрузка",
"empty": "(пусто)",
"deliverDirect": "Доставка: напрямую",
"channel": "Канал: {{name}}",
"to": "Кому: {{name}}",
"edit": "Редактировать",
"preview": "Предпросмотр",
"noMessage": "Сообщение не настроено",
"lastError": "Последняя ошибка",
"runHistory": "История запусков",
"refresh": "Обновить",
"noHistory": "Пока нет истории запусков.",
"inOut": "{{input}} вход / {{output}} выход",
"infoRows": {
"schedule": "Расписание",
"timezone": "Часовой пояс",
"nextRun": "Следующий запуск",
"lastRun": "Последний запуск",
"lastStatus": "Последний статус",
"created": "Создано",
"updated": "Обновлено",
"autoDelete": "Автоудаление",
"autoDeleteValue": "Да (однократно)"
},
"tabs": {
"overview": "Обзор",
"history": "История запусков"
},
"advanced": "Дополнительно",
"saveFailed": "Не удалось сохранить",
"schedule": "Расписание",
"scheduleDesc": "Настройка времени",
"messageSection": "Сообщение",
"messageSectionDesc": "Что должен сделать агент",
"agentStatus": "Агент и статус",
"agentStatusDesc": "Назначение агента и статус задания",
"info": "Информация",
"infoDesc": "Метаданные задания",
"scheduling": "Планирование",
"schedulingDesc": "Настройка часового пояса",
"delivery": "Доставка",
"deliveryDesc": "Направить вывод задания в канал или пользователю",
"deliverToChannel": "Доставить в канал",
"channelLabel": "Канал",
"channelPlaceholder": "#general",
"toLabel": "Кому (пользователь)",
"toPlaceholder": "user-id",
"wakeHeartbeat": "Пробуждать heartbeat при запуске",
"wakeHeartbeatDesc": "Запускать heartbeat агента при выполнении задания",
"lifecycle": "Жизненный цикл",
"lifecycleDesc": "Настройки жизненного цикла задания",
"deleteAfterRun": "Удалить после запуска",
"deleteAfterRunDesc": "Автоматически удалить это задание после первого успешного запуска",
"timezone": "Часовой пояс",
"timezoneDesc": "Часовой пояс для cron-выражений"
},
"stateless": "Без сохранения состояния",
"statelessHelp": "Пропустить сохранение сессии. Каждый запуск начинается заново без загрузки предыдущих сообщений. Экономит токены для заданий cron, которым не нужен прошлый контекст.",
"toast": {
"created": "Задание cron создано",
"createdDesc": "{{name}} добавлено",
"enabled": "Задание cron включено",
"disabled": "Задание cron отключено",
"deleted": "Задание cron удалено",
"triggered": "Задание cron запущено",
"failedCreate": "Не удалось создать задание cron",
"failedToggle": "Не удалось переключить задание cron",
"failedDelete": "Не удалось удалить задание cron",
"failedRun": "Не удалось запустить задание cron",
"updated": "Задание обновлено",
"failedUpdate": "Не удалось обновить задание"
}
}
@@ -0,0 +1,162 @@
{
"onboarding": {
"welcome": "Настройка GoClaw",
"welcomeDesc": "Давайте запустим ваш шлюз",
"providerStep": "Настройка провайдера",
"providerStepDesc": "Выберите AI-провайдера и введите свои учётные данные.",
"modelStep": "Выбор и проверка модели",
"modelStepDesc": "Выберите модель и проверьте соединение.",
"agentStep": "Создайте своего агента",
"agentStepDesc": "Придайте вашему агенту характер.",
"descPlaceholder": "Опишите характер вашего агента...",
"complete": "Настройка завершена",
"stepProvider": "Провайдер",
"stepModel": "Модель",
"stepAgent": "Агент",
"createProvider": "Создать провайдера"
},
"summoning": {
"title": "Призыв агента",
"weavingSoul": "Плетём душу для {{name}}",
"completed": "Агент готов!",
"completedTitle": "Агент готов!",
"failedTitle": "Призыв не удался",
"failed": "Призыв не удался",
"wait": "Это может занять некоторое время",
"fileLabelSOUL": "Основной характер",
"fileLabelIDENTITY": "Идентичность и знания",
"agentReady": "{{name}} готов!",
"retrying": "Повторная попытка...",
"takingTooLong": "Слишком долго?",
"cancel": "Отмена",
"cancelling": "Отмена..."
},
"settings": {
"title": "Настройки",
"tabs": {
"appearance": "Внешний вид",
"providers": "Провайдеры",
"agents": "Агенты",
"channels": "Каналы",
"mcp": "MCP",
"skills": "Навыки",
"tools": "Инструменты",
"cron": "Cron",
"traces": "Трассировки",
"storage": "Хранилище",
"about": "О программе"
},
"theme": "Тема",
"dark": "Тёмная",
"light": "Светлая",
"language": "Язык",
"timezone": "Часовой пояс",
"timezoneHint": "Измените часовой пояс с помощью значка часов в верхней панели."
},
"sidebar": {
"newChat": "Новый чат",
"connected": "Подключено",
"offline": "Не в сети",
"lightMode": "Светлый режим",
"darkMode": "Тёмный режим",
"settings": "Настройки",
"teams": "Команды"
},
"about": {
"title": "GoClaw Lite",
"subtitle": "Настольная редакция",
"version": "Версия",
"edition": "Редакция",
"runtime": "Среда выполнения",
"runtimeValue": "Wails v2",
"editionLimits": "Ограничения редакции",
"agents": "Агенты",
"teams": "Команды",
"teamMembers": "Участники команды",
"database": "База данных",
"users": "Пользователи",
"maxAgents": "макс. 5",
"maxTeams": "макс. 1",
"maxTeamMembers": "макс. 5",
"databaseValue": "SQLite (локально)",
"usersValue": "Один пользователь",
"builtWith": "Создано на Go + React + Wails",
"reset": {
"title": "Опасная зона",
"description": "Удалить базу данных и перезапустить приложение. Все агенты, сессии, провайдеры и настройки будут безвозвратно потеряны.",
"button": "Сбросить базу данных",
"confirmTitle": "Сбросить базу данных?",
"confirmDescription": "Это удалит все ваши данные и перезапустит приложение с нуля.",
"confirmPrompt": "Введите {{word}} для подтверждения",
"cancel": "Отмена",
"confirm": "Сбросить и перезапустить",
"resetting": "Сброс..."
}
},
"presets": {
"researcher": {
"label": "🔬 Исследователь",
"prompt": "Имя: Учёный. Дотошный аналитик-исследователь, который не оставляет камня на камне.\nХарактер: Методичный, тщательный и точный. Представляет информацию в хорошо структурированных отчётах со ссылками на источники. Сочетает глубину с ясностью.\n\nНазначение: Глубокие исследования в любой области — научные статьи, анализ рынка, технические расследования. Синтезирует множество источников в применимые на практике выводы. Всегда отличает факты от мнений."
},
"writer": {
"label": "✍️ Писатель",
"prompt": "Имя: Перо. Разносторонний писатель, адаптирующий голос и тон под любую аудиторию.\nХарактер: Творческий, красноречивый и чуткий. Понимает силу слов. Сочетает ясность с изяществом.\n\nНазначение: Специалист по созданию контента — статьи в блог, публикации, копирайтинг, сторителлинг, техническое письмо. Умело выстраивает аргументацию, создаёт повествования и сохраняет единый тон в длинных текстах."
},
"coder": {
"label": "👨‍💻 Программист",
"prompt": "Имя: Дев. Старший инженер-программист с глубоким опытом во всём стеке.\nХарактер: Прагматичный и эффективный. Пишет чистый, поддерживаемый код. Просто объясняет сложные концепции. Следует лучшим практикам, но знает, когда стоит отступить от правил.\n\nНазначение: Ревью кода, проектирование архитектуры, отладка, реализация. Владеет несколькими языками и фреймворками. Ставит в приоритет корректность, производительность и безопасность."
}
},
"agent": {
"summon": "Призвать",
"summoning": "Призыв...",
"verifyModel": "Проверить модель",
"verifying": "Проверка...",
"verified": "Проверено",
"verifyFailed": "Проверка не удалась"
},
"chat": {
"emptyTitle": "Чат с {{name}}",
"emptyTitleDefault": "Начните разговор",
"emptyDescAgent": "Задайте вопрос, напишите что-нибудь или исследуйте идеи.",
"emptyDescNoAgent": "Выберите агента на боковой панели, чтобы начать.",
"suggestions": ["Какие последние новости на сегодня?", "Расскажи анекдот", "Придумай идеи для эпохи ИИ"]
},
"activity": {
"thinking": "Думает",
"executingTool": "Выполняет инструмент",
"compacting": "Сжатие контекста",
"streaming": "Потоковая передача",
"retrying": "Повторная попытка",
"processing": "Обработка",
"runningTool": "Выполняется {{tool}}",
"retryingAttempt": "Повтор (попытка {{n}})",
"step": "шаг {{n}}"
},
"toast": {
"agentCreated": "Агент создан",
"agentUpdated": "Агент обновлён",
"agentDeleted": "Агент удалён",
"providerCreated": "Провайдер создан",
"providerUpdated": "Провайдер обновлён",
"providerDeleted": "Провайдер удалён",
"serverCreated": "MCP-сервер создан",
"serverUpdated": "MCP-сервер обновлён",
"serverDeleted": "MCP-сервер удалён",
"skillUploaded": "Навык загружен",
"skillDeleted": "Навык удалён",
"grantUpdated": "Разрешение обновлено",
"saveFailed": "Не удалось сохранить",
"deleteFailed": "Не удалось удалить",
"createFailed": "Не удалось создать"
},
"update": {
"available": "Доступна GoClaw Lite v{{version}}",
"now": "Обновить сейчас",
"downloading": "Загрузка обновления...",
"ready": "Обновление установлено! Перезапустите для применения.",
"restart": "Перезапустить сейчас",
"failed": "Не удалось обновить.",
"retry": "Повторить"
}
}
@@ -0,0 +1,132 @@
{
"title": "MCP-серверы",
"description": "Управление подключениями к серверам Model Context Protocol",
"addServer": "Добавить сервер",
"searchPlaceholder": "Поиск серверов...",
"emptyTitle": "Нет MCP-серверов",
"emptyDescription": "Добавьте свой первый MCP-сервер, чтобы начать.",
"noMatchTitle": "Нет подходящих серверов",
"noMatchDescription": "Попробуйте другой поисковый запрос.",
"columns": {
"name": "Имя",
"transport": "Транспорт",
"tools": "Инструменты",
"agents": "Агенты",
"enabled": "Включено",
"createdBy": "Создатель",
"actions": "Действия"
},
"viewTools": "Просмотр инструментов",
"manageGrants": "Управление доступом",
"reconnect": "Переподключить",
"delete": {
"title": "Удалить MCP-сервер",
"description": "Вы уверены, что хотите удалить «{{name}}»? Это также удалит все связанные разрешения доступа.",
"confirmLabel": "Удалить"
},
"form": {
"createTitle": "Добавить MCP-сервер",
"editTitle": "Редактировать MCP-сервер",
"name": "Имя *",
"nameHint": "Только строчные буквы, цифры и дефисы",
"displayName": "Отображаемое имя",
"displayNamePlaceholder": "Мой MCP-сервер",
"transport": "Транспорт *",
"command": "Команда *",
"args": "Аргументы (через пробел)",
"argsPlaceholder": "--flag1 --flag2=\"value with spaces\"",
"url": "URL *",
"headers": "Заголовки",
"headerKeyPlaceholder": "Имя заголовка",
"headerValuePlaceholder": "Значение заголовка",
"addHeader": "Добавить заголовок",
"env": "Переменные окружения",
"envKeyPlaceholder": "Имя переменной",
"envValuePlaceholder": "Значение",
"addVariable": "Добавить переменную",
"toolPrefix": "Префикс инструментов",
"toolPrefixHint": "Автоматически выводится из имени, если пусто.",
"timeout": "Тайм-аут (секунды)",
"enabled": "Включено",
"testConnection": "Проверить подключение",
"testing": "Проверка...",
"toolsFound": "Найдено инструментов: {{count}}",
"cancel": "Отмена",
"create": "Создать",
"update": "Обновить",
"saving": "Сохранение...",
"errors": {
"nameRequired": "Имя и транспорт обязательны",
"nameSlug": "Имя должно быть корректным slug (только строчные буквы, цифры, дефисы)",
"commandRequired": "Для транспорта stdio требуется команда",
"urlRequired": "Для транспорта SSE/HTTP требуется URL",
"connectionFailed": "Не удалось подключиться"
},
"requireUserCredentials": "Требовать учётные данные пользователя",
"requireUserCredentialsHint": "Каждый пользователь должен настроить свои собственные учётные данные. Сервер отключён для пользователей без личных учётных данных."
},
"grants": {
"title": "Разрешения агентов — {{name}}",
"currentGrants": "Текущие разрешения",
"allToolsAllowed": "Разрешены все инструменты",
"addGrant": "Добавить разрешение агенту",
"editGrant": "Редактировать разрешение",
"selectAgent": "Выберите агента...",
"toolAllowList": "Список разрешённых инструментов (необязательно)",
"toolDenyList": "Список запрещённых инструментов (необязательно)",
"allowPlaceholder": "Выберите инструменты для разрешения...",
"denyPlaceholder": "Выберите инструменты для запрета...",
"grant": "Предоставить",
"revoke": "Отозвать",
"noAgentsGranted": "Ни одному агенту не предоставлен доступ",
"update": "Обновить",
"cancel": "Отмена",
"agentRequired": "Агент обязателен",
"failedGrant": "Не удалось предоставить доступ",
"failedRevoke": "Не удалось отозвать доступ"
},
"tools": {
"title": "Инструменты — {{name}}",
"prefix": "префикс:",
"discovering": "Обнаружение инструментов...",
"noToolsTitle": "Инструменты не обнаружены",
"noToolsDescription": "Сервер может быть недоступен или в нём не зарегистрировано ни одного инструмента.",
"failedLoad": "Не удалось загрузить инструменты",
"filterPlaceholder": "Фильтр инструментов...",
"noMatch": "Нет подходящих инструментов"
},
"toast": {
"created": "MCP-сервер создан",
"updated": "MCP-сервер обновлён",
"deleted": "MCP-сервер удалён",
"failedCreate": "Не удалось создать MCP-сервер",
"failedUpdate": "Не удалось обновить MCP-сервер",
"failedDelete": "Не удалось удалить MCP-сервер"
},
"userCredentials": {
"title": "Мои учётные данные",
"description": "Задайте личные учётные данные для этого MCP-сервера. Они переопределяют значения по умолчанию сервера только для вашей учётной записи.",
"titleAdmin": "Учётные данные пользователя",
"descriptionAdmin": "Задайте учётные данные для конкретного пользователя на этом MCP-сервере. Они переопределяют значения по умолчанию сервера только для выбранного пользователя.",
"selectUser": "Выберите пользователя",
"apiKey": "API-ключ",
"apiKeyPlaceholder": "Оставьте пустым, чтобы сохранить текущий",
"headers": "Заголовки",
"env": "Переменные окружения",
"headerPlaceholder": "КЛЮЧ=ЗНАЧЕНИЕ, по одному в строке",
"save": "Сохранить",
"delete": "Удалить",
"deleteAll": "Удалить всё",
"cancel": "Отмена",
"saved": "Учётные данные сохранены",
"deleted": "Учётные данные удалены",
"hasApiKey": "API-ключ задан",
"hasHeaders": "Заголовки заданы",
"hasEnv": "Переменные окружения заданы",
"noCredentials": "Учётные данные не заданы",
"addHeader": "Добавить заголовок",
"addEnv": "Добавить переменную",
"saveFailed": "Не удалось сохранить учётные данные",
"deleteFailed": "Не удалось удалить учётные данные"
}
}
@@ -0,0 +1,191 @@
{
"title": "Память",
"description": "Просмотр и управление документами памяти агентов, фрагментами и эмбеддингами",
"search": "Поиск",
"create": "Создать",
"indexAll": "Индексировать всё",
"indexing": "Индексация...",
"emptyTitle": "Нет документов памяти",
"emptyAgentDescription": "У этого агента пока нет документов памяти.",
"emptyGlobalDescription": "Ни у одного агента не найдено документов памяти.",
"filters": {
"agent": "Агент",
"allAgents": "Все агенты",
"scope": "Область",
"allScope": "Все (глобальные + личные)",
"selectAgent": "Выберите агента"
},
"tabs": {
"documents": "Документы",
"knowledgeGraph": "Граф знаний"
},
"columns": {
"path": "Путь",
"agent": "Агент",
"scope": "Область",
"hash": "Хеш",
"updated": "Обновлено",
"actions": "Действия"
},
"scopeLabel": {
"personal": "Личная",
"global": "Глобальная"
},
"delete": {
"title": "Удалить документ памяти",
"description": "Вы уверены, что хотите удалить «{{path}}»? Это также удалит все связанные фрагменты и эмбеддинги.",
"confirmLabel": "Удалить"
},
"createDialog": {
"title": "Создать документ памяти",
"path": "Путь *",
"pathPlaceholder": "напр. notes/project-overview.md",
"content": "Содержимое *",
"contentPlaceholder": "Содержимое документа...",
"agentId": "Агент *",
"agentIdPlaceholder": "Выберите агента...",
"scope": "Область",
"existingScope": "Существующая область",
"customScope": "Своя",
"selectGroupUser": "Выберите группу/пользователя...",
"scopeHint": "Глобальная = общая для всех пользователей. Личная = ограничена конкретным пользователем или групповым чатом.",
"autoIndex": "Автоиндексация после создания",
"agentRequired": "Пожалуйста, выберите агента",
"pathRequired": "Путь обязателен",
"contentRequired": "Содержимое обязательно",
"cancel": "Отмена",
"create": "Создать",
"creating": "Создание..."
},
"documentDialog": {
"title": "Документ памяти",
"path": "Путь:",
"agent": "Агент:",
"scope": "Область:",
"hash": "Хеш:",
"updated": "Обновлено:",
"content": "Содержимое",
"chunks": "Фрагменты ({{count}})",
"chunkIndex": "Фрагмент {{index}}",
"noChunks": "Нет фрагментов",
"embedded": "С эмбеддингом",
"noEmbedding": "Без эмбеддинга"
},
"searchDialog": {
"title": "Поиск в памяти",
"query": "Поисковый запрос",
"queryPlaceholder": "Введите поисковый запрос...",
"agentId": "ID агента",
"agentIdPlaceholder": "Фильтр по агенту...",
"limit": "Лимит",
"search": "Поиск",
"searching": "Поиск...",
"results": "Результаты",
"noResults": "Результатов не найдено",
"similarity": "сходство",
"path": "Путь:"
},
"kg": {
"pageTitle": "Граф знаний",
"pageDescription": "Изучение сущностей и связей, извлечённых из памяти агента.",
"selectAgentTitle": "Выберите агента",
"selectAgentDescription": "Выберите агента, чтобы просмотреть его граф знаний.",
"emptyTitle": "Нет сущностей",
"emptyDescription": "У этого агента пока нет сущностей графа знаний.",
"emptySearchDescription": "Ни одна сущность не соответствует вашему поиску.",
"stats": {
"entities": "Сущности: {{count}}",
"relations": "Связи: {{count}}"
},
"search": {
"placeholder": "Поиск сущностей...",
"button": "Поиск",
"clear": "Очистить"
},
"refresh": "Обновить",
"extract": "Извлечь",
"columns": {
"name": "Имя",
"type": "Тип",
"description": "Описание",
"confidence": "Достоверность",
"actions": "Действия",
"observations": "Наблюдения",
"relations": "Связи"
},
"deleteEntity": {
"title": "Удалить сущность",
"description": "Удалить «{{name}}»? Это также удалит все связанные связи.",
"confirmLabel": "Удалить"
},
"entity": {
"externalId": "Внешний ID:",
"confidence": "Достоверность:",
"description": "Описание:",
"source": "Источник:",
"properties": "Свойства:",
"relations": "Связи",
"traverse": "Обход (2 перехода)",
"traversing": "Обход...",
"loading": "Загрузка...",
"noRelations": "Связи не найдены.",
"traversalResults": "Результаты обхода ({{count}})",
"direction": {
"outgoing": "→ исходящая",
"incoming": "← входящая"
},
"columns": {
"direction": "Направление",
"relation": "Связь",
"target": "Цель",
"confidence": "Достоверность"
}
},
"extractDialog": {
"title": "Извлечь сущности из текста",
"providerLabel": "Провайдер извлечения",
"modelLabel": "Модель извлечения",
"textLabel": "Текст для извлечения",
"textPlaceholder": "Вставьте текст разговора, заметки или любое содержимое для извлечения сущностей и связей...",
"extract": "Извлечь",
"extracting": "Извлечение...",
"cancel": "Отмена",
"agentId": "ID агента",
"agentIdPlaceholder": "Оставьте пустым для глобального"
},
"graphView": {
"loading": "Загрузка графа...",
"empty": "Нет сущностей для визуализации",
"nodes": "{{count}} узлов",
"edges": "{{count}} рёбер"
}
},
"toast": {
"created": "Документ памяти создан",
"deleted": "Документ памяти удалён",
"indexed": "Все документы проиндексированы",
"failedCreate": "Не удалось создать документ",
"failedDelete": "Не удалось удалить документ",
"failedIndex": "Не удалось проиндексировать документы",
"entitySaved": "Сущность сохранена",
"entitySaveFailed": "Не удалось сохранить сущность",
"entityDeleted": "Сущность удалена",
"entityDeleteFailed": "Не удалось удалить сущность",
"extractionComplete": "Извлечение завершено",
"extractionFailed": "Не удалось выполнить извлечение",
"traversalFailed": "Не удалось выполнить обход",
"unknownError": "Неизвестная ошибка",
"docCreated": "Документ создан",
"docCreateFailed": "Не удалось создать документ",
"docUpdated": "Документ обновлён",
"docUpdateFailed": "Не удалось обновить документ",
"docDeleted": "Документ удалён",
"docDeleteFailed": "Не удалось удалить документ",
"docIndexed": "Документ проиндексирован",
"docIndexFailed": "Не удалось проиндексировать документ",
"allIndexed": "Все документы проиндексированы",
"allIndexFailed": "Не удалось проиндексировать все",
"searchFailed": "Не удалось выполнить поиск",
"docLoadFailed": "Не удалось загрузить документ"
}
}
@@ -0,0 +1,179 @@
{
"title": "Провайдеры",
"description": "Управление LLM-провайдерами",
"addProvider": "Добавить провайдера",
"searchPlaceholder": "Поиск провайдеров...",
"emptyTitle": "Нет провайдеров",
"emptyDescription": "Добавьте первого LLM-провайдера, чтобы начать.",
"noMatchTitle": "Нет подходящих провайдеров",
"noMatchDescription": "Попробуйте другой поисковый запрос.",
"columns": {
"name": "Имя",
"type": "Тип",
"apiBase": "Базовый URL API",
"apiKey": "API-ключ",
"status": "Статус",
"actions": "Действия"
},
"apiKey": {
"oauthToken": "Токен OAuth",
"notSet": "Не задан"
},
"card": {
"apiKeySet": "API-ключ задан",
"authenticated": "Аутентифицирован",
"oauthLinked": "OAuth привязан"
},
"detail": {
"title": "Сведения о провайдере",
"advanced": "Дополнительно"
},
"form": {
"createTitle": "Добавить провайдера",
"editTitle": "Редактировать провайдера",
"name": "Имя *",
"namePlaceholder": "например openrouter",
"nameHint": "Строчные буквы, цифры, дефисы",
"displayName": "Отображаемое имя",
"displayNamePlaceholder": "OpenRouter",
"providerType": "Тип провайдера *",
"apiKey": "API-ключ",
"apiKeyPlaceholder": "sk-...",
"apiKeyEditPlaceholder": "Оставьте как есть или введите новый ключ",
"apiKeySetHint": "API-ключ задан. Очистите поле и введите новое значение, чтобы изменить его.",
"apiBase": "Базовый URL API",
"enabled": "Включён",
"cancel": "Отмена",
"close": "Закрыть",
"create": "Создать",
"save": "Сохранить",
"update": "Обновить",
"saving": "Сохранение...",
"creating": "Создание...",
"alreadyAdded": "(уже добавлен)",
"nameFixed": "Имя",
"configure": "Настройте подключение к LLM-провайдеру.",
"lowercaseHint": "Строчные буквы, цифры, дефисы"
},
"delete": {
"title": "Удалить провайдера",
"description": "Вы уверены, что хотите удалить «{{name}}»? Это действие нельзя отменить.",
"confirmLabel": "Удалить"
},
"types": {
"anthropic_native": "Anthropic",
"openai_compat": "OpenAI-совместимый",
"gemini_native": "Gemini",
"openrouter": "OpenRouter",
"groq": "Groq",
"deepseek": "DeepSeek",
"mistral": "Mistral",
"xai": "xAI",
"minimax_native": "MiniMax",
"cohere": "Cohere",
"perplexity": "Perplexity",
"chatgpt_oauth": "ChatGPT (OAuth)",
"yescale": "YesScale",
"acp": "ACP"
},
"acp": {
"description": "Оркестрируйте ACP-совместимых агентов для кодинга как подпроцессы. API-ключ не нужен.",
"binary": "Бинарный файл",
"binaryPlaceholder": "claude",
"binaryHint": "Путь или имя бинарного файла ACP-агента (например claude, codex, gemini)",
"args": "Аргументы",
"argsPlaceholder": "--profile goclaw",
"argsHint": "Аргументы через пробел, передаваемые бинарному файлу",
"idleTTL": "TTL простоя",
"idleTTLPlaceholder": "5m",
"idleTTLHint": "Завершать простаивающие процессы по истечении этого времени (например 5m, 1h)",
"permMode": "Режим разрешений",
"permModeApproveAll": "Одобрять всё",
"permModeApproveReads": "Одобрять только чтение",
"permModeDenyAll": "Отклонять всё",
"workDir": "Рабочий каталог",
"workDirPlaceholder": "/tmp/workspace",
"workDirHint": "Рабочий каталог для подпроцессов агента (необязательно)"
},
"oauth": {
"checkingStatus": "Проверка статуса аутентификации...",
"authSuccessful": "Аутентификация успешна!",
"activeProvider": "Провайдер",
"closingIn": "теперь активен. Закрытие через {{count}} с...",
"authenticated": "Аутентифицирован — провайдер",
"active": "активен",
"modelPrefixHint": "Используйте префикс модели",
"modelPrefixExample": "в конфигурации агента (например openai-codex/gpt-4o). Токен обновляется автоматически.",
"removeToken": "Удалить токен",
"signInDesc": "Войдите в свою учётную запись ChatGPT, чтобы использовать модели вашей подписки без отдельного API-ключа.",
"waiting": "Ожидание аутентификации... Завершите вход в открывшемся окне.",
"remoteVpsHint": "После входа ваш браузер попытается открыть",
"remoteVpsError": "и покажет ошибку «Не удаётся открыть эту страницу». Это нормально — скопируйте полный URL из адресной строки браузера и вставьте ниже.",
"pasteUrlPlaceholder": "http://localhost:1455/auth/callback?code=...&state=...",
"submit": "Отправить",
"signInWithChatGPT": "Войти через ChatGPT",
"starting": "Запуск...",
"remoteVps": "Удалённый сервер/VPS?",
"loggedOut": "Выполнен выход",
"loggedOutDesc": "Токен OAuth OpenAI удалён",
"oauthFailed": "Ошибка OAuth",
"exchangeFailed": "Не удался обмен",
"logoutFailed": "Не удалось выйти"
},
"cli": {
"description": "Claude CLI использует ваш локальный",
"descriptionSuffix": "бинарный файл. API-ключ не нужен.",
"checkingAuth": "Проверка аутентификации...",
"authenticatedAs": "Аутентифицирован как",
"switchAccount": "Сменить учётную запись?",
"switchAccountInstructions": "Выполните в терминале сервера:",
"switchAccountRecheck": "Затем нажмите",
"switchAccountRecheckSuffix": "для повторной проверки.",
"notAuthenticated": "Не аутентифицирован",
"runOnServer": "Выполните в терминале сервера:",
"recheckButton": "Проверить снова"
},
"detail": {
"advanced": "Дополнительно",
"identity": "Идентификация",
"identityDesc": "Идентификация провайдера",
"connection": "Подключение",
"connectionDesc": "Настройка конечной точки API",
"acpConfig": "Конфигурация ACP",
"acpConfigDesc": "Настройки подпроцессов агента",
"cliConfig": "Claude CLI",
"cliConfigDesc": "Локальная аутентификация CLI",
"oauthConfig": "OAuth",
"oauthConfigDesc": "Аутентификация ChatGPT через OAuth",
"nameReadonly": "Идентификатор провайдера, нельзя изменить",
"providerType": "Тип провайдера",
"apiKeySection": "API-ключ",
"apiKeySectionDesc": "Учётные данные для аутентификации",
"statusSection": "Статус",
"statusSectionDesc": "Доступность провайдера",
"enabledDesc": "Провайдер активен и доступен для агентов",
"embeddingSection": "Эмбеддинги"
},
"embedding": {
"enable": "Включить эмбеддинги",
"enableDesc": "Разрешить этому провайдеру генерировать текстовые эмбеддинги для памяти, навыков и графа знаний",
"model": "Модель эмбеддингов",
"dimensions": "Размерность вывода",
"dimensionsHint": "Обрезать вывод до N измерений (например 1536). Требуется для моделей с исходной размерностью > 1536, таких как gemini-embedding-001 (3072d).",
"apiBase": "Базовый URL API эмбеддингов",
"apiBasePlaceholder": "(как у провайдера)",
"apiBaseHint": "Переопределите, если конечная точка эмбеддингов отличается от основного базового URL API провайдера",
"verify": "Проверить эмбеддинги",
"verifyFailed": "Проверка эмбеддингов не удалась",
"dimensionsMismatch": "{{count}} измерений — не соответствует требуемым 1536"
},
"toast": {
"created": "Провайдер создан",
"createdDesc": "{{name}} добавлен",
"updated": "Провайдер обновлён",
"deleted": "Провайдер удалён",
"failedCreate": "Не удалось создать провайдера",
"failedUpdate": "Не удалось обновить провайдера",
"failedDelete": "Не удалось удалить провайдера"
}
}
@@ -0,0 +1,45 @@
{
"title": "Сессии",
"description": "Просмотр сессий разговоров",
"searchPlaceholder": "Поиск сессий...",
"emptyTitle": "Пока нет сессий",
"emptyDescription": "Сессии появятся здесь, как только вы начнёте общение.",
"noMatchTitle": "Нет подходящих сессий",
"noMatchDescription": "Попробуйте другой поисковый запрос.",
"columns": {
"session": "Сессия",
"agent": "Агент",
"context": "Контекст",
"messages": "Сообщения",
"updated": "Обновлено"
},
"contextBar": {
"compacted": "Сжато {{count}} раз(а)"
},
"detail": {
"reset": "Сбросить",
"delete": "Удалить",
"deleteTitle": "Удалить сессию",
"deleteDescription": "Это навсегда удалит все сообщения в этой сессии.",
"resetTitle": "Сбросить сессию",
"resetDescription": "Это очистит все сообщения, но сохранит сессию.",
"confirmDelete": "Удалить",
"confirmReset": "Сбросить",
"noMessages": "В этой сессии нет сообщений",
"summary": "Сводка",
"showMore": "Показать больше",
"showLess": "Показать меньше",
"showDetails": "показать подробности",
"hide": "скрыть",
"systemMessage": "Системное сообщение",
"messages": "сообщения"
},
"toast": {
"deleted": "Сессия удалена",
"deleteFailed": "Не удалось удалить сессию",
"reset": "Сессия сброшена",
"resetFailed": "Не удалось сбросить сессию",
"updated": "Сессия обновлена",
"updateFailed": "Не удалось обновить сессию"
}
}
@@ -0,0 +1,122 @@
{
"title": "Навыки",
"description": "Управление навыками и возможностями агентов",
"searchPlaceholder": "Поиск навыков...",
"emptyTitle": "Нет навыков",
"emptyDescription": "Пока не зарегистрировано ни одного навыка.",
"noMatchTitle": "Нет подходящих навыков",
"noMatchDescription": "Попробуйте другой поисковый запрос.",
"columns": {
"name": "Имя",
"description": "Описание",
"source": "Источник",
"author": "Автор",
"visibility": "Видимость",
"status": "Статус",
"actions": "Действия"
},
"noDescription": "Нет описания",
"visibility": {
"clickToCycle": "Нажмите, чтобы изменить видимость"
},
"delete": {
"title": "Удалить навык",
"description": "Вы уверены, что хотите удалить «{{name}}»? Это действие нельзя отменить.",
"confirmLabel": "Удалить"
},
"upload": {
"title": "Загрузка навыков",
"description": "Загрузите ZIP-файлы, содержащие SKILL.md с YAML-заголовком (name, description, slug).",
"button": "Загрузить",
"uploading": "Загрузка...",
"dropOrClick": "Нажмите или перетащите .zip-файлы",
"dropHere": "Перетащите .zip-файлы сюда",
"onlyZip": "Принимаются только .zip-файлы",
"cancel": "Отмена",
"done": "Готово",
"tooLarge": "Файл превышает лимит 20 МБ",
"invalidZip": "Некорректный ZIP-файл",
"noSkillMd": "ZIP должен содержать SKILL.md в корне",
"emptySkillMd": "SKILL.md пуст",
"noFrontmatter": "В SKILL.md отсутствует YAML-заголовок",
"nameRequired": "В YAML-заголовке SKILL.md обязательно поле name",
"invalidSlug": "Некорректный формат slug",
"failed": "Не удалось загрузить",
"validating": "Проверка...",
"validCount": "{{valid}} из {{total}} корректны",
"uploadCount": "Загрузить ({{count}})",
"successCount": "{{success}} из {{total}} успешно загружено",
"remove": "Удалить файл"
},
"edit": {
"title": "Редактировать навык",
"name": "Имя",
"description": "Описание",
"visibility": "Видимость",
"tags": "Теги",
"addTag": "Добавить тег...",
"add": "Добавить",
"cancel": "Отмена",
"save": "Сохранить",
"saving": "Сохранение...",
"privateOption": "Приватный (только владелец)",
"internalOption": "Внутренний (агенты/пользователи с доступом)",
"publicOption": "Публичный (все агенты)"
},
"system": "Системный",
"tabs": {
"core": "Основные",
"custom": "Пользовательские"
},
"toggle": {
"enable": "Включить навык",
"disable": "Отключить навык",
"disabled": "Отключён"
},
"tenant": {
"enabled": "Включён",
"disabled": "Отключён",
"default": "По умолчанию",
"overrideHint": "Переопределение этого навыка для арендатора",
"resetDefault": "Сбросить по умолчанию"
},
"deps": {
"rescan": "Пересканировать зависимости",
"rescanning": "Сканирование...",
"rescanSuccess": "Обновлено навыков: {{count}}",
"missing": "Отсутствуют: {{deps}}",
"install": "Установить зависимости",
"installing": "Установка...",
"installSuccess": "Зависимости успешно установлены",
"installPartial": "Некоторые зависимости не удалось установить",
"installItem": "Установить",
"itemSuccess": "Установлено",
"itemError": "Не удалось",
"missingTitle": "Отсутствующие зависимости",
"systemLabel": "Система",
"pythonLabel": "Python",
"nodeLabel": "Node.js",
"statusActive": "Активен",
"statusArchived": "Нет зависимостей",
"runtimeMissing": "Отсутствуют предпосылки среды выполнения",
"runtimeMissingDesc": "Основным навыкам требуются среды выполнения Python и/или Node.js. Пересоберите с ENABLE_PYTHON=true, ENABLE_NODE=true или ENABLE_FULL_SKILLS=true, либо установите вручную.",
"runtimeRequired": "Сначала установите среды выполнения"
},
"detail": {
"title": "Детали навыка",
"content": "Содержимое",
"files": "Файлы",
"version": "Версия:",
"current": "(текущая)",
"noContent": "Содержимое недоступно."
},
"toast": {
"updated": "Навык обновлён",
"updateFailed": "Не удалось обновить навык",
"deleted": "Навык удалён",
"deleteFailed": "Не удалось удалить навык",
"rescanUpdated": "Обновлено навыков: {{count}}",
"rescanNoChanges": "Все навыки актуальны",
"rescanFailed": "Не удалось пересканировать зависимости"
}
}
@@ -0,0 +1,25 @@
{
"title": "Хранилище",
"description": "Обозреватель файлов рабочего пространства",
"descriptionWithPath": "{{path}} — {{size}}",
"sizeCacheInfo": "Размер хранилища кэшируется на 60 минут",
"unsupportedFile": "Предпросмотр этого типа файлов не поддерживается",
"download": "Скачать",
"delete": {
"fileTitle": "Удалить файл",
"folderTitle": "Удалить папку",
"description": "Вы уверены, что хотите удалить {{name}}?",
"folderWarning": " Всё содержимое будет удалено рекурсивно.",
"undone": " Это действие нельзя отменить.",
"deleting": "Удаление...",
"confirmLabel": "Удалить"
},
"upload": {
"title": "Загрузка в хранилище",
"description": "Загрузка файлов в каталог данных"
},
"toast": {
"deleted": "Файл удалён",
"deleteFailed": "Не удалось удалить файл"
}
}
@@ -0,0 +1,111 @@
{
"title": "Команды",
"team": "Команда",
"selectTeam": "Выберите команду на боковой панели",
"kanban": "Канбан",
"list": "Список",
"allStatuses": "Все",
"active": "Активные",
"completed": "Завершённые",
"createTask": "Создать задачу",
"noTasks": "Пока нет задач",
"id": "ID",
"subject": "Тема",
"status": "Статус",
"owner": "Владелец",
"priority": "Приоритет",
"created": "Создано",
"updated": "Обновлено",
"description": "Описание",
"result": "Результат",
"progress": "Прогресс",
"blockedBy": "Заблокировано",
"assignTo": "Назначить",
"selectAgent": "Выберите агента...",
"delete": "Удалить",
"deleting": "Удаление...",
"attachments": "Вложения",
"download": "Скачать",
"deleteSelected": "Удалить выбранное",
"cancel": "Отмена",
"create": "Создать",
"creating": "Создание...",
"subjectPlaceholder": "Тема задачи...",
"descPlaceholder": "Детали задачи...",
"teamTasks": "Команда",
"tasksActive": "активных",
"createTeam": "Создать команду",
"teamName": "Название команды",
"teamNamePlaceholder": "Моя команда...",
"leadAgent": "Ведущий агент",
"selectLead": "Выберите ведущего агента...",
"members": "Участники",
"teamCreated": "Команда создана",
"createFailed": "Не удалось создать команду",
"limitReached": "Достигнут лимит команд",
"noTeams": "Пока нет команд",
"selected": "выбрано",
"needMembers": "Выберите хотя бы 1 участника для команды",
"teamSettings": "Настройки команды",
"settings": {
"teamInfo": "Информация о команде",
"addMember": "Добавить участника",
"searchAgent": "Поиск агента...",
"add": "Добавить",
"noMembers": "Нет участников",
"notifications": "Уведомления",
"notify_dispatched": "Задача отправлена",
"notify_progress": "Обновления прогресса",
"notify_failed": "Сбои задач",
"notify_completed": "Завершение задач",
"notify_new_task": "Новые задачи",
"notifyMode": "Режим уведомлений",
"notifyMode_direct": "Напрямую",
"notifyMode_direct_desc": "Отправлять обновления участникам напрямую",
"notifyMode_leader": "Через ведущего",
"notifyMode_leader_desc": "Ведущий перефразирует обновления перед отправкой",
"notifyModeLeaderWarn": "Режим ведущего использует ИИ для перефразирования (расходует токены, может быть медленнее).",
"save": "Сохранить",
"ok": "OK"
},
"taskCreateInfo": {
"title": "Как создаются задачи",
"body": "Задачи создаются в чате с ведущим агентом команды. Начните разговор с {{leader}}, чтобы создавать задачи и управлять ими."
},
"editionCompare": "GoClaw Lite и Standard",
"editionUpgrade": "Перейдите на Standard с PostgreSQL для полного набора функций",
"feature": "Функция",
"edition": {
"group": {
"limits": "Лимиты",
"core": "Основные функции",
"standardOnly": "Расширенные (Standard)"
},
"agents": "Агенты",
"teams": "Команды",
"teamMembers": "Участники команды",
"sessions": "Параллельные сессии",
"chat": "Чат (потоковая передача, инструменты, медиа)",
"tools": "Встроенные инструменты",
"mcpServers": "MCP-серверы",
"skills": "Навыки",
"memory": "Память",
"cron": "Планирование cron",
"heartbeat": "Heartbeat агента",
"storage": "Файловое хранилище",
"traces": "Трассировки",
"taskActions": "Действия над задачами команды",
"channels": "Каналы (Telegram, Discord...)",
"skillManage": "Самоуправление навыками",
"knowledgeGraph": "Граф знаний",
"vectorSearch": "Векторный поиск",
"rbac": "Ролевой доступ",
"multiTenant": "Мультиарендность",
"agentLinks": "Связи агентов",
"activityLogs": "Журналы активности",
"apiKeys": "API-ключи",
"poolProvider": "Пул провайдеров",
"secureCli": "Защищённый CLI",
"tenantUsers": "Управление арендаторами и пользователями"
}
}
@@ -0,0 +1,229 @@
{
"custom": {
"title": "Пользовательские инструменты",
"description": "Управление пользовательскими инструментами на основе shell для агентов",
"createTool": "Создать инструмент",
"searchPlaceholder": "Поиск инструментов...",
"emptyTitle": "Нет пользовательских инструментов",
"emptyDescription": "Создайте первый пользовательский инструмент, чтобы начать.",
"noMatchTitle": "Нет подходящих инструментов",
"noMatchDescription": "Попробуйте другой поисковый запрос.",
"noDescription": "Нет описания",
"columns": {
"name": "Имя",
"description": "Описание",
"scope": "Область",
"enabled": "Включён",
"timeout": "Тайм-аут",
"actions": "Действия"
},
"scope": {
"agent": "Агент",
"global": "Глобальная"
},
"delete": {
"title": "Удалить пользовательский инструмент",
"description": "Вы уверены, что хотите удалить «{{name}}»? Это действие нельзя отменить.",
"confirmLabel": "Удалить"
},
"form": {
"createTitle": "Создать пользовательский инструмент",
"editTitle": "Редактировать инструмент",
"name": "Имя *",
"namePlaceholder": "my-tool",
"nameHint": "Только строчные буквы, цифры и дефисы",
"description": "Описание",
"descriptionPlaceholder": "Что делает этот инструмент...",
"command": "Команда *",
"commandHint": "Shell-шаблон. Используйте {{.key}} для подстановки параметров.",
"parameters": "Параметры (JSON Schema)",
"workingDir": "Рабочий каталог",
"workingDirPlaceholder": "/path/to/dir",
"timeout": "Тайм-аут (секунды)",
"agentId": "ID агента (необязательно)",
"agentIdPlaceholder": "Оставьте пустым для глобальной области",
"enabled": "Включён",
"cancel": "Отмена",
"create": "Создать",
"update": "Обновить",
"saving": "Сохранение...",
"errors": {
"nameRequired": "Требуются имя и команда",
"nameSlug": "Имя должно быть корректным slug (только строчные буквы, цифры, дефисы)",
"invalidJson": "Параметры должны быть корректным JSON"
}
},
"toast": {
"created": "Инструмент создан",
"createdDesc": "{{name}} добавлен",
"updated": "Инструмент обновлён",
"deleted": "Инструмент удалён",
"failedCreate": "Не удалось создать инструмент",
"failedUpdate": "Не удалось обновить инструмент",
"failedDelete": "Не удалось удалить инструмент"
}
},
"builtin": {
"title": "Встроенные инструменты",
"description": "Управление системными встроенными инструментами. Включайте/отключайте или настраивайте параметры глобально.",
"searchPlaceholder": "Поиск инструментов...",
"emptyTitle": "Нет встроенных инструментов",
"emptyDescription": "Встроенные инструменты ещё не инициализированы.",
"noMatchTitle": "Нет подходящих инструментов",
"noMatchDescription": "Попробуйте другой поисковый запрос.",
"toolCount": "{{count}} инструмент",
"toolCountPlural": "{{count}} инструментов",
"categoryCount": "{{count}} категорий",
"requires": "треб",
"requiresTooltip": "Требуется: {{list}}",
"deprecated": "Устарел",
"deprecatedTooltip": "Этот инструмент устарел и больше недоступен",
"settings": "Настройки",
"configuredVia": "Настраивается на странице конфигурации",
"tenantOverride": "Переопределение арендатора",
"tenantEnabled": "Включён для этого арендатора",
"tenantDisabled": "Отключён для этого арендатора",
"tenantDefault": "По умолчанию",
"resetToDefault": "Сбросить к значению по умолчанию",
"unconfiguredWarning": "Для {{count}} инструментов требуется настройка провайдера, чтобы агенты могли использовать их в полном объёме.",
"unconfiguredAction": "Настроить",
"categories": {
"filesystem": "Файловая система",
"runtime": "Среда выполнения",
"web": "Веб",
"memory": "Память",
"media": "Медиа",
"browser": "Браузер",
"sessions": "Сессии",
"messaging": "Обмен сообщениями",
"scheduling": "Планирование",
"subagents": "Агенты",
"skills": "Навыки",
"delegation": "Делегирование",
"teams": "Команды"
},
"settingsDialog": {
"title": "Настройки — {{name}}",
"cancel": "Отмена",
"save": "Сохранить",
"saving": "Сохранение...",
"noFields": "Для этого инструмента нет настраиваемых параметров.",
"toast": {
"saved": "Настройки сохранены",
"failed": "Не удалось сохранить настройки"
}
},
"jsonDialog": {
"title": "Настройки: {{name}}",
"description": "Редактируйте настройки инструмента в формате JSON. Изменения вступают в силу сразу после сохранения.",
"formatJson": "Форматировать JSON",
"invalidJsonSyntax": "Некорректный синтаксис JSON",
"invalidJson": "Некорректный JSON",
"cannotFormat": "Невозможно отформатировать: некорректный JSON",
"cancel": "Отмена",
"save": "Сохранить",
"saving": "Сохранение..."
},
"kgSettings": {
"title": "Настройки графа знаний",
"description": "Настройте извлечение сущностей при записи в память. Требуется провайдер/модель, поддерживающая структурированный вывод JSON.",
"extractionProvider": "Провайдер извлечения",
"extractionModel": "Модель извлечения",
"providerTip": "LLM-провайдер, используемый для извлечения сущностей и связей из текста.",
"modelTip": "ID модели для извлечения. Должна поддерживать структурированный вывод JSON.",
"minConfidence": "Мин. уверенность",
"minConfidenceHint": "Сущности с оценкой уверенности ниже этого значения отбрасываются (0.0–1.0).",
"autoExtract": "Автоизвлечение при записи в память",
"autoExtractHint": "Автоматически извлекать сущности, когда агенты записывают в файлы памяти.",
"cancel": "Отмена",
"save": "Сохранить",
"saving": "Сохранение..."
},
"extractorChain": {
"title": "Web Fetch — цепочка экстракторов",
"description": "Упорядоченный список экстракторов контента. Каждый URL обрабатывается сверху вниз, пока один из них не вернёт качественный контент.",
"timeout": "Тайм-аут",
"baseUrl": "Базовый URL",
"save": "Сохранить",
"saving": "Сохранение…",
"cancel": "Отмена",
"extractors": {
"defuddle": "Defuddle (Cloudflare Worker)",
"defuddleDesc": "Извлекает чистый markdown через fetch.goclaw.sh с помощью библиотеки Defuddle.",
"html-to-markdown": "Встроенный HTML→Markdown",
"html-to-markdownDesc": "Внутрипроцессный конвертер на основе DOM с обнаружением скрытых элементов."
}
},
"mediaChain": {
"providerChainSuffix": "— цепочка провайдеров",
"description": "Настройте и упорядочьте резервные провайдеры. Перетаскивайте для изменения порядка — первый включённый провайдер пробуется первым.",
"newProvider": "Новый провайдер",
"provider": "Провайдер",
"model": "Модель",
"selectProvider": "Выберите провайдера",
"loadingModels": "Загрузка...",
"selectModel": "Выберите модель",
"timeout": "Тайм-аут",
"retries": "Повторы",
"settings": "Настройки",
"noProviders": "Провайдеры не настроены. Добавьте один ниже.",
"addProvider": "Добавить провайдера",
"cancel": "Отмена",
"save": "Сохранить",
"saving": "Сохранение..."
},
"toast": {
"toggled": "Инструмент обновлён",
"failedToggle": "Не удалось обновить инструмент"
},
"descriptions": {
"read_file": "Прочитать содержимое файла из рабочей области агента по пути",
"write_file": "Записать содержимое в файл в рабочей области, создавая каталоги при необходимости",
"list_files": "Вывести список файлов и каталогов по указанному пути в рабочей области",
"edit": "Применить точечные правки поиска и замены к существующим файлам без перезаписи всего файла",
"exec": "Выполнить shell-команду в рабочей области и вернуть stdout/stderr",
"web_search": "Искать информацию в интернете с помощью поисковой системы (Brave или DuckDuckGo)",
"web_fetch": "Загрузить веб-страницу или конечную точку API и извлечь её текстовое содержимое",
"memory_search": "Искать в долговременной памяти агента по семантическому сходству",
"memory_get": "Получить конкретный документ памяти по его пути к файлу",
"knowledge_graph_search": "Искать сущности, связи и наблюдения в графе знаний агента",
"read_image": "Анализировать изображения с помощью LLM-провайдера с поддержкой зрения",
"read_document": "Анализировать документы (PDF, Word, Excel, PowerPoint, CSV и т. д.) с помощью LLM-провайдера с поддержкой документов",
"create_image": "Генерировать изображения из текстовых запросов с помощью провайдера генерации изображений",
"read_audio": "Анализировать аудиофайлы (речь, музыка, звуки) с помощью LLM-провайдера с поддержкой аудио",
"read_video": "Анализировать видеофайлы с помощью LLM-провайдера с поддержкой видео",
"create_video": "Генерировать видео из текстовых описаний с помощью ИИ",
"create_audio": "Генерировать музыку или звуковые эффекты из текстовых описаний с помощью ИИ",
"tts": "Преобразовать текст в естественно звучащую речь",
"browser": "Автоматизировать действия в браузере: навигация по страницам, клики по элементам, заполнение форм, создание скриншотов",
"sessions_list": "Вывести список активных сессий чата по всем каналам",
"session_status": "Получить текущий статус и метаданные конкретной сессии чата",
"sessions_history": "Получить историю сообщений конкретной сессии чата",
"sessions_send": "Отправить сообщение в активную сессию чата от имени агента",
"message": "Отправить проактивное сообщение пользователю в подключённом канале (Telegram, Discord и т. д.)",
"cron": "Планировать или управлять повторяющимися задачами с помощью cron-выражений, времени или интервалов",
"spawn": "Запустить субагента для выполнения задачи в фоновом режиме",
"skill_search": "Искать доступные навыки по ключевому слову или описанию, чтобы найти нужные возможности",
"use_skill": "Активировать навык для использования его специализированных возможностей (маркер трассировки)",
"team_tasks": "Просматривать, создавать, обновлять и завершать задачи на доске задач команды"
},
"sttForm": {
"title": "Настройки STT",
"description": "Настройте провайдеры распознавания речи для транскрибации голосовых сообщений.",
"providersLabel": "Провайдеры",
"elevenlabsSectionTitle": "ElevenLabs",
"elevenlabsApiKeyLabel": "API-ключ",
"elevenlabsDefaultLanguageLabel": "Язык по умолчанию",
"proxySectionTitle": "Прокси",
"proxyUrlLabel": "URL прокси",
"proxyApiKeyLabel": "API-ключ прокси",
"proxyTenantIdLabel": "ID арендатора прокси",
"whatsappEnabledLabel": "Включить STT для WhatsApp",
"whatsappPrivacyWarning": "Включение STT для WhatsApp нарушает сквозное шифрование для голосовых сообщений, отправляемых этому агенту.",
"providersRequiredError": "Необходимо выбрать хотя бы одного провайдера.",
"cancel": "Отмена",
"save": "Сохранить",
"saving": "Сохранение..."
}
}
}
@@ -0,0 +1,63 @@
{
"title": "Трассировки",
"description": "Трассировки вызовов LLM и данные о производительности",
"filterPlaceholder": "Фильтр по ID агента...",
"filter": "Фильтр",
"allAgents": "Все агенты",
"allChannels": "Все каналы",
"emptyTitle": "Нет трассировок",
"emptyDescription": "Трассировки не найдены. Трассировки записываются, когда агенты обрабатывают запросы.",
"columns": {
"name": "Имя",
"status": "Статус",
"duration": "Длительность",
"tokens": "Токены",
"spans": "Спаны",
"time": "Время"
},
"unnamed": "Без имени",
"stopRun": "Остановить выполнение",
"cached": "из кэша",
"detail": {
"title": "Детали трассировки",
"copyTraceId": "Копировать ID трассировки",
"notFound": "Трассировка не найдена.",
"name": "Имя:",
"status": "Статус:",
"duration": "Длительность:",
"channel": "Канал:",
"tokens": "Токены:",
"spans": "Спаны:",
"started": "Начато:",
"delegatedFrom": "Делегировано от:",
"createdAt": "Создано:",
"input": "Ввод",
"output": "Вывод",
"copy": "Копировать",
"spansCount": "Спаны ({{count}})",
"llmCalls": "LLM",
"toolCalls": "инструмент",
"export": "Экспорт трассировки",
"stopRun": "Остановить выполнение"
},
"span": {
"model": "Модель:",
"tokens": "Токены:",
"createdAt": "Создано:",
"input": "Ввод:",
"output": "Вывод:",
"copy": "Копировать",
"startTime": "Начало:",
"endTime": "Конец:",
"cacheRead": "чтение",
"cacheWrite": "запись",
"thinking": "размышление",
"cached": "из кэша"
},
"toast": {
"failedLoad": "Не удалось загрузить трассировки",
"abortSent": "Выполнение остановлено",
"abortFailed": "Не удалось остановить выполнение",
"abortNotFound": "Выполнение уже завершено или не найдено"
}
}
@@ -0,0 +1,279 @@
{
"title": "Синтез речи (TTS)",
"description": "Настройка провайдеров TTS и параметров автоприменения",
"save": "Сохранить",
"saving": "Сохранение...",
"saveChanges": "Сохранить изменения",
"status": {
"title": "Статус",
"configured": "Настроено",
"disabled": "Отключено",
"noProvider": "Провайдер TTS не настроен",
"activeProvider": "Основной провайдер: {{provider}}, Авто: {{auto}}"
},
"general": {
"title": "Общие настройки",
"primaryProvider": "Основной провайдер",
"autoApplyMode": "Режим автоприменения",
"replyMode": "Режим ответа",
"maxTextLength": "Макс. длина текста",
"timeout": "Тайм-аут (мс)"
},
"providers": {
"none": "Нет (отключено)",
"openai": "OpenAI",
"elevenlabs": "ElevenLabs",
"edge": "Edge (бесплатно)",
"minimax": "MiniMax",
"gemini": "Google Gemini"
},
"autoModes": {
"off": "Выключено",
"offDesc": "Агент может использовать инструмент TTS вручную",
"always": "Всегда",
"alwaysDesc": "Все ответы озвучиваются",
"inbound": "Входящие",
"inboundDesc": "Только когда пользователь отправляет голос/аудио",
"tagged": "По тегу",
"taggedDesc": "Только когда ответ содержит тег [[tts]]"
},
"replyModes": {
"final": "Только финальные",
"finalDesc": "Только финальные ответы",
"all": "Все",
"allDesc": "Все ответы, включая инструмент/блок"
},
"providerSettings": "Настройки {{provider}}",
"openai": {
"apiKey": "API-ключ",
"apiBase": "Базовый URL API",
"model": "Модель",
"voice": "Голос",
"speed": {
"label": "Скорость",
"help": "Множитель скорости речи — 0.25 = самая медленная, 4.0 = самая быстрая."
},
"responseFormat": {
"label": "Формат вывода",
"help": "Кодировка аудио, возвращаемая API (mp3, opus, aac, flac, wav, pcm)."
},
"instructions": {
"label": "Инструкции",
"help": "Системный промпт стиля — поддерживается только моделью gpt-4o-mini-tts."
}
},
"elevenlabs": {
"apiKey": "API-ключ",
"baseUrl": "Базовый URL",
"voiceId": "Voice ID",
"modelId": "Model ID",
"voiceSettings": {
"stability": {
"label": "Стабильность",
"help": "0 = больше выразительных вариаций, 1 = более согласованно и стабильно."
},
"similarityBoost": {
"label": "Усиление сходства",
"help": "Насколько точно вывод соответствует оригинальному клону голоса (0 = креативно, 1 = похоже)."
},
"style": {
"label": "Усиление стиля",
"help": "Усиливает стиль голоса. 0 = нет; более высокие значения добавляют выразительности."
},
"useSpeakerBoost": {
"label": "Усиление диктора",
"help": "Повышает чёткость голоса и сходство с целевым диктором."
},
"speed": {
"label": "Скорость",
"help": "Скорость речи — диапазон от 0.7 (медленно) до 1.2 (быстро)."
}
},
"applyTextNormalization": {
"label": "Нормализация текста",
"help": "Как раскрываются числа и сокращения (auto, on или off)."
},
"seed": {
"label": "Seed (для опытных)",
"help": "Задайте фиксированный seed для воспроизводимого вывода. 0 = случайный."
},
"optimizeStreamingLatency": {
"label": "Задержка потока (для опытных)",
"help": "Уровень оптимизации задержки: 0 = нет, 4 = максимальная."
},
"languageCode": {
"label": "Код языка",
"help": "Подсказка языка по ISO 639-1, напр. «en» или «vi». Для опытных."
}
},
"edge": {
"voice": "Голос",
"speechRate": "Темп речи",
"hint": "Edge TTS бесплатен и не требует API-ключа. Установка: pip install edge-tts",
"rate": {
"label": "Темп речи",
"help": "Корректировка темпа в процентах. -50% = намного медленнее, +100% = намного быстрее."
},
"pitch": {
"label": "Высота тона",
"help": "Сдвиг высоты тона в Гц относительно нейтрального. Диапазон: от -50 Гц до +50 Гц."
},
"volume": {
"label": "Громкость",
"help": "Корректировка громкости в процентах. -50% = тише, +100% = громче."
}
},
"minimax": {
"apiKey": "API-ключ",
"groupId": "Group ID *",
"groupIdPlaceholder": "Обязательно для MiniMax",
"apiBase": "Базовый URL API",
"model": "Модель",
"voiceId": "Voice ID",
"speed": {
"label": "Скорость",
"help": "Множитель скорости речи — 0.5 = самая медленная, 2.0 = самая быстрая."
},
"vol": {
"label": "Громкость",
"help": "Множитель громкости — 0.01 = почти беззвучно, 10.0 = максимально громко."
},
"pitch": {
"label": "Высота тона",
"help": "Сдвиг высоты тона в полутонах. -12 = на октаву ниже, +12 = на октаву выше."
},
"emotion": {
"label": "Эмоция",
"help": "Эмоциональный тон, применяемый к синтезированному голосу."
},
"textNormalization": {
"label": "Нормализация текста",
"help": "Раскрывать ли числа и символы перед синтезом."
},
"audio": {
"format": {
"label": "Формат аудио",
"help": "Кодировка вывода: mp3, pcm, flac или wav."
},
"sampleRate": {
"label": "Частота дискретизации",
"help": "Частота дискретизации аудио в Гц. Для большинства случаев оставьте значение по умолчанию."
},
"bitrate": {
"label": "Битрейт (только MP3)",
"help": "Битрейт MP3 в бит/с. Применяется, только когда формат — mp3."
},
"channel": {
"label": "Каналы",
"help": "1 = моно (меньший файл), 2 = стерео."
}
}
},
"gemini": {
"apiKey": "API-ключ",
"apiBase": "Базовый URL API",
"voice": "Голос",
"model": "Модель",
"multiSpeaker": "Несколько дикторов",
"multiSpeakerHint": "Поддерживается до 2 дикторов",
"audioTags": "Аудиотеги",
"audioTagsHint": "Вставляйте выразительные теги вроде [laughs] прямо в текст",
"speakerName": "Имя диктора",
"speakerVoice": "Голос диктора",
"addSpeaker": "Добавить диктора",
"removeSpeaker": "Удалить",
"maxSpeakersReached": "Достигнут максимум в 2 диктора",
"filterAll": "Все",
"filterEmotion": "Эмоция",
"filterPacing": "Темп",
"filterEffect": "Эффект",
"filterVoiceQuality": "Качество голоса",
"searchPlaceholder": "Поиск тегов…",
"insertTag": "Вставить",
"multiSpeakerMode": {
"title": "Режим нескольких дикторов",
"addSpeaker": "Добавить диктора",
"speakerName": "Имя диктора",
"speakerVoice": "Голос",
"removeSpeaker": "Удалить",
"limitReached": "Максимум 2 диктора"
},
"audioTagsPanel": {
"title": "Аудиотеги",
"search": "Поиск тегов",
"categoryEmotion": "Эмоция",
"categoryPacing": "Темп",
"categoryEffect": "Эффект",
"categoryVoiceQuality": "Качество голоса",
"insertHint": "Нажмите на тег, чтобы вставить его в позицию курсора"
},
"previewBadge": "Предпросмотр"
},
"voice_label": "Голос",
"voice_placeholder": "Выберите голос…",
"voice_picker": {
"requires_provider": "Сначала настройте провайдера TTS",
"enter_voice_id": "Введите voice_id вручную"
},
"voice_refresh": "Обновить",
"voice_preview": "Прослушать",
"voice_stop_preview": "Стоп",
"voice_no_voices": "Нет доступных голосов",
"voice_loading": "Загрузка голосов…",
"voice_preview_error": "Не удалось прослушать — обновление списка",
"model_label": "Модель",
"model_placeholder": "По умолчанию (арендатор/система)",
"empty_state": {
"title": "Голос ИИ не настроен",
"description": "Настройте TTS, чтобы агенты могли отвечать голосом.",
"cta": "Настроить TTS",
"non_owner_hint": "Обратитесь к владельцу, чтобы включить голос ИИ."
},
"test": {
"button": "Проверить этот голос",
"sample_text": "Здравствуйте, это проверка голоса.",
"title": "Прослушать",
"placeholder": "Введите текст, чтобы услышать образец…",
"play": "Воспроизвести",
"stop": "Стоп",
"error_missing_config": "Сначала выберите провайдера и введите API-ключ.",
"error_synthesize": "Не удалось создать аудио: {{error}}"
},
"override": {
"label": "Переопределить голос для этого агента",
"inherits": "Наследует: {{provider}} · {{voice}} · {{model}}",
"params": {
"title": "Точная настройка"
}
},
"testConnection": {
"label": "Проверить подключение",
"testing": "Проверка…",
"success": "Подключение успешно",
"failed": "Не удалось подключиться"
},
"connection": {
"test": "Проверить подключение",
"ok": "Подключение в порядке",
"fail": "Неверный ключ или сетевая ошибка"
},
"agent": {
"override_label": "Переопределить голос для этого агента",
"inherits_from_global": "Наследует из глобальных: {{provider}} · {{voice}} · {{model}}"
},
"playground": {
"title": "Тестовая площадка",
"inputLabel": "Текст для синтеза",
"placeholder": "Введите текст, чтобы услышать…",
"play": "Воспроизвести",
"stop": "Стоп",
"synthesizing": "Синтез…",
"playbackFailed": "Не удалось воспроизвести",
"requiresProvider": "Выберите провайдера выше, чтобы включить тестовое воспроизведение."
},
"advanced": {
"title": "Дополнительные настройки",
"count": "{{count}} дополнительных настроек",
"count_one": "{{count}} дополнительная настройка"
}
}
+1
View File
@@ -3,6 +3,7 @@ export const LANGUAGES = [
{ value: 'en', label: 'EN', flag: '🇺🇸' },
{ value: 'vi', label: 'VI', flag: '🇻🇳' },
{ value: 'zh', label: 'ZH', flag: '🇨🇳' },
{ value: 'ru', label: 'RU', flag: '🇷🇺' },
] as const
// Fallback timezone list if Intl.supportedValuesOf is unavailable
+66 -1
View File
@@ -170,15 +170,59 @@ import zhHooks from "./locales/zh/hooks.json";
import zhWebhooks from "./locales/zh/webhooks.json";
import zhWorkstations from "./locales/zh/workstations.json";
// --- RU namespaces ---
import ruCommon from "./locales/ru/common.json";
import ruSidebar from "./locales/ru/sidebar.json";
import ruTopbar from "./locales/ru/topbar.json";
import ruLogin from "./locales/ru/login.json";
import ruOverview from "./locales/ru/overview.json";
import ruChat from "./locales/ru/chat.json";
import ruAgents from "./locales/ru/agents.json";
import ruTeams from "./locales/ru/teams.json";
import ruSessions from "./locales/ru/sessions.json";
import ruSkills from "./locales/ru/skills.json";
import ruCron from "./locales/ru/cron.json";
import ruConfig from "./locales/ru/config.json";
import ruChannels from "./locales/ru/channels.json";
import ruProviders from "./locales/ru/providers.json";
import ruTraces from "./locales/ru/traces.json";
import ruEvents from "./locales/ru/events.json";
import ruUsage from "./locales/ru/usage.json";
import ruApprovals from "./locales/ru/approvals.json";
import ruNodes from "./locales/ru/nodes.json";
import ruLogs from "./locales/ru/logs.json";
import ruTools from "./locales/ru/tools.json";
import ruMcp from "./locales/ru/mcp.json";
import ruTts from "./locales/ru/tts.json";
import ruSetup from "./locales/ru/setup.json";
import ruMemory from "./locales/ru/memory.json";
import ruVault from "./locales/ru/vault.json";
import ruStorage from "./locales/ru/storage.json";
import ruPendingMessages from "./locales/ru/pending-messages.json";
import ruContacts from "./locales/ru/contacts.json";
import ruActivity from "./locales/ru/activity.json";
import ruApiKeys from "./locales/ru/api-keys.json";
import ruCliCredentials from "./locales/ru/cli-credentials.json";
import ruPackages from "./locales/ru/packages.json";
import ruTenants from "./locales/ru/tenants.json";
import ruSystemSettings from "./locales/ru/system-settings.json";
import ruImportExport from "./locales/ru/import-export.json";
import ruV3Capabilities from "./locales/ru/v3-capabilities.json";
import ruBackup from "./locales/ru/backup.json";
import ruHooks from "./locales/ru/hooks.json";
import ruWebhooks from "./locales/ru/webhooks.json";
import ruWorkstations from "./locales/ru/workstations.json";
const STORAGE_KEY = "goclaw:language";
function getInitialLanguage(): string {
const stored = localStorage.getItem(STORAGE_KEY);
if (stored === "en" || stored === "vi" || stored === "zh" || stored === "ko") return stored;
if (stored === "en" || stored === "vi" || stored === "zh" || stored === "ko" || stored === "ru") return stored;
const lang = navigator.language.toLowerCase();
if (lang.startsWith("vi")) return "vi";
if (lang.startsWith("zh")) return "zh";
if (lang.startsWith("ko")) return "ko";
if (lang.startsWith("ru")) return "ru";
return "en";
}
@@ -279,6 +323,27 @@ i18n.use(initReactI18next).init({
"v3-capabilities": koV3Capabilities,
backup: koBackup,
},
ru: {
common: ruCommon, sidebar: ruSidebar, topbar: ruTopbar, login: ruLogin,
overview: ruOverview, chat: ruChat, agents: ruAgents, teams: ruTeams,
sessions: ruSessions, skills: ruSkills, cron: ruCron, config: ruConfig,
channels: ruChannels, providers: ruProviders, traces: ruTraces,
events: ruEvents, usage: ruUsage,
approvals: ruApprovals, nodes: ruNodes, logs: ruLogs, tools: ruTools,
mcp: ruMcp, tts: ruTts, setup: ruSetup, memory: ruMemory, vault: ruVault, storage: ruStorage,
"pending-messages": ruPendingMessages,
contacts: ruContacts, activity: ruActivity, "api-keys": ruApiKeys,
"cli-credentials": ruCliCredentials,
packages: ruPackages,
tenants: ruTenants,
"system-settings": ruSystemSettings,
"import-export": ruImportExport,
"v3-capabilities": ruV3Capabilities,
backup: ruBackup,
hooks: ruHooks,
webhooks: ruWebhooks,
workstations: ruWorkstations,
},
},
ns: [...ns],
defaultNS: "common",
+1
View File
@@ -372,6 +372,7 @@
"systemMessages.locale.vi": "Vietnamese",
"systemMessages.locale.zh": "Chinese",
"systemMessages.locale.ko": "Korean",
"systemMessages.locale.ru": "Russian",
"systemMessages.override": "Override Template",
"systemMessages.overrideTip": "Template sent instead of the built-in message for the selected locale. Variables use {{name}}.",
"systemMessages.defaultTemplate": "Default Template",
+26
View File
@@ -0,0 +1,26 @@
{
"title": "Журнал активности",
"description": "Аудиторский след изменений администрирования и конфигурации.",
"filters": {
"action": "Действие",
"allActions": "Все действия",
"agentCreated": "Агент создан",
"agentUpdated": "Агент обновлён",
"agentDeleted": "Агент удалён",
"entityType": "Тип сущности",
"allEntities": "Все сущности",
"agent": "Агент"
},
"table": {
"action": "Действие",
"actor": "Инициатор",
"entity": "Сущность",
"entityId": "ID сущности",
"ip": "IP-адрес",
"time": "Время"
},
"empty": {
"title": "Нет журналов активности",
"description": "Журналы активности появятся здесь при выполнении действий администратора."
}
}
File diff suppressed because it is too large. Load diff
+87
View File
@@ -0,0 +1,87 @@
{
"title": "Ключи API",
"description": "Управление ключами API шлюза с гранулярными разрешениями.",
"addKey": "Создать ключ API",
"searchPlaceholder": "Поиск ключей...",
"emptyTitle": "Нет ключей API",
"emptyDescription": "Создайте свой первый ключ API для аутентификации на шлюзе.",
"columns": {
"name": "Имя",
"prefix": "Ключ",
"scopes": "Области",
"lastUsed": "Последнее использование",
"created": "Создан",
"status": "Статус",
"actions": "Действия"
},
"status": {
"active": "Активен",
"revoked": "Отозван",
"expired": "Истёк"
},
"form": {
"title": "Создать ключ API",
"name": "Имя",
"namePlaceholder": "напр. ci-deploy, dashboard-readonly",
"scopes": "Области",
"scopeDescriptions": {
"operator.admin": "Полный доступ администратора",
"operator.read": "Доступ только для чтения",
"operator.write": "Доступ на чтение и запись",
"operator.approvals": "Управление одобрениями выполнения",
"operator.pairing": "Управление привязкой устройств",
"operator.provision": "Создание новых арендаторов"
},
"tenant": "Арендатор",
"tenantSystem": "Система (все арендаторы)",
"expiry": "Срок действия",
"expiryOptions": {
"never": "Никогда",
"7d": "7 дней",
"30d": "30 дней",
"90d": "90 дней"
},
"cancel": "Отмена",
"create": "Создать",
"creating": "Создание..."
},
"created": {
"title": "Ключ API создан",
"description": "Скопируйте этот ключ сейчас — он больше не будет показан.",
"copied": "Скопировано!",
"copy": "Копировать в буфер обмена",
"done": "Готово"
},
"revoke": {
"title": "Отозвать ключ API",
"description": "Вы уверены, что хотите отозвать «{{name}}»? Это действие нельзя отменить.",
"confirmLabel": "Отозвать"
},
"toast": {
"created": "Ключ API создан",
"revoked": "Ключ API отозван",
"failedCreate": "Не удалось создать ключ API",
"failedRevoke": "Не удалось отозвать ключ API"
},
"never": "Никогда",
"neverUsed": "Не использовался",
"tenantBadgeSystem": "Система",
"tenantBadgeUnknown": "Неизвестно",
"columns.expiry": "Срок действия",
"codeDialog": {
"title": "Использование ключа API",
"description": "Используйте этот ключ API для аутентификации в HTTP API шлюза.",
"copy": "Копировать",
"copied": "Скопировано!",
"tabs": {
"curl": "cURL",
"typescript": "TypeScript",
"go": "Go"
},
"comments": {
"chat": "Чат с агентом (совместимо с OpenAI)",
"listAgents": "Список агентов",
"listSessions": "Список сессий"
}
}
}
+33
View File
@@ -0,0 +1,33 @@
{
"title": "Одобрения",
"description": "Ожидающие одобрения на выполнение",
"pending": "{{count}} ожидает",
"emptyTitle": "Нет ожидающих одобрений",
"emptyDescription": "Все запросы на выполнение обработаны. Новые запросы появятся здесь в реальном времени.",
"allowOnce": "Разрешить один раз",
"allowAlways": "Разрешить всегда",
"deny": "Отклонить",
"confirmAllowOnce": {
"title": "Разрешить один раз",
"description": "Разрешить выполнение «{{command}}» от агента «{{agentId}}»?"
},
"confirmAllowAlways": {
"title": "Разрешить всегда",
"description": "Разрешить «{{command}}» для агента «{{agentId}}» навсегда? Эта команда будет автоматически одобряться в будущем."
},
"confirmDeny": {
"title": "Отклонить выполнение",
"description": "Отклонить запрос на выполнение «{{command}}» от агента «{{agentId}}»?",
"confirmLabel": "Отклонить"
},
"toast": {
"approved": "Одобрено",
"approvedAlways": "Команда разрешена всегда",
"approvedOnce": "Команда одобрена",
"approveFailed": "Не удалось одобрить",
"denied": "Отклонено",
"deniedDesc": "Команда отклонена",
"denyFailed": "Не удалось отклонить",
"unknownError": "Неизвестная ошибка"
}
}
+129
View File
@@ -0,0 +1,129 @@
{
"title": "Резервное копирование и восстановление",
"description": "Создавайте резервные копии системы, восстанавливайте из архивов и управляйте хранилищем S3",
"tabs": {
"systemBackup": "Резервная копия системы",
"systemRestore": "Восстановление системы",
"s3Config": "Хранилище S3",
"tenantBackup": "Резервная копия арендатора"
},
"backup": {
"preflight": {
"title": "Проверка системы",
"pgDump": "pg_dump доступен",
"diskSpace": "Достаточно места на диске",
"dbSize": "Размер базы данных",
"dataDir": "Каталог данных",
"workspace": "Рабочее пространство",
"freeDisk": "Свободное место на диске",
"warnings": "Предупреждения",
"refresh": "Обновить",
"pgDumpMissing": "pg_dump недоступен или несовместим",
"goToPackages": "Перейти к пакетам"
},
"options": {
"includeDb": "Включить базу данных",
"includeFiles": "Включить файлы",
"destination": "Назначение резервной копии",
"local": "Скачать локально",
"s3": "Загрузить в S3"
},
"start": "Начать резервное копирование",
"running": "Резервное копирование...",
"complete": "Резервное копирование завершено",
"download": "Скачать резервную копию",
"uploadS3": "Загрузить в S3",
"newBackup": "Новая резервная копия",
"fileSize": "Размер файла",
"schemaVersion": "Версия схемы",
"s3History": {
"title": "Резервные копии S3",
"empty": "Резервные копии в S3 не найдены",
"name": "Файл",
"size": "Размер",
"date": "Дата"
},
"errorTitle": "Резервное копирование не удалось"
},
"restore": {
"warning": "Восстановление перезапишет существующие данные. Это действие нельзя отменить. Сначала создайте резервную копию.",
"dropzone": "Перетащите архив резервной копии .tar.gz сюда",
"dropzoneHint": "или нажмите для выбора",
"options": {
"restoreDb": "Восстановить базу данных",
"restoreFiles": "Восстановить файлы",
"dryRun": "Пробный запуск (только предпросмотр)"
},
"start": "Восстановить",
"confirmTitle": "Подтвердить восстановление системы",
"confirmDesc": "Это перезапишет вашу текущую базу данных и файлы содержимым резервной копии. Вы уверены?",
"running": "Восстановление...",
"doNotClose": "Не закрывайте эту страницу во время восстановления",
"complete": "Восстановление завершено",
"dryRunNote": "Это был пробный запуск. Изменения не внесены.",
"dbRestored": "База данных восстановлена",
"filesExtracted": "Файлы извлечены",
"bytesExtracted": "Данные восстановлены",
"schemaVersion": "Версия схемы",
"warnings": "Предупреждения",
"newRestore": "Новое восстановление",
"errorTitle": "Восстановление не удалось",
"tryAgain": "Повторить"
},
"s3": {
"title": "Конфигурация хранилища S3",
"description": "Настройте S3-совместимое хранилище для удалённых резервных копий",
"status": {
"configured": "Настроено",
"notConfigured": "Не настроено"
},
"fields": {
"accessKeyId": "Access Key ID",
"secretAccessKey": "Secret Access Key",
"secretPlaceholder": "Введите для обновления",
"bucket": "Бакет",
"region": "Регион",
"endpoint": "Эндпоинт (необязательно)",
"endpointHint": "Для S3-совместимых сервисов (MinIO, R2 и т. д.)",
"prefix": "Префикс ключа"
},
"save": "Сохранить и проверить подключение",
"saving": "Проверка подключения...",
"saveSuccess": "Конфигурация S3 сохранена, подключение проверено",
"saveError": "Не удалось сохранить конфигурацию S3"
},
"tenant": {
"title": "Резервное копирование и восстановление арендатора",
"description": "Резервное копирование или восстановление данных отдельного арендатора",
"selectTenant": "Выберите арендатора",
"selectTenantPlaceholder": "Выберите арендатора...",
"backup": {
"start": "Резервировать арендатора",
"running": "Резервное копирование арендатора...",
"complete": "Резервное копирование арендатора завершено",
"download": "Скачать",
"tableCounts": "Скопировано таблиц",
"newBackup": "Новая резервная копия"
},
"restore": {
"mode": "Режим восстановления",
"modeUpsert": "Объединить (upsert)",
"modeReplace": "Заменить всё",
"modeNew": "Новый арендатор",
"newTenantSlug": "Слаг нового арендатора",
"newTenantSlugPlaceholder": "Введите уникальный слаг для нового арендатора",
"dropzone": "Перетащите архив резервной копии арендатора сюда",
"dryRun": "Пробный запуск (только предпросмотр)",
"start": "Восстановить арендатора",
"confirmTitle": "Подтвердить восстановление арендатора",
"confirmDesc": "Это изменит данные выбранного арендатора. Вы уверены?",
"confirmDescNew": "Это создаст нового арендатора и восстановит архив в него. Вы уверены?",
"running": "Восстановление арендатора...",
"complete": "Восстановление арендатора завершено",
"tablesRestored": "Восстановлено таблиц",
"filesExtracted": "Файлы извлечены",
"dryRunNote": "Пробный запуск — изменения не внесены",
"newRestore": "Новое восстановление"
}
}
}
+786
View File
@@ -0,0 +1,786 @@
{
"title": "Каналы",
"description": "Управление экземплярами каналов",
"statusDescription": "Статус канала связи",
"addChannel": "Добавить канал",
"refresh": "Обновить",
"searchPlaceholder": "Поиск каналов...",
"emptyTitle": "Нет каналов",
"emptyDescription": "Добавьте свой первый экземпляр канала, чтобы начать работу.",
"emptyStatusDescription": "Каналы связи не настроены.",
"noMatchTitle": "Нет подходящих каналов",
"noMatchDescription": "Попробуйте другой поисковый запрос.",
"columns": {
"name": "Имя",
"type": "Тип",
"agent": "Агент",
"status": "Статус",
"enabled": "Включён",
"actions": "Действия"
},
"status": {
"running": "Работает",
"stopped": "Остановлен",
"checking": "Проверка",
"degraded": "Ухудшен",
"starting": "Запускается",
"registered": "Настроен",
"failed": "Ошибка"
},
"enabled": "Включён",
"disabled": "Отключён",
"actions": {
"reauthenticate": "Повторная аутентификация",
"authenticate": "Аутентифицируйтесь для запуска канала",
"reauthShort": "Повт. аутент.",
"openCredentials": "Открыть учётные данные",
"openAdvanced": "Открыть расширенные",
"inspect": "Изучить проблему"
},
"list": {
"failureStreak": "{{count}} ошибок подряд",
"openChannelDetail": "Откройте детали канала для просмотра последней диагностики",
"nextStep": "Следующий шаг"
},
"failureKind": {
"auth": "Аутентификация",
"config": "Конфигурация",
"network": "Сеть",
"unknown": "Внимание"
},
"delete": {
"title": "Удалить экземпляр канала",
"description": "Вы уверены, что хотите удалить «{{name}}»? Это действие нельзя отменить.",
"confirmLabel": "Удалить"
},
"form": {
"createTitle": "Создать экземпляр канала",
"editTitle": "Редактировать экземпляр канала",
"key": "Ключ *",
"keyPlaceholder": "my-telegram-bot",
"keyHint": "Уникальный слаг, используемый как идентификатор канала",
"displayName": "Отображаемое имя",
"displayNamePlaceholder": "Sales Bot",
"channelType": "Тип канала *",
"agent": "Агент *",
"selectAgent": "Выберите агента",
"credentials": "Учётные данные",
"credentialsHint": "(оставьте пустым, чтобы сохранить текущие)",
"credentialsEncrypted": "Шифруются на стороне сервера. Никогда не возвращаются в ответах API.",
"configuration": "Конфигурация",
"enabled": "Включён",
"cancel": "Отмена",
"create": "Создать",
"update": "Обновить",
"saving": "Сохранение...",
"step": "Шаг {{current}} из {{total}}",
"authenticate": "Аутентификация — {{label}}",
"configure": "Настройка — {{label}}",
"skip": "Пропустить",
"done": "Готово",
"errors": {
"keyRequired": "Ключ обязателен",
"keySlug": "Ключ должен быть корректным слагом (только строчные буквы, цифры и дефисы)",
"agentRequired": "Агент обязателен",
"requiredFields": "Обязательные: {{fields}}",
"failedSave": "Не удалось сохранить",
"failedSaveConfig": "Не удалось сохранить конфигурацию"
},
"authStatus": {
"authenticated": "Аутентифицирован",
"notAuthenticated": "Не аутентифицирован",
"useQrHint": "— Используйте кнопку входа по QR из таблицы каналов"
}
},
"detail": {
"agent": "Агент: {{name}}",
"lastChecked": "Последняя проверка: {{value}}",
"checkedRelative": "Проверено {{value}}",
"advanced": "Расширенные",
"advancedTitle": "Расширенные настройки",
"policies": "Политики",
"policiesDesc": "Политики обработки сообщений",
"network": "Сеть",
"networkDesc": "Настройка сервера и прокси",
"limits": "Ограничения",
"limitsDesc": "Ограничения на сообщения и медиа",
"streaming": "Потоковая передача",
"streamingDesc": "Параметры потоковой передачи сообщений в реальном времени",
"behavior": "Поведение",
"behaviorDesc": "Настройка поведения ответов",
"accessControl": "Контроль доступа",
"accessControlDesc": "Ограничения доступа пользователей",
"telegramManagement": "Управление Telegram",
"telegramManagementDesc": "Включите скрытый инструмент и выберите действия Telegram для агентов, использующих этот канал",
"reviewDiagnostics": "Просмотрите последнюю диагностику этого канала перед изменением настроек.",
"whatHappened": "Что произошло",
"recommendedAction": "Рекомендуемое действие",
"technicalDetail": "Технические детали",
"tabs": {
"general": "Общие",
"config": "Конфигурация",
"credentials": "Учётные данные",
"groups": "Группы",
"contexts": "Контексты",
"managers": "Менеджеры"
},
"general": {
"identity": "Идентичность",
"name": "Имя",
"nameHint": "Уникальный слаг (только для чтения)",
"channelType": "Тип канала",
"displayName": "Отображаемое имя",
"displayNamePlaceholder": "Понятное имя",
"agent": "Агент",
"selectAgent": "Выберите агента",
"enabled": "Включён",
"saved": "Сохранено",
"saveChanges": "Сохранить изменения",
"saving": "Сохранение..."
},
"credentials": {
"hint": "Оставьте поля пустыми, чтобы сохранить текущие значения. Учётные данные шифруются на стороне сервера и никогда не возвращаются в ответах API.",
"noSchema": "Нет схемы учётных данных для этого типа канала.",
"noCredentials": "Нет учётных данных для обновления",
"failedSave": "Не удалось сохранить",
"saved": "Сохранено",
"updateCredentials": "Обновить учётные данные",
"saving": "Сохранение..."
},
"config": {
"noSchema": "Нет схемы конфигурации для этого типа канала.",
"saved": "Сохранено",
"saveConfig": "Сохранить конфигурацию",
"saving": "Сохранение...",
"webhookUrlLabel": "Установите это как Event Request URL вашего приложения Lark:",
"copyPath": "Копировать путь"
},
"groups": {
"saved": "Сохранено",
"saveGroups": "Сохранить группы",
"saving": "Сохранение..."
},
"contexts": {
"description": "Просмотрите контексты канала, сохранённых участников, действующие инструменты MCP, инструменты Secure CLI и учётные данные с ограниченной областью действия.",
"emptyTitle": "Нет контекстов",
"emptyHint": "Контексты появляются после того, как этот канал получит сообщения или метаданные группы.",
"loading": "Загрузка сведений о контексте...",
"capabilities": "Возможности",
"members": "Участники",
"noCapabilities": "В этом контексте нет доступных возможностей.",
"noMembers": "Для этого контекста нет сохранённых участников.",
"none": "Нет",
"allTools": "Все инструменты",
"scopedCount": "{{count}} переопределение области",
"scopedCount_plural": "{{count}} переопределений области",
"live": "В реальном времени",
"grant": "Предоставить",
"revoke": "Отозвать",
"manageCapability": "Управление возможностью",
"scopedCredential": "Учётные данные с ограниченной областью",
"apiKeyPlaceholder": "API-ключ (только MCP)",
"envPlaceholder": "JSON окружения, например {\"TOKEN\":\"...\"}",
"secretHint": "Значения шифруются и никогда не возвращаются после сохранения.",
"saveCredential": "Сохранить учётные данные",
"deleteCredential": "Удалить учётные данные",
"grantSaved": "Предоставление контекста сохранено",
"grantDeleted": "Предоставление контекста удалено",
"credentialSaved": "Учётные данные контекста сохранены",
"credentialDeleted": "Учётные данные контекста удалены",
"invalidEnv": "Окружение должно быть объектом JSON со строковыми значениями.",
"envRequired": "Учётные данные Secure CLI требуют JSON окружения.",
"credentialRequired": "Введите API-ключ или JSON окружения.",
"actionFailed": "Действие не выполнено",
"columns": {
"name": "Имя",
"type": "Тип",
"source": "Источник",
"credentials": "Учётные данные",
"tools": "Инструменты",
"actions": "Действия"
}
},
"passiveMemory": {
"title": "Пассивное извлечение памяти",
"description": "Извлекайте долгоживущие факты из пассивного трафика групп в память, доступную для проверки.",
"pendingCount": "{{count}} в ожидании",
"unprocessedCount": "{{count}} необработанных сообщений",
"enable": "Включить пассивное извлечение",
"reviewMode": "Требовать проверку перед записью",
"interval": "Интервал (минуты)",
"messageCap": "Лимит сообщений",
"retention": "Хранение (часы)",
"minMessages": "Мин. сообщений",
"types": "Типы памяти",
"excludeUsers": "Исключённые пользователи",
"excludePatterns": "Исключённые шаблоны",
"excludeGroups": "Исключённые каналы Discord",
"excludeGroupsPlaceholder": "Выберите канал для исключения",
"manualExcludePlaceholder": "Вставьте ID канала Discord",
"addExcludedGroup": "Добавить",
"noExcludeGroups": "История каналов Discord пока не найдена.",
"noExcludedGroups": "Каналы не исключены.",
"removeExcludedGroup": "Удалить {{group}} из исключённых каналов",
"runNow": "Запустить последнюю группу",
"processAll": "Запустить все группы",
"save": "Сохранить",
"saving": "Сохранение...",
"saved": "Настройки памяти сохранены",
"saveFailed": "Не удалось сохранить настройки памяти",
"runQueued": "Извлечение памяти запущено",
"runAllDone": "Обработано {{messages}} сообщений в {{runs}} группах",
"runFailed": "Не удалось выполнить извлечение памяти",
"runAllProgress": "Прогресс запуска всех групп",
"runAllProgressStats": "{{runs}} выполнено, {{skipped}} пропущено, {{errors}} с ошибкой, {{messages}} сообщений",
"groupCompleted": "Группа {{historyKey}} завершена",
"groupSkipped": "Группа {{historyKey}} пропущена: ниже минимального количества сообщений",
"groupFailed": "Ошибка группы {{historyKey}}: {{error}}",
"itemUpdated": "Элемент памяти обновлён",
"itemFailed": "Не удалось выполнить действие с элементом памяти",
"reviewQueue": "Очередь проверки",
"loading": "Загрузка статуса памяти...",
"noRuns": "Запусков извлечения пока нет.",
"noItems": "Кандидатов в память пока нет.",
"lastRun": "Последний запуск",
"runStats": "{{messages}} сообщений, {{items}} элементов, {{redactions}} редактирований",
"approve": "Одобрить",
"reject": "Отклонить",
"delete": "Удалить",
"type": {
"people": "Люди",
"projects": "Проекты",
"decisions": "Решения",
"todos": "Задачи",
"preferences": "Предпочтения",
"events": "События"
}
},
"timeline": {
"title": "Хронология",
"firstFailed": "Первая ошибка",
"lastChecked": "Последняя проверка",
"failures": "Ошибки",
"failureStreak": "{{count}} подряд",
"failureTotal": "{{count}} всего",
"lastHealthy": "Последняя успешная",
"noData": "Недавних проверок канала пока не зафиксировано."
},
"managers": {
"description": "Управляйте тем, какие пользователи имеют права менеджера в групповых чатах.",
"groups": "Группы",
"noManagerGroups": "Нет групп с менеджерами",
"noManagerGroupsHint": "Используйте форму ниже, чтобы добавить менеджера в группу.",
"loadingManagers": "Загрузка менеджеров...",
"noManagers": "В этой группе нет менеджеров.",
"managersCount": "{{count}} менеджер",
"managersCountPlural": "{{count}} менеджеров",
"searchContacts": "Поиск контактов...",
"noResults": "Контакты не найдены",
"columns": {
"userId": "ID пользователя",
"name": "Имя",
"username": "Имя пользователя"
},
"addForm": {
"title": "Добавить менеджера в новую группу",
"hint": "Добавьте менеджера в группу, которой нет в списке выше.",
"groupId": "ID группы *",
"groupIdPlaceholder": "напр. group:telegram:-100123456",
"userId": "ID пользователя *",
"userIdPlaceholder": "Найдите или введите ID пользователя",
"displayName": "Отображаемое имя",
"username": "Имя пользователя",
"optional": "Необязательно",
"usernameWithout": "Необязательно (без @)",
"adding": "Добавление...",
"addManager": "Добавить менеджера",
"add": "Добавить",
"errors": {
"groupUserRequired": "ID группы и ID пользователя обязательны",
"failedAdd": "Не удалось добавить менеджера"
}
}
}
},
"fieldConfig": {
"token": { "label": "Токен бота", "help": "От @BotFather" },
"bot_token": { "label": "Токен бота" },
"app_token": {
"label": "Токен уровня приложения",
"help": "Токен уровня приложения с областью connections:write (требуется для Socket Mode)"
},
"user_token": {
"label": "Токен пользователя (необязательно)",
"help": "Необязательно: пользовательский OAuth-токен для собственной идентичности бота. Оставьте пустым, чтобы использовать идентичность бота по умолчанию."
},
"app_id": { "label": "App ID" },
"app_secret": { "label": "Секрет приложения" },
"encrypt_key": { "label": "Ключ шифрования", "help": "Для режима вебхука" },
"verification_token": {
"label": "Токен верификации",
"help": "Для режима вебхука"
},
"webhook_secret": { "label": "Секрет вебхука" },
"api_server": {
"label": "URL сервера API",
"help": "Пользовательский сервер Telegram Bot API для загрузки больших файлов (до 2 ГБ). Оставьте пустым для значения по умолчанию."
},
"proxy": {
"label": "HTTP-прокси",
"help": "Маршрутизировать трафик бота через HTTP-прокси"
},
"dm_policy": { "label": "Политика ЛС" },
"group_policy": { "label": "Политика групп" },
"require_mention": {
"label": "Требовать @упоминание в группах",
"disabledHint": "Мультибот-режим всегда слушает все сообщения"
},
"mention_mode": {
"label": "Поведение ответов в группах",
"help": "Как бот решает, когда отвечать в группах с несколькими ботами."
},
"history_limit": {
"label": "Лимит истории группы",
"help": "Макс. количество ожидающих сообщений группы для контекста (0 = отключено)"
},
"dm_stream": {
"label": "Потоковая передача в ЛС",
"help": "Передавать ответ постепенно в ЛС"
},
"group_stream": {
"label": "Потоковая передача в группах",
"help": "Передавать ответ постепенно в группах"
},
"draft_transport": {
"label": "Предпросмотр черновика",
"help": "Использовать скрытый предпросмотр черновика для потока ответа в ЛС — без уведомления на каждое изменение (требует потоковой передачи в ЛС)"
},
"reasoning_delivery": {
"label": "Показывать рассуждения",
"help": "Выберите, как рассуждения модели отображаются в сообщениях канала."
},
"reaction_level": { "label": "Уровень реакций" },
"media_max_mb": { "label": "Макс. размер медиа (МБ)" },
"link_preview": { "label": "Предпросмотр ссылок" },
"allow_from": { "label": "Разрешённые пользователи" },
"telegram_manager": {
"enabled": {
"label": "Включить инструмент управления Telegram",
"help": "Применяется только к агентам, работающим через этот канал Telegram. Это скрытый инструмент, который не отображается в общих профилях инструментов."
},
"allowed_actions": {
"label": "Разрешения на управление Telegram",
"help": "Выберите, какие действия Telegram может использовать агент. Если не выбрано ни одного разрешения, инструмент не предоставляется агенту."
}
},
"domain": { "label": "Домен" },
"connection_mode": {
"label": "Режим подключения",
"help": "WebSocket не требует публичного IP — только исходящее соединение"
},
"webhook_port": {
"label": "Порт вебхука",
"help": "0 = использовать основной порт шлюза (рекомендуется)"
},
"webhook_path": {
"label": "Путь вебхука",
"help": "Путь на основном сервере для событий Lark"
},
"webhook_url": { "label": "URL вебхука" },
"topic_session_mode": {
"label": "Режим сессий по темам",
"help": "Использовать root_id ветки для изоляции сессий"
},
"render_mode": { "label": "Режим рендеринга" },
"text_chunk_limit": {
"label": "Лимит фрагмента текста",
"help": "Макс. количество символов в сообщении"
},
"group_allow_from": {
"label": "Разрешённые пользователи группы",
"help": "Отдельный список разрешённых отправителей для групп"
},
"native_stream": {
"label": "Нативная потоковая передача (агенты и AI-приложения)",
"help": "Использовать API ChatStreamer от Slack для нативной потоковой передачи. При недоступности выполняется откат к редактированию на месте."
},
"debounce_delay": {
"label": "Задержка дебаунса (мс)",
"help": "Миллисекунды ожидания перед отправкой быстрых сообщений. Установите 0, чтобы отключить."
},
"thread_ttl": {
"label": "TTL участия в ветке (часы)",
"help": "Часов до того, как бот перестанет автоматически отвечать в ветках, в которых он участвовал. 0 = всегда требовать @упоминание."
},
"skills": {
"label": "Фильтр навыков",
"help": "Ограничить доступные навыки для этой группы"
},
"tools": {
"label": "Список разрешённых инструментов",
"help": "Ограничить, какие инструменты агент может использовать в этой группе"
},
"system_prompt": { "label": "Системный промпт" },
"chat_behavior": {
"enabled": {
"label": "Человекоподобная доставка",
"help": "Переопределение поведения доставки на уровне канала. Настройки канала имеют приоритет над настройками агента и рабочего пространства."
},
"intermediate_replies": {
"enabled": {
"label": "Промежуточные ответы",
"help": "Отправлять естественные сообщения о ходе выполнения во время длительных или насыщенных инструментами запусков. Эти сообщения не добавляются в историю сессии."
},
"mode": {
"label": "Режим промежуточных ответов",
"help": "Выберите, генерируются ли обновления хода выполнения моделью доставки или отключены для этого канала."
},
"provider": {
"label": "Промежуточный провайдер",
"help": "Необязательный провайдер для сообщений о ходе выполнения. Оставьте пустым, чтобы наследовать провайдера агента; выберите здесь быстрый и дешёвый провайдер."
},
"model": {
"label": "Промежуточная модель",
"help": "Необязательная модель для сообщений о ходе выполнения. Оставьте пустым, чтобы наследовать модель агента; допускаются пользовательские имена моделей."
},
"timeout_ms": {
"label": "Промежуточный тайм-аут (мс)",
"help": "Максимальное время ожидания модели доставки перед пропуском промежуточного обновления."
},
"max_tokens": {
"label": "Промежуточный макс. токенов",
"help": "Лимит токенов для каждого генерируемого сообщения о ходе выполнения. Держите его небольшим, чтобы обновления оставались краткими."
},
"max_chars": {
"label": "Промежуточный макс. символов",
"help": "Лимит символов после генерации, чтобы сообщения о ходе выполнения не превращались в полные ответы."
}
},
"quick_ack": {
"enabled": {
"label": "Быстрое подтверждение",
"help": "Отправлять короткое естественное подтверждение перед началом длительной работы. Это сообщение не добавляется в историю сессии."
},
"mode": {
"label": "Режим быстрого подтверждения",
"help": "Генерируемые режимы используют настроенный провайдер/модель доставки. Режим фиксированного шаблона — единственный режим, отправляющий текст шаблона."
},
"provider": {
"label": "Провайдер быстрого подтверждения",
"help": "Необязательный провайдер для быстрых подтверждений. Оставьте пустым, чтобы наследовать провайдера агента; выберите здесь быстрый и дешёвый провайдер."
},
"model": {
"label": "Модель быстрого подтверждения",
"help": "Необязательная модель для быстрых подтверждений. Оставьте пустым, чтобы наследовать модель агента; допускаются пользовательские имена моделей."
},
"timeout_ms": {
"label": "Тайм-аут быстрого подтверждения (мс)",
"help": "Максимальное время ожидания модели подтверждения перед пропуском сгенерированного подтверждения."
},
"max_tokens": {
"label": "Макс. токенов быстрого подтверждения",
"help": "Лимит токенов для подтверждения. Держите его небольшим, чтобы оно читалось как квитанция, а не как ответ."
},
"max_chars": {
"label": "Макс. символов быстрого подтверждения",
"help": "Лимит символов после генерации, чтобы сообщения подтверждения оставались компактными."
}
},
"final_split": {
"enabled": {
"label": "Разбиение финального ответа",
"help": "Разбивать длинные финальные ответы на несколько сообщений канала. Это отдельно от рассуждений и сообщений о ходе выполнения."
}
}
},
"platform": { "label": "Платформа", "help": "Выберите платформу, которую обслуживает эта страница Pancake." },
"tiktok_type": { "label": "Тип TikTok", "help": "Выберите тип аккаунта TikTok для этой страницы" },
"features.private_reply": {
"label": "Приватный ответ (комментарий → ЛС)",
"help": "Отправить единоразовое ЛС комментаторам после публичного ответа. Только Facebook/Instagram. Meta разрешает ЛС в течение 7 дней после комментария."
},
"private_reply_message": {
"label": "Сообщение в ЛС",
"help": "Поддерживает плейсхолдеры commenter_name и post_title. Пусто = текст на английском по умолчанию."
}
},
"fieldOptions": {
"dm_policy": {
"pairing": "Привязка (требуется код)",
"open": "Открыто (принимать всех)",
"allowlist": "Только по списку разрешённых",
"disabled": "Отключено"
},
"group_policy": {
"open": "Открыто (принимать всех)",
"pairing": "Привязка (требуется одобрение)",
"allowlist": "Только по списку разрешённых",
"disabled": "Отключено"
},
"mention_mode": {
"strict": "По умолчанию (следовать настройке @упоминания)",
"yield": "Мультибот (отвечать, если не @упомянут другой бот)"
},
"reaction_level": {
"off": "Выкл",
"minimal": "Минимальный",
"full": "Полный"
},
"reasoning_delivery": {
"streaming_only": "Только при потоковой передаче",
"always_bubbles": "Всегда отдельными сообщениями",
"off": "Выкл"
},
"telegram_manager": {
"allowed_actions": {
"topic": "Управление темами",
"message": "Управление сообщениями",
"member": "Управление участниками",
"invite": "Управление ссылками-приглашениями",
"chat": "Информация/настройки чата",
"join_request": "Одобрение запросов на вступление"
}
},
"chat_behavior": {
"enabled": {
"inherit": "Наследовать от шлюза",
"true": "Включено",
"false": "Отключено"
},
"intermediate_replies": {
"enabled": {
"inherit": "Наследовать от шлюза",
"true": "Включено",
"false": "Отключено"
},
"mode": {
"inherit": "Наследовать от шлюза",
"sidecar_generated": "Сгенерировано sidecar",
"off": "Выкл"
}
},
"quick_ack": {
"enabled": {
"inherit": "Наследовать от шлюза",
"true": "Включено",
"false": "Отключено"
},
"mode": {
"inherit": "Наследовать от шлюза",
"sidecar_generated": "Сгенерировано sidecar",
"llm_generated": "Сгенерировано LLM",
"fixed_template": "Фиксированный шаблон",
"off": "Выкл"
}
},
"final_split": {
"enabled": {
"inherit": "Наследовать от шлюза",
"true": "Включено",
"false": "Отключено"
}
}
},
"domain": {
"lark": "Lark (глобальный)",
"feishu": "Feishu (Китай)"
},
"connection_mode": {
"webhook": "Webhook",
"websocket": "WebSocket (рекомендуется)"
},
"topic_session_mode": {
"disabled": "Отключено",
"enabled": "Включено"
},
"render_mode": {
"auto": "Авто",
"raw": "Без обработки",
"card": "Карточка"
},
"platform": {
"facebook": "Facebook",
"instagram": "Instagram",
"threads": "Threads (бета)",
"tiktok": "TikTok",
"youtube": "YouTube (бета)",
"shopee": "Shopee",
"line": "Line",
"google": "Google",
"chat_plugin": "Chat Plugin",
"lazada": "Lazada",
"tokopedia": "Tokopedia"
}
},
"groupOverrides": {
"title": "Переопределения групп и тем",
"hint": "Переопределяйте настройки канала по умолчанию для каждого группового чата или темы форума. Используйте «*» как ID группы для настроек по умолчанию (маска).",
"groupLabel": "Группа: {{id}}",
"groupWildcard": "* (маска)",
"addGroupPlaceholder": "ID чата (напр. -100123456) или *",
"addGroup": "Добавить группу",
"knownGroups": "Известные группы",
"topicOverrides": "Переопределения тем",
"topicLabel": "Тема: {{id}}",
"addTopicPlaceholder": "ID ветки темы",
"addTopic": "Добавить тему",
"fieldConfig": {
"dm_stream": {
"label": "Потоковая передача в ЛС",
"help": "Передавать ответ постепенно в ЛС"
},
"group_stream": {
"label": "Потоковая передача в группах",
"help": "Передавать ответ постепенно в группах"
},
"draft_transport": {
"label": "Предпросмотр черновика",
"help": "Использовать скрытый предпросмотр черновика для потока ответа в ЛС — без уведомления на каждое изменение (требует потоковой передачи в ЛС)"
},
"reasoning_delivery": {
"label": "Показывать рассуждения",
"help": "Выберите, как рассуждения модели отображаются в сообщениях канала."
}
},
"fields": {
"groupPolicy": "Политика группы",
"requireMention": "Требовать @упоминание",
"enabled": "Включён",
"allowedUsers": "Разрешённые пользователи",
"allowedUsersPlaceholder": "По одному ID пользователя в строке или через запятую",
"skillsFilter": "Фильтр навыков",
"skillsPlaceholder": "По одному имени навыка в строке (пусто = наследовать)",
"toolAllow": "Разрешённые инструменты",
"toolAllowPlaceholder": "Выберите разрешённые инструменты (пусто = наследовать все)...",
"toolAllowHint": "Ограничьте, какие инструменты доступны в этой группе. Поддерживает имена групп, такие как «group:web», «group:fs». Пусто = наследовать все инструменты.",
"systemPrompt": "Системный промпт",
"systemPromptPlaceholder": "Дополнительный системный промпт для этой группы/темы",
"inherit": "Наследовать (по умолчанию для канала)",
"yes": "Да",
"no": "Нет"
}
},
"wizard": {
"zaloPersonal": {
"createLabel": "Создать и аутентифицировать",
"formBanner": "После создания вы пройдёте аутентификацию по QR-коду и настроите разрешённых пользователей."
},
"whatsapp": {
"createLabel": "Создать и сканировать QR",
"formBanner": "После создания отсканируйте QR-код в WhatsApp для аутентификации."
}
},
"fallback": {
"authRequiredSummary": "Требуется аутентификация",
"authRequiredDetail": "Экземпляр канала включён, но требует входа перед подключением.",
"authRequiredHeadline": "Переподключите сессию канала",
"authRequiredHint": "Аутентифицируйте этот канал повторно, чтобы восстановить текущую сессию.",
"missingCredentialsSummary": "Отсутствуют учётные данные",
"missingCredentialsDetail": "Экземпляр канала включён, но обязательные учётные данные неполные.",
"missingCredentialsHeadline": "Заполните обязательные учётные данные",
"missingCredentialsHint": "Откройте учётные данные и заполните отсутствующие или недействительные значения для этого канала."
},
"scopes": {
"title": "Требуемые разрешения API",
"description": "Ваше приложение Lark/Feishu должно иметь эти области, включённые в Developer Console. После добавления разрешений опубликуйте новую версию приложения.",
"publishReminder": "После добавления областей установите Contact Range на «Все участники» и опубликуйте новую версию приложения, чтобы изменения вступили в силу."
},
"toast": {
"created": "Канал создан",
"createdDesc": "{{name}} добавлен",
"updated": "Канал обновлён",
"deleted": "Канал удалён",
"failedCreate": "Не удалось создать канал",
"failedUpdate": "Не удалось обновить канал",
"failedDelete": "Не удалось удалить канал"
},
"zalo": {
"allowedUsers": "Разрешённые пользователи",
"loadContacts": "Загрузить контакты",
"loading": "Загрузка...",
"searchContacts": "Поиск контактов...",
"friends": "Друзья",
"groups": "Группы",
"membersCount": "{{count}} участников",
"noContacts": "Контакты не найдены",
"noContactsMatch": "Нет контактов, соответствующих «{{search}}»",
"addManualPlaceholder": "Добавить ID вручную",
"add": "Добавить",
"zaloIdsHint": "ID пользователей или групп Zalo",
"completeQrLogin": "Завершите вход по QR, чтобы загрузить контакты",
"loginQr": "Вход по QR — {{name}}",
"loginSuccessful": "Вход выполнен! Канал запускается...",
"generatingQr": "Генерация QR-кода...",
"scanHint": "Отсканируйте в приложении Zalo (истекает через ~100 с)",
"loginSuccessLoading": "Вход выполнен! Загрузка контактов...",
"retry": "Повторить",
"close": "Закрыть",
"skip": "Пропустить"
},
"whatsapp": {
"loginSuccessLoading": "✅ WhatsApp подключён! Загрузка канала...",
"waitingForQr": "Ожидание QR-кода...",
"scanHint": "Откройте WhatsApp → нажмите «Вы» → Связанные устройства → Привязать устройство",
"initializing": "Инициализация...",
"skip": "Пропустить",
"retry": "Повторить",
"close": "Закрыть",
"reauthTitle": "Привязать WhatsApp — {{name}}",
"reauthDescription": "Отсканируйте QR-код в WhatsApp, чтобы привязать устройство.",
"alreadyLinked": "✅ Устройство уже привязано",
"alreadyLinkedDetail": "WhatsApp подключён. Чтобы привязать другое устройство, нажмите «Перепривязать» — это завершит текущую сессию.",
"relinkDevice": "Перепривязать устройство",
"connectedSuccess": "✅ WhatsApp успешно подключён!",
"tabQrCode": "QR-код"
},
"bitrix24": {
"portalSelect": {
"placeholder": "Выберите портал...",
"empty": "Порталы Bitrix24 пока не подключены.",
"createFirst": "Подключите свой первый портал Bitrix24",
"createNew": "Создать новый портал",
"pendingBadge": "Установка в ожидании — нажмите для продолжения",
"loadError": "Не удалось загрузить порталы. Обновите, чтобы повторить."
},
"errors": {
"portalRequired": "Пожалуйста, выберите портал.",
"portalNotInstalled": "Этот портал не завершил авторизацию. Авторизуйте его перед созданием канала."
},
"create": {
"title": "Подключить портал Bitrix24",
"submit": "Создать и авторизовать →",
"fields": {
"name": "Имя портала",
"nameHint": "Внутренний слаг. Автозаполняется из домена; вы можете его изменить.",
"domain": "Домен",
"clientId": "Client ID",
"clientSecret": "Client Secret"
},
"errors": {
"invalidName": "Используйте строчные буквы, цифры, дефисы, подчёркивания (2-64 символа).",
"invalidDomain": "Должен быть корректным именем хоста (напр. mycorp.bitrix24.com, mycorp.bitrix24.vn или ваш самостоятельно размещённый домен).",
"duplicateName": "Портал с таким именем уже существует.",
"forbidden": "Для создания порталов необходимы права администратора арендатора.",
"gatewayURLUnknown": "Сначала откройте UI goclaw через ваш публичный URL (не localhost), затем повторите."
},
"help": {
"title": "Как получить Client ID и Secret?",
"step1": "Откройте ваш портал Bitrix24 от имени администратора.",
"step2": "Перейдите в Ресурсы разработчика → Другое → Локальное приложение → Добавить.",
"step3": "Установите Handler URL на:",
"step4": "Отметьте необходимые области:",
"step5": "Сохраните → скопируйте Application ID и Key в форму выше.",
"localDevWarning": "Вы на localhost — Bitrix24 не может достучаться до этого URL. Сначала используйте Cloudflare Tunnel или ваш публичный домен."
},
"authorize": {
"title": "Авторизовать «{{name}}»",
"openButton": "Открыть страницу авторизации",
"waiting": "Ожидание авторизации...",
"installed": "Портал успешно установлен!",
"timedOut": "Авторизация ещё не завершена. Вы можете продолжить из выпадающего списка.",
"closeResumeLater": "Закрыть (продолжить позже)",
"urlUnknown": "URL установки недоступен. Откройте UI goclaw через ваш публичный URL и повторите из выпадающего списка."
}
}
}
}
+34
View File
@@ -0,0 +1,34 @@
{
"deleteChat": "Удалить чат",
"deleteChatConfirm": "Это навсегда удалит эту беседу и все её сообщения.",
"newChat": "Новый чат",
"openSessions": "Открытые сессии",
"readOnly": "Только чтение — эта сессия принадлежит другому пользователю",
"contextUsage": {
"tooltip": "{{used}} / {{max}} токенов ({{percent}}%) · сжатий: {{compactions}} · последнее: {{lastCompact}}",
"never": "никогда"
},
"empty": {
"title": "Начните беседу",
"description": "Отправьте сообщение, чтобы начать общение с агентом."
},
"media": {
"image": "Изображение",
"video": "Видео",
"audio": "Аудио",
"voice": "Голосовое сообщение",
"document": "Документ",
"animation": "Анимация",
"attached": "прикреплено"
},
"forwardedFrom": "Переслано от",
"replyingTo": "Ответ на",
"error": {
"notConnected": "Нет соединения. Пожалуйста, дождитесь установления соединения."
},
"selectAgent": {
"title": "Выберите агента",
"description": "Выберите агента, чтобы начать общение"
},
"imageGenDownloadName": "generated-{{timestamp}}.png"
}
@@ -0,0 +1,179 @@
{
"title": "Учётные данные CLI",
"description": "Управление защищёнными бинарными файлами CLI, доступными агентам с внедрёнными учётными данными.",
"addCredential": "Добавить учётные данные",
"emptyTitle": "Учётных данных CLI пока нет",
"emptyDescription": "Добавьте учётные данные CLI, чтобы агенты могли выполнять аутентифицированные команды CLI.",
"columns": {
"binary": "Бинарный файл",
"scope": "Область",
"timeout": "Тайм-аут",
"restricted": "Ограничено"
},
"delete": {
"title": "Удалить учётные данные CLI",
"description": "Удалить «{{name}}»? Зависящие от них агенты потеряют доступ.",
"confirm": "Удалить"
},
"form": {
"createTitle": "Добавить учётные данные CLI",
"editTitle": "Изменить учётные данные CLI",
"preset": "Пресет",
"presetPlaceholder": "Выберите пресет (необязательно)",
"noPreset": "Без пресета (вручную)",
"presetHint": "Выбор пресета автоматически заполняет поля и показывает необходимые переменные окружения.",
"encryptedHint": "Значения зашифрованы и никогда не отображаются. Имена переменных перечислены ниже; оставьте значение пустым, чтобы сохранить хранимый секрет, или введите новое значение для замены.",
"envVars": "Переменные окружения",
"binaryName": "Имя бинарного файла",
"binaryPath": "Путь к бинарному файлу",
"denyArgs": "Запрещённые аргументы",
"denyVerbose": "Запрещённые подробные аргументы",
"timeout": "Тайм-аут (с)",
"tips": "Подсказки",
"agentId": "Агент",
"agentIdHint": "необязательно — оставьте пустым для глобального",
"commaSeparated": "через запятую",
"binaryNameRequired": "Имя бинарного файла обязательно.",
"failedToSave": "Не удалось сохранить.",
"addEnvVar": "Добавить переменную",
"noEnvVarsHint": "Нажмите «Добавить переменную», чтобы задать переменные окружения для этого инструмента CLI.",
"envKeyPlaceholder": "ENV_VAR_NAME",
"envValuePlaceholder": "значение",
"envKindSensitive": "Конфиденциальное",
"envKindValue": "Значение",
"envValueWarning": "Значения в открытом виде видны авторизованным пользователям.",
"envValueSuspicious": "Это значение в открытом виде похоже на токен, пароль или ключ.",
"invalidEnvKey": "«{{key}}» не является допустимым именем переменной окружения (используйте A-Z, 0-9, подчёркивание).",
"binaryPathHint": "Оставьте пустым для автоопределения из PATH",
"checkBinary": "Проверить",
"binaryFound": "Найдено в {{path}}",
"binaryNotFound": "Бинарный файл не найден в PATH сервера",
"checking": "Проверка...",
"isGlobal": "Доступно всем агентам",
"isGlobalHint": "Когда отключено, этот CLI могут использовать только агенты с явными разрешениями"
},
"placeholders": {
"binaryName": "напр. gh",
"binaryPath": "/usr/local/bin/...",
"description": "Что делает этот инструмент CLI",
"denyArgs": "--admin, --force",
"denyVerbose": "-v, --verbose",
"tips": "Подсказки по использованию для агента",
"agentId": "Глобально (все агенты)"
},
"toast": {
"created": "Учётные данные CLI созданы",
"createdDesc": "«{{name}}» успешно добавлено.",
"createFailed": "Не удалось создать учётные данные",
"updated": "Учётные данные CLI обновлены",
"updateFailed": "Не удалось обновить учётные данные",
"deleted": "Учётные данные CLI удалены",
"deleteFailed": "Не удалось удалить учётные данные"
},
"agentAccess": {
"title": "Доступ агентов",
"description": "Управляйте тем, какие агенты могут использовать {{name}} и какие учётные данные они применяют.",
"credentialsTab": "Учётные данные",
"grantsTab": "Политика доступа"
},
"agentCredentials": {
"title": "Учётные данные агента",
"description": "Настройте PAT, ключ SSH или учётные данные окружения, которые {{name}} может использовать, когда его запускает выбранный агент.",
"securityHint": "Любой, у кого есть доступ к выбранному агенту, может заставить этого агента использовать эти учётные данные.",
"agent": "Агент",
"env": "Переменные окружения",
"add": "Добавить учётные данные агента",
"save": "Сохранить",
"edit": "Изменить",
"delete": "Удалить",
"back": "Назад",
"empty": "Учётные данные агента не настроены",
"saved": "Учётные данные агента сохранены",
"saveFailed": "Не удалось сохранить учётные данные агента",
"deleted": "Учётные данные агента удалены",
"deleteFailed": "Не удалось удалить учётные данные агента",
"envRequired": "Требуется хотя бы одна переменная окружения"
},
"userCredentials": {
"title": "Расширенные переопределения пользователя",
"description": "Необязательные переопределения для {{name}} на уровне пользователя. Для обычной настройки git PAT или SSH используйте «Учётные данные агента».",
"userId": "ID пользователя",
"userIdPlaceholder": "user-id или email",
"env": "Переменные окружения",
"addEnv": "Добавить переменную",
"add": "Добавить",
"save": "Сохранить",
"edit": "Изменить",
"delete": "Удалить",
"back": "Назад",
"close": "Закрыть",
"empty": "Учётные данные пользователя не настроены",
"saved": "Учётные данные пользователя сохранены",
"saveFailed": "Не удалось сохранить учётные данные пользователя",
"deleted": "Учётные данные пользователя удалены",
"deleteFailed": "Не удалось удалить учётные данные пользователя",
"envRequired": "Требуется хотя бы одна переменная окружения",
"mergeHint": "Используйте только для личных переопределений. Пользователи чатов (Telegram, Discord и т. д.) должны быть сначала объединены с пользователем арендатора через страницу «Контакты».",
"credentialType": "Тип учётных данных",
"credentialTypeEnv": "Переменные окружения (устаревшее)",
"credentialTypePAT": "Личный токен доступа (PAT)",
"credentialTypeSSH": "Приватный ключ SSH",
"hostScope": "Область хоста",
"hostScopePlaceholder": "github.com или gitlab.example.com:2222",
"hostScopeRequired": "Область хоста обязательна для учётных данных PAT и SSH",
"hostScopeInvalid": "Область хоста должна быть допустимым именем хоста (необязательно :порт)",
"token": "Личный токен доступа",
"tokenPlaceholder": "ghp_… / glpat-… (никогда не отображается обратно)",
"sshKey": "Приватный ключ SSH (PEM)",
"sshKeyPlaceholder": "-----BEGIN OPENSSH PRIVATE KEY-----\n…\n-----END OPENSSH PRIVATE KEY-----",
"sshKeyInvalid": "Ключ SSH не является допустимым незашифрованным приватным ключом PEM",
"passphraseUnsupported": "Ключи SSH, защищённые парольной фразой, не поддерживаются. Укажите незашифрованный ключ.",
"secretMasked": "•••••••• (сохранено, оставьте пустым для сохранения)",
"noSecret": "Секрет ещё не сохранён"
},
"grants": {
"title": "Разрешения агентов — {{name}}",
"currentGrants": "Текущие разрешения",
"addGrant": "Добавить разрешение",
"editGrant": "Изменить разрешение",
"selectAgent": "Выберите агента...",
"usingDefaults": "Используются значения по умолчанию бинарного файла",
"overrideTimeout": "Переопределить тайм-аут (секунды)",
"overrideDenyArgs": "Переопределить запрещённые аргументы",
"overrideDenyVerbose": "Переопределить запрещённые подробные аргументы",
"overrideTips": "Переопределить подсказки",
"defaultPlaceholder": "по умолчанию",
"grant": "Разрешить",
"update": "Обновить",
"agentRequired": "Пожалуйста, выберите агента",
"envVars": {
"title": "Переменные окружения",
"overrideToggle": "Переопределить значения по умолчанию бинарного файла",
"overrideHelp": "Когда включено, переменные окружения этого разрешения полностью заменяют переменные окружения бинарного файла по умолчанию",
"reveal": "Показать значения",
"revealHidden": "Скрыто — нажмите «Показать» для просмотра",
"revealError": "Не удалось показать переменные окружения — превышен лимит запросов или отказано в доступе",
"addKey": "Добавить переменную",
"keyPlaceholder": "КЛЮЧ",
"valuePlaceholder": "Значение",
"deniedKey": "Ключ '{{key}}' не разрешён",
"emptyState": "Нет переопределений окружения — применяются значения бинарного файла по умолчанию"
},
"chips": {
"title": "Выдано",
"none": "Нет разрешений",
"countMore": "+ещё {{count}}"
},
"toast": {
"granted": "Разрешение агента создано",
"grantFailed": "Не удалось создать разрешение",
"updated": "Разрешение агента обновлено",
"updateFailed": "Не удалось обновить разрешение",
"revoked": "Разрешение агента отозвано",
"revokeFailed": "Не удалось отозвать разрешение"
}
},
"list": {
"truncated": "Показаны первые 20 — используйте поиск или фильтр, чтобы найти больше"
}
}
+142
View File
@@ -0,0 +1,142 @@
{
"refresh": "Обновить",
"cancel": "Отмена",
"confirm": "Подтвердить",
"delete": "Удалить",
"save": "Сохранить",
"edit": "Изменить",
"create": "Создать",
"add": "Добавить",
"view": "Просмотр",
"filter": "Фильтр",
"search": "Поиск",
"retry": "Повторить",
"manage": "Управление",
"uploadLabel": "Загрузить",
"close": "Закрыть",
"back": "Назад",
"update": "Обновить",
"enabled": "Включено",
"disabled": "Отключено",
"yes": "Да",
"no": "Нет",
"loading": "Загрузка...",
"saving": "Сохранение...",
"creating": "Создание...",
"connecting": "Подключение...",
"connected": "Подключено",
"disconnected": "Отключено",
"running": "Выполняется",
"stopped": "Остановлено",
"pending": "В ожидании",
"completed": "Завершено",
"failed": "Ошибка",
"cancelled": "Отменено",
"unknown": "Неизвестно",
"active": "активно",
"items": "элементов",
"rows": "Строки",
"pageOf": "Страница {{page}} из {{totalPages}}",
"messages": "сообщений",
"cached": "кэшировано",
"live": "В реальном времени",
"noDescription": "Нет описания",
"unsavedChanges": "Несохранённые изменения",
"tryDifferentSearch": "Попробуйте другой поисковый запрос.",
"notSet": "Не задано",
"default": "по умолчанию",
"optional": "необязательно",
"required": "обязательно",
"actions": "Действия",
"status": "Статус",
"name": "Название",
"description": "Описание",
"type": "Тип",
"none": "нет",
"all": "Все",
"global": "Глобально",
"agent": "Агент",
"saved": "Сохранено",
"saveChanges": "Сохранить изменения",
"saveConfig": "Сохранить конфигурацию",
"checkAndCreate": "Проверить и создать",
"checking": "Проверка...",
"format": "Форматировать JSON",
"invalidJson": "Неверный синтаксис JSON",
"usingGlobalDefaults": "Используются глобальные значения по умолчанию из config.json",
"disconnectedGateway": "Соединение со шлюзом потеряно. Попытка переподключения...",
"serverUnreachable": "Сервер недоступен",
"serverUnreachableDesc": "Не удаётся подключиться к серверу шлюза. Проверьте, что сервер запущен.",
"reconnecting": "Переподключение...",
"noFiles": "Файлы не найдены.",
"selectFileToView": "Выберите файл для просмотра содержимого",
"typeToConfirmPrefix": "Введите",
"typeToConfirmSuffix": "для подтверждения.",
"searchPlaceholder": "Поиск...",
"noSessions": "Пока нет сессий. Начните чат!",
"noAgentsAvailable": "Нет доступных агентов",
"selectAgent": "Выберите агента",
"sendMessage": "Отправить сообщение... (Shift+Enter — новая строка)",
"stopGeneration": "Остановить генерацию",
"sendMessageTitle": "Отправить сообщение",
"sendFollowUp": "Отправить уточняющее сообщение",
"attachFile": "Прикрепить файл",
"recordVoice": "Записать голосовое сообщение",
"stopRecording": "Остановить запись",
"cancelRecording": "Отменить запись",
"thinking": "Размышление",
"thinkingStreaming": "Размышление...",
"toolArguments": "Аргументы",
"toolResult": "Результат",
"skillActivating": "Активация...",
"skillActivated": "Активировано",
"toolRunning": "Выполняется...",
"toolDone": "Готово",
"toolFailed": "Ошибка",
"filesBack": "Файлы",
"noProvidersConfigured": "Провайдеры не настроены",
"loadingModels": "Загрузка моделей...",
"modelVerified": "Модель проверена",
"verificationFailed": "Проверка не удалась",
"provider": "Провайдер",
"model": "Модель",
"selectProvider": "Выберите провайдера",
"enterOrSelectModel": "Введите или выберите модель",
"useCustomModel": "Использовать свою:",
"providerTip": "Название провайдера LLM. Должно совпадать с настроенным провайдером.",
"modelTip": "ID модели для использования.",
"check": "Проверить",
"builtinTools": "Встроенные",
"customTools": "Пользовательские",
"selectOrTypeTools": "Выберите или введите названия инструментов...",
"selectOrTypeSkills": "Выберите или введите названия навыков...",
"typeAndPressEnter": "Введите и нажмите Enter...",
"copyCode": "Копировать код",
"copy": "Копировать",
"download": "Скачать",
"errorBoundary": "Что-то пошло не так при отображении этого раздела.",
"csvRows": "csv ({{count}} строк)",
"failedToLoadImage": "Не удалось загрузить изображение",
"deleteFolder": "Удалить папку",
"deleteFile": "Удалить файл",
"loadMore": "Загрузить ещё...",
"viewCard": "Вид карточками",
"viewList": "Вид списком",
"done": "Готово",
"upload": {
"title": "Загрузка файлов",
"dropOrClick": "Перетащите файлы сюда или нажмите для выбора",
"dropHere": "Перетащите файлы сюда",
"maxSize": "Максимум 50 МБ на файл",
"blockedType": "Тип файла {{ext}} не разрешён",
"tooLarge": "Файл превышает лимит 50 МБ",
"failed": "Ошибка загрузки",
"readyCount": "{{ready}} из {{total}} файлов готово",
"successCount": "{{success}} из {{total}} файлов загружено",
"uploading": "Загрузка...",
"uploadCount": "Загрузить {{count}} файл(ов)"
},
"errors": {
"serverError": "Что-то пошло не так. Пожалуйста, попробуйте позже."
}
}
+414
View File
@@ -0,0 +1,414 @@
{
"title": "Конфигурация",
"description": "Управление шлюзом, настройками агентов по умолчанию, инструментами и интеграциями",
"noConfig": "Конфигурация не загружена",
"noConfigDescription": "Не удалось загрузить файл конфигурации. Возможно, шлюз недоступен.",
"retry": "Повторить",
"warning": "Изменения здесь глобально влияют на всех агентов и все каналы. Неправильная настройка может нарушить работу шлюза.",
"save": "Сохранить",
"saving": "Сохранение...",
"saved": "Сохранено",
"failedToSave": "Не удалось сохранить конфигурацию",
"saveConfig": "Сохранить конфигурацию",
"usingGlobalDefaults": "Используются глобальные значения по умолчанию",
"tabs.server": "Сервер",
"tabs.behavior": "Поведение",
"tabs.aiDefaults": "Настройки ИИ по умолчанию",
"tabs.quota": "Квота",
"tabs.tools": "Инструменты",
"tabs.integrations": "Интеграции",
"server.title": "Сервер шлюза",
"server.description": "Привязка к сети, токен аутентификации и контроль доступа",
"branding.title": "Настройки внешнего вида",
"branding.description": "Публичное имя приложения, метаданные, иконки, логотип, фавикон и ресурсы для превью в соцсетях",
"branding.appName": "Имя приложения",
"branding.appNameTip": "Полное имя приложения, отображаемое в метаданных и будущих брендированных элементах UI.",
"branding.appShortName": "Короткое имя",
"branding.appShortNameTip": "Компактное имя приложения для небольших элементов UI или экранов установки.",
"branding.themeColor": "Цвет темы",
"branding.themeColorTip": "Цвет темы браузера, используемый поддерживаемыми клиентами.",
"branding.metaTitle": "Meta-заголовок",
"branding.metaTitleTip": "Заголовок HTML-документа. Оставьте пустым, чтобы использовать встроенное значение по умолчанию.",
"branding.metaDescription": "Meta-описание",
"branding.metaDescriptionTip": "HTML meta-описание для превью в поиске.",
"branding.metaDescriptionPlaceholder": "Приватный шлюз ИИ-агентов",
"branding.metaKeywords": "Meta-ключевые слова",
"branding.metaKeywordsTip": "Необязательные ключевые слова через запятую.",
"branding.ogTitle": "Заголовок Open Graph",
"branding.ogTitleTip": "Заголовок, используемый при публикации сайта в социальных платформах.",
"branding.ogDescription": "Описание Open Graph",
"branding.ogDescriptionTip": "Описание, используемое при публикации сайта в социальных платформах.",
"branding.logoUrl": "URL логотипа",
"branding.logoUrlTip": "Внешний URL или загруженный путь логотипа /branding-assets/*.",
"branding.faviconUrl": "URL фавикона",
"branding.faviconUrlTip": "Внешний URL или загруженный путь фавикона /branding-assets/*.",
"branding.appleTouchIconUrl": "URL иконки Apple Touch",
"branding.appleTouchIconUrlTip": "Внешний URL или загруженный путь touch-иконки /branding-assets/*.",
"branding.ogImageUrl": "URL изображения Open Graph",
"branding.ogImageUrlTip": "Внешний URL или загруженное изображение /branding-assets/* для превью в соцсетях.",
"branding.upload": "Загрузить ресурс",
"branding.uploaded": "Ресурс брендинга загружен",
"branding.uploadFailed": "Не удалось загрузить ресурс брендинга",
"branding.uploadErrors.too_large": "Файл должен быть не больше 2 МБ.",
"branding.uploadErrors.unsupported_type": "Используйте файлы SVG, PNG, JPG, WEBP или ICO.",
"gateway.host": "Хост",
"gateway.hostTip": "Сетевой интерфейс, который прослушивает шлюз. Используйте 0.0.0.0 для прослушивания всех интерфейсов.",
"gateway.port": "Порт",
"gateway.portTip": "TCP-порт, к которому привязываются WebSocket и HTTP-сервер шлюза.",
"gateway.token": "Токен аутентификации",
"gateway.tokenTip": "Bearer-токен, необходимый для всех клиентских подключений. Оставьте пустым, чтобы отключить аутентификацию.",
"gateway.tokenManaged": "Токен управляется через переменную окружения и не может быть изменён здесь.",
"gateway.ownerIds": "ID владельцев",
"gateway.ownerIdsTip": "ID пользователей с правами администратора. Разделяйте несколько ID клавишей Enter.",
"gateway.ownerIdsPlaceholder": "Введите ID владельца...",
"gateway.allowedOrigins": "Разрешённые источники",
"gateway.allowedOriginsTip": "Разрешённые CORS-источники для HTTP API. Используйте * для разрешения всех источников.",
"gateway.allowedOriginsPlaceholder": "https://yourdomain.com",
"gateway.maxMessageChars": "Макс. символов в сообщении",
"gateway.maxMessageCharsTip": "Максимально допустимое количество символов во входящем сообщении. Сообщения, превышающие этот лимит, отклоняются.",
"gateway.rateLimitRpm": "Ограничение частоты (RPM)",
"gateway.rateLimitRpmTip": "Максимальное количество запросов в минуту на пользователя. Установите 0, чтобы отключить ограничение частоты.",
"gateway.inboundDebounceMs": "Дебаунс входящих (мс)",
"gateway.inboundDebounceMsTip": "Задержка в миллисекундах перед обработкой быстрых последующих сообщений из каналов или веб-чата. 0 = без дебаунса; положительные значения объединяют последующие сообщения после этого ожидания.",
"gateway.injectionAction": "Действие при обнаружении инъекции",
"agents.title": "Настройки агентов по умолчанию",
"agents.description": "LLM-провайдер, модель и настройки среды выполнения по умолчанию, применяемые ко всем агентам, если не переопределены",
"agents.providerTip": "LLM-провайдер по умолчанию, используемый, когда агент его не указывает.",
"agents.modelTip": "Модель по умолчанию, используемая, когда агент её не указывает.",
"agents.maxTokens": "Макс. токенов",
"agents.maxTokensTip": "Максимальное количество токенов, которое модель может сгенерировать в одном ответе.",
"agents.temperature": "Температура",
"agents.temperatureTip": "Температура сэмплирования (0-2). Меньшие значения дают более детерминированный результат.",
"agents.maxToolIterations": "Макс. итераций инструментов",
"agents.maxToolIterationsTip": "Максимальное количество итераций вызова инструментов на один запрос агента.",
"agents.contextWindow": "Контекстное окно",
"agents.contextWindowTip": "Общий бюджет токенов для контекстного окна модели.",
"agents.workspace": "Путь к рабочему пространству",
"agents.workspaceTip": "Корневой каталог для файловых операций агента. Подкаталоги для каждого пользователя создаются автоматически.",
"agents.restrictToWorkspace": "Ограничить рабочим пространством",
"agents.restrictToWorkspaceTip": "Запретить агентам чтение или запись файлов за пределами пути рабочего пространства.",
"agents.intentClassify": "Классификация сообщений занятого агента",
"agents.saveError": "Не удалось сохранить настройки агентов по умолчанию",
"agents.subagents.title": "Субагенты",
"agents.subagents.desc": "Ограничения на порождение субагентов",
"agents.subagents.maxConcurrent": "Макс. одновременно",
"agents.subagents.maxConcurrentTip": "Максимальное количество субагентов, которые могут работать одновременно.",
"agents.subagents.maxSpawnDepth": "Макс. глубина порождения",
"agents.subagents.maxSpawnDepthTip": "Максимальная глубина вложенности для цепочек субагентов.",
"agents.subagents.maxChildrenPerAgent": "Макс. дочерних на агента",
"agents.subagents.maxChildrenPerAgentTip": "Максимальное количество дочерних субагентов, которое может породить один агент.",
"agents.subagents.archiveAfterMin": "Архивировать через (мин)",
"agents.subagents.archiveAfterMinTip": "Минут бездействия до архивации сессии субагента.",
"agents.subagents.modelOverride": "Переопределение модели",
"agents.subagents.modelOverrideTip": "Заставить всех субагентов использовать конкретную модель. Оставьте пустым, чтобы наследовать от родительского агента.",
"agents.subagents.modelOverridePlaceholder": "(наследовать от агента)",
"agents.memory.title": "Память",
"agents.memory.desc": "Семантический поиск в памяти и эмбеддинги",
"agents.memory.enabled": "Включена",
"agents.memory.embeddingProvider": "Провайдер эмбеддингов",
"agents.memory.embeddingModel": "Модель эмбеддингов",
"agents.memory.embeddingProviderTip": "Провайдер, используемый для генерации текстовых эмбеддингов для хранения в памяти.",
"agents.memory.embeddingModelTip": "Имя модели эмбеддингов. Оставьте пустым, чтобы использовать значение провайдера по умолчанию.",
"agents.memory.maxResults": "Макс. результатов",
"agents.memory.maxResultsTip": "Максимальное количество записей памяти, возвращаемых на один запрос воспоминания.",
"agents.memory.maxChunkLen": "Макс. длина фрагмента",
"agents.memory.maxChunkLenTip": "Максимальное количество символов во фрагменте памяти перед разбиением.",
"agents.memory.chunkOverlap": "Перекрытие фрагментов",
"agents.memory.chunkOverlapTip": "Символы перекрытия между фрагментами для непрерывности контекста.",
"agents.memory.minScore": "Мин. оценка",
"agents.memory.minScoreTip": "Минимальная оценка сходства (0-1) для включения записи памяти в результаты.",
"agents.compaction.title": "Уплотнение",
"agents.compaction.desc": "Настройки уплотнения контекстного окна",
"agents.compaction.reserveTokensFloor": "Минимум резервных токенов",
"agents.compaction.reserveTokensFloorTip": "Минимальный буфер токенов, резервируемый для новых ответов перед уплотнением.",
"agents.compaction.maxHistoryShare": "Макс. доля истории (0-1)",
"agents.compaction.maxHistoryShareTip": "Доля контекстного окна, которую может занимать история разговора.",
"agents.compaction.timeoutSeconds": "Тайм-аут (секунды)",
"agents.compaction.timeoutSecondsTip": "Максимальное время ожидания уплотнения перед сохранением исходной истории.",
"agents.pruning.title": "Сокращение контекста",
"agents.pruning.desc": "Обрезка старых результатов инструментов для освобождения места в контексте",
"agents.pruning.mode": "Режим",
"agents.pruning.keepLastAssistants": "Сохранять последние ответы ассистента",
"agents.pruning.keepLastAssistantsTip": "Количество недавних ходов ассистента, всегда сохраняемых при сокращении.",
"agents.sandbox.title": "Песочница",
"agents.sandbox.desc": "Docker-песочница для выполнения кода",
"agents.sandbox.mode": "Режим",
"agents.sandbox.image": "Docker-образ",
"agents.sandbox.imageTip": "Docker-образ, используемый для контейнера песочницы.",
"agents.sandbox.memoryMb": "Память (МБ)",
"agents.sandbox.memoryMbTip": "Лимит памяти для контейнера песочницы в мегабайтах.",
"agents.sandbox.cpus": "CPU",
"agents.sandbox.cpusTip": "Квота CPU для контейнера песочницы (напр. 1.0 = одно полное ядро).",
"agents.sandbox.timeoutSec": "Тайм-аут (сек)",
"agents.sandbox.timeoutSecTip": "Максимальное время выполнения в секундах, после которого песочница завершается.",
"agents.sandbox.networkEnabled": "Сеть включена",
"behavior.uxTitle": "Поведение UX",
"behavior.uxDescription": "Значимые переключатели, изменяющие взаимодействие шлюза с пользователями",
"behavior.intentClassifyHint": "Когда агент уже обрабатывает предыдущий ход, классифицировать новые сообщения как вопросы о статусе, запросы на отмену, инструкции по корректировке или новые запросы.",
"behavior.intentClassifyInfo": "Это применяется только пока сессия занята; это не определяет, требуется ли для запроса командный рабочий процесс.",
"behavior.teamWorkClassify": "Классификация командной работы",
"behavior.teamWorkClassifyHint": "Классифицировать новые запросы как прямую обработку или командный/делегирующий рабочий процесс.",
"behavior.teamWorkClassifyInfo": "Когда запрос превышает область действия текущего агента или должен быть разделён, система использует эмбеддинги как доказательство и просит модель выбрать между прямой обработкой и командным/делегирующим рабочим процессом. Система также проверяет права руководителя/участника; участники могут создавать запросы о помощи только когда команда включила запросы участников и автодиспетчеризацию.",
"behavior.teamWorkClassifyEmbeddingRequired": "Настройте эмбеддинги перед включением классификации командной работы.",
"behavior.chatTitle": "Человекоподобная доставка в каналы",
"behavior.chatDescription": "Подтверждение через sidecar, промежуточный прогресс и безопасное разбиение финального ответа для непотоковых каналов",
"behavior.chatEnabled": "Включить поведение доставки в каналы",
"behavior.chatEnabledHint": "Применяется глобально, с необязательными переопределениями для каждого канала.",
"behavior.quickAck": "Быстрое подтверждение",
"behavior.quickAckHint": "Использовать sidecar-провайдер/модель для короткой естественной квитанции. Текст шаблона отправляется только в режиме фиксированного шаблона.",
"behavior.quickAckPurpose": "Назначение: отправить короткую квитанцию, чтобы пользователи знали, что их сообщение принято, до начала более длительной работы. Это подтверждение, а не рассуждение или прогресс инструментов.",
"behavior.quickAckMode": "Режим",
"behavior.quickAckMode.sidecar_generated": "Сгенерировано sidecar",
"behavior.quickAckMode.llm_generated": "Сгенерировано LLM",
"behavior.quickAckMode.fixed_template": "Фиксированный шаблон",
"behavior.quickAckMode.off": "Выкл",
"behavior.quickAckDelay": "Задержка подтверждения (мс)",
"behavior.quickAckTemplates": "Сообщения фиксированного шаблона",
"behavior.intermediate": "Промежуточные ответы",
"behavior.intermediateHint": "Отправлять естественные обновления о ходе выполнения во время фаз работы инструментов, не добавляя их в историю сессии.",
"behavior.intermediatePurpose": "Назначение: показать пользователям, что работа продвигается во время более длительных запусков с интенсивным использованием инструментов. Это только доставочные sidecar-сообщения, отдельные от «Показывать рассуждения» и не входящие в контекст агента.",
"behavior.intermediateMode": "Режим",
"behavior.intermediateMode.sidecar_generated": "Сгенерировано sidecar",
"behavior.intermediateMode.off": "Выкл",
"behavior.provider": "Провайдер",
"behavior.providerPlaceholder": "Использовать провайдера агента",
"behavior.model": "Модель",
"behavior.modelPlaceholder": "Использовать модель агента",
"behavior.timeoutMs": "Тайм-аут (мс)",
"behavior.maxTokens": "Макс. токенов",
"behavior.maxChars": "Макс. символов",
"behavior.finalSplit": "Разбиение финального ответа",
"behavior.finalSplitHint": "Разбивать длинные финальные ответы на безопасные сообщения по абзацам.",
"behavior.finalSplitMinChars": "Мин. символов",
"behavior.finalSplitMaxMessages": "Макс. сообщений",
"behavior.finalSplitDelay": "Задержка (мс)",
"behavior.preview": "Предпросмотр",
"behavior.previewAck": "Подтверждение",
"behavior.previewGeneratedAck": "Сгенерировано настроенной моделью доставки.",
"behavior.previewNoAck": "Нет подтверждения для этого примера.",
"behavior.previewParts": "{{count}} часть финального сообщения",
"behavior.previewParts_plural": "{{count}} частей финального сообщения",
"behavior.pendingCompactionTitle": "Уплотнение ожидающих сообщений",
"behavior.pendingCompactionDescription": "Автоматически суммировать старые групповые сообщения с помощью LLM, когда буфер превышает порог",
"behavior.pendingCompactionThreshold": "Порог",
"behavior.pendingCompactionThresholdTip": "Запускать уплотнение, когда группа накапливает больше указанного количества ожидающих сообщений. Установите 0, чтобы использовать значение по умолчанию (50).",
"behavior.pendingCompactionKeepRecent": "Сохранять недавние",
"behavior.pendingCompactionKeepRecentTip": "Количество недавних необработанных сообщений, сохраняемых после уплотнения. Более старые сообщения заменяются кратким изложением LLM. По умолчанию 15.",
"behavior.pendingCompactionMaxTokens": "Макс. токенов",
"behavior.pendingCompactionMaxTokensTip": "Максимальное количество выходных токенов для суммирования LLM. По умолчанию 4096.",
"behavior.pendingCompactionProvider": "Провайдер",
"behavior.pendingCompactionProviderTip": "LLM-провайдер для суммирования. Оставьте пустым, чтобы использовать провайдера агента канала.",
"behavior.pendingCompactionProviderPlaceholder": "Использовать провайдера агента",
"behavior.pendingCompactionModel": "Модель",
"behavior.pendingCompactionModelTip": "Модель для суммирования. Оставьте пустым, чтобы использовать модель агента канала.",
"behavior.pendingCompactionModelPlaceholder": "Использовать модель агента",
"behavior.pendingCompactionInfo": "Когда групповой чат превышает порог, LLM автоматически суммирует более старые сообщения в одну компактную запись, сохраняя самые недавние нетронутыми для контекста.",
"behavior.rateLimitTitle": "Ограничение частоты",
"behavior.rateLimitDescription": "Ограничения размера входящих сообщений и троттлинг запросов на пользователя",
"behavior.sessionsTitle": "Область действия сессий",
"behavior.sessionsDescription": "Управляет тем, как контекст разговора разделяется между пользователями и каналами",
"behavior.securityTitle": "Безопасность ввода",
"behavior.securityDescription": "Обнаружение инъекций в промпты и очистка учётных данных для защиты шлюза",
"behavior.injectionActionHint": "Что делать при обнаружении попытки инъекции в промпт во входящем сообщении.",
"behavior.injectionBlockInfo": "Все сообщения, помеченные как попытки инъекции, будут заблокированы, а пользователь будет уведомлён.",
"behavior.injectionOffInfo": "Обнаружение инъекций отключено. Вредоносные промпты не будут отфильтровываться.",
"behavior.scrubCredentialsHint": "Автоматически скрывать API-ключи, токены и пароли, найденные в выводе инструментов, перед возвратом агенту.",
"behavior.scrubCredentialsInfo": "Шаблоны учётных данных в ответах инструментов маскируются до того, как их увидит агент.",
"behavior.scrubCredentialsOffInfo": "Очистка учётных данных отключена. Секреты в выводе инструментов могут быть раскрыты агенту.",
"sessions.scope": "Область сессии",
"sessions.scopeTip": "Определяет, как разделяются сессии. «На отправителя» даёт каждому пользователю отдельную сессию; «Глобальная» использует одну общую сессию для всех пользователей.",
"sessions.dmScope": "Область ЛС",
"sessions.dmScopeTip": "Как формируются ключи сессий личных сообщений. «На собеседника канала» — рекомендуемое значение по умолчанию.",
"quota.title": "Квота использования",
"quota.description": "Ограничения квоты сообщений на пользователя с необязательными переопределениями по провайдеру, каналу и группе",
"quota.enabled": "Включить квоты",
"quota.enabledTip": "Когда включено, пользователи ограничены количеством сообщений, указанным ниже.",
"quota.defaultLimits": "Лимиты по умолчанию",
"quota.defaultLimitsTip": "Резервная квота, применяемая ко всем пользователям, не охваченным конкретным переопределением.",
"quota.hour": "В час",
"quota.hourTip": "Максимальное количество сообщений в час.",
"quota.day": "В день",
"quota.dayTip": "Максимальное количество сообщений в день.",
"quota.week": "В неделю",
"quota.weekTip": "Максимальное количество сообщений в неделю.",
"quota.keyLabel": "Ключ",
"quota.addOverride": "Добавить переопределение",
"quota.allOptionsAdded": "Все варианты уже добавлены",
"quota.providerOverrides": "Переопределения провайдеров",
"quota.providerOverridesTip": "Пользовательские лимиты квоты для каждого LLM-провайдера. Переопределяют значение по умолчанию, когда пользователи взаимодействуют через конкретного провайдера.",
"quota.channelOverrides": "Переопределения каналов",
"quota.channelOverridesTip": "Пользовательские лимиты квоты для каждого типа канала (напр. telegram, discord).",
"quota.groupOverrides": "Переопределения групп",
"quota.groupOverridesTip": "Пользовательские лимиты квоты для конкретных групповых чатов.",
"quota.selectProvider": "Выберите провайдера",
"quota.selectChannel": "Выберите канал",
"quota.selectGroup": "Выберите группу",
"tools.title": "Профиль инструментов",
"tools.description": "Доступность инструментов по умолчанию и почасовое ограничение частоты вызовов для всех агентов",
"tools.profile": "Профиль",
"tools.profileTip": "Предопределённый набор инструментов. «Минимальный» открывает только безопасные инструменты только для чтения; «Полный» включает все инструменты.",
"tools.profilePlaceholder": "Выберите профиль...",
"tools.rateLimitPerHour": "Ограничение частоты (в час)",
"tools.rateLimitPerHourTip": "Максимальное количество вызовов инструментов на агента в час. Установите 0, чтобы отключить.",
"tools.allow": "Разрешить",
"tools.allowTip": "Явно разрешить дополнительные инструменты, не входящие в выбранный профиль.",
"tools.allowPlaceholder": "Выберите инструменты для разрешения...",
"tools.deny": "Запретить",
"tools.denyTip": "Явно заблокировать инструменты, даже если они входят в выбранный профиль.",
"tools.denyPlaceholder": "Выберите инструменты для запрета...",
"tools.alsoAllow": "Также разрешить",
"tools.alsoAllowTip": "Дополнительные инструменты для разрешения поверх профиля. Полезно при использовании ограничительного профиля.",
"tools.alsoAllowPlaceholder": "Выберите дополнительные инструменты...",
"tools.execApproval": "Выполнение команд",
"tools.execSecurity": "Режим безопасности",
"tools.execSecurityTip": "Управляет тем, какие команды оболочки разрешено выполнять агентам. «Список разрешённых» ограничивает утверждёнными шаблонами.",
"tools.execAskMode": "Режим запроса",
"tools.execAskModeTip": "Когда запрашивать у пользователя одобрение перед выполнением команды.",
"tools.execAllowlistLabel": "Разрешённые команды (по одному шаблону в строке)",
"tools.commandKeywordAllowlist": "Список разрешённых ключевых слов команд",
"tools.commandKeywordAllowlistTip": "Правила JSON, разрешающие настроенные ключевые слова только внутри выбранных аргументов содержимого CLI с учётными данными. Правила запрета по пути команды по-прежнему применяются.",
"tools.commandKeywordAllowlistJsonError": "Недопустимый JSON.",
"tools.commandKeywordAllowlistArrayError": "Используйте JSON-массив правил.",
"tools.scrubCredentials": "Очищать учётные данные",
"browser.title": "Автоматизация браузера",
"browser.description": "Настройки среды выполнения для серверного инструмента браузера",
"browser.enabled": "Включён",
"browser.enabledHint": "Предоставить инструмент браузера агентам.",
"browser.headless": "Без интерфейса",
"browser.headlessHint": "Запускать локальный Chrome без видимого окна.",
"browser.remoteUrl": "URL удалённого CDP",
"browser.remoteUrlTip": "Подключаться к существующей конечной точке Chrome DevTools вместо запуска локального Chrome.",
"browser.maxPages": "Макс. страниц",
"browser.maxPagesTip": "Максимальное количество открытых страниц на изолированную область браузера.",
"browser.actionTimeout": "Тайм-аут действия (мс)",
"browser.actionTimeoutTip": "Максимальное время для одного действия браузера.",
"browser.idleTimeout": "Тайм-аут бездействия (мс)",
"browser.idleTimeoutTip": "Закрывать бездействующие страницы после этого периода. Установите 0, чтобы отключить.",
"browser.cookieSync": "Синхронизация выбранных cookie",
"browser.cookieSyncHint": "Применять явно синхронизированные cookie к соответствующим сессиям браузера пользователя и агента.",
"tts.title": "Синтез речи",
"tts.configured": "Настроен",
"tts.disabled": "Отключён",
"tts.providerInfo": "Провайдер: {{provider}} — Авто: {{auto}}",
"tts.noProvider": "TTS-провайдер не настроен.",
"tts.manageLink": "Управление настройками TTS",
"cron.title": "Планировщик cron",
"cron.description": "Поведение повторных попыток для невыполненных запланированных задач",
"cron.maxRetries": "Макс. попыток",
"cron.maxRetriesTip": "Максимальное количество повторных попыток для невыполненной задачи cron.",
"cron.baseDelay": "Базовая задержка",
"cron.baseDelayTip": "Начальная задержка отката между попытками (напр. 2s, 500ms).",
"cron.maxDelay": "Макс. задержка",
"cron.maxDelayTip": "Максимальная задержка отката между попытками (напр. 30s, 5m).",
"cron.defaultTimezone": "Часовой пояс по умолчанию",
"cron.defaultTimezoneTip": "Часовой пояс IANA для cron-выражений, когда он не задан для задачи (напр. Asia/Ho_Chi_Minh). Оставьте пустым, чтобы использовать системный часовой пояс сервера.",
"cron.defaultTimezonePlaceholder": "Системный часовой пояс",
"telemetry.title": "Телеметрия (OpenTelemetry)",
"telemetry.description": "Экспорт трейсов и метрик в бэкенд, совместимый с OpenTelemetry",
"telemetry.enabled": "Включена",
"telemetry.enabledTip": "Включить экспорт трейсов OpenTelemetry. Требует тег сборки «otel».",
"telemetry.endpoint": "Конечная точка",
"telemetry.endpointTip": "Конечная точка экспортёра OTLP (host:port). Для gRPC по умолчанию 4317, для HTTP — 4318.",
"telemetry.protocol": "Протокол",
"telemetry.protocolTip": "Транспортный протокол для экспортёра OTLP.",
"telemetry.serviceName": "Имя сервиса",
"telemetry.serviceNameTip": "Имя сервиса, указываемое в трейсах. Полезно для фильтрации в бэкенде наблюдаемости.",
"telemetry.insecure": "Небезопасно",
"telemetry.insecureTip": "Отключить TLS для соединения OTLP. Используйте только в локальных/dev-окружениях.",
"telemetry.headers": "Заголовки экспорта",
"telemetry.headersTip": "Дополнительные HTTP-заголовки, отправляемые с каждым запросом экспорта OTLP (напр. API-ключи для размещённых бэкендов).",
"telemetry.headerKeyPlaceholder": "Имя заголовка",
"telemetry.headerValuePlaceholder": "Значение заголовка",
"telemetry.addHeader": "Добавить заголовок",
"bindings.title": "Привязки агентов",
"bindings.description": "Направлять конкретные каналы, собеседников или аккаунты назначенному агенту",
"bindings.add": "Добавить привязку",
"bindings.noBindings": "Привязки не настроены. Все сообщения направляются агенту по умолчанию.",
"bindings.agentId": "ID агента",
"bindings.channel": "Канал",
"bindings.peerKind": "Тип собеседника",
"bindings.peerId": "ID собеседника",
"providers.title": "API-ключи провайдеров",
"providers.description": "Переопределить API-ключи и базовые URL для настроенных LLM-провайдеров",
"providers.noProviders": "В файле конфигурации не найдено провайдеров.",
"providers.apiKey": "API-ключ",
"providers.apiBaseUrl": "Базовый URL",
"providers.apiBaseUrlPlaceholder": "https://api.example.com/v1",
"providers.managedVia": "Управляется через переменную окружения {{envKey}}.",
"channels.title": "Настройки каналов",
"channels.description": "Настройка встроенных интеграций каналов (токены, политики, потоковая передача)",
"channels.noChannels": "В файле конфигурации не найдено каналов.",
"channels.enabled": "Включён",
"channels.token": "Токен / Секрет",
"channels.managedVia": "Управляется через переменную окружения {{envKey}}.",
"channels.dmPolicy": "Политика ЛС",
"channels.groupPolicy": "Политика групп",
"channels.allowFrom": "Разрешить от",
"channels.allowFromPlaceholder": "user_id_1, user_id_2, ...",
"channels.dmStreaming": "Потоковая передача в ЛС",
"channels.dmStreamingHint": "Постепенные обновления сообщений в ЛС",
"channels.groupStreaming": "Потоковая передача в группах",
"channels.groupStreamingHint": "Постепенные обновления сообщений в группах",
"channels.streaming": "Потоковая передача",
"channels.draftTransport": "Предпросмотр черновика",
"channels.draftTransportHint": "Скрытый потоковый предпросмотр в ЛС (без уведомлений на каждое изменение)",
"channels.reasoningDelivery": "Показывать рассуждения",
"channels.reasoningDeliveryHint": "Выберите, как рассуждения модели отображаются в сообщениях канала. «Всегда отдельными сообщениями» работает, даже когда потоковая передача в реальном времени отключена.",
"channels.reasoningStreamingOnly": "Только при потоковой передаче",
"channels.reasoningAlwaysBubbles": "Всегда отдельными сообщениями",
"channels.reasoningOff": "Выкл",
"channels.reactionLevel": "Уровень реакций",
"channels.connectionMode": "Режим подключения",
"channels.reactionOff": "Выкл",
"channels.reactionMinimal": "Минимальный",
"channels.reactionFull": "Полный",
"channels.connectionWebsocket": "WebSocket",
"channels.connectionWebhook": "Webhook",
"bindings.any": "Любой",
"tabs.systemMessages": "Системные сообщения",
"systemMessages.title": "Пользовательские системные сообщения",
"systemMessages.description": "Переопределить встроенные сообщения шлюза, отправляемые напрямую каналами",
"systemMessages.message": "Сообщение",
"systemMessages.messageTip": "Ключ встроенного системного сообщения для настройки.",
"systemMessages.locale": "Язык",
"systemMessages.defaultLocale": "Язык доставки по умолчанию",
"systemMessages.defaultLocaleTip": "Язык, используемый, когда канал не предоставляет локаль.",
"systemMessages.localeTip": "Переопределение локали для редактирования. Пустые значения возвращаются к встроенному значению по умолчанию.",
"systemMessages.locale.en": "Английский",
"systemMessages.locale.vi": "Вьетнамский",
"systemMessages.locale.zh": "Китайский",
"systemMessages.locale.ko": "Корейский",
"systemMessages.locale.ru": "Русский",
"systemMessages.override": "Переопределить шаблон",
"systemMessages.overrideTip": "Шаблон, отправляемый вместо встроенного сообщения для выбранной локали. Переменные используют {{name}}.",
"systemMessages.defaultTemplate": "Шаблон по умолчанию",
"systemMessages.defaultTemplateTip": "Встроенный резервный шаблон, используемый, когда переопределение пусто.",
"systemMessages.useDefault": "Использовать по умолчанию",
"toast": {
"saved": "Конфигурация сохранена",
"saveFailed": "Не удалось сохранить конфигурацию"
}
}
+59
View File
@@ -0,0 +1,59 @@
{
"title": "Контакты",
"description": "Автоматически собранные контакты из всех взаимодействий по каналам.",
"searchPlaceholder": "Поиск по имени, имени пользователя или ID...",
"filter": "Фильтр",
"emptyTitle": "Нет контактов",
"emptyDescription": "Контакты появятся здесь по мере того, как пользователи будут взаимодействовать с вашими агентами через каналы.",
"noMatchTitle": "Нет подходящих контактов",
"noMatchDescription": "Попробуйте другой поисковый запрос или фильтр.",
"columns": {
"name": "Имя",
"username": "Имя пользователя",
"senderId": "ID отправителя",
"channelType": "Канал",
"peerKind": "Тип",
"lastSeen": "Последняя активность",
"merged": "Объединён"
},
"permissionsNote": {
"title": "Разрешения каналов для имён контактов",
"telegram": "Telegram — имена и имена пользователей доступны автоматически.",
"discord": "Discord — отображаемые имена и имена пользователей доступны автоматически.",
"zalo": "Zalo — отображаемые имена доступны автоматически.",
"slack": "Slack — отображаемые имена определяются через Slack API (бот должен быть в рабочем пространстве).",
"feishu": "Feishu/Lark — требуется разрешение contact:user.base:readonly. Без него имена будут пустыми.",
"bitrix24": "Bitrix24 — требуется область `user` + один вызов `user.get` на каждого нового отправителя. Имена могут быть пустыми недолго при первом сообщении."
},
"selectedCount": "Выбрано: {{count}}",
"merge": {
"button": "Объединить",
"unmergeButton": "Разъединить",
"dialogTitle": "Объединить контакты",
"dialogDescription": "Свяжите выбранные контакты с личностью пользователя арендатора. Это определяет их как одного человека во всех каналах.",
"linkExisting": "Связать с существующим пользователем",
"createNew": "Создать нового пользователя",
"selectUser": "Выберите пользователя арендатора...",
"displayName": "Отображаемое имя",
"displayNamePlaceholder": "напр. Иван Иванов",
"userId": "ID пользователя",
"userIdPlaceholder": "Уникальный идентификатор",
"confirm": "Объединить",
"cancel": "Отмена",
"success": "Контакты успешно объединены",
"unmergeSuccess": "Контакты успешно разъединены",
"error": "Не удалось объединить контакты",
"unmergeError": "Не удалось разъединить контакты",
"comingSoon": "Эта функция в разработке и пока недоступна."
},
"types": {
"user": "Пользователь",
"group": "Группа"
},
"filters": {
"allChannels": "Все каналы",
"allTypes": "Все типы",
"direct": "Личные",
"group": "Групповые"
}
}
+173
View File
@@ -0,0 +1,173 @@
{
"title": "Cron",
"description": "Планирование повторяющихся задач агента",
"newJob": "Новая задача",
"emptyTitle": "Нет cron-задач",
"emptyDescription": "Создайте cron-задачу для планирования повторяющихся задач агента.",
"columns": {
"enabled": "Включено",
"name": "Имя",
"schedule": "Расписание",
"message": "Сообщение",
"agent": "Агент",
"actions": "Действия"
},
"runNow": "Запустить сейчас",
"running": "Выполняется...",
"runHistory": "История запусков",
"defaultAgent": "по умолчанию",
"searchPlaceholder": "Поиск cron-задач...",
"noMatchTitle": "Нет подходящих задач",
"noMatchDescription": "Попробуйте другой поисковый запрос.",
"card": {
"nextRun": "Далее: {{time}}",
"noNextRun": "Нет следующего запуска",
"defaultAgent": "Агент по умолчанию"
},
"create": {
"title": "Создать cron-задачу",
"name": "Имя",
"namePlaceholder": "my-daily-task",
"nameHint": "Только строчные буквы, цифры и дефисы",
"agentId": "ID агента (необязательно)",
"agentIdPlaceholder": "по умолчанию",
"scheduleType": "Тип расписания",
"every": "Каждые",
"cron": "Cron",
"once": "Один раз",
"intervalSeconds": "Интервал (секунды)",
"cronExpression": "Cron-выражение",
"cronHint": "Стандартный cron из 5 полей: мин час день месяц день_недели",
"onceDesc": "Задача выполнится один раз, примерно через 1 минуту.",
"message": "Сообщение",
"messagePlaceholder": "Что должен сделать агент?",
"cancel": "Отмена",
"create": "Создать",
"creating": "Создание...",
"payloadType": "Тип полезной нагрузки"
},
"enable": {
"title": "Включить cron-задачу",
"description": "Включить \"{{name}}\"? Она начнёт выполняться по расписанию.",
"confirmLabel": "Включить"
},
"disable": {
"title": "Отключить cron-задачу",
"description": "Отключить \"{{name}}\"? Она перестанет выполняться до повторного включения.",
"confirmLabel": "Отключить"
},
"delete": {
"title": "Удалить cron-задачу",
"description": "Удалить \"{{name}}\"? Это действие нельзя отменить.",
"confirmLabel": "Удалить"
},
"runLog": {
"title": "Журнал запусков: {{name}}",
"noHistory": "Истории запусков пока нет.",
"loading": "Загрузка..."
},
"detail": {
"runNow": "Запустить сейчас",
"running": "Выполняется...",
"disable": "Отключить",
"enable": "Включить",
"delete": "Удалить",
"enabled": "включено",
"disabled": "отключено",
"runningStatus": "выполняется...",
"payload": "Полезная нагрузка",
"empty": "(пусто)",
"deliverDirect": "Доставка: напрямую",
"channel": "Канал: {{name}}",
"to": "Кому: {{name}}",
"edit": "Редактировать",
"preview": "Предпросмотр",
"noMessage": "Сообщение не настроено",
"lastError": "Последняя ошибка",
"runHistory": "История запусков",
"refresh": "Обновить",
"noHistory": "Истории запусков пока нет.",
"inOut": "{{input}} вход / {{output}} выход",
"infoRows": {
"schedule": "Расписание",
"timezone": "Часовой пояс",
"nextRun": "Следующий запуск",
"lastRun": "Последний запуск",
"lastStatus": "Последний статус",
"created": "Создано",
"updated": "Обновлено",
"autoDelete": "Автоудаление",
"autoDeleteValue": "Да (однократно)"
},
"tabs": {
"overview": "Обзор",
"history": "История запусков"
},
"advanced": "Расширенные",
"saveFailed": "Не удалось сохранить",
"schedule": "Расписание",
"scheduleDesc": "Настройка времени",
"messageSection": "Сообщение",
"messageSectionDesc": "Что должен сделать агент",
"agentStatus": "Агент и статус",
"agentStatusDesc": "Назначение агента и статус задачи",
"info": "Информация",
"infoDesc": "Метаданные задачи",
"scheduling": "Планирование",
"schedulingDesc": "Настройка часового пояса",
"delivery": "Доставка",
"deliveryDesc": "Направить вывод задачи в канал или пользователю",
"deliverToChannel": "Доставить в канал",
"channelLabel": "Канал",
"channelPlaceholder": "#general",
"toLabel": "Кому (пользователь)",
"toPlaceholder": "user-id",
"wakeHeartbeat": "Активировать heartbeat при запуске",
"wakeHeartbeatDesc": "Запускать heartbeat агента при выполнении задачи",
"lifecycle": "Жизненный цикл",
"lifecycleDesc": "Настройки жизненного цикла задачи",
"deleteAfterRun": "Удалить после выполнения",
"deleteAfterRunDesc": "Автоматически удалить эту задачу после первого успешного выполнения",
"timezone": "Часовой пояс",
"timezoneDesc": "Часовой пояс для cron-выражений",
"commandSection": "Команда",
"commandArgv": "Команда",
"noCommand": "Команда не настроена",
"commandCwd": "Рабочий каталог",
"defaultWorkingDirectory": "По умолчанию (шлюз)",
"commandTimeout": "Тайм-аут",
"commandOutputLimit": "Лимит вывода",
"commandEnv": "Окружение",
"commandInput": "Ввод",
"commandNoOutputTimeout": "Тайм-аут отсутствия вывода",
"seconds": "{{count}} с",
"bytes": "{{count}} байт",
"defaultValue": "По умолчанию",
"none": "Нет",
"envVars": "{{count}} перем.",
"commandJson": "Команда JSON",
"commandJsonHelp": "Отредактируйте полезную нагрузку команды в формате JSON. Поле argv обязательно и должно быть непустым массивом строк.",
"invalidCommandJson": "Некорректный JSON команды: argv должен быть непустым массивом.",
"commandArgvHelp": "По одному аргументу в строке. Используйте sh / -c / ваш скрипт для синтаксиса оболочки."
},
"stateless": "Без состояния",
"statelessHelp": "Пропускать сохранение сессии. Каждый запуск начинается с чистого листа без загрузки предыдущих сообщений. Экономит токены для cron-задач, которым не нужен прошлый контекст.",
"toast": {
"created": "Cron-задача создана",
"createdDesc": "{{name}} добавлена",
"enabled": "Cron-задача включена",
"disabled": "Cron-задача отключена",
"deleted": "Cron-задача удалена",
"triggered": "Cron-задача запущена",
"failedCreate": "Не удалось создать cron-задачу",
"failedToggle": "Не удалось переключить cron-задачу",
"failedDelete": "Не удалось удалить cron-задачу",
"failedRun": "Не удалось запустить cron-задачу",
"updated": "Задача обновлена",
"failedUpdate": "Не удалось обновить задачу"
},
"payload": {
"agent": "Агент",
"command": "Команда"
}
}
+36
View File
@@ -0,0 +1,36 @@
{
"title": "События в реальном времени",
"description": "События WebSocket в реальном времени по всем командам и агентам",
"live": "В реальном времени",
"paused": "Приостановлено",
"resume": "Возобновить",
"pause": "Пауза",
"clear": "Очистить",
"scrollToBottom": "Прокрутить вниз",
"eventCount": "{{count}} событие",
"eventCountPlural": "{{count}} событий",
"categories": {
"all": "Все",
"task": "Задача",
"message": "Сообщение",
"agent": "Агент",
"teamCrud": "CRUD команды",
"agentLink": "Связь агента"
},
"filters": {
"allTeams": "Все команды",
"allUsers": "Все пользователи",
"allChats": "Все чаты"
},
"global": "Глобально",
"emptyTitle": "Пока нет событий",
"emptyPaused": "Захват событий приостановлен. Возобновите, чтобы увидеть новые события.",
"emptyWaiting": "Ожидание событий в реальном времени... События появятся по мере работы агентов.",
"detail": {
"copy": "Копировать",
"copied": "Скопировано"
},
"toolBadge": { "error": "ошибка", "activated": "активировано", "ok": "ок" },
"moreArgs": "...ещё {{count}}",
"parentLabel": "родитель:"
}
+149
View File
@@ -0,0 +1,149 @@
{
"title": "Хуки агента",
"subtitle": "Хуки жизненного цикла: блокировка, наблюдение, внедрение контекста между событиями агента",
"empty": "Хуки пока не настроены",
"nav": "Хуки",
"beta": {
"title": "Хуки (Бета)",
"badge": "Бета",
"description": "Хуки позволяют перехватывать события жизненного цикла агента, чтобы разрешать, блокировать или переписывать происходящее. Сейчас в бета-версии — ожидайте шероховатостей и следите за журналом аудита.",
"howItWorksTitle1": "1. Выберите событие",
"howItWorksBody1": "Каждый хук срабатывает на одном событии, таком как user_prompt_submit, pre_tool_use или stop. Блокирующие события ждут вашего решения перед продолжением.",
"howItWorksTitle2": "2. Выберите обработчик",
"howItWorksBody2": "Script выполняет JavaScript в песочнице. HTTP отправляет запрос на ваш вебхук. Prompt спрашивает LLM. Встроенные хуки (значок «Система») поставляются с GoClaw, и в них можно менять только переключатель включения.",
"howItWorksTitle3": "3. Протестируйте перед включением",
"howItWorksBody3": "Используйте «Запустить хук» с образцом события, чтобы просмотреть решение, длительность и любые изменения ввода — ничто не затрагивает реальную сессию до включения.",
"collapse": "Скрыть",
"learnMore": "Как хуки работают с навыками и MCP",
"modalTitle": "Хуки + Навыки + MCP",
"modalIntro": "Хуки интегрируются с системой навыков GoClaw и серверами MCP (Model Context Protocol), давая вам гранулярный контроль над конвейером агента.",
"modalSkillTitle": "Хуки × Навыки",
"modalSkillBody": "Когда вызывается навык, агент генерирует события pre_tool_use и post_tool_use. Хук на pre_tool_use может проверить имя навыка и аргументы, затем разрешить, заблокировать или переписать их перед выполнением. Хуки post_tool наблюдают за результатами для логирования или цепочек.",
"modalMcpTitle": "Хуки × Серверы MCP",
"modalMcpBody": "Инструменты MCP, зарегистрированные с внешних серверов, отображаются как обычные инструменты в конвейере агента. Хуки срабатывают на тех же событиях pre_tool_use / post_tool_use — специальная настройка не нужна. Используйте regex-матчер для нацеливания на конкретные имена инструментов MCP (напр. mcp__.*).",
"modalBuiltinTitle": "Встроенные хуки (Система)",
"modalBuiltinBody": "Встроенные хуки, такие как PII Redactor, выполняются как скрипты в песочнице с повышенными привилегиями: они могут переписывать ввод пользователя (rawInput) и аргументы инструментов до того, как агент их увидит. Пользовательские скрипты не могут — это обеспечивается на уровне диспетчера.",
"modalClose": "Понятно"
},
"actions": {
"create": "Создать хук",
"edit": "Изменить",
"delete": "Удалить",
"test": "Тест",
"toggle": "Включить/Отключить"
},
"filters": {
"event": "Событие",
"type": "Обработчик",
"scope": "Область",
"enabled": "Статус",
"all": "Все"
},
"table": {
"name": "Имя",
"event": "Событие",
"type": "Обработчик",
"scope": "Область",
"matcher": "Матчер",
"enabled": "Включено",
"actions": "Действия",
"systemBadge": "Система"
},
"form": {
"title_create": "Создать хук",
"title_edit": "Изменить хук",
"name": "Имя",
"namePlaceholder": "напр. Блокировать конфиденциальные инструменты",
"agents": "Агенты",
"agentsHint": "Выберите, к каким агентам применяется этот хук",
"event": "Событие",
"handlerType": "Тип обработчика",
"scope": "Область",
"matcher": "Матчер (regex)",
"matcherHint": "Применяется к имени инструмента перед срабатыванием (необязательно, кроме prompt)",
"ifExpr": "Условие (CEL)",
"ifExprHint": "Вычисляется по tool_input; синтаксис cel-go",
"timeout": "Тайм-аут (мс)",
"onTimeout": "При тайм-ауте",
"priority": "Приоритет",
"enabled": "Включено",
"url": "URL",
"method": "HTTP-метод",
"headers": "Заголовки",
"bodyTemplate": "Шаблон тела",
"promptTemplate": "Шаблон промпта",
"model": "Модель",
"maxInvocationsPerTurn": "Макс. вызовов за ход",
"scriptSource": "Исходный код скрипта (ES5.1 JavaScript)",
"scriptSchemaHelp": "Экспортируйте функцию handle(event), возвращающую {decision: \"allow\"|\"block\", reason?: string, updatedInput?: object}. Лимит 32 КиБ.",
"compileError": "Синтаксическая ошибка в строке {{line}}, столбец {{col}}",
"builtinReadonly": "Встроенный хук — можно изменить только переключатель включения.",
"saveToggle": "Сохранить переключатель",
"save": "Сохранить",
"cancel": "Отмена"
},
"tabs": {
"overview": "Обзор",
"config": "Конфигурация",
"test": "Тест",
"history": "История"
},
"test": {
"title": "Тестировать хук",
"sampleEvent": "Образец события",
"sampleEventHint": "Составьте фиктивное событие, чтобы запустить хук против него — ничто здесь не затрагивает реальную сессию.",
"toolName": "Имя инструмента",
"toolNameHint": "Используется матчерами pre/post_tool_use (напр. bash, edit, web_search).",
"toolInput": "Ввод инструмента (JSON)",
"toolInputHint": "Аргументы, передаваемые инструменту. Должны быть корректным JSON.",
"rawInput": "Сырое сообщение пользователя",
"rawInputPlaceholder": "Необязательно — текст запроса пользователя",
"rawInputHint": "Используется хуками user_prompt_submit. Оставьте пустым для событий инструментов.",
"parseError": "Ввод инструмента должен быть корректным JSON",
"resultTitle": "Результат",
"resultHint": "Что вернул диспетчер, включая любые изменения ввода от встроенных хуков.",
"emptyState": "Запустите хук, чтобы увидеть, как он ответит.",
"fire": "Запустить хук",
"firing": "Выполнение…",
"decision": "Решение",
"duration": "Длительность",
"reason": "Причина",
"stdout": "Stdout",
"stderr": "Stderr",
"statusCode": "Код статуса",
"updatedInput": "Обновлённый ввод (diff)",
"toolNamePickerPlaceholder": "Выберите или введите имя инструмента...",
"overwriteConfirm": "Текущий ввод будет заменён шаблоном. Продолжить?"
},
"history": {
"title": "История выполнения",
"empty": "Выполнений пока нет",
"phaseFourNote": "Пагинация истории появится в фазе 4",
"decision": "Решение",
"duration": "Длительность",
"error": "Ошибка",
"timestamp": "Когда"
},
"toast": {
"created": "Хук создан",
"updated": "Хук обновлён",
"deleted": "Хук удалён",
"toggled": "Хук переключён",
"failedCreate": "Не удалось создать хук",
"failedUpdate": "Не удалось обновить хук",
"failedDelete": "Не удалось удалить хук",
"failedTest": "Тест не удался"
},
"validation": {
"promptRequiresMatcher": "Хуки prompt требуют матчер или if_expr",
"invalidRegex": "Недопустимый regex",
"promptTemplateRequired": "Шаблон промпта обязателен",
"scriptSourceRequired": "Исходный код скрипта обязателен"
},
"decision": {
"allow": "Разрешить",
"block": "Блокировать",
"error": "Ошибка",
"timeout": "Тайм-аут"
}
}
@@ -0,0 +1,131 @@
{
"title": "Импорт и экспорт",
"description": "Экспортируйте агентов в переносимый архив или импортируйте из него.",
"beta": "Бета",
"betaWarning": "Импорт и экспорт находятся в бета-версии. Всегда создавайте резервную копию перед импортом в существующего агента.",
"tabs": {
"teams": "Команды",
"agents": "Агенты",
"skillsMcp": "Навыки и MCP",
"export": "Экспорт",
"import": "Импорт"
},
"comingSoon": {
"title": "Скоро",
"description": "Этот раздел пока недоступен."
},
"export": {
"title": "Экспорт агента",
"agent": "Агент",
"agentPlaceholder": "Выберите агента",
"sections": "Разделы",
"preset": "Пресет",
"presetsLabel": "Пресеты",
"infoNote": "Используйте вкладку «Команды», чтобы экспортировать агентов вместе с их командой.",
"startExport": "Экспорт",
"exporting": "Экспорт...",
"preview": "Предпросмотр",
"previewLoading": "Загрузка предпросмотра...",
"download": "Скачать",
"done": "Экспорт завершён",
"errorTitle": "Экспорт не удался",
"selectAgent": "Выберите агента для экспорта.",
"noAgents": "Нет доступных агентов."
},
"import": {
"title": "Импорт агента",
"mode": "Режим",
"modeNew": "Создать нового агента",
"modeMerge": "Объединить с существующим",
"agentKey": "Ключ агента",
"agentKeyPlaceholder": "напр. my-agent",
"agentKeyHint": "Строчные буквы, цифры, дефисы. Оставьте пустым, чтобы использовать ключ из архива.",
"targetAgent": "Целевой агент",
"targetAgentPlaceholder": "Выберите целевого агента",
"file": "Файл архива (.tar.gz)",
"filePlaceholder": "Нажмите для выбора или перетащите",
"sections": "Разделы для объединения",
"startImport": "Импорт",
"importing": "Импорт...",
"done": "Импорт завершён",
"agentCreated": "Агент создан: {{key}}",
"mergedInto": "Объединено с: {{key}}",
"errorTitle": "Импорт не удался",
"manifestLabel": "Информация об архиве",
"agentFrom": "Агент из архива: {{key}}",
"exportedAt": "Экспортировано: {{date}}"
},
"sections": {
"config": "Конфигурация",
"configDesc": "Конфигурация агента (модель, инструменты и т. д.)",
"context_files": "Файлы контекста",
"context_filesDesc": "Файлы контекста уровня агента (SOUL.md, IDENTITY.md и т. д.)",
"user_data": "Данные пользователей",
"user_dataDesc": "Все данные по каждому пользователю (файлы контекста, профили, переопределения)",
"user_context_files": "Файлы контекста пользователей",
"user_context_filesDesc": "Файлы контекста по каждому пользователю (USER.md на пользователя)",
"user_profiles": "Профили пользователей",
"user_profilesDesc": "Записи профилей рабочего пространства пользователей",
"user_overrides": "Переопределения пользователей",
"user_overridesDesc": "Переопределения модели/провайдера по каждому пользователю",
"memory": "Память",
"memoryDesc": "Все документы памяти (глобальные + по каждому пользователю)",
"memory_global": "Глобальная память",
"memory_globalDesc": "Общие документы памяти",
"memory_per_user": "Память по пользователям",
"memory_per_userDesc": "Индивидуальные документы памяти пользователей",
"knowledge_graph": "Граф знаний",
"knowledge_graphDesc": "Сущности и связи KG",
"cron": "Задачи cron",
"cronDesc": "Запланированные задачи (импортируются отключёнными)",
"workspace": "Файлы рабочего пространства",
"workspaceDesc": "Файлы каталога рабочего пространства агента",
"sessions": "Сессии",
"sessionsDesc": "Сессии чата и сообщения",
"media": "Медиа",
"mediaDesc": "Загруженные медиафайлы",
"comingSoon": "Скоро"
},
"presets": {
"minimal": "Минимальный",
"standard": "Стандартный",
"complete": "Полный"
},
"teamExportNote": "Экспорт команды включает всех агентов-участников и их данные (файлы контекста, память, граф знаний, cron, рабочее пространство).",
"teamSelectPlaceholder": "Выберите команду...",
"teamDropHere": "Перетащите файл архива команды сюда или нажмите для выбора",
"teamDropFormats": "Поддерживаются файлы .tar.gz",
"teamDontClose": "Не закрывайте эту страницу — идёт импорт",
"teamImportAnother": "Импортировать ещё",
"teamTryAgain": "Повторить",
"teamChangeFile": "Изменить файл",
"teamPreview": {
"members": "{{count}} участников",
"agents": "{{count}} агентов",
"tasks": "{{count}} задач",
"links": "{{count}} связей",
"loading": "Загрузка предпросмотра...",
"error": "Не удалось загрузить предпросмотр"
},
"skillsMcp": {
"skillsTab": "Навыки",
"mcpTab": "Серверы MCP",
"skillsNote": "Экспортируются только пользовательские навыки (не системные). Системные навыки не включаются.",
"mcpNote": "Конфигурации серверов MCP экспортируются без ключей API, переменных окружения и заголовков. Вам потребуется заново ввести секреты после импорта.",
"customSkills": "{{count}} пользовательских навыков",
"grants": "{{count}} разрешений агентов",
"servers": "{{count}} серверов",
"noSkills": "Нет пользовательских навыков для экспорта.",
"noServers": "Нет серверов MCP для экспорта.",
"exportSkills": "Экспортировать навыки",
"exportMcp": "Экспортировать серверы MCP",
"importSkills": "Импортировать навыки",
"importMcp": "Импортировать серверы MCP",
"importedSkills": "Навыки импортированы",
"skippedSkills": "Навыки пропущены (уже существуют)",
"importedServers": "Серверы импортированы",
"skippedServers": "Серверы пропущены (уже существуют)",
"dropSkills": "Перетащите файл архива навыков сюда или нажмите для выбора",
"dropMcp": "Перетащите файл архива MCP сюда или нажмите для выбора"
}
}
+41
View File
@@ -0,0 +1,41 @@
{
"subtitle": "Войдите в панель управления шлюзом",
"selectTenant": "Выберите арендатора",
"selectTenantDescription": "Выберите арендатора, чтобы продолжить",
"allTenantsOption": "Все арендаторы",
"allTenantsDescription": "Просмотр данных всех арендаторов",
"noAccess": "Нет доступа",
"noAccessDescription": "У вас нет доступа ни к одному арендатору. Обратитесь к администратору.",
"tabs": {
"token": "Токен",
"pairing": "Привязка"
},
"token": {
"userId": "ID пользователя",
"userIdPlaceholder": "ваш-user-id",
"userIdHint": "Используйте \"system\" для полного доступа к системе",
"gatewayToken": "Токен шлюза",
"tokenPlaceholder": "Bearer-токен",
"connect": "Подключиться",
"connecting": "Подключение...",
"errorInvalidCredentials": "Неверные учётные данные. Проверьте токен и ID пользователя.",
"errorServer": "Сервер вернул {{status}}. Пожалуйста, попробуйте снова.",
"errorCannotConnect": "Не удаётся подключиться к шлюзу. Проверьте, запущен ли сервер."
},
"pairing": {
"userId": "ID пользователя",
"userIdPlaceholder": "ваш-user-id",
"noTokenNeeded": "Токен не требуется. Будет сгенерирован код привязки для одобрения администратором.",
"requestAccess": "Запросить доступ",
"connecting": "Подключение...",
"errorConnectionLost": "Соединение потеряно. Пожалуйста, попробуйте снова.",
"errorCannotConnect": "Не удалось подключиться к шлюзу.",
"askAdmin": "Попросите администратора одобрить этот код:",
"orRun": "Или выполните:",
"waitingForApproval": "Ожидание одобрения...",
"cancel": "Отмена",
"approved": "Доступ одобрен! Перенаправление..."
},
"noAccessHint": "Попросите администратора добавить вас к арендатору или используйте другую учётную запись.",
"logout": "Выйти"
}
+15
View File
@@ -0,0 +1,15 @@
{
"title": "Журналы",
"description": "Отслеживание журналов в реальном времени",
"descriptionLive": "Отслеживание в реальном времени на уровне {{level}}",
"live": "В реальном времени",
"start": "Запустить",
"stop": "Остановить",
"clear": "Очистить",
"filterPlaceholder": "Фильтровать журналы...",
"logLevelTitle": "Уровень журнала",
"emptyWaiting": "Ожидание журналов...",
"emptyFilter": "Нет журналов, соответствующих фильтру.",
"emptyStart": "Нажмите «Запустить», чтобы начать потоковую передачу журналов.",
"count": "{{filtered}}/{{total}}"
}
+174
View File
@@ -0,0 +1,174 @@
{
"title": "MCP-серверы",
"description": "Управление подключениями к серверам Model Context Protocol",
"addServer": "Добавить сервер",
"searchPlaceholder": "Поиск серверов...",
"emptyTitle": "Нет MCP-серверов",
"emptyDescription": "Добавьте свой первый MCP-сервер, чтобы начать.",
"noMatchTitle": "Нет подходящих серверов",
"noMatchDescription": "Попробуйте другой поисковый запрос.",
"columns": {
"name": "Имя",
"transport": "Транспорт",
"tools": "Инструменты",
"agents": "Агенты",
"enabled": "Включено",
"createdBy": "Создал",
"actions": "Действия"
},
"viewTools": "Просмотр инструментов",
"manageGrants": "Управление доступом",
"reconnect": "Переподключить",
"delete": {
"title": "Удалить MCP-сервер",
"description": "Вы уверены, что хотите удалить \"{{name}}\"? Это также удалит все связанные права доступа.",
"confirmLabel": "Удалить"
},
"form": {
"createTitle": "Добавить MCP-сервер",
"editTitle": "Редактировать MCP-сервер",
"name": "Имя *",
"nameHint": "Только строчные буквы, цифры и дефисы",
"displayName": "Отображаемое имя",
"displayNamePlaceholder": "Мой MCP-сервер",
"transport": "Транспорт *",
"command": "Команда *",
"args": "Аргументы (через пробел)",
"argsPlaceholder": "--flag1 --flag2=\"значение с пробелами\"",
"url": "URL *",
"headers": "Заголовки",
"headerKeyPlaceholder": "Имя заголовка",
"headerValuePlaceholder": "Значение заголовка",
"addHeader": "Добавить заголовок",
"env": "Переменные окружения",
"envKeyPlaceholder": "Имя переменной",
"envValuePlaceholder": "Значение",
"addVariable": "Добавить переменную",
"toolPrefix": "Префикс инструмента",
"toolPrefixHint": "Автоматически выводится из имени, если не задан.",
"timeout": "Тайм-аут (секунды)",
"enabled": "Включено",
"testConnection": "Проверить подключение",
"testing": "Проверка...",
"toolsFound": "Найдено инструментов: {{count}}",
"cancel": "Отмена",
"create": "Создать",
"update": "Обновить",
"saving": "Сохранение...",
"errors": {
"nameRequired": "Имя и транспорт обязательны",
"nameSlug": "Имя должно быть корректным слагом (только строчные буквы, цифры и дефисы)",
"commandRequired": "Команда обязательна для транспорта stdio",
"urlRequired": "URL обязателен для транспорта SSE/HTTP",
"connectionFailed": "Подключение не удалось"
},
"requireUserCredentials": "Требовать учётные данные пользователя",
"requireUserCredentialsHint": "Каждый пользователь должен настроить свои учётные данные. Сервер отключён для пользователей без личных учётных данных.",
"toolHints": "Подсказки для ИИ-агента (необязательно)",
"toolHintsHint": "Заметки, написанные администратором, добавляются к описанию каждого инструмента, чтобы LLM знала об особенностях сервера.",
"toolHintsGlobal": "Общая подсказка",
"toolHintsGlobalPlaceholder": "напр. Все инструменты ожидают JS-выражения. Не добавляйте точку с запятой в конце.",
"toolHintsGlobalHint": "Применяется к каждому инструменту этого сервера.",
"toolHintsPerTool": "Подсказки по инструментам",
"toolHintsToolNamePlaceholder": "Имя инструмента (напр. search)",
"toolHintsToolValuePlaceholder": "Текст подсказки, показываемый LLM",
"toolHintsAdd": "Добавить подсказку",
"oauth": {
"title": "Аутентификация OAuth",
"titleHint": "Подключение к MCP-серверам, требующим авторизации OAuth 2.1.",
"enable": "Включить OAuth",
"useDcr": "Динамическая регистрация клиента (DCR)",
"useDcrHint": "Автоматически регистрироваться как OAuth-клиент. Отключите, чтобы ввести учётные данные вручную.",
"grantType": "Тип разрешения",
"pkce": "Authorization Code + PKCE (публичный клиент)",
"authCode": "Authorization Code (конфиденциальный клиент)",
"clientCreds": "Client Credentials",
"authEndpoint": "URL авторизации",
"authEndpointPlaceholder": "https://auth.example.com/oauth/authorize",
"tokenEndpoint": "URL токена",
"tokenEndpointPlaceholder": "https://auth.example.com/oauth/token",
"clientId": "Client ID",
"clientSecret": "Client Secret",
"clientSecretPlaceholder": "Оставьте пустым, чтобы сохранить текущее",
"scope": "Области доступа",
"scopePlaceholder": "напр. read write offline_access",
"modePerUser": "Режим аутентификации: для каждого пользователя (каждый должен авторизоваться отдельно)",
"modeGlobal": "Режим аутентификации: глобальный (общий токен для всех пользователей)",
"authorize": "Авторизовать",
"reauthorize": "Повторно авторизовать",
"revoke": "Отозвать",
"authorized": "Авторизовано",
"notAuthorized": "Не авторизовано",
"expired": "Токен истёк",
"authorizing": "Открытие авторизации...",
"authSuccess": "Авторизация выполнена",
"authFailed": "Авторизация не удалась",
"savingFirst": "Сохранение сервера перед авторизацией..."
}
},
"grants": {
"title": "Доступ агентов — {{name}}",
"currentGrants": "Текущие права доступа",
"allToolsAllowed": "Разрешены все инструменты",
"addGrant": "Добавить доступ агенту",
"editGrant": "Редактировать доступ",
"selectAgent": "Выберите агента...",
"toolAllowList": "Список разрешённых инструментов (необязательно)",
"toolDenyList": "Список запрещённых инструментов (необязательно)",
"allowPlaceholder": "Выберите инструменты для разрешения...",
"denyPlaceholder": "Выберите инструменты для запрета...",
"grant": "Предоставить",
"update": "Обновить",
"cancel": "Отмена",
"agentRequired": "Агент обязателен",
"failedGrant": "Не удалось предоставить доступ",
"failedRevoke": "Не удалось отозвать доступ"
},
"tools": {
"title": "Инструменты — {{name}}",
"prefix": "префикс:",
"discovering": "Обнаружение инструментов...",
"noToolsTitle": "Инструменты не обнаружены",
"noToolsDescription": "Возможно, сервер офлайн или у него нет зарегистрированных инструментов.",
"failedLoad": "Не удалось загрузить инструменты",
"filterPlaceholder": "Фильтр инструментов...",
"noMatch": "Нет подходящих инструментов"
},
"toast": {
"created": "MCP-сервер создан",
"updated": "MCP-сервер обновлён",
"deleted": "MCP-сервер удалён",
"failedCreate": "Не удалось создать MCP-сервер",
"failedUpdate": "Не удалось обновить MCP-сервер",
"failedDelete": "Не удалось удалить MCP-сервер",
"reconnected": "Подключение к MCP-серверу сброшено",
"failedReconnect": "Не удалось переподключить MCP-сервер"
},
"userCredentials": {
"title": "Мои учётные данные",
"description": "Задайте свои личные учётные данные для этого MCP-сервера. Они переопределяют настройки сервера только для вашей учётной записи.",
"titleAdmin": "Учётные данные пользователя",
"descriptionAdmin": "Задайте учётные данные для конкретного пользователя на этом MCP-сервере. Они переопределяют настройки сервера только для выбранного пользователя.",
"selectUser": "Выберите пользователя",
"apiKey": "API-ключ",
"apiKeyPlaceholder": "Оставьте пустым, чтобы сохранить текущий",
"headers": "Заголовки",
"env": "Переменные окружения",
"headerPlaceholder": "КЛЮЧ=ЗНАЧЕНИЕ, по одному в строке",
"save": "Сохранить",
"delete": "Удалить",
"deleteAll": "Удалить все",
"cancel": "Отмена",
"saved": "Учётные данные сохранены",
"deleted": "Учётные данные удалены",
"hasApiKey": "API-ключ задан",
"hasHeaders": "Заголовки заданы",
"hasEnv": "Переменные окружения заданы",
"noCredentials": "Учётные данные не заданы",
"addHeader": "Добавить заголовок",
"addEnv": "Добавить переменную",
"saveFailed": "Не удалось сохранить учётные данные",
"deleteFailed": "Не удалось удалить учётные данные",
"mergeHint": "Пользователи чатов (Telegram, Discord и т. д.) должны сначала быть объединены в пользователя арендатора на странице «Контакты», прежде чем у них появятся личные учётные данные."
}
}
+239
View File
@@ -0,0 +1,239 @@
{
"title": "Память",
"description": "Просмотр и управление документами памяти агента, фрагментами и эмбеддингами",
"search": "Поиск",
"create": "Создать",
"indexAll": "Индексировать все",
"indexing": "Индексация...",
"emptyTitle": "Нет документов памяти",
"emptyAgentDescription": "У этого агента пока нет документов памяти.",
"emptyGlobalDescription": "Документы памяти не найдены ни у одного агента.",
"filters": {
"agent": "Агент",
"allAgents": "Все агенты",
"scope": "Область",
"allScope": "Все (глобальные + личные)",
"selectAgent": "Выберите агента"
},
"tabs": {
"documents": "Документы",
"knowledgeGraph": "Граф знаний"
},
"columns": {
"path": "Путь",
"agent": "Агент",
"scope": "Область",
"hash": "Хеш",
"updated": "Обновлено",
"actions": "Действия"
},
"scopeLabel": {
"personal": "Личная",
"global": "Глобальная"
},
"delete": {
"title": "Удалить документ памяти",
"description": "Вы уверены, что хотите удалить \"{{path}}\"? Это также удалит все связанные фрагменты и эмбеддинги.",
"confirmLabel": "Удалить"
},
"createDialog": {
"title": "Создать документ памяти",
"path": "Путь *",
"pathPlaceholder": "напр. notes/project-overview.md",
"content": "Содержимое *",
"contentPlaceholder": "Содержимое документа...",
"agentId": "Агент *",
"agentIdPlaceholder": "Выберите агента...",
"scope": "Область",
"existingScope": "Существующая область",
"customScope": "Свой вариант",
"selectGroupUser": "Выберите группу/пользователя...",
"scopeHint": "Глобальная = доступна всем пользователям. Личная = ограничена конкретным пользователем или групповым чатом.",
"autoIndex": "Автоиндексация после создания",
"agentRequired": "Пожалуйста, выберите агента",
"pathRequired": "Путь обязателен",
"contentRequired": "Содержимое обязательно",
"cancel": "Отмена",
"create": "Создать",
"creating": "Создание..."
},
"documentDialog": {
"title": "Документ памяти",
"path": "Путь:",
"agent": "Агент:",
"scope": "Область:",
"hash": "Хеш:",
"updated": "Обновлено:",
"content": "Содержимое",
"chunks": "Фрагменты ({{count}})",
"chunkIndex": "Фрагмент {{index}}",
"noChunks": "Нет фрагментов",
"embedded": "Эмбеддинг создан",
"noEmbedding": "Нет эмбеддинга"
},
"searchDialog": {
"title": "Поиск по памяти",
"query": "Поисковый запрос",
"queryPlaceholder": "Введите поисковый запрос...",
"agentId": "ID агента",
"agentIdPlaceholder": "Фильтр по агенту...",
"limit": "Лимит",
"search": "Поиск",
"searching": "Поиск...",
"results": "Результаты",
"noResults": "Ничего не найдено",
"similarity": "сходство",
"path": "Путь:"
},
"kg": {
"pageTitle": "Граф знаний",
"pageDescription": "Исследуйте сущности и связи, извлечённые из памяти агента.",
"selectAgentTitle": "Выберите агента",
"selectAgentDescription": "Выберите агента, чтобы просмотреть его граф знаний.",
"emptyTitle": "Нет сущностей",
"emptyDescription": "У этого агента пока нет сущностей графа знаний.",
"emptySearchDescription": "Ни одна сущность не соответствует вашему запросу.",
"stats": {
"entities": "Сущности: {{count}}",
"relations": "Связи: {{count}}"
},
"search": {
"placeholder": "Поиск сущностей...",
"button": "Поиск",
"clear": "Очистить"
},
"refresh": "Обновить",
"extract": "Извлечь",
"columns": {
"name": "Имя",
"type": "Тип",
"description": "Описание",
"confidence": "Уверенность",
"actions": "Действия",
"observations": "Наблюдения",
"relations": "Связи"
},
"dedup": {
"button": "Дедупликация",
"title": "Дублирующиеся сущности",
"description": "Проверьте и объедините сущности, которые могут быть дубликатами, на основе сходства эмбеддингов.",
"noCandidates": "Кандидатов на дубликаты не найдено.",
"similar": "сходство",
"merge": "Объединить",
"dismiss": "Отклонить",
"merged": "Сущности успешно объединены.",
"mergeFailed": "Не удалось объединить сущности.",
"dismissed": "Кандидат отклонён.",
"dismissFailed": "Не удалось отклонить кандидата.",
"scan": "Сканировать все",
"scanning": "Сканирование...",
"scanComplete": "Сканирование завершено.",
"scanFailed": "Сканирование не удалось.",
"count": "{{count}} кандидат(ов)"
},
"deleteEntity": {
"title": "Удалить сущность",
"description": "Удалить \"{{name}}\"? Это также удалит все связанные отношения.",
"confirmLabel": "Удалить"
},
"entity": {
"externalId": "Внешний ID:",
"confidence": "Уверенность:",
"description": "Описание:",
"source": "Источник:",
"properties": "Свойства:",
"relations": "Связи",
"traverse": "Обход",
"depthOption": "уровень {{depth}}",
"tabs": {
"table": "Таблица",
"graph": "Граф"
},
"traversing": "Обход...",
"loading": "Загрузка...",
"noRelations": "Связи не найдены.",
"showAll": "Показать все",
"traversalResults": "Результаты обхода ({{count}})",
"direction": {
"outgoing": "→ исходящая",
"incoming": "← входящая"
},
"columns": {
"direction": "Направление",
"relation": "Связь",
"target": "Цель",
"confidence": "Уверенность"
}
},
"extractDialog": {
"title": "Извлечь сущности из текста",
"providerLabel": "Провайдер извлечения",
"modelLabel": "Модель извлечения",
"textLabel": "Текст для извлечения",
"textPlaceholder": "Вставьте текст беседы, заметки или любой контент для извлечения сущностей и связей...",
"extract": "Извлечь",
"extracting": "Извлечение...",
"cancel": "Отмена",
"agentId": "ID агента",
"agentIdPlaceholder": "Оставьте пустым для глобального"
},
"graphView": {
"loading": "Загрузка графа...",
"empty": "Нет сущностей для визуализации",
"nodes": "{{count}} узлов",
"edges": "{{count}} рёбер",
"selected": "Выбрано: {{name}}",
"limitNote": "Показаны первые {{limit}} из {{total}} сущностей",
"limitHint": "Граф ограничен {{limit}} сущностями для производительности. Используйте табличный вид для просмотра всех {{total}} сущностей."
}
},
"toast": {
"created": "Документ памяти создан",
"deleted": "Документ памяти удалён",
"indexed": "Все документы проиндексированы",
"failedCreate": "Не удалось создать документ",
"failedDelete": "Не удалось удалить документ",
"failedIndex": "Не удалось проиндексировать документы",
"entitySaved": "Сущность сохранена",
"entitySaveFailed": "Не удалось сохранить сущность",
"entityDeleted": "Сущность удалена",
"entityDeleteFailed": "Не удалось удалить сущность",
"extractionComplete": "Извлечение завершено",
"extractionFailed": "Извлечение не удалось",
"traversalFailed": "Обход не удался",
"unknownError": "Неизвестная ошибка",
"docCreated": "Документ создан",
"docCreateFailed": "Не удалось создать документ",
"docUpdated": "Документ обновлён",
"docUpdateFailed": "Не удалось обновить документ",
"docDeleted": "Документ удалён",
"docDeleteFailed": "Не удалось удалить документ",
"docIndexed": "Документ проиндексирован",
"docIndexFailed": "Не удалось проиндексировать документ",
"allIndexed": "Все документы проиндексированы",
"allIndexFailed": "Не удалось проиндексировать все",
"searchFailed": "Поиск не удался",
"docLoadFailed": "Не удалось загрузить документ"
},
"tabs": {
"documents": "Документы",
"episodic": "Эпизодическая память"
},
"episodic": {
"noData": "Пока нет эпизодических воспоминаний",
"noDataHint": "Сводки создаются автоматически из сессий агента",
"selectAgent": "Выберите агента для просмотра эпизодических воспоминаний",
"searchPlaceholder": "Поиск по эпизодической памяти...",
"clearSearch": "Очистить",
"results": "результатов",
"turns": "реплик",
"tokens": "токенов",
"expand": "Показать полную сводку",
"collapse": "Скрыть сводку",
"source": {
"session": "Сессия",
"v2_daily": "Ежедневно",
"manual": "Вручную"
}
}
}
+35
View File
@@ -0,0 +1,35 @@
{
"title": "Узлы",
"description": "Управление привязанными устройствами и ожидающими запросами на привязку",
"emptyTitle": "Нет устройств",
"emptyDescription": "Нет привязанных устройств или ожидающих запросов на привязку.",
"pendingRequests": "Ожидающие запросы ({{count}})",
"pairedDevices": "Привязанные устройства ({{count}})",
"sender": "Отправитель:",
"chat": "Чат:",
"columns": {
"channel": "Канал",
"senderId": "ID отправителя",
"paired": "Привязано",
"by": "Кем",
"actions": "Действия"
},
"approve": "Одобрить",
"deny": "Отклонить",
"revoke": "Отозвать",
"confirmApprove": {
"title": "Одобрить привязку",
"description": "Одобрить запрос на привязку от {{channel}}:{{senderId}} (код: {{code}})? Это устройство сможет взаимодействовать с агентами.",
"confirmLabel": "Одобрить"
},
"confirmDeny": {
"title": "Отклонить привязку",
"description": "Отклонить запрос на привязку от {{channel}}:{{senderId}} (код: {{code}})? Запрос будет удалён.",
"confirmLabel": "Отклонить"
},
"confirmRevoke": {
"title": "Отозвать устройство",
"description": "Отозвать привязку для {{channel}}:{{senderId}}? Устройству потребуется повторная привязка.",
"confirmLabel": "Отозвать"
}
}
+93
View File
@@ -0,0 +1,93 @@
{
"title": "Панель управления",
"description": "Обзор шлюза и использование квот",
"tabs": {
"overview": "Обзор",
"usage": "Использование"
},
"statCards": {
"requestsToday": "Запросов сегодня",
"tokensToday": "Токенов сегодня",
"costToday": "Стоимость за сегодня",
"agents": "Агенты",
"channels": "Каналы",
"channelsAttention": "{{count}} требуют внимания",
"running": "выполняется",
"online": "онлайн",
"users": "{{count}} пользователей",
"inOut": "{{input}} вход / {{output}} выход"
},
"providers": {
"noProvidersTitle": "Провайдеры LLM не настроены",
"noEnabledTitle": "Нет включённых провайдеров LLM",
"noProvidersDesc": "Необходимо добавить хотя бы одного провайдера LLM, прежде чем агенты смогут работать. ",
"noEnabledDesc": "Все провайдеры сейчас отключены. Включите хотя бы одного, чтобы начать использовать агентов. ",
"goToSettings": "Перейти к настройкам провайдеров"
},
"systemHealth": {
"title": "Состояние системы",
"uptime": "Время работы",
"version": "Версия",
"database": "База данных",
"providers": "Провайдеры",
"tools": "Инструменты",
"sessions": "Сессии",
"clients": "Клиенты",
"channels": "Каналы",
"needsAttention": "Требует внимания",
"channelsNeedingAttention": "{{count}} каналов",
"failedCount": "{{count}} с ошибкой",
"warningCountOne": "{{count}} предупреждение",
"warningCountOther": "{{count}} предупреждений",
"moreAttention": "+ещё {{count}}",
"active": "{{count}} активно",
"none": "нет",
"runtimes": "Среды выполнения"
},
"connectedClients": {
"title": "Подключённые клиенты",
"noClients": "Нет подключённых клиентов",
"columns": {
"ip": "IP",
"user": "Пользователь",
"role": "Роль",
"connected": "Подключён"
},
"you": "вы"
},
"cronJobs": {
"title": "Задачи Cron",
"manage": "Управление",
"noJobs": "Задачи cron не настроены",
"disabled": "отключено"
},
"recentRequests": {
"title": "Недавние запросы",
"viewAll": "Показать все",
"noRequests": "Нет недавних запросов",
"columns": {
"time": "Время",
"name": "Название",
"user": "Пользователь",
"channel": "Канал",
"tokens": "Токены",
"duration": "Длительность",
"status": "Статус"
}
},
"quotaUsage": {
"title": "Использование квоты",
"columns": {
"userGroup": "Пользователь / Группа",
"hour": "Час",
"day": "День",
"week": "Неделя"
},
"noLimit": "без лимита"
},
"embedding": {
"title": "Эмбеддинги",
"notConfigured": "Не настроено",
"configure": "Настроить в разделе «Провайдеры» →"
}
}
+125
View File
@@ -0,0 +1,125 @@
{
"title": "Среда выполнения и пакеты",
"description": "Управление средами выполнения и установленными пакетами внутри активного контейнера среды выполнения GoClaw",
"runtimes": {
"title": "Среды выполнения",
"scopeTitle": "Статус сред выполнения в рамках контейнера",
"scopeDesc": "Эти проверки выполняются внутри активного контейнера среды выполнения GoClaw. Среды выполнения, установленные на хосте, изменения профиля оболочки и бинарные файлы, управляемые nvm, здесь не используются.",
"minimalImageHint": "Опубликованный образ latest включает Python, но не Node. Используйте образ full для Node/npm и встроенных дополнений, base для минимального образа, пересоберите с ENABLE_NODE=true / ENABLE_FULL_SKILLS=true или установите среды выполнения вручную в этом контейнере.",
"available": "Доступно",
"missing": "Отсутствует",
"missingInContainer": "Отсутствует в контейнере"
},
"system": {
"title": "Системные пакеты",
"placeholder": "Имя пакета (напр. github-cli)"
},
"pip": {
"title": "Пакеты Python",
"placeholder": "Имя пакета (напр. pandas)"
},
"npm": {
"title": "Пакеты Node",
"placeholder": "Имя пакета (напр. typescript)"
},
"github": {
"title": "Бинарные файлы GitHub",
"placeholder": "owner/repo[@tag] (напр. cli/cli@v2.45.0)",
"browse": "Обзор релизов",
"muslWarning": "Alpine Linux использует musl libc. Бинарные файлы, скомпилированные под glibc, могут не работать во время выполнения. Предпочитайте статические или совместимые с musl релизы.",
"muslDismiss": "Закрыть",
"pickerTitle": "Выберите релиз из {{repo}}",
"pickerEmpty": "Релизы для {{repo}} не найдены",
"pickerLoading": "Загрузка релизов...",
"pickerMatchingAssets": "{{count}} подходящих / {{total}} всего",
"pickerPrerelease": "Предварительный выпуск",
"pickerSelect": "Выбрать",
"columns": {
"repo": "Репозиторий",
"tag": "Версия",
"binaries": "Бинарные файлы",
"installedAt": "Установлено"
}
},
"updates": {
"available": "Доступно обновлений: {{count}}",
"none": "Все пакеты актуальны",
"refresh": "Обновить",
"refreshing": "Обновление...",
"lastCheckedAgo": "Последняя проверка {{ago}}",
"neverChecked": "Ещё не проверялось",
"update": "Обновить",
"updateAll": "Обновить все",
"updating": "Обновление {{name}}...",
"updateSucceeded": "{{name}} обновлён до {{version}}",
"updateFailed": "Не удалось обновить {{name}}: {{reason}}",
"updateAllResult": "Успешно: {{succeeded}}, с ошибкой: {{failed}}",
"confirmAllTitle": "Обновить пакетов: {{count}}?",
"confirmAllBody": "Это может занять несколько минут. Отдельные обновления применяются последовательно.",
"selected": "Выбрано: {{count}}",
"manifestDesyncWarn": "Бинарный файл обновлён, но не удалось сохранить манифест. Требуется ручное восстановление для {{name}}.",
"cacheStale": "Кэш обновлений устарел. Пожалуйста, сначала обновите.",
"adminOnly": "Требуется доступ администратора",
"empty": "Нет доступных обновлений",
"source": {
"github": "GitHub",
"pip": "pip",
"npm": "npm",
"apk": "apk"
},
"filter": {
"all": "Все источники",
"label": "Фильтр"
},
"unavailable": {
"pip": "pip не установлен",
"npm": "npm не установлен",
"apk": "apk недоступен в этой системе"
},
"button": {
"tooltip": {
"github": "Обновить из релиза GitHub",
"pip": "Обновить через pip",
"npm": "Обновить через npm",
"apk": "Обновить через apk (системный пакет)"
}
},
"summary": {
"perSource": "{{source}}: {{count}}"
}
},
"actions": {
"install": "Установить",
"uninstall": "Удалить",
"installing": "Установка...",
"uninstalling": "Удаление..."
},
"messages": {
"installSuccess": "{{name}} успешно установлен",
"installError": "Не удалось установить {{name}}",
"uninstallSuccess": "{{name}} успешно удалён",
"uninstallError": "Не удалось удалить {{name}}"
},
"confirmUninstall": {
"title": "Подтвердить удаление",
"description": "Вы уверены, что хотите удалить {{name}}? Это действие нельзя отменить."
},
"table": {
"name": "Имя",
"version": "Версия",
"actions": "Действия",
"empty": "Пакеты не установлены"
},
"tabs": {
"system": "Система",
"python": "Python",
"node": "Node",
"github": "GitHub",
"cliCredentials": "Учётные данные CLI"
},
"runtimesHeader": {
"title": "Среды выполнения",
"available": "Доступно",
"missing": "Отсутствует"
}
}
@@ -0,0 +1,50 @@
{
"title": "Ожидающие сообщения",
"description": "Буферизованные сообщения каналов, ожидающие обработки агентом",
"emptyTitle": "Нет ожидающих сообщений",
"emptyDescription": "Буферизованные группы сообщений не найдены. Сообщения появляются здесь, когда каналы буферизуют входящие сообщения до обработки агентом.",
"howItWorks": {
"title": "Как это работает",
"step1": "Сообщения из каналов (Telegram, Discord и т. д.) буферизуются здесь, пока агент занят или не в сети.",
"step2": "Когда буфер достигает порога (по умолчанию: 50 сообщений), включается автосжатие — LLM обобщает старые сообщения, сохраняя только 15 самых свежих.",
"step3": "При следующем ходе агента сжатая сводка + недавние сообщения внедряются как контекст, чтобы агент наверстал упущенное, не будучи перегруженным.",
"compactAction": "Сжать — вручную запустить обобщение LLM сейчас. Полезно, когда вы хотите, чтобы агент обработал чистую сводку вместо потока сырых сообщений.",
"clearAction": "Очистить — навсегда удалить все буферизованные сообщения группы. Используйте, когда сообщения больше не актуальны."
},
"columns": {
"channel": "Канал",
"group": "Группа",
"messages": "Сообщения",
"status": "Статус",
"lastActivity": "Последняя активность",
"actions": "Действия"
},
"status": {
"compacted": "Сжато",
"raw": "Сырое"
},
"compact": "Сжать",
"compacting": "Сжатие…",
"clear": "Очистить",
"confirmClear": {
"title": "Очистить сообщения?",
"description": "Это навсегда удалит все сообщения в {{channel}} / {{key}}. Это действие нельзя отменить.",
"cancel": "Отмена",
"confirm": "Очистить"
},
"dialog": {
"title": "Сообщения — {{name}}",
"noMessages": "Сообщения не найдены.",
"summary": "Сводка"
},
"toast": {
"compacted": "Сжатие завершено",
"compactedSummarized": "Обобщено до {{count}} сообщений",
"compactedDeleted": "Все сообщения удалены (провайдер LLM недоступен)",
"compacting": "Сжатие…",
"compactingDesc": "Обобщение LLM выполняется в фоне. Список обновится автоматически.",
"failedCompact": "Сжатие не удалось",
"cleared": "Сообщения очищены",
"failedClear": "Не удалось очистить сообщения"
}
}
+388
View File
@@ -0,0 +1,388 @@
{
"title": "Провайдеры",
"description": "Управление провайдерами LLM",
"addProvider": "Добавить провайдера",
"searchPlaceholder": "Поиск провайдеров...",
"emptyTitle": "Нет провайдеров",
"emptyDescription": "Добавьте своего первого провайдера LLM, чтобы начать.",
"noMatchTitle": "Провайдеры не найдены",
"noMatchDescription": "Попробуйте другой поисковый запрос.",
"columns": {
"name": "Имя",
"type": "Тип",
"apiBase": "Базовый URL API",
"apiKey": "Ключ API",
"status": "Статус",
"actions": "Действия"
},
"apiKey": {
"oauthToken": "Токен OAuth",
"notSet": "Не задан"
},
"card": {
"apiKeySet": "Ключ API задан",
"authenticated": "Аутентифицирован",
"oauthAccount": "Аккаунт OAuth",
"oauthAlias": "Псевдоним: {{name}}",
"connected": "Подключено",
"signInNeeded": "Требуется вход",
"disabled": "Отключено"
},
"quota": {
"checking": "Проверка квоты",
"plan": "Тариф",
"lastChecked": "Проверено {{value}}",
"failure": {
"billing": {
"label": "Оплата",
"description": "Оплата рабочего пространства или права доступа сейчас блокируют этот аккаунт."
},
"exhausted": {
"label": "Исчерпано",
"description": "Этот аккаунт выполнил вход, но одно из его основных окон квоты исчерпано."
},
"reauth": {
"label": "Повторный вход",
"description": "Войдите снова, чтобы обновить доступ к рабочему пространству."
},
"forbidden": {
"label": "Запрещено",
"description": "Этот аккаунт не может прочитать данные квоты вышестоящего сервиса."
},
"needs_setup": {
"label": "Требуется настройка",
"description": "Войдите снова, чтобы GoClaw мог восстановить метаданные рабочего пространства аккаунта ChatGPT."
},
"retry_later": {
"label": "Повторить позже",
"description": "Эндпоинт квоты временно недоступен или ограничен по частоте запросов."
},
"unavailable": {
"label": "Недоступно",
"description": "Данные квоты сейчас недоступны для этого аккаунта."
}
}
},
"form": {
"createTitle": "Добавить провайдера",
"editTitle": "Редактировать провайдера",
"name": "Имя *",
"namePlaceholder": "напр. openrouter",
"nameHint": "Строчные буквы, цифры, дефисы",
"displayName": "Отображаемое имя",
"displayNamePlaceholder": "OpenRouter",
"providerType": "Тип провайдера *",
"apiKey": "Ключ API",
"apiKeyPlaceholder": "sk-...",
"apiKeyEditPlaceholder": "Оставьте как есть или введите новый ключ",
"apiKeySetHint": "Ключ API задан. Очистите поле и введите новое значение, чтобы изменить его.",
"apiBase": "Базовый URL API",
"enabled": "Включено",
"cancel": "Отмена",
"close": "Закрыть",
"create": "Создать",
"save": "Сохранить",
"update": "Обновить",
"saving": "Сохранение...",
"creating": "Создание...",
"alreadyAdded": "(уже добавлено)",
"nameFixed": "Имя",
"configure": "Настройте подключение к провайдеру LLM.",
"configureOauth": "Подключите один аккаунт OpenAI Codex OAuth.",
"oauthAlias": "Псевдоним аккаунта *",
"oauthAliasPlaceholder": "напр. primary",
"oauthAliasHint": "Строчный псевдоним, используемый в маршрутизации и пулах.",
"oauthDisplayNamePlaceholder": "Основной аккаунт Codex",
"oauthDisplayNameHint": "Необязательная метка, отображаемая в панели управления.",
"lowercaseHint": "Строчные буквы, цифры, дефисы"
},
"delete": {
"title": "Удалить провайдера",
"description": "Вы уверены, что хотите удалить «{{name}}»? Это действие нельзя отменить.",
"confirmLabel": "Удалить"
},
"types": {
"anthropic_native": "Anthropic",
"openai_compat": "OpenAI Compat",
"gemini_native": "Gemini",
"openrouter": "OpenRouter",
"groq": "Groq",
"deepseek": "DeepSeek",
"mistral": "Mistral",
"xai": "xAI",
"minimax_native": "MiniMax",
"cohere": "Cohere",
"perplexity": "Perplexity",
"chatgpt_oauth": "Подписка ChatGPT (OAuth)",
"yescale": "YesScale",
"acp": "ACP"
},
"acp": {
"description": "Оркестрация ACP-совместимых агентов кодирования в виде подпроцессов. Ключ API не требуется.",
"binary": "Бинарный файл",
"binaryPlaceholder": "claude",
"binaryHint": "Путь или имя бинарного файла ACP-агента (напр. claude, codex, gemini)",
"args": "Аргументы",
"argsPlaceholder": "--profile goclaw",
"argsHint": "Аргументы через пробел, передаваемые бинарному файлу",
"idleTTL": "Idle TTL",
"idleTTLPlaceholder": "5m",
"idleTTLHint": "Завершать простаивающие процессы по истечении этого времени (напр. 5m, 1h)",
"permMode": "Режим разрешений",
"permModeApproveAll": "Одобрять всё",
"permModeApproveReads": "Одобрять только чтение",
"permModeDenyAll": "Отклонять всё",
"workDir": "Рабочий каталог",
"workDirPlaceholder": "/tmp/workspace",
"workDirHint": "Рабочий каталог для подпроцессов агента (необязательно)"
},
"ollama": {
"title": "Конфигурация Ollama",
"description": "Настройки, специфичные для Ollama",
"numCtx": "Контекстное окно (токены)",
"numCtxPlaceholder": "Оставьте пустым для автоопределения из модели",
"numCtxHelp": "Максимальное количество токенов. Оставьте пустым для автоопределения через Ollama API.",
"thinkingEnabled": "Токены рассуждений / размышлений",
"thinkingEnabledDefault": "По умолчанию (выкл.)",
"thinkingEnabledOn": "Вкл.",
"thinkingEnabledOff": "Выкл.",
"thinkingEnabledHelp": "Определяет, будет ли этот провайдер запрашивать у модели выдачу видимых токенов рассуждений («размышлений»). По умолчанию отключено, чтобы избежать раздутого вывода цепочки рассуждений от моделей вроде qwq или deepseek-r1."
},
"oauth": {
"checkingStatus": "Проверка статуса аутентификации...",
"authSuccessful": "Аутентификация успешна!",
"authSuccessfulDesc": "Этот именованный аккаунт OpenAI/Codex готов к использованию.",
"activeProvider": "Псевдоним аккаунта",
"authenticated": "Аутентифицирован — аккаунт",
"active": "активен",
"poolBadge": "Пул готов",
"roundRobinBadge": "Круговой перебор",
"modelPrefixHint": "Используйте префикс модели",
"modelPrefixExample": "в конфигурации агента (например {{example}}).",
"multiAccountHint": "Добавьте больше псевдонимов позже из пула агентов, чтобы включить объединение в пул или круговой перебор.",
"aliasRequired": "Введите корректный строчный псевдоним аккаунта перед началом OpenAI Codex OAuth.",
"removeToken": "Отключить аккаунт",
"signInDesc": "Войдите с помощью вашей подписки ChatGPT/Codex. Отдельный ключ API не требуется.",
"waiting": "Ожидание аутентификации... Завершите вход в открывшемся окне.",
"remoteVpsHint": "После входа ваш браузер попытается открыть",
"remoteVpsError": "и покажет ошибку «Не удаётся получить доступ к странице». Это нормально — скопируйте полный URL из адресной строки браузера и вставьте его ниже.",
"pasteUrlPlaceholder": "http://localhost:1455/auth/callback?code=...&state=...",
"submit": "Отправить",
"signInWithChatGPT": "Подключить аккаунт OpenAI",
"starting": "Запуск...",
"remoteVps": "Удалённый сервер/VPS?",
"loggedOut": "Выход выполнен",
"loggedOutDesc": "Аккаунт OpenAI Codex OAuth отключён",
"oauthFailed": "Ошибка OAuth",
"exchangeFailed": "Ошибка обмена",
"logoutFailed": "Ошибка выхода",
"done": "Готово"
},
"cli": {
"description": "Claude CLI использует ваш локальный",
"descriptionSuffix": "бинарный файл. Ключ API не требуется.",
"checkingAuth": "Проверка аутентификации...",
"authenticatedAs": "Аутентифицирован как",
"switchAccount": "Сменить аккаунт?",
"switchAccountInstructions": "Выполните в терминале сервера:",
"switchAccountRecheck": "Затем нажмите",
"switchAccountRecheckSuffix": "для повторной проверки.",
"notAuthenticated": "Не аутентифицирован",
"runOnServer": "Выполните в терминале сервера:",
"recheckButton": "Проверить снова"
},
"detail": {
"title": "Сведения о провайдере",
"advanced": "Дополнительно",
"identity": "Идентификация",
"identityDesc": "Идентификация провайдера",
"connection": "Подключение",
"connectionDesc": "Конфигурация эндпоинта API",
"acpConfig": "Конфигурация ACP",
"acpConfigDesc": "Настройки подпроцесса агента",
"cliConfig": "Claude CLI",
"cliConfigDesc": "Локальная аутентификация CLI",
"oauthConfig": "Подписка ChatGPT (OAuth)",
"oauthConfigDesc": "Управление входом для этого именованного аккаунта OpenAI/Codex",
"nameReadonly": "Идентификатор провайдера, изменить нельзя",
"oauthAliasReadonly": "Псевдоним аккаунта OAuth, изменить нельзя",
"providerType": "Тип провайдера",
"apiKeySection": "Ключ API",
"apiKeySectionDesc": "Учётные данные аутентификации",
"statusSection": "Статус",
"statusSectionDesc": "Доступность провайдера",
"enabledDesc": "Провайдер активен и доступен для агентов",
"embeddingSection": "Эмбеддинги",
"oauthAccountUsage": "Использование аккаунта",
"oauthAccountUsageDesc": "Как этот псевдоним работает в рамках объединения OpenAI Codex, принадлежащего провайдеру.",
"oauthAccountUsageManagedDesc": "Этот псевдоним в настоящее время является участником пула, управляемого {{provider}}.",
"oauthAccountUsageOwnerDesc": "Этому псевдониму сейчас принадлежит переиспользуемый пул с {{count}} дополнительными аккаунтами.",
"oauthPoolRole": {
"member": "Участник пула",
"owner": "Владелец пула",
"standalone": "Отдельный"
},
"oauthAliasLabel": "Псевдоним аккаунта",
"oauthAccountBadge": "Подписка ChatGPT (OAuth)",
"oauthModelPrefix": "Префикс модели",
"oauthQuotaTitle": "Статус квоты",
"oauthQuotaDescription": "Последняя квота рабочего пространства ChatGPT для этого аккаунта.",
"oauthModelPrefixCopied": "Префикс модели скопирован",
"oauthPreferredHint": "Задайте этот псевдоним в поле «Провайдер» агента, чтобы сделать его основным псевдонимом OpenAI.",
"oauthProviderDefaultHint": "Используйте настройки пула по умолчанию ниже, чтобы задать переиспользуемую политику маршрутизации OpenAI Codex для каждого агента, указывающего на этот псевдоним.",
"oauthRoutingHint": "Страницы агентов теперь показывают действующий пул для этого агента, а также наследует ли он эти настройки по умолчанию или сохраняет собственное переопределение.",
"oauthManagedByHint": "Этот псевдоним управляется провайдером {{provider}}. Изменяйте членство в пуле там, а не в этом аккаунте.",
"reasoningDefaultsTitle": "Настройки рассуждений по умолчанию",
"reasoningDefaultsDescription": "Задайте политику рассуждений по умолчанию для агентов, использующих этого провайдера. Итоговое усилие во время выполнения всё равно нормализуется относительно выбранной модели каждого агента.",
"reasoningPreset": "Пресет по умолчанию",
"reasoningExpertMode": "Экспертные настройки по умолчанию",
"reasoningExpertModeDesc": "Используйте расширенные настройки рассуждений по умолчанию, принадлежащие провайдеру, когда нужны усилия вроде auto, none, minimal или xhigh.",
"reasoningPreviewDescription": "Предпросмотр явных метаданных о возможностях рассуждений для {{model}}.",
"reasoningPreviewLabel": "Предпросмотр возможностей",
"reasoningPreviewDefault": "Рассуждения модели по умолчанию для предпросмотра: {{level}}",
"reasoningPreviewEmpty": "Для этого провайдера пока не возвращено моделей с явной поддержкой рассуждений.",
"reasoningRequestedEffort": "Запрошенное усилие",
"reasoningFallbackBehavior": "Поведение при откате",
"codexPoolDefaultsTitle": "Настройки пула по умолчанию",
"codexPoolDefaultsDescription": "Задайте переиспользуемый пул OpenAI Codex, принадлежащий этому псевдониму, для агентов, использующих его как основного провайдера.",
"poolManagedByDescription": "Этот провайдер является участником пула, принадлежащего {{owner}}. Чтобы изменить настройки пула, перейдите к владельцу пула.",
"oauthDisplayNameRecommendation": "Добавьте отображаемое имя, если хотите более понятные метки, когда в пуле появляется несколько аккаунтов OpenAI Codex OAuth.",
"poolActivityTitle": "Активность пула",
"poolActivityDescription": "Совокупная активность во время выполнения по всем агентам, использующим пул Codex этого провайдера.",
"poolActivityRefresh": "Обновить",
"poolActivityTopAgents": "Агенты",
"poolActivityTopAgentsTitle": "Топ агентов, использующих этот пул",
"poolActivityRequests": "зап.",
"poolActivityEmpty": "Активности пока нет",
"poolActivityEmptyDesc": "Активность пула появится здесь, как только агенты начнут маршрутизировать запросы через этот пул."
},
"embedding": {
"enable": "Включить эмбеддинги",
"enableDesc": "Разрешить этому провайдеру генерировать текстовые эмбеддинги для памяти, навыков и графа знаний",
"model": "Модель эмбеддингов",
"dimensions": "Размерность вывода",
"dimensionsHint": "Память GoClaw в настоящее время хранит эмбеддинги в vector(1536). Оставьте это поле пустым, если модель уже выдаёт 1536, или задайте ровно 1536, если провайдер поддерживает усечение из более крупных нативных размерностей.",
"dimensionsInvalid": "Память GoClaw в настоящее время поддерживает только 1536.",
"apiBase": "Базовый URL API эмбеддингов",
"apiBasePlaceholder": "(как у провайдера)",
"apiBaseHint": "Переопределите, если эндпоинт эмбеддингов отличается от основного базового URL API провайдера",
"verify": "Проверить эмбеддинги",
"verifyFailed": "Проверка эмбеддингов не удалась",
"dimensionsMismatch": "{{count}} размерностей — не соответствует требуемым 1536"
},
"pricing": {
"title": "Стоимость моделей",
"description": "Синхронизируйте цены OpenRouter и переопределите стоимость моделей этого провайдера для лимитов использования.",
"skippedDescription": "Лимиты использования пропускают провайдеров подписки и локальных провайдеров, но цены всё равно можно подготовить для последующей маршрутизации через API.",
"sync": "Синхронизировать OpenRouter",
"model": "Модель",
"saveOverride": "Сохранить переопределение",
"catalogMatches": "Совпадения в каталоге OpenRouter",
"source": "Источник",
"configuredFields": "Настроенные поля",
"override": "Переопределение",
"emptyOverrides": "Для этого провайдера нет переопределений стоимости.",
"deleteOverride": "Удалить переопределение",
"fields": {
"input": "Ввод",
"output": "Вывод",
"cache_read": "Чтение кэша",
"cache_write": "Запись кэша",
"reasoning": "Рассуждения",
"request": "Запрос",
"image": "Изображение",
"web_search": "Веб-поиск"
},
"toast": {
"synced": "Синхронизировано {{count}} моделей OpenRouter",
"syncFailed": "Не удалось синхронизировать цены OpenRouter",
"saved": "Переопределение стоимости сохранено",
"saveFailed": "Не удалось сохранить переопределение стоимости",
"deleted": "Переопределение стоимости удалено",
"deleteFailed": "Не удалось удалить переопределение стоимости"
}
},
"reasoning": {
"off": "Выкл.",
"offDesc": "Расширенные размышления по умолчанию отключены",
"auto": "Авто",
"autoDesc": "Попросить модель использовать собственное усилие рассуждений по умолчанию",
"none": "Нет",
"noneDesc": "Явно отключить рассуждения провайдера, сохранив расширенный контракт",
"minimal": "Минимальное",
"minimalDesc": "Использовать наименьшее поддерживаемое усилие рассуждений выше «нет»",
"low": "Низкое",
"lowDesc": "Бюджет ~4K токенов",
"medium": "Среднее",
"mediumDesc": "Бюджет ~10-16K токенов",
"high": "Высокое",
"highDesc": "Бюджет ~32K токенов",
"xhigh": "Очень высокое",
"xhighDesc": "Использовать максимальное поддерживаемое усилие рассуждений",
"downgrade": "Понизить",
"downgradeDesc": "Нормализовать до ближайшего поддерживаемого более низкого уровня или отключить, если более низкого поддерживаемого уровня не существует",
"provider_default": "Использовать значение модели по умолчанию",
"provider_defaultDesc": "Позволить выбранной модели откатиться к собственному усилию рассуждений по умолчанию"
},
"list": {
"poolOwner": "Владелец пула",
"poolMember": "Участник пула",
"poolAvailable": "Пул доступен",
"poolBadge": "Пул",
"standalone": "Отдельный",
"reasoningDefault": "Рассуждения {{level}}",
"managedBy": "Управляется {{provider}}",
"memberCount_one": "{{count}} участник",
"memberCount_other": "{{count}} участников",
"memberOverflow": "+{{count}}",
"strategy": {
"roundRobin": "Круговой перебор",
"priorityOrder": "По приоритету",
"primaryFirst": "Сначала основной"
},
"status": {
"needsSignIn": "Требуется вход",
"disabled": "Отключено"
}
},
"pageHint": {
"title": "Аккаунты подписки ChatGPT (OAuth)",
"description": "Каждый псевдоним — это один аккаунт Codex. Владельцы пулов управляют аккаунтами-участниками здесь, а страницы агентов показывают только действующий маршрут.",
"connected_one": "{{count}} подключённый аккаунт",
"connected_other": "{{count}} подключённых аккаунтов",
"owners_one": "{{count}} владелец пула",
"owners_other": "{{count}} владельцев пулов",
"members_one": "{{count}} участник",
"members_other": "{{count}} участников"
},
"poolCta": {
"unpooledCount": "{{count}} аккаунтов готовы к объединению в пул",
"setupPool": "Настроить пул",
"dismiss": "Скрыть"
},
"poolWizard": {
"title": "Настройка пула",
"description": "Объедините аккаунты ChatGPT для автоматического переключения при сбоях и балансировки нагрузки.",
"selectOwner": "Владелец пула",
"selectOwnerHint": "Основной аккаунт, которому принадлежит конфигурация пула.",
"selectMembers": "Участники пула",
"selectMembersHint": "Выберите аккаунты для включения в пул.",
"selectAll": "Выбрать все",
"deselectAll": "Снять выбор со всех",
"selectedCount": "Выбрано: {{count}}",
"strategy": "Стратегия",
"createPool": "Создать пул",
"noMembers": "Выберите хотя бы одного участника для создания пула.",
"success": "Пул успешно создан.",
"error": "Не удалось создать пул."
},
"toast": {
"created": "Провайдер создан",
"createdDesc": "{{name}} добавлен",
"updated": "Провайдер обновлён",
"deleted": "Провайдер удалён",
"failedCreate": "Не удалось создать провайдера",
"failedUpdate": "Не удалось обновить провайдера",
"failedDelete": "Не удалось удалить провайдера"
}
}
+57
View File
@@ -0,0 +1,57 @@
{
"title": "Сессии",
"description": "Просмотр сессий бесед",
"searchPlaceholder": "Поиск сессий...",
"emptyTitle": "Пока нет сессий",
"emptyDescription": "Сессии появятся здесь, как только вы начнёте общение.",
"noMatchTitle": "Нет подходящих сессий",
"noMatchDescription": "Попробуйте другой поисковый запрос.",
"columns": {
"session": "Сессия",
"agent": "Агент",
"context": "Контекст",
"messages": "Сообщения",
"updated": "Обновлено"
},
"contextBar": {
"compacted": "Сжато раз: {{count}}"
},
"detail": {
"reset": "Сбросить",
"delete": "Удалить",
"deleteTitle": "Удалить сессию",
"deleteDescription": "Это навсегда удалит все сообщения в этой сессии.",
"resetTitle": "Сбросить сессию",
"resetDescription": "Это очистит все сообщения, но сохранит сессию.",
"confirmDelete": "Удалить",
"confirmReset": "Сбросить",
"noMessages": "В этой сессии нет сообщений",
"summary": "Сводка",
"showMore": "Показать больше",
"showLess": "Показать меньше",
"showDetails": "показать детали",
"hide": "скрыть",
"systemMessage": "Системное сообщение",
"messages": "сообщений",
"timeline": {
"title": "Хронология запуска",
"loading": "загрузка",
"count": "{{count}} элементов",
"runStatus": "запуск",
"assistant": "ассистент",
"toolCall": "вызов инструмента",
"toolResult": "результат инструмента",
"trace": "трассировка",
"activity": "активность",
"failed": "не удалось"
}
},
"toast": {
"deleted": "Сессия удалена",
"deleteFailed": "Не удалось удалить сессию",
"reset": "Сессия сброшена",
"resetFailed": "Не удалось сбросить сессию",
"updated": "Сессия обновлена",
"updateFailed": "Не удалось обновить сессию"
}
}
+122
View File
@@ -0,0 +1,122 @@
{
"layout": {
"subtitle": "Давайте запустим ваш шлюз в работу"
},
"steps": {
"provider": "Провайдер",
"model": "Модель",
"agent": "Агент",
"channel": "Канал",
"channelOptional": "(Необязательно)"
},
"complete": {
"title": "Настройка завершена!",
"ready": "Ваша система готова к работе!",
"description": "Провайдер, агент и канал настроены. Вы можете управлять ими в любое время из панели управления.",
"goToDashboard": "Перейти в панель управления"
},
"provider": {
"title": "Настройка провайдера LLM",
"descriptionCli": "Подключение через локальную установку Claude CLI. Ключ API не требуется.",
"descriptionOauth": "Войдите, чтобы создать одну именованную учётную запись OpenAI Codex OAuth. Задайте ей псевдоним сейчас, а затем добавьте другие псевдонимы для участников пула или циклического распределения.",
"description": "Подключитесь к AI-провайдеру для работы ваших агентов. Вам понадобится ключ API.",
"providerType": "Тип провайдера",
"providerTypeHint": "Сервис LLM, к которому вы хотите подключиться. Для доступа к нескольким моделям рекомендуется OpenRouter.",
"name": "Название",
"nameHint": "Внутренний идентификатор этого провайдера. Генерируется автоматически из типа провайдера.",
"oauthAlias": "Псевдоним учётной записи",
"oauthAliasPlaceholder": "например, primary",
"oauthAliasHint": "Используйте уникальный псевдоним в нижнем регистре, например primary, work или team, для этой учётной записи OpenAI/Codex. Псевдоним становится префиксом провайдера/модели, используемым агентами.",
"displayName": "Отображаемое имя (необязательно)",
"displayNameHint": "Понятная метка для этой учётной записи OpenAI/Codex. Полезно, когда вы позже добавите другие псевдонимы.",
"displayNamePlaceholder": "Основная учётная запись Codex",
"apiKey": "Ключ API *",
"apiKeyHint": "Секретный ключ вашего провайдера. Шифруется на стороне сервера и никогда не раскрывается в ответах API.",
"apiBase": "Базовый URL API",
"apiBaseHint": "URL-адрес конечной точки для запросов к API. Заполняется автоматически на основе типа провайдера. Переопределяйте только при использовании собственного прокси.",
"creating": "Создание...",
"create": "Создать провайдера",
"errors": {
"apiKeyRequired": "Требуется ключ API",
"oauthProviderNotFound": "Аутентификация OAuth прошла успешно, но провайдер не найден. Пожалуйста, попробуйте снова.",
"failedCreate": "Не удалось создать провайдера"
}
},
"model": {
"title": "Выбор и проверка модели",
"description": "Выберите модель и проверьте, что подключение к провайдеру работает.",
"provider": "Провайдер:",
"model": "Модель *",
"modelHint": "AI-модель для использования. Выберите из списка или введите ID модели вручную, если её нет в списке.",
"loadingModels": "Загрузка моделей...",
"selectModel": "Выберите или введите ID модели",
"noModelsHint": "Этот провайдер не предоставляет список моделей — введите ID модели вручную.",
"verified": "Проверено",
"verify": "Проверить",
"verifying": "Проверка...",
"continue": "Продолжить",
"modelVerified": "Модель проверена",
"modelVerifiedDesc": "{{model}} работает корректно",
"verificationFailed": "Проверка не удалась. Проверьте ключ API и модель."
},
"agent": {
"title": "Создайте вашего первого агента",
"description": "Агент — это ваш AI-ассистент. Настройте его имя и характер.",
"provider": "Провайдер:",
"model": "Модель:",
"displayName": "Отображаемое имя",
"displayNameHint": "Будет сгенерировано автоматически при вызове на основе характера агента.",
"agentKey": "Ключ агента",
"agentKeyHint": "Уникальный идентификатор агента. Только строчные буквы, цифры и дефисы.",
"agentKeyPlaceholder": "my-agent",
"personality": "Характер агента",
"personalityHint": "Опишите роль и поведение вашего агента. AI сгенерирует из этого контекстные файлы при вызове.",
"personalityPlaceholder": "Опишите характер, назначение и поведение вашего агента...",
"personalityHintBottom": "Настройте этот запрос, чтобы сформировать характер и компетенции вашего агента.",
"selfEvolve": "Саморазвитие",
"selfEvolveDesc": "Разрешить агенту со временем развивать свой стиль общения через SOUL.md",
"gatewayOperatorAccess": "Доступ оператора шлюза",
"gatewayOperatorAccessDesc": "Предоставить отзываемый доступ SecureCLI к локальному CLI goclaw для этого первого агента.",
"gatewayOperatorGranted": "Доступ оператора шлюза предоставлен",
"gatewayOperatorGrantedDesc": "Агент может использовать локальный CLI goclaw. Просмотрите или отзовите доступ в разделе «Пакеты → Учётные данные CLI».",
"gatewayOperatorWarning": "Предупреждение о доступе оператора шлюза",
"creating": "Создание...",
"create": "Создать агента",
"summoningFailed": "Вызов не удался. Пожалуйста, измените настройки и попробуйте снова.",
"errors": {
"noProvider": "Нет доступного провайдера",
"failedCreate": "Не удалось создать агента"
}
},
"channel": {
"title": "Подключение канала",
"description": "Подключите платформу обмена сообщениями к вашему агенту. Вы всегда можете добавить каналы позже.",
"skip": "Пропустить",
"skipFinish": "Пропустить и завершить",
"agent": "Агент:",
"channelType": "Тип канала",
"channelTypeHint": "Платформа обмена сообщениями для подключения. Например, Telegram, Discord, Zalo.",
"name": "Название",
"nameHint": "Внутренний идентификатор этого экземпляра канала. Генерируется автоматически из типа канала.",
"namePlaceholder": "my-telegram",
"displayName": "Отображаемое имя",
"displayNameHint": "Понятное имя, отображаемое в интерфейсе. Необязательно.",
"displayNamePlaceholder": "Бот продаж",
"credentials": "Учётные данные",
"credentialsHint": "Шифруются на стороне сервера. Никогда не возвращаются в ответах API.",
"creating": "Создание...",
"create": "Создать канал",
"errors": {
"noAgent": "Нет доступного агента",
"requiredFields": "Обязательно: {{fields}}",
"failedCreate": "Не удалось создать канал"
}
},
"common": {
"back": "Назад"
},
"skipSetup": "Пропустить настройку и перейти в панель управления",
"skipSetupConfirm": "Вы уверены, что хотите пропустить настройку? Вы всегда можете настроить провайдеров и агентов позже из панели управления.",
"switchTenant": "Сменить",
"allTenants": "Все арендаторы"
}
+50
View File
@@ -0,0 +1,50 @@
{
"groups": {
"core": "Основное",
"conversations": "Беседы",
"connectivity": "Подключения",
"capabilities": "Возможности",
"data": "Данные",
"monitoring": "Мониторинг",
"system": "Система"
},
"nav": {
"overview": "Обзор",
"chat": "Чат",
"agents": "Агенты",
"agentTeams": "Связи и команды агентов",
"sessions": "Сессии",
"pendingMessages": "Ожидающие сообщения",
"channels": "Каналы",
"webhooks": "Вебхуки",
"contacts": "Контакты",
"skills": "Навыки",
"cron": "Cron",
"hooks": "Хуки",
"customTools": "Пользовательские инструменты",
"builtinTools": "Встроенные инструменты",
"mcpServers": "Серверы MCP",
"memory": "Память",
"vault": "Хранилище знаний",
"knowledgeGraph": "Граф знаний",
"traces": "Трассировки",
"realtimeEvents": "События в реальном времени",
"usage": "Использование",
"logs": "Журналы",
"storage": "Хранилище",
"providers": "Провайдеры",
"config": "Конфигурация",
"approvals": "Одобрения",
"importExport": "Импорт и экспорт",
"nodes": "Узлы",
"tts": "TTS",
"activity": "Активность",
"cliCredentials": "Учётные данные CLI",
"apiKeys": "Ключи API",
"apiDocs": "Документация API",
"packages": "Пакеты",
"tenants": "Арендаторы",
"backupRestore": "Резервное копирование и восстановление",
"workstations": "Рабочие станции"
}
}
+270
View File
@@ -0,0 +1,270 @@
{
"title": "Навыки",
"description": "Управление навыками и возможностями агентов",
"searchPlaceholder": "Поиск навыков...",
"emptyTitle": "Нет навыков",
"emptyDescription": "Навыки ещё не зарегистрированы.",
"noMatchTitle": "Нет подходящих навыков",
"noMatchDescription": "Попробуйте другой поисковый запрос.",
"columns": {
"name": "Имя",
"description": "Описание",
"source": "Источник",
"author": "Автор",
"agents": "Агенты",
"owner": "Владелец",
"visibility": "Режим доступа",
"accessMode": "Режим доступа",
"status": "Статус",
"actions": "Действия"
},
"noDescription": "Нет описания",
"status": {
"unmanaged": "Не управляется",
"missingDepsCount": "{{count}} отсутствует"
},
"filters": {
"label": "Фильтр",
"all": "Все навыки",
"attention": "Требуют внимания",
"missing-deps": "Отсутствуют зависимости",
"disabled": "Отключённые",
"archived": "Архивированные",
"unmanaged": "Не управляемые",
"clear": "Сбросить фильтры"
},
"sort": {
"label": "Сортировка",
"name": "Имя",
"deps": "Отсутствующие зависимости",
"version": "Версия"
},
"health": {
"total": "Всего",
"attention": "Требуют внимания",
"missingDeps": "Отсутствуют зависимости",
"disabled": "Отключённые",
"archived": "Архивированные",
"unmanaged": "Не управляемые"
},
"owner": "Владелец",
"unknownOwner": "Неизвестно",
"grants": {
"title": "Доступ агентов для {{name}}",
"manage": "Управление доступом агентов",
"current": "Текущие права доступа агентов",
"none": "Прав доступа агентов пока нет.",
"add": "Добавить доступ",
"update": "Обновить доступ",
"grant": "Предоставить",
"save": "Сохранить",
"revoke": "Отозвать доступ",
"selectAgent": "Выберите агента",
"allowManage": "Разрешить этому агенту редактировать или удалять навык",
"canManage": "Может редактировать",
"grantAllAgents": "Предоставить всем агентам",
"grantAllPartial": "Не удалось предоставить доступ {{count}} агенту(ам)",
"loadFailed": "Не удалось загрузить права доступа",
"saveFailed": "Не удалось сохранить доступ",
"revokeFailed": "Не удалось отозвать доступ"
},
"bulk": {
"selected": "Выбрано: {{count}}",
"selectSkill": "Выбрать {{name}}",
"selectPage": "Выбрать видимые навыки",
"enable": "Включить",
"disable": "Отключить",
"grantAllAgents": "Предоставить всем агентам",
"delete": "Удалить",
"clear": "Очистить",
"enabled": "Включено навыков: {{count}}",
"disabled": "Отключено навыков: {{count}}",
"grantedAllAgents": "Всем агентам предоставлен доступ к {{count}} навыку(ам)",
"deleted": "Удалено навыков: {{count}}",
"failed": "Массовое действие не удалось",
"deleteTitle": "Удалить выбранные навыки",
"deleteDescription": "Это удалит {{count}} выбранных пользовательских навыков. Введите DELETE для подтверждения.",
"customAvailable": "Доступно пользовательских действий: {{count}}",
"skippedSystem": "Пропущено системных навыков: {{count}}",
"customOnlyReason": "Это действие применимо только к пользовательским навыкам",
"noAgentsReason": "Нет доступных текущих агентов"
},
"export": {
"format": "Формат архива",
"download": "Скачать",
"downloadSelected": "Скачать выбранные",
"downloading": "Загрузка...",
"downloadSuccess": "Загрузка начата",
"downloadFailed": "Загрузка не удалась"
},
"visibility": {
"clickToCycle": "Нажмите, чтобы изменить режим доступа"
},
"accessMode": {
"private": "Только владелец",
"internal": "Агенты с доступом",
"public": "Все агенты арендатора",
"unknown": "Неизвестно ({{value}})",
"clickToCycle": "Нажмите, чтобы изменить режим доступа"
},
"delete": {
"title": "Удалить навык",
"description": "Вы уверены, что хотите удалить \"{{name}}\"? Это действие нельзя отменить.",
"confirmLabel": "Удалить"
},
"upload": {
"title": "Загрузить навыки",
"description": "Загрузите ZIP-файлы, содержащие SKILL.md с YAML-фронтматтером (name, description, slug). Максимум {{max}} МБ на файл.",
"button": "Загрузить",
"uploading": "Загрузка...",
"dropOrClick": "Нажмите или перетащите .zip-файлы",
"dropHere": "Перетащите .zip-файлы сюда",
"onlyZip": "Принимаются только .zip-файлы",
"cancel": "Отмена",
"done": "Готово",
"tooLarge": "Файл превышает установленный лимит загрузки",
"invalidZip": "Некорректный ZIP-файл",
"noSkillMd": "ZIP должен содержать SKILL.md в корне",
"emptySkillMd": "SKILL.md пуст",
"noFrontmatter": "В SKILL.md отсутствует YAML-фронтматтер",
"nameRequired": "В фронтматтере SKILL.md обязательно поле name",
"invalidSlug": "Некорректный формат слага",
"failed": "Загрузка не удалась",
"validating": "Проверка...",
"validCount": "{{valid}} из {{total}} корректны",
"uploadCount": "Загрузить ({{count}})",
"successCount": "{{success}} из {{total}} загружено успешно",
"remove": "Удалить файл",
"tooManySkills": "ZIP содержит слишком много навыков (максимум 50)",
"multiDetected": "Обнаружено навыков: {{count}}",
"skillUnchanged": "Содержимое не изменилось — пропущено",
"slugConflict": "Слаг конфликтует с системным навыком",
"unchanged": "Без изменений",
"new": "Новый",
"agentManagers": "Предоставить агентам права управления",
"managerAgentsHelp": "Выбранные текущие агенты смогут обновлять этот навык позже.",
"selectAllAgents": "Выбрать всех агентов",
"selectAllCurrentAgents": "Выбрать всех текущих агентов",
"clearAgents": "Очистить агентов",
"noAgents": "Нет доступных агентов",
"selectedAgentsCount": "Выбрано {{selected}} из {{total}} текущих агентов",
"summaryUploaded": "Загружено: {{count}}",
"summaryWarnings": "Предупреждений: {{count}}",
"summaryUnchanged": "Без изменений: {{count}}",
"summaryFailed": "Не удалось: {{count}}",
"securityViolations": "Нарушения безопасности:",
"violationLine": "Строка {{line}}: {{reason}}"
},
"edit": {
"title": "Редактировать навык",
"name": "Имя",
"description": "Описание",
"visibility": "Режим доступа",
"accessMode": "Режим доступа",
"tags": "Теги",
"addTag": "Добавить тег...",
"add": "Добавить",
"cancel": "Отмена",
"save": "Сохранить",
"saving": "Сохранение...",
"privateOption": "Приватный (только владелец)",
"internalOption": "Внутренний (агенты/пользователи с доступом)",
"publicOption": "Публичный (все агенты)"
},
"system": "Системный",
"tabs": {
"core": "Основные",
"custom": "Пользовательские"
},
"toggle": {
"enable": "Включить навык",
"disable": "Отключить навык",
"disabled": "Отключено"
},
"tenant": {
"enabled": "Включено",
"disabled": "Отключено",
"default": "По умолчанию",
"overrideHint": "Переопределение этого навыка для арендатора",
"resetDefault": "Сбросить к значению по умолчанию"
},
"deps": {
"rescan": "Пересканировать зависимости",
"rescanning": "Сканирование...",
"rescanSuccess": "Обновлено навыков: {{count}}",
"missing": "Отсутствуют: {{deps}}",
"install": "Установить зависимости",
"installAll": "Установить все зависимости",
"installing": "Установка...",
"installSuccess": "Зависимости успешно установлены",
"installPartial": "Некоторые зависимости не удалось установить",
"installItem": "Установить",
"itemSuccess": "Установлено",
"itemError": "Не удалось",
"missingTitle": "Отсутствующие зависимости",
"systemLabel": "Система",
"pythonLabel": "Python",
"nodeLabel": "Node.js",
"statusActive": "Активен",
"statusArchived": "Архивирован",
"runtimeMissing": "Отсутствуют предварительные требования среды выполнения",
"runtimeMissingDesc": "Основным навыкам требуются среды выполнения Python и/или Node.js внутри контейнера среды выполнения GoClaw. Среды выполнения, установленные на хосте, здесь не используются. Если вы используете опубликованный образ latest, отсутствие сред выполнения в нём ожидаемо.",
"runtimeMissingAction": "Откройте «Пакеты», чтобы проверить или установить среды выполнения в этом контейнере.",
"runtimeRequired": "Сначала установите среды выполнения контейнера"
},
"agents": {
"creator": "Создатель",
"managers": "Менеджеры"
},
"detail": {
"title": "Сведения о навыке",
"content": "Содержимое",
"files": "Файлы",
"version": "Версия:",
"current": "(текущая)",
"noContent": "Содержимое недоступно.",
"fileSearch": "Поиск файлов...",
"filesShown": "{{shown}} из {{total}} файлов",
"copyLink": "Копировать ссылку",
"copySuccess": "Ссылка скопирована",
"copyFailed": "Не удалось скопировать ссылку",
"editContent": "Редактировать содержимое",
"editContentLoading": "Загрузка...",
"editContentSystemHint": "Системные навыки доступны только для чтения и не могут быть отредактированы из веб-интерфейса.",
"editContentLoadFailed": "Не удалось загрузить содержимое навыка для редактирования"
},
"evolution": {
"tab": "Эволюция",
"title": "Саморазвитие",
"enabled": "Включено",
"disabled": "Отключено",
"status": "Статус: {{status}}",
"unavailable": "Данные эволюции для этого навыка недоступны.",
"modes": {
"suggest_only": "Только предложения",
"auto_analyze": "Автоанализ"
},
"metrics": "Метрики",
"total": "Всего",
"succeeded": "Успешно",
"failed": "Неудачно",
"successRate": "Доля успеха",
"suggestions": "Предложения",
"noSuggestions": "Нет предложений.",
"noReason": "Причина не указана.",
"approve": "Одобрить",
"reject": "Отклонить",
"apply": "Применить",
"activity": "Активность",
"noActivity": "Нет недавней активности."
},
"toast": {
"updated": "Навык обновлён",
"updateFailed": "Не удалось обновить навык",
"deleted": "Навык удалён",
"deleteFailed": "Не удалось удалить навык",
"rescanUpdated": "Обновлено навыков: {{count}}",
"rescanNoChanges": "Все навыки актуальны",
"rescanFailed": "Не удалось пересканировать зависимости"
}
}
+25
View File
@@ -0,0 +1,25 @@
{
"title": "Хранилище",
"description": "Обозреватель файлов рабочей области",
"descriptionWithPath": "{{path}} — {{size}}",
"sizeCacheInfo": "Размер хранилища кэшируется на 60 минут",
"unsupportedFile": "Предпросмотр этого типа файла не поддерживается",
"download": "Скачать",
"delete": {
"fileTitle": "Удалить файл",
"folderTitle": "Удалить папку",
"description": "Вы уверены, что хотите удалить {{name}}?",
"folderWarning": " Всё содержимое будет удалено рекурсивно.",
"undone": " Это действие нельзя отменить.",
"deleting": "Удаление...",
"confirmLabel": "Удалить"
},
"upload": {
"title": "Загрузка в хранилище",
"description": "Загрузка файлов в каталог данных"
},
"toast": {
"deleted": "Файл удалён",
"deleteFailed": "Не удалось удалить файл"
}
}
@@ -0,0 +1,103 @@
{
"title": "Системные настройки",
"save": "Сохранить",
"cancel": "Отмена",
"saving": "Сохранение...",
"saved": "Настройки сохранены",
"loadFailed": "Не удалось загрузить настройки",
"saveFailed": "Не удалось сохранить настройки",
"embedding": {
"title": "Эмбеддинги",
"description": "Провайдер и модель для векторных эмбеддингов и семантического поиска.",
"importance": "Эмбеддинги критичны для точности восстановления памяти, поиска навыков, графа знаний и сопоставления задач. Изменения затрагивают всю систему.",
"provider": "Провайдер эмбеддингов",
"model": "Модель эмбеддингов",
"providerTip": "Провайдер LLM, используемый для генерации текстовых эмбеддингов.",
"modelTip": "Модель эмбеддингов (напр. text-embedding-3-small). Должна поддерживать эндпоинт /embeddings.",
"providerPlaceholder": "Выберите провайдера",
"modelPlaceholder": "text-embedding-3-small",
"supportedProviders": "Проверено 1536d: OpenAI (text-embedding-3-small/large), Gemini (gemini-embedding-001 + dimensions), Mistral (codestral-embed), Cohere (embed-v4), DashScope (text-embedding-v3 + dimensions). Настройте размерность в параметрах провайдера для моделей с нативной размерностью > 1536.",
"verify": "Проверить эмбеддинги",
"verifyRequired": "Проверьте модель эмбеддингов перед сохранением.",
"verifyFailed": "Проверка не удалась",
"dimensions": "{{count}} измерений",
"dimensionsMismatch": "{{count}} измерений — не соответствует требуемым 1536",
"maxChunkLen": "Макс. длина фрагмента",
"maxChunkLenHint": "Максимум символов на фрагмент памяти перед разбиением.",
"chunkOverlap": "Перекрытие фрагментов",
"chunkOverlapHint": "Перекрытие символов между последовательными фрагментами для непрерывности контекста."
},
"ux": {
"title": "Поведение UX",
"description": "Управляйте тем, как шлюз отображает активность агента пользователям.",
"intentClassify": "Классификация сообщений занятого агента",
"intentClassifyHint": "Когда агент уже обрабатывает предыдущий ход, классифицировать новые сообщения как вопросы о статусе, запросы на отмену, корректирующие инструкции или новые запросы.",
"intentClassifyInfo": "Это применяется только пока сессия занята; это не определяет, нужен ли запросу командный рабочий процесс.",
"teamWorkClassify": "Классификация командной работы",
"teamWorkClassifyHint": "Классифицировать новые запросы как прямую обработку или командный/делегирующий рабочий процесс.",
"teamWorkClassifyInfo": "Когда запрос выходит за рамки текущего агента или должен быть разбит, система использует эмбеддинги как признак и просит модель выбрать между прямой обработкой и командным/делегирующим рабочим процессом. Система также проверяет разрешения лидера/участника; участники могут создавать запросы на помощь только когда команда включила запросы участников и автодиспетчеризацию.",
"teamWorkClassifyEmbeddingRequired": "Настройте эмбеддинги перед включением классификации командной работы."
},
"kg": {
"title": "Граф знаний",
"description": "Извлекайте сущности и связи из памяти агента в граф знаний с возможностью поиска.",
"provider": "Провайдер извлечения",
"model": "Модель извлечения",
"providerTip": "Провайдер LLM, используемый для извлечения сущностей из памяти.",
"modelTip": "Модель для извлечения сущностей/связей (напр. claude-sonnet-4-20250514).",
"providerPlaceholder": "Выберите провайдера",
"modelPlaceholder": "Выберите модель",
"minConfidence": "Мин. уверенность",
"minConfidenceHint": "Минимальный порог уверенности (0–1) для извлечённых сущностей.",
"info": "Автоматически извлекает сущности и связи, когда агенты записывают в память. Оставьте провайдера пустым для отключения."
},
"bg": {
"title": "Фоновые воркеры",
"description": "Провайдер и модель для фоновых задач (обогащение хранилища, консолидация, сновидения).",
"provider": "Провайдер",
"model": "Модель",
"providerTip": "Провайдер LLM для фоновых задач. Оставьте пустым для использования значения агента по умолчанию.",
"modelTip": "Модель для фоновых задач. Оставьте пустым для использования значения провайдера по умолчанию.",
"providerPlaceholder": "(агент по умолчанию)",
"modelPlaceholder": "(по умолчанию)",
"info": "Используется для обогащения хранилища (обобщение документов), консолидации (сводки сессий) и сновидений. Оставьте пустым, чтобы вернуться к провайдеру агента по умолчанию."
},
"skills": {
"title": "Навыки",
"description": "Настройки пакетов навыков и слэш-команд арендатора.",
"maxUploadSize": "Макс. размер загрузки",
"maxUploadSizeHint": "Лимит ZIP на файл в МБ. Допустимый диапазон: 1-500.",
"slashEnabled": "Включить слэш-команды",
"slashEnabledHint": "Обнаруживать /skill-name и /use skill-name в начале запросов пользователя.",
"slashSuggest": "Предлагать похожие навыки",
"slashSuggestHint": "Показывать близкие совпадения, когда запрошенный навык не найден.",
"slashPartial": "Разрешить частичное совпадение",
"slashPartialHint": "Позволять уникальным префиксам вроде /frontend активировать подходящие навыки.",
"slashPrefix": "Префикс команды",
"slashPrefixHint": "Одиночный символ, используемый перед командами навыков."
},
"compaction": {
"title": "Сжатие ожидающих сообщений",
"description": "Обобщайте длинную историю ожидающих сообщений, чтобы оставаться в пределах контекста.",
"providerPlaceholder": "(авто)",
"threshold": "Порог",
"thresholdHint": "Сообщений до запуска сжатия.",
"keepRecent": "Сохранять недавние",
"keepRecentHint": "Сообщения, сохраняемые после сжатия.",
"maxTokens": "Макс. токенов",
"maxTokensHint": "Лимит токенов для сжатой сводки.",
"info": "Когда групповой чат превышает порог, LLM автоматически обобщает старые сообщения в единую сжатую запись, сохраняя самые свежие для контекста."
},
"moreConfig": "Больше настроек",
"alert": {
"message": "Сбой фоновых воркеров: {{reason}}. Такие функции, как консолидация памяти и обогащение хранилища, могут не работать.",
"openSettings": "Исправить в настройках",
"reason": {
"auth": "Ошибка аутентификации (недействительный или истёкший ключ API)",
"auth_permanent": "Ключ API отозван или отключён",
"billing": "Проблема с оплатой (кредиты исчерпаны или требуется оплата)",
"model_not_found": "Модель не найдена (недействительное имя модели или недоступна)",
"unknown": "Неизвестная ошибка провайдера"
}
}
}
+410
View File
@@ -0,0 +1,410 @@
{
"title": "Команды",
"description": "Управление вашими командами агентов",
"createTeam": "Создать команду",
"searchPlaceholder": "Поиск команд...",
"emptyTitle": "Пока нет команд",
"emptyDescription": "Создайте свою первую команду, чтобы начать.",
"noMatchTitle": "Команды не найдены",
"noMatchDescription": "Попробуйте другой поисковый запрос.",
"viewCard": "Вид карточками",
"viewList": "Вид списком",
"scope": {
"all": "Все области",
"label": "Область"
},
"delete": {
"title": "Удалить команду",
"description": "Вы уверены, что хотите удалить «{{name}}»? Это действие нельзя отменить.",
"confirmLabel": "Удалить"
},
"detail": {
"lead": "Руководитель",
"memberCount": "{{count}} участник",
"memberCountPlural": "{{count}} участников",
"more": "ещё",
"deleteDescription": "Вы уверены, что хотите удалить «{{name}}»? Все участники, задачи и настройки будут безвозвратно удалены.",
"tabs": {
"tasks": "Задачи",
"members": "Участники",
"delegations": "Делегирования",
"workspace": "Рабочее пространство",
"settings": "Настройки"
}
},
"members": {
"title": "Участники",
"noMembers": "Нет участников",
"addMember": "Добавить участника",
"addMemberTooltip": "В качестве участников команды можно добавлять только предопределённых агентов. Открытые агенты работают в контексте отдельного пользователя и не имеют общего контекста, необходимого для командной работы.",
"selectAgent": "Выберите агента для добавления...",
"noAvailableAgents": "Нет доступных агентов",
"searchAgents": "Поиск агентов...",
"adding": "Добавление...",
"add": "Добавить",
"added": "Участник добавлен",
"failedAdd": "Не удалось добавить участника",
"removed": "Участник удалён",
"failedRemove": "Не удалось удалить участника",
"removeMember": "Удалить участника",
"columns": {
"agent": "Агент",
"frontmatter": "Метаданные",
"role": "Роль",
"addedAt": "Добавлен",
"actions": "Действия"
}
},
"tasks": {
"title": "Задачи",
"loading": "Загрузка задач...",
"noTasks": "Пока нет задач",
"noTasksDescription": "Задачи создаются агентами команды в процессе совместной работы.",
"refresh": "Обновить",
"createTask": "Создать задачу",
"createTaskTitle": "Создать задачу",
"subjectPlaceholder": "Тема задачи...",
"descriptionPlaceholder": "Необязательное описание...",
"priorityLabel": "Приоритет",
"assign": "Назначить",
"assignTo": "Назначить...",
"unassigned": "Не назначено",
"filters": {
"active": "Активные",
"pending": "Ожидающие",
"inProgress": "В работе",
"inReview": "На проверке",
"completed": "Завершённые",
"all": "Все"
},
"columns": {
"id": "ID",
"subject": "Тема",
"status": "Статус",
"owner": "Владелец",
"priority": "Приоритет",
"taskId": "ID задачи",
"created": "Создано",
"actions": "Действия"
},
"detail": {
"title": "Сведения о задаче",
"subject": "Тема",
"status": "Статус:",
"priority": "Приоритет:",
"owner": "Владелец:",
"type": "Тип:",
"blockedBy": "Заблокировано:",
"description": "Описание",
"result": "Результат",
"created": "Создано:",
"updated": "Обновлено:",
"taskId": "ID задачи:",
"noDescription": "Нет описания",
"noResult": "Результата пока нет",
"progress": "Прогресс",
"approve": "Одобрить",
"reject": "Отклонить",
"comments": "Комментарии",
"noComments": "Пока нет комментариев",
"commentPlaceholder": "Добавить комментарий...",
"addComment": "Комментировать",
"timeline": "Хронология",
"attachments": "Вложения",
"followupStatus": "Ожидание ответа",
"followupMessage": "Текст напоминания:",
"followupCount": "Отправлено напоминаний: {{count}}",
"followupCountMax": "Отправлено напоминаний: {{count}}/{{max}}",
"followupNext": "Следующее напоминание:",
"followupDone": "Все напоминания отправлены",
"download": "Скачать"
},
"delete": "Удалить",
"deleteConfirm": "Удалить эту задачу? Это действие нельзя отменить.",
"selected": "Выбрано: {{count}}",
"deleteSelected": "Удалить выбранные",
"deleteBulkTitle": "Удалить задачи",
"deleteBulkConfirm": "Это безвозвратно удалит {{count}} задач(и). Введите «delete» для подтверждения.",
"badges": {
"awaitingReply": "ожидает ответа"
}
},
"delegations": {
"noTitle": "Нет делегирований",
"noDescription": "Для этой команды не найдено записей о делегированиях.",
"refresh": "Обновить",
"columns": {
"sourceTarget": "Источник / Цель",
"task": "Задача",
"status": "Статус",
"duration": "Длительность",
"time": "Время"
}
},
"workspace": {
"title": "Рабочее пространство",
"noFiles": "Пока нет файлов рабочего пространства",
"noFilesDescription": "Файлы создаются агентами команды в процессе совместной работы.",
"refresh": "Обновить",
"delete": "Удалить",
"confirmDelete": "Удалить этот файл?",
"columns": {
"fileName": "Имя файла",
"size": "Размер",
"uploadedBy": "Загружено",
"scope": "Область",
"updated": "Обновлено"
},
"detail": {
"title": "Содержимое файла",
"empty": "Файл пуст или является бинарным"
},
"upload": {
"title": "Загрузить в рабочее пространство",
"description": "Загрузите файлы для чтения агентами в процессе совместной работы"
},
"crossScopeMoveError": "Нельзя перемещать файлы между разными областями",
"moveFailed": "Не удалось переместить файл"
},
"auditLogs": {
"title": "Журналы аудита",
"empty": "Пока нет событий",
"loadMore": "Загрузить ещё",
"event": {
"created": "Создано",
"claimed": "Взято в работу",
"assigned": "Назначено",
"dispatched": "Отправлено",
"completed": "Завершено",
"failed": "Не удалось",
"cancelled": "Отменено",
"reviewed": "Проверено",
"approved": "Одобрено",
"rejected": "Отклонено",
"commented": "Прокомментировано",
"progress": "Прогресс",
"updated": "Обновлено",
"stale": "Устарело"
}
},
"settings": {
"title": "Настройки команды",
"name": "Имя",
"displayName": "Отображаемое имя",
"description": "Описание",
"leadAgent": "Ведущий агент",
"status": "Статус",
"active": "Активна",
"inactive": "Неактивна",
"save": "Сохранить настройки",
"saving": "Сохранение...",
"saved": "Сохранено",
"failedSave": "Не удалось сохранить",
"userAccessControl": "Управление доступом пользователей",
"allowedUsers": "Разрешённые пользователи",
"allowedUsersHint": "Если задано, только эти пользователи могут запускать рабочие процессы команды. Пусто = разрешены все.",
"deniedUsers": "Заблокированные пользователи",
"deniedUsersHint": "Всегда заблокированы, переопределяет список разрешённых.",
"channelRestrictions": "Ограничения каналов",
"allowedChannels": "Разрешённые каналы",
"allowedChannelsHint": "Если задано, только эти каналы могут активировать рабочие процессы команды. Пусто = разрешены все.",
"deniedChannels": "Заблокированные каналы",
"deniedChannelsHint": "Сообщения из этих каналов всегда блокируются.",
"notifications": "Уведомления",
"notifyDispatched": "Задача отправлена",
"notifyDispatchedHint": "Уведомлять, когда задача назначается участнику команды.",
"notifyProgress": "Прогресс задачи",
"notifyProgressHint": "Уведомлять, когда участник обновляет прогресс задачи.",
"notifyFailed": "Задача не выполнена",
"notifyFailedHint": "Уведомлять при сбое задачи.",
"notifySlowTool": "Оповещение о медленном инструменте",
"notifySlowToolHint": "Системное оповещение, когда вызов инструмента занимает аномально много времени. Всегда напрямую — никогда через руководителя.",
"notifyMode": "Режим доставки",
"notifyModeHint": "Как уведомления доставляются в канал чата.",
"notifyModeDirect": "Напрямую",
"notifyModeDirectDesc": "Отправлять уведомления прямо в канал чата. Быстро, без обработки ИИ.",
"notifyModeLeader": "Через руководителя",
"notifyModeLeaderDesc": "Агент-руководитель естественно переформулирует обновления перед отправкой пользователю.",
"notifyModeLeaderWarning": "Режим руководителя использует ИИ для переформулирования сообщений (расходует токены, может быть медленнее).",
"notifyCompleted": "Уведомлять при завершении задачи",
"notifyCommented": "Уведомлять при комментировании задачи",
"notifyNewTask": "Уведомлять при создании новой задачи",
"memberRequests": "Запросы участников",
"memberRequestsEnabled": "Разрешить задачи-запросы участников",
"memberRequestsEnabledDesc": "Участники могут создавать задачи-запросы, чтобы попросить помощи у других членов команды",
"memberRequestsAutoDispatch": "Автоматически отправлять исполнителю",
"memberRequestsAutoDispatchDesc": "Запросы отправляются немедленно; иначе они остаются в ожидании проверки руководителем",
"searchUsers": "Поиск пользователей...",
"selectChannel": "Выберите канал...",
"escalationPolicy": "Политика эскалации",
"escalationMode": "Режим эскалации",
"escalationModeHint": "Определяет, как обрабатываются привилегированные действия в рабочем пространстве (закрепление, теги, удаление чужих файлов, set_template), запрошенные агентами.",
"blockerEscalation": "Эскалация блокировок",
"blockerEscalationEnabled": "Включить эскалацию блокировок",
"blockerEscalationHint": "Когда участники сообщают о блокировке, задача автоматически завершается сбоем, и руководитель уведомляется для повтора с обновлёнными инструкциями.",
"escalationModeAuto": "Авто (по умолчанию)",
"escalationModeAutoDesc": "Руководитель на базе LLM оценивает запрос — либо отклоняет, либо создаёт задачу на проверку. Никогда не выполняет напрямую.",
"escalationModeReview": "Проверка",
"escalationModeReviewDesc": "Всегда создаёт ожидающую задачу для одобрения человеком. Без автоотклонения.",
"escalationModeReject": "Отклонить",
"escalationModeRejectDesc": "Отклоняет все запросы на привилегированные действия сразу. Режим блокировки.",
"escalationModeNone": "Нет",
"escalationModeNoneDesc": "Без политики эскалации. Ведущий агент выполняет действия напрямую.",
"escalationActions": "Действия эскалации",
"escalationActionsHint": "Выберите, какие действия в рабочем пространстве требуют эскалации. Если ничего не выбрано, эскалации подлежат все привилегированные действия.",
"followupReminders": "Напоминания",
"followupInterval": "Интервал напоминаний (минуты)",
"followupIntervalHint": "Сколько ждать перед отправкой каждого напоминания пользователю.",
"followupMaxReminders": "Макс. напоминаний",
"followupMaxRemindersHint": "Максимальное число напоминаний на задачу. 0 = без ограничений (напоминать, пока пользователь не ответит).",
"workspace": "Рабочее пространство",
"workspaceScope": "Область рабочего пространства",
"workspaceScopeHint": "Управляйте тем, как организованы файлы рабочего пространства команды.",
"workspaceScopeIsolated": "Изолированная",
"workspaceScopeIsolatedDesc": "У каждого разговора своя папка рабочего пространства. Файлы из одного чата не видны в другом.",
"workspaceScopeShared": "Общая",
"workspaceScopeSharedDesc": "Все разговоры используют одну папку рабочего пространства. Файлы, созданные в любом чате, видны всем.",
"teamVersion": "Версия команды",
"versionBasic": "Базовая",
"versionAdvanced": "Расширенная",
"versionBasicDesc": "Управление задачами и общее рабочее пространство.",
"versionAdvancedDesc": "Все возможности V1 плюс блокировка выполнения, напоминания, рабочий процесс проверки, отслеживание прогресса, комментарии, журнал аудита и автовосстановление.",
"whatsNew": "В чём отличие?",
"versionModal": {
"title": "Возможности Super Team",
"feature": "Возможность",
"taskManagement": "Управление задачами",
"taskManagementDesc": "Создание, назначение, завершение, отмена задач",
"sharedWorkspace": "Общее рабочее пространство",
"sharedWorkspaceDesc": "Файлы, версии, командная работа",
"executionLocking": "Блокировка выполнения",
"executionLockingDesc": "Предотвращает конфликты задач с автовосстановлением",
"followupReminders": "Напоминания",
"followupRemindersDesc": "Автоматически напоминать в ожидании ответа пользователя",
"reviewWorkflow": "Рабочий процесс проверки",
"reviewWorkflowDesc": "Отправлять на проверку человеком перед завершением",
"progressTracking": "Отслеживание прогресса",
"progressTrackingDesc": "Обновления процентов и шагов в реальном времени",
"commentsAudit": "Комментарии и аудит",
"commentsAuditDesc": "Комментарии к задачам и полная история событий",
"autoRecovery": "Автовосстановление",
"autoRecoveryDesc": "Зависшие задачи автоматически сбрасываются по тайм-ауту",
"escalationPolicy": "Эскалация блокировок",
"escalationPolicyDesc": "Участники могут сообщать о блокировках — задача автоматически завершается сбоем, и руководитель уведомляется для повтора",
"comingSoon": "Скоро",
"downgradeNote": "Понижение версии безопасно — данные V2 сохраняются, но скрываются.",
"betaNote": "Некоторые возможности сейчас в бета-версии.",
"gotIt": "Понятно"
}
},
"create": {
"title": "Создать команду",
"name": "Имя *",
"namePlaceholder": "напр. Research Team",
"nameHint": "Строчные буквы, цифры, дефисы",
"description": "Описание",
"descriptionPlaceholder": "Необязательное описание команды...",
"leadAgent": "Ведущий агент *",
"selectLeadAgent": "Выберите ведущего агента...",
"loadingAgents": "Загрузка агентов...",
"noActiveAgents": "Активные агенты не найдены. Сначала создайте агентов.",
"members": "Участники",
"membersTooltip": "В качестве участников команды можно добавлять только предопределённых агентов. Открытые агенты работают в контексте отдельного пользователя и не имеют общего контекста, необходимого для командной работы.",
"needMembers": "Выберите хотя бы 1 участника для команды",
"searchMembers": "Найдите и добавьте участников...",
"displayName": "Отображаемое имя",
"displayNamePlaceholder": "Support Team",
"cancel": "Отмена",
"create": "Создать",
"creating": "Создание..."
},
"rename": {
"nameAria": "Переименовать команду",
"descAria": "Редактировать описание команды",
"descPlaceholder": "Описание команды",
"addDescription": "+ Добавить описание",
"emptyError": "Имя команды обязательно",
"staleError": "Команда была изменена в другом месте — ваше изменение отменено"
},
"toast": {
"created": "Команда создана",
"deleted": "Команда удалена",
"updated": "Команда обновлена",
"memberAdded": "Участник добавлен",
"memberRemoved": "Участник удалён",
"failedCreate": "Не удалось создать команду",
"failedDelete": "Не удалось удалить команду",
"failedUpdate": "Не удалось обновить команду",
"failedAddMember": "Не удалось добавить участника",
"failedRemoveMember": "Не удалось удалить участника",
"taskCreated": "Задача создана",
"taskDeleted": "Задача удалена",
"taskAssigned": "Задача назначена",
"taskApproved": "Задача одобрена",
"taskRejected": "Задача отклонена",
"tasksBulkDeleted": "Задачи удалены",
"failedCreateTask": "Не удалось создать задачу",
"failedDeleteTask": "Не удалось удалить задачу",
"failedAssignTask": "Не удалось назначить задачу",
"failedApproveTask": "Не удалось одобрить задачу",
"failedRejectTask": "Не удалось отклонить задачу",
"failedBulkDeleteTasks": "Не удалось удалить задачи",
"workspaceFileDeleted": "Файл удалён",
"failedDeleteWorkspaceFile": "Не удалось удалить файл"
},
"board": {
"kanban": "Доска",
"list": "Список",
"groupBy": "Группировать по",
"groupByStatus": "Статус",
"groupByOwner": "Владелец",
"groupByType": "Тип",
"running": "Выполняется",
"locked": "Агент выполняется",
"emptyColumn": "Нет задач",
"unassigned": "Не назначено",
"createViaChat": "Пообщайтесь с агентом команды, чтобы создать задачи"
},
"sidebar": {
"members": "Участники",
"workspace": "Рабочее пространство",
"delegations": "Делегирования",
"settings": "Настройки",
"addMember": "Добавить участника"
},
"tabs": {
"teams": "Команды агентов",
"board": "Доска",
"links": "Связи агентов",
"settings": "Настройки"
},
"links": {
"title": "Связи агентов",
"empty": "Связи агентов не настроены.",
"create": "Создать связь",
"editLink": "Редактировать связь",
"save": "Сохранить",
"source": "Исходный агент",
"target": "Целевой агент",
"selectAgent": "Выберите агента...",
"direction": "Направление",
"outbound": "Исходящее",
"inbound": "Входящее",
"bidirectional": "Двунаправленное",
"description": "Описание",
"descriptionPlaceholder": "Необязательное описание...",
"maxConcurrent": "Макс. одновременных",
"status": "Статус",
"active": "Активна",
"disabled": "Отключена",
"deleteTitle": "Удалить связь",
"confirmDelete": "Удалить эту связь агентов? Это действие нельзя отменить.",
"deleted": "Связь удалена",
"deleteFailed": "Не удалось удалить связь",
"created": "Связь создана",
"createFailed": "Не удалось создать связь",
"updated": "Связь обновлена",
"updateFailed": "Не удалось обновить связь",
"sameAgentError": "Исходный и целевой агенты должны различаться."
}
}
+33
View File
@@ -0,0 +1,33 @@
{
"title": "Арендаторы",
"description": "Управление арендаторами и доступом пользователей",
"createTenant": "Создать арендатора",
"name": "Имя",
"slug": "Слаг",
"status": "Статус",
"users": "Пользователи",
"role": "Роль",
"addUser": "Добавить пользователя",
"removeUser": "Удалить пользователя",
"userId": "ID пользователя",
"active": "Активен",
"suspended": "Приостановлен",
"archived": "Архивирован",
"allTenants": "Все арендаторы",
"currentTenant": "Текущий арендатор",
"noTenants": "Арендаторы не найдены",
"confirmRemoveUser": "Удалить этого пользователя из арендатора?",
"slugHelp": "URL-безопасный идентификатор (только строчные буквы и дефисы)",
"detail": "Сведения об арендаторе",
"back": "Назад к арендаторам",
"userManagement": "Управление пользователями",
"addUserTitle": "Добавить пользователя в арендатора",
"selectRole": "Выберите роль",
"roleOwner": "Владелец",
"roleAdmin": "Администратор",
"roleOperator": "Оператор",
"roleMember": "Участник",
"roleViewer": "Наблюдатель",
"noUsers": "В этом арендаторе нет пользователей",
"created": "Создан"
}
+286
View File
@@ -0,0 +1,286 @@
{
"custom": {
"title": "Пользовательские инструменты",
"description": "Управление пользовательскими инструментами на основе shell для агентов",
"createTool": "Создать инструмент",
"searchPlaceholder": "Поиск инструментов...",
"emptyTitle": "Нет пользовательских инструментов",
"emptyDescription": "Создайте свой первый пользовательский инструмент, чтобы начать.",
"noMatchTitle": "Инструменты не найдены",
"noMatchDescription": "Попробуйте другой поисковый запрос.",
"noDescription": "Нет описания",
"columns": {
"name": "Имя",
"description": "Описание",
"scope": "Область",
"enabled": "Включено",
"timeout": "Тайм-аут",
"actions": "Действия"
},
"scope": {
"agent": "Агент",
"global": "Глобальный"
},
"delete": {
"title": "Удалить пользовательский инструмент",
"description": "Вы уверены, что хотите удалить «{{name}}»? Это действие нельзя отменить.",
"confirmLabel": "Удалить"
},
"form": {
"createTitle": "Создать пользовательский инструмент",
"editTitle": "Редактировать инструмент",
"name": "Имя *",
"namePlaceholder": "my-tool",
"nameHint": "Только строчные буквы, цифры и дефисы",
"description": "Описание",
"descriptionPlaceholder": "Что делает этот инструмент...",
"command": "Команда *",
"commandHint": "Shell-шаблон. Используйте {{.key}} для подстановки параметров.",
"parameters": "Параметры (JSON Schema)",
"workingDir": "Рабочий каталог",
"workingDirPlaceholder": "/path/to/dir",
"timeout": "Тайм-аут (секунды)",
"agentId": "ID агента (необязательно)",
"agentIdPlaceholder": "Оставьте пустым для глобальной области",
"enabled": "Включено",
"cancel": "Отмена",
"create": "Создать",
"update": "Обновить",
"saving": "Сохранение...",
"errors": {
"nameRequired": "Имя и команда обязательны",
"nameSlug": "Имя должно быть корректным слагом (только строчные буквы, цифры, дефисы)",
"invalidJson": "Параметры должны быть корректным JSON"
}
},
"toast": {
"created": "Инструмент создан",
"createdDesc": "{{name}} добавлен",
"updated": "Инструмент обновлён",
"deleted": "Инструмент удалён",
"failedCreate": "Не удалось создать инструмент",
"failedUpdate": "Не удалось обновить инструмент",
"failedDelete": "Не удалось удалить инструмент"
}
},
"builtin": {
"title": "Встроенные инструменты",
"description": "Управление системными встроенными инструментами. Включайте/отключайте или настраивайте параметры глобально.",
"searchPlaceholder": "Поиск инструментов...",
"emptyTitle": "Нет встроенных инструментов",
"emptyDescription": "Встроенные инструменты ещё не были инициализированы.",
"noMatchTitle": "Инструменты не найдены",
"noMatchDescription": "Попробуйте другой поисковый запрос.",
"toolCount": "{{count}} инструмент",
"toolCountPlural": "{{count}} инструментов",
"categoryCount": "{{count}} категорий",
"requires": "треб.",
"requiresTooltip": "Требуется: {{list}}",
"deprecated": "Устарел",
"deprecatedTooltip": "Этот инструмент устарел и больше недоступен",
"settings": "Настройки",
"configuredVia": "Настраивается на странице конфигурации",
"tenantOverride": "Переопределение арендатора",
"tenantEnabled": "Включено для этого арендатора",
"tenantDisabled": "Отключено для этого арендатора",
"tenantDefault": "Используется значение по умолчанию",
"resetToDefault": "Сбросить к значению по умолчанию",
"tenantOverrideBadge": "Переопределение арендатора",
"tenantOverrideHint": "Редактирование переопределения этого арендатора. Изменения применяются только к данному арендатору.",
"tenantOverrideNewHint": "Создание нового переопределения для этого арендатора. Предзаполнено глобальными значениями по умолчанию.",
"resetToGlobalDefault": "Сбросить к глобальному значению по умолчанию",
"unconfiguredWarning": "{{count}} инструментов требуют настройки провайдера, чтобы агенты могли использовать их в полную силу.",
"unconfiguredAction": "Настроить",
"categories": {
"filesystem": "Файловая система",
"runtime": "Среда выполнения",
"web": "Веб",
"memory": "Память",
"media": "Медиа",
"browser": "Браузер",
"sessions": "Сессии",
"messaging": "Сообщения",
"scheduling": "Планирование",
"subagents": "Агенты",
"skills": "Навыки",
"delegation": "Делегирование",
"teams": "Команды"
},
"settingsDialog": {
"title": "Настройки — {{name}}",
"cancel": "Отмена",
"save": "Сохранить",
"saving": "Сохранение...",
"noFields": "Для этого инструмента нет настраиваемых параметров.",
"toast": {
"saved": "Настройки сохранены",
"failed": "Не удалось сохранить настройки"
}
},
"jsonDialog": {
"title": "Настройки: {{name}}",
"description": "Редактируйте специфичные для инструмента настройки в формате JSON. Изменения вступают в силу сразу после сохранения.",
"formatJson": "Форматировать JSON",
"invalidJsonSyntax": "Некорректный синтаксис JSON",
"invalidJson": "Некорректный JSON",
"cannotFormat": "Не удаётся отформатировать: некорректный JSON",
"cancel": "Отмена",
"save": "Сохранить",
"saving": "Сохранение..."
},
"kgSettings": {
"title": "Настройки графа знаний",
"description": "Настройте извлечение сущностей из записей в память. Требуется провайдер/модель с поддержкой структурированного вывода JSON.",
"extractionProvider": "Провайдер извлечения",
"extractionModel": "Модель извлечения",
"providerTip": "Провайдер LLM, используемый для извлечения сущностей и связей из текста.",
"modelTip": "ID модели для извлечения. Должна поддерживать структурированный вывод JSON.",
"minConfidence": "Мин. уверенность",
"minConfidenceHint": "Сущности с оценкой уверенности ниже этого значения отбрасываются (0.0–1.0).",
"autoExtract": "Автоизвлечение при записи в память",
"autoExtractHint": "Автоматически извлекать сущности, когда агенты записывают в файлы памяти.",
"cancel": "Отмена",
"save": "Сохранить",
"saving": "Сохранение..."
},
"execSettings": {
"title": "Настройки выполнения",
"description": "Настройте тайм-аут команды на хосте для встроенного инструмента выполнения.",
"timeoutSeconds": "Тайм-аут (секунды)",
"timeoutHint": "Допустимый диапазон: {{min}}-{{max}} секунд.",
"sandboxHint": "Запуски в песочнице Docker используют настройку тайм-аута песочницы агента.",
"cancel": "Отмена",
"save": "Сохранить",
"saving": "Сохранение..."
},
"searchChain": {
"title": "Цепочка провайдеров веб-поиска",
"description": "Перетащите, чтобы изменить порядок провайдеров поиска. Первым пробуется первый включённый провайдер с корректным ключом API.",
"maxResults": "Макс. результатов",
"locked": "Постоянный резервный вариант",
"cancel": "Отмена",
"save": "Сохранить",
"saving": "Сохранение...",
"providers": {
"exa": "Exa",
"tavily": "Tavily",
"brave": "Brave Search",
"duckduckgo": "DuckDuckGo"
},
"apiKey": "Ключ API",
"apiKeySet": "✓ Ключ задан",
"apiKeyChange": "Изменить",
"apiKeyPlaceholder": "Введите ключ API",
"apiKeyReplacePlaceholder": "Введите новый ключ для замены"
},
"ttsForm": {
"title": "Настройки TTS",
"description": "Настройте провайдера синтеза речи и режим автоприменения.",
"primary": "Основной провайдер",
"auto": "Автоматический режим",
"autoOff": "Выкл.",
"autoInbound": "Входящие голосовые",
"autoTagged": "С тегом",
"autoAlways": "Всегда",
"autoOffDesc": "Только когда агент явно использует инструмент tts",
"autoInboundDesc": "Автоприменение, когда пользователь отправляет голос/аудио",
"autoTaggedDesc": "Применять, когда текст содержит директиву [[tts]]",
"autoAlwaysDesc": "Всегда преобразовывать финальный ответ в речь",
"cancel": "Отмена",
"save": "Сохранить",
"saving": "Сохранение..."
},
"sttForm": {
"title": "Настройки STT",
"description": "Настройте провайдеров распознавания речи для транскрибации голосовых сообщений.",
"providersLabel": "Провайдеры",
"providersPlaceholder": "Выберите провайдеров",
"elevenlabsSectionTitle": "ElevenLabs",
"elevenlabsApiKeyLabel": "Ключ API",
"elevenlabsDefaultLanguageLabel": "Язык по умолчанию",
"proxySectionTitle": "Прокси",
"proxyUrlLabel": "URL прокси",
"proxyApiKeyLabel": "Ключ API прокси",
"proxyTenantIdLabel": "ID арендатора прокси",
"whatsappEnabledLabel": "Включить STT для WhatsApp",
"whatsappPrivacyWarning": "Включение STT для WhatsApp нарушает сквозное шифрование голосовых сообщений, отправляемых этому агенту.",
"providersRequiredError": "Должен быть выбран хотя бы один провайдер.",
"cancel": "Отмена",
"save": "Сохранить",
"saving": "Сохранение...",
"saveSuccess": "Настройки STT сохранены",
"saveFailed": "Не удалось сохранить настройки STT"
},
"extractorChain": {
"title": "Веб-загрузка — цепочка извлечения",
"description": "Упорядоченный список экстракторов контента. Каждый URL обрабатывается сверху вниз, пока один из них не вернёт качественный контент.",
"timeout": "Тайм-аут",
"baseUrl": "Базовый URL",
"save": "Сохранить",
"saving": "Сохранение…",
"cancel": "Отмена",
"extractors": {
"defuddle": "Defuddle (Cloudflare Worker)",
"defuddleDesc": "Извлекает чистый markdown через fetch.goclaw.sh с помощью библиотеки Defuddle.",
"html-to-markdown": "Встроенный HTML→Markdown",
"html-to-markdownDesc": "Внутрипроцессный конвертер на основе DOM с обнаружением скрытых элементов."
}
},
"mediaChain": {
"providerChainSuffix": "— цепочка провайдеров",
"description": "Настройте и упорядочьте резервных провайдеров. Перетащите для изменения порядка — первым пробуется первый включённый провайдер.",
"newProvider": "Новый провайдер",
"provider": "Провайдер",
"model": "Модель",
"selectProvider": "Выберите провайдера",
"loadingModels": "Загрузка...",
"selectModel": "Выберите модель",
"timeout": "Тайм-аут",
"retries": "Повторы",
"settings": "Настройки",
"noProviders": "Провайдеры не настроены. Добавьте одного ниже.",
"addProvider": "Добавить провайдера",
"cancel": "Отмена",
"save": "Сохранить",
"saving": "Сохранение...",
"imageModelLabel": "Модель изображений",
"imageModelDefaultOption": "По умолчанию · gpt-image-2 (рекомендуется)",
"imageModelLegacyOption": "Устаревшая · gpt-image-1.5"
},
"toast": {
"toggled": "Инструмент обновлён",
"failedToggle": "Не удалось обновить инструмент"
},
"descriptions": {
"read_file": "Прочитать содержимое файла из рабочего пространства агента по пути",
"write_file": "Записать содержимое в файл в рабочем пространстве, создавая каталоги по мере необходимости",
"list_files": "Вывести список файлов и каталогов по заданному пути в рабочем пространстве",
"edit": "Применить точечные правки поиска и замены к существующим файлам без переписывания всего файла",
"exec": "Выполнить команду shell в рабочем пространстве и вернуть stdout/stderr",
"web_search": "Искать информацию в вебе с помощью поисковой системы (Brave или DuckDuckGo)",
"web_fetch": "Загрузить веб-страницу или эндпоинт API и извлечь её текстовое содержимое",
"memory_search": "Искать в долговременной памяти агента с помощью семантического сходства",
"memory_get": "Получить конкретный документ памяти по пути к файлу",
"knowledge_graph_search": "Искать сущности, связи и наблюдения в графе знаний агента",
"read_image": "Анализировать изображения с помощью провайдера LLM с поддержкой зрения",
"read_document": "Анализировать документы (PDF, Word, Excel, PowerPoint, CSV и др.) с помощью провайдера LLM с поддержкой документов",
"create_image": "Генерировать изображения по текстовым запросам с помощью провайдера генерации изображений",
"read_audio": "Анализировать аудиофайлы (речь, музыка, звуки) с помощью провайдера LLM с поддержкой аудио",
"read_video": "Анализировать видеофайлы с помощью провайдера LLM с поддержкой видео",
"create_video": "Генерировать видео по текстовым описаниям с помощью ИИ",
"create_audio": "Генерировать музыку или звуковые эффекты по текстовым описаниям с помощью ИИ",
"tts": "Преобразовать текст в естественно звучащую речь",
"browser": "Автоматизировать взаимодействие с браузером: навигация по страницам, клики по элементам, заполнение форм, скриншоты",
"sessions_list": "Вывести список активных сессий чата по всем каналам",
"session_status": "Получить текущий статус и метаданные конкретной сессии чата",
"sessions_history": "Получить историю сообщений конкретной сессии чата",
"sessions_send": "Отправить сообщение в активную сессию чата от имени агента",
"message": "Отправить проактивное сообщение пользователю в подключённом канале (Telegram, Discord и др.)",
"cron": "Планировать периодические задачи или управлять ими с помощью выражений cron, времени или интервалов",
"spawn": "Запустить субагента для выполнения задачи в фоновом режиме",
"skill_search": "Искать доступные навыки по ключевому слову или описанию, чтобы найти подходящие возможности",
"use_skill": "Активировать навык для использования его специализированных возможностей (маркер трассировки)",
"team_tasks": "Просматривать, создавать, обновлять и завершать задачи на доске задач команды"
}
}
}
+35
View File
@@ -0,0 +1,35 @@
{
"expandSidebar": "Развернуть боковую панель",
"collapseSidebar": "Свернуть боковую панель",
"openMenu": "Открыть меню",
"systemSettings": "Системные настройки",
"toggleTheme": "Переключить тему",
"logout": "Выйти",
"logoutConfirm": "Вы уверены, что хотите выйти?",
"language": "Язык",
"timezone": "Часовой пояс",
"pairingRequests": "Запросы на привязку",
"pendingPairingRequest": "{{count}} ожидающий запрос на привязку",
"pendingPairingRequests": "{{count}} ожидающих запросов на привязку",
"apiKeys": "Ключи API",
"documents": "Документы",
"about": {
"menuItem": "О программе",
"title": "О GoClaw",
"version": "Версия",
"sourceCode": "Исходный код",
"license": "Лицензия",
"documentation": "Документация",
"reportBug": "Сообщить об ошибке",
"upToDate": "Актуальная версия",
"updateAvailable": "Доступно обновление: {{version}}",
"viewRelease": "Смотреть заметки о выпуске →",
"releaseNotes": "Заметки о выпуске"
},
"languages": {
"en": "English",
"vi": "Tiếng Việt",
"zh": "中文",
"ko": "한국어"
}
}
+130
View File
@@ -0,0 +1,130 @@
{
"title": "Трассировки",
"description": "Трассировки вызовов LLM и данные о производительности",
"filterPlaceholder": "Фильтр по ID агента...",
"filter": "Фильтр",
"allAgents": "Все агенты",
"allChannels": "Все каналы",
"status": {
"running": "Выполняется",
"completed": "Завершено",
"error": "Ошибка",
"cancelled": "Отменено"
},
"filters": {
"search": "Поиск трассировок или ID трассировки...",
"status": "Статус",
"allStatuses": "Все статусы",
"advanced": "Расширенные",
"from": "С",
"to": "По",
"minInputTokens": "Мин. входных токенов",
"maxInputTokens": "Макс. входных токенов",
"minOutputTokens": "Мин. выходных токенов",
"maxOutputTokens": "Макс. выходных токенов",
"minToolCalls": "Мин. вызовов инструментов",
"maxToolCalls": "Макс. вызовов инструментов",
"toolName": "Имя инструмента",
"hasToolCalls": "Вызовы инструментов",
"anyToolCalls": "Любые вызовы инструментов",
"withToolCalls": "С вызовами инструментов",
"withoutToolCalls": "Без вызовов инструментов",
"clearFilter": "Сбросить фильтр",
"clearAll": "Сбросить всё",
"chips": {
"query": "Поиск",
"agentId": "Агент",
"status": "Статус",
"channel": "Канал",
"from": "С",
"to": "По",
"minInputTokens": "Мин. вход",
"maxInputTokens": "Макс. вход",
"minOutputTokens": "Мин. выход",
"maxOutputTokens": "Макс. выход",
"minToolCalls": "Мин. инструментов",
"maxToolCalls": "Макс. инструментов",
"toolName": "Инструмент",
"hasToolCalls": "Вызовы инструментов"
}
},
"emptyTitle": "Нет трассировок",
"emptyDescription": "Трассировки не найдены. Трассировки записываются, когда агенты обрабатывают запросы.",
"columns": {
"name": "Имя",
"status": "Статус",
"duration": "Длительность",
"tokens": "Токены",
"spans": "Спаны",
"time": "Время"
},
"source": {
"direct": "Напрямую",
"group": "Группа",
"cron": "Cron",
"team": "Команда",
"ws": "Веб",
"unknown": "Другое"
},
"unnamed": "Без имени",
"stopRun": "Остановить запуск",
"cached": "из кеша",
"detail": {
"title": "Сведения о трассировке",
"copyTraceId": "Копировать ID трассировки",
"notFound": "Трассировка не найдена.",
"name": "Имя:",
"status": "Статус:",
"duration": "Длительность:",
"channel": "Канал:",
"tokens": "Токены:",
"spans": "Спаны:",
"started": "Начато:",
"delegatedFrom": "Делегировано от:",
"createdAt": "Создано:",
"input": "Ввод",
"output": "Вывод",
"copy": "Копировать",
"spansCount": "Спаны ({{count}})",
"llmCalls": "LLM",
"toolCalls": "инструмент",
"export": "Экспортировать трассировку",
"stopRun": "Остановить запуск"
},
"span": {
"model": "Модель:",
"tokens": "Токены:",
"reasoning": "Рассуждение:",
"source": "источник",
"requested": "запрошено",
"effective": "фактически",
"fallback": "резервное",
"modelDefault": "по умолчанию для модели",
"supportedLevels": "поддерживается:",
"sourceValue": {
"provider_default": "по умолчанию у провайдера",
"reasoning": "расширенные настройки агента",
"thinking_level": "устаревший уровень мышления",
"unset": "не задано"
},
"createdAt": "Создано:",
"input": "Ввод:",
"output": "Вывод:",
"copy": "Копировать",
"startTime": "Начало:",
"endTime": "Конец:",
"cacheRead": "чтение",
"cacheWrite": "запись",
"thinking": "мышление",
"cached": "из кеша"
},
"toast": {
"failedLoad": "Не удалось загрузить трассировки",
"abortStopped": "Запуск остановлен",
"abortForced": "Запуск принудительно остановлен (очистка ещё выполняется в фоне)",
"abortAlreadyAborting": "Остановка уже выполняется",
"abortNotFound": "Запуск уже завершён",
"abortUnauthorized": "Нет прав на остановку этого запуска",
"abortFailed": "Не удалось остановить запуск"
}
}
+265
View File
@@ -0,0 +1,265 @@
{
"title": "Синтез речи (TTS)",
"description": "Настройка провайдеров TTS и параметров автоприменения",
"save": "Сохранить",
"saving": "Сохранение...",
"saveChanges": "Сохранить изменения",
"status": {
"title": "Статус",
"configured": "Настроено",
"disabled": "Отключено",
"noProvider": "Провайдер TTS не настроен",
"activeProvider": "Основной провайдер: {{provider}}, Авто: {{auto}}"
},
"general": {
"title": "Общие настройки",
"primaryProvider": "Основной провайдер",
"autoApplyMode": "Режим автоприменения",
"replyMode": "Режим ответов",
"maxTextLength": "Максимальная длина текста",
"timeout": "Тайм-аут (мс)"
},
"providers": {
"none": "Нет (отключено)",
"openai": "OpenAI",
"elevenlabs": "ElevenLabs",
"edge": "Edge (бесплатно)",
"minimax": "MiniMax",
"gemini": "Google Gemini"
},
"autoModes": {
"off": "Выкл.",
"offDesc": "Агент может использовать инструмент TTS вручную",
"always": "Всегда",
"alwaysDesc": "Все ответы озвучиваются",
"inbound": "Входящие",
"inboundDesc": "Только когда пользователь отправляет голос/аудио",
"tagged": "По тегу",
"taggedDesc": "Только когда ответ содержит тег [[tts]]"
},
"replyModes": {
"final": "Только финальные",
"finalDesc": "Только финальные ответы",
"all": "Все",
"allDesc": "Все ответы, включая инструменты/блоки"
},
"providerSettings": "Настройки {{provider}}",
"openai": {
"apiKey": "API-ключ",
"apiBase": "Базовый URL API",
"model": "Модель",
"voice": "Голос",
"speed": {
"label": "Скорость",
"help": "Множитель скорости речи — 0.25 = самая медленная, 4.0 = самая быстрая."
},
"responseFormat": {
"label": "Формат вывода",
"help": "Кодировка аудио, возвращаемая API (mp3, opus, aac, flac, wav, pcm)."
},
"instructions": {
"label": "Инструкции",
"help": "Системный стилевой промпт — поддерживается только моделью gpt-4o-mini-tts."
}
},
"elevenlabs": {
"apiKey": "API-ключ",
"baseUrl": "Базовый URL",
"voiceId": "ID голоса",
"modelId": "ID модели",
"voiceSettings": {
"stability": {
"label": "Стабильность",
"help": "0 = больше выразительных вариаций, 1 = более согласованно и стабильно."
},
"similarityBoost": {
"label": "Усиление сходства",
"help": "Насколько точно вывод соответствует оригинальному клону голоса (0 = креативно, 1 = похоже)."
},
"style": {
"label": "Усиление стиля",
"help": "Усиливает стиль голоса. 0 = нет; более высокие значения добавляют выразительности."
},
"useSpeakerBoost": {
"label": "Усиление диктора",
"help": "Повышает чёткость голоса и сходство с целевым диктором."
},
"speed": {
"label": "Скорость",
"help": "Скорость речи — диапазон от 0.7 (медленно) до 1.2 (быстро)."
}
},
"applyTextNormalization": {
"label": "Нормализация текста",
"help": "Как раскрываются числа и сокращения (авто, вкл. или выкл.)."
},
"seed": {
"label": "Seed (расширенное)",
"help": "Задайте фиксированный seed для воспроизводимого результата. 0 = случайно."
},
"optimizeStreamingLatency": {
"label": "Задержка потока (расширенное)",
"help": "Уровень оптимизации задержки: 0 = нет, 4 = максимум."
},
"languageCode": {
"label": "Код языка",
"help": "Подсказка языка ISO 639-1, напр. 'en' или 'vi'. Расширенное."
}
},
"edge": {
"voice": "Голос",
"speechRate": "Темп речи",
"hint": "Edge TTS бесплатен и не требует API-ключа. Установите командой: pip install edge-tts",
"rate": {
"label": "Темп речи",
"help": "Регулировка темпа в процентах. -50% = намного медленнее, +100% = намного быстрее."
},
"pitch": {
"label": "Высота тона",
"help": "Сдвиг высоты тона в Гц относительно нейтральной. Диапазон: от -50 Гц до +50 Гц."
},
"volume": {
"label": "Громкость",
"help": "Регулировка громкости в процентах. -50% = тише, +100% = громче."
}
},
"minimax": {
"apiKey": "API-ключ",
"groupId": "ID группы *",
"groupIdPlaceholder": "Обязательно для MiniMax",
"apiBase": "Базовый URL API",
"model": "Модель",
"voiceId": "ID голоса",
"speed": {
"label": "Скорость",
"help": "Множитель скорости речи — 0.5 = самая медленная, 2.0 = самая быстрая."
},
"vol": {
"label": "Громкость",
"help": "Множитель громкости — 0.01 = почти беззвучно, 10.0 = самая громкая."
},
"pitch": {
"label": "Высота тона",
"help": "Сдвиг высоты тона в полутонах. -12 = на октаву ниже, +12 = на октаву выше."
},
"emotion": {
"label": "Эмоция",
"help": "Эмоциональный тон, применяемый к синтезированному голосу."
},
"textNormalization": {
"label": "Нормализация текста",
"help": "Раскрываются ли числа и символы перед синтезом."
},
"audio": {
"format": {
"label": "Формат аудио",
"help": "Кодировка вывода: mp3, pcm, flac или wav."
},
"sampleRate": {
"label": "Частота дискретизации",
"help": "Частота дискретизации аудио в Гц. Для большинства случаев оставьте значение по умолчанию."
},
"bitrate": {
"label": "Битрейт (только MP3)",
"help": "Битрейт MP3 в бит/с. Применяется только при формате mp3."
},
"channel": {
"label": "Каналы",
"help": "1 = моно (меньший файл), 2 = стерео."
}
}
},
"gemini": {
"apiKey": "API-ключ",
"apiBase": "Базовый URL API",
"voice": "Голос",
"model": "Модель",
"multiSpeaker": "Несколько дикторов",
"multiSpeakerHint": "Поддерживается до 2 дикторов",
"audioTags": "Аудиотеги",
"audioTagsHint": "Вставляйте выразительные теги, например [laughs], прямо в текст",
"speakerName": "Имя диктора",
"speakerVoice": "Голос диктора",
"addSpeaker": "Добавить диктора",
"removeSpeaker": "Удалить",
"maxSpeakersReached": "Достигнут максимум в 2 диктора",
"filterAll": "Все",
"filterEmotion": "Эмоция",
"filterPacing": "Темп",
"filterEffect": "Эффект",
"filterVoiceQuality": "Качество голоса",
"searchPlaceholder": "Поиск тегов…",
"insertTag": "Вставить",
"multiSpeakerMode": {
"title": "Режим нескольких дикторов",
"addSpeaker": "Добавить диктора",
"speakerName": "Имя диктора",
"speakerVoice": "Голос",
"removeSpeaker": "Удалить",
"limitReached": "Максимум 2 диктора"
},
"audioTagsPanel": {
"title": "Аудиотеги",
"search": "Поиск тегов",
"categoryEmotion": "Эмоция",
"categoryPacing": "Темп",
"categoryEffect": "Эффект",
"categoryVoiceQuality": "Качество голоса",
"insertHint": "Нажмите на тег, чтобы вставить в позицию курсора"
},
"previewBadge": "Предпросмотр"
},
"voice_label": "Голос",
"voice_placeholder": "Выберите голос…",
"voice_picker": {
"requires_provider": "Сначала настройте провайдер TTS",
"enter_voice_id": "Введите voice_id вручную"
},
"voice_refresh": "Обновить",
"voice_preview": "Предпросмотр",
"voice_stop_preview": "Стоп",
"voice_no_voices": "Нет доступных голосов",
"voice_save_config_first": "Сначала сохраните API-ключ, чтобы загрузить голоса",
"voice_loading": "Загрузка голосов…",
"voice_preview_error": "Предпросмотр не удался — обновление списка",
"model_label": "Модель",
"model_placeholder": "По умолчанию (арендатор/система)",
"empty_state": {
"title": "TTS не настроен",
"description": "Настройте провайдер TTS, чтобы включить голос для агентов.",
"cta": "Настроить TTS",
"non_owner_hint": "Обратитесь к владельцу рабочего пространства для настройки TTS."
},
"override": {
"label": "Переопределить голос для этого агента",
"inherits": "Наследует: {{provider}} · {{voice}} · {{model}}",
"params": {
"title": "Тонкая настройка"
}
},
"test": {
"button": "Проверить этот голос",
"sample_text": "Здравствуйте, это проверка голоса."
},
"testConnection": {
"label": "Проверить подключение",
"testing": "Проверка…",
"success": "Подключение успешно",
"failed": "Подключение не удалось"
},
"playground": {
"title": "Тестовая площадка",
"inputLabel": "Текст для синтеза",
"placeholder": "Введите текст, чтобы прослушать…",
"play": "Воспроизвести",
"stop": "Стоп",
"synthesizing": "Синтез…",
"playbackFailed": "Воспроизведение не удалось",
"requiresProvider": "Выберите провайдер выше, чтобы включить тестовое воспроизведение."
},
"advanced": {
"title": "Расширенные настройки",
"count": "{{count}} расширенных настроек",
"count_one": "{{count}} расширенная настройка"
}
}
+172
View File
@@ -0,0 +1,172 @@
{
"title": "Использование",
"description": "Использование токенов и расходы по агентам",
"emptyTitle": "Нет данных об использовании",
"emptyDescription": "Данные об использовании появятся здесь после обработки запросов агентами.",
"summary": {
"sessions": "{{count}} сессий",
"inputTokens": "Входные токены",
"outputTokens": "Выходные токены",
"total": "Всего"
},
"recentRecords": "Недавние записи",
"columns": {
"agent": "Агент",
"model": "Модель",
"provider": "Провайдер",
"input": "Вход",
"output": "Выход",
"total": "Всего",
"channel": "Канал",
"cost": "Стоимость",
"status": "Статус",
"actions": "Действия"
},
"caps": {
"title": "Лимиты использования",
"description": "Ограничьте бюджет ИИ по токенам и стоимости в разрезе арендатора, агента, провайдера и модели.",
"window": "Окно",
"windows": {
"hour": "Почасовой",
"day": "Ежедневный",
"week": "Еженедельный",
"month": "Ежемесячный"
},
"agent": "Агент",
"provider": "Провайдер",
"model": "Модель",
"allAgents": "Все агенты",
"allProviders": "Все провайдеры",
"maxTokens": "Макс. токенов",
"maxCost": "Макс. стоимость USD",
"create": "Создать лимит",
"edit": "Изменить лимит",
"save": "Сохранить лимит",
"cancel": "Отменить изменение",
"scope": "Область",
"tokens": "Токены",
"cost": "Стоимость",
"empty": "Политик лимитов пока нет.",
"tenantScope": "Лимит арендатора",
"tenantScoped": "На уровне арендатора",
"agentScoped": "На уровне агента",
"agentBudgetSource": "Бюджет агента",
"agentBudgetManaged": "Очистите это в поле месячного бюджета агента.",
"enabled": "Включено",
"disabled": "Отключено",
"delete": "Удалить лимит",
"recentBlocks": "Недавние блокировки",
"blocked": "Заблокировано",
"toast": {
"created": "Лимит использования создан",
"updated": "Лимит использования обновлён",
"createFailed": "Не удалось создать лимит использования",
"updateFailed": "Не удалось обновить лимит использования",
"deleted": "Лимит использования удалён",
"deleteFailed": "Не удалось удалить лимит использования"
}
},
"analytics": {
"title": "Аналитика использования",
"period24h": "24 ч",
"period7d": "7 дней",
"period30d": "30 дней",
"periodCustom": "Произвольный",
"allAgents": "Все агенты",
"allProviders": "Все провайдеры",
"allChannels": "Все каналы",
"activeFilters": "Активные фильтры",
"clearAll": "Очистить всё",
"exportCsv": "Экспорт CSV",
"requests": "Запросы",
"tokens": "Токены",
"cost": "Стоимость",
"errors": "Ошибки",
"uniqueUsers": "Уникальные пользователи",
"llmCalls": "Вызовы LLM",
"toolCalls": "Вызовы инструментов",
"trendUp": "+{{value}}%",
"trendDown": "{{value}}%",
"vsPrevious": "по сравнению с предыдущим периодом",
"configurePricing": "Настройте цены моделей для учёта расходов",
"noData": "Нет данных за выбранный период",
"tokenChart": {
"title": "Использование токенов во времени",
"input": "Входные токены",
"output": "Выходные токены",
"cache": "Токены чтения кэша",
"thinking": "Токены рассуждений",
"total": "Всего"
},
"requestChart": {
"title": "Объём запросов и ошибки",
"requests": "Запросы",
"errors": "Ошибки",
"errorRate": "Доля ошибок"
},
"distribution": {
"provider": "Распределение по провайдерам",
"model": "Распределение по моделям",
"channel": "Распределение по каналам",
"other": "Другое",
"calls": "вызовов"
},
"durationChart": {
"title": "Длительность и производительность",
"avgDuration": "Средняя длительность",
"errorRate": "Доля ошибок %"
},
"knowledgeChart": {
"title": "Рост памяти и графа знаний",
"memoryDocs": "Документы памяти",
"memoryChunks": "Фрагменты памяти",
"kgEntities": "Сущности KG",
"kgRelations": "Связи KG"
},
"topModels": {
"title": "Топ моделей",
"model": "Модель",
"provider": "Провайдер",
"llmCalls": "Вызовы LLM",
"inputTokens": "Входные токены",
"outputTokens": "Выходные токены",
"avgDuration": "Средняя длительность",
"cost": "Стоимость"
},
"events": {
"title": "Аналитика событий ресурсов",
"description": "Подсчёт активности инструментов, навыков, MCP и среды выполнения по трассируемым выполнениям.",
"tabs": {
"tool": "Инструменты",
"skill": "Навыки",
"mcp_tool": "MCP",
"runtime_tool": "Среда выполнения"
},
"metrics": {
"calls": "Вызовы",
"errorRate": "Доля ошибок",
"tokens": "Токены",
"avgDuration": "Средняя длительность",
"cost": "Стоимость"
},
"activeBuckets": "{{count}} активных сегментов",
"unknownSource": "Неизвестно",
"empty": "Нет данных о событиях для этого выбора.",
"table": {
"resource": "Ресурс",
"source": "Источник",
"calls": "Вызовы",
"errors": "Ошибки",
"errorRate": "Доля ошибок",
"avgDuration": "Средняя длительность",
"tokens": "Токены",
"cost": "Стоимость"
}
},
"tooltip": {
"date": "Дата",
"total": "Всего",
"errorRate": "{{value}}% доля ошибок"
}
}
}
@@ -0,0 +1,56 @@
{
"title": "Возможности агента V3",
"subtitle": "Ключевые системы, обеспечивающие интеллект вашего агента",
"note": "Все возможности всегда включены для агентов v3.",
"tabs": {
"pipeline": "Конвейер",
"memory": "Память",
"knowledge": "Знания",
"orchestration": "Оркестрация"
},
"pipeline": {
"title": "8-этапный конвейер выполнения",
"description": "Каждое сообщение проходит через 8 структурированных этапов в 3 фазах.",
"setup": "Подготовка",
"setupDesc": "Обогащает контекст конфигурацией агента, метаданными рабочего пространства, историей пользователя и автоматически внедряемыми воспоминаниями из прошлых сессий.",
"iteration": "Цикл итераций",
"iterationDesc": "Повторяется до завершения задачи или достижения максимума итераций.",
"think": "Мышление",
"thinkDesc": "Рассуждение LLM с полным контекстом",
"prune": "Обрезка",
"pruneDesc": "Управление токенами и сжатие",
"tools": "Инструменты",
"toolsDesc": "Выполнение вызовов инструментов от LLM",
"observe": "Наблюдение",
"observeDesc": "Захват и проверка вывода",
"checkpoint": "Контрольная точка",
"checkpointDesc": "Сохранение промежуточного состояния",
"finalize": "Завершение",
"finalizeDesc": "Сохраняет метаданные, генерирует события для консолидации памяти и очищает выполнение."
},
"memory": {
"title": "3-уровневая система памяти",
"description": "Прогрессивная память от разговора до долговременных знаний.",
"l0Title": "L0 Рабочая память",
"l0Desc": "История сессии с автосжатием на основе токенов. Когда история превышает порог окна контекста, старые сообщения обобщаются через LLM и усекаются. Сброс памяти извлекает ключевые факты в постоянные файлы перед сжатием.",
"l1Title": "L1 Эпизодическая память",
"l1Desc": "Сводки сессий, создаваемые после каждого разговорного прохода. Каждая получает абстракт L0 (~50 токенов) для быстрого внедрения. Гибридный поиск FTS + вектор с TTL 90 дней. Релевантные абстракты автоматически внедряются в системный промпт каждый ход.",
"l2Title": "L2 Семантическая память",
"l2Desc": "Граф знаний с сущностями и связями, извлечёнными через LLM (порог уверенности 0.75). Автодедупликация объединяет похожие сущности. Сновидения консолидируют 5+ эпизодических записей в долговременные документы фактов, доступные для поиска через инструменты памяти.",
"eventFlow": "На основе событий: session.completed запускает создание L1, что запускает извлечение L2 и сновидения."
},
"knowledge": {
"kgTitle": "Граф знаний",
"kgDesc": "Сущности (люди, проекты, технологии) и их связи извлекаются из сводок сессий через LLM. Темпоральное версионирование отслеживает, когда факты были действительны. Поиск через инструмент knowledge_graph_search с многошаговым обходом до 5 уровней в глубину.",
"vaultTitle": "Хранилище знаний",
"vaultDesc": "Реестр документов с разрешением [[wikilink]]. Унифицированный поиск объединяет документы хранилища (40%), эпизодические воспоминания (30%) и сущности KG (30%) в единый ранжированный набор результатов. Хеширование SHA-256 обнаруживает изменения содержимого для инкрементного индексирования.",
"dreamingTitle": "Сновидения",
"dreamingDesc": "Когда накапливается 5+ сводок сессий, LLM синтезирует долговременные факты: предпочтения пользователя, архитектуру проекта, повторяющиеся паттерны и ключевые решения с обоснованием. Хранятся как документы памяти с возможностью поиска. С задержкой в 10-минутных интервалах на агента."
},
"orchestration": {
"delegateTitle": "Делегирование агентов",
"delegateDesc": "Агенты делегируют задачи связанным агентам через agent_links с проверкой разрешений. Синхронный режим блокируется до настраиваемого тайм-аута в ожидании результатов. Асинхронный режим срабатывает немедленно и объявляет результаты обратно через шину сообщений по завершении.",
"evolutionTitle": "Самоэволюция",
"evolutionDesc": "Отслеживает использование инструментов и метрики извлечения на еженедельном цикле. Обнаруживает три паттерна: низкое использование извлечения (< 20%), высокую частоту сбоев инструментов (< 10% успеха) и повторяющиеся паттерны инструментов (> 100 вызовов/неделю). Предлагает корректировки конфигурации с защищённым ограничителями автоприменением и откатом."
}
}
+117
View File
@@ -0,0 +1,117 @@
{
"title": "Хранилище знаний",
"description": "Реестр документов с вики-ссылками и семантическим поиском",
"search": "Поиск",
"searchPlaceholder": "Поиск документов...",
"filterAgent": "Агент",
"allAgents": "Все агенты",
"allTypes": "Все",
"noDocuments": "В хранилище нет документов",
"noResults": "Нет результатов поиска",
"searchFailed": "Поиск не удался",
"create": "Создать",
"createDoc": "Создать документ",
"edit": "Изменить",
"save": "Сохранить",
"saving": "Сохранение...",
"cancel": "Отмена",
"delete": "Удалить",
"confirmDelete": "Удалить этот документ?",
"yes": "Да",
"no": "Нет",
"createLink": "Добавить ссылку",
"addLink": "Добавить ссылку",
"deleteLink": "Удалить ссылку",
"columns": {
"title": "Заголовок",
"agent": "Агент",
"path": "Путь",
"type": "Тип",
"scope": "Область",
"updated": "Обновлено"
},
"detail": {
"metadata": "Метаданные",
"outlinks": "Исходящие ссылки",
"backlinks": "Обратные ссылки",
"noLinks": "Нет ссылок",
"contentPreview": "Предпросмотр содержимого",
"fileNotFound": "Файл не найден или недоступен",
"emptyContent": "Содержимое отсутствует",
"binaryFile": "Двоичный файл — предпросмотр недоступен"
},
"fields": {
"title": "Заголовок",
"titlePlaceholder": "Заголовок документа",
"path": "Путь",
"pathPlaceholder": "напр. notes/my-doc.md",
"docType": "Тип",
"scope": "Область",
"fromDoc": "Из",
"toDoc": "В документ",
"selectDoc": "Выберите документ...",
"linkType": "Тип ссылки",
"linkContext": "Контекст",
"linkContextPlaceholder": "Необязательный контекст для этой ссылки"
},
"scope": {
"personal": "Личное",
"team": "Команда",
"shared": "Общее"
},
"type": {
"context": "Контекст",
"memory": "Память",
"note": "Заметка",
"skill": "Навык",
"episodic": "Эпизодическое",
"media": "Медиа",
"document": "Документ"
},
"rescanTooltip": "Пересканировать рабочее пространство",
"enriching": "Обогащение",
"enrichComplete": "Обогащение завершено",
"enrichError": "Ошибка обогащения",
"enrichStopped": "Обогащение остановлено",
"enrichStopFailed": "Не удалось остановить обогащение",
"stopEnrich": "Остановить обогащение",
"stopEnrichConfirm": "Вы уверены, что хотите остановить процесс обогащения? Уже обработанные документы сохранят свои сводки.",
"stop": "Остановить",
"errors": "ошибок",
"rescanNew": "{{count}} новых",
"rescanUpdated": "{{count}} обновлено",
"rescanReenqueued": "{{count}} снова поставлено в очередь на обогащение",
"rescanUnchanged": "{{count}} без изменений",
"rescanTruncated": "сканирование усечено (достигнут лимит)",
"rescanNoFiles": "Новые файлы не найдены",
"rescanBusy": "Пересканирование уже выполняется",
"rescanError": "Пересканирование не удалось",
"upload": {
"title": "Загрузить в хранилище",
"destination": "Назначение",
"shared": "Общее",
"agent": "Агент",
"team": "Команда",
"selectAgent": "Выберите агента...",
"selectTeam": "Выберите команду...",
"dropzone": "Перетащите файлы сюда или нажмите для выбора",
"dropzoneHint": "Только текстовые файлы (.md, .txt, .json, .yaml, .csv, ...)",
"files": "Файлы ({{count}})",
"uploading": "Загрузка...",
"upload": "Загрузить"
},
"toast": {
"uploadSuccess": "Загружено файлов: {{count}}",
"uploadFailed": "Загрузка не удалась",
"docCreated": "Документ создан",
"docCreateFailed": "Не удалось создать документ",
"docUpdated": "Документ обновлён",
"docUpdateFailed": "Не удалось обновить документ",
"docDeleted": "Документ удалён",
"docDeleteFailed": "Не удалось удалить документ",
"linkCreated": "Ссылка создана",
"linkCreateFailed": "Не удалось создать ссылку",
"linkDeleted": "Ссылка удалена",
"linkDeleteFailed": "Не удалось удалить ссылку"
}
}
+157
View File
@@ -0,0 +1,157 @@
{
"title": "Вебхуки",
"description": "Входящие HTTP-вебхуки, которые запускают агента (LLM) или отправляют сообщение в канал.",
"addWebhook": "Создать вебхук",
"searchPlaceholder": "Поиск вебхуков...",
"showRevoked": "Показать отозванные",
"emptyTitle": "Нет вебхуков",
"emptyDescription": "Создайте свой первый вебхук, чтобы открыть агента или канал по HTTP.",
"neverUsed": "Не использовался",
"pager": {
"prev": "Назад",
"next": "Вперёд",
"pageOf": "Страница {{page}} из {{total}}",
"noMore": "Больше вебхуков нет."
},
"kind": {
"llm": "LLM",
"message": "Сообщение"
},
"status": {
"active": "Активен",
"revoked": "Отозван"
},
"columns": {
"name": "Имя",
"webhookId": "ID вебхука",
"kind": "Тип",
"target": "Цель",
"status": "Статус",
"lastUsed": "Последнее использование",
"actions": "Действия"
},
"actions": {
"test": "Тест",
"calls": "История доставки",
"edit": "Изменить",
"rotate": "Сменить секрет",
"revoke": "Отозвать"
},
"form": {
"createTitle": "Создать вебхук",
"editTitle": "Изменить вебхук",
"description": "Настройте, как этот вебхук аутентифицируется и что он запускает.",
"name": "Имя",
"namePlaceholder": "напр. обработчик лидов CRM",
"kind": "Тип",
"messageStandardOnly": "Только редакция Standard",
"agent": "Агент",
"agentPlaceholder": "Выберите агента",
"agentHint": "Требуется для вызова и тестирования вебхука LLM.",
"none": "Нет",
"channel": "Канал",
"channelPlaceholder": "Выберите канал",
"channelAny": "Любой (указывать в каждом запросе)",
"rateLimit": "Лимит частоты (запросов / минуту)",
"ipAllowlist": "Белый список IP",
"ipAllowlistPlaceholder": "напр. 203.0.113.0/24, 198.51.100.7",
"ipAllowlistHint": "IP или CIDR через запятую. Пусто — разрешить все.",
"requireHmac": "Требовать HMAC",
"requireHmacHint": "Отклонять аутентификацию по bearer-токену; требовать только подписанные запросы.",
"localhostOnly": "Только localhost",
"localhostOnlyHint": "Принимать запросы только с 127.0.0.1 / ::1.",
"localhostOnlyLite": "Принудительно включено в редакции Lite.",
"cancel": "Отмена",
"create": "Создать",
"save": "Сохранить",
"saving": "Сохранение..."
},
"secret": {
"title": "Секрет вебхука",
"description": "Скопируйте эти значения сейчас — они показываются только один раз.",
"warning": "Этот секрет больше не будет показан. Храните его надёжно.",
"webhookId": "ID вебхука (заголовок X-Webhook-Id)",
"bearer": "Секрет (Bearer-токен)",
"hmacKey": "Ключ подписи HMAC",
"copy": "Копировать",
"copied": "Скопировано",
"usageHint": "Отправляйте секрет как 'Authorization: Bearer <secret>' или подписывайте запросы ключом HMAC.",
"done": "Готово"
},
"test": {
"title": "Тестировать вебхук: {{name}}",
"description": "Вызовите этот вебхук на стороне сервера, используя вашу сессию администратора (секрет не нужен).",
"messageWarning": "Это отправит реальное сообщение в целевой чат.",
"channelName": "Имя канала",
"channelNamePlaceholder": "telegram-main",
"input": "Ввод",
"inputPlaceholder": "Введите запрос для отправки агенту",
"chatId": "ID чата",
"chatIdPlaceholder": "Идентификатор чата получателя",
"content": "Содержимое",
"result": "Результат",
"sent": "Отправлено в {{channel}} (чат {{chatId}})",
"run": "Отправить тест",
"running": "Отправка...",
"close": "Закрыть",
"failed": "Тест не удался"
},
"calls": {
"title": "История доставки: {{name}}",
"description": "Недавние вызовы этого вебхука.",
"statusAll": "Все статусы",
"status": {
"queued": "В очереди",
"running": "Выполняется",
"done": "Готово",
"failed": "Ошибка",
"dead": "Мёртв"
},
"cols": {
"status": "Статус",
"mode": "Режим",
"attempts": "Попытки",
"created": "Создан",
"detail": "Детали"
},
"emptyTitle": "Доставок пока нет",
"emptyDescription": "Вызовы этого вебхука появятся здесь.",
"noMore": "Больше вызовов нет.",
"pageOf": "Страница {{page}} из {{total}}",
"prev": "Назад",
"next": "Вперёд"
},
"callDetail": {
"title": "Детали доставки",
"description": "Полная запись одного вызова вебхука.",
"loading": "Загрузка...",
"deliveryId": "ID доставки",
"idempotencyKey": "Ключ идемпотентности",
"callbackUrl": "URL обратного вызова",
"created": "Создан",
"started": "Запущен",
"completed": "Завершён",
"nextAttempt": "Следующая попытка",
"lastError": "Последняя ошибка",
"requestPayload": "Полезная нагрузка запроса",
"response": "Ответ"
},
"rotate": {
"title": "Сменить секрет",
"description": "Смена делает недействительным текущий секрет для «{{name}}». Новый секрет будет показан один раз."
},
"revoke": {
"title": "Отозвать вебхук",
"description": "Отзыв навсегда отключает «{{name}}». Это нельзя отменить."
},
"toast": {
"created": "Вебхук создан",
"updated": "Вебхук обновлён",
"secretRotated": "Секрет сменён",
"revoked": "Вебхук отозван",
"failedCreate": "Не удалось создать вебхук",
"failedUpdate": "Не удалось обновить вебхук",
"failedRotate": "Не удалось сменить секрет",
"failedRevoke": "Не удалось отозвать вебхук"
}
}
@@ -0,0 +1,82 @@
{
"title": "Рабочие станции",
"description": "Управление подключениями к удалённым рабочим станциям (SSH, Docker) для выполнения команд агентами.",
"addWorkstation": "Добавить рабочую станцию",
"emptyTitle": "Рабочие станции не настроены",
"emptyDescription": "Добавьте рабочую станцию, чтобы агенты могли выполнять команды на удалённых машинах.",
"backend": {
"ssh": "SSH",
"docker": "Docker"
},
"status": {
"active": "Активна",
"inactive": "Неактивна"
},
"columns": {
"name": "Имя",
"key": "Ключ",
"backend": "Бэкенд",
"status": "Статус",
"created": "Создана",
"actions": "Действия"
},
"actions": {
"edit": "Изменить",
"delete": "Удалить",
"test": "Проверить подключение",
"activate": "Активировать",
"deactivate": "Деактивировать"
},
"createDialog": {
"title": "Добавить рабочую станцию",
"description": "Настройте новое подключение к удалённой рабочей станции.",
"nameLabel": "Отображаемое имя",
"namePlaceholder": "Мой сервер разработки",
"keyLabel": "Ключ рабочей станции",
"keyPlaceholder": "dev-server",
"keyHint": "Строчные буквы, цифры, дефисы. Используется агентами для ссылки на эту рабочую станцию.",
"backendLabel": "Тип бэкенда",
"sshOption": "SSH",
"dockerOption": "Docker",
"hostLabel": "Хост",
"hostPlaceholder": "192.168.1.100",
"portLabel": "Порт",
"userLabel": "Пользователь SSH",
"userPlaceholder": "ubuntu",
"identityFileLabel": "Файл идентификации (необязательно)",
"identityFilePlaceholder": "~/.ssh/id_rsa",
"containerLabel": "Имя / ID контейнера",
"containerPlaceholder": "my-container",
"dockerHostLabel": "Docker-хост (необязательно)",
"dockerHostPlaceholder": "unix:///var/run/docker.sock",
"cancel": "Отмена",
"create": "Создать"
},
"deleteDialog": {
"title": "Удалить рабочую станцию",
"description": "Вы уверены, что хотите удалить «{{name}}»? Это нельзя отменить.",
"confirmLabel": "Удалить"
},
"testResult": {
"success": "Подключение успешно",
"notImplemented": "Проверка подключения пока недоступна"
},
"activity": {
"title": "Недавняя активность",
"emptyTitle": "Активности пока нет",
"emptyDescription": "События выполнения появятся здесь, как только агенты запустят команды.",
"columns": {
"action": "Действие",
"cmdPreview": "Команда",
"exitCode": "Код выхода",
"duration": "Длительность",
"agent": "Агент",
"timestamp": "Время"
},
"actions": {
"exec": "Выполнить",
"deny": "Отклонено"
},
"loadMore": "Загрузить ещё"
}
}
+1
View File
@@ -371,6 +371,7 @@
"systemMessages.locale.vi": "Tiếng Việt",
"systemMessages.locale.zh": "Tiếng Trung",
"systemMessages.locale.ko": "Tiếng Hàn",
"systemMessages.locale.ru": "Tiếng Nga",
"systemMessages.override": "Mẫu ghi đè",
"systemMessages.overrideTip": "Mẫu sẽ được gửi thay cho thông báo có sẵn. Biến dùng dạng {{name}}.",
"systemMessages.defaultTemplate": "Mẫu mặc định",
+1
View File
@@ -371,6 +371,7 @@
"systemMessages.locale.vi": "越南语",
"systemMessages.locale.zh": "中文",
"systemMessages.locale.ko": "韩语",
"systemMessages.locale.ru": "俄语",
"systemMessages.override": "覆盖模板",
"systemMessages.overrideTip": "替代内置消息发送的模板。变量使用 {{name}}。",
"systemMessages.defaultTemplate": "默认模板",
+2 -1
View File
@@ -20,7 +20,7 @@ export const LOCAL_STORAGE_KEYS = {
TIMEZONE: "goclaw:timezone",
} as const;
export const SUPPORTED_LANGUAGES = ["en", "vi", "zh", "ko"] as const;
export const SUPPORTED_LANGUAGES = ["en", "vi", "zh", "ko", "ru"] as const;
export type Language = (typeof SUPPORTED_LANGUAGES)[number];
export const LANGUAGE_LABELS: Record<Language, string> = {
@@ -28,4 +28,5 @@ export const LANGUAGE_LABELS: Record<Language, string> = {
vi: "Tiếng Việt",
zh: "中文",
ko: "한국어",
ru: "Русский",
};
@@ -46,7 +46,7 @@ describe("system-messages-section-utils", () => {
});
it("normalizes all supported locales for each known message definition", () => {
expect(SYSTEM_MESSAGE_LOCALES.map((locale) => locale.code)).toEqual(["en", "vi", "zh", "ko"]);
expect(SYSTEM_MESSAGE_LOCALES.map((locale) => locale.code)).toEqual(["en", "vi", "zh", "ko", "ru"]);
const draft = normalizeSystemMessagesDraft(
{
@@ -91,6 +91,7 @@ describe("system-messages-section-utils", () => {
vi: "Nhóm {{code}}",
zh: "",
ko: "",
ru: "",
},
},
});
@@ -108,6 +109,7 @@ describe("system-messages-section-utils", () => {
vi: "",
zh: "",
ko: "",
ru: "",
},
},
});
@@ -132,6 +134,7 @@ describe("system-messages-section-utils", () => {
vi: "",
zh: "",
ko: "",
ru: "",
},
},
});
@@ -19,6 +19,7 @@ export const SYSTEM_MESSAGE_LOCALES = [
{ code: "vi", labelKey: "systemMessages.locale.vi" },
{ code: "zh", labelKey: "systemMessages.locale.zh" },
{ code: "ko", labelKey: "systemMessages.locale.ko" },
{ code: "ru", labelKey: "systemMessages.locale.ru" },
] as const;
export function systemMessageDefinitionsFromSchema(schema: Record<string, any> | null | undefined): SystemMessageDefinition[] {
@@ -113,8 +113,16 @@ describe("hooks i18n key contracts", () => {
expect(zhKeys).toEqual(enKeys);
});
it("ru locale has same top-level keys as en", async () => {
const en = await import("@/i18n/locales/en/hooks.json");
const ru = await import("@/i18n/locales/ru/hooks.json");
const enKeys = Object.keys(en as unknown as Record<string, unknown>).sort();
const ruKeys = Object.keys(ru as unknown as Record<string, unknown>).sort();
expect(ruKeys).toEqual(enKeys);
});
it("decision keys exist in all locales", async () => {
for (const locale of ["en", "vi", "zh"]) {
for (const locale of ["en", "vi", "zh", "ru"]) {
const mod = await import(`@/i18n/locales/${locale}/hooks.json`);
const data = mod as unknown as Record<string, Record<string, string>>;
expect(data.decision?.allow).toBeTruthy();
@@ -5,14 +5,16 @@ describe("traces i18n filter keys", () => {
const en = await import("@/i18n/locales/en/traces.json");
const vi = await import("@/i18n/locales/vi/traces.json");
const zh = await import("@/i18n/locales/zh/traces.json");
const ru = await import("@/i18n/locales/ru/traces.json");
const enKeys = Object.keys(en as Record<string, unknown>).sort();
expect(Object.keys(vi as Record<string, unknown>).sort()).toEqual(enKeys);
expect(Object.keys(zh as Record<string, unknown>).sort()).toEqual(enKeys);
expect(Object.keys(ru as Record<string, unknown>).sort()).toEqual(enKeys);
});
it("filter labels exist in all locales", async () => {
for (const locale of ["en", "vi", "zh"]) {
for (const locale of ["en", "vi", "zh", "ru"]) {
const mod = await import(`@/i18n/locales/${locale}/traces.json`);
const data = mod as unknown as { filters?: Record<string, string> };
for (const key of ["search", "status", "advanced", "from", "to", "toolName", "hasToolCalls", "clearAll"]) {