@piagent/platform 1.17.0 → 1.19.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.
Files changed (98) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/README.md +1 -1
  3. package/README.vi.md +1 -1
  4. package/catalog/claude-model-additions.json +49 -2
  5. package/docs/command-reference-vietnamese.md +2 -2
  6. package/docs/distribution-standard.md +6 -6
  7. package/docs/languages.json +2 -2
  8. package/docs/operator-manual-vietnamese.md +7 -7
  9. package/docs/publishing-for-teams.md +2 -0
  10. package/docs/release-install-policy.md +2 -2
  11. package/docs/team-onboarding.md +2 -2
  12. package/docs-site/architecture.html +1 -1
  13. package/docs-site/benchmark.html +1 -1
  14. package/docs-site/commands.html +1 -1
  15. package/docs-site/content/en/index.html +4 -4
  16. package/docs-site/content/en/whats-new.html +13 -0
  17. package/docs-site/content/index.html +4 -4
  18. package/docs-site/content/whats-new.html +13 -0
  19. package/docs-site/context-engine.html +1 -1
  20. package/docs-site/ecosystem.html +1 -1
  21. package/docs-site/en/architecture.html +1 -1
  22. package/docs-site/en/benchmark.html +1 -1
  23. package/docs-site/en/commands.html +1 -1
  24. package/docs-site/en/context-engine.html +1 -1
  25. package/docs-site/en/ecosystem.html +1 -1
  26. package/docs-site/en/index.html +5 -5
  27. package/docs-site/en/mcp-approval.html +1 -1
  28. package/docs-site/en/mcp-auth.html +1 -1
  29. package/docs-site/en/mcp-servers.html +1 -1
  30. package/docs-site/en/mcp.html +1 -1
  31. package/docs-site/en/permissions.html +1 -1
  32. package/docs-site/en/profiles.html +1 -1
  33. package/docs-site/en/quickstart.html +1 -1
  34. package/docs-site/en/runtime.html +1 -1
  35. package/docs-site/en/scope.html +1 -1
  36. package/docs-site/en/security.html +1 -1
  37. package/docs-site/en/team.html +1 -1
  38. package/docs-site/en/whats-new.html +14 -1
  39. package/docs-site/en/windows.html +1 -1
  40. package/docs-site/en/workflows.html +1 -1
  41. package/docs-site/index.html +5 -5
  42. package/docs-site/mcp-approval.html +1 -1
  43. package/docs-site/mcp-auth.html +1 -1
  44. package/docs-site/mcp-servers.html +1 -1
  45. package/docs-site/mcp.html +1 -1
  46. package/docs-site/permissions.html +1 -1
  47. package/docs-site/profiles.html +1 -1
  48. package/docs-site/quickstart.html +1 -1
  49. package/docs-site/runtime.html +1 -1
  50. package/docs-site/scope.html +1 -1
  51. package/docs-site/security.html +1 -1
  52. package/docs-site/team.html +1 -1
  53. package/docs-site/whats-new.html +14 -1
  54. package/docs-site/windows.html +1 -1
  55. package/docs-site/workflows.html +1 -1
  56. package/evals/private-holdout-v1/public-exposure.v2.json +3 -3
  57. package/evals/runtime-conformance-v1/runner.mjs +13 -17
  58. package/package.json +1 -1
  59. package/packages/piagent-core/managed/call-purpose.mjs +3 -2
  60. package/packages/piagent-core/managed/command-tools.mjs +59 -0
  61. package/packages/piagent-core/managed/container-engine.mjs +102 -0
  62. package/packages/piagent-core/managed/continuation.mjs +131 -0
  63. package/packages/piagent-core/managed/doctor.mjs +7 -0
  64. package/packages/piagent-core/managed/language-environment.mjs +57 -0
  65. package/packages/piagent-core/managed/linux-sandbox.mjs +3 -1
  66. package/packages/piagent-core/managed/native-catalog.mjs +14 -1
  67. package/packages/piagent-core/managed/patch-snapshot.mjs +25 -9
  68. package/packages/piagent-core/managed/repository-operation.mjs +20 -0
  69. package/packages/piagent-core/managed/request-stream.mjs +28 -0
  70. package/packages/piagent-core/managed/review-snapshot-worker.mjs +11 -4
  71. package/packages/piagent-core/managed/sandbox-diagnostic.mjs +6 -1
  72. package/packages/piagent-core/managed/session.mjs +52 -63
  73. package/packages/piagent-core/managed/tool-boundary.mjs +21 -10
  74. package/packages/piagent-core/managed/tool-worker.mjs +3 -3
  75. package/packages/piagent-core/managed/workflow.mjs +20 -20
  76. package/packages/piagent-core/package.json +1 -1
  77. package/packages/piagent-webui/dist/client/assets/{MarkdownMessage-CeQ79h30.js → MarkdownMessage-nggiOt0N.js} +1 -1
  78. package/packages/piagent-webui/dist/client/assets/{index-BNQK7rHr.js → index-CM9cs-gP.js} +16 -14
  79. package/packages/piagent-webui/dist/client/index.html +1 -1
  80. package/packages/piagent-webui/gateway/company-relay.ts +14 -2
  81. package/packages/piagent-webui/gateway/gateway-service.ts +38 -0
  82. package/packages/piagent-webui/gateway/git-branches.ts +94 -0
  83. package/packages/piagent-webui/gateway/git-repositories.ts +46 -0
  84. package/packages/piagent-webui/gateway/managed-projection.ts +9 -2
  85. package/packages/piagent-webui/gateway/project-registry.ts +10 -6
  86. package/packages/piagent-webui/gateway/session-catalog.ts +13 -6
  87. package/packages/piagent-webui/gateway/session-operation-lifecycle.ts +10 -3
  88. package/packages/piagent-webui/server/loopback-server.ts +9 -2
  89. package/packages/piagent-webui/server/member-routes.ts +41 -0
  90. package/packages/piagent-webui/server/tool-call-summary.ts +3 -1
  91. package/packages/piagent-webui/server/transcript-projection.ts +20 -4
  92. package/packages/piagent-webui/shared/process-copy.ts +3 -1
  93. package/packages/piagent-webui/shared/turn-end.ts +68 -0
  94. package/schemas/piagent-webui/session-catalog-v1.schema.json +11 -1
  95. package/schemas/piagent-webui/transcript-v1.schema.json +23 -2
  96. package/scripts/company-terminal.mjs +15 -0
  97. package/scripts/configure-model-scope.sh +1 -0
  98. package/templates/global/settings.json +2 -1
