diff --git a/crates/openplotva-app/src/python_sandbox.rs b/crates/openplotva-app/src/python_sandbox.rs index ddf2c685..93d19f6a 100644 --- a/crates/openplotva-app/src/python_sandbox.rs +++ b/crates/openplotva-app/src/python_sandbox.rs @@ -318,7 +318,8 @@ struct DeliveryOutcome { report: DeliveryReport, /// Named files left unsent because the script failed. skipped: Vec, - /// Files a run with withheld delivery would have sent. + /// Files a run with withheld delivery would have sent. The model reads + /// them as received, so a test dialog continues as a real chat would. withheld: Vec, /// Changed files left unsent because there were too many to send unasked. unselected: usize, @@ -501,10 +502,15 @@ fn run_result(response: &RunResponse, inputs: Vec, outcome: DeliveryOutc let (code, reason) = match (response.termination, response.exit_code) { (Termination::Exited, Some(0)) if report.errors.is_empty() => { - let message = if !report.sent.is_empty() { + let received = if report.sent.is_empty() { + &withheld + } else { + &report.sent + }; + let message = if !received.is_empty() { format!( "The script finished; the chat received {}.", - report.sent.join(", ") + received.join(", ") ) } else if unselected > 0 { format!( @@ -1294,6 +1300,10 @@ mod tests { assert_eq!(result.status, TOOL_RESULT_STATUS_OK); assert!(delivery.delivered.lock().expect("delivered").is_empty()); + assert_eq!( + result.message, + "The script finished; the chat received chart.png." + ); let data = result.data.expect("data"); assert_eq!(data["send_withheld"], json!(["chart.png"])); assert!(data.get("sent").is_none()); diff --git a/prompts/aifarm/system.prompt b/prompts/aifarm/system.prompt index 0e5c0627..b811c8ab 100644 --- a/prompts/aifarm/system.prompt +++ b/prompts/aifarm/system.prompt @@ -9,7 +9,7 @@ В случайном включении можно поставить реакцию или вызвать finish_turn без текста. При прямом обращении ответь или уточни. Команды и разговорные шорткаты задают намерение пользователя: выполни соответствующее действие через инструмент. Прямая просьба нарисовать, сгенерировать, переделать или отредактировать изображение требует вызова draw_image (draw_api для %). Не заменяй действие рассуждением, описанием, обещанием или вопросом «начать?». По известному запросу сразу вызови инструмент; уточняй только недостающую деталь, без которой результат нельзя получить. Обычное рисование не требует предварительного get_user_status: исполнитель сам проверит доступ и лимиты. Действующие ограничения контента и результат инструмента сохраняют силу. - Графики, диаграммы, схемы и планы по данным или размерам, таблицы, конвертацию файлов, обработку аудио и видео и точные расчёты делай через run_python: draw_image рисует иллюстрации, а не данные. Чтобы поправить прежний результат run_python, возьми его код из истории и измени только то, о чём просят. + Графики, диаграммы, схемы и планы по данным или размерам, таблицы, конвертацию файлов, обработку аудио и видео и точные расчёты делай через run_python: draw_image рисует иллюстрации, а не данные. Заголовки, подписи и текст на графиках пиши на языке собеседника. Чтобы поправить прежний результат run_python, возьми его код из истории и измени только то, о чём просят. Для draw_image и draw_api всегда передавай caption: короткое название запрошенного изображения на языке пользователя. Убери обращение к боту, просьбу рисовать и слова вежливости. Сохрани смысл, имена и детали пользователя; название оформи естественно, с заглавной буквы. «Плотва, нарисуй собаквака» → caption «Собака-квака»; «Плотва, а нарисуй же мне, пожалуйста, золотую рыбку в кляре» → caption «Золотая рыбка в кляре». В prompt передавай отдельные, при необходимости обогащённые инструкции генератору. Не добавляй в caption придуманные для генератора детали и технический промпт. Если вызов вернул image_caption_required, добавь подпись и повтори вызов: генерация ещё не началась.