@goodandready/dsh-russian-lang 0.3.26 → 0.3.28

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -5,7 +5,7 @@
5
5
  <h3>Полная русская локализация, умная типографика и исправление раскладки клавиатуры для DeepSeek Harness</h3>
6
6
 
7
7
  <p align="center">
8
- <a href="https://www.npmjs.com/package/@goodandready/dsh-russian-lang"><img src="https://img.shields.io/badge/npm-v0.3.26-6366f1.svg?style=for-the-badge&labelColor=1e1b4b" alt="npm version"></a>
8
+ <a href="https://www.npmjs.com/package/@goodandready/dsh-russian-lang"><img src="https://img.shields.io/badge/npm-v0.3.28-6366f1.svg?style=for-the-badge&labelColor=1e1b4b" alt="npm version"></a>
9
9
  <a href="LICENSE"><img src="https://img.shields.io/badge/License-MIT-10b981.svg?style=for-the-badge&color=10b981&labelColor=064e3b" alt="license"></a>
10
10
  <a href="https://github.com/topics/dsh-plugin"><img src="https://img.shields.io/badge/DSH-Plugin-8b5cf6.svg?style=for-the-badge&labelColor=2e1065" alt="DSH Plugin"></a>
11
11
  <a href="https://nodejs.org"><img src="https://img.shields.io/badge/Node-20%2B-f59e0b.svg?style=for-the-badge&labelColor=451a03" alt="Node version"></a>
@@ -14,7 +14,7 @@
14
14
  <p align="center">
15
15
  <img src="https://img.shields.io/badge/DSH-v0.2.0--rc.2%2B-blue.svg?style=for-the-badge&labelColor=1e1b4b" alt="DSH v0.1.7-rc.2+">
16
16
  <img src="https://img.shields.io/badge/Покрытие-100%25-10b981.svg?style=for-the-badge&labelColor=064e3b" alt="Покрытие 100%">
17
- <img src="https://img.shields.io/badge/Ключей_UI-8576-6366f1.svg?style=for-the-badge&labelColor=1e1b4b" alt="8576 ключей">
17
+ <img src="https://img.shields.io/badge/Ключей_UI-8584-6366f1.svg?style=for-the-badge&labelColor=1e1b4b" alt="8584 ключей">
18
18
  <img src="https://img.shields.io/badge/Ручная_вычитка-100%25-0ea5e9.svg?style=for-the-badge&labelColor=082f49" alt="100% ручная вычитка">
19
19
  </p>
20
20
 
@@ -52,9 +52,9 @@ graph LR
52
52
  DSH[Web UI Интерфейс] --> Loader[Загрузчик локализации dsh-russian-lang]
53
53
  end
54
54
 
55
- subgraph TranslationLayer [Слой перевода и адаптации — 8576 ключей / 100% вычитано]
56
- Loader --> CoreDict[58 Пространств имён ядра DSH / 2442 ключа]
57
- Loader --> PluginDict[64 Плагина экосистемы DSH / 6134 ключа]
55
+ subgraph TranslationLayer [Слой перевода и адаптации — 8 584 ключа / 100% вычитано]
56
+ Loader --> CoreDict[58 Пространств имён ядра DSH / 2 442 ключа]
57
+ Loader --> PluginDict[43 Пространства имён плагинов DSH / 6 142 ключа]
58
58
  Loader --> PluralEngine[Движок грамматических Plural-форм: 1/2/5]
59
59
  end
60
60
 
@@ -85,7 +85,7 @@ graph LR
85
85
 
86
86
  ## ✨ Полный обзор возможностей
87
87
 
88
- ### 1. 🌐 100% покрытие ядра DSH (59 Пространств имён, 2415 ключей)
88
+ ### 1. 🌐 100% покрытие ядра DSH (58 пространств имён, 2 442 ключа)
89
89
  * **Диалоги и переписка (`conversation`)**: лента сообщений, ветки обсуждений, карточки вызова инструментов, статус генерации и рассуждений (thinking traces).
90
90
  * **Модели и провайдеры (`settings.models`)**: каталог моделей, параметры инференса, управление токенами и ключами API.
91
91
  * **Трейсы рассуждений (`trajectory`)**: детальные шаги, параметры вызовов инструментов, временные метки и визуализация размышлений модели.
