Skip to main content
Glama

Логика переходов опроса

update_quiz_logic

Сохраняет логические условия опроса: условные переходы между виджетами, переходы по умолчанию, логику по баллам (score). Новый формат: score-правила идут в savedLogic как обычные группы с condition.score=true; legacy savedScoring сохраняется только для backward compatibility. group.actionType ∈ {"jump","screenout","show","hide"} ("show"/"hide" — логика видимости: jumpTo указывает виджет, который показывается или скрывается, а не следующий шаг маршрута; дополнительные цели — в visibilityActions). defaultConditions разрежен: запись нужна только там, где переход отличается от следующего вопроса по порядку. Все идентификаторы виджетов (widget_id, widgetId, jumpTo и т.д.) — те же уникальные UUID, что в quiz://{id}/structure (поле ids или ids внутри child-элементов inline_group). Перед вызовом прочитайте quiz://{id}/structure и используйте id без изменений. Обновление частичное: переданная карта заменяет одноимённую целиком (пустой объект очищает её), не переданные карты остаются как были. Служебные ключи conditions ведёт бэкенд: isQuota выводится из наличия групп дисквалификации по квоте, defaultConditionsVersion=2 проставляется при передаче defaultConditions — присылать их не нужно и нельзя. Валидация: проверка существования виджетов, корректности операторов, отсутствия циклов и тупиков в маршруте. Блокируют сохранение также противоречивые действия внутри одной группы: показ и скрытие одного вопроса, переход на вопрос, который эта же группа скрывает, и изменение видимости уже пройденного вопроса. В поле warnings возвращаются переходы назад, вопросы без входящих путей, правила-дубли перехода по умолчанию, условия по ответу вопроса ниже по порядку, порядок carry-forward и риски случайной сортировки вопросов — сохранению они не мешают.

Input Schema

