@piagent/platform 1.9.3 → 1.10.0
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 +31 -0
- package/README.md +1 -1
- package/README.vi.md +1 -1
- package/docs/command-reference-vietnamese.md +2 -2
- package/docs/distribution-standard.md +6 -6
- package/docs/en/architecture.md +1 -1
- package/docs/languages.json +4 -4
- package/docs/managed-local-acceptance.md +35 -0
- package/docs/operator-manual-vietnamese.md +7 -7
- package/docs/publishing-for-teams.md +1 -0
- package/docs/release-install-policy.md +2 -2
- package/docs/team-onboarding.md +2 -2
- package/docs/vi/architecture.md +1 -1
- package/docs-site/architecture.html +1 -1
- package/docs-site/benchmark.html +1 -1
- package/docs-site/commands.html +1 -1
- package/docs-site/content/en/index.html +4 -4
- package/docs-site/content/en/whats-new.html +11 -0
- package/docs-site/content/index.html +4 -4
- package/docs-site/content/whats-new.html +11 -0
- 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 +5 -5
- 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/whats-new.html +12 -1
- package/docs-site/en/workflows.html +1 -1
- package/docs-site/index.html +5 -5
- 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/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/whats-new.html +12 -1
- package/docs-site/workflows.html +1 -1
- package/evals/private-holdout-v1/public-exposure.v2.json +2 -2
- package/package.json +1 -1
- package/packages/piagent-core/managed/grant-share.mjs +18 -0
- package/packages/piagent-core/managed/helper-roles.mjs +8 -4
- package/packages/piagent-core/managed/helper-run.mjs +116 -0
- package/packages/piagent-core/managed/member-questions.d.mts +15 -0
- package/packages/piagent-core/managed/member-questions.mjs +178 -0
- package/packages/piagent-core/managed/objections.mjs +73 -0
- package/packages/piagent-core/managed/patch-snapshot.mjs +108 -22
- package/packages/piagent-core/managed/request-stream.mjs +54 -7
- package/packages/piagent-core/managed/review-snapshot-worker.mjs +31 -13
- package/packages/piagent-core/managed/session.mjs +33 -85
- package/packages/piagent-core/managed/web-search.mjs +23 -2
- package/packages/piagent-core/managed/workflow.mjs +137 -51
- package/packages/piagent-core/package.json +1 -1
- package/packages/piagent-core/runtime/managed-failure.mjs +6 -2
- package/packages/piagent-webui/dist/client/assets/{MarkdownMessage-IaGBsZNX.js → MarkdownMessage-CnSRvuah.js} +1 -1
- package/packages/piagent-webui/dist/client/assets/{index-DgSmcnP8.css → index-Z91z6SlN.css} +1 -1
- package/packages/piagent-webui/dist/client/assets/{index-Cv5u0MN8.js → index-yg9s8sA_.js} +14 -14
- package/packages/piagent-webui/dist/client/index.html +2 -2
- package/packages/piagent-webui/gateway/gateway-service.ts +7 -0
- package/packages/piagent-webui/gateway/managed-projection.ts +1 -1
- package/packages/piagent-webui/gateway/session-questions.ts +15 -0
- package/packages/piagent-webui/gateway/session-runtime-supervisor.ts +7 -2
- package/packages/piagent-webui/server/loopback-server.ts +29 -0
- package/packages/piagent-webui/server/transcript-projection.ts +17 -4
- package/schemas/piagent-webui/session-catalog-v1.schema.json +1 -1
- package/schemas/piagent-webui/transcript-v1.schema.json +29 -2
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
<span>Pi Agent Platform</span>
|
|
31
31
|
</a>
|
|
32
32
|
<div class="top-actions">
|
|
33
|
-
<span class="pill"><span class="pill-dot"></span>v1.
|
|
33
|
+
<span class="pill"><span class="pill-dot"></span>v1.10.0 docs · EN</span>
|
|
34
34
|
<nav class="language-switch" aria-label="Language">
|
|
35
35
|
<a class="language-option" href="/permissions" hreflang="vi" lang="vi">VI</a>
|
|
36
36
|
<a class="language-option current" href="/en/permissions" hreflang="en" lang="en" aria-current="true">EN</a>
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
<span>Pi Agent Platform</span>
|
|
31
31
|
</a>
|
|
32
32
|
<div class="top-actions">
|
|
33
|
-
<span class="pill"><span class="pill-dot"></span>v1.
|
|
33
|
+
<span class="pill"><span class="pill-dot"></span>v1.10.0 docs · EN</span>
|
|
34
34
|
<nav class="language-switch" aria-label="Language">
|
|
35
35
|
<a class="language-option" href="/profiles" hreflang="vi" lang="vi">VI</a>
|
|
36
36
|
<a class="language-option current" href="/en/profiles" hreflang="en" lang="en" aria-current="true">EN</a>
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
<span>Pi Agent Platform</span>
|
|
31
31
|
</a>
|
|
32
32
|
<div class="top-actions">
|
|
33
|
-
<span class="pill"><span class="pill-dot"></span>v1.
|
|
33
|
+
<span class="pill"><span class="pill-dot"></span>v1.10.0 docs · EN</span>
|
|
34
34
|
<nav class="language-switch" aria-label="Language">
|
|
35
35
|
<a class="language-option" href="/quickstart" hreflang="vi" lang="vi">VI</a>
|
|
36
36
|
<a class="language-option current" href="/en/quickstart" hreflang="en" lang="en" aria-current="true">EN</a>
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
<span>Pi Agent Platform</span>
|
|
31
31
|
</a>
|
|
32
32
|
<div class="top-actions">
|
|
33
|
-
<span class="pill"><span class="pill-dot"></span>v1.
|
|
33
|
+
<span class="pill"><span class="pill-dot"></span>v1.10.0 docs · EN</span>
|
|
34
34
|
<nav class="language-switch" aria-label="Language">
|
|
35
35
|
<a class="language-option" href="/runtime" hreflang="vi" lang="vi">VI</a>
|
|
36
36
|
<a class="language-option current" href="/en/runtime" hreflang="en" lang="en" aria-current="true">EN</a>
|
package/docs-site/en/scope.html
CHANGED
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
<span>Pi Agent Platform</span>
|
|
31
31
|
</a>
|
|
32
32
|
<div class="top-actions">
|
|
33
|
-
<span class="pill"><span class="pill-dot"></span>v1.
|
|
33
|
+
<span class="pill"><span class="pill-dot"></span>v1.10.0 docs · EN</span>
|
|
34
34
|
<nav class="language-switch" aria-label="Language">
|
|
35
35
|
<a class="language-option" href="/scope" hreflang="vi" lang="vi">VI</a>
|
|
36
36
|
<a class="language-option current" href="/en/scope" hreflang="en" lang="en" aria-current="true">EN</a>
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
<span>Pi Agent Platform</span>
|
|
31
31
|
</a>
|
|
32
32
|
<div class="top-actions">
|
|
33
|
-
<span class="pill"><span class="pill-dot"></span>v1.
|
|
33
|
+
<span class="pill"><span class="pill-dot"></span>v1.10.0 docs · EN</span>
|
|
34
34
|
<nav class="language-switch" aria-label="Language">
|
|
35
35
|
<a class="language-option" href="/security" hreflang="vi" lang="vi">VI</a>
|
|
36
36
|
<a class="language-option current" href="/en/security" hreflang="en" lang="en" aria-current="true">EN</a>
|
package/docs-site/en/team.html
CHANGED
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
<span>Pi Agent Platform</span>
|
|
31
31
|
</a>
|
|
32
32
|
<div class="top-actions">
|
|
33
|
-
<span class="pill"><span class="pill-dot"></span>v1.
|
|
33
|
+
<span class="pill"><span class="pill-dot"></span>v1.10.0 docs · EN</span>
|
|
34
34
|
<nav class="language-switch" aria-label="Language">
|
|
35
35
|
<a class="language-option" href="/team" hreflang="vi" lang="vi">VI</a>
|
|
36
36
|
<a class="language-option current" href="/en/team" hreflang="en" lang="en" aria-current="true">EN</a>
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
<span>Pi Agent Platform</span>
|
|
31
31
|
</a>
|
|
32
32
|
<div class="top-actions">
|
|
33
|
-
<span class="pill"><span class="pill-dot"></span>v1.
|
|
33
|
+
<span class="pill"><span class="pill-dot"></span>v1.10.0 docs · EN</span>
|
|
34
34
|
<nav class="language-switch" aria-label="Language">
|
|
35
35
|
<a class="language-option" href="/whats-new" hreflang="vi" lang="vi">VI</a>
|
|
36
36
|
<a class="language-option current" href="/en/whats-new" hreflang="en" lang="en" aria-current="true">EN</a>
|
|
@@ -103,6 +103,17 @@
|
|
|
103
103
|
<h1>1.9.0: ask in plain language, the team's Harness checks</h1>
|
|
104
104
|
<p>The task contract and workflow commands are gone. Company mode asks for checks and a review on its own; Stop, network commands on approval and clearer approval cards.</p>
|
|
105
105
|
</div>
|
|
106
|
+
<section class="section">
|
|
107
|
+
<p class="section-kicker">v1.10.0 · 2026-10-05</p>
|
|
108
|
+
<h2 id="v1-10-0">The main agent asks when it is unsure, and subagents may object to a brief</h2>
|
|
109
|
+
<p class="section-lead">When a request leaves a decision open, the main agent asks you with a card of numbered choices instead of guessing. A subagent shows its evidence when a brief drifts from the request, and a second disagreement is yours to decide. Used-up quota or a very large patch no longer stops the work.</p>
|
|
110
|
+
<div class="grid cols-3">
|
|
111
|
+
<article class="card"><h3 id="ask-user">Questions with choices</h3><p>1–4 questions, each with 2–4 numbered choices, always "Other" in your own words and "Let the agent decide". Press a number to choose, Enter to send. Stop while it waits, and on "continue" the agent asks again instead of choosing for you.</p></article>
|
|
112
|
+
<article class="card"><h3 id="objections">Subagents object to a brief</h3><p>A subagent reads your request verbatim and the plan above its brief. When the brief is wrong or drifts from the request it shows its evidence, and the main agent has to answer. A second disagreement marks the conversation "needs your decision".</p></article>
|
|
113
|
+
<article class="card"><h3 id="fallback">Work goes on when quota runs out</h3><p>A subagent whose quota is used up, or whose account rests, starts again on the Harness fallback model. A patch over 120 KB is reviewed in parts and the findings merge.</p></article>
|
|
114
|
+
</div>
|
|
115
|
+
</section>
|
|
116
|
+
|
|
106
117
|
<section class="section">
|
|
107
118
|
<p class="section-kicker">v1.9.3 · 2026-10-03</p>
|
|
108
119
|
<h2 id="v1-9-3">Typing Vietnamese never sends by mistake, and subagents read leaner pages</h2>
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
<span>Pi Agent Platform</span>
|
|
31
31
|
</a>
|
|
32
32
|
<div class="top-actions">
|
|
33
|
-
<span class="pill"><span class="pill-dot"></span>v1.
|
|
33
|
+
<span class="pill"><span class="pill-dot"></span>v1.10.0 docs · EN</span>
|
|
34
34
|
<nav class="language-switch" aria-label="Language">
|
|
35
35
|
<a class="language-option" href="/workflows" hreflang="vi" lang="vi">VI</a>
|
|
36
36
|
<a class="language-option current" href="/en/workflows" hreflang="en" lang="en" aria-current="true">EN</a>
|
package/docs-site/index.html
CHANGED
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
<span>Pi Agent Platform</span>
|
|
31
31
|
</a>
|
|
32
32
|
<div class="top-actions">
|
|
33
|
-
<span class="pill"><span class="pill-dot"></span>v1.
|
|
33
|
+
<span class="pill"><span class="pill-dot"></span>v1.10.0 docs · VI</span>
|
|
34
34
|
<nav class="language-switch" aria-label="Ngôn ngữ">
|
|
35
35
|
<a class="language-option current" href="/" hreflang="vi" lang="vi" aria-current="true">VI</a>
|
|
36
36
|
<a class="language-option" href="/en/" hreflang="en" lang="en">EN</a>
|
|
@@ -93,7 +93,7 @@
|
|
|
93
93
|
<main>
|
|
94
94
|
<div class="content-shell" data-article>
|
|
95
95
|
<section class="hero">
|
|
96
|
-
<p class="eyebrow">Piagent 1.
|
|
96
|
+
<p class="eyebrow">Piagent 1.10.0</p>
|
|
97
97
|
<h1>Coding agent cho cả team, kiểm tra từng bước.</h1>
|
|
98
98
|
<p>
|
|
99
99
|
Một dashboard cho Terminal và trình duyệt. Dùng model bằng tài khoản của bạn, hoặc model của công ty qua Agent Watch và Agent Studio. Guard kiểm tra từng tool call; ở chế độ công ty, Harness của team tự yêu cầu chạy check, cho subagent review và báo kết quả ngay dưới câu trả lời.
|
|
@@ -107,7 +107,7 @@
|
|
|
107
107
|
<div class="hero-actions">
|
|
108
108
|
<a class="button primary" href="/quickstart">Bắt đầu</a>
|
|
109
109
|
<a class="button" href="/ecosystem">Hệ sinh thái</a>
|
|
110
|
-
<a class="button" href="/whats-new">Có gì mới trong 1.
|
|
110
|
+
<a class="button" href="/whats-new">Có gì mới trong 1.10.0</a>
|
|
111
111
|
<a class="button" href="/commands">Xem command</a>
|
|
112
112
|
</div>
|
|
113
113
|
</section>
|
|
@@ -183,9 +183,9 @@ piagent-setup</code></pre>
|
|
|
183
183
|
<h2 id="bat-dau-tu-dau">Bắt đầu từ đâu</h2>
|
|
184
184
|
<div class="card-grid">
|
|
185
185
|
<a class="doc-card" href="/whats-new">
|
|
186
|
-
<span class="card-kicker">Bản 1.
|
|
186
|
+
<span class="card-kicker">Bản 1.10.0</span>
|
|
187
187
|
<h3>Có gì mới</h3>
|
|
188
|
-
<p>
|
|
188
|
+
<p>Main agent hỏi lại khi chưa rõ, subagent được phản biện brief; ở 1.9.3: gõ tiếng Việt không gửi nhầm, subagent đọc trang gọn hơn.</p>
|
|
189
189
|
</a>
|
|
190
190
|
<a class="doc-card" href="/ecosystem">
|
|
191
191
|
<span class="card-kicker">Get started</span>
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
<span>Pi Agent Platform</span>
|
|
31
31
|
</a>
|
|
32
32
|
<div class="top-actions">
|
|
33
|
-
<span class="pill"><span class="pill-dot"></span>v1.
|
|
33
|
+
<span class="pill"><span class="pill-dot"></span>v1.10.0 docs · VI</span>
|
|
34
34
|
<nav class="language-switch" aria-label="Ngôn ngữ">
|
|
35
35
|
<a class="language-option current" href="/mcp-approval" hreflang="vi" lang="vi" aria-current="true">VI</a>
|
|
36
36
|
<a class="language-option" href="/en/mcp-approval" hreflang="en" lang="en">EN</a>
|
package/docs-site/mcp-auth.html
CHANGED
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
<span>Pi Agent Platform</span>
|
|
31
31
|
</a>
|
|
32
32
|
<div class="top-actions">
|
|
33
|
-
<span class="pill"><span class="pill-dot"></span>v1.
|
|
33
|
+
<span class="pill"><span class="pill-dot"></span>v1.10.0 docs · VI</span>
|
|
34
34
|
<nav class="language-switch" aria-label="Ngôn ngữ">
|
|
35
35
|
<a class="language-option current" href="/mcp-auth" hreflang="vi" lang="vi" aria-current="true">VI</a>
|
|
36
36
|
<a class="language-option" href="/en/mcp-auth" hreflang="en" lang="en">EN</a>
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
<span>Pi Agent Platform</span>
|
|
31
31
|
</a>
|
|
32
32
|
<div class="top-actions">
|
|
33
|
-
<span class="pill"><span class="pill-dot"></span>v1.
|
|
33
|
+
<span class="pill"><span class="pill-dot"></span>v1.10.0 docs · VI</span>
|
|
34
34
|
<nav class="language-switch" aria-label="Ngôn ngữ">
|
|
35
35
|
<a class="language-option current" href="/mcp-servers" hreflang="vi" lang="vi" aria-current="true">VI</a>
|
|
36
36
|
<a class="language-option" href="/en/mcp-servers" hreflang="en" lang="en">EN</a>
|
package/docs-site/mcp.html
CHANGED
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
<span>Pi Agent Platform</span>
|
|
31
31
|
</a>
|
|
32
32
|
<div class="top-actions">
|
|
33
|
-
<span class="pill"><span class="pill-dot"></span>v1.
|
|
33
|
+
<span class="pill"><span class="pill-dot"></span>v1.10.0 docs · VI</span>
|
|
34
34
|
<nav class="language-switch" aria-label="Ngôn ngữ">
|
|
35
35
|
<a class="language-option current" href="/mcp" hreflang="vi" lang="vi" aria-current="true">VI</a>
|
|
36
36
|
<a class="language-option" href="/en/mcp" hreflang="en" lang="en">EN</a>
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
<span>Pi Agent Platform</span>
|
|
31
31
|
</a>
|
|
32
32
|
<div class="top-actions">
|
|
33
|
-
<span class="pill"><span class="pill-dot"></span>v1.
|
|
33
|
+
<span class="pill"><span class="pill-dot"></span>v1.10.0 docs · VI</span>
|
|
34
34
|
<nav class="language-switch" aria-label="Ngôn ngữ">
|
|
35
35
|
<a class="language-option current" href="/permissions" hreflang="vi" lang="vi" aria-current="true">VI</a>
|
|
36
36
|
<a class="language-option" href="/en/permissions" hreflang="en" lang="en">EN</a>
|
package/docs-site/profiles.html
CHANGED
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
<span>Pi Agent Platform</span>
|
|
31
31
|
</a>
|
|
32
32
|
<div class="top-actions">
|
|
33
|
-
<span class="pill"><span class="pill-dot"></span>v1.
|
|
33
|
+
<span class="pill"><span class="pill-dot"></span>v1.10.0 docs · VI</span>
|
|
34
34
|
<nav class="language-switch" aria-label="Ngôn ngữ">
|
|
35
35
|
<a class="language-option current" href="/profiles" hreflang="vi" lang="vi" aria-current="true">VI</a>
|
|
36
36
|
<a class="language-option" href="/en/profiles" hreflang="en" lang="en">EN</a>
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
<span>Pi Agent Platform</span>
|
|
31
31
|
</a>
|
|
32
32
|
<div class="top-actions">
|
|
33
|
-
<span class="pill"><span class="pill-dot"></span>v1.
|
|
33
|
+
<span class="pill"><span class="pill-dot"></span>v1.10.0 docs · VI</span>
|
|
34
34
|
<nav class="language-switch" aria-label="Ngôn ngữ">
|
|
35
35
|
<a class="language-option current" href="/quickstart" hreflang="vi" lang="vi" aria-current="true">VI</a>
|
|
36
36
|
<a class="language-option" href="/en/quickstart" hreflang="en" lang="en">EN</a>
|
package/docs-site/runtime.html
CHANGED
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
<span>Pi Agent Platform</span>
|
|
31
31
|
</a>
|
|
32
32
|
<div class="top-actions">
|
|
33
|
-
<span class="pill"><span class="pill-dot"></span>v1.
|
|
33
|
+
<span class="pill"><span class="pill-dot"></span>v1.10.0 docs · VI</span>
|
|
34
34
|
<nav class="language-switch" aria-label="Ngôn ngữ">
|
|
35
35
|
<a class="language-option current" href="/runtime" hreflang="vi" lang="vi" aria-current="true">VI</a>
|
|
36
36
|
<a class="language-option" href="/en/runtime" hreflang="en" lang="en">EN</a>
|
package/docs-site/scope.html
CHANGED
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
<span>Pi Agent Platform</span>
|
|
31
31
|
</a>
|
|
32
32
|
<div class="top-actions">
|
|
33
|
-
<span class="pill"><span class="pill-dot"></span>v1.
|
|
33
|
+
<span class="pill"><span class="pill-dot"></span>v1.10.0 docs · VI</span>
|
|
34
34
|
<nav class="language-switch" aria-label="Ngôn ngữ">
|
|
35
35
|
<a class="language-option current" href="/scope" hreflang="vi" lang="vi" aria-current="true">VI</a>
|
|
36
36
|
<a class="language-option" href="/en/scope" hreflang="en" lang="en">EN</a>
|
package/docs-site/security.html
CHANGED
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
<span>Pi Agent Platform</span>
|
|
31
31
|
</a>
|
|
32
32
|
<div class="top-actions">
|
|
33
|
-
<span class="pill"><span class="pill-dot"></span>v1.
|
|
33
|
+
<span class="pill"><span class="pill-dot"></span>v1.10.0 docs · VI</span>
|
|
34
34
|
<nav class="language-switch" aria-label="Ngôn ngữ">
|
|
35
35
|
<a class="language-option current" href="/security" hreflang="vi" lang="vi" aria-current="true">VI</a>
|
|
36
36
|
<a class="language-option" href="/en/security" hreflang="en" lang="en">EN</a>
|
package/docs-site/team.html
CHANGED
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
<span>Pi Agent Platform</span>
|
|
31
31
|
</a>
|
|
32
32
|
<div class="top-actions">
|
|
33
|
-
<span class="pill"><span class="pill-dot"></span>v1.
|
|
33
|
+
<span class="pill"><span class="pill-dot"></span>v1.10.0 docs · VI</span>
|
|
34
34
|
<nav class="language-switch" aria-label="Ngôn ngữ">
|
|
35
35
|
<a class="language-option current" href="/team" hreflang="vi" lang="vi" aria-current="true">VI</a>
|
|
36
36
|
<a class="language-option" href="/en/team" hreflang="en" lang="en">EN</a>
|
package/docs-site/whats-new.html
CHANGED
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
<span>Pi Agent Platform</span>
|
|
31
31
|
</a>
|
|
32
32
|
<div class="top-actions">
|
|
33
|
-
<span class="pill"><span class="pill-dot"></span>v1.
|
|
33
|
+
<span class="pill"><span class="pill-dot"></span>v1.10.0 docs · VI</span>
|
|
34
34
|
<nav class="language-switch" aria-label="Ngôn ngữ">
|
|
35
35
|
<a class="language-option current" href="/whats-new" hreflang="vi" lang="vi" aria-current="true">VI</a>
|
|
36
36
|
<a class="language-option" href="/en/whats-new" hreflang="en" lang="en">EN</a>
|
|
@@ -103,6 +103,17 @@
|
|
|
103
103
|
<h1>Bản 1.9.0: nói việc bằng lời, Harness của team kiểm tra</h1>
|
|
104
104
|
<p>Bỏ task contract và lệnh workflow. Chế độ công ty tự yêu cầu check và review; nút Dừng, lệnh có mạng theo lần duyệt và thẻ duyệt dễ đọc hơn.</p>
|
|
105
105
|
</div>
|
|
106
|
+
<section class="section">
|
|
107
|
+
<p class="section-kicker">v1.10.0 · 2026-10-05</p>
|
|
108
|
+
<h2 id="v1-10-0">Main agent hỏi lại khi chưa rõ, subagent được phản biện brief</h2>
|
|
109
|
+
<p class="section-lead">Khi yêu cầu còn để ngỏ một quyết định, main agent hỏi bạn bằng thẻ câu hỏi có lựa chọn đánh số thay vì đoán. Subagent được nêu bằng chứng khi brief lệch yêu cầu, và bất đồng lần hai thì bạn quyết. Hết quota hay patch quá lớn không còn làm dừng việc.</p>
|
|
110
|
+
<div class="grid cols-3">
|
|
111
|
+
<article class="card"><h3 id="ask-user">Hỏi lại bằng lựa chọn</h3><p>1–4 câu hỏi, mỗi câu 2–4 lựa chọn đánh số, luôn có "Khác" để tự nhập và "Để agent tự quyết". Bấm số để chọn, Enter để gửi. Bấm Dừng giữa chừng thì khi "tiếp tục", agent hỏi lại chứ không chọn thay bạn.</p></article>
|
|
112
|
+
<article class="card"><h3 id="objections">Subagent phản biện brief</h3><p>Subagent đọc nguyên văn yêu cầu và plan trước brief. Brief sai hoặc lệch yêu cầu thì subagent nêu bằng chứng và main agent phải trả lời. Bất đồng lần hai, hội thoại ghi "Cần bạn quyết".</p></article>
|
|
113
|
+
<article class="card"><h3 id="fallback">Chạy tiếp khi hết quota</h3><p>Subagent hết quota hoặc tài khoản đang nghỉ sẽ chạy lại trên model dự phòng của Harness. Patch trên 120 KB được review theo từng phần rồi gộp findings.</p></article>
|
|
114
|
+
</div>
|
|
115
|
+
</section>
|
|
116
|
+
|
|
106
117
|
<section class="section">
|
|
107
118
|
<p class="section-kicker">v1.9.3 · 2026-10-03</p>
|
|
108
119
|
<h2 id="v1-9-3">Gõ tiếng Việt không gửi nhầm, subagent đọc trang gọn hơn</h2>
|
package/docs-site/workflows.html
CHANGED
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
<span>Pi Agent Platform</span>
|
|
31
31
|
</a>
|
|
32
32
|
<div class="top-actions">
|
|
33
|
-
<span class="pill"><span class="pill-dot"></span>v1.
|
|
33
|
+
<span class="pill"><span class="pill-dot"></span>v1.10.0 docs · VI</span>
|
|
34
34
|
<nav class="language-switch" aria-label="Ngôn ngữ">
|
|
35
35
|
<a class="language-option current" href="/workflows" hreflang="vi" lang="vi" aria-current="true">VI</a>
|
|
36
36
|
<a class="language-option" href="/en/workflows" hreflang="en" lang="en">EN</a>
|
|
@@ -256,8 +256,8 @@
|
|
|
256
256
|
},
|
|
257
257
|
{
|
|
258
258
|
"path": "tests",
|
|
259
|
-
"fileCount":
|
|
260
|
-
"sha256": "
|
|
259
|
+
"fileCount": 517,
|
|
260
|
+
"sha256": "8c5cc0362e54e3b4f88047b696232895c479eb2ea93337b19e1e0a436d712ec1"
|
|
261
261
|
}
|
|
262
262
|
],
|
|
263
263
|
"custodianComparisonRules": {
|
package/package.json
CHANGED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
// Every renew replaces the role's token. Searches of one role running side
|
|
2
|
+
// by side, and a delegate refreshing main beside main's search, share one
|
|
3
|
+
// renew, so none voids a sibling's token before Studio admits its request.
|
|
4
|
+
// The share lasts while one of them still runs, at most a minute (the lease
|
|
5
|
+
// is two). `owner` is the ManagedSession.
|
|
6
|
+
export function shareGrant(owner, role) {
|
|
7
|
+
owner.sharedGrants ??= new Map();
|
|
8
|
+
const shared = owner.sharedGrants.get(role);
|
|
9
|
+
if (shared && Date.now() - shared.at < 60_000) { shared.users++; return shared; }
|
|
10
|
+
const entry = { at: Date.now(), users: 1, grant: owner.broker.request('renew', { role }) };
|
|
11
|
+
entry.grant.catch(() => { if (owner.sharedGrants.get(role) === entry) owner.sharedGrants.delete(role); });
|
|
12
|
+
owner.sharedGrants.set(role, entry);
|
|
13
|
+
return entry;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function releaseGrant(owner, role, entry) {
|
|
17
|
+
if (--entry.users <= 0 && owner.sharedGrants?.get(role) === entry) owner.sharedGrants.delete(role);
|
|
18
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { REVIEW_PROMPT, VERIFY_PROMPT, isCheckCommand } from './workflow.mjs';
|
|
1
|
+
import { REVIEW_PROMPT, VERIFY_PROMPT, BRIEF_CHECK, BRIEF_ISSUES_JSON, isCheckCommand } from './workflow.mjs';
|
|
2
2
|
|
|
3
3
|
// Each helper role runs at most this often per user message (Studio's MaxHelperCalls).
|
|
4
4
|
export const HELPER_CALLS = 8;
|
|
@@ -25,6 +25,8 @@ export function helperPrompt(roles) {
|
|
|
25
25
|
if (roles.includes('research')) lines.push(roles.includes('scout') ? 'Use the research helper (delegate role "research") for anything on the web (current information, news, library and API docs, releases, error messages), together with the code when needed; give it the question and the answer you need, and work from its summary.'
|
|
26
26
|
: `Use the research helper (delegate role "research") for anything on the web (current information, news, documentation) and ${WIDE_READING}; work from its findings and do small code lookups yourself.`);
|
|
27
27
|
if (roles.includes('verify')) lines.push('Before you report a non-trivial result as done, you may have the verify helper (delegate role "verify") confirm it independently: it runs the repository checks on the current code and checks claims against the code and primary sources, answering pass, fail or unverifiable with evidence.');
|
|
28
|
+
// Helpers read the member's request beside the brief and may object to it.
|
|
29
|
+
if (lines.length) lines.push('A helper sees the member\'s request next to your brief and may object to the brief with evidence (brief_issues). You decide, but answer every objection: send a corrected brief, change your approach, or tell the member why it does not hold. A helper that objects twice for one message goes to the member.');
|
|
28
30
|
return lines.length ? ' ' + lines.join(' ') : '';
|
|
29
31
|
}
|
|
30
32
|
const HELPER_USES = {
|
|
@@ -37,8 +39,10 @@ const HELPER_USES = {
|
|
|
37
39
|
export function delegateDescription(roles) {
|
|
38
40
|
return `Hand work to a helper with its own context. Helpers read the project but cannot change files or call helpers. ${roles.map(role => HELPER_USES[role](roles)).join(' ')} A lookup that one grep or read answers stays with you. Write the task as a brief the helper can act on alone: the goal, what to find or check, where to start and what you already know or ruled out, and the answer you need (file:line facts). One call per helper runs at a time; each can be called again, up to ${HELPER_CALLS} times per user message, for example a second review after fixing what the first one found.`;
|
|
39
41
|
}
|
|
40
|
-
|
|
41
|
-
const
|
|
42
|
+
// Scout and research end with their objections to the brief, if any.
|
|
43
|
+
const OBJECTIONS = `${BRIEF_CHECK} End your answer with one JSON object in a \`\`\`json block: {${BRIEF_ISSUES_JSON}}, with an empty list when the brief is sound. You cannot change files or delegate.`;
|
|
44
|
+
const RESEARCH_PROMPT = `Research the assigned question. Read only the needed source; use web_search or web_fetch for external documentation. Answer with facts the main agent can act on: file:line, short quotes, what calls what, and what you checked and found nothing in. ${OBJECTIONS}`;
|
|
45
|
+
const SCOUT_PROMPT = `Scout the codebase for the assigned question. Search first (grep, find), then read only the parts that matter. Answer with facts the main agent can act on: file:line, short quotes, what calls what, and where you looked and found nothing. You have no web access: when the answer needs external documentation, say so. ${OBJECTIONS}`;
|
|
42
46
|
export const READ_TOOLS = ['read', 'grep', 'find', 'ls'];
|
|
43
47
|
// What each helper may use. Every helper's project is read-only; verify also
|
|
44
48
|
// runs commands there (offline, writes only to its temporary directory).
|
|
@@ -56,7 +60,7 @@ export function countedCheck(managed, tool) {
|
|
|
56
60
|
return { ...tool, execute: async (...args) => {
|
|
57
61
|
const counted = managed.run && isCheckCommand(args[1]?.command, managed.checks.commands), before = counted ? await managed.digest() : null;
|
|
58
62
|
let ok = false;
|
|
59
|
-
try { const result = await tool.execute(...args); ok =
|
|
63
|
+
try { const result = await tool.execute(...args); ok = !result?.isError; return result; }
|
|
60
64
|
finally {
|
|
61
65
|
const after = counted && before !== null ? await managed.digest() : null;
|
|
62
66
|
if (after !== null && after === before) await managed.run.afterTool('bash', args[1], ok, async () => after);
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
// A helper role's run: its grant from Studio, its read-only sessions (one per
|
|
2
|
+
// part of a large patch for a review), the receipt and the review it records.
|
|
3
|
+
// A helper whose company model account is out of usage, or resting after a
|
|
4
|
+
// refusal, starts once more: Studio then gives the new helper the next model
|
|
5
|
+
// of its role that serves (an auto role's list).
|
|
6
|
+
import { ManagedToolBoundary } from './tool-boundary.mjs';
|
|
7
|
+
import { managedResourceLoader } from './resource-loader.mjs';
|
|
8
|
+
import { shareGrant, releaseGrant } from './grant-share.mjs';
|
|
9
|
+
import { describeFailure, failureCode } from '../runtime/managed-failure.mjs';
|
|
10
|
+
import { reviewParts, mergeReviews, REVIEW_PARALLEL } from './patch-snapshot.mjs';
|
|
11
|
+
import { reviewFindings, briefIssues } from './workflow.mjs';
|
|
12
|
+
import { anchorText, relayObjection, recordVerdicts } from './objections.mjs';
|
|
13
|
+
import { HELPER_CALLS, HELPER_SETUP, READ_TOOLS, countedCheck } from './helper-roles.mjs';
|
|
14
|
+
|
|
15
|
+
const textContent = result => result.content?.filter(p => p.type === 'text').map(p => p.text).join('\n') ?? '';
|
|
16
|
+
// A helper failure that another model of its role may not have: the model's
|
|
17
|
+
// company account is out of usage or resting, was switched off or removed
|
|
18
|
+
// under the helper, or none serves it now. The new helper is a new
|
|
19
|
+
// conversation for Studio, so it is not held to the old account.
|
|
20
|
+
const HELPER_SWITCH = new Set(['upstream_rate_limited', 'session_account_not_ready_retry_later', 'session_account_unavailable_start_new_session', 'account_capacity_unavailable', 'execution_capability_unavailable']);
|
|
21
|
+
const HELPER_ATTEMPTS = 2;
|
|
22
|
+
|
|
23
|
+
export async function runHelper(managed, role, task, signal, harness, { verifyGrant, patiently }) {
|
|
24
|
+
const snapshot = role === 'review' ? await managed.patchSnapshot() : null, parts = snapshot ? reviewParts(snapshot) : null;
|
|
25
|
+
// A helper whose company model account is out of usage, or resting after
|
|
26
|
+
// a refusal, starts once more: Studio then gives the new helper the next
|
|
27
|
+
// model of its role that serves (an auto role's list). Helpers read and
|
|
28
|
+
// run checks only, so starting over repeats no change.
|
|
29
|
+
for (let attempt = 1; ; attempt += 1) {
|
|
30
|
+
try { return await helperAttempt(managed, role, task, signal, harness, snapshot, parts, { verifyGrant, patiently }); }
|
|
31
|
+
catch (error) {
|
|
32
|
+
if (attempt >= HELPER_ATTEMPTS || signal?.aborted || !HELPER_SWITCH.has(failureCode(error?.message)) || (managed.helperCalls.get(role) ?? 0) >= HELPER_CALLS) throw error;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
async function helperAttempt(managed, role, task, signal, harness, snapshot, parts, { verifyGrant, patiently }) {
|
|
37
|
+
// A long local tool step may outlive the main lease. Refresh authority
|
|
38
|
+
// before asking for a child; the broker serializes concurrent renewals,
|
|
39
|
+
// and main's own searches running beside it share managed renew.
|
|
40
|
+
let grant;
|
|
41
|
+
try {
|
|
42
|
+
const share = shareGrant(managed, 'main');
|
|
43
|
+
try {
|
|
44
|
+
const parent = await share.grant;
|
|
45
|
+
verifyGrant(parent, managed.manifest, 'main'); managed.grant = parent;
|
|
46
|
+
grant = await patiently(() => managed.broker.request('child', { role }), 2);
|
|
47
|
+
} finally { releaseGrant(managed, 'main', share); }
|
|
48
|
+
managed.helperCalls.set(role, (managed.helperCalls.get(role) ?? 0) + 1);
|
|
49
|
+
try { verifyGrant(grant, managed.manifest, role); }
|
|
50
|
+
catch (error) { try { await managed.broker.request('close', { role }); } catch { /* closes with the run */ } throw error; }
|
|
51
|
+
} catch (error) { throw Error(`managed-helper-failed: ${describeFailure(role, error?.message)}`); }
|
|
52
|
+
let boundary;
|
|
53
|
+
const sessions = new Set();
|
|
54
|
+
try {
|
|
55
|
+
const runtime = await managed.api.ModelRuntime.create({ credentials: new managed.ai.InMemoryCredentialStore(), modelsPath: null, refreshOnCreate: false, allowModelNetwork: false });
|
|
56
|
+
const model = managed.installModel(runtime, grant); managed.wrapStreams(runtime, role);
|
|
57
|
+
const setup = HELPER_SETUP[role];
|
|
58
|
+
boundary = new ManagedToolBoundary({ cwd: managed.cwd, sdkRoot: managed.sdk, protectedRoots: managed.protectedRoots, readOnly: true, commands: setup.commands });
|
|
59
|
+
const checks = role === 'verify' ? `\n\nRepository checks: ${managed.checks.commands.length ? managed.checks.commands.map(c => '`' + c + '`').join(', ') : 'none declared or detected; choose the tests, type check or build that cover the claims'}.` : '';
|
|
60
|
+
// One helper session answers the brief (with one part of the patch for a
|
|
61
|
+
// review in parts); its reply and tokens. A helper runs at its role's
|
|
62
|
+
// level from Studio (fixed by the Harness, or its main agent's).
|
|
63
|
+
const ask = async extra => {
|
|
64
|
+
const { session } = await managed.api.createAgentSession({ cwd: managed.cwd, model, modelRuntime: runtime, thinkingLevel: grant.effort || 'off',
|
|
65
|
+
settingsManager: managed.api.SettingsManager.inMemory({ retry: { enabled: false, provider: { maxRetries: 0 } }, cacheWarming: 'off' }),
|
|
66
|
+
sessionManager: managed.api.SessionManager.inMemory(managed.cwd), noTools: 'builtin', tools: [...READ_TOOLS, ...(setup.commands ? ['bash'] : []), ...(setup.web ? ['web_search', 'web_fetch'] : [])],
|
|
67
|
+
customTools: [...boundary.tools(managed.api).filter(tool => READ_TOOLS.includes(tool.name) || setup.commands && tool.name === 'bash').map(tool => countedCheck(managed, tool)),
|
|
68
|
+
...(setup.web ? managed.webTools(runtime, role) : [])], resourceLoader: managedResourceLoader(managed.api, { systemPrompt: setup.prompt }) });
|
|
69
|
+
sessions.add(session);
|
|
70
|
+
const abort = () => void session.abort(); signal?.addEventListener('abort', abort, { once: true });
|
|
71
|
+
try { if (signal?.aborted) throw Error('managed-helper-cancelled'); await session.prompt(anchorText(managed.session.sessionManager, harness) + task + checks + extra, { expandPromptTemplates: false }); }
|
|
72
|
+
finally { signal?.removeEventListener('abort', abort); }
|
|
73
|
+
const messages = session.messages.filter(m => m.role === 'assistant');
|
|
74
|
+
// The main agent (and the member) learn why a helper failed, not just that it did.
|
|
75
|
+
if (messages.at(-1)?.stopReason === 'error') throw Error(`managed-helper-failed: ${messages.at(-1).errorMessage}`);
|
|
76
|
+
// Stopped by the member: say so, rather than that the helper failed.
|
|
77
|
+
if (!messages.length || messages.at(-1).stopReason === 'aborted') throw Error(signal?.aborted ? 'managed-helper-cancelled' : 'managed-helper-failed');
|
|
78
|
+
return { reply: messages.map(textContent).join('\n'), usage: messages.reduce((n, m) => n + (m.usage?.totalTokens ?? 0), 0) };
|
|
79
|
+
};
|
|
80
|
+
let reply, usage, review = null;
|
|
81
|
+
if (!parts || parts.parts.length === 1) {
|
|
82
|
+
({ reply, usage } = await ask(parts ? `\n${parts.parts[0].text}` : ''));
|
|
83
|
+
reply = reply.slice(0, 16000);
|
|
84
|
+
} else {
|
|
85
|
+
// A large patch: one reviewer per part, REVIEW_PARALLEL at a time (Studio
|
|
86
|
+
// admits one request of a role at a time); the first part that fails
|
|
87
|
+
// stops the others.
|
|
88
|
+
const answers = new Array(parts.parts.length);
|
|
89
|
+
let next = 0;
|
|
90
|
+
const reviewer = async () => {
|
|
91
|
+
while (next < parts.parts.length) { const i = next++; answers[i] = await ask(`\n${parts.parts[i].text}`); }
|
|
92
|
+
};
|
|
93
|
+
try { await Promise.all(Array.from({ length: Math.min(REVIEW_PARALLEL, parts.parts.length) }, reviewer)); }
|
|
94
|
+
catch (error) { next = parts.parts.length; for (const session of sessions) void session.abort(); throw error; }
|
|
95
|
+
review = mergeReviews(parts, answers, { findingsOf: reviewFindings, issuesOf: briefIssues });
|
|
96
|
+
({ reply, usage } = review);
|
|
97
|
+
}
|
|
98
|
+
const stale = snapshot ? (await managed.patchDigest()) !== snapshot.digest : false;
|
|
99
|
+
const details = { role, runID: grant.run_id, tokens: usage, patchDigest: snapshot?.digest, stale };
|
|
100
|
+
if (snapshot) {
|
|
101
|
+
// Severity-graded findings decide whether the harness sends the agent back.
|
|
102
|
+
const findings = review ? review.findings : reviewFindings(reply);
|
|
103
|
+
Object.assign(details, { parsed: review ? review.parsed : !!findings, findings: (findings ?? []).slice(0, 40), blocking: findings?.filter(f => f.severity === 'blocking').length ?? 0 });
|
|
104
|
+
if (review) Object.assign(details, { parts: parts.parts.length, unread: parts.omitted.map(o => o.path).slice(0, 50) });
|
|
105
|
+
if (managed.run) { managed.run.reviews += 1; managed.run.blocking += details.blocking; }
|
|
106
|
+
managed.review = details;
|
|
107
|
+
managed.session.sessionManager.appendCustomEntry('agent-watch-review', details);
|
|
108
|
+
}
|
|
109
|
+
const verdicts = role === 'verify' ? recordVerdicts(managed.run, reply, harness, details) : '';
|
|
110
|
+
await managed.session.sendCustomMessage({ customType: 'agent-watch-helper-receipt', display: true,
|
|
111
|
+
content: `${setup.label}: ${usage.toLocaleString('en-US')} tokens${verdicts}${review ? ` · ${parts.parts.length} parts` : ''}${snapshot ? (stale ? ' · review is stale' : ' · patch ' + snapshot.digest.slice(0, 12)) : ''}.`, details }, { triggerTurn: false });
|
|
112
|
+
// An objection to the brief comes with the answer; a stale review has none to act on.
|
|
113
|
+
const objection = stale ? '' : await relayObjection(managed, role, reply, harness);
|
|
114
|
+
return { content: [{ type: 'text', text: stale ? 'Review is stale: the patch changed during review. Obtain a new review for the current patch.' : reply + objection }], details };
|
|
115
|
+
} finally { for (const session of sessions) session.dispose(); await boundary?.dispose(); await managed.broker.request('close', { role }); }
|
|
116
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export type MemberQuestion = { header: string; question: string; options: Array<{ label: string; description: string }>; multiSelect: boolean };
|
|
2
|
+
export type MemberAnswer = { skipped: boolean; answers: Array<{ selected: number[]; other: string | null }> };
|
|
3
|
+
export type MemberQuestionEvent = { type: "asked" | "waiting" | "answered" | "withdrawn"; ref: string; reason?: string };
|
|
4
|
+
export function normalizeQuestions(raw: unknown): MemberQuestion[] | null;
|
|
5
|
+
export function normalizeAnswer(questions: MemberQuestion[], raw: unknown): MemberAnswer | null;
|
|
6
|
+
export function answerText(questions: MemberQuestion[], answer: MemberAnswer): string;
|
|
7
|
+
export const memberQuestions: {
|
|
8
|
+
pulseMs: number;
|
|
9
|
+
bindSurface(sessionId: string, onEvent: (event: MemberQuestionEvent) => void): () => void;
|
|
10
|
+
hasSurface(sessionId: string): boolean;
|
|
11
|
+
ask(input: { sessionId: string; toolCallId: string; questions: MemberQuestion[]; signal?: AbortSignal }): Promise<MemberAnswer>;
|
|
12
|
+
pending(sessionId: string): Array<{ questionRef: string; askedAt: string; questions: MemberQuestion[] }>;
|
|
13
|
+
answer(sessionId: string, questionRef: string, raw: unknown): { questionRef: string; state: "answered" };
|
|
14
|
+
};
|
|
15
|
+
export function askTool(managed: unknown): unknown;
|