@@ -94,9 +94,9 @@ graph LR
94
94
  * **Планировщик и инвентарь (`schedule.catalog`, `settings.pluginInventory`, `settings.plugins`)**: фоновые задания, периодичность, фильтры и каталог установленных плагинов.
95
95
  * **Права доступа и безопасность (`permission.access`, `plan`, `skill`)**: пресеты прав (полный доступ, только чтение, запись в рабочую область), выполнение планов и навыки.
96
96
 
97
- > **О качестве перевода.** Все **8110 ключей интерфейса (2146 ядра + 6589 плагинов) переведены на 100% и вычитаны вручную**. Черновой машинный перевод полностью замещён проверенными формулировками (`draft = 0`). Перевод регулярно валидируется автоматическими линтерами целостности плейсхолдеров, проверкой соблюдения глоссария (`glossary.json`) и детекторами переполнения верстки. Нашли неточность — кнопка «Сообщить о проблеме перевода» в карточке настроек создаёт готовый issue.
97
+ > **О качестве перевода.** Все **8 584 ключа интерфейса (2 442 ядра + 6 142 плагинов) переведены на 100% и вычитаны вручную**. Черновой машинный перевод полностью замещён проверенными формулировками (`draft = 0`). Перевод регулярно валидируется автоматическими линтерами целостности плейсхолдеров, проверкой соблюдения глоссария (`glossary.json`) и детекторами переполнения верстки. Нашли неточность — кнопка «Сообщить о проблеме перевода» в карточке настроек создаёт готовый issue.
98
98
 
99
- ### 2. 🧩 Встроенный перевод 65+ плагинов экосистемы DSH (5695 ключей)
99
+ ### 2. 🧩 Встроенный перевод 65+ плагинов экосистемы DSH (6 142 ключа)
100
100
  Локализация автоматически распространяется на все ключевые плагины экосистемы DeepSeek Harness:
101
101
  * **`dsh-session-control`** — расширенное управление сессиями: закрепление диалогов, архив по периодам, просмотр расшифровок и фильтрация шума;
102
102
  * **`dsh-kanban` и `task-board`** — канбан-доски задач, карточки, чек-листы, дедлайны, критерии готовности (DoD) и шлюз приёмки (Acceptance Gate);
@@ -149,7 +149,7 @@ graph LR
149
149
 
150
150
  ### 7. ⚡ Оптимизации производительности и архитектурная безопасность
151
151
  * **Пакетная обработка MutationObserver**: оптимизированный наблюдатель мутаций интерфейса с адаптивным debounce (16 мс) предотвращает лавинообразные перерисовки и перерасчёт макета (reflow) при интенсивном рендеринге списков и стриминге LLM-токенов.
152
- * **Защита HTTP-маршрутов словарей (405 Method Not Allowed)**: серверные эндпоинты `/dict/core`, `/dict/plugins`, `/dict/all`, `/dict/search` строго защищены и принимают только безопасные методы GET/HEAD.
152
+ * **Защита HTTP-маршрутов словарей (405 Method Not Allowed)**: серверные эндпоинты `/api/dsh-russian-lang/dict/core`, `/api/dsh-russian-lang/dict/plugins`, `/api/dsh-russian-lang/dict/all` строго защищены и принимают только безопасные методы GET/HEAD.
153
153
  * **Клиентский бандл с запасом**: оптимизированная архитектура и компактный бутстрап обеспечивают размер клиентского скрипта 153.7 KiB (запас более 10 KiB до предельного лимита).
154
154
 
155
155
  ### 8. 🔤 Нативная интеграция в ядро
@@ -167,33 +167,48 @@ dsh plugin --profile web add @goodandready/dsh-russian-lang
167
167
 
168
168
  ---
169
169
 
170
- ## ⚙️ Параметры конфигурации (`settings.yaml`)
170
+ ## ⚙️ Параметры конфигурации (`settings.yaml` / профиль Cordis)
171
171
 
