Админ -> Настроить -> Текст ведёт себя некорректно

При попытке фильтрации подсказок чат-бота сталкиваюсь с рядом похожих проблем.

Самое странное, что в одной установке всё работает нормально, а в другой — нет.

Возьмём очень простой фильтр chatbot.prompt в разделе Администрирование → Настройка → Текст:

Рабочая установка:

Не работающая установка:

NoMethodError (undefined method `scan' for {:basic=>"You are a helpful assistant.", :agent=>"You are a helpful assistant.  You have great tools in the form of functions that give you the power to get newer information. Only use the functions you have been provided with.  The current date and time is %{current_date_time}.  Only respond to the last question, using the prior information as context, if appropriate."}:Hash)
lib/i18n/i18n_interpolation_keys_finder.rb:6:in `find'
app/controllers/admin/site_texts_controller.rb:183:in `record_for'
app/controllers/admin/site_texts_controller.rb:249:in `block in find_translations'
app/controllers/admin/site_texts_controller.rb:234:in `each'
app/controllers/admin/site_texts_controller.rb:234:in `find_translations'
app/controllers/admin/site_texts_controller.rb:34:in `index'
app/controllers/application_controller.rb:422:in `block in with_resolved_locale'
app/controllers/application_controller.rb:422:in `with_resolved_locale'
lib/middleware/omniauth_bypass_middleware.rb:64:in `call'
lib/content_security_policy/middleware.rb:12:in `call'
lib/middleware/anonymous_cache.rb:389:in `call'
lib/middleware/gtm_script_nonce_injector.rb:10:in `call'
config/initializers/100-quiet_logger.rb:20:in `call'
config/initializers/100-silence_logger.rb:29:in `call'
lib/middleware/enforce_hostname.rb:24:in `call'
lib/middleware/request_tracker.rb:233:in `call'

Речь идёт о следующем файле локализации:

Не делаю ли я что-то запрещённое?

3 лайка

ок

похоже, что рассматриваемый метод ожидает текст:

но каким-то образом получает хэш:

irb(main):001:0> item = {:basic=>"You are a helpful assistant.", :agent=>"You are a helpful assistant.  You have great tools in the form of functions that give you the power to get newer information. Only use the functions you have been provided with.  The current date and time is %{current_date_time}.  Only respond to the last question, using the prior information as context, if appropriate."}
=>
{:basic=>"You are a helpful assistant.",
...
irb(main):002:0> item
=>
{:basic=>"You are a helpful assistant.",
 :agent=>
  "You are a helpful assistant.  You have great tools in the form of functions that give you the power to get newer information. Only use the functions you have been provided with.  The current date and time is %{current_date_time}.  Only respond to the last question, using the prior information as context, if appropriate."}
irb(main):003:0> item.scan
(irb):3:in `<main>': undefined method `scan' for {:basic=>"You are a helpful assistant.", :agent=>"You are a helpful assistant.  You have great tools in the form of functions that give you the power to get newer information. Only use the functions you have been provided with.  The current date and time is %{current_date_time}.  Only respond to the last question, using the prior information as context, if appropriate."}:Hash (NoMethodError)
        from /home/robert/.rbenv/versions/3.2.1/lib/ruby/gems/3.2.0/gems/irb-1.6.2/exe/irb:11:in `<top (required)>'
        from /home/robert/.rbenv/versions/3.2.1/bin/irb:25:in `load'
        from /home/robert/.rbenv/versions/3.2.1/bin/irb:25:in `<main>'
irb(main):004:0>

из-за чего происходит сбой… Я продолжу расследование

Полагаю, вызов происходит отсюда:

Я могу воспроизвести проблему с помощью:

I18nInterpolationKeysFinder.find(I18n.overrides_disabled { I18n.t("chatbot.prompt.system.", locale: :en) })
в консоли rails.

Думаю, эта строка должна предотвращать передачу методам хэша, но почему-то не работает, почему?:

1 лайк

Переношу это в bug, так как считаю, что такое поведение некорректно и по какой-то причине ненадёжно.

Согласно коду, если значение является Hash, оно не должно передаваться в метод record_for (где это вызвало бы исключение, так как метод ожидает текст), но в некоторых случаях это происходит.

Готов признать свою ошибку, если я неправ.

1 лайк

Это происходит, когда существует переопределение перевода для ключа, который ранее был переводимой строкой, но позже был преобразован в хэш. Именно это произошло с chatbot.prompt.system.

Кажется, это регрессия. Я почти уверен, что раньше это работало.

Я могу легко воспроизвести это с помощью файла локализации, подобного этому:

en:
  foo: "this is foo"

Перейдите в Настройки —> Текст и переопределите значение “foo” на другое.

Затем измените файл локализации так:

en:
  foo:
    basic: "Basic Foo"
    advanced: "Advanced Foo"

Снова откройте Настройки —> Текст и выполните поиск по “foo”. Discourse запишет следующую ошибку:

NoMethodError (undefined method `scan' for {:basic=>"Basic Foo", :advanced=>"Advanced Foo"}:Hash)
lib/i18n/i18n_interpolation_keys_finder.rb:6:in `find'
app/controllers/admin/site_texts_controller.rb:183:in `record_for'
app/controllers/admin/site_texts_controller.rb:249:in `block in find_translations'
app/controllers/admin/site_texts_controller.rb:234:in `each'
app/controllers/admin/site_texts_controller.rb:234:in `find_translations'
app/controllers/admin/site_texts_controller.rb:34:in `index'

Discourse не должен загружать переопределения переводов, если нет соответствующей английской строки.

4 лайка

Спасибо @gerhard

Именно так и произошло: я добавил еще один финальный ключ в тот же бакет.

… И это не влияет на новые установки.

Есть ли какое-то решение через rails console?

1 лайк
TranslationOverride.where(translation_key: "chatbot.prompt.system").delete_all
TranslationOverride.send(:reload_locale!)
5 лайков

Пеееееерфектно. Да, я собирался это попробовать, но не за :laptop:

Кажется, можно добавить это в миграцию?!

2 лайка

Я считаю, что этот баг также был исправлен вместе с этим: :tada:

2 лайка