@@ -0,0 +1,68 @@
1
+ // How a member's message ended in a company conversation ("agent-watch-turn-end"),
2
+ // read the same way by the transcript, the session list and the company
3
+ // Terminal: every checklist step done, stopped with steps open, failed (which
4
+ // harness role), or stopped by the member.
5
+ import { failureRoleText, type CopyLocale, type FailureRole } from "./company-copy.ts";
6
+
7
+ export type TurnEndState = "done" | "midway" | "failed" | "cancelled";
8
+ export type TurnEnd = { state: TurnEndState; planSteps: number; planDone: number; planDeferred?: number; rounds: number;
9
+ reason?: "idle" | "limit" | "policy"; role?: FailureRole; code?: string };
10
+ const ROLES: FailureRole[] = ["main", "scout", "research", "verify", "review"];
11
+ // The harness gives up after this many rounds in a row without progress, and
12
+ // runs at most this many (packages/piagent-core/managed/continuation.mjs).
13
+ export const IDLE_ROUNDS = 2, MAX_ROUNDS = 30;
14
+
15
+ // The recorded details, checked; null when they do not have the expected shape.
16
+ export function turnEndOf(details: any): TurnEnd | null {
17
+ const count = (n: unknown): n is number => Number.isInteger(n) && (n as number) >= 0 && (n as number) <= 30;
18
+ if (!["done", "midway", "failed", "cancelled"].includes(details?.state) || !count(details.planSteps) || !count(details.planDone)
19
+ || !count(details.rounds) || (details.planDeferred !== undefined && !count(details.planDeferred))
20
+ || details.planDone + (details.planDeferred ?? 0) > details.planSteps) return null;
21
+ const out: TurnEnd = { state: details.state, planSteps: details.planSteps, planDone: details.planDone, rounds: details.rounds };
22
+ if (details.planDeferred) out.planDeferred = details.planDeferred;
23
+ if (details.state === "midway" && ["idle", "limit", "policy"].includes(details.reason)) out.reason = details.reason;
24
+ if (details.state === "failed") {
25
+ out.role = ROLES.includes(details.role) ? details.role : "main";
26
+ if (typeof details.code === "string" && /^[a-z0-9_]{1,64}$/.test(details.code)) out.code = details.code;
27
+ }
28
+ return out;
29
+ }
30
+
31
+ const pick = (locale: CopyLocale, vi: string, en: string) => locale === "vi" ? vi : en;
32
+ export type TurnEndCopy = { tone: "success" | "warning" | "error" | "info"; title: string; text: string; continuable: boolean };
33
+
34
+ // What the member reads under the last answer: is the task finished, and if
35
+ // not, why the agent stopped and what to do.
36
+ export function turnEndCopy(end: TurnEnd, locale: CopyLocale): TurnEndCopy {
37
+ const later = end.planDeferred ?? 0, open = end.planSteps - end.planDone - later;
38
+ const rounds = end.rounds ? pick(locale, ` Harness đã cho agent làm tiếp ${end.rounds} vòng.`, ` The harness sent the agent back ${end.rounds} time(s).`) : "";
39
+ if (end.state === "cancelled") return { tone: "info", continuable: true, title: pick(locale, "Bạn đã dừng lượt này", "You stopped this turn"),
40
+ text: pick(locale, `Task chưa xong${end.planSteps ? ` (${end.planDone}/${end.planSteps} bước)` : ""}. Bấm Tiếp tục để agent làm tiếp từ chỗ dừng.`,
41
+ `The task is not finished${end.planSteps ? ` (${end.planDone}/${end.planSteps} steps)` : ""}. Choose Continue to pick up where it stopped.`) };
42
+ if (end.state === "failed") return { tone: "error", continuable: true,
43
+ title: pick(locale, `Lượt dừng vì lỗi · ${failureRoleText(end.role ?? "main", locale)}`, `Turn stopped by a failure · ${failureRoleText(end.role ?? "main", locale)}`),
44
+ text: pick(locale, `Task chưa xong${end.planSteps ? `: còn ${open}/${end.planSteps} bước` : ""}. Xem lỗi phía trên; khi đã xử lý, bấm Tiếp tục để chạy lại từ chỗ dừng.`,
45
+ `The task is not finished${end.planSteps ? `: ${open} of ${end.planSteps} steps open` : ""}. See the failure above; once it is resolved, choose Continue.`) + (end.code ? ` [${end.code}]` : "") };
46
+ if (end.state === "midway") {
47
+ const why = end.reason === "idle" ? pick(locale, `Main agent dừng ${IDLE_ROUNDS} vòng liên tiếp mà không xong thêm bước nào: đọc câu trả lời cuối để biết vướng gì.`,
48
+ `The main agent stopped ${IDLE_ROUNDS} rounds in a row without finishing a step: its last answer says what is in the way.`)
49
+ : end.reason === "limit" ? pick(locale, `Đã tới giới hạn ${MAX_ROUNDS} vòng tự làm tiếp cho một tin nhắn.`, `The limit of ${MAX_ROUNDS} automatic rounds for one message was reached.`)
50
+ : pick(locale, "Harness của team không bắt buộc plan nên không tự làm tiếp.", "The team's Harness does not require a plan, so it does not continue on its own.");
51
+ return { tone: "warning", continuable: true, title: pick(locale, `Dừng giữa chừng · còn ${open}/${end.planSteps} bước`, `Stopped midway · ${open} of ${end.planSteps} steps open`),
52
+ text: `${why}${rounds} ${pick(locale, "Bấm Tiếp tục để làm tiếp.", "Choose Continue to go on.")}` };
53
+ }
54
+ // Steps left for later at the member's word (or no longer needed): done as asked, not all done.
55
+ if (later) return { tone: "info", continuable: true, title: pick(locale, `Dừng theo yêu cầu · ${end.planDone}/${end.planSteps} bước xong, ${later} bước để sau`, `Stopped as asked · ${end.planDone} of ${end.planSteps} steps done, ${later} left for later`),
56
+ text: pick(locale, "Các bước còn lại được để sau theo yêu cầu hoặc vì không cần nữa: câu trả lời cuối nói lý do. Bấm Tiếp tục khi muốn làm nốt.", "The other steps were left for later as asked, or are no longer needed: the last answer says why. Choose Continue to do them.") + rounds };
57
+ return { tone: "success", continuable: false, title: end.planSteps ? pick(locale, `Hoàn thành · ${end.planSteps}/${end.planSteps} bước`, `Done · ${end.planSteps}/${end.planSteps} steps`) : pick(locale, "Xong lượt", "Turn finished"),
58
+ text: (end.planSteps ? pick(locale, "Mọi bước trong checklist đã xong.", "Every checklist step is completed.") : pick(locale, "Main agent đã trả lời xong; lượt này không có checklist.", "The main agent finished its answer; this turn had no checklist.")) + rounds };
59
+ }
60
+
61
+ // The short label of the session list.
62
+ export function turnEndShort(end: Pick<TurnEnd, "state" | "planSteps" | "planDone" | "planDeferred">, locale: CopyLocale): string {
63
+ if (end.state === "done" && end.planDeferred) return pick(locale, `Xong ${end.planDone}/${end.planSteps}, để sau ${end.planDeferred}`, `Done ${end.planDone}/${end.planSteps}, ${end.planDeferred} later`);
64
+ if (end.state === "midway") return pick(locale, `Dừng giữa chừng ${end.planDone}/${end.planSteps}`, `Stopped ${end.planDone}/${end.planSteps}`);
65
+ if (end.state === "failed") return pick(locale, "Lỗi, chưa xong", "Failed");
66
+ if (end.state === "cancelled") return pick(locale, "Đã dừng", "Stopped");
67
+ return end.planSteps ? pick(locale, `Xong ${end.planSteps}/${end.planSteps}`, `Done ${end.planSteps}/${end.planSteps}`) : pick(locale, "Xong", "Done");
68
+ }
@@ -95,13 +95,23 @@
95
95
  "managedThinkingLevels": {"type": "array", "uniqueItems": true, "maxItems": 7, "items": {"enum": ["off","minimal","low","medium","high","xhigh","max"]}}, "managedPermission": {"enum": ["workspace-write","trusted-full-access"]},
