Alex CubeandClaude Opus 5 97eefb57c7 Первая версия: инструменты и цикл для DeepSeek
DeepSeek через веб-чат видит только то, что человек положил в вопрос. Здесь
у него появляется обратное направление: он возвращает блок-запрос, программа
исполняет его и досылает результат следующим сообщением в тот же чат. Обычный
агентский цикл, только транспорт — текст.

Инструменты (только чтение, только внутри рабочей папки):
  === NEED: путь, путь ===   прислать файлы целиком
  === LIST: **/*.mjs ===     список файлов по маске
  === FIND: текст ===        где встречается, с номерами строк

Запуска команд намеренно нет: исполнять строки из ответа, пришедшего из
интернета, без белого списка и подтверждения нельзя.

Мост ollama_orchestro/ask.mjs не импортируется и не копируется — он разбирает
process.argv и исполняет команду на верхнем уровне, поэтому import немедленно
запустил бы её. Вызывается подпроцессом теми флагами, которые у него уже есть:
шаг 1 без --new (правка первого сообщения), шаги 2..N с --new, иначе DeepSeek
не помнит предыдущий шаг. Взамен orchestro не меняется ни на строку, а его
правки прилетают сюда даром.

Два урока, каждый стоил живого прогона и вписан в код:
- инструкция в начале сообщения не работает. 22 КБ файла между приставкой и
  вопросом — и блоки-запросы игнорируются. Помогает дословное напоминание
  вплотную к вопросу;
- дерево папки надо давать сразу. Без него DeepSeek угадывает имена файлов и
  тратит два круга по минуте на LIST.

Есть веб-пульт (start-deepwork.cmd, бросить папку): файлы галочками, журнал
шагов по ходу, запись правок с копией в backup/.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-11 16:31:33 +03:00

deepwork

Цикл с инструментами поверх моста ollama_orchestro/ask.mjs.

DeepSeek через веб-чат видит только то, что положили ему в вопрос. Здесь у него появляется обратное направление: он возвращает блок-запрос, программа его исполняет и досылает результат следующим сообщением в тот же чат. Обычный агентский цикл, только транспорт — текст.

Как пользоваться

Обычный путь — пульт: бросить папку проекта на start-deepwork.cmd. Откроется страница: файлы галочками, поле вопроса, ход работы построчно, кнопка «Записать» у каждого пришедшего файла.

Пульт открывается в браузере ПО УМОЛЧАНИЮ, а не в отладочном: там он занял бы вкладку, и мост перестал бы видеть DeepSeek. Порт 8787 — рядом с пультом orchestro (8777), оба могут работать разом.

Тот же цикл из консоли:

cd c:\мой\проект
node c:\#Projects\deepwork\deepwork.mjs "вопрос" --files a.js,b.js --apply
node c:\#Projects\deepwork\deepwork.mjs ui        тот же пульт вручную

Работает в текущей папке: её файлы показывает, в неё же пишет правки.

Инструменты

Только чтение и только внутри текущей папки:

Блок в ответе Что делает
=== NEED: путь, путь === прислать файлы целиком
=== LIST: **/*.mjs === список файлов по маске
=== FIND: текст === где встречается текст, с номерами строк

Запуска команд (RUN) нет намеренно: исполнять строки из ответа, пришедшего из интернета, без белого списка и подтверждения нельзя.

Лимиты на результат шага: NEED — 200 000 символов суммарно, FIND — 100 попаданий, LIST — 300 путей. Обрезанное помечается прямо в тексте.

Как устроено

Мост не импортируется и не копируется. ask.mjs разбирает process.argv и исполняет команду на верхнем уровне — import немедленно запустил бы её. Поэтому мост вызывается подпроцессом теми флагами, которые у него уже есть:

node ask.mjs ask --chat think --file step1.txt --out ans1.txt --quiet
node ask.mjs ask --chat think --new --file step2.txt --out ans2.txt --quiet

Шаг 1 идёт без --new: мост правит первое сообщение, и чат остаётся из одного обмена. Шаги 2..N — с --new, обычной отправкой: только так DeepSeek помнит предыдущий шаг. Цена — переподключение к браузеру на каждом шаге, 1–2 секунды. Взамен ollama_orchestro не меняется ни на строку, а его правки прилетают сюда даром.

Чат берётся тот же, что у orchestro (think из его chats.json). Своя роль не заводится: chats.json принадлежит мосту.

Цикл останавливается, когда запросов в ответе нет, когда кончились шаги или когда пришёл тот же самый запрос второй раз подряд (петля).

Настройка

config.json (в репозиторий не попадает, образец — config.example.json):

{ "bridge": "C:/#Projects/ollama_orchestro/ask.mjs", "chat": "think", "steps": 4 }

