@piagent/platform 1.46.1 → 1.46.4
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/CHANGELOG.md +42 -0
- package/docs/command-reference-vietnamese.md +2 -2
- package/docs/distribution-standard.md +6 -6
- package/docs/operator-manual-vietnamese.md +7 -7
- package/docs/publishing-for-teams.md +3 -0
- package/docs/release-install-policy.md +2 -2
- package/docs/team-onboarding.md +2 -2
- package/docs-site/architecture.html +1 -1
- package/docs-site/assets/search-en.json +1 -1
- package/docs-site/assets/search-vi.json +1 -1
- package/docs-site/benchmark.html +1 -1
- package/docs-site/commands.html +1 -1
- package/docs-site/context-engine.html +1 -1
- package/docs-site/ecosystem.html +1 -1
- package/docs-site/en/architecture.html +1 -1
- package/docs-site/en/benchmark.html +1 -1
- package/docs-site/en/commands.html +1 -1
- package/docs-site/en/context-engine.html +1 -1
- package/docs-site/en/ecosystem.html +1 -1
- package/docs-site/en/index.html +15 -15
- package/docs-site/en/mcp-approval.html +1 -1
- package/docs-site/en/mcp-auth.html +1 -1
- package/docs-site/en/mcp-servers.html +1 -1
- package/docs-site/en/mcp.html +1 -1
- package/docs-site/en/permissions.html +1 -1
- package/docs-site/en/profiles.html +1 -1
- package/docs-site/en/quickstart.html +1 -1
- package/docs-site/en/runtime.html +1 -1
- package/docs-site/en/scope.html +1 -1
- package/docs-site/en/security.html +1 -1
- package/docs-site/en/team.html +1 -1
- package/docs-site/en/update.html +3 -3
- package/docs-site/en/whats-new.html +77 -46
- package/docs-site/en/windows.html +1 -1
- package/docs-site/en/workflows.html +1 -1
- package/docs-site/index.html +15 -15
- package/docs-site/mcp-approval.html +1 -1
- package/docs-site/mcp-auth.html +1 -1
- package/docs-site/mcp-servers.html +1 -1
- package/docs-site/mcp.html +1 -1
- package/docs-site/permissions.html +1 -1
- package/docs-site/profiles.html +1 -1
- package/docs-site/quickstart.html +1 -1
- package/docs-site/releases.json +93 -0
- package/docs-site/runtime.html +1 -1
- package/docs-site/scope.html +1 -1
- package/docs-site/security.html +1 -1
- package/docs-site/team.html +1 -1
- package/docs-site/update.html +3 -3
- package/docs-site/whats-new.html +77 -46
- package/docs-site/windows.html +1 -1
- package/docs-site/workflows.html +1 -1
- package/evals/private-holdout-v1/public-exposure.v2.json +1 -1
- package/package.json +1 -1
- package/packages/piagent-core/extensions/piagent-guard.ts +4 -1
- package/packages/piagent-core/managed/copies.mjs +14 -4
- package/packages/piagent-core/managed/session.mjs +3 -3
- package/packages/piagent-core/package.json +1 -1
- package/packages/piagent-core/runtime/hooks/session-hooks.ts +6 -0
- package/packages/piagent-core/runtime/managed-failure.mjs +0 -1
- package/packages/piagent-webui/gateway/gateway-session-stream.ts +24 -0
- package/scripts/claude-model-additions.mjs +8 -1
- package/scripts/configure-model-scope.sh +6 -1
- package/scripts/install-global.sh +10 -4
- package/scripts/personal-pi-config.mjs +5 -2
- package/scripts/pi-models-json.mjs +13 -0
package/docs-site/releases.json
CHANGED
|
@@ -1,4 +1,97 @@
|
|
|
1
1
|
[
|
|
2
|
+
{
|
|
3
|
+
"version": "1.46.4",
|
|
4
|
+
"date": "2026-10-29",
|
|
5
|
+
"status": "stable",
|
|
6
|
+
"title": {
|
|
7
|
+
"en": "One subagent instead of a refused request; update reads a commented models.json",
|
|
8
|
+
"vi": "Một subagent thay vì bị chặn; bản cập nhật đọc được models.json có comment"
|
|
9
|
+
},
|
|
10
|
+
"summary": {
|
|
11
|
+
"en": "Company sessions no longer loop on a refused subagent call, and the update no longer stops when the Pi model list file has comments.",
|
|
12
|
+
"vi": "Session công ty không còn lặp lại lệnh gọi subagent bị chặn, và bản cập nhật không còn dừng khi file danh sách model của Pi có comment."
|
|
13
|
+
},
|
|
14
|
+
"requires": null,
|
|
15
|
+
"items": [
|
|
16
|
+
{
|
|
17
|
+
"kind": "fixed",
|
|
18
|
+
"en": "An agent asking for 2–3 subagents the member did not ask for was refused, and some models retried until the member stopped the turn. One subagent now runs, and the agent is told why.",
|
|
19
|
+
"vi": "Agent xin 2–3 subagent mà member không yêu cầu từng bị chặn, và một số model gọi lại liên tục đến khi member phải dừng. Giờ một subagent chạy, và agent được báo lý do."
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"kind": "fixed",
|
|
23
|
+
"en": "piagent-update failed when models.json had // comments, which Pi allows. It reads the file as Pi does and leaves a commented file unchanged.",
|
|
24
|
+
"vi": "piagent-update lỗi khi models.json có comment //, dù Pi cho phép. Giờ file được đọc như Pi đọc, và file có comment được giữ nguyên."
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"kind": "improved",
|
|
28
|
+
"en": "A model-list setup problem no longer stops the whole install: it warns, names the file and gives the command to run again.",
|
|
29
|
+
"vi": "Lỗi khi cấu hình danh sách model không còn làm dừng cả bản cài: bản cài cảnh báo, nêu tên file và lệnh để chạy lại."
|
|
30
|
+
}
|
|
31
|
+
]
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
"version": "1.46.3",
|
|
35
|
+
"date": "2026-10-29",
|
|
36
|
+
"status": "unpublished",
|
|
37
|
+
"title": {
|
|
38
|
+
"en": "One subagent instead of a refused request; update reads a commented models.json",
|
|
39
|
+
"vi": "Một subagent thay vì bị chặn; bản cập nhật đọc được models.json có comment"
|
|
40
|
+
},
|
|
41
|
+
"summary": {
|
|
42
|
+
"en": "Tagged but not published: a release title over the page limit failed the release check. Superseded by 1.46.4.",
|
|
43
|
+
"vi": "Đã tag nhưng chưa publish: tiêu đề bản phát hành dài quá giới hạn của trang nên kiểm tra release fail. Thay bằng 1.46.4."
|
|
44
|
+
},
|
|
45
|
+
"requires": null,
|
|
46
|
+
"items": [
|
|
47
|
+
{
|
|
48
|
+
"kind": "fixed",
|
|
49
|
+
"en": "An agent asking for 2–3 subagents the member did not ask for was refused, and some models retried until the member stopped the turn. One subagent now runs, and the agent is told why.",
|
|
50
|
+
"vi": "Agent xin 2–3 subagent mà member không yêu cầu từng bị chặn, và một số model gọi lại liên tục đến khi member phải dừng. Giờ một subagent chạy, và agent được báo lý do."
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
"kind": "fixed",
|
|
54
|
+
"en": "piagent-update failed when models.json had // comments, which Pi allows. It reads the file as Pi does and leaves a commented file unchanged.",
|
|
55
|
+
"vi": "piagent-update lỗi khi models.json có comment //, dù Pi cho phép. Giờ file được đọc như Pi đọc, và file có comment được giữ nguyên."
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
"kind": "improved",
|
|
59
|
+
"en": "A model-list setup problem no longer stops the whole install: it warns, names the file and gives the command to run again.",
|
|
60
|
+
"vi": "Lỗi khi cấu hình danh sách model không còn làm dừng cả bản cài: bản cài cảnh báo, nêu tên file và lệnh để chạy lại."
|
|
61
|
+
}
|
|
62
|
+
]
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
"version": "1.46.2",
|
|
66
|
+
"date": "2026-10-29",
|
|
67
|
+
"status": "stable",
|
|
68
|
+
"title": {
|
|
69
|
+
"en": "A message sent after an answer shows at once; the WebUI streams word by word",
|
|
70
|
+
"vi": "Tin gửi sau câu trả lời hiện ngay; WebUI hiện chữ dần"
|
|
71
|
+
},
|
|
72
|
+
"summary": {
|
|
73
|
+
"en": "The terminal takes the next message as soon as an answer ends, and the WebUI shows an answer while the model writes it instead of once its paragraph ends.",
|
|
74
|
+
"vi": "Terminal nhận tin tiếp theo ngay khi câu trả lời kết thúc, và WebUI hiện câu trả lời trong lúc model đang viết thay vì đợi hết đoạn."
|
|
75
|
+
},
|
|
76
|
+
"requires": null,
|
|
77
|
+
"items": [
|
|
78
|
+
{
|
|
79
|
+
"kind": "fixed",
|
|
80
|
+
"en": "In a folder of repositories, a message sent right after an answer reached the terminal 1–2 s late: Pi waited for the PIAGENT panel's working-tree scan. The panel now refreshes afterwards.",
|
|
81
|
+
"vi": "Ở thư mục nhiều repo, tin gửi ngay sau câu trả lời hiện trễ 1–2 giây trong terminal: Pi chờ panel PIAGENT quét working tree. Panel giờ làm mới sau khi Pi nhận tin."
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
"kind": "improved",
|
|
85
|
+
"en": "The WebUI shows an answer word by word while the model writes it; a one-paragraph answer appeared only once complete (first text at about 1.5 s, now 0.4 s, measured locally).",
|
|
86
|
+
"vi": "WebUI hiện câu trả lời từng chữ trong lúc model viết; trước đây câu trả lời một đoạn chỉ hiện khi viết xong (chữ đầu tiên khoảng 1,5 giây, nay 0,4 giây khi đo cục bộ)."
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
"kind": "security",
|
|
90
|
+
"en": "Streaming holds back a line's last words, so a secret written over several words (Authorization: Basic …, password: …, --token …, a quoted value) is redacted whole.",
|
|
91
|
+
"vi": "Khi hiện chữ dần, vài từ cuối của dòng được giữ lại để bí mật viết qua nhiều từ (Authorization: Basic …, password: …, --token …, giá trị trong ngoặc) được che trọn."
|
|
92
|
+
}
|
|
93
|
+
]
|
|
94
|
+
},
|
|
2
95
|
{
|
|
3
96
|
"version": "1.46.1",
|
|
4
97
|
"date": "2026-10-28",
|
package/docs-site/runtime.html
CHANGED
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
<span class="brand-mark"><img src="/assets/piagent-logo.svg" alt="" width="28" height="28" /></span>
|
|
38
38
|
<span class="brand-name"><b>Piagent</b> <span>Platform</span></span>
|
|
39
39
|
</a>
|
|
40
|
-
<a class="version-badge" href="/whats-new" data-docs-version="v1.46.
|
|
40
|
+
<a class="version-badge" href="/whats-new" data-docs-version="v1.46.4" title="v1.46.4 docs · VI"><span class="dot"></span>v1.46.4</a>
|
|
41
41
|
<nav class="top-nav" aria-label="Tài liệu">
|
|
42
42
|
<a href="/quickstart">Tài liệu</a>
|
|
43
43
|
<a href="/whats-new">Changelog</a>
|
package/docs-site/scope.html
CHANGED
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
<span class="brand-mark"><img src="/assets/piagent-logo.svg" alt="" width="28" height="28" /></span>
|
|
38
38
|
<span class="brand-name"><b>Piagent</b> <span>Platform</span></span>
|
|
39
39
|
</a>
|
|
40
|
-
<a class="version-badge" href="/whats-new" data-docs-version="v1.46.
|
|
40
|
+
<a class="version-badge" href="/whats-new" data-docs-version="v1.46.4" title="v1.46.4 docs · VI"><span class="dot"></span>v1.46.4</a>
|
|
41
41
|
<nav class="top-nav" aria-label="Tài liệu">
|
|
42
42
|
<a href="/quickstart">Tài liệu</a>
|
|
43
43
|
<a href="/whats-new">Changelog</a>
|
package/docs-site/security.html
CHANGED
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
<span class="brand-mark"><img src="/assets/piagent-logo.svg" alt="" width="28" height="28" /></span>
|
|
38
38
|
<span class="brand-name"><b>Piagent</b> <span>Platform</span></span>
|
|
39
39
|
</a>
|
|
40
|
-
<a class="version-badge" href="/whats-new" data-docs-version="v1.46.
|
|
40
|
+
<a class="version-badge" href="/whats-new" data-docs-version="v1.46.4" title="v1.46.4 docs · VI"><span class="dot"></span>v1.46.4</a>
|
|
41
41
|
<nav class="top-nav" aria-label="Tài liệu">
|
|
42
42
|
<a href="/quickstart">Tài liệu</a>
|
|
43
43
|
<a href="/whats-new">Changelog</a>
|
package/docs-site/team.html
CHANGED
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
<span class="brand-mark"><img src="/assets/piagent-logo.svg" alt="" width="28" height="28" /></span>
|
|
38
38
|
<span class="brand-name"><b>Piagent</b> <span>Platform</span></span>
|
|
39
39
|
</a>
|
|
40
|
-
<a class="version-badge" href="/whats-new" data-docs-version="v1.46.
|
|
40
|
+
<a class="version-badge" href="/whats-new" data-docs-version="v1.46.4" title="v1.46.4 docs · VI"><span class="dot"></span>v1.46.4</a>
|
|
41
41
|
<nav class="top-nav" aria-label="Tài liệu">
|
|
42
42
|
<a href="/quickstart">Tài liệu</a>
|
|
43
43
|
<a href="/whats-new">Changelog</a>
|
package/docs-site/update.html
CHANGED
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
<span class="brand-mark"><img src="/assets/piagent-logo.svg" alt="" width="28" height="28" /></span>
|
|
38
38
|
<span class="brand-name"><b>Piagent</b> <span>Platform</span></span>
|
|
39
39
|
</a>
|
|
40
|
-
<a class="version-badge" href="/whats-new" data-docs-version="v1.46.
|
|
40
|
+
<a class="version-badge" href="/whats-new" data-docs-version="v1.46.4" title="v1.46.4 docs · VI"><span class="dot"></span>v1.46.4</a>
|
|
41
41
|
<nav class="top-nav" aria-label="Tài liệu">
|
|
42
42
|
<a href="/quickstart">Tài liệu</a>
|
|
43
43
|
<a href="/whats-new">Changelog</a>
|
|
@@ -145,9 +145,9 @@
|
|
|
145
145
|
<h2 id="pin-cho-team">Pin một bản cho cả team</h2>
|
|
146
146
|
<p>Khi rollout cho team, cài đúng bản Pi host và đúng bản platform, rồi chạy installer ở chế độ stable. Bước <code>--dry-run</code> in ra những gì sẽ đổi.</p>
|
|
147
147
|
<div class="command-card">
|
|
148
|
-
<header><span>Cài pin theo bản</span><button class="clip-btn" data-clip="npm install -g --ignore-scripts @earendil-works/pi-coding-agent@1.3.0 npm install -g --ignore-scripts @piagent/platform@1.46.
|
|
148
|
+
<header><span>Cài pin theo bản</span><button class="clip-btn" data-clip="npm install -g --ignore-scripts @earendil-works/pi-coding-agent@1.3.0 npm install -g --ignore-scripts @piagent/platform@1.46.4 piagent-install --stable --dry-run piagent-install --stable">Lấy lệnh</button></header>
|
|
149
149
|
<pre><code>npm install -g --ignore-scripts @earendil-works/pi-coding-agent@1.3.0
|
|
150
|
-
npm install -g --ignore-scripts @piagent/platform@1.46.
|
|
150
|
+
npm install -g --ignore-scripts @piagent/platform@1.46.4
|
|
151
151
|
piagent-install --stable --dry-run
|
|
152
152
|
piagent-install --stable</code></pre>
|
|
153
153
|
</div>
|
package/docs-site/whats-new.html
CHANGED
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
<span class="brand-mark"><img src="/assets/piagent-logo.svg" alt="" width="28" height="28" /></span>
|
|
38
38
|
<span class="brand-name"><b>Piagent</b> <span>Platform</span></span>
|
|
39
39
|
</a>
|
|
40
|
-
<a class="version-badge" href="/whats-new" data-docs-version="v1.46.
|
|
40
|
+
<a class="version-badge" href="/whats-new" data-docs-version="v1.46.4" title="v1.46.4 docs · VI"><span class="dot"></span>v1.46.4</a>
|
|
41
41
|
<nav class="top-nav" aria-label="Tài liệu">
|
|
42
42
|
<a href="/quickstart">Tài liệu</a>
|
|
43
43
|
<a href="/whats-new" aria-current="page">Changelog</a>
|
|
@@ -108,7 +108,43 @@
|
|
|
108
108
|
<div class="release-filter" role="toolbar" aria-label="Lọc theo loại thay đổi"><button type="button" data-filter-kind="all" aria-pressed="true">Tất cả</button><button type="button" data-filter-kind="new" aria-pressed="false">Mới</button><button type="button" data-filter-kind="improved" aria-pressed="false">Cải thiện</button><button type="button" data-filter-kind="fixed" aria-pressed="false">Sửa lỗi</button><button type="button" data-filter-kind="security" aria-pressed="false">Bảo mật</button></div>
|
|
109
109
|
<section class="section releases" data-releases>
|
|
110
110
|
<h2 id="latest" class="sr-only">Mới nhất</h2>
|
|
111
|
-
<article class="release latest" id="v1-46-
|
|
111
|
+
<article class="release latest" id="v1-46-4" data-release>
|
|
112
|
+
<div class="release-meta"><a class="release-version" href="#v1-46-4">v1.46.4</a><time class="release-date" datetime="2026-10-29">29/10/2026</time></div>
|
|
113
|
+
<div class="release-body">
|
|
114
|
+
<h3 data-toc-skip id="v1-46-4-title">Một subagent thay vì bị chặn; bản cập nhật đọc được models.json có comment</h3>
|
|
115
|
+
<p>Session công ty không còn lặp lại lệnh gọi subagent bị chặn, và bản cập nhật không còn dừng khi file danh sách model của Pi có comment.</p>
|
|
116
|
+
<ul class="release-items">
|
|
117
|
+
<li data-kind="improved"><span class="kind kind-improved">Cải thiện</span><span>Lỗi khi cấu hình danh sách model không còn làm dừng cả bản cài: bản cài cảnh báo, nêu tên file và lệnh để chạy lại.</span></li>
|
|
118
|
+
<li data-kind="fixed"><span class="kind kind-fixed">Sửa lỗi</span><span>Agent xin 2–3 subagent mà member không yêu cầu từng bị chặn, và một số model gọi lại liên tục đến khi member phải dừng. Giờ một subagent chạy, và agent được báo lý do.</span></li>
|
|
119
|
+
<li data-kind="fixed"><span class="kind kind-fixed">Sửa lỗi</span><span>piagent-update lỗi khi models.json có comment //, dù Pi cho phép. Giờ file được đọc như Pi đọc, và file có comment được giữ nguyên.</span></li>
|
|
120
|
+
</ul>
|
|
121
|
+
</div>
|
|
122
|
+
</article>
|
|
123
|
+
<article class="release" id="v1-46-3" data-release>
|
|
124
|
+
<div class="release-meta"><a class="release-version" href="#v1-46-3">v1.46.3</a><time class="release-date" datetime="2026-10-29">29/10/2026</time></div>
|
|
125
|
+
<div class="release-body">
|
|
126
|
+
<h3 data-toc-skip id="v1-46-3-title">Một subagent thay vì bị chặn; bản cập nhật đọc được models.json có comment <span class="tag">không phát hành</span></h3>
|
|
127
|
+
<p>Đã tag nhưng chưa publish: tiêu đề bản phát hành dài quá giới hạn của trang nên kiểm tra release fail. Thay bằng 1.46.4.</p>
|
|
128
|
+
<ul class="release-items">
|
|
129
|
+
<li data-kind="improved"><span class="kind kind-improved">Cải thiện</span><span>Lỗi khi cấu hình danh sách model không còn làm dừng cả bản cài: bản cài cảnh báo, nêu tên file và lệnh để chạy lại.</span></li>
|
|
130
|
+
<li data-kind="fixed"><span class="kind kind-fixed">Sửa lỗi</span><span>Agent xin 2–3 subagent mà member không yêu cầu từng bị chặn, và một số model gọi lại liên tục đến khi member phải dừng. Giờ một subagent chạy, và agent được báo lý do.</span></li>
|
|
131
|
+
<li data-kind="fixed"><span class="kind kind-fixed">Sửa lỗi</span><span>piagent-update lỗi khi models.json có comment //, dù Pi cho phép. Giờ file được đọc như Pi đọc, và file có comment được giữ nguyên.</span></li>
|
|
132
|
+
</ul>
|
|
133
|
+
</div>
|
|
134
|
+
</article>
|
|
135
|
+
<article class="release" id="v1-46-2" data-release>
|
|
136
|
+
<div class="release-meta"><a class="release-version" href="#v1-46-2">v1.46.2</a><time class="release-date" datetime="2026-10-29">29/10/2026</time></div>
|
|
137
|
+
<div class="release-body">
|
|
138
|
+
<h3 data-toc-skip id="v1-46-2-title">Tin gửi sau câu trả lời hiện ngay; WebUI hiện chữ dần</h3>
|
|
139
|
+
<p>Terminal nhận tin tiếp theo ngay khi câu trả lời kết thúc, và WebUI hiện câu trả lời trong lúc model đang viết thay vì đợi hết đoạn.</p>
|
|
140
|
+
<ul class="release-items">
|
|
141
|
+
<li data-kind="improved"><span class="kind kind-improved">Cải thiện</span><span>WebUI hiện câu trả lời từng chữ trong lúc model viết; trước đây câu trả lời một đoạn chỉ hiện khi viết xong (chữ đầu tiên khoảng 1,5 giây, nay 0,4 giây khi đo cục bộ).</span></li>
|
|
142
|
+
<li data-kind="fixed"><span class="kind kind-fixed">Sửa lỗi</span><span>Ở thư mục nhiều repo, tin gửi ngay sau câu trả lời hiện trễ 1–2 giây trong terminal: Pi chờ panel PIAGENT quét working tree. Panel giờ làm mới sau khi Pi nhận tin.</span></li>
|
|
143
|
+
<li data-kind="security"><span class="kind kind-security">Bảo mật</span><span>Khi hiện chữ dần, vài từ cuối của dòng được giữ lại để bí mật viết qua nhiều từ (Authorization: Basic …, password: …, --token …, giá trị trong ngoặc) được che trọn.</span></li>
|
|
144
|
+
</ul>
|
|
145
|
+
</div>
|
|
146
|
+
</article>
|
|
147
|
+
<article class="release" id="v1-46-1" data-release>
|
|
112
148
|
<div class="release-meta"><a class="release-version" href="#v1-46-1">v1.46.1</a><time class="release-date" datetime="2026-10-28">28/10/2026</time></div>
|
|
113
149
|
<div class="release-body">
|
|
114
150
|
<h3 data-toc-skip id="v1-46-1-title">Phản biện có sổ ghi, review một nhịp, subagent song song khi được yêu cầu</h3>
|
|
@@ -383,55 +419,50 @@
|
|
|
383
419
|
</ul>
|
|
384
420
|
</div>
|
|
385
421
|
</article>
|
|
386
|
-
<article class="release" id="v1-40-0" data-release>
|
|
387
|
-
<div class="release-meta"><a class="release-version" href="#v1-40-0">v1.40.0</a><time class="release-date" datetime="2026-10-24">24/10/2026</time></div>
|
|
388
|
-
<div class="release-body">
|
|
389
|
-
<h3 data-toc-skip id="v1-40-0-title">Project local cũng được báo cho Studio</h3>
|
|
390
|
-
<p>Cuộc trò chuyện công ty trong thư mục không có remote báo project local cho Studio, mọi lượt chạy đều báo, và member thấy mọi loại cảnh báo project.</p>
|
|
391
|
-
<ul class="release-items">
|
|
392
|
-
<li data-kind="new"><span class="kind kind-new">Mới</span><span>Thư mục không có remote đọc được được báo như project local, theo commit gốc của Git hoặc theo mã băm; đường dẫn không bao giờ rời khỏi máy.</span></li>
|
|
393
|
-
<li data-kind="new"><span class="kind kind-new">Mới</span><span>Key local của project Git giống nhau trên mọi máy có cùng lịch sử, kể cả bản clone và checkout không có remote <code>origin</code>.</span></li>
|
|
394
|
-
<li data-kind="improved"><span class="kind kind-improved">Cải thiện</span><span>Mọi lượt chạy đều báo project, không chỉ lượt đầu của cuộc trò chuyện, nên Studio đếm được từng lần dùng và biết máy nào chưa bao giờ báo.</span></li>
|
|
395
|
-
<li data-kind="improved"><span class="kind kind-improved">Cải thiện</span><span>Member thấy một dòng cho mọi cảnh báo: project của team khác, ngoài danh sách của team, chưa đăng ký cho team, hoặc thư mục không đọc được.</span></li>
|
|
396
|
-
<li data-kind="improved"><span class="kind kind-improved">Cải thiện</span><span>Thư mục chứa nhiều checkout báo từng checkout, tối đa sáu, và project local được gọi theo tên thư mục.</span></li>
|
|
397
|
-
<li data-kind="security"><span class="kind kind-security">Bảo mật</span><span>Ba cảnh báo bảo mật của dependency trong Pi host được chấp nhận tới 2026-11-07: từ chối dịch vụ và lỗi Pi không dùng tới, không lộ dữ liệu.</span></li>
|
|
398
|
-
</ul>
|
|
399
|
-
<p class="release-requires"><strong>Cần:</strong> Agent Studio 0.40.0</p>
|
|
400
|
-
</div>
|
|
401
|
-
</article>
|
|
402
|
-
<article class="release" id="v1-39-0" data-release>
|
|
403
|
-
<div class="release-meta"><a class="release-version" href="#v1-39-0">v1.39.0</a><time class="release-date" datetime="2026-10-23">23/10/2026</time></div>
|
|
404
|
-
<div class="release-body">
|
|
405
|
-
<h3 data-toc-skip id="v1-39-0-title">Cảnh báo khi key của team được dùng ngoài team</h3>
|
|
406
|
-
<p>Studio biết cuộc trò chuyện công ty làm trong repository nào và cảnh báo khi key của team bị dùng ngoài team; dashboard giữ ngôn ngữ và theme màu.</p>
|
|
407
|
-
<ul class="release-items">
|
|
408
|
-
<li data-kind="new"><span class="kind kind-new">Mới</span><span>Cuộc trò chuyện công ty báo cho Studio các repository đang làm, dùng cùng key <code>host/path</code> mà team memory đã gửi.</span></li>
|
|
409
|
-
<li data-kind="new"><span class="kind kind-new">Mới</span><span>Admin thấy cảnh báo trong Logs → "Sai project"; member thấy một dòng nhắc phía trên ô soạn tin và trong <code>piagent studio</code>.</span></li>
|
|
410
|
-
<li data-kind="improved"><span class="kind kind-improved">Cải thiện</span><span>Không có gì bị chặn, và team memory chạy như cũ.</span></li>
|
|
411
|
-
<li data-kind="fixed"><span class="kind kind-fixed">Sửa lỗi</span><span>Dashboard trước đây quay về ngôn ngữ và theme màu mặc định sau mỗi lần khởi động lại; giờ nó giữ cả hai.</span></li>
|
|
412
|
-
</ul>
|
|
413
|
-
<p class="release-requires"><strong>Cần:</strong> Agent Studio 0.39.0</p>
|
|
414
|
-
</div>
|
|
415
|
-
</article>
|
|
416
|
-
<article class="release" id="v1-38-2" data-release>
|
|
417
|
-
<div class="release-meta"><a class="release-version" href="#v1-38-2">v1.38.2</a><time class="release-date" datetime="2026-10-23">23/10/2026</time></div>
|
|
418
|
-
<div class="release-body">
|
|
419
|
-
<h3 data-toc-skip id="v1-38-2-title">Cây thư mục, theme màu và editor luôn trong tầm nhìn</h3>
|
|
420
|
-
<p>Khung Tệp thành cây thư mục, có 13 theme màu, và editor cùng terminal đứng yên khi cuộc trò chuyện cuộn.</p>
|
|
421
|
-
<ul class="release-items">
|
|
422
|
-
<li data-kind="new"><span class="kind kind-new">Mới</span><span>Theme màu trong Cài đặt → Giao diện hoặc bảng lệnh (⌘K) đổi màu cả giao diện, cú pháp trong editor và terminal.</span></li>
|
|
423
|
-
<li data-kind="improved"><span class="kind kind-improved">Cải thiện</span><span>Trên màn hình rộng, editor và terminal đứng yên dưới header khi cuộc trò chuyện cuộn; kéo thanh chia để đổi độ rộng editor.</span></li>
|
|
424
|
-
<li data-kind="improved"><span class="kind kind-improved">Cải thiện</span><span>Khung Tệp là cây thư mục: thư mục mở ngay tại chỗ, file đang mở được tô sáng, và Tệp mới bắt đầu ở thư mục vừa chọn.</span></li>
|
|
425
|
-
<li data-kind="improved"><span class="kind kind-improved">Cải thiện</span><span>Nút Tệp/Terminal luôn hiện ở mọi độ rộng; trên điện thoại cây thư mục hẹp hơn và các nút của editor nằm trên một dòng.</span></li>
|
|
426
|
-
</ul>
|
|
427
|
-
</div>
|
|
428
|
-
</article>
|
|
429
422
|
</section>
|
|
430
423
|
<section class="section archive">
|
|
431
424
|
<h2 id="archive">Các bản trước</h2>
|
|
432
425
|
<p class="section-lead">Bản cũ hơn, gom theo tháng. Mở một tháng để xem từng thay đổi.</p>
|
|
433
426
|
<details class="release-archive">
|
|
434
|
-
<summary><span>Tháng 10/2026</span><span class="archive-count">
|
|
427
|
+
<summary><span>Tháng 10/2026</span><span class="archive-count">61</span></summary>
|
|
428
|
+
<div class="archive-row" id="v1-40-0">
|
|
429
|
+
<div class="archive-head"><a class="release-version" href="#v1-40-0">v1.40.0</a> <span class="release-date">24/10/2026</span></div>
|
|
430
|
+
<div class="archive-body">
|
|
431
|
+
<p><strong>Project local cũng được báo cho Studio</strong> — Cuộc trò chuyện công ty trong thư mục không có remote báo project local cho Studio, mọi lượt chạy đều báo, và member thấy mọi loại cảnh báo project.</p>
|
|
432
|
+
<ul class="release-items">
|
|
433
|
+
<li data-kind="new"><span class="kind kind-new">Mới</span><span>Thư mục không có remote đọc được được báo như project local, theo commit gốc của Git hoặc theo mã băm; đường dẫn không bao giờ rời khỏi máy.</span></li>
|
|
434
|
+
<li data-kind="new"><span class="kind kind-new">Mới</span><span>Key local của project Git giống nhau trên mọi máy có cùng lịch sử, kể cả bản clone và checkout không có remote <code>origin</code>.</span></li>
|
|
435
|
+
<li data-kind="improved"><span class="kind kind-improved">Cải thiện</span><span>Mọi lượt chạy đều báo project, không chỉ lượt đầu của cuộc trò chuyện, nên Studio đếm được từng lần dùng và biết máy nào chưa bao giờ báo.</span></li>
|
|
436
|
+
<li data-kind="improved"><span class="kind kind-improved">Cải thiện</span><span>Member thấy một dòng cho mọi cảnh báo: project của team khác, ngoài danh sách của team, chưa đăng ký cho team, hoặc thư mục không đọc được.</span></li>
|
|
437
|
+
<li data-kind="improved"><span class="kind kind-improved">Cải thiện</span><span>Thư mục chứa nhiều checkout báo từng checkout, tối đa sáu, và project local được gọi theo tên thư mục.</span></li>
|
|
438
|
+
<li data-kind="security"><span class="kind kind-security">Bảo mật</span><span>Ba cảnh báo bảo mật của dependency trong Pi host được chấp nhận tới 2026-11-07: từ chối dịch vụ và lỗi Pi không dùng tới, không lộ dữ liệu.</span></li>
|
|
439
|
+
</ul>
|
|
440
|
+
</div>
|
|
441
|
+
</div>
|
|
442
|
+
<div class="archive-row" id="v1-39-0">
|
|
443
|
+
<div class="archive-head"><a class="release-version" href="#v1-39-0">v1.39.0</a> <span class="release-date">23/10/2026</span></div>
|
|
444
|
+
<div class="archive-body">
|
|
445
|
+
<p><strong>Cảnh báo khi key của team được dùng ngoài team</strong> — Studio biết cuộc trò chuyện công ty làm trong repository nào và cảnh báo khi key của team bị dùng ngoài team; dashboard giữ ngôn ngữ và theme màu.</p>
|
|
446
|
+
<ul class="release-items">
|
|
447
|
+
<li data-kind="new"><span class="kind kind-new">Mới</span><span>Cuộc trò chuyện công ty báo cho Studio các repository đang làm, dùng cùng key <code>host/path</code> mà team memory đã gửi.</span></li>
|
|
448
|
+
<li data-kind="new"><span class="kind kind-new">Mới</span><span>Admin thấy cảnh báo trong Logs → "Sai project"; member thấy một dòng nhắc phía trên ô soạn tin và trong <code>piagent studio</code>.</span></li>
|
|
449
|
+
<li data-kind="improved"><span class="kind kind-improved">Cải thiện</span><span>Không có gì bị chặn, và team memory chạy như cũ.</span></li>
|
|
450
|
+
<li data-kind="fixed"><span class="kind kind-fixed">Sửa lỗi</span><span>Dashboard trước đây quay về ngôn ngữ và theme màu mặc định sau mỗi lần khởi động lại; giờ nó giữ cả hai.</span></li>
|
|
451
|
+
</ul>
|
|
452
|
+
</div>
|
|
453
|
+
</div>
|
|
454
|
+
<div class="archive-row" id="v1-38-2">
|
|
455
|
+
<div class="archive-head"><a class="release-version" href="#v1-38-2">v1.38.2</a> <span class="release-date">23/10/2026</span></div>
|
|
456
|
+
<div class="archive-body">
|
|
457
|
+
<p><strong>Cây thư mục, theme màu và editor luôn trong tầm nhìn</strong> — Khung Tệp thành cây thư mục, có 13 theme màu, và editor cùng terminal đứng yên khi cuộc trò chuyện cuộn.</p>
|
|
458
|
+
<ul class="release-items">
|
|
459
|
+
<li data-kind="new"><span class="kind kind-new">Mới</span><span>Theme màu trong Cài đặt → Giao diện hoặc bảng lệnh (⌘K) đổi màu cả giao diện, cú pháp trong editor và terminal.</span></li>
|
|
460
|
+
<li data-kind="improved"><span class="kind kind-improved">Cải thiện</span><span>Trên màn hình rộng, editor và terminal đứng yên dưới header khi cuộc trò chuyện cuộn; kéo thanh chia để đổi độ rộng editor.</span></li>
|
|
461
|
+
<li data-kind="improved"><span class="kind kind-improved">Cải thiện</span><span>Khung Tệp là cây thư mục: thư mục mở ngay tại chỗ, file đang mở được tô sáng, và Tệp mới bắt đầu ở thư mục vừa chọn.</span></li>
|
|
462
|
+
<li data-kind="improved"><span class="kind kind-improved">Cải thiện</span><span>Nút Tệp/Terminal luôn hiện ở mọi độ rộng; trên điện thoại cây thư mục hẹp hơn và các nút của editor nằm trên một dòng.</span></li>
|
|
463
|
+
</ul>
|
|
464
|
+
</div>
|
|
465
|
+
</div>
|
|
435
466
|
<div class="archive-row" id="v1-38-1">
|
|
436
467
|
<div class="archive-head"><a class="release-version" href="#v1-38-1">v1.38.1</a> <span class="release-date">23/10/2026</span></div>
|
|
437
468
|
<div class="archive-body">
|
package/docs-site/windows.html
CHANGED
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
<span class="brand-mark"><img src="/assets/piagent-logo.svg" alt="" width="28" height="28" /></span>
|
|
38
38
|
<span class="brand-name"><b>Piagent</b> <span>Platform</span></span>
|
|
39
39
|
</a>
|
|
40
|
-
<a class="version-badge" href="/whats-new" data-docs-version="v1.46.
|
|
40
|
+
<a class="version-badge" href="/whats-new" data-docs-version="v1.46.4" title="v1.46.4 docs · VI"><span class="dot"></span>v1.46.4</a>
|
|
41
41
|
<nav class="top-nav" aria-label="Tài liệu">
|
|
42
42
|
<a href="/quickstart">Tài liệu</a>
|
|
43
43
|
<a href="/whats-new">Changelog</a>
|
package/docs-site/workflows.html
CHANGED
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
<span class="brand-mark"><img src="/assets/piagent-logo.svg" alt="" width="28" height="28" /></span>
|
|
38
38
|
<span class="brand-name"><b>Piagent</b> <span>Platform</span></span>
|
|
39
39
|
</a>
|
|
40
|
-
<a class="version-badge" href="/whats-new" data-docs-version="v1.46.
|
|
40
|
+
<a class="version-badge" href="/whats-new" data-docs-version="v1.46.4" title="v1.46.4 docs · VI"><span class="dot"></span>v1.46.4</a>
|
|
41
41
|
<nav class="top-nav" aria-label="Tài liệu">
|
|
42
42
|
<a href="/quickstart">Tài liệu</a>
|
|
43
43
|
<a href="/whats-new">Changelog</a>
|
|
@@ -257,7 +257,7 @@
|
|
|
257
257
|
{
|
|
258
258
|
"path": "tests",
|
|
259
259
|
"fileCount": 636,
|
|
260
|
-
"sha256": "
|
|
260
|
+
"sha256": "7d8a3af48dd9179f3bf3921cae65d3e6d18d17ff87d3454c29247f8cf1b34b63"
|
|
261
261
|
}
|
|
262
262
|
],
|
|
263
263
|
"custodianComparisonRules": {
|
package/package.json
CHANGED
|
@@ -3756,7 +3756,10 @@ export default function piagentGuard(pi: ExtensionAPI) {
|
|
|
3756
3756
|
appendTrace,
|
|
3757
3757
|
flushObservedTaskContext: noTask,
|
|
3758
3758
|
onTurnEnd: activityInspector.refresh,
|
|
3759
|
-
onAgentSettled:
|
|
3759
|
+
onAgentSettled: ctx => personalCheckpoints.finish(ctx),
|
|
3760
|
+
// The panel hashes the working tree: seconds in a folder of repositories,
|
|
3761
|
+
// during which a message sent next stayed off the screen.
|
|
3762
|
+
afterAgentSettled: activityInspector.refresh,
|
|
3760
3763
|
beforeShutdown: async (ctx) => {
|
|
3761
3764
|
try { await personalCheckpoints.close(ctx); }
|
|
3762
3765
|
finally {
|
|
@@ -20,17 +20,27 @@ export function namedCount(words) {
|
|
|
20
20
|
}
|
|
21
21
|
// The copies a delegate call asks for, checked against the member's words;
|
|
22
22
|
// null for a plain call. `split`: one line per copy naming its share of the work.
|
|
23
|
+
// Copies the member did not ask for come back as `{ dropped }`: one helper runs
|
|
24
|
+
// and the main agent is told why. A refusal here sent agents round in retries,
|
|
25
|
+
// each quoting other words, until the member stopped the turn.
|
|
23
26
|
export function fanOut(manager, role, args, harness) {
|
|
24
27
|
const split = Array.isArray(args?.split) ? args.split.map(s => typeof s === 'string' ? s.trim().slice(0, 500) : '').filter(Boolean) : [];
|
|
25
28
|
const n = split.length || (Number.isInteger(args?.copies) ? args.copies : 1);
|
|
26
|
-
if (n <= 1
|
|
29
|
+
if (n <= 1) return null;
|
|
27
30
|
if (harness) throw Error('managed-copies-invalid: the harness runs one helper per call.');
|
|
28
|
-
if (n < 2 || n > MAX_COPIES) throw Error(`managed-copies-invalid: ask for 2 to ${MAX_COPIES} ${role} helpers (copies, or one split line per helper).`);
|
|
29
31
|
const words = normal(args?.member_words);
|
|
30
|
-
if (words.length < 3 || !memberRequest(memberMessages(manager)).some(text => normal(text).includes(words)) || namedCount(words) < n || !HELPER_WORDS.test(words))
|
|
31
|
-
|
|
32
|
+
if (words.length < 3 || !memberRequest(memberMessages(manager)).some(text => normal(text).includes(words)) || namedCount(words) < n || !HELPER_WORDS.test(words)) return { dropped: n };
|
|
33
|
+
if (n > MAX_COPIES) throw Error(`managed-copies-invalid: ask for 2 to ${MAX_COPIES} ${role} helpers (copies, or one split line per helper).`);
|
|
32
34
|
return { n, split: split.length ? split : null };
|
|
33
35
|
}
|
|
36
|
+
// The helper's answer, with what the main agent reads above it when it asked
|
|
37
|
+
// for helpers the member did not (`asked`: what fanOut returned).
|
|
38
|
+
export function withDroppedNote(result, role, asked) {
|
|
39
|
+
const n = asked?.dropped, first = result?.content?.[0];
|
|
40
|
+
if (!n || first?.type !== 'text') return result;
|
|
41
|
+
const note = `One ${role} helper ran, not ${n}: the member's own words did not ask for ${n} ${role} helpers. Go on with this answer; run several only when the member asks for that many.\n\n`;
|
|
42
|
+
return { ...result, content: [{ ...first, text: note + first.text }, ...result.content.slice(1)] };
|
|
43
|
+
}
|
|
34
44
|
// What one copy reads under its brief.
|
|
35
45
|
export function copyNote(role, i, fan) {
|
|
36
46
|
return `\n\nThe member asked for ${fan.n} ${role} helpers; you are ${role} helper ${i + 1} of ${fan.n}. ${fan.split ? `Your share of the work: ${fan.split[i]}. The others cover the rest.` : 'The others have the same brief: answer on your own judgement.'}`;
|
|
@@ -24,7 +24,7 @@ import { readPatchDigest, readPatchSnapshot, readChangedFiles, readHead } from '
|
|
|
24
24
|
import { memberTurn } from './continuation.mjs';
|
|
25
25
|
import { workflowPolicy, repositoryChecks, sessionPlanTool, currentPlan, workflowPrompt, RunProcess, completionGate, pendingBaseline, pendingPaths, pendingHead, processEditTools } from './workflow.mjs';
|
|
26
26
|
import { workflowContextTool, workflowContextExtension } from './workflow-context.mjs';
|
|
27
|
-
import { beforeDelegate, resolveTool } from './objections.mjs'; import { fanOut } from './copies.mjs';
|
|
27
|
+
import { beforeDelegate, resolveTool } from './objections.mjs'; import { fanOut, withDroppedNote } from './copies.mjs';
|
|
28
28
|
import { HELPER_CALLS, HELPER_ROLES, helperRoles, helperPrompt, webPrompt, delegateDescription, mainWebLookups, limitedWebTools } from './helper-roles.mjs'; import { delegateParameters, delegateArgs, SPEC_PROMPT } from './helper-settlement.mjs';
|
|
29
29
|
import { loadAgentResources } from './agent-skills.mjs';
|
|
30
30
|
import { loadPiagentThemes } from '../runtime/terminal/terminal-style.mjs';
|
|
@@ -469,7 +469,7 @@ export class ManagedSession {
|
|
|
469
469
|
if (!enabled.includes(role)) throw Error(`managed-helper-not-configured: the company Harness has no ${role} subagent${enabled.length ? `; use ${enabled.join(', ')}` : ''}.`);
|
|
470
470
|
// Studio lets each helper role run HELPER_CALLS times per run (one user
|
|
471
471
|
// message), each helper the member asked for counted (copies.mjs). Say so at once.
|
|
472
|
-
const
|
|
472
|
+
const asked = fanOut(this.session?.sessionManager, role, more, harness), fan = asked?.dropped ? null : asked;
|
|
473
473
|
if ((this.helperCalls.get(role) ?? 0) + (fan?.n ?? 1) > HELPER_CALLS) throw Error(`managed-helper-limit: the ${role} subagent already ran ${HELPER_CALLS} times for this user message. Go on with what it returned, or use it again after the next user message.`);
|
|
474
474
|
beforeDelegate(this.run, role, harness, { since, review: this.review, changed: (this.ownPaths?.size ?? 0) > 0, asked: !!fan });
|
|
475
475
|
const job = this.runHelper(role, task, signal, harness, title, role === 'review' && typeof since === 'string' && since.trim() ? since.trim() : null, fan); this.helpers.set(role, job); this.publishHelpers();
|
|
@@ -477,7 +477,7 @@ export class ManagedSession {
|
|
|
477
477
|
// quiet: a beat each minute tells the dashboard's watchdog, which stops a
|
|
478
478
|
// turn after 15 minutes without an event, that the turn is working.
|
|
479
479
|
const beat = setInterval(() => this.notify({ type: 'managed_helper_progress', role }), this.helperBeatMs ?? HELPER_BEAT_MS); beat.unref?.();
|
|
480
|
-
try { return await job; } finally { clearInterval(beat); this.helpers.delete(role); this.publishHelpers(); }
|
|
480
|
+
try { return withDroppedNote(await job, role, asked); } finally { clearInterval(beat); this.helpers.delete(role); this.publishHelpers(); }
|
|
481
481
|
}
|
|
482
482
|
publishHelpers() {
|
|
483
483
|
// One of each enabled helper role can run at a time.
|
|
@@ -25,6 +25,9 @@ type SessionHookDependencies = {
|
|
|
25
25
|
) => TaskContract | undefined;
|
|
26
26
|
onTurnEnd?: (ctx: ExtensionContext) => void;
|
|
27
27
|
onAgentSettled?: (ctx: ExtensionContext) => void | Promise<void>;
|
|
28
|
+
// Display-only work after settlement. Pi takes the next message only when
|
|
29
|
+
// agent_settled handlers return, so this runs without holding the host.
|
|
30
|
+
afterAgentSettled?: (ctx: ExtensionContext) => void | Promise<void>;
|
|
28
31
|
beforeShutdown?: (ctx: ExtensionContext) => void | Promise<void>;
|
|
29
32
|
};
|
|
30
33
|
|
|
@@ -103,6 +106,9 @@ export function registerSessionHooks(pi: ExtensionAPI, dependencies: SessionHook
|
|
|
103
106
|
taskOutcome: task?.trace.outcome
|
|
104
107
|
});
|
|
105
108
|
await dependencies.onAgentSettled?.(ctx);
|
|
109
|
+
if (dependencies.afterAgentSettled) {
|
|
110
|
+
void Promise.resolve().then(() => dependencies.afterAgentSettled?.(ctx)).catch(() => undefined);
|
|
111
|
+
}
|
|
106
112
|
});
|
|
107
113
|
|
|
108
114
|
pi.on("session_compact", async (event, ctx) => {
|
|
@@ -96,7 +96,6 @@ const CODES = {
|
|
|
96
96
|
'managed-review-by-harness': ['tool', 'the harness reviews the final patch; the agent does not ask for one'],
|
|
97
97
|
'managed-review-once': ['tool', 'this change was reviewed already; ask again only after fixing blocking findings'],
|
|
98
98
|
'managed-copies-invalid': ['tool', 'several helpers of a role run 2 or 3 at a time, at the member\'s request'],
|
|
99
|
-
'managed-copies-not-asked': ['tool', 'more than one helper of a role runs only when the member asks for it'],
|
|
100
99
|
helper_run_limit_reached: ['tool', 'this subagent already ran 8 times for this message'],
|
|
101
100
|
'managed-helper-cancelled': ['tool', 'the subagent was stopped'],
|
|
102
101
|
'managed-helper-failed': ['failed', 'the subagent ended without an answer'],
|
|
@@ -13,6 +13,16 @@ const MAX_EVENTS = 128;
|
|
|
13
13
|
const MAX_DELTA = 16_384;
|
|
14
14
|
const PRIVATE_BEGIN = /-----BEGIN [A-Z ]*PRIVATE KEY-----/;
|
|
15
15
|
const PRIVATE_END = /-----END [A-Z ]*PRIVATE KEY-----/;
|
|
16
|
+
// Within a line, text goes out as it arrives except its last words: a secret
|
|
17
|
+
// written over several words ("Authorization: Basic …", "password: …",
|
|
18
|
+
// "--token …") is then whole on one side of every cut.
|
|
19
|
+
const HELD_WORDS = 6;
|
|
20
|
+
// A key whose quoted value has not closed yet (`password = "two words…`).
|
|
21
|
+
const OPEN_QUOTED_VALUE = /(?:(?::=|:|=)\s*|--[A-Za-z][A-Za-z0-9_.-]*\s+)(["'])(?:(?!\1)[^\r\n])*$/;
|
|
22
|
+
// Pieces of a line share MAX_EVENTS with whole lines: they grow as the
|
|
23
|
+
// operation's events are spent, and stop leaving whole lines a reserve.
|
|
24
|
+
const PIECE_EVENTS = 96;
|
|
25
|
+
const PIECE_MIN_CHARS = 24;
|
|
16
26
|
const RUNTIME_DRIFT = /Installed Piagent runtime changed (?:during this session|while the capability lock was being re-pinned)/i;
|
|
17
27
|
const COMPLETION_GATE = /^\[Piagent completion gate: (CONTINUING|NOT APPROVED)\]/i;
|
|
18
28
|
|
|
@@ -327,6 +337,7 @@ export class GatewaySessionStream {
|
|
|
327
337
|
const space = this.#buffer.search(/\s\S*$/);
|
|
328
338
|
take = space >= 0 ? space + 1 : this.#buffer.length >= 16_384 ? this.#buffer.length : 0;
|
|
329
339
|
}
|
|
340
|
+
if (take <= 0 && !final) take = this.#pieceEnd();
|
|
330
341
|
if (take <= 0) return;
|
|
331
342
|
const candidate = this.#buffer.slice(0, take), privateStart = candidate.search(PRIVATE_BEGIN);
|
|
332
343
|
if (privateStart >= 0 && !PRIVATE_END.test(candidate.slice(privateStart))) {
|
|
@@ -341,6 +352,19 @@ export class GatewaySessionStream {
|
|
|
341
352
|
this.#emit(redactSensitiveText(clean(source)).text);
|
|
342
353
|
}
|
|
343
354
|
|
|
355
|
+
#pieceEnd(): number {
|
|
356
|
+
if (this.#eventCount >= PIECE_EVENTS) return 0;
|
|
357
|
+
const line = this.#buffer, words = [...line.matchAll(/\s+(?=\S)/g)];
|
|
358
|
+
if (words.length < HELD_WORDS) return 0;
|
|
359
|
+
const word = words[words.length - HELD_WORDS]!, end = word.index + word[0].length;
|
|
360
|
+
if (end < PIECE_MIN_CHARS * 2 ** Math.floor(this.#eventCount / 32)) return 0;
|
|
361
|
+
// Wait for the quote to close: its words would otherwise leave the key.
|
|
362
|
+
if (OPEN_QUOTED_VALUE.test(line)) return 0;
|
|
363
|
+
const head = line.slice(0, end), tail = line.slice(end);
|
|
364
|
+
// The cut must not change what redaction finds in the text known so far.
|
|
365
|
+
return redactSensitiveText(head).text + redactSensitiveText(tail).text === redactSensitiveText(line).text ? end : 0;
|
|
366
|
+
}
|
|
367
|
+
|
|
344
368
|
#emit(value: string): void {
|
|
345
369
|
for (let offset = 0; offset < value.length; offset += MAX_DELTA) {
|
|
346
370
|
if (this.#eventCount >= MAX_EVENTS) { this.#truncated = true; break; }
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import path from "node:path";
|
|
3
|
+
import { parsePiModelsJson } from "./pi-models-json.mjs";
|
|
3
4
|
|
|
4
5
|
const additions = JSON.parse(fs.readFileSync(new URL("../catalog/claude-model-additions.json", import.meta.url), "utf8"));
|
|
5
6
|
const object = value => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
@@ -9,7 +10,11 @@ const object = value => value !== null && typeof value === "object" && !Array.is
|
|
|
9
10
|
export function prepareClaudeModelAdditions(file) {
|
|
10
11
|
if (fs.existsSync(file) && (!fs.lstatSync(file).isFile() || fs.lstatSync(file).isSymbolicLink())) throw new Error("Unsafe model configuration path");
|
|
11
12
|
const before = fs.existsSync(file) ? fs.readFileSync(file, "utf8") : null;
|
|
12
|
-
|
|
13
|
+
let data = {}, strict = true;
|
|
14
|
+
if (before !== null) {
|
|
15
|
+
try { ({ data, strict } = parsePiModelsJson(before)); }
|
|
16
|
+
catch (error) { throw new Error(`Cannot read model configuration ${file}: ${error.message}`); }
|
|
17
|
+
}
|
|
13
18
|
if (!object(data) || (data.providers !== undefined && !object(data.providers))) throw new Error("Unsupported model configuration");
|
|
14
19
|
data.providers ??= {};
|
|
15
20
|
const provider = data.providers.anthropic ?? {};
|
|
@@ -19,6 +24,8 @@ export function prepareClaudeModelAdditions(file) {
|
|
|
19
24
|
const models = provider.models ?? [];
|
|
20
25
|
const missing = additions.models.filter(model => !models.some(existing => existing.id === model.id));
|
|
21
26
|
if (missing.length === 0) return null;
|
|
27
|
+
// Rewriting would drop the member's comments; leave the file to them.
|
|
28
|
+
if (!strict) return { skipped: `${file} has comments; not adding ${missing.map(model => model.id).join(", ")} (add them by hand if wanted)`, apply() {} };
|
|
22
29
|
data.providers.anthropic = { ...provider, models: [...models, ...missing] };
|
|
23
30
|
return { apply() {
|
|
24
31
|
const current = fs.existsSync(file) ? fs.readFileSync(file, "utf8") : null;
|
|
@@ -168,7 +168,11 @@ function parseDefaultModel(input) {
|
|
|
168
168
|
|
|
169
169
|
const parsedDefault = parseDefaultModel(defaultModelInput);
|
|
170
170
|
const settingsBefore = fs.existsSync(settingsPath) ? fs.readFileSync(settingsPath, "utf8") : null;
|
|
171
|
-
|
|
171
|
+
let settings = {};
|
|
172
|
+
if (settingsBefore !== null) {
|
|
173
|
+
try { settings = JSON.parse(settingsBefore); }
|
|
174
|
+
catch (error) { console.error(`FAIL: cannot read Pi settings ${settingsPath}: ${error.message}`); process.exit(1); }
|
|
175
|
+
}
|
|
172
176
|
|
|
173
177
|
// What Piagent last offered, so an update adds only models new to this
|
|
174
178
|
// release and never puts back one the member removed.
|
|
@@ -213,6 +217,7 @@ if (dryRun) {
|
|
|
213
217
|
console.log(` preset: ${preset}`);
|
|
214
218
|
console.log(` default: ${settings.defaultProvider}/${settings.defaultModel}:${settings.defaultThinkingLevel}`);
|
|
215
219
|
console.log(` enabledModels: ${settings.enabledModels.length}`);
|
|
220
|
+
if (catalogEdit?.skipped) console.log(` note: ${catalogEdit.skipped}`);
|
|
216
221
|
for (const note of notes) console.log(` ${note}`);
|
|
217
222
|
}
|
|
218
223
|
NODE
|
|
@@ -881,10 +881,16 @@ fi
|
|
|
881
881
|
|
|
882
882
|
if [[ "$CONFIGURE_MODEL_SCOPE" == true ]]; then
|
|
883
883
|
echo "Configuring Pi model selector scope:"
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
884
|
+
MODEL_SCOPE_ARGS=(--preset "$MODEL_SCOPE_PRESET" --default-model "$DEFAULT_MODEL")
|
|
885
|
+
if [[ "$RESET_MODEL_SCOPE" != true ]]; then
|
|
886
|
+
MODEL_SCOPE_ARGS+=(--keep-member-choices)
|
|
887
|
+
fi
|
|
888
|
+
# The model list is a convenience: a member's settings or models.json that the
|
|
889
|
+
# script cannot read must not stop the install (Pi and the package are already
|
|
890
|
+
# in place). The script restores settings.json when it fails part way.
|
|
891
|
+
if ! run_cmd bash "$PLATFORM_ROOT/scripts/configure-model-scope.sh" "${MODEL_SCOPE_ARGS[@]}"; then
|
|
892
|
+
echo "WARN: the Pi model selector scope was not changed; the install continues." >&2
|
|
893
|
+
echo " Fix the file named above, then run: piagent-model-scope ${MODEL_SCOPE_ARGS[*]}" >&2
|
|
888
894
|
fi
|
|
889
895
|
fi
|
|
890
896
|
|