README для новичка, ASCII в батнике, лицензия

README переписан под человека, который видит проект впервые: что это вообще
такое (схемой), что понадобится, установка по шагам с проверкой на каждом,
как пользоваться пультом и консолью, чего ожидать по времени, таблица
"если не работает" на десять строк и отдельный раздел про безопасность.

Замеры и выводы прошлых прогонов сохранены — это самое ценное, что тут есть,
но убраны под "Что проверено вживую", а не вперемешку с инструкцией.

Поправлено попутно:
- start-deepwork.cmd стучался в порт 9333 и советовал запустить start-browser.cmd
  в ollama_orchestro; теперь проверяет deepseek-api на 11500. Заодно батник
  снова стал чисто ASCII, как ему и положено;
- в USAGE --timeout и --check ссылались на мост, --chat не знал про vision;
- добавлена LICENSE (MIT), на которую README ссылается, и .gitattributes:
  без него start-deepwork.cmd уехал бы в репозиторий с LF.

Раздел про обрезанные ответы поправлен по существу: обе поломки лечатся
в deepseek-api (отрисовка и кнопка Continue живут в его browser.mjs),
а не в ollama_orchestro, как было написано.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Alex Cube
2026-08-26 13:53:54 +03:00
co-authored by Claude Opus 5
parent 44f07c8af9
commit f34e07e807
5 changed files with 366 additions and 123 deletions
+11
View File
@@ -0,0 +1,11 @@
# Батникам нужны CRLF: с LF cmd.exe способен повести себя странно —
# например, оборвать последнюю строку или неверно разобрать блок в скобках.
*.cmd text eol=crlf
*.bat text eol=crlf
# Остальному текстовому — LF в репозитории, нормализация при выгрузке.
*.mjs text
*.md text
*.html text
*.json text
.gitignore text
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2026 Alex
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+324 -116
View File
@@ -1,33 +1,168 @@
# deepwork # deepwork
Цикл с инструментами поверх сервиса [deepseek-api](https://git.08h.ru/alex/deepseek-api). **DeepSeek, который сам читает вашу папку с кодом.**
DeepSeek через веб-чат видит только то, что положили ему в вопрос. Здесь у него Обычный веб-чат видит только то, что вы вставили в вопрос. Спросишь «почему
появляется обратное направление: он возвращает блок-запрос, программа его падает вот эта функция» — и в ответ получишь три догадки, потому что остального
исполняет и досылает результат следующим сообщением в тот же чат. Обычный кода он не видел.
агентский цикл, только транспорт — текст.
Здесь у него появляется обратное направление. DeepSeek отвечает не текстом,
а **запросом**: «пришлите мне файл `server.js`», «покажите, где встречается
`waitForAnswer`». Программа исполняет запрос, досылает данные, и так по кругу,
пока он не соберёт всё нужное и не ответит по существу.
```
вы: "почему падает загрузка?"
DeepSeek ──► "=== NEED: upload.js ==="
│ │
│ программа читает файл и досылает
│ │
▼ ▼
DeepSeek ──► "=== FIND: parseBody ==="
│ │
▼ ▼
DeepSeek ──► ответ по существу + исправленный файл
```
Читает он только вашу папку и только на чтение. Правки возвращает файлами,
которые вы записываете нажатием кнопки — или не записываете.
---
## Оглавление
1. [Что понадобится](#что-понадобится)
2. [Установка по шагам](#установка-по-шагам)
3. [Как пользоваться](#как-пользоваться)
4. [Что он умеет запрашивать](#что-он-умеет-запрашивать)
5. [Правки файлов](#правки-файлов)
6. [Настройка](#настройка)
7. [Если не работает](#если-не-работает)
8. [Безопасность](#безопасность)
9. [Как это устроено внутри](#как-это-устроено-внутри)
10. [Что проверено вживую](#что-проверено-вживую)
---
## Что понадобится
| Что | Зачем | Как проверить |
|---|---|---|
| **Windows** | скрипт запуска написан под неё | — |
| **Node.js 22 или новее** | на нём написана программа | `node --version``v22.…` и выше |
| **Сервис `deepseek-api`** | через него идёт разговор с DeepSeek | см. шаг 1 |
Node.js, если его нет, ставится с [nodejs.org](https://nodejs.org) — берите
версию LTS. После установки **закройте и откройте заново** командную строку,
иначе `node` в ней не найдётся.
---
## Установка по шагам
### Шаг 1. Поднять deepseek-api
У веб-версии DeepSeek нет API — только вкладка в браузере. Разговором с ней
занимается отдельная программа
[deepseek-api](https://git.08h.ru/alex/deepseek-api): она держит вкладку
и отдаёт наружу обычный HTTP.
Поставьте и запустите её по инструкции в её README — это отдельные пять шагов,
включая вход в аккаунт DeepSeek. Возвращайтесь сюда, когда заработает.
> **Проверка:**
> ```cmd
> curl http://localhost:11500/api/tags
> ```
> должен вернуть список из трёх «моделей». Окно `deepseek-api` при этом
> остаётся открытым — пока оно живо, работает и сервис.
### Шаг 2. Скачать deepwork
```cmd
cd C:\#Projects
git clone https://git.08h.ru/alex/deepwork.git
```
Без git — скачайте ZIP с той же страницы и распакуйте. Папка может лежать где
угодно; рядом с чем-то конкретным её класть не нужно.
> **Проверка:**
> ```cmd
> cd C:\#Projects\deepwork
> node deepwork.mjs --selftest
> ```
> Ответ `самопроверка пройдена`. Ничего никуда не отправляется.
### Шаг 3. Проверить связку
```cmd
node deepwork.mjs --check
```
Три возможных ответа:
| Что видно | Что это значит |
|---|---|
| `готов: браузер поднят, вкладка DeepSeek открыта` | всё на месте, можно работать |
| `не готов (HTTP 503)` | сервис жив, но браузер ещё не поднят — встанет сам на первом вопросе |
| `не отвечает: …` | `deepseek-api` не запущен, вернитесь к шагу 1 |
**Готово.** Настраивать больше нечего: адрес `http://localhost:11500` вшит
как значение по умолчанию.
---
## Как пользоваться ## Как пользоваться
Обычный путь — **пульт**: бросить папку проекта на `start-deepwork.cmd`. ### Способ 1: пульт (обычный путь)
Откроется страница: файлы галочками, поле вопроса, ход работы построчно,
кнопка «Записать» у каждого пришедшего файла.
Пульт открывается в браузере ПО УМОЛЧАНИЮ, а не в отладочном: там он занял бы **Перетащите папку своего проекта мышкой на файл `start-deepwork.cmd`.**
вкладку, и мост перестал бы видеть DeepSeek. Порт 8787 — рядом с пультом
orchestro (8777), оба могут работать разом.
Тот же цикл из консоли: Откроется страница в браузере:
``` - слева файлы папки — отметьте галочками те, что точно нужны (можно ни одного);
cd c:\мой\проект - поле вопроса;
node c:\#Projects\deepwork\deepwork.mjs "вопрос" --files a.js,b.js --apply - ход работы построчно: видно, что DeepSeek запросил и сколько это заняло;
node c:\#Projects\deepwork\deepwork.mjs ui тот же пульт вручную - у каждого пришедшего файла кнопка «Записать».
Пульт открывается в браузере **по умолчанию**, а не в том, которым управляет
`deepseek-api`: иначе он занял бы там вкладку, и вкладка с чатом потерялась бы.
Порт 8787.
Остановить — `Ctrl+C` в чёрном окне.
### Способ 2: командная строка
Работает в **текущей** папке: её читает, в неё же пишет правки.
```cmd
cd C:\мой\проект
node C:\#Projects\deepwork\deepwork.mjs "почему падает загрузка файла?"
``` ```
Работает в текущей папке: её файлы показывает, в неё же пишет правки. Полезные флаги:
## Инструменты | Флаг | Что делает |
|---|---|
| `--files a.js,b.js` | положить эти файлы в вопрос сразу |
| `--steps 6` | сколько кругов позволить (по умолчанию 4) |
| `--apply` | записать пришедшие файлы на диск (без него только покажет) |
| `--chat search` | режим с поиском в интернете вместо обычного |
| `--check` | проверить связку и выйти |
| `--selftest` | внутренние проверки, ничего не отправляя |
### Чего ожидать по времени
Один круг — 7–15 секунд. Обычная задача укладывается в два-три круга, то есть
полминуты. Если DeepSeek запросил много файлов, вопрос на следующем круге
вырастает до десятков килобайт — это нормально.
---
## Что он умеет запрашивать
Только чтение и только внутри текущей папки: Только чтение и только внутри текущей папки:
@@ -37,147 +172,220 @@ node c:\#Projects\deepwork\deepwork.mjs ui тот же пульт вру
| `=== LIST: **/*.mjs ===` | список файлов по маске | | `=== LIST: **/*.mjs ===` | список файлов по маске |
| `=== FIND: текст ===` | где встречается текст, с номерами строк | | `=== FIND: текст ===` | где встречается текст, с номерами строк |
Запуска команд (`RUN`) нет намеренно: исполнять строки из ответа, пришедшего **Запуска команд (`RUN`) нет, и не будет.** Исполнять строки, пришедшие
из интернета, без белого списка и подтверждения нельзя. из интернета, без белого списка и подтверждения нельзяа белого списка,
который был бы и полезен, и безопасен, придумать не вышло.
Лимиты на результат шага: `NEED` — 200 000 символов суммарно, `FIND` — 100 Лимиты на один круг: `NEED` — 200 000 символов суммарно, `FIND` — 100
попаданий, `LIST` — 300 путей. Обрезанное помечается прямо в тексте. попаданий, `LIST` — 300 путей. Обрезанное помечается прямо в тексте, чтобы
DeepSeek видел, что данные неполные.
## Как устроено Цикл останавливается, когда запросов в ответе больше нет, когда кончились
круги или когда пришёл тот же самый запрос второй раз подряд — это петля,
данные ему уже присылали.
У веб-версии DeepSeek нет API — только вкладка в браузере. Разговором с ней ---
занимается отдельный сервис `deepseek-api`, а нам показывает протокол Ollama.
Здесь про браузер не знают вовсе: обычный `POST /api/chat`.
**Разговор помним мы, а не DeepSeek.** Сервис без памяти: каждый запрос он ## Правки файлов
кладёт в чат целиком, затирая прошлый. Поэтому стенограмма растёт здесь —
`growTranscript` подклеивает к отправленному тексту прошлый ответ модели
(между метками `=== ТВОЙ ПРЕДЫДУЩИЙ ОТВЕТ ===` и `=== END ===`) и результаты
запросов, и следующим шагом уезжает всё сразу.
Раньше эту роль играл флаг `--new` у моста, и помнил всё сам чат. Своя Исправленный код DeepSeek возвращает блоками:
стенограмма надёжнее: видно в одном месте, что именно уедет модели, а чужой
потребитель, вклинившийся между нашими шагами, ничего не портит — мы всё
приносим заново. Плата — вопрос растёт на длину прошлого ответа; при `steps: 4`
это единицы килобайт против 22 КБ первого сообщения.
Цикл останавливается, когда запросов в ответе нет, когда кончились шаги или ```
когда пришёл тот же самый запрос второй раз подряд (петля). === FILE: src/upload.js ===
```
...содержимое целиком...
```
=== END FILE ===
```
Записываются они **только по вашей команде** — кнопкой «Записать» в пульте
или флагом `--apply` в консоли. Без этого программа просто перечислит, что
пришло.
**Прежняя версия не пропадает:** перед записью она уезжает в папку `backup/`
внутри проекта. Файлы вне рабочей папки не пишутся вовсе — путь проверяется.
---
## Настройка ## Настройка
`config.json` (в репозиторий не попадает, образец — `config.example.json`): Нужна редко. `config.json` рядом с программой (в репозиторий не попадает,
образец — `config.example.json`):
```json ```json
{ "deepseekHost": "http://localhost:11500", "deepseekModel": "deepseek:think", "steps": 4 } {
"deepseekHost": "http://localhost:11500",
"deepseekModel": "deepseek:think",
"steps": 4,
"timeout": 240
}
``` ```
Без файла берётся `http://localhost:11500`. | Ключ | По умолчанию | Смысл |
|---|---|---|
| `deepseekHost` | `http://localhost:11500` | адрес сервиса `deepseek-api` |
| `deepseekModel` | `deepseek:think` | режим чата: `think`, `search` или `vision` |
| `steps` | `4` | сколько кругов позволить |
| `timeout` | `240` | секунд на один круг (сверх этого сервису дают ещё две минуты на очередь) |
| `uiPort` | `8787` | порт пульта |
## Проверка Без файла всё работает на значениях по умолчанию. А вот **битый** `config.json`
не молчит: программа скажет об ошибке, а не откатится тихо к умолчаниям —
иначе правка в настройках не действует, и понять почему невозможно.
``` ---
node deepwork.mjs --selftest внутренние проверки, ничего не отправляют
node deepwork.mjs --check сервис на месте, вкладка жива
```
`--check` различает три состояния: сервис отвечает и браузер поднят; сервис ## Если не работает
жив, но браузера ещё нет (встанет на первом же вопросе); сервис не запущен.
Запускается сервис своим `start.cmd` в папке `deepseek-api` — браузер он | Что видно | В чём дело | Что делать |
поднимает сам. |---|---|---|
| `deepseek-api не отвечает по адресу …` | сервис не запущен | Запустите `start.cmd` в папке `deepseek-api` |
| `--check` говорит `не готов (HTTP 503)` | сервис жив, браузера ещё нет | Ничего: браузер встанет на первом же вопросе |
| `deepseek-api ответил 500` | что-то со вкладкой | `curl http://localhost:11500/api/probe` покажет, что там видно |
| **Ответ пришёл обрезанным**, код оборван на середине | окно браузера свёрнуто | Разверните его. Свёрнутое окно Windows не отрисовывает, а DeepSeek рисует блоки кода лениво — см. [ниже](#обрезанные-ответы-причина-найдена) |
| `шаг 1: запросов нет, готово`, а ответ — догадки | DeepSeek поленился спросить и придумал | Спросите конкретнее либо дайте файл сразу через `--files`. Так бывает; напоминание в конце вопроса помогает, но не всегда |
| `тот же запрос повторно — петля, выхожу` | он не принял присланные данные | Обычно значит, что запрошенного файла нет или он пуст. Посмотрите журнал шагов |
| `шаги кончились, а запросы ещё идут` | задача крупнее четырёх кругов | `--steps 6`, но сначала подумайте, не проще ли разбить вопрос |
| `DeepSeek занят: «Server is busy»` | лимиты на стороне DeepSeek | Подождите минуту |
| `node не является внутренней или внешней командой` | Node не установлен или консоль открыта до установки | Поставьте Node, **закройте и откройте заново** консоль |
| Чаты в DeepSeek пропадают сами | тот же профиль браузера использует другая программа | Дайте `deepseek-api` отдельный профиль |
## Переезд на deepseek-api (26.08.2026) ---
Транспорт сменился: был дочерний процесс `ask.mjs` из `ollama_orchestro` ## Безопасность
с обменом через временные файлы, стал `POST /api/chat` к сервису
`deepseek-api`. Заодно ушли временные файлы шагов (и флаг `--keep-temp`),
проверка существования моста и запуск браузера — всё это теперь не наша забота.
Память шагов переехала из чата DeepSeek в `growTranscript` (см. «Как устроено»). - **Ваш код уходит на серверы DeepSeek.** Не только присланные файлы: он сам
Проверено живым прогоном: шаг 1 — 2094 символа, ответ `NEED: deepwork.mjs`; запрашивает то, что считает нужным, из всей рабочей папки. Для закрытых
шаг 2 — 28 447 символов стенограммы, ответ дословно верный и по вопросу проектов это не годится.
из ПЕРВОГО сообщения. Два шага за 17 с. - **Ключей и паролей в папке быть не должно.** `.env`, `config.json` с токенами,
приватные ключи — всё это он может запросить, и это уедет наружу. Убирайте
такое из рабочей папки заранее.
- **Правки не применяются сами.** Только кнопкой или флагом `--apply`,
и прежняя версия всегда сохраняется в `backup/`.
- **За пределы рабочей папки программа не пишет** и не читает: путь
проверяется, `..` не проходит.
- **Пульт слушает только этот компьютер** (`127.0.0.1`), из сети к нему
не подключиться.
## Что проверено ---
- `--selftest`: разбор запросов, отказ пути за пределы папки, маски `*` и `**`, ## Как это устроено внутри
снятие тройных кавычек и подписи языка. Строка вида `=== NEED: … ===`
**внутри** блока `=== FILE: ===` за запрос не принимается — иначе правка
файла с описанием формата запускала бы запрос сама.
- Цикл целиком на заглушке вместо моста: приставка едет в первом сообщении,
второй вызов уходит с `--new`, результаты `NEED` и `FIND` доезжают,
отступы в записанном файле сохраняются, прежняя версия уходит в `backup/`.
- Пропавший файл в `NEED` возвращает «файла нет» и цикл не роняет.
- `--steps 1` отдаёт ответ с пометкой «шаги кончились», а не зависает.
- Битый `config.json` — понятная ошибка, а не молчаливый откат к умолчаниям.
### Живые прогоны на DeepSeek, 11.08.2026 ### Разговор помним мы, а не DeepSeek
Задача одна и та же: из папки `ollama_orchestro` спросить, где решается, что Сервис `deepseek-api` **без памяти**: каждый запрос он кладёт в чат целиком,
ответ дописан до конца, дав в вопросе **только** `ui.html` — то есть заведомо затирая прошлый. Поэтому стенограмму ведёт `deepwork` — функция
не тот файл. Правильный ответ (`waitForAnswer` в `ask.mjs`) достижим только `growTranscript` подклеивает к отправленному тексту прошлый ответ модели
через инструменты. (между метками `=== ТВОЙ ПРЕДЫДУЩИЙ ОТВЕТ ===` и `=== END ===`) и результаты
запросов, и следующим кругом уезжает всё сразу.
| Прогон | Шагов | Что вышло | Раньше память держал сам чат DeepSeek. Своя стенограмма надёжнее: видно
в одном месте, что именно уедет модели, а чужая программа, вклинившаяся между
нашими кругами, ничего не портит — мы всё приносим заново. Плата — вопрос
растёт на длину прошлого ответа; при четырёх кругах это единицы килобайт
против 22 КБ первого сообщения.
### Что уезжает в первом сообщении
1. Приставка из `agent-prompt.md` — кто он и какие блоки может вернуть.
2. **Дерево рабочей папки.** Без него первый живой прогон ушёл на угадывание
имён файлов, см. замеры ниже.
3. Файлы, отмеченные галочками (или переданные через `--files`).
4. **Напоминание про инструменты — вплотную к вопросу.** Не в начале: между
приставкой и вопросом ложатся килобайты файлов, и инструкция теряется.
5. Сам вопрос.
### Файлы
| Файл | Что в нём |
|---|---|
| `deepwork.mjs` | всё: цикл, инструменты, разбор ответов, пульт |
| `agent-prompt.md` | приставка к первому сообщению |
| `ui.html` | страница пульта |
| `config.json` | настройки (не в репозитории) |
| `start-deepwork.cmd` | запуск пульта перетаскиванием папки |
Зависимостей нет — только то, что есть в Node 22.
---
## Что проверено вживую
### Внутренние проверки (`--selftest`)
Разбор запросов, отказ пути за пределы папки, маски `*` и `**`, снятие тройных
кавычек и подписи языка. Строка вида `=== NEED: … ===` **внутри** блока
`=== FILE: ===` за запрос не принимается — иначе правка файла с описанием
формата запускала бы запрос сама. Пропавший файл в `NEED` возвращает «файла
нет» и цикл не роняет. `--steps 1` отдаёт ответ с пометкой «шаги кончились»,
а не зависает.
### Из чего выросли два правила, 11.08.2026
Задача одна и та же: спросить, где решается, что ответ дописан до конца, дав
в вопросе **заведомо не тот файл**. Правильный ответ достижим только через
инструменты.
| Прогон | Кругов | Что вышло |
|---|---|---| |---|---|---|
| 1. приставка только в начале сообщения | 1 | **запросов нет.** «Точный код в серверном файле» и три догадки | | 1. приставка только в начале сообщения | 1 | **запросов нет.** «Точный код в серверном файле» и три догадки |
| 2. + напоминание вплотную к вопросу | 4 | нашёл, но 2 круга ушли на угадывание имён файлов | | 2. + напоминание вплотную к вопросу | 4 | нашёл, но два круга ушли на угадывание имён файлов |
| 3. + дерево папки в первом сообщении | **2** | запросил `ask.mjs` сразу, ответил по существу | | 3. + дерево папки в первом сообщении | **2** | запросил нужный файл сразу, ответил по существу |
Два вывода, оба стоили живого прогона:
- **Инструкция в начале сообщения не работает.** Между приставкой и вопросом - **Инструкция в начале сообщения не работает.** Между приставкой и вопросом
легли 22 КБ файла, и DeepSeek инструменты просто не заметил. Помогло легли 22 КБ файла, и DeepSeek инструменты просто не заметил.
дословное повторение перед самим вопросом (`TAIL_REMINDER`). - **Дерево папки надо давать сразу.** Без него он угадывал имена (`server.js`,
- **Дерево папки надо давать сразу.** Без него DeepSeek угадывал имена `bridge.js` — таких в проекте нет), потом просил `LIST *.js` (проект
(`server.js`, `bridge.js` — таких в проекте нет), потом просил `LIST *.js` на `.mjs`, пусто), потом `LIST **/*`. Дерево — 600 символов против двух
(проект на `.mjs`, пусто), потом `LIST **/*`. Дерево — 600 символов против кругов по минуте.
двух кругов по минуте.
### Пульт, 11.08.2026 ### Пульт, 11.08.2026
Сквозной прогон через страницу: вопрос без единого приложенного файла — Вопрос без единого приложенного файла — «какая функция решает, что ответ
«какая функция решает, что ответ дописан?». 36 секунд, три шага. DeepSeek дописан?». 36 секунд, три круга: пять блоков `FIND` сразу, затем `NEED`
запросил пятью блоками `FIND` сразу (`waitForAnswer`, `streaming`, `done`, на найденный файл, и точный ответ с номером строки. Журнал кругов обновлялся
`stop_reason`, `finish_reason`), затем `NEED: ask.mjs`, и ответил точно: на странице по ходу.
`waitForAnswer`, строка 675. Журнал шагов обновлялся на странице по ходу.
## Обрезанные ответы: причина найдена и устранена в мосте (11.08.2026) ### Обрезанные ответы: причина найдена
В третьем прогоне ответ оборвался посреди блока кода на `// Бы`. Оказалось, Один из прогонов оборвался посреди блока кода на `// Бы`. Это не «конец
это не «конец определён раньше времени» и не кнопка `Continue`. определён раньше времени» и не кнопка `Continue`.
**Браузер работал в фоне.** У неактивного окна страница не отрисовывается, а **Браузер работал в фоне.** У неактивного окна страница не отрисовывается,
DeepSeek рисует блоки кода лениво: пока блок не нарисован, в DOM от него а DeepSeek рисует блоки кода лениво: пока блок не нарисован, в DOM от него
лежат первые две строки, а остального нет вовсе — его не достать ни лежат первые две строки, а остального нет вовсе — его не достать ни
`innerText`, ни `textContent`. Прокрутка не помогает (проверено проходом по `innerText`, ни `textContent`. Прокрутка не помогает.
всему ответу шагами: ни одного лишнего символа).
Помогает единственное — заставить браузер отрисовать страницу, и через CDP Помогает единственное — заставить браузер отрисовать страницу. Замеры на живых
это делает `Page.captureScreenshot`. Замеры на живых ответах: ответах:
| | до отрисовки | после | | | до отрисовки | после |
|---|---|---| |---|---|---|
| ответ про TaskQueue | 2068 | 24 362 | | ответ про TaskQueue | 2068 | 24 362 |
| ответ про EventBus | 3136 | 30 817 | | ответ про EventBus | 3136 | 30 817 |
| ответ про Router (уже с правкой) | 258 | **32 045** | | ответ про Router | 258 | **32 045** |
Правка в `ollama_orchestro/ask.mjs`: `revealAnswer()` перед съёмом текста Вторая причина обрезания — кнопка **Continue**: DeepSeek режет длинный ответ
делает дешёвый скриншот (jpeg, качество 1) и перечитывает ответ, до трёх раз, по своему лимиту и предлагает дописать, а генерация при этом честно
пока текст растёт. Картинка выбрасывается. завершается. Сквозная проверка после починки — ответ на 47 414 символов
с целыми кодом и тестами.
Вдобавок `browser-launch.ps1` запускает браузер развёрнутым и с запретом Обе поломки лечатся в `deepseek-api`, а не здесь: отрисовка и кнопка `Continue`
фонового режима (`--disable-backgrounding-occluded-windows`, живут в его `browser.mjs`. Отсюда остаётся одно требование — **не сворачивать
`--disable-renderer-backgrounding`, `--disable-background-timer-throttling`, окно браузера**.
`--disable-features=CalculateNativeWinOcclusion`). Это не замена скриншоту:
свёрнутое окно Windows не рисует вообще.
Вторая причина обрезания, найденная там же, — кнопка **Continue**: DeepSeek ### Переезд на deepseek-api, 26.08.2026
режет длинный ответ по своему лимиту и предлагает дописать, а генерация при
этом честно завершается. Теперь `waitForAnswer` жмёт её и ждёт дальше;
продолжение уходит в тот же блок ответа. Сквозная проверка — ответ на 47 414
символов с целыми кодом и тестами.
Обе правки в `ollama_orchestro`, deepwork получает их даром — мост вызывается Раньше `deepwork` вызывал мост `ask.mjs` из проекта DeepShim дочерним процессом
подпроцессом. и гонял текст через временные файлы. Теперь это `POST /api/chat`, а память
кругов переехала из чата в стенограмму (см. выше).
Проверено живым прогоном: круг 1 — 2094 символа, ответ `NEED: deepwork.mjs`;
круг 2 — 28 447 символов стенограммы, ответ дословно верный и по вопросу
из **первого** сообщения. Два круга за 17 с.
---
## Лицензия
MIT.
+3 -3
View File
@@ -44,9 +44,9 @@ deepwork — задать DeepSeek вопрос и дать ему дочита
--steps N сколько кругов позволить (по умолчанию 4) --steps N сколько кругов позволить (по умолчанию 4)
--apply применить пришедшие блоки === FILE: === на диск --apply применить пришедшие блоки === FILE: === на диск
(прежняя версия уезжает в backup/) (прежняя версия уезжает в backup/)
--chat роль think (по умолчанию) | search --chat роль think (по умолчанию) | search | vision
--timeout сек максимум бездействия страницы, передаётся мосту --timeout сек сколько секунд ждать ответа на один шаг
--check проверить, что мост на месте и вкладка жива --check проверить, что сервис на месте и вкладка жива
--selftest прогнать внутренние проверки, ничего не отправляя --selftest прогнать внутренние проверки, ничего не отправляя
Инструменты, которые может вернуть DeepSeek (только чтение, только внутри Инструменты, которые может вернуть DeepSeek (только чтение, только внутри
+7 -4
View File
@@ -5,6 +5,7 @@ REM ============================================================
REM deepwork web console. Drag and drop a project folder onto REM deepwork web console. Drag and drop a project folder onto
REM this file: DeepSeek gets tools (NEED / LIST / FIND) and can REM this file: DeepSeek gets tools (NEED / LIST / FIND) and can
REM read that folder himself, step by step. REM read that folder himself, step by step.
REM Needs the deepseek-api service running (its own start.cmd).
REM ASCII only on purpose - cmd.exe mangles UTF-8 Cyrillic. REM ASCII only on purpose - cmd.exe mangles UTF-8 Cyrillic.
REM ============================================================ REM ============================================================
@@ -43,10 +44,11 @@ if errorlevel 1 (
) )
echo [OK] Node.js found echo [OK] Node.js found
powershell -NoProfile -Command "try { Invoke-RestMethod -Uri 'http://127.0.0.1:9333/json/version' -TimeoutSec 2 | Out-Null; exit 0 } catch { exit 1 }" >nul 2>&1 powershell -NoProfile -Command "try { Invoke-RestMethod -Uri 'http://localhost:11500/api/tags' -TimeoutSec 3 | Out-Null; exit 0 } catch { exit 1 }" >nul 2>&1
if errorlevel 1 ( if errorlevel 1 (
echo [WARN] Bridge is NOT available on port 9333. echo [WARN] deepseek-api is NOT ready on port 11500.
echo Run start-browser.cmd in ollama_orchestro, then log in. echo Run start.cmd in the deepseek-api folder - it starts the
echo browser by itself. Log in to DeepSeek in the window it opens.
echo The console will start anyway and show the same warning. echo The console will start anyway and show the same warning.
echo. echo.
) )
@@ -54,7 +56,8 @@ if errorlevel 1 (
cd /d "%~1" cd /d "%~1"
echo. echo.
echo Open the printed address in your DEFAULT browser, not the debug one. echo Open the printed address in your DEFAULT browser, not the one
echo that deepseek-api drives.
echo Ctrl+C here stops it. echo Ctrl+C here stops it.
echo. echo.
node "%DW_DIR%deepwork.mjs" ui node "%DW_DIR%deepwork.mjs" ui