NameRequiredDescriptionDefault
quiz_idYesID опроса для обновления логики.
savedLogicNoУсловные переходы (включая score-логику в новом формате). Ключ — UUID виджета-источника (из structure ids). Значение — ВСЕГДА массив групп, даже если группа одна: [{ conditionGroupId, actionType, jumpTo (UUID или { widgetId, type }), conditionsData[] }]. Группа объектом вместо массива отклоняется валидацией. Порядок элементов массива сохраняется runtime-ом: группы выполняются сверху вниз. actionType: "jump" (переход; по умолчанию), "screenout" (дисквалификация; jumpTo может отсутствовать — рендерер покажет дефолтный screenout-экран) либо "show"/"hide" (условие показа). Условие показа: в группе с actionType "show"/"hide" jumpTo — это вопрос, который показывается или скрывается, а не следующий шаг маршрута. Чтобы одна группа управляла несколькими вопросами, перечислите их в visibilityActions: [{ "action": "show"|"hide", "targetWidget": { "widgetId": "<UUID>" } }]. Показ и скрытие одного вопроса в одной группе, как и переход на вопрос, который эта же группа скрывает, отклоняются валидацией. Дисквалификация по квоте: группа с actionType "screenout", пустым conditionsData и screenoutConfig = { "mode": "answer_quota", "sourceWidgetId": "<UUID вопроса>", "quotaType": "question_answers" | "answer_option", "quotaLimit": "<число строкой>", "quotaOptionId": "<UUID опции для answer_option>" }. Без screenoutConfig это обычная дисквалификация по ответу. Флаг conditions.isQuota бэкенд выставляет сам по наличию таких групп — передавать его не нужно. Переданная карта savedLogic заменяет прежнюю целиком; не переданные карты сохраняются. Чтобы поправить одно правило, сначала прочитайте conditions из структуры опроса, измените нужную запись и отправьте полную изменённую карту. Пустой объект очищает карту. conditionsData: conditionId, widget (widgetId — UUID), option (id оператора), answer, statement, score, scoreSourceType, scoreSourceWidgetId, extraField, extraFieldName, matrixData, allocationData, semanticDifferentialData, additional_option. Формы answer и операторы по типам вопросов — в описаниях этих полей. Все widgetId/jumpTo — только UUID из quiz://{id}/structure. Пример «если шкала меньше 10 — показать вопрос B»: { "<UUID шкалы>": [{ "conditionGroupId": "g1", "actionType": "show", "jumpTo": { "widgetId": "<UUID вопроса B>" }, "conditionsData": [{ "conditionId": "c1", "widget": { "widgetId": "<UUID шкалы>" }, "option": { "id": 7 }, "answer": { "label": "10", "optionId": "10" }, "statement": { "signature": "" } }] }] }. Условия по скрытым переменным опроса: пометьте condition как extraField=true и укажите extraFieldName — имя переменной из extra_fields (см. quiz://{id}/structure). Виджет у такого условия остаётся якорем группы, сравнивается значение переменной. Допустимые операторы: 1,2,3,4,5,6,7,8,9,10 (сравнение значения) и 27/28 (факт передачи, answer не нужен). statement.signature — связка условия со СЛЕДУЮЩИМ условием группы: "AND" | "OR" | "". Для «A И B» у A стоит "AND", у B — пустая строка; у последнего условия связка пустая. score-условия: если condition.score=true — runtime сравнивает не ответ пользователя, а totalScore. Допустимы только числовые операторы (option.id ∈ {1,2,7,8,9,10}); answer.label/answer.optionId содержат строковое представление порога (например "8"). Для нового контента отдавайте score-правила сюда, в savedLogic, а не в savedScoring. Источник значения для score-условия задаётся парой scoreSourceType/scoreSourceWidgetId (оба поля опциональны — при их отсутствии runtime трактует условие как "survey"): - scoreSourceType="survey", scoreSourceWidgetId=null — сумма по всему опросу (также трактуется runtime-ом при отсутствии обоих полей — backward compat); - scoreSourceType="widget", scoreSourceWidgetId=<UUID> — сумма по конкретному widget. UUID может указывать как на обычный scoring-виджет, так и на inline_group (runtime просуммирует scoring-enabled детей) или на ребёнка inline_group. Берите UUID из quiz://{id}/structure (вкл. groupWidgets.ids у inline_group). allocation_slider условия: если condition.widget.widgetId указывает на виджет allocation_slider — в условие нужно добавить allocationData.optionId (UUID опции-слайдера из allocationSliderIds), значение которой runtime сравнит с answer.optionId (числовой порог в виде строки). Поле обязательно для операторов 1,2,7,8,9,10,11; для специального оператора hard_to_answer (23) allocationData не используется. Справочник операторов option.id: 1 — равно; 2 — не равно (форма значения зависит от вопроса). 3 — начинается с; 4 — заканчивается на; 5 — содержит; 6 — не содержит (строковое сравнение; для обычного выбора 5/6 не предлагаются и не срабатывают — используйте 1/2). 7 — меньше; 8 — меньше или равно; 9 — больше; 10 — больше или равно (числовое сравнение). 11 — любой ответ (answer не нужен). 12 — файл загружен; 13 — файл не загружен (legacy: конструктор для file пишет оператор 1 с answer.optionId "12" или "13"). 14 — дата раньше; 15 — дата позже; 16 — дата раньше или в этот день; 17 — дата позже или в этот день (datetime). 18 — ячейка отмечена; 19 — ячейка не отмечена (matrix, нужен matrixData.row/col). 20 — позиция в ранжировании равна; 21 — позиция выше (номер меньше); 22 — позиция ниже (номер больше) (ranking, нужен additional_option). 23 — затрудняюсь ответить (нужен hardToAnswer=true у вопроса; answer не нужен). 24 — ни один из вариантов (нужен noneOfAbove=true у dropdown или текстового choice; answer не нужен). 25 — увидел вариант A/B-теста; 26 — не увидел вариант A/B-теста (нужен abEnabled=true; answer.optionId — ID варианта из abVariantIds, а не вариант ответа). 27 — скрытая переменная передана; 28 — скрытая переменная не передана (только extraField=true + extraFieldName; answer не нужен).
savedScoringNoLegacy-формат переходов по баллам: UUID вопроса → ID score-условия → {score,jumpTo,inCase,inCaseMeaning}. Служебные ключи: scoringEnabledWidgets, correctAnswers, scoringSwitcher. Для новых правил используйте savedLogic с condition.score:true. Это не описание назначения баллов вариантам ответа. Переданная карта заменяет прежнюю целиком.
multiLogicFlagsNoФлаги мульти-логики: ключ — UUID виджета (из structure ids), значение boolean. true — несколько групп условий в savedLogic.
defaultConditionsNoПереходы по умолчанию — РАЗРЕЖЕННАЯ карта: запись есть только там, где респондента надо увести не на следующий вопрос. Отсутствие записи и означает «След. шаг (по умолчанию)», поэтому НЕ заполняйте карту подряд и не пишите в неё следующий по порядку вопрос: такая запись ничего не меняет сейчас и ломает маршрут после вставки или перестановки вопросов. Ключ — UUID виджета-источника (из quiz structure ids), значение — { "widgetId": "<UUID цели>", "type": "<тип>" } или строка widgetId. Цель "submit" — финальный экран. Используйте только UUID из quiz://{id}/structure.
savedInlineGroupLogicNoЛогика ВНУТРИ inline-группы. Ключ — UUID самой inline-группы (из structure ids), значение — массив групп условий. Форма группы здесь ДРУГАЯ, чем у savedLogic: маршрута внутри группы нет — все её вопросы показываются на одном экране, — поэтому нет ни actionType, ни jumpTo. Группа выглядит так: { conditionGroupId, actions: [{ "action": "show"|"hide", "targetWidget": { "widgetId": "<UUID ребёнка группы>" } }], conditionsData: [ … ] }. Условия — той же формы, что в savedLogic, но widgetId ссылаются на детей группы. ID детей берите из groupWidgets.ids в quiz://{id}/structure.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed32 schema fields changed
    • changedInput schema / properties / defaultConditions / description
      Previous value: -"Переходы по умолчанию по widget_id."New value: +"Переходы по умолчанию — РАЗРЕЖЕННАЯ карта: запись есть только там, где респондента надо увести не на следующий вопрос. Отсутствие записи и означает «След. шаг (по умолчанию)», поэтому НЕ заполняйте карту подряд и не пишите в неё следующий по порядку вопрос: такая запись ничего не меняет сейчас и ломает маршрут после вставки или перестановки вопросов. Ключ — UUID виджета-источника (из quiz structure ids), значение — { \"widgetId\": \"<UUID цели>\", \"type\": \"<тип>\" } или строка widgetId. Цель \"submit\" — финальный экран. Используйте только UUID из quiz://{id}/structure."
    • changedInput schema / properties / multiLogicFlags / description
      Previous value: -"Флаги мульти-логики: {widget_id: boolean}."New value: +"Флаги мульти-логики: ключ — UUID виджета (из structure ids), значение boolean. true — несколько групп условий в savedLogic."
    • addedInput schema / properties / savedInlineGroupLogic / additionalProperties / items / properties / actions / description
      Added value: +"Показ и скрытие вопросов группы: [{ \"action\": \"show\"|\"hide\", \"targetWidget\": { \"widgetId\": \"<UUID ребёнка группы>\" } }]."
    • addedInput schema / properties / savedInlineGroupLogic / additionalProperties / items / properties / conditionGroupId / description
      Added value: +"Уникальный ID группы условий (любая строка, например UUID)."
    • addedInput schema / properties / savedInlineGroupLogic / additionalProperties / items / properties / conditionsData / description
      Added value: +"Условия той же формы, что в savedLogic; widgetId — дети группы (groupWidgets.ids)."
    • changedInput schema / properties / savedInlineGroupLogic / description
      Previous value: -"Показ и скрытие вопросов внутри inline-группы, по widget_id самой группы: [{ conditionGroupId, actions: [{action: \"show\"|\"hide\", targetWidget: {widgetId}}], conditionsData: [...] }]. Без actionType и jumpTo — маршрута внутри группы нет."New value: +"Логика ВНУТРИ inline-группы. Ключ — UUID самой inline-группы (из structure ids), значение — массив групп условий. Форма группы здесь ДРУГАЯ, чем у savedLogic: маршрута внутри группы нет — все её вопросы показываются на одном экране, — поэтому нет ни actionType, ни jumpTo. Группа выглядит так: { conditionGroupId, actions: [{ \"action\": \"show\"|\"hide\", \"targetWidget\": { \"widgetId\": \"<UUID ребёнка группы>\" } }], conditionsData: [ … ] }. Условия — той же формы, что в savedLogic, но widgetId ссылаются на детей группы. ID детей берите из groupWidgets.ids в quiz://{id}/structure."
    • addedInput schema / properties / savedLogic / additionalProperties / items / properties / actionType / description
      Added value: +"Действие группы: \"jump\" (по умолчанию) — переход на jumpTo; \"screenout\" — дисквалификация (jumpTo можно не указывать); \"show\"/\"hide\" — показать или скрыть вопрос jumpTo."
    • addedInput schema / properties / savedLogic / additionalProperties / items / properties / conditionGroupId / description
      Added value: +"Уникальный ID группы условий (любая строка, например UUID)."
    • addedInput schema / properties / savedLogic / additionalProperties / items / properties / conditionsData / description
      Added value: +"Условия группы. Связка каждого условия (statement.signature) соединяет его со следующим."
    • addedInput schema / properties / savedLogic / additionalProperties / items / properties / conditionsData / items / properties / additional_option
      Added value: +{
      +  "description": "Только ranking: позиция { id: номер позиции с нуля, label: номер для показа с единицы }, например { \"id\": 0, \"label\": 1 } — первое место.",
      +  "properties": {
      +    "id": {
      +      "type": "integer"
      +    },
      +    "label": {
      +      "type": [
      +        "integer",
      +        "string"
      +      ]
      +    }
      +  },
      +  "type": "object"
      +}
    • addedInput schema / properties / savedLogic / additionalProperties / items / properties / conditionsData / items / properties / allocationData / description
      Added value: +"Только allocation_slider: { optionId: UUID слайдера из allocationSliderIds }. Его значение сравнивается с порогом answer.optionId."
    • addedInput schema / properties / savedLogic / additionalProperties / items / properties / conditionsData / items / properties / answer / description
      Added value: +"С чем сравнивать. Поля строковые; рантайм берёт answer.optionId, а если он пуст — answer.label.\nВыбор, список, да/нет, matrix_3d: optionId — UUID варианта из структуры (подпись вместо UUID не сработает), label — подпись для показа. Вариант «Другое» — optionId \"other\". area_select: optionId — UUID области из areaSelectIds.\npair, pair_manual: optionId \"<pairId>::<ID элемента пары>\". У pair pairId — \"<ID>__<ID>\" двух элементов из pairItemIds в порядке их следования, вторая часть — один из этих ID, например \"a__b::a\". У pair_manual pairId — из pairIds, вторая часть — \"left\" или \"right\".\nЧисло, шкала, рейтинг, NPS, слайдер: порог строкой в label и optionId — «меньше 10»: option.id=7, answer={\"label\":\"10\",\"optionId\":\"10\"}. click_test, area_highlight, map: так же, порог — число отметок строкой.\nТекстовые поля (3–6, 1/2): строка в label и optionId, с учётом регистра.\ndatetime: дата строкой \"ДД - ММ - ГГГГ\" в label и optionId, например \"05 - 03 - 2008\" (ISO-формат конструктор не использует).\nranking: optionId — UUID ранжируемого варианта; позиция — в additional_option.\nfile: при операторе 1 optionId \"12\" (загружен) или \"13\" (не загружен). payment: optionId \"paid\" или \"unpaid\".\nallocation_slider: порог в optionId, слайдер — в allocationData.optionId. semantic_differential: число строкой в optionId, строка — в semanticDifferentialData.row.\nscore=true: порог баллов строкой. A/B 25/26: optionId — ID показанного варианта из abVariantIds. extraField=true: значение переменной для 1–10.\nОператорам 11, 23, 24, 27, 28 answer не нужен — можно не передавать или передать пустым."
    • addedInput schema / properties / savedLogic / additionalProperties / items / properties / conditionsData / items / properties / conditionId / description
      Added value: +"Уникальный ID условия (любая строка, например UUID)."
    • addedInput schema / properties / savedLogic / additionalProperties / items / properties / conditionsData / items / properties / extraField / description
      Added value: +"true — условие сравнивает скрытую переменную опроса, а не ответ. Операторы 1–10 и 27/28."
    • addedInput schema / properties / savedLogic / additionalProperties / items / properties / conditionsData / items / properties / extraFieldName / description
      Added value: +"Имя скрытой переменной из extra_fields опроса (quiz://{id}/structure). Обязательно при extraField=true."
    • addedInput schema / properties / savedLogic / additionalProperties / items / properties / conditionsData / items / properties / matrixData / description
      Added value: +"Ячейка матрицы: { row: UUID из matrixRowIds, col: UUID из matrixColIds }. Обязательна для 18/19 у matrix и 1/2 у matrix_3d (у matrix_3d вариант ячейки — в answer.optionId)."
    • addedInput schema / properties / savedLogic / additionalProperties / items / properties / conditionsData / items / properties / option / description
      Added value: +"Оператор сравнения: { id, label }. label — необязательный ключ подписи конструктора."
    • addedInput schema / properties / savedLogic / additionalProperties / items / properties / conditionsData / items / properties / option / properties / id / description
      Added value: +"ID оператора 1–28.\nСправочник операторов option.id:\n1 — равно; 2 — не равно (форма значения зависит от вопроса).\n3 — начинается с; 4 — заканчивается на; 5 — содержит; 6 — не содержит (строковое сравнение; для обычного выбора 5/6 не предлагаются и не срабатывают — используйте 1/2).\n7 — меньше; 8 — меньше или равно; 9 — больше; 10 — больше или равно (числовое сравнение).\n11 — любой ответ (answer не нужен).\n12 — файл загружен; 13 — файл не загружен (legacy: конструктор для file пишет оператор 1 с answer.optionId \"12\" или \"13\").\n14 — дата раньше; 15 — дата позже; 16 — дата раньше или в этот день; 17 — дата позже или в этот день (datetime).\n18 — ячейка отмечена; 19 — ячейка не отмечена (matrix, нужен matrixData.row/col).\n20 — позиция в ранжировании равна; 21 — позиция выше (номер меньше); 22 — позиция ниже (номер больше) (ranking, нужен additional_option).\n23 — затрудняюсь ответить (нужен hardToAnswer=true у вопроса; answer не нужен).\n24 — ни один из вариантов (нужен noneOfAbove=true у dropdown или текстового choice; answer не нужен).\n25 — увидел вариант A/B-теста; 26 — не увидел вариант A/B-теста (нужен abEnabled=true; answer.optionId — ID варианта из abVariantIds, а не вариант ответа).\n27 — скрытая переменная передана; 28 — скрытая переменная не передана (только extraField=true + extraFieldName; answer не нужен).\nОператоры для нового правила по типу вопроса (набор конструктора; у старых правил встречаются и другие — сохранение их не отклоняет):\nchoice, choiceSingle, choiceMultiple, dropdown, yesno, area_select — 1, 2, 11;\ninput, fio, email, phone — 1, 2, 3, 4, 5, 6, 11;\nnumber, slider, rating, scale, nps, smile-rating, semantic_differential, allocation_slider — 1, 2, 7, 8, 9, 10, 11;\ndatetime — 1, 2, 14, 15, 16, 17;\nmatrix — 18, 19; matrix_3d — 1, 2, 11; ranking — 20, 21, 22;\npair — 11; pair_manual, file — 1, 11;\nclick_test, area_highlight, map — 1, 2, 7, 8, 9, 10, 11 (по числу отметок);\npayment — 1; inline_group — 11; message, html — операторов нет.\ncondition.score=true — 1, 2, 7, 8, 9, 10 (сравниваются баллы, не ответ); condition.extraField=true — 1–10, 27, 28 (сравнивается переменная).\nДополнительно: 23 — при hardToAnswer=true (кроме inline_group и allocation_slider), 24 — при noneOfAbove=true, 25/26 — при abEnabled=true."
    • addedInput schema / properties / savedLogic / additionalProperties / items / properties / conditionsData / items / properties / score / description
      Added value: +"true — условие сравнивает накопленные баллы, а не ответ. Операторы 1, 2, 7, 8, 9, 10; порог — строкой в answer."
    • addedInput schema / properties / savedLogic / additionalProperties / items / properties / conditionsData / items / properties / scoreSourceType / description
      Added value: +"Источник баллов: \"survey\" — сумма по опросу (scoreSourceWidgetId=null), \"widget\" — по вопросу scoreSourceWidgetId. Без поля — \"survey\"."
    • addedInput schema / properties / savedLogic / additionalProperties / items / properties / conditionsData / items / properties / scoreSourceWidgetId / description
      Added value: +"UUID вопроса-источника баллов при scoreSourceType=\"widget\" (можно inline_group или её ребёнка); null при \"survey\"."
    • addedInput schema / properties / savedLogic / additionalProperties / items / properties / conditionsData / items / properties / semanticDifferentialData / description
      Added value: +"Только semantic_differential: { row: UUID строки из semanticDifferentialIds }. Её значение сравнивается с answer.optionId."
    • addedInput schema / properties / savedLogic / additionalProperties / items / properties / conditionsData / items / properties / statement / description
      Added value: +"Связка условия со следующим условием группы."
    • addedInput schema / properties / savedLogic / additionalProperties / items / properties / conditionsData / items / properties / statement / properties / signature / description
      Added value: +"Связка соединяет это условие со СЛЕДУЮЩИМ условием группы: \"AND\" | \"OR\" | \"\". Для «A И B» у A стоит \"AND\", у B — пустая строка. У последнего условия связка пустая. Инструмент исправляет распознанный обратный порядок и возвращает предупреждение."
    • addedInput schema / properties / savedLogic / additionalProperties / items / properties / conditionsData / items / properties / widget / description
      Added value: +"Вопрос, на ответ которого смотрит условие."
    • addedInput schema / properties / savedLogic / additionalProperties / items / properties / conditionsData / items / properties / widget / properties / widgetId / description
      Added value: +"UUID вопроса из quiz://{id}/structure. У условия по скрытой переменной — якорь группы."
    • addedInput schema / properties / savedLogic / additionalProperties / items / properties / jumpTo / description
      Added value: +"UUID цели строкой или { widgetId, type }. Для \"jump\" — следующий шаг маршрута (\"submit\" — финал); для \"show\"/\"hide\" — вопрос, который показывается или скрывается; для \"screenout\" — экран отсева, необязательно."
    • addedInput schema / properties / savedLogic / additionalProperties / items / properties / logicType / description
      Added value: +"Пометка конструктора: \"routing\" — маршрут, \"visibility\" — показ/скрытие. Необязательно."
    • addedInput schema / properties / savedLogic / additionalProperties / items / properties / screenoutConfig / description
      Added value: +"Дисквалификация по квоте: { mode: \"answer_quota\", sourceWidgetId, quotaType: \"question_answers\"|\"answer_option\", quotaLimit: \"<число строкой>\", quotaOptionId } при пустом conditionsData. Без него screenout — обычная дисквалификация по ответу."
    • addedInput schema / properties / savedLogic / additionalProperties / items / properties / visibilityActions / description
      Added value: +"Дополнительные цели показа/скрытия сверх jumpTo: [{ \"action\": \"show\"|\"hide\", \"targetWidget\": { \"widgetId\": \"<UUID>\" } }]."
    • changedInput schema / properties / savedLogic / description
      Previous value: -"Группы условий переходов по widget_id (включая score-правила: condition.score=true, операторы 1/2/7/8/9/10, answer.optionId — порог totalScore). group.actionType: \"jump\" или \"screenout\". Источник баллов — пара condition.scoreSourceType (\"survey\" | \"widget\") и condition.scoreSourceWidgetId (UUID при \"widget\", null при \"survey\"). Отсутствие обоих полей = legacy \"survey\". Для условий на allocation_slider передайте allocationData.optionId — UUID из allocationSliderIds виджета; runtime сравнит значение этой опции с answer.optionId."New value: +"Условные переходы (включая score-логику в новом формате). Ключ — UUID виджета-источника (из structure ids). Значение — ВСЕГДА массив групп, даже если группа одна: [{ conditionGroupId, actionType, jumpTo (UUID или { widgetId, type }), conditionsData[] }]. Группа объектом вместо массива отклоняется валидацией. Порядок элементов массива сохраняется runtime-ом: группы выполняются сверху вниз.\nactionType: \"jump\" (переход; по умолчанию), \"screenout\" (дисквалификация; jumpTo может отсутствовать — рендерер покажет дефолтный screenout-экран) либо \"show\"/\"hide\" (условие показа).\nУсловие показа: в группе с actionType \"show\"/\"hide\" jumpTo — это вопрос, который показывается или скрывается, а не следующий шаг маршрута. Чтобы одна группа управляла несколькими вопросами, перечислите их в visibilityActions: [{ \"action\": \"show\"|\"hide\", \"targetWidget\": { \"widgetId\": \"<UUID>\" } }]. Показ и скрытие одного вопроса в одной группе, как и переход на вопрос, который эта же группа скрывает, отклоняются валидацией.\nДисквалификация по квоте: группа с actionType \"screenout\", пустым conditionsData и screenoutConfig = { \"mode\": \"answer_quota\", \"sourceWidgetId\": \"<UUID вопроса>\", \"quotaType\": \"question_answers\" | \"answer_option\", \"quotaLimit\": \"<число строкой>\", \"quotaOptionId\": \"<UUID опции для answer_option>\" }. Без screenoutConfig это обычная дисквалификация по ответу. Флаг conditions.isQuota бэкенд выставляет сам по наличию таких групп — передавать его не нужно.\nПереданная карта savedLogic заменяет прежнюю целиком; не переданные карты сохраняются. Чтобы поправить одно правило, сначала прочитайте conditions из структуры опроса, измените нужную запись и отправьте полную изменённую карту. Пустой объект очищает карту.\nconditionsData: conditionId, widget (widgetId — UUID), option (id оператора), answer, statement, score, scoreSourceType, scoreSourceWidgetId, extraField, extraFieldName, matrixData, allocationData, semanticDifferentialData, additional_option. Формы answer и операторы по типам вопросов — в описаниях этих полей.\nВсе widgetId/jumpTo — только UUID из quiz://{id}/structure.\nПример «если шкала меньше 10 — показать вопрос B»: { \"<UUID шкалы>\": [{ \"conditionGroupId\": \"g1\", \"actionType\": \"show\", \"jumpTo\": { \"widgetId\": \"<UUID вопроса B>\" }, \"conditionsData\": [{ \"conditionId\": \"c1\", \"widget\": { \"widgetId\": \"<UUID шкалы>\" }, \"option\": { \"id\": 7 }, \"answer\": { \"label\": \"10\", \"optionId\": \"10\" }, \"statement\": { \"signature\": \"\" } }] }] }.\nУсловия по скрытым переменным опроса: пометьте condition как extraField=true и укажите extraFieldName — имя переменной из extra_fields (см. quiz://{id}/structure). Виджет у такого условия остаётся якорем группы, сравнивается значение переменной. Допустимые операторы: 1,2,3,4,5,6,7,8,9,10 (сравнение значения) и 27/28 (факт передачи, answer не нужен).\nstatement.signature — связка условия со СЛЕДУЮЩИМ условием группы: \"AND\" | \"OR\" | \"\". Для «A И B» у A стоит \"AND\", у B — пустая строка; у последнего условия связка пустая.\nscore-условия: если condition.score=true — runtime сравнивает не ответ пользователя, а totalScore. Допустимы только числовые операторы (option.id ∈ {1,2,7,8,9,10}); answer.label/answer.optionId содержат строковое представление порога (например \"8\"). Для нового контента отдавайте score-правила сюда, в savedLogic, а не в savedScoring.\nИсточник значения для score-условия задаётся парой scoreSourceType/scoreSourceWidgetId (оба поля опциональны — при их отсутствии runtime трактует условие как \"survey\"):\n- scoreSourceType=\"survey\", scoreSourceWidgetId=null — сумма по всему опросу (также трактуется runtime-ом при отсутствии обоих полей — backward compat);\n- scoreSourceType=\"widget\", scoreSourceWidgetId=<UUID> — сумма по конкретному widget. UUID может указывать как на обычный scoring-виджет, так и на inline_group (runtime просуммирует scoring-enabled детей) или на ребёнка inline_group. Берите UUID из quiz://{id}/structure (вкл. groupWidgets.ids у inline_group).\nallocation_slider условия: если condition.widget.widgetId указывает на виджет allocation_slider — в условие нужно добавить allocationData.optionId (UUID опции-слайдера из allocationSliderIds), значение которой runtime сравнит с answer.optionId (числовой порог в виде строки). Поле обязательно для операторов 1,2,7,8,9,10,11; для специального оператора hard_to_answer (23) allocationData не используется.\nСправочник операторов option.id:\n1 — равно; 2 — не равно (форма значения зависит от вопроса).\n3 — начинается с; 4 — заканчивается на; 5 — содержит; 6 — не содержит (строковое сравнение; для обычного выбора 5/6 не предлагаются и не срабатывают — используйте 1/2).\n7 — меньше; 8 — меньше или равно; 9 — больше; 10 — больше или равно (числовое сравнение).\n11 — любой ответ (answer не нужен).\n12 — файл загружен; 13 — файл не загружен (legacy: конструктор для file пишет оператор 1 с answer.optionId \"12\" или \"13\").\n14 — дата раньше; 15 — дата позже; 16 — дата раньше или в этот день; 17 — дата позже или в этот день (datetime).\n18 — ячейка отмечена; 19 — ячейка не отмечена (matrix, нужен matrixData.row/col).\n20 — позиция в ранжировании равна; 21 — позиция выше (номер меньше); 22 — позиция ниже (номер больше) (ranking, нужен additional_option).\n23 — затрудняюсь ответить (нужен hardToAnswer=true у вопроса; answer не нужен).\n24 — ни один из вариантов (нужен noneOfAbove=true у dropdown или текстового choice; answer не нужен).\n25 — увидел вариант A/B-теста; 26 — не увидел вариант A/B-теста (нужен abEnabled=true; answer.optionId — ID варианта из abVariantIds, а не вариант ответа).\n27 — скрытая переменная передана; 28 — скрытая переменная не передана (только extraField=true + extraFieldName; answer не нужен)."
    • changedInput schema / properties / savedScoring / description
      Previous value: -"Legacy-формат переходов по scoring (для backward compatibility). По ключам widget_id — объекты scoreConditionId→{score,jumpTo,inCase,inCaseMeaning}. Глобальные ключи: scoringEnabledWidgets, correctAnswers, scoringSwitcher. Для нового контента используйте savedLogic + score:true."New value: +"Legacy-формат переходов по баллам: UUID вопроса → ID score-условия → {score,jumpTo,inCase,inCaseMeaning}. Служебные ключи: scoringEnabledWidgets, correctAnswers, scoringSwitcher. Для новых правил используйте savedLogic с condition.score:true. Это не описание назначения баллов вариантам ответа. Переданная карта заменяет прежнюю целиком."
  2. First observed