Без файла мост ищется рядом: ../ollama_orchestro/ask.mjs.

Проверка

node deepwork.mjs --selftest   внутренние проверки, ничего не отправляют
node deepwork.mjs --check      мост на месте, вкладка жива

Браузер должен быть запущен start-browser.cmd из ollama_orchestro — с отладочным портом 9333.

Что проверено

  • --selftest: разбор запросов, отказ пути за пределы папки, маски * и **, снятие тройных кавычек и подписи языка. Строка вида === NEED: … === внутри блока === FILE: === за запрос не принимается — иначе правка файла с описанием формата запускала бы запрос сама.
  • Цикл целиком на заглушке вместо моста: приставка едет в первом сообщении, второй вызов уходит с --new, результаты NEED и FIND доезжают, отступы в записанном файле сохраняются, прежняя версия уходит в backup/.
  • Пропавший файл в NEED возвращает «файла нет» и цикл не роняет.
  • --steps 1 отдаёт ответ с пометкой «шаги кончились», а не зависает.
  • Битый config.json — понятная ошибка, а не молчаливый откат к умолчаниям.

Живые прогоны на DeepSeek, 11.08.2026

Задача одна и та же: из папки ollama_orchestro спросить, где решается, что ответ дописан до конца, дав в вопросе только ui.html — то есть заведомо не тот файл. Правильный ответ (waitForAnswer в ask.mjs) достижим только через инструменты.

Прогон Шагов Что вышло
1. приставка только в начале сообщения 1 запросов нет. «Точный код в серверном файле» и три догадки
2. + напоминание вплотную к вопросу 4 нашёл, но 2 круга ушли на угадывание имён файлов
3. + дерево папки в первом сообщении 2 запросил ask.mjs сразу, ответил по существу

Два вывода, оба стоили живого прогона:

  • Инструкция в начале сообщения не работает. Между приставкой и вопросом легли 22 КБ файла, и DeepSeek инструменты просто не заметил. Помогло дословное повторение перед самим вопросом (TAIL_REMINDER).
  • Дерево папки надо давать сразу. Без него DeepSeek угадывал имена (server.js, bridge.js — таких в проекте нет), потом просил LIST *.js (проект на .mjs, пусто), потом LIST **/*. Дерево — 600 символов против двух кругов по минуте.

Пульт, 11.08.2026

Сквозной прогон через страницу: вопрос без единого приложенного файла — «какая функция решает, что ответ дописан?». 36 секунд, три шага. DeepSeek запросил пятью блоками FIND сразу (waitForAnswer, streaming, done, stop_reason, finish_reason), затем NEED: ask.mjs, и ответил точно: waitForAnswer, строка 675. Журнал шагов обновлялся на странице по ходу.

Обрезанные ответы: причина найдена и устранена в мосте (11.08.2026)

В третьем прогоне ответ оборвался посреди блока кода на // Бы. Оказалось, это не «конец определён раньше времени» и не кнопка Continue.

Браузер работал в фоне. У неактивного окна страница не отрисовывается, а DeepSeek рисует блоки кода лениво: пока блок не нарисован, в DOM от него лежат первые две строки, а остального нет вовсе — его не достать ни innerText, ни textContent. Прокрутка не помогает (проверено проходом по всему ответу шагами: ни одного лишнего символа).

Помогает единственное — заставить браузер отрисовать страницу, и через CDP это делает Page.captureScreenshot. Замеры на живых ответах:

до отрисовки после
ответ про TaskQueue 2068 24 362
ответ про EventBus 3136 30 817
ответ про Router (уже с правкой) 258 32 045

Правка в ollama_orchestro/ask.mjs: revealAnswer() перед съёмом текста делает дешёвый скриншот (jpeg, качество 1) и перечитывает ответ, до трёх раз, пока текст растёт. Картинка выбрасывается.

Вдобавок browser-launch.ps1 запускает браузер развёрнутым и с запретом фонового режима (--disable-backgrounding-occluded-windows, --disable-renderer-backgrounding, --disable-background-timer-throttling, --disable-features=CalculateNativeWinOcclusion). Это не замена скриншоту: свёрнутое окно Windows не рисует вообще.

Вторая причина обрезания, найденная там же, — кнопка Continue: DeepSeek режет длинный ответ по своему лимиту и предлагает дописать, а генерация при этом честно завершается. Теперь waitForAnswer жмёт её и ждёт дальше; продолжение уходит в тот же блок ответа. Сквозная проверка — ответ на 47 414 символов с целыми кодом и тестами.

Обе правки в ollama_orchestro, deepwork получает их даром — мост вызывается подпроцессом.

S
Description
No description provided
Readme MIT
145 KiB
Languages
JavaScript 75.1%
HTML 21.1%
Batchfile 3.8%