deel-local-cli 1.5.8 → 1.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.en.md +30 -14
- package/README.md +28 -12
- package/bin/deel.js +10 -0
- package/package.json +2 -2
- package/src/acp/map.js +143 -0
- package/src/acp/serve.js +166 -13
- package/src/agent/commit.js +511 -0
- package/src/agent/compact.js +269 -226
- package/src/agent/loop.js +196 -12
- package/src/agent/mention.js +56 -10
- package/src/agent/review.js +192 -0
- package/src/agent/session.js +22 -2
- package/src/agent/threads.js +1 -1
- package/src/backend/adapter.js +342 -280
- package/src/backend/azure.js +151 -0
- package/src/backend/ctxsize.js +19 -0
- package/src/backend/detect.js +106 -0
- package/src/backend/http.js +350 -30
- package/src/backend/probe.js +48 -1
- package/src/backend/proxy.js +151 -0
- package/src/backend/quota.js +133 -0
- package/src/backend/retry.js +132 -0
- package/src/backend/vision.js +185 -0
- package/src/commands.js +341 -8
- package/src/completion.js +264 -0
- package/src/config.js +117 -1
- package/src/i18n/en.js +13 -1
- package/src/i18n/index.js +22 -3
- package/src/i18n/ja.js +266 -0
- package/src/i18n/ko.js +12 -0
- package/src/i18n/zh.js +266 -0
- package/src/oneshot.js +28 -3
- package/src/pack/sbom.js +25 -0
- package/src/pack/selfpack.js +9 -3
- package/src/plugins/manage.js +34 -7
- package/src/repl.js +92 -6
- package/src/report.js +26 -2
- package/src/safety/guard.js +74 -2
- package/src/safety/keystore.js +237 -0
- package/src/safety/network.js +76 -14
- package/src/safety/policy.js +209 -0
- package/src/safety/secrets.js +32 -0
- package/src/setup.js +40 -7
- package/src/tools/clipboard.js +178 -0
- package/src/tools/convert.js +287 -0
- package/src/tools/docs.js +72 -1
- package/src/tools/fastgrep.js +217 -0
- package/src/tools/fsutil.js +55 -12
- package/src/tools/ignore.js +192 -0
- package/src/tools/index.js +391 -41
- package/src/tools/jobs.js +4 -12
- package/src/tools/outline.js +3 -1
- package/src/tools/pdf.js +1368 -0
- package/src/tools/shell.js +123 -0
- package/src/tools/verify.js +20 -4
- package/src/tools/webfetch.js +18 -5
- package/src/ui/inputbox.js +2 -2
- package/src/ui/screen.js +4 -1
- package/src/ui/status.js +22 -0
package/README.en.md
CHANGED
|
@@ -18,7 +18,7 @@ Zero dependencies · Node 20+ · Exactly one place your source can go
|
|
|
18
18
|
|
|
19
19
|
[](https://github.com/jysvai/deel-local-cli/actions/workflows/test.yml)
|
|
20
20
|
[](https://github.com/jysvai/deel-local-cli/actions/workflows/codeql.yml)
|
|
21
|
-
[](docs/en/develop.md)
|
|
22
22
|
|
|
23
23
|
[](https://www.npmjs.com/package/deel-local-cli?activeTab=dependencies)
|
|
24
24
|
[](package.json)
|
|
@@ -95,12 +95,12 @@ This page is the **summary**. Each section links to the detail behind it.
|
|
|
95
95
|
| [Models](docs/en/models.md) | Grade and window size · Korean-model presets · project detection |
|
|
96
96
|
| [The screen](docs/en/interface.md) | The input box · work modes · simple vs developer · what it asks about |
|
|
97
97
|
| [Tools in depth](docs/en/tools.md) | `Outline` · `Verify` · `Task` · `Jobs` · `Append` · `Def`/`Refs` · edit matching |
|
|
98
|
-
| [Korean documents and Excel](docs/en/documents.md) | hwpx/docx/pptx · encoding · Excel → CSV |
|
|
98
|
+
| [Korean documents and Excel](docs/en/documents.md) | hwpx/docx/pptx/**PDF** · encoding · Excel → CSV |
|
|
99
99
|
| [Extending](docs/en/extend.md) | Skills · plugins · MCP · ACP |
|
|
100
100
|
| [Speed and spend](docs/en/tuning.md) | Per-stage effort · the prefix cache · context length |
|
|
101
101
|
| [Safety and corporate review](docs/en/safety.md) | Undo · working scope · audit log · the review package |
|
|
102
102
|
| [Configuration](docs/en/config.md) · [Development](docs/en/develop.md) | Env vars · run flags · running the tests · folder layout |
|
|
103
|
-
| [Release notes](docs/en/releases.md) | [1.5.8](docs/en/releases.md#158) · [1.5.7](docs/en/releases.md#157) · [1.5.6](docs/en/releases.md#156) · [1.5.5](docs/en/releases.md#155) · [1.5.4](docs/en/releases.md#154) · [1.5.3](docs/en/releases.md#153) · [1.5.2](docs/en/releases.md#152) · [1.5.1](docs/en/releases.md#151) · [1.5.0](docs/en/releases.md#150) · [1.4.3](docs/en/releases.md#143) · [1.4.2](docs/en/releases.md#142) · [1.4.1](docs/en/releases.md#141) · [1.4.0](docs/en/releases.md#140) · [1.3.0](docs/en/releases.md#130) · [1.2.0](docs/en/releases.md#120) |
|
|
103
|
+
| [Release notes](docs/en/releases.md) | [1.6.1](docs/en/releases.md#161) · [1.6.0](docs/en/releases.md#160) · [1.5.8](docs/en/releases.md#158) · [1.5.7](docs/en/releases.md#157) · [1.5.6](docs/en/releases.md#156) · [1.5.5](docs/en/releases.md#155) · [1.5.4](docs/en/releases.md#154) · [1.5.3](docs/en/releases.md#153) · [1.5.2](docs/en/releases.md#152) · [1.5.1](docs/en/releases.md#151) · [1.5.0](docs/en/releases.md#150) · [1.4.3](docs/en/releases.md#143) · [1.4.2](docs/en/releases.md#142) · [1.4.1](docs/en/releases.md#141) · [1.4.0](docs/en/releases.md#140) · [1.3.0](docs/en/releases.md#130) · [1.2.0](docs/en/releases.md#120) |
|
|
104
104
|
|
|
105
105
|
---
|
|
106
106
|
|
|
@@ -207,19 +207,23 @@ reviewer catches one drifted claim, they stop trusting the rest of it.
|
|
|
207
207
|
|
|
208
208
|
## Quick start
|
|
209
209
|
|
|
210
|
-
### The screen speaks
|
|
210
|
+
### The screen speaks your language
|
|
211
211
|
|
|
212
212
|
deel is written in Korean — the code, the function names, the comments. That part stays.
|
|
213
|
-
What you see on screen does not have to.
|
|
213
|
+
What you see on screen does not have to. Four screen languages ship: **한국어 · English ·
|
|
214
|
+
日本語 · 中文**, all four complete.
|
|
214
215
|
|
|
215
216
|
```bash
|
|
216
|
-
DEEL_LANG=en deel # this run only
|
|
217
|
+
DEEL_LANG=en deel # this run only (also ja, zh)
|
|
217
218
|
/lang en # and remember it
|
|
219
|
+
/lang ja # 日本語
|
|
220
|
+
/lang zh # 中文
|
|
218
221
|
/lang # how much is translated so far
|
|
219
222
|
```
|
|
220
223
|
|
|
221
|
-
|
|
222
|
-
|
|
224
|
+
Nothing ever comes through blank. A line that has not been translated falls back to English
|
|
225
|
+
first and Korean second — so a Japanese or Chinese screen degrades to English, not to Korean —
|
|
226
|
+
and `/lang` prints exactly how many strings are covered.
|
|
223
227
|
|
|
224
228
|
What the model reads follows the same switch. Set it to English and the rules, the mode
|
|
225
229
|
instructions, and the tool descriptions all go out in English — so the model answers you in
|
|
@@ -379,6 +383,7 @@ Names follow Claude Code / Codex conventions.
|
|
|
379
383
|
| `/learned [clear]` | What deel has picked up on its own — commands that work here, this model's habits |
|
|
380
384
|
| `/pin <text>` | Pin a line — folding and compaction **cannot reach it** |
|
|
381
385
|
| `/evidence [file]` | Evidence — what changed, and what proves it. **What is unproven is listed too** |
|
|
386
|
+
| `/commit [all\|preview\|title]` | Commits only what this session changed; message from the diff and the evidence. **Never pushes** |
|
|
382
387
|
| `/model` | Switch connection / model |
|
|
383
388
|
| `/model 카드` | Model card — what this model has actually done here, and what deel changed because of it |
|
|
384
389
|
| `/think <level>` | Reasoning level (`off·low·medium·high·max`) |
|
|
@@ -421,10 +426,11 @@ the conversation.
|
|
|
421
426
|
| `Ctrl+O` | Work mode (`종합` → `코드` → `계획` → …) |
|
|
422
427
|
| `↑` `↓` | Input history |
|
|
423
428
|
| `Ctrl+C` | Stops the answer in progress; twice on an empty line quits |
|
|
429
|
+
| Typing while it works, then `Enter` | Steers without throwing anything away — takes effect from the next step |
|
|
424
430
|
|
|
425
431
|
Korean IME composition, paste, `Ctrl+A/E` and backspace all keep working.
|
|
426
432
|
|
|
427
|
-
> **More** — Attaching a file with @ · Interrupting
|
|
433
|
+
> **More** — Attaching a file with @ · Interrupting · Steering without stopping
|
|
428
434
|
>
|
|
429
435
|
> **[The screen read →](docs/en/interface.md#slash-commands)**
|
|
430
436
|
|
|
@@ -493,7 +499,7 @@ Names and arguments match Claude Code, so skills written for that convention wor
|
|
|
493
499
|
|
|
494
500
|
| Tool | What it does |
|
|
495
501
|
|---|---|
|
|
496
|
-
| `Read` | Read a file (line numbers, `offset`/`limit`, **Excel as CSV, hwpx/docx/pptx as text**) |
|
|
502
|
+
| `Read` | Read a file (line numbers, `offset`/`limit`, **Excel as CSV, hwpx/docx/pptx and PDF as text**) |
|
|
497
503
|
| `Write` | Write / overwrite a file (**several at once via the `files` array**) |
|
|
498
504
|
| `Append` | Append to the end of a file — **how large files get written in pieces** |
|
|
499
505
|
| `Edit` | Replace an exact string (`replace_all`; **several sites at once via the `edits` array**) |
|
|
@@ -530,7 +536,12 @@ their cost; here is why.
|
|
|
530
536
|
**A file saved as CP949 is written back as CP949.** The encoding is never changed.
|
|
531
537
|
Excel (`.xlsx`) is read as CSV — read-only.
|
|
532
538
|
|
|
533
|
-
|
|
539
|
+
Old formats (`.ppt`, `.doc`, `.xls`, `.rtf`) are read by **borrowing the LibreOffice already
|
|
540
|
+
on this machine** — the same terms on which deel borrows `rg`, and nothing is ever installed.
|
|
541
|
+
With no converter it **says so definitively and stops**: what is missing, what you can do about
|
|
542
|
+
it, and not to open the file again. Turn it off with `DEEL_CONVERT=off`.
|
|
543
|
+
|
|
544
|
+
> **More** — Encoding · Excel · borrowing a converter
|
|
534
545
|
>
|
|
535
546
|
> **[Korean documents and Excel read →](docs/en/documents.md#korean-text-and-excel)**
|
|
536
547
|
|
|
@@ -767,6 +778,7 @@ stdio. It is not a command you type yourself.
|
|
|
767
778
|
| Approval dialog | deel's safety rails, rendered as the editor's own prompt (`allow once` · `always allow` · `reject`) |
|
|
768
779
|
| Mode picker | deel's seven work modes (auto · code · plan · architect · debug · ask · orchestrator) |
|
|
769
780
|
| Stop button | Reaches the turn mid-flight, even while waiting on the model |
|
|
781
|
+
| Past conversations | Still there after a restart. They live in the **same place** as the terminal's, so a session started in the editor can be picked up with `deel --resume` |
|
|
770
782
|
|
|
771
783
|
**Still zero dependencies.** Same reason as MCP — newline-delimited JSON-RPC 2.0 is the whole
|
|
772
784
|
transport, so no SDK is needed.
|
|
@@ -918,13 +930,15 @@ Stored in `~/.deel/config.json`. A `.deel/config.json` in the project folder tak
|
|
|
918
930
|
| `address not found` | Typo, DNS, VPN / intranet connectivity |
|
|
919
931
|
| `connection refused` | Server is down or the port differs |
|
|
920
932
|
| certificate error | `set NODE_EXTRA_CA_CERTS=C:\path\corp-ca.pem` |
|
|
921
|
-
| behind a proxy | `set HTTPS_PROXY=http://proxy:port` |
|
|
933
|
+
| behind a proxy | `set HTTPS_PROXY=http://proxy:port` (with auth: `http://user:pw@proxy:port`). If the first screen and `/status` show `proxy …`, it is in use. Exclude hosts with `NO_PROXY=.corp.com,10.1.2.3`; turn it off entirely with `"proxy": "none"` in the config |
|
|
934
|
+
| the proxy answers 407 | Put `user:pw@` into the proxy address. Proxies that only accept NTLM · Negotiate are not supported — ask the admin for Basic or an unauthenticated address |
|
|
922
935
|
| 401 / 403 | Wrong key or auth header style (four are tried automatically) |
|
|
923
936
|
| `address not permitted` | The lock did its job — pick a connection with `/model` |
|
|
924
937
|
| Tool calls don't work | Run `deel diagnose`. Small models (1B–3B) often can't |
|
|
925
938
|
| Empty replies | The server ignores streaming. deel retries once, then turns streaming off for the session |
|
|
926
939
|
| Large files cut off mid-write | Check `/out` and raise it — the cap may be sitting at the 16,384 default because it could not be discovered |
|
|
927
940
|
| Only `HTTP 400` shows | The server's own message is shown verbatim. If it is a length problem the number is read and applied automatically |
|
|
941
|
+
| `429` · `503` shows | The gateway pushed back for a moment. deel waits and calls again, up to three times (honouring `Retry-After`). If it keeps happening, check your quota |
|
|
928
942
|
| `deel scan` finds nothing | Server is off or on another port — use `--ports` |
|
|
929
943
|
|
|
930
944
|
---
|
|
@@ -932,7 +946,7 @@ Stored in `~/.deel/config.json`. A `.deel/config.json` in the project folder tak
|
|
|
932
946
|
## Development
|
|
933
947
|
|
|
934
948
|
```bash
|
|
935
|
-
npm test Full suite (
|
|
949
|
+
npm test Full suite (4,932 checks)
|
|
936
950
|
npm run coverage Which lines the tests actually execute
|
|
937
951
|
npm run verify Import + network checks only
|
|
938
952
|
npm run bench Edit success rate
|
|
@@ -957,7 +971,7 @@ so one run tells you everything.
|
|
|
957
971
|
| `guard` | 24 | **What it refuses to do** — denied edits, unknown tools, repeated mutations, out-of-scope writes |
|
|
958
972
|
| `network` | 30 | Nothing escapes the configured address |
|
|
959
973
|
| `web` | 25 | Web reads stay read-only |
|
|
960
|
-
| `abort` | 16 | Ctrl+C leaves the conversation valid |
|
|
974
|
+
| `abort` · `steer` | 16 · 15 | Ctrl+C leaves the conversation valid · a line typed mid-turn rides the next call |
|
|
961
975
|
| `parallel` | 23 | Read-only tools run together; checklists |
|
|
962
976
|
| `cli` | 75 | **Spawns the real `deel`** and drives it to completion |
|
|
963
977
|
| `setup` | 42 | First-run wizard, driven through a fake TTY |
|
|
@@ -984,6 +998,8 @@ so one run tells you everything.
|
|
|
984
998
|
|
|
985
999
|
| Version | What changed |
|
|
986
1000
|
|---|---|
|
|
1001
|
+
| **[1.6.1](docs/en/releases.md#161)** | The places that made a turn spin in circles — the fence blocking `/dev/null` · old documents it could not read · images vanishing from files |
|
|
1002
|
+
| **[1.6.0](docs/en/releases.md#160)** | The things that did not work on a corporate network — proxy · 429 · Windows shell · 50k-file repos · PDF · clipboard paste · editor resume |
|
|
987
1003
|
| **[1.5.8](docs/en/releases.md#158)** | A 5MB document showed 8 lines out of 919 · a regex read as a path blocked the command |
|
|
988
1004
|
| **[1.5.7](docs/en/releases.md#157)** | Korean folders on macOS made your own files "out of scope" · paste · ESC |
|
|
989
1005
|
| **[1.5.6](docs/en/releases.md#156)** | It asks when stuck — instead of writing a question and ending the turn |
|
package/README.md
CHANGED
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
|
|
19
19
|
[](https://github.com/jysvai/deel-local-cli/actions/workflows/test.yml)
|
|
20
20
|
[](https://github.com/jysvai/deel-local-cli/actions/workflows/codeql.yml)
|
|
21
|
-
[](docs/ko/develop.md)
|
|
22
22
|
|
|
23
23
|
[](https://www.npmjs.com/package/deel-local-cli?activeTab=dependencies)
|
|
24
24
|
[](package.json)
|
|
@@ -96,12 +96,12 @@
|
|
|
96
96
|
| [모델 다루기](docs/ko/models.md) | 급과 창 크기 · 국산 모델 이름표 · 켤 때 프로젝트 읽기 |
|
|
97
97
|
| [화면과 조작](docs/ko/interface.md) | 입력칸 · 작업 모드 · 쉬움과 개발자 · 무엇을 묻고 무엇을 그냥 하나 |
|
|
98
98
|
| [도구 자세히](docs/ko/tools.md) | `Outline` · `Verify` · `Task` · `Jobs` · `Append` · `Def`/`Refs` · 편집 매칭 |
|
|
99
|
-
| [한글 문서와 엑셀](docs/ko/documents.md) | hwpx·docx·pptx · 인코딩 · 엑셀 → CSV |
|
|
99
|
+
| [한글 문서와 엑셀](docs/ko/documents.md) | hwpx·docx·pptx·**PDF** · 인코딩 · 엑셀 → CSV |
|
|
100
100
|
| [늘려 쓰기](docs/ko/extend.md) | 스킬 · 플러그인 · MCP · ACP |
|
|
101
101
|
| [속도와 씀씀이](docs/ko/tuning.md) | 단계별 추론 강도 · 프리픽스 캐시 · 컨텍스트 길이 |
|
|
102
102
|
| [안전망과 사내 반입](docs/ko/safety.md) | 되돌리기 · 작업 범위 · 감사기록 · 심사 서류 |
|
|
103
103
|
| [설정](docs/ko/config.md) · [개발](docs/ko/develop.md) | 환경변수 · 실행 옵션 · 검사 돌리기 · 폴더 구조 |
|
|
104
|
-
| [릴리스 노트](docs/ko/releases.md) | [1.5.8](docs/ko/releases.md#158) · [1.5.7](docs/ko/releases.md#157) · [1.5.6](docs/ko/releases.md#156) · [1.5.5](docs/ko/releases.md#155) · [1.5.4](docs/ko/releases.md#154) · [1.5.3](docs/ko/releases.md#153) · [1.5.2](docs/ko/releases.md#152) · [1.5.1](docs/ko/releases.md#151) · [1.5.0](docs/ko/releases.md#150) · [1.4.3](docs/ko/releases.md#143) · [1.4.2](docs/ko/releases.md#142) · [1.4.1](docs/ko/releases.md#141) · [1.4.0](docs/ko/releases.md#140) · [1.3.0](docs/ko/releases.md#130) · [1.2.0](docs/ko/releases.md#120) |
|
|
104
|
+
| [릴리스 노트](docs/ko/releases.md) | [1.6.1](docs/ko/releases.md#161) · [1.6.0](docs/ko/releases.md#160) · [1.5.8](docs/ko/releases.md#158) · [1.5.7](docs/ko/releases.md#157) · [1.5.6](docs/ko/releases.md#156) · [1.5.5](docs/ko/releases.md#155) · [1.5.4](docs/ko/releases.md#154) · [1.5.3](docs/ko/releases.md#153) · [1.5.2](docs/ko/releases.md#152) · [1.5.1](docs/ko/releases.md#151) · [1.5.0](docs/ko/releases.md#150) · [1.4.3](docs/ko/releases.md#143) · [1.4.2](docs/ko/releases.md#142) · [1.4.1](docs/ko/releases.md#141) · [1.4.0](docs/ko/releases.md#140) · [1.3.0](docs/ko/releases.md#130) · [1.2.0](docs/ko/releases.md#120) |
|
|
105
105
|
|
|
106
106
|
---
|
|
107
107
|
|
|
@@ -342,7 +342,7 @@ LM Studio 는 `/api/v0/models`, llama.cpp 는 `/props`. 못 알아보면 `(추
|
|
|
342
342
|
|---|---|
|
|
343
343
|
| `/help` | 명령 목록 |
|
|
344
344
|
| `/bell [on|off]` | 다 됐을 때·물어볼 때 종소리와 창 제목 |
|
|
345
|
-
| `/lang [ko|en] [시킬말]` | 화면
|
|
345
|
+
| `/lang [ko|en|ja|zh] [시킬말]` | 화면 말 (한국어·English·日本語·中文 네 가지, 전부 다 채워져 있다). **시킬 말을 따로 줄 수 있다** — `/lang ko en` 이면 모델에게는 영어로 시키고 답은 한국어로 받는다(8k 창에서 고정 몫 23% 감소). 코드는 그대로 |
|
|
346
346
|
| `/keys` | 이 터미널이 무슨 키를 보내는지 눌러서 확인 — 줄바꿈이 안 될 때 |
|
|
347
347
|
| `/consult <프로필> <질문>` | 다른 모델에게 한 번 물어보기 — 지금 쓰는 것은 안 바꿈 |
|
|
348
348
|
| `/export` | 이 대화를 **보고서 한 장**(HTML)으로 — 시킨 것·바뀐 것·확인한 것. 폐쇄망에서 여는 자기완결 파일 |
|
|
@@ -357,6 +357,7 @@ LM Studio 는 `/api/v0/models`, llama.cpp 는 `/props`. 못 알아보면 `(추
|
|
|
357
357
|
| `/learned [지우기]` | 쓰면서 저절로 알게 된 것 — 되는 명령·이 모델의 버릇 |
|
|
358
358
|
| `/pin <말>` | 못 박기 — 접거나 요약해도 **안 지워지는** 말 |
|
|
359
359
|
| `/evidence [파일]` | 증거 — 무엇을 바꿨고 무엇이 그걸 증명하나. **안 된 것도** 적습니다 |
|
|
360
|
+
| `/commit [전부\|미리보기\|제목]` | 이번 대화가 바꾼 것만 담아 커밋. 메시지는 diff 와 증거에서. **push 는 안 합니다** |
|
|
360
361
|
| `/model` | 연결·모델 바꾸기 |
|
|
361
362
|
| `/model 카드` | 이 모델을 겪어 본 결과 — 그래서 deel 이 무엇을 바꿔 뒀는지 |
|
|
362
363
|
| `/think <강도>` | 추론 강도 (`off·low·medium·high·max`) |
|
|
@@ -396,10 +397,11 @@ LM Studio 는 `/api/v0/models`, llama.cpp 는 `/props`. 못 알아보면 `(추
|
|
|
396
397
|
| `Ctrl+O` | 작업 모드 (`종합` → `코드` → `계획` → …) |
|
|
397
398
|
| `↑` `↓` | 지난 입력 이력 |
|
|
398
399
|
| `Ctrl+C` | 답하는 중이면 그 답만 끊고, 빈 줄에서 두 번이면 끝냅니다 |
|
|
400
|
+
| 일하는 중에 그냥 치고 `Enter` | 하던 일을 안 버리고 방향만 틉니다 — 다음 걸음부터 반영 |
|
|
399
401
|
|
|
400
402
|
한글 조합·붙여넣기·`Ctrl+A/E`·백스페이스는 전부 그대로 됩니다.
|
|
401
403
|
|
|
402
|
-
> **자세히** — @파일 로 바로 붙이기 · 도중에 멈추기
|
|
404
|
+
> **자세히** — @파일 로 바로 붙이기 · 도중에 멈추기 · 멈추지 않고 방향만 틀기
|
|
403
405
|
>
|
|
404
406
|
> **[화면과 조작 읽기 →](docs/ko/interface.md#대화-중-명령)**
|
|
405
407
|
|
|
@@ -468,7 +470,7 @@ LM Studio 는 `/api/v0/models`, llama.cpp 는 `/props`. 못 알아보면 `(추
|
|
|
468
470
|
|
|
469
471
|
| 도구 | 하는 일 |
|
|
470
472
|
|---|---|
|
|
471
|
-
| `Read` | 파일 읽기 (줄 번호 · `offset`/`limit` 지원 · **엑셀은 CSV 로, hwpx·docx·pptx 는 글로 바꿔서**) |
|
|
473
|
+
| `Read` | 파일 읽기 (줄 번호 · `offset`/`limit` 지원 · **엑셀은 CSV 로, hwpx·docx·pptx·PDF 는 글로 바꿔서**) |
|
|
472
474
|
| `Write` | 파일 쓰기·덮어쓰기 (**여러 개는 `files` 배열로 한 번에**) |
|
|
473
475
|
| `Append` | 파일 끝에 이어 붙이기 — **큰 파일을 나눠 쓰는 자리** |
|
|
474
476
|
| `Edit` | 정확한 문자열 바꾸기 (`replace_all` · **여러 군데는 `edits` 배열로 한 번에**) |
|
|
@@ -504,10 +506,19 @@ Claude Code 에 없는 것은 아홉입니다 — `Append` · `Move` · `Ask` ·
|
|
|
504
506
|
## 한글 문서와 엑셀
|
|
505
507
|
|
|
506
508
|
**CP949 로 저장된 파일은 CP949 로 되돌려 씁니다.** 인코딩을 바꾸지 않습니다.
|
|
507
|
-
엑셀(`.xlsx`)은 CSV 로, 한글·워드·파워포인트(`.hwpx`/`.docx`/`.pptx`)
|
|
508
|
-
바꿔서 읽습니다 — 전부 읽기 전용입니다.
|
|
509
|
+
엑셀(`.xlsx`)은 CSV 로, 한글·워드·파워포인트(`.hwpx`/`.docx`/`.pptx`)와
|
|
510
|
+
**PDF** 는 글로 바꿔서 읽습니다 — 전부 읽기 전용입니다.
|
|
509
511
|
|
|
510
|
-
|
|
512
|
+
PDF 는 **못 읽은 쪽을 못 읽었다고 말합니다.** 스캔본·암호·글꼴 표가 없는 쪽은
|
|
513
|
+
빈 글로 넘기지 않고 그 자리에 까닭을 적습니다 — 빈 글은 「그런 내용이 없다」로
|
|
514
|
+
읽히기 때문입니다.
|
|
515
|
+
|
|
516
|
+
옛 형식(`.ppt`·`.doc`·`.xls`·`.rtf`)은 **이 PC 에 깔린 LibreOffice 를 빌려서**
|
|
517
|
+
읽습니다 — `rg` 를 빌려 쓰는 것과 같은 원칙으로, 아무것도 설치하지 않습니다.
|
|
518
|
+
없으면 **없다고 못 박고 끝냅니다**(무엇이 없어서 못 하는지, 무엇을 하면 되는지,
|
|
519
|
+
그리고 「다시 열지 말라」까지). 끄려면 `DEEL_CONVERT=off`.
|
|
520
|
+
|
|
521
|
+
> **자세히** — 인코딩 · 엑셀 · hwpx/docx/pptx · PDF · 변환기 빌려 쓰기
|
|
511
522
|
>
|
|
512
523
|
> **[한글 문서와 엑셀 읽기 →](docs/ko/documents.md#한글-문서와-엑셀)**
|
|
513
524
|
|
|
@@ -742,6 +753,7 @@ deel acp
|
|
|
742
753
|
| 승인 창 | deel 의 안전망이 그대로 에디터 창으로 뜹니다 (`이번만` · `앞으로 묻지 않기` · `안 함`) |
|
|
743
754
|
| 모드 고르개 | deel 의 작업 모드 7개 (`종합` · `코드` · `계획` · `설계` · `디버그` · `묻기` · `총괄`) |
|
|
744
755
|
| 멈춤 단추 | 도중에 닿습니다 — 답을 기다리는 중에도 |
|
|
756
|
+
| 지난 대화 | 껐다 켜도 그대로 열립니다. 터미널과 **같은 자리**에 남아서, 에디터에서 하던 것을 `deel --resume` 으로 이어받는 것도 됩니다 |
|
|
745
757
|
|
|
746
758
|
**의존성은 그대로 0 입니다.** MCP 와 같은 이유입니다 — 줄 단위 JSON-RPC 2.0 이
|
|
747
759
|
전부라 SDK 가 필요 없습니다.
|
|
@@ -896,13 +908,15 @@ deel sbom --only sbom # SBOM 한 장만
|
|
|
896
908
|
| `주소를 찾을 수 없습니다` | 주소 오타, DNS, 사내망 접속 여부 |
|
|
897
909
|
| `연결이 거부되었습니다` | 서버가 꺼져 있거나 포트가 다름 |
|
|
898
910
|
| `인증서 문제` | `set NODE_EXTRA_CA_CERTS=C:\경로\사내CA.pem` |
|
|
899
|
-
| 프록시를 거쳐야 함 | `set HTTPS_PROXY=http://프록시:포트` |
|
|
911
|
+
| 프록시를 거쳐야 함 | `set HTTPS_PROXY=http://프록시:포트` (인증은 `http://user:pw@프록시:포트`). 첫 화면과 `/status` 에 `프록시 …` 가 뜨면 거치는 것. 안 거칠 곳은 `NO_PROXY=.corp.com,10.1.2.3`, 아예 끄려면 설정에 `"proxy": "none"` |
|
|
912
|
+
| 프록시가 407 을 줌 | 프록시 주소에 `user:pw@` 를 넣으세요. NTLM · Negotiate 만 받는 프록시는 못 씁니다 — 담당자에게 Basic 이나 인증 없는 주소를 문의 |
|
|
900
913
|
| 401 / 403 | 키가 틀렸거나 인증 헤더 형식이 다름 (4가지를 자동 시도합니다) |
|
|
901
914
|
| `허용되지 않은 주소입니다` | 자물쇠가 막은 것. 정상입니다 — `/model` 로 연결을 고르세요 |
|
|
902
915
|
| 도구 호출이 안 먹음 | `deel diagnose` 로 판정을 보세요. 작은 모델(1B~3B)은 자주 못 합니다 |
|
|
903
916
|
| 대답이 비어 있음 | 스트리밍을 무시하는 서버입니다. 한 번은 저절로 다시 부르고, 그래도 비면 이 대화에서는 스트리밍을 끕니다 |
|
|
904
917
|
| 큰 파일이 중간에 끊김 | `/out` 으로 지금 상한을 보고 올리세요. 상한을 몰라 16,384 로 서 있을 수 있습니다 |
|
|
905
918
|
| `HTTP 400` 만 뜸 | 서버가 보낸 문장을 그대로 보여 줍니다. 길이 문제면 숫자를 읽어 저절로 맞춥니다 |
|
|
919
|
+
| `429` · `503` 이 뜸 | 게이트웨이가 잠깐 막은 것입니다. 세 번까지 저절로 기다렸다 다시 부릅니다(`Retry-After` 를 지킵니다). 그래도 계속 뜨면 할당량을 보세요 |
|
|
906
920
|
| `deel scan` 이 0곳 | 로컬 서버가 꺼져 있거나 다른 포트 — `--ports` 로 지정 |
|
|
907
921
|
|
|
908
922
|
---
|
|
@@ -910,7 +924,7 @@ deel sbom --only sbom # SBOM 한 장만
|
|
|
910
924
|
## 개발
|
|
911
925
|
|
|
912
926
|
```bash
|
|
913
|
-
npm test 전체 검증 (
|
|
927
|
+
npm test 전체 검증 (4,932항목)
|
|
914
928
|
npm run coverage 검사가 소스의 어디를 밟았는지
|
|
915
929
|
npm run verify 반입·통신 검증만
|
|
916
930
|
npm run bench 편집 성공률 측정
|
|
@@ -948,7 +962,7 @@ zip 은 진짜 `unzip` 으로, tar 는 진짜 `tar` 가 만든 것을 읽혀 교
|
|
|
948
962
|
| `guard` | 24 | **안 하는 자리** — 거부·모르는 도구·두 번 실행·범위 밖 |
|
|
949
963
|
| `network` | 30 | 정해진 자리 밖으로 새지 않는가 |
|
|
950
964
|
| `web` | 25 | 웹 읽기가 읽기만 하는가 |
|
|
951
|
-
| `abort` | 16 | Ctrl+C 로 끊어도 대화가 성한가 |
|
|
965
|
+
| `abort` · `steer` | 16 · 15 | Ctrl+C 로 끊어도 대화가 성한가 · 도중에 낀 말이 다음 부름에 실리는가 |
|
|
952
966
|
| `parallel` | 23 | 읽기만 동시에 도는가 · 할 일 목록 |
|
|
953
967
|
| `cli` | 75 | **진짜 `deel` 을 띄워** 끝까지 돌려 본다 |
|
|
954
968
|
| `setup` | 42 | 첫 실행 마법사 (가짜 TTY 로 사람처럼 입력) |
|
|
@@ -975,6 +989,8 @@ zip 은 진짜 `unzip` 으로, tar 는 진짜 `tar` 가 만든 것을 읽혀 교
|
|
|
975
989
|
|
|
976
990
|
| 판 | 무엇이 바뀌었나 |
|
|
977
991
|
|---|---|
|
|
992
|
+
| **[1.6.1](docs/ko/releases.md#161)** | 헛도는 턴을 만들던 자리들 — 울타리가 `/dev/null` 까지 막던 것 · 옷 문서를 못 읽던 것 · 파일에서 그림이 사라지던 것 |
|
|
993
|
+
| **[1.6.0](docs/ko/releases.md#160)** | 사내망에서 안 되던 것들 — 프록시 · 429 · 윈도우 셸 · 5만 개 저장소 · PDF · 캡처 붙여넣기 · 에디터 이어하기 |
|
|
978
994
|
| **[1.5.8](docs/ko/releases.md#158)** | 5MB 문서를 919줄 중 8줄만 보던 것 · 정규식을 경로로 읽어 명령을 막던 것 |
|
|
979
995
|
| **[1.5.7](docs/ko/releases.md#157)** | 맥 한글 폴더에서 제 파일이 「범위 밖」이던 것 · 붙여넣기 · ESC |
|
|
980
996
|
| **[1.5.6](docs/ko/releases.md#156)** | 막히면 물어본다 — 글로 묻고 턴을 끝내는 대신에 |
|
package/bin/deel.js
CHANGED
|
@@ -13,6 +13,7 @@ import { closeConnections } from '../src/backend/http.js';
|
|
|
13
13
|
import { parseSize } from '../src/backend/ctxsize.js';
|
|
14
14
|
import { runSessions } from '../src/agent/sessionui.js';
|
|
15
15
|
import { acp } from '../src/acp/serve.js';
|
|
16
|
+
import { runCompletion } from '../src/completion.js';
|
|
16
17
|
|
|
17
18
|
const MIN_NODE = 20;
|
|
18
19
|
|
|
@@ -137,6 +138,7 @@ function help() {
|
|
|
137
138
|
say(` ${c.cyan('deel setup')} 연결 설정 (주소·키·모델)`);
|
|
138
139
|
say(` ${c.cyan('deel status')} 연결 상태 보기`);
|
|
139
140
|
say(` ${c.cyan('deel diagnose')} 저장된 연결로 진단 다시 돌리기`);
|
|
141
|
+
say(` ${c.cyan('deel completion <셸>')} 탭 완성 스크립트 ${c.gray('(bash · zsh · powershell)')}`);
|
|
140
142
|
say(` ${c.cyan('deel --version')} 판 번호 ${c.gray('(-v 도 됩니다)')}`);
|
|
141
143
|
say('');
|
|
142
144
|
say(` ${c.bold('여러 로컬을 같이 쓸 때')}`);
|
|
@@ -298,6 +300,14 @@ async function main() {
|
|
|
298
300
|
case 'sessions':
|
|
299
301
|
case 'ls':
|
|
300
302
|
return runSessions(flags);
|
|
303
|
+
/*
|
|
304
|
+
* 탭 완성 스크립트를 낸다 (src/completion.js).
|
|
305
|
+
*
|
|
306
|
+
* 표준출력으로만 낸다 — `deel completion bash > ~/.deel-completion.bash`
|
|
307
|
+
* 처럼 바로 파이프에 물릴 수 있어야 한다. 그래서 여기서는 say() 를 안 쓴다.
|
|
308
|
+
*/
|
|
309
|
+
case 'completion':
|
|
310
|
+
return runCompletion(args);
|
|
301
311
|
default:
|
|
302
312
|
say('');
|
|
303
313
|
say(` ${c.red('모르는 명령')} ${c.bold(cmd)}`);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "deel-local-cli",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.6.1",
|
|
4
4
|
"description": "로컬 모델·사내 게이트웨이 전용 코딩 에이전트 CLI — 외부 의존성 0개 / Zero-dependency coding agent CLI for local LLMs and private gateways",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
"verify": "node test/no-bundle.test.js && node test/network.test.js && node test/web.test.js",
|
|
52
52
|
"bench": "node test/edit-bench.js",
|
|
53
53
|
"demo": "node test/demo.js",
|
|
54
|
-
"check": "node --check bin/deel.js && node --check src/repl.js && node --check src/oneshot.js && node --check src/commands.js && node --check src/agent/loop.js && node --check src/agent/session.js && node --check src/agent/effort.js && node --check src/agent/modes.js && node --check src/agent/route.js && node --check src/agent/models.js && node --check src/agent/grade.js && node --check src/agent/mention.js && node --check src/agent/project.js && node --check src/tools/encoding.js && node --check src/tools/excel-com.js && node --check src/tools/excel.js && node --check src/tools/xlsx.js && node --check src/tools/docs.js && node --check src/agent/compact.js && node --check src/agent/store.js && node --check src/agent/sessionui.js && node --check src/backend/adapter.js && node --check src/backend/ctxsize.js && node --check src/backend/probe.js && node --check src/backend/detect.js && node --check src/backend/http.js && node --check src/backend/scan.js && node --check src/backend/scanui.js && node --check src/tools/index.js && node --check src/tools/desc.en.js && node --check src/tools/lsp.js && node --check src/lsp/rpc.js && node --check src/lsp/servers.js && node --check src/lsp/client.js && node --check src/lsp/diag.js && node --check src/tools/fsutil.js && node --check src/tools/edit-match.js && node --check src/tools/webfetch.js && node --check src/tools/todo.js && node --check src/tools/jobs.js && node --check src/skills/discover.js && node --check src/plugins/manage.js && node --check src/pack/zip.js && node --check src/pack/tar.js && node --check src/pack/selfpack.js && node --check src/safety/guard.js && node --check src/safety/undo.js && node --check src/safety/audit.js && node --check src/safety/network.js && node --check src/setup.js && node --check src/report.js && node --check src/config.js && node --check src/ui/diff.js && node --check src/ui/ansi.js && node --check src/ui/status.js && node --check src/ui/level.js && node --check src/ui/prompt.js && node --check src/ui/spinner.js && node --check src/ui/motion.js && node --check src/ui/office.js && node --check src/ui/notify.js && node --check src/ui/intro.js && node --check src/ui/banner.js && node --check src/ui/export.js && node --check src/i18n/index.js && node --check src/i18n/ko.js && node --check src/i18n/en.js && node --check src/preview/serve.js && node --check src/ui/working.js && node --check src/ui/inputbox.js && node --check src/ui/wrap.js && node --check src/ui/md.js && node --check src/agent/threads.js && node --check src/agent/evolve.js && node --check src/agent/pins.js && node --check src/agent/card.js && node --check src/agent/preset.js && node --check src/agent/evidence.js && node --check src/acp/jsonrpc.js && node --check src/acp/map.js && node --check src/acp/serve.js && node --check src/pack/sbom.js && node --check src/safety/secrets.js && echo OK",
|
|
54
|
+
"check": "node --check bin/deel.js && node --check src/repl.js && node --check src/oneshot.js && node --check src/commands.js && node --check src/agent/loop.js && node --check src/agent/session.js && node --check src/agent/effort.js && node --check src/agent/modes.js && node --check src/agent/route.js && node --check src/agent/models.js && node --check src/agent/grade.js && node --check src/agent/mention.js && node --check src/agent/project.js && node --check src/tools/encoding.js && node --check src/tools/excel-com.js && node --check src/tools/excel.js && node --check src/tools/xlsx.js && node --check src/tools/docs.js && node --check src/tools/convert.js && node --check src/tools/pdf.js && node --check src/tools/clipboard.js && node --check src/agent/compact.js && node --check src/agent/store.js && node --check src/agent/sessionui.js && node --check src/backend/adapter.js && node --check src/backend/ctxsize.js && node --check src/backend/probe.js && node --check src/backend/detect.js && node --check src/backend/http.js && node --check src/backend/retry.js && node --check src/backend/proxy.js && node --check src/backend/azure.js && node --check src/backend/vision.js && node --check src/backend/quota.js && node --check src/backend/scan.js && node --check src/backend/scanui.js && node --check src/tools/index.js && node --check src/tools/desc.en.js && node --check src/tools/lsp.js && node --check src/lsp/rpc.js && node --check src/lsp/servers.js && node --check src/lsp/client.js && node --check src/lsp/diag.js && node --check src/tools/fsutil.js && node --check src/tools/ignore.js && node --check src/tools/fastgrep.js && node --check src/tools/edit-match.js && node --check src/tools/webfetch.js && node --check src/tools/todo.js && node --check src/tools/jobs.js && node --check src/tools/shell.js && node --check src/skills/discover.js && node --check src/plugins/manage.js && node --check src/pack/zip.js && node --check src/pack/tar.js && node --check src/pack/selfpack.js && node --check src/safety/guard.js && node --check src/safety/undo.js && node --check src/safety/audit.js && node --check src/safety/keystore.js && node --check src/safety/policy.js && node --check src/safety/network.js && node --check src/setup.js && node --check src/report.js && node --check src/config.js && node --check src/completion.js && node --check src/ui/diff.js && node --check src/ui/ansi.js && node --check src/ui/status.js && node --check src/ui/level.js && node --check src/ui/prompt.js && node --check src/ui/spinner.js && node --check src/ui/motion.js && node --check src/ui/office.js && node --check src/ui/notify.js && node --check src/ui/intro.js && node --check src/ui/banner.js && node --check src/ui/export.js && node --check src/i18n/index.js && node --check src/i18n/ko.js && node --check src/i18n/en.js && node --check src/i18n/ja.js && node --check src/i18n/zh.js && node --check src/preview/serve.js && node --check src/ui/working.js && node --check src/ui/inputbox.js && node --check src/ui/wrap.js && node --check src/ui/md.js && node --check src/agent/threads.js && node --check src/agent/evolve.js && node --check src/agent/pins.js && node --check src/agent/card.js && node --check src/agent/preset.js && node --check src/agent/evidence.js && node --check src/agent/commit.js && node --check src/agent/review.js && node --check src/acp/jsonrpc.js && node --check src/acp/map.js && node --check src/acp/serve.js && node --check src/pack/sbom.js && node --check src/safety/secrets.js && echo OK",
|
|
55
55
|
"coverage": "node test/coverage.mjs",
|
|
56
56
|
"prepublishOnly": "npm run check && npm test"
|
|
57
57
|
},
|
package/src/acp/map.js
CHANGED
|
@@ -175,6 +175,149 @@ export function 멈춘까닭(까닭) {
|
|
|
175
175
|
}
|
|
176
176
|
}
|
|
177
177
|
|
|
178
|
+
/**
|
|
179
|
+
* 메시지 하나에서 사람이 읽을 글만 뽑는다.
|
|
180
|
+
*
|
|
181
|
+
* content 는 글 한 덩어리일 때도 있고, 그림이 섞인 배열일 때도 있다
|
|
182
|
+
* (backend/vision.js). 배열에서 글만 빼고 그림은 조용히 버리면, 되살린
|
|
183
|
+
* 화면에서 "이 말을 왜 했는지" 가 사라진다 — 몇 장이 붙어 있었는지는 적는다.
|
|
184
|
+
*/
|
|
185
|
+
function 글만(m) {
|
|
186
|
+
const c = m?.content;
|
|
187
|
+
let 글 = '';
|
|
188
|
+
let 장수 = Array.isArray(m?.images) ? m.images.length : 0; // ollama 규격
|
|
189
|
+
if (typeof c === 'string') 글 = c;
|
|
190
|
+
else if (Array.isArray(c)) {
|
|
191
|
+
const 조각 = [];
|
|
192
|
+
for (const p of c) {
|
|
193
|
+
if (p?.type === 'text' && typeof p.text === 'string') 조각.push(p.text);
|
|
194
|
+
else if (p?.type === 'image_url') 장수++;
|
|
195
|
+
}
|
|
196
|
+
글 = 조각.join('\n');
|
|
197
|
+
}
|
|
198
|
+
글 = 글.trim();
|
|
199
|
+
if (장수) 글 = 글 ? `${글}\n\n_(그림 ${장수}장)_` : `_(그림 ${장수}장)_`;
|
|
200
|
+
return 글;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/** 저장된 도구 인자. 규격에 따라 글일 수도, 이미 풀린 것일 수도 있다. */
|
|
204
|
+
function 인자풀기(x) {
|
|
205
|
+
if (x && typeof x === 'object') return x;
|
|
206
|
+
if (typeof x !== 'string' || !x.trim()) return {};
|
|
207
|
+
try { return JSON.parse(x); } catch { return {}; }
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* 저장된 대화를 에디터에 다시 흘려 줄 알림 묶음으로.
|
|
212
|
+
*
|
|
213
|
+
* ── 왜 이 자리가 필요한가 ───────────────────────────────────────────────
|
|
214
|
+
*
|
|
215
|
+
* session/load 는 "지난 대화를 되살려라" 는 부름인데, 규격에는 되살린 것을
|
|
216
|
+
* **답으로 돌려주는 자리가 없다.** 오간 말을 전부 session/update 로 다시
|
|
217
|
+
* 흘려야 한다. 그러니까 에디터가 그리는 지난 대화는 여기서 만든 것이 전부다 —
|
|
218
|
+
* 여기서 빠뜨린 것은 화면에서 통째로 사라지고, 사람은 기록이 날아간 줄 안다.
|
|
219
|
+
*
|
|
220
|
+
* 도구 호출은 시작·끝 두 번으로 안 나눈다. 이미 끝난 일을 '도는 중' 으로 한 번
|
|
221
|
+
* 그렸다가 고칠 까닭이 없다. 끝난 모습 한 덩이만 준다.
|
|
222
|
+
*
|
|
223
|
+
* @param {object[]} messages store.js 가 읽어 온 대화
|
|
224
|
+
* @returns {object[]} session/update 의 update 자리에 그대로 넣을 것들
|
|
225
|
+
*/
|
|
226
|
+
export function 되살린것(messages, { 최대내용 = 2000 } = {}) {
|
|
227
|
+
const 줄 = Array.isArray(messages) ? messages : [];
|
|
228
|
+
|
|
229
|
+
/*
|
|
230
|
+
* 도구 답을 먼저 줄 세운다.
|
|
231
|
+
*
|
|
232
|
+
* 답(role:'tool')은 부름보다 뒤에 온다. 앞에서부터 한 번에 그리려면 미리
|
|
233
|
+
* 찾아 둬야 한다. OpenAI 규격은 id 로 짝을 짓고, ollama 규격은 id 를 안 주므로
|
|
234
|
+
* 이름별 차례로 짝을 짓는다 (session.js 의 repairToolPairs 와 같은 눈).
|
|
235
|
+
*/
|
|
236
|
+
const id로 = new Map();
|
|
237
|
+
const 이름으로 = new Map();
|
|
238
|
+
for (const m of 줄) {
|
|
239
|
+
if (m?.role !== 'tool') continue;
|
|
240
|
+
if (m.tool_call_id != null) id로.set(m.tool_call_id, m.content);
|
|
241
|
+
else if (m.tool_name) {
|
|
242
|
+
const q = 이름으로.get(m.tool_name) ?? [];
|
|
243
|
+
q.push(m.content);
|
|
244
|
+
이름으로.set(m.tool_name, q);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
const 나온것 = [];
|
|
249
|
+
let 말번호 = 0;
|
|
250
|
+
let 도구번호 = 0;
|
|
251
|
+
|
|
252
|
+
for (const m of 줄) {
|
|
253
|
+
if (!m || typeof m !== 'object') continue;
|
|
254
|
+
// 시스템 프롬프트는 사람이 한 말이 아니다. 되살리면 매번 대화 머리에
|
|
255
|
+
// 수천 자짜리 지시문이 붙어서, 정작 무슨 얘기를 했는지가 안 보인다.
|
|
256
|
+
if (m.role === 'system' || m.role === 'tool') continue;
|
|
257
|
+
|
|
258
|
+
if (m.role === 'user') {
|
|
259
|
+
const 글 = 글만(m);
|
|
260
|
+
if (글) 나온것.push({ sessionUpdate: 'user_message_chunk', content: { type: 'text', text: 글 } });
|
|
261
|
+
continue;
|
|
262
|
+
}
|
|
263
|
+
if (m.role !== 'assistant') continue;
|
|
264
|
+
|
|
265
|
+
말번호++;
|
|
266
|
+
const 생각 = typeof m.thinking === 'string' ? m.thinking.trim() : '';
|
|
267
|
+
if (생각) {
|
|
268
|
+
나온것.push({
|
|
269
|
+
sessionUpdate: 'agent_thought_chunk',
|
|
270
|
+
content: { type: 'text', text: 자르기(생각, 최대내용) },
|
|
271
|
+
messageId: `h${말번호}`,
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
const 글 = 글만(m);
|
|
275
|
+
if (글) {
|
|
276
|
+
나온것.push({
|
|
277
|
+
sessionUpdate: 'agent_message_chunk',
|
|
278
|
+
content: { type: 'text', text: 글 },
|
|
279
|
+
messageId: `h${말번호}`,
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
for (const tc of Array.isArray(m.tool_calls) ? m.tool_calls : []) {
|
|
284
|
+
const fn = tc?.function ?? tc ?? {};
|
|
285
|
+
const 이름 = String(fn.name ?? tc?.name ?? '도구');
|
|
286
|
+
const 인자 = 인자풀기(fn.arguments ?? fn.args ?? tc?.args);
|
|
287
|
+
|
|
288
|
+
let 답;
|
|
289
|
+
if (tc?.id != null && id로.has(tc.id)) 답 = id로.get(tc.id);
|
|
290
|
+
else {
|
|
291
|
+
const q = 이름으로.get(이름);
|
|
292
|
+
if (q?.length) 답 = q.shift();
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
/*
|
|
296
|
+
* 답이 안 남은 부름 = 그때 프로그램이 도구 도는 중에 끊긴 것이다.
|
|
297
|
+
*
|
|
298
|
+
* 성공으로 그리면 안 된다. 그 도구가 끝까지 갔는지 아닌지가 다음에 무엇을
|
|
299
|
+
* 시킬지를 정한다 — 파일을 고치던 중이었을 수도 있다.
|
|
300
|
+
*/
|
|
301
|
+
const 없음 = 답 === undefined || 답 === null;
|
|
302
|
+
나온것.push({
|
|
303
|
+
sessionUpdate: 'tool_call',
|
|
304
|
+
toolCallId: `h${말번호}-${++도구번호}`,
|
|
305
|
+
title: 도구이름표(이름, 인자),
|
|
306
|
+
kind: 도구갈래(이름),
|
|
307
|
+
// 남은 글만 보고 성공·실패를 점치지 않는다. 도구마다 실패를 적는 말이
|
|
308
|
+
// 달라서, 맞히려 들면 멀쩡한 것을 빨갛게 칠하게 된다.
|
|
309
|
+
status: 없음 ? 'failed' : 'completed',
|
|
310
|
+
content: 없음
|
|
311
|
+
? [{ type: 'content', content: { type: 'text', text: '결과가 안 남았습니다 — 이 도구가 도는 중에 끊겼습니다.' } }]
|
|
312
|
+
: [{ type: 'content', content: { type: 'text', text: 자르기(String(답), 최대내용) } }],
|
|
313
|
+
locations: 도구자리(이름, 인자, null),
|
|
314
|
+
});
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
return 나온것;
|
|
319
|
+
}
|
|
320
|
+
|
|
178
321
|
/**
|
|
179
322
|
* 프롬프트로 온 덩이들에서 글만 뽑는다.
|
|
180
323
|
*
|