96
96
  "managedPlan": { "type": "object", "additionalProperties": false, "required": ["steps"], "properties": {
97
97
  "steps": { "type": "array", "minItems": 1, "maxItems": 30, "items": { "type": "object", "additionalProperties": false, "required": ["step", "status"], "properties": {
98
- "step": { "type": "string", "minLength": 1, "maxLength": 200 }, "status": { "enum": ["pending", "in_progress", "completed"] } } } } } },
98
+ "step": { "type": "string", "minLength": 1, "maxLength": 200 }, "status": { "enum": ["pending", "in_progress", "completed", "deferred"] } } } } } },
99
99
  "managedProcess": { "type": "object", "additionalProperties": false, "required": ["outcome", "verified", "reviewed", "blockingOpen"], "properties": {
100
100
  "outcome": { "enum": ["no_change", "interrupted", "disputed", "blocking_open", "unverified", "review_unavailable", "unreviewed", "clean"] },
101
101
  "verified": { "type": "boolean" }, "reviewed": { "type": "boolean" }, "blockingOpen": { "type": "integer", "minimum": 0, "maximum": 1000 }, "planSkipped": { "const": true } } },
102
+ "managedTurnEnd": { "type": "object", "additionalProperties": false, "required": ["state", "planSteps", "planDone"], "properties": {
103
+ "state": { "enum": ["done", "midway", "failed", "cancelled"] },
104
+ "planSteps": { "type": "integer", "minimum": 0, "maximum": 30 }, "planDone": { "type": "integer", "minimum": 0, "maximum": 30 },
105
+ "planDeferred": { "type": "integer", "minimum": 1, "maximum": 30 },
106
+ "reason": { "enum": ["idle", "limit", "policy"] } } },
102
107
  "gitBranch": { "type": "object", "additionalProperties": false, "required": ["name", "detached"], "properties": {
103
108
  "name": { "type": "string", "minLength": 1, "maxLength": 200, "pattern": "^[^\\u0000-\\u001F\\u007F]*$" },
104
109
  "detached": { "type": "boolean" } } },