TDQS

A4.1/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations (readOnlyHint=false, destructiveHint=false, idempotentHint=false) establish it's a non-destructive write that is not idempotent. The description adds extensive behavioral context: partial update semantics (passed maps replace entirely, empty object clears), validation and blocking rules, warnings returned, server-managed keys, backward compatibility details, and the need to read structure first. This far exceeds what annotations provide.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness2/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is extremely long and dense, with much of the operator reference duplicated verbatim in the schema's option.id description. While front-loaded with the core purpose, it buries key usage rules under repetitive technical detail. It is not concise — significant redundancy reduces readability and increases cognitive load.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the complexity — 6 parameters, nested objects, no output schema, and strict validation — the description provides complete coverage of all mutation semantics, edge cases, validations, warnings, and references to structure for IDs. An agent has all necessary information to invoke the tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3. The description goes well beyond by explaining the cardinality constraint (value is always an array, even for one group), actionType semantics including show/hide vs jump, visibilityActions, score condition operators and sources, extraField usage, allocation_slider specifics, and sparse defaultConditions. It adds substantial meaning over the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states a specific verb+resource — saving survey logic conditions (conditional jumps, default transitions, score logic). It distinguishes itself from siblings like update_quiz_settings and update_quiz_widgets by focusing on routing logic. However, it does not explicitly name a sibling alternative or contrast its scope with them, keeping it at 4 rather than 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies when to use savedLogic versus savedScoring ('for new content, output score rules here, not in savedScoring'), and instructs reading the structure first. But it does not provide explicit when/when-not guidance or name alternative sibling tools for different update tasks. Usage context is present but not comprehensive.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.

Resources