172
- Пространство настроек — `russian-lang`. Схема объявлена в [`lib/index.js`](lib/index.js),
173
- все поля необязательные:
172
+ В актуальных версиях DSH (v0.2.0-rc.2+, v0.1.7+) конфигурация плагина управляется штатно через managed-форму в веб-интерфейсе (**Настройки → Плагины → Русская локализация**) либо в профиле/конфиге под идентификатором плагина `dsh-russian-lang` (согласно `cordis.patch.yml`).
173
+
174
+ Для полной обратной совместимости с ранними версиями ядра (DSH <= 0.1.6) плагин также автоматически поддерживает чтение из легаси-пространства `russian-lang`.
175
+
176
+ Схема параметров объявлена в [`lib/index.js`](lib/index.js), все поля необязательные:
174
177
 
175
178
  ```yaml
176
- russian-lang:
177
- enabled: true # Русский язык интерфейса
178
- typography:
179
- enabled: true # Ёлочки, длинные тире, неразрывные пробелы
180
- yo: false # Восстанавливать «ё» (по умолчанию выключено)
181
- agentPrompt: false # Просить агента отвечать по-русски
182
- overrides: {} # Свои значения для любых ключей перевода
179
+ # Актуальный формат (DSH v0.2.0-rc.2+ / v0.1.7+):
180
+ dsh-russian-lang:
181
+ enabled: true # Русский язык интерфейса (по умолчанию: true)
182
+ overrides: {} # Пользовательские оверрайды ключей (по умолчанию: {})
183
+ typography: # Интеллектуальная типографика (по умолчанию: все opt-in false)
184
+ enabled: false # Ёлочки, длинные тире, неразрывные пробелы
185
+ yo: false # Восстановление безопасной буквы «ё»
186
+ liveInput: false # Живая типографика при вводе в текстовых полях
187
+ agentPrompt: false # Системная инструкция агенту отвечать по-русски (по умолчанию: false)
188
+ agentPromptPreset: technical_expert # Пресет системного промпта (по умолчанию: technical_expert)
189
+ slashAliases: true # Русские алиасы слэш-команд (/помощь, /очистить) (по умолчанию: true)
190
+ layoutConversion: true # Детектор неверной раскладки и подсказка Alt+L (по умолчанию: true)
191
+ quickSwitch: true # Быстрый переключатель RU/EN в статусной строке (по умолчанию: true)
192
+ translateEngine: local # Движок перевода реплик: local (LibreTranslate) или cloud (Google) (по умолчанию: local)
193
+ localApiUrl: http://localhost:5000 # URL локального инстанса LibreTranslate (по умолчанию: http://localhost:5000)
194
+
195
+ # Легаси-формат (DSH <= 0.1.6, поддерживается автоматически как fallback):
196
+ # russian-lang:
197
+ # enabled: true
198
+ # ...
183
199
  ```
184
200
 
185
- Проще то же самое — в **Настройки → Плагины → Русская локализация**.
201
+ Удобнее всего настраивать параметры визуально в интерфейсе: **Настройки → Плагины → Русская локализация**.
186
202
 
187
- Исправление раскладки (<kbd>Alt+L</kbd>) и браузерный спелчек включаются вместе с
188
- русским языком и отдельных ключей не имеют.
203
+ Исправление раскладки (<kbd>Alt+L</kbd>) и русские алиасы слэш-команд включены по умолчанию (`true`) и могут быть индивидуально отключены в настройках (`layoutConversion: false`, `slashAliases: false`). Браузерный спелчек (`lang="ru-RU"`) активируется автоматически при выборе русской локали.
189
204
 
190
205
  ---
191
206
 
192
207
  ## 🛠 Разработка и зеркало репозитория
193
208
 
194
- Публичный репозиторий на GitHub является дистрибутивным зеркалом релизов `@goodandready/dsh-russian-lang`. Основная разработка, сборочный пайплайн и полный тестовый контур ведутся в закрытом репозитории проекта.
209
+ Публичный репозиторий на GitHub является дистрибутивным зеркалом релизов `@goodandready/dsh-russian-lang`. Основная разработка, сборочный пайплайн и полный тестовый контур ведутся в основном Gitea-репозитории проекта.
195
210
 
196
- Pull Requests и Issues на GitHub приветствуются и обрабатываются в обычном порядке! Для внесения правок в логику клиента используйте `lib/client.template.js`. Запуск `npm test` в клоне репозитория проверяет синтаксис бандла через `node --check`.
211
+ Pull Requests и Issues на GitHub приветствуются и обрабатываются в обычном порядке! Для внесения правок в логику клиента используйте `lib/client.template.js`. Запуск `npm test` в репозитории выполняет полную проверку (270+ модульных тестов Node.js, тесты сборщика, линтеры переводов и глоссария).
197
212
 