110
+ "gitRepositories": { "type": "array", "maxItems": 30, "items": { "type": "object", "additionalProperties": false, "required": ["name", "branch"], "properties": {
111
+ "name": { "type": "string", "minLength": 1, "maxLength": 255, "pattern": "^[^\\u0000-\\u001F\\u007F/\\\\]*$" },
112
+ "branch": { "anyOf": [{ "type": "null" }, { "type": "object", "additionalProperties": false, "required": ["name", "detached"], "properties": {
113
+ "name": { "type": "string", "minLength": 1, "maxLength": 200, "pattern": "^[^\\u0000-\\u001F\\u007F]*$" },
114
+ "detached": { "type": "boolean" } } }] } } } },
105
115
  "modelLabel": { "$ref": "common-v1.schema.json#/$defs/nullableDisplayText" },
106
116
  "thinkingLevel": { "enum": ["off", "minimal", "low", "medium", "high", "xhigh", "max", "unknown"] },
107
117
  "contextUsage": { "$ref": "#/$defs/contextUsage" },
@@ -157,7 +157,7 @@
157
157
  "additionalProperties": false,
158
158
  "required": ["phase"],
159
159
  "properties": {
160
- "phase": { "enum": ["plan", "verify", "review", "final", "objection", "answer", "claims", "rejudge", "dispute"] },
160
+ "phase": { "enum": ["plan", "verify", "review", "final", "objection", "answer", "claims", "rejudge", "dispute", "continue"] },
161
161
  "outcome": { "enum": ["no_change", "interrupted", "disputed", "blocking_open", "unverified", "review_unavailable", "unreviewed", "clean"] },
162
162
  "role": { "enum": ["scout", "research", "verify", "review"] },
163
163
  "by": { "enum": ["main", "harness"] },
@@ -192,6 +192,11 @@
192
192
  "reviewed": { "type": "boolean" },
193
193
  "blockingOpen": { "type": "integer", "minimum": 0, "maximum": 1000 },
194
194
  "planOpen": { "type": "integer", "minimum": 1, "maximum": 30 },
195
+ "planDone": { "type": "integer", "minimum": 0, "maximum": 30 },
196
+ "planSteps": { "type": "integer", "minimum": 1, "maximum": 30 },
197
+ "round": { "type": "integer", "minimum": 1, "maximum": 30 },
198
+ "maxRounds": { "type": "integer", "minimum": 1, "maximum": 30 },
199
+ "idle": { "type": "integer", "minimum": 1, "maximum": 2 },
195
200
  "planSkipped": { "const": true },
196
201
  "verifyPolicy": { "enum": ["off", "suggest", "require"] },
197
202
  "reviewPolicy": { "enum": ["off", "suggest", "require"] },
@@ -213,6 +218,21 @@
213
218
  }
