Звідки брати контекст і назви

Як через API BDO UA Translate отримати контекст цілої пачки рядків одним запитом і читати глосарій: визначення терміна, посилання на вікі, область дії та обовʼязкові відповідники.

Контекст береться пачкою, одним запитом на всі рядки ітерації:

curl -s -X POST -H "X-API-Key: $BDO_API_KEY" -H 'Content-Type: application/json' \
  -d '{"identity_hashes":["<64 hex>","<64 hex>"]}' \
  https://bdo-ua.com.ua/api/agent/v1/rows/context
{
  "success": true,
  "data": { "contexts": { "<identity_hash>": { "indexed": true, "terms": [], "related_rows": [] } } },
  "meta": { "requested": 2, "found": 2 }
}

Обʼєкт кожного рядка дослівно збігається з одиничним GET /rows/{identity_hash}/context. Невідомий хеш запиту не валить · він просто відсутній у contexts, а різниця видна з meta.requested і meta.found.

Розмір пачки читайте з GET /medata.batch.max_context_rows. Це стеля запиту, а не фіксований розмір: менше · можна завжди, більше · batch_too_large з details.max і details.given.

Що всередині контексту

  • related_rows · до 12 уже перекладених рядків, у яких трапляється той самий канонічний термін: видно оригінал, переклад, його шар і свіжість. Це не «схожий текст» і не сусідні рядки файлу, а підтверджений звʼязок за терміном.
  • terms · терміни цього рядка (те саме, що GET /glossary/rows/{hash}).
  • indexed: false означає «не знаю», а не «термінів немає». Різниця принципова: у першому випадку назву перекладати вільно не можна.

Термін: не лише «як називається»

Кожен термін приходить із контекстом сутності:

Поле Що означає
ukrainian канонічний відповідник; ukrainian_layer каже, звідки він
definition що це таке: предмет, NPC, механіка. null · опису ще немає
wiki_url зовнішній опис, якщо він є
scopes де термін чинний: [{"domain":"quest","semantic_type":"name"}]. Порожньо · чинний скрізь
severity mandatory · саме цей відповідник, forbidden · так не можна
ambiguous true · однозначного відповідника немає, вигадувати заборонено
forms українські відмінкові форми, щоб не відмінювати назву самотужки

definition і wiki_url існують саме для моделі: без них вона знає, ЯК називається термін, але не знає, ЩО це, і добудовує зміст із самого рядка · звідси хибний рід, відмінок і зайві уточнення.

Внутрішні коментарі модераторів API не віддає ніколи · це не частина контракту.

Поняття гри: те, чого немає в жодному рядку

GET /glossary/concepts віддає повний перелік понять · посилення, стек невдач, пробудження, вузол, життєві навички. Це не назви предметів: у тексті вони трапляються як звичайні англійські слова, тому в індекс згадок не потрапляють ніколи й через два попередні маршрути ви їх не побачите.

{"data": {"concepts": [
  {"term_id": 12, "term": "Enhancement", "ua": "посилення",
   "gist": "Механіка підвищення рівня спорядження.",
   "definition": "Середній рід: «посилення», «посиленню». Не плутати з «покращенням» предмета.",
   "wiki_url": null, "case_sensitive": false}
]}, "meta": {"count": 1, "complete": true}}

Список приходить цілком, без пагінації (complete: true): понять сотні, а не сотні тисяч. Прочитайте його один раз на сесію, покладіть gist у системний промпт і самі обирайте релевантні для конкретного рядка.

case_sensitive ігнорувати не можна: MAP у грі означає Monster AP, а map · звичайну карту, і це різні картки глосарія. Усі скорочення показників (AP, DP, EXP, LT, CP, MAP) приходять із true.

Якщо назви немає в глосарії

Не вигадуйте її в тексті рядка. Порядок такий:

  1. POST /glossary/terms/resolve з canonical_sourcesource_identity, якщо назва належить кільком сутностям);
  2. відповідь ready дає term_id та підтверджену identity;
  3. POST /glossary/proposals подає відповідник у модерацію · разом із definition (до 4 000 символів) і wiki_url (до 512), якщо вам є що додати.

Відповідь blocked_identity означає, що сутність не однозначна. Обходити її вибором навмання не можна: саме так у базу потрапляють «однойменні, але різні» предмети.

Далі: як надіслати переклад і що робити з відмовою.