198
213
  ---
199
214
 
package/bin/dsh-i18n.mjs CHANGED
@@ -6,6 +6,10 @@ import { fileURLToPath } from 'node:url'
6
6
  const __dirname = path.dirname(fileURLToPath(import.meta.url))
7
7
  const ROOT = path.resolve(__dirname, '..')
8
8
 
9
+ function escapeRegExp(string) {
10
+ return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
11
+ }
12
+
9
13
  function getPkgVersion() {
10
14
  try {
11
15
  const pkg = JSON.parse(fs.readFileSync(path.join(ROOT, 'package.json'), 'utf8'))
@@ -41,6 +45,115 @@ dsh-i18n (v${getPkgVersion()}) — Инструмент локализации
41
45
  `)
42
46
  }
43
47
 
48
+ function extractFromCode(code, result, defaultNs = 'common') {
49
+ let i = 0
50
+ const len = code.length
51
+
52
+ function skipWhitespace(idx) {
53
+ while (idx < len && /\s/.test(code[idx])) idx++
54
+ return idx
55
+ }
56
+
57
+ function readString(idx) {
58
+ const quote = code[idx]
59
+ if (quote !== "'" && quote !== '"' && quote !== '`') return null
60
+ let s = ''
61
+ idx++
62
+ while (idx < len) {
63
+ const ch = code[idx]
64
+ if (ch === '\\') {
65
+ if (idx + 1 < len) {
66
+ s += code[idx + 1]
67
+ idx += 2
68
+ continue
69
+ }
70
+ }
71
+ if (ch === quote) {
72
+ return { val: s, next: idx + 1 }
73
+ }
74
+ s += ch
75
+ idx++
76
+ }
77
+ return null
78
+ }
79
+
80
+ while (i < len) {
81
+ const ch = code[i]
82
+
83
+ // Single-line comment
84
+ if (ch === '/' && code[i + 1] === '/') {
85
+ i += 2
86
+ while (i < len && code[i] !== '\n') i++
87
+ continue
88
+ }
89
+
90
+ // Multi-line comment
91
+ if (ch === '/' && code[i + 1] === '*') {
92
+ i += 2
93
+ while (i < len && !(code[i] === '*' && code[i + 1] === '/')) i++
94
+ i += 2
95
+ continue
96
+ }
97
+
98
+ // String literals in normal code
99
+ if (ch === "'" || ch === '"' || ch === '`') {
100
+ const strRes = readString(i)
101
+ if (strRes) {
102
+ i = strRes.next
103
+ continue
104
+ }
105
+ }
106
+
107
+ // Check for word boundary identifier
108
+ const prevChar = i > 0 ? code[i - 1] : ' '
109
+ const isWordStart = !/[a-zA-Z0-9_$.]/.test(prevChar)
110
+
111
+ if (isWordStart) {
112
+ if (code.startsWith('translate', i) && !/[a-zA-Z0-9_$]/.test(code[i + 9] || '')) {
113
+ let j = skipWhitespace(i + 9)
114
+ if (code[j] === '(') {
115
+ j = skipWhitespace(j + 1)
116
+ const nsStr = readString(j)
117
+ if (nsStr) {
118
+ j = skipWhitespace(nsStr.next)
119
+ if (code[j] === ',') {
120
+ j = skipWhitespace(j + 1)
121
+ const keyStr = readString(j)
122
+ if (keyStr) {
123
+ j = skipWhitespace(keyStr.next)
124
+ if (code[j] === ',' || code[j] === ')') {
125
+ const ns = nsStr.val
126
+ const key = keyStr.val
127
+ if (!result[ns]) result[ns] = {}
128
+ result[ns][key] = result[ns][key] || ''
129
+ i = j
130
+ continue
131
+ }
132
+ }
133
+ }
134
+ }
135
+ }
136
+ } else if (code.startsWith('t', i) && !/[a-zA-Z0-9_$]/.test(code[i + 1] || '')) {
137
+ let j = skipWhitespace(i + 1)
138
+ if (code[j] === '(') {
139
+ j = skipWhitespace(j + 1)
140
+ const keyStr = readString(j)
141
+ if (keyStr) {
142
+ j = skipWhitespace(keyStr.next)
143
+ if (code[j] === ',' || code[j] === ')') {
144
+ result[defaultNs][keyStr.val] = result[defaultNs][keyStr.val] || ''
145
+ i = j
146
+ continue
147
+ }
148
+ }
149
+ }
150
+ }
151
+ }
152
+
153
+ i++
154
+ }
155
+ }
156
+
44
157
  function extractKeys(targetDir, defaultNs = 'common') {
45
158
  const result = { [defaultNs]: {} }
46
159
  const extensions = new Set(['.js', '.mjs', '.cjs', '.ts', '.tsx', '.jsx'])
@@ -55,17 +168,7 @@ function extractKeys(targetDir, defaultNs = 'common') {
55
168
  walk(fullPath)
56
169
  } else if (entry.isFile() && extensions.has(path.extname(entry.name))) {
57
170
  const code = fs.readFileSync(fullPath, 'utf8')
58
- const tMatches = code.matchAll(/\bt\(\s*['"`]([a-zA-Z0-9_.-]+)['"`]\s*\)/g)
59
- for (const m of tMatches) {
60
- result[defaultNs][m[1]] = result[defaultNs][m[1]] || ''
61
- }
62
- const transMatches = code.matchAll(/\btranslate\(\s*['"`]([a-zA-Z0-9_.-]+)['"`]\s*,\s*['"`]([a-zA-Z0-9_.-]+)['"`]/g)
63
- for (const m of transMatches) {
64
- const ns = m[1]
65
- const key = m[2]
66
- if (!result[ns]) result[ns] = {}
67
- result[ns][key] = result[ns][key] || ''
68
- }
171
+ extractFromCode(code, result, defaultNs)
69
172
  }
70
173
  }
71
174
  }
@@ -88,22 +191,42 @@ function validateDict(filePath, glossaryPath) {
88
191
  return false
89
192
  }
90
193
 
194
+ if (!data || typeof data !== 'object' || Array.isArray(data)) {
195
+ console.error(`Ошибка структуры JSON в ${filePath}: корневой элемент должен быть объектом`)
196
+ return false
197
+ }
198
+
91
199
  let errors = []
92
200
  let warnings = []
93
201
  let totalKeys = 0
94
202
 
95
203
  let glossary = null
96
- const gPath = glossaryPath || path.join(ROOT, 'glossary.json')
97
- if (fs.existsSync(gPath)) {
204
+ if (glossaryPath) {
205
+ if (!fs.existsSync(glossaryPath)) {
206
+ console.error(`Ошибка: Файл глоссария не найден: ${glossaryPath}`)
207
+ return false
208
+ }
98
209
  try {
99
- glossary = JSON.parse(fs.readFileSync(gPath, 'utf8')).terms || {}
100
- } catch (_) {}
210
+ const parsed = JSON.parse(fs.readFileSync(glossaryPath, 'utf8'))
211
+ glossary = parsed.terms || parsed
212
+ } catch (err) {
213
+ console.error(`Ошибка чтения глоссария ${glossaryPath}: ${err.message}`)
214
+ return false
215
+ }
216
+ } else {
217
+ const defaultGPath = path.join(ROOT, 'glossary.json')
218
+ if (fs.existsSync(defaultGPath)) {
219
+ try {
220
+ const parsed = JSON.parse(fs.readFileSync(defaultGPath, 'utf8'))
221
+ glossary = parsed.terms || parsed
222
+ } catch (_) {}
223
+ }
101
224
  }
102
225
 
103
226
  function checkString(ns, key, val) {
104
227
  totalKeys++
105
228
  if (typeof val !== 'string') {
106
- errors.push(`[${ns}:${key}] Значение должно быть строкой, получено: ${typeof val}`)
229
+ errors.push(`[${ns}:${key}] Значение должно быть строкой, получено: ${val === null ? 'null' : Array.isArray(val) ? 'массив' : typeof val}`)
107
230
  return
108
231
  }
109
232
 
@@ -117,13 +240,12 @@ function validateDict(filePath, glossaryPath) {
117
240
  }
118
241
 
119
242
  if (glossary) {
120
- const lower = val.toLowerCase()
121
243
  for (const [term, info] of Object.entries(glossary)) {
122
244
  if (Array.isArray(info.forbidden)) {
123
245
  for (const forbidden of info.forbidden) {
124
- const fLow = forbidden.toLowerCase()
125
- const re = new RegExp(`\\b${fLow}\\b`, 'i')
126
- if (re.test(lower)) {
246
+ const esc = escapeRegExp(forbidden)
247
+ const re = new RegExp(`(?<=[^\\p{L}\\p{N}]|^)${esc}(?=[^\\p{L}\\p{N}]|$)`, 'iu')
248
+ if (re.test(val)) {
127
249
  warnings.push(`[${ns}:${key}] Запрещённый термин по глоссарию "${forbidden}" (рекомендуется: "${info.canonical}")`)
128
250
  }
129
251
  }
@@ -134,10 +256,12 @@ function validateDict(filePath, glossaryPath) {
134
256
 
135
257
  for (const ns of Object.keys(data)) {
136
258
  const section = data[ns]
137
- if (typeof section === 'object' && section !== null) {
138
- for (const [k, v] of Object.entries(section)) {
139
- checkString(ns, k, v)
140
- }
259
+ if (!section || typeof section !== 'object' || Array.isArray(section)) {
260
+ errors.push(`[${ns}] Пространство имён должно быть объектом, получено: ${section === null ? 'null' : Array.isArray(section) ? 'массив' : typeof section}`)
261
+ continue
262
+ }
263
+ for (const [k, v] of Object.entries(section)) {
264
+ checkString(ns, k, v)
141
265
  }
142
266
  }
143
267
 
@@ -214,7 +338,8 @@ if (command === 'extract') {
214
338
  if (out) {
215
339
  fs.mkdirSync(path.dirname(path.resolve(out)), { recursive: true })
216
340
  fs.writeFileSync(path.resolve(out), jsonStr + '\n', 'utf8')
217
- console.log(`✓ Извлечено ключей: ${Object.keys(extracted[ns] || {}).length} -> ${out}`)
341
+ const totalCount = Object.values(extracted).reduce((sum, nObj) => sum + Object.keys(nObj || {}).length, 0)
342
+ console.log(`✓ Извлечено ключей: ${totalCount} -> ${out}`)
218
343
  } else {
219
344
  console.log(jsonStr)
220
345
  }
package/glossary.json ADDED
@@ -0,0 +1,206 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "version": "1.0.0",
4
+ "description": "Канонический глоссарий терминов DeepSeek Harness (DSH) и AI-экосистемы",
5
+ "terms": {
6
+ "workspace": {
7
+ "canonical": "Рабочая область",
8
+ "allowed": [
9
+ "Рабочая область",
10
+ "Воркспейс"
11
+ ],
12
+ "forbidden": [
13
+ "Рабочее место",
14
+ "Рабочий стол",
15
+ "Пространство задач"
16
+ ],
17
+ "description": "Изолированная рабочая директория/проект агента"
18
+ },
19
+ "subagent": {
20
+ "canonical": "Субагент",
21
+ "allowed": [
22
+ "Субагент",
23
+ "Дочерний агент"
24
+ ],
25
+ "forbidden": [
26
+ "Подагент",
27
+ "Младший агент",
28
+ "Вспомогательный агент"
29
+ ],
30
+ "description": "Автономный дочерний агент"
31
+ },
32
+ "prompt": {
33
+ "canonical": "Промпт",
34
+ "allowed": [
35
+ "Промпт",
36
+ "Инструкция",
37
+ "Системный промпт"
38
+ ],
39
+ "forbidden": [
40
+ "Затравка",
41
+ "Побуждение",
42
+ "Внушение"
43
+ ],
44
+ "description": "Инструкция или текстовый ввод для модели"
45
+ },
46
+ "tool": {
47
+ "canonical": "Инструмент",
48
+ "allowed": [
49
+ "Инструмент",
50
+ "Вызов инструмента"
51
+ ],
52
+ "forbidden": [
53
+ "Орудие",
54
+ "Утилита"
55
+ ],
56
+ "description": "Функция или инструмент, вызываемый агентом (tool/tool call)"
57
+ },
58
+ "session": {
59
+ "canonical": "Сессия",
60
+ "allowed": [
61
+ "Сессия",
62
+ "Диалог",
63
+ "Чат"
64
+ ],
65
+ "forbidden": [
66
+ "Заседание",
67
+ "Сеанс связи"
68
+ ],
69
+ "description": "Отдельный поток диалога или сессия работы"
70
+ },
71
+ "skill": {
72
+ "canonical": "Навык",
73
+ "allowed": [
74
+ "Навык",
75
+ "Навыки",
76
+ "Skill"
77
+ ],
78
+ "forbidden": [
79
+ "Умение",
80
+ "Мастерство"
81
+ ],
82
+ "description": "Подключаемый модуль навыков агента"
83
+ },
84
+ "plugin": {
85
+ "canonical": "Плагин",
86
+ "allowed": [
87
+ "Плагин",
88
+ "Плагины"
89
+ ],
90
+ "forbidden": [
91
+ "Встраиваемый модуль"
92
+ ],
93
+ "description": "Плагин Cordis / DSH"
94
+ },
95
+ "provider": {
96
+ "canonical": "Провайдер",
97
+ "allowed": [
98
+ "Провайдер",
99
+ "Провайдеры"
100
+ ],
101
+ "forbidden": [
102
+ "Поставщик",
103
+ "Поставщики"
104
+ ],
105
+ "description": "Провайдер LLM API (OpenAI, DeepSeek, Ollama и др.)"
106
+ },
107
+ "token": {
108
+ "canonical": "Токен",
109
+ "allowed": [
110
+ "Токен",
111
+ "Токены"
112
+ ],
113
+ "forbidden": [
114
+ "Жетон",
115
+ "Жетоны"
116
+ ],
117
+ "description": "Единица расхода контекста LLM"
118
+ },
119
+ "thinking": {
120
+ "canonical": "Размышления",
121
+ "allowed": [
122
+ "Размышления",
123
+ "Рассуждения",
124
+ "Цепочка рассуждений"
125
+ ],
126
+ "forbidden": [
127
+ "Думание",
128
+ "Мышление модели"
129
+ ],
130
+ "description": "Трейс внутренних рассуждений (thinking traces) модели"
131
+ },
132
+ "effort": {
133
+ "canonical": "Уровень рассуждений",
134
+ "allowed": [
135
+ "Уровень рассуждений",
136
+ "Усилие рассуждений",
137
+ "Усилие"
138
+ ],
139
+ "forbidden": [
140
+ "Старание",
141
+ "Напряжение"
142
+ ],
143
+ "description": "Параметр reasoning effort модели"
144
+ },
145
+ "approval": {
146
+ "canonical": "Подтверждение",
147
+ "allowed": [
148
+ "Подтверждение",
149
+ "Одобрение"
150
+ ],
151
+ "forbidden": [
152
+ "Апробация",
153
+ "Санкционирование"
154
+ ],
155
+ "description": "Запрос подтверждения опасного действия пользователем"
156
+ },
157
+ "deliverables": {
158
+ "canonical": "Результаты работы",
159
+ "allowed": [
160
+ "Результаты работы",
161
+ "Файлы результатов",
162
+ "Результаты"
163
+ ],
164
+ "forbidden": [
165
+ "Поставки",
166
+ "Доставляемые элементы"
167
+ ],
168
+ "description": "Созданные агентом итоговые файлы"
169
+ },
170
+ "branch": {
171
+ "canonical": "Ветка",
172
+ "allowed": [
173
+ "Ветка",
174
+ "Ветвление"
175
+ ],
176
+ "forbidden": [
177
+ "Ответвление",
178
+ "Ветвь"
179
+ ],
180
+ "description": "Ветка диалога или Git-ветка"
181
+ },
182
+ "checkpoint": {
183
+ "canonical": "Контрольная точка",
184
+ "allowed": [
185
+ "Контрольная точка",
186
+ "Чекпоинт"
187
+ ],
188
+ "forbidden": [
189
+ "Точка проверки",
190
+ "Контрольный пункт"
191
+ ],
192
+ "description": "Точка сохранения состояния сессии или памяти"
193
+ },
194
+ "command_code": {
195
+ "canonical": "Command Code",
196
+ "allowed": [
197
+ "Command Code"
198
+ ],
199
+ "forbidden": [
200
+ "Код команды",
201
+ "Командный код"
202
+ ],
203
+ "description": "Название провайдера и расширения Command Code (commandcode.ai)"
204
+ }
205
+ }
206
+ }