214
219
  }
215
220
  },
221
+ "turnEnd": {
222
+ "type": "object",
223
+ "additionalProperties": false,
224
+ "required": ["state", "planSteps", "planDone", "rounds"],
225
+ "properties": {
226
+ "state": { "enum": ["done", "midway", "failed", "cancelled"] },
227
+ "planSteps": { "type": "integer", "minimum": 0, "maximum": 30 },
228
+ "planDone": { "type": "integer", "minimum": 0, "maximum": 30 },
229
+ "planDeferred": { "type": "integer", "minimum": 1, "maximum": 30 },
230
+ "rounds": { "type": "integer", "minimum": 0, "maximum": 30 },
231
+ "reason": { "enum": ["idle", "limit", "policy"] },
232
+ "role": { "enum": ["main", "scout", "research", "verify", "review"] },
233
+ "code": { "type": "string", "pattern": "^[a-z0-9_]{1,64}$" }
234
+ }
235
+ },
216
236
  "companyFailure": {
217
237
  "type": "object",
218
238
  "additionalProperties": false,
@@ -243,7 +263,7 @@
243
263
  "additionalProperties": false,
244
264
  "required": ["kind", "target", "detail"],
245
265
  "properties": {
246
- "kind": { "enum": ["read", "write", "edit", "command", "search", "list", "web-search", "web-fetch", "subagent", "network", "git", "plan", "other"] },
266
+ "kind": { "enum": ["read", "write", "edit", "command", "search", "list", "web-search", "web-fetch", "subagent", "network", "docker", "git", "plan", "other"] },
247
267
  "target": { "anyOf": [{ "type": "string", "maxLength": 400 }, { "type": "null" }] },
248
268
  "detail": { "anyOf": [{ "type": "string", "maxLength": 400 }, { "type": "null" }] }
249
269
  }
@@ -315,6 +335,7 @@
315
335
  "model": { "type": "string", "minLength": 1, "maxLength": 120, "pattern": "^[A-Za-z0-9._:@/-]{1,120}$" },
316
336
  "failure": { "$ref": "#/$defs/companyFailure" },
317
337
  "process": { "$ref": "#/$defs/harnessProcess" },
338
+ "turnEnd": { "$ref": "#/$defs/turnEnd" },
318
339
  "toolCalls": {
319
340
  "type": "array",
320
341
  "maxItems": 64,
@@ -11,6 +11,7 @@ import { registerTerminalUpdateOffer } from '../packages/piagent-core/runtime/up
11
11
  import { parseFailure } from '../packages/piagent-core/runtime/managed-failure.mjs';
12
12
  import { companyFailureText } from '../packages/piagent-webui/shared/company-copy.ts';
13
13
  import { headlineText, outcomeText, processItems } from '../packages/piagent-webui/shared/process-copy.ts';
14
+ import { turnEndCopy, turnEndOf } from '../packages/piagent-webui/shared/turn-end.ts';
14
15
 
15
16
  const LOCALE = 'vi';
16
17
  const PERMISSION_STATUS = 'agent-watch-permission';
@@ -88,6 +89,20 @@ export function companyTerminalExtension({ managed, packageRoot, sdkRoot, bindin
88
89
  const loud = ['dispute', 'objection'].includes(message.details?.phase) || message.details?.outcome === 'disputed';
89
90
  return lines ? box(lines.join('\n'), theme, loud ? 'warning' : message.details?.outcome === 'clean' ? 'success' : 'muted') : undefined;
90
91
  });
92
+ // How the member's message ended (finished, stopped with steps open,
93
+ // failed, stopped), as the dashboard says it under the last answer.
94
+ let heard = null;
95
+ pi.on('session_start', async (_event, ctx) => {
96
+ const session = managed()?.session;
97
+ if (!session?.subscribe || heard === session) return;
98
+ heard = session;
99
+ session.subscribe((event) => {
100
+ const end = event?.type === 'managed_turn_end' ? turnEndOf(event.end) : null;
101
+ if (!end) return;
102
+ const copy = turnEndCopy(end, LOCALE);
103
+ ctx.ui?.notify?.(`${copy.title}. ${copy.text.replace('Bấm Tiếp tục', 'Gửi "tiếp tục"').replace('bấm Tiếp tục', 'gửi "tiếp tục"')}`, copy.tone === 'success' ? 'info' : copy.tone === 'error' ? 'error' : copy.tone === 'warning' ? 'warning' : 'info');
104
+ });
105
+ });
91
106
  pi.registerMessageRenderer('agent-watch-review-status', (_message, _options, theme) =>
92
107
  box('Review đã cũ: code đổi sau khi review. Cần review lại cho thay đổi hiện tại.', theme, 'warning'));
93
108
  pi.registerMessageRenderer('agent-watch-helper-receipt', (message, _options, theme) =>
@@ -135,6 +135,7 @@ const codexModels = [
135
135
 
136
136
  const claudeModels = [
137
137
  "anthropic/claude-haiku-4-5:low",
138
+ "anthropic/claude-haiku-5-5:medium",
138
139
  "anthropic/claude-sonnet-4-5:high",
139
140
  "anthropic/claude-sonnet-4-6:max",
140
141
  "anthropic/claude-sonnet-5:xhigh",
@@ -27,7 +27,8 @@
27
27
  "anthropic/claude-opus-4-8:xhigh",
28
28
  "anthropic/claude-fable-5:xhigh",
29
29
  "anthropic/claude-sonnet-5-5:high",
30
- "anthropic/claude-opus-5-5:high"
30
+ "anthropic/claude-opus-5-5:high",
31
+ "anthropic/claude-haiku-5-5:medium"
31
32
  ],
32
33
  "compaction": {
33
34
  "enabled": true,