@piagent/platform 1.15.0 → 1.15.2
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 +28 -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/languages.json +2 -2
- package/docs/operator-manual-vietnamese.md +7 -7
- package/docs/publishing-for-teams.md +2 -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/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 +23 -0
- package/docs-site/content/index.html +4 -4
- package/docs-site/content/whats-new.html +23 -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 +24 -1
- package/docs-site/en/windows.html +1 -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 +24 -1
- package/docs-site/windows.html +1 -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/call-purpose.mjs +49 -0
- package/packages/piagent-core/managed/compaction.mjs +47 -1
- package/packages/piagent-core/managed/helper-roles.mjs +7 -3
- package/packages/piagent-core/managed/helper-run.mjs +6 -3
- package/packages/piagent-core/managed/patch-snapshot.mjs +29 -7
- package/packages/piagent-core/managed/request-stream.mjs +12 -1
- package/packages/piagent-core/managed/review-snapshot-worker.mjs +27 -3
- package/packages/piagent-core/managed/sandbox-diagnostic.mjs +4 -1
- package/packages/piagent-core/managed/session.mjs +42 -13
- package/packages/piagent-core/managed/web-search.mjs +1 -1
- package/packages/piagent-core/managed/workflow.mjs +19 -5
- package/packages/piagent-core/package.json +1 -1
- package/packages/piagent-webui/dist/client/assets/{MarkdownMessage-PIk4Femi.js → MarkdownMessage-DjA3OGyI.js} +1 -1
- package/packages/piagent-webui/dist/client/assets/{index-DeCt-FaN.js → index-bE2DKmc1.js} +4 -4
- package/packages/piagent-webui/dist/client/index.html +1 -1
- package/packages/piagent-webui/gateway/session-command-controller.ts +11 -0
- package/packages/piagent-webui/gateway/session-runtime-supervisor.ts +2 -2
- package/packages/piagent-webui/ownership/session-lease-store.ts +20 -1
- package/scripts/piagent-cli.mjs +5 -1
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
<meta name="csp-nonce" content="__PIAGENT_CSP_NONCE__" />
|
|
8
8
|
<meta name="piagent-webui-mode" content="__PIAGENT_WEBUI_MODE__" />
|
|
9
9
|
<title>Piagent WebUI</title>
|
|
10
|
-
<script type="module" crossorigin src="/assets/index-
|
|
10
|
+
<script type="module" crossorigin src="/assets/index-bE2DKmc1.js"></script>
|
|
11
11
|
<link rel="stylesheet" crossorigin href="/assets/index-Z91z6SlN.css">
|
|
12
12
|
</head>
|
|
13
13
|
<body>
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { randomBytes } from "node:crypto";
|
|
2
|
+
import { parseFailure } from "../../piagent-core/runtime/managed-failure.mjs";
|
|
2
3
|
|
|
3
4
|
import type { Catalog, SessionRow } from "../contracts/generated/session-catalog-v1.ts";
|
|
4
5
|
import type { Receipt } from "../contracts/generated/session-command-v1.ts";
|
|
@@ -279,6 +280,16 @@ export class SessionCommandController {
|
|
|
279
280
|
try { if (noDispatchEffect) attachmentReservation.release(); else attachmentReservation.commit(); }
|
|
280
281
|
catch { /* an attempted dispatch with an unprovable reservation remains uncertain */ }
|
|
281
282
|
}
|
|
283
|
+
// The company runtime of a new or reopened conversation did not open
|
|
284
|
+
// (key, harness, Agent Watch helper): nothing was sent. Say why, by
|
|
285
|
+
// its kind, rather than "resyncing" or a bare "could not restart".
|
|
286
|
+
const company = ["session.create", "session.acquire"].includes(command.action) && /^managed-[a-z]/.test(message) ? parseFailure(message) : null;
|
|
287
|
+
if (company && company.code !== "managed-request-failed") {
|
|
288
|
+
const receipt = this.#rejected(command, after, afterRow, "unavailable", `company-${company.kind}`);
|
|
289
|
+
try { this.#store.settle(command, receipt, this.#now()); } catch { /* intent remains uncertain */ }
|
|
290
|
+
if (command.action === "session.create" && afterRow) this.#events.publish("session.changed", { catalogRevision: after.catalogRevision, session: afterRow });
|
|
291
|
+
return receipt;
|
|
292
|
+
}
|
|
282
293
|
const code = /recovery/.test(message) ? "recovery-required"
|
|
283
294
|
: /(owner-conflict|operation-conflict|runtime-busy)/.test(message) ? "owner-conflict"
|
|
284
295
|
: noDispatchEffect || command.action === "session.send" && !sendAttempted ? "unavailable" : "effect-unknown";
|
|
@@ -133,7 +133,7 @@ export class SessionRuntimeSupervisor {
|
|
|
133
133
|
const runtimeInstanceRef = `runtime_${randomBytes(24).toString("base64url")}`;
|
|
134
134
|
const prior = this.#leases.inspect(sessionRef);
|
|
135
135
|
if (prior.state === "gateway-owned" || prior.state === "terminal-owned" || prior.state === "recovery-required") {
|
|
136
|
-
try { this.#leases.releaseDeadOwnerForExplicitRecovery(sessionRef); } catch { /* live or unprovable owners stay authoritative */ }
|
|
136
|
+
try { this.#leases.releaseDeadOwnerForExplicitRecovery(sessionRef, new Date(), this.#gatewayInstanceRef); } catch { /* live or unprovable owners stay authoritative */ }
|
|
137
137
|
}
|
|
138
138
|
const lease = this.#leases.acquire(sessionRef, this.#gatewayInstanceRef, runtimeInstanceRef);
|
|
139
139
|
try {
|
|
@@ -161,7 +161,7 @@ export class SessionRuntimeSupervisor {
|
|
|
161
161
|
const active = this.#active.get(sessionRef);
|
|
162
162
|
if (!active) {
|
|
163
163
|
const current = this.#leases.inspect(sessionRef);
|
|
164
|
-
if (current.state === "released") return
|
|
164
|
+
if (current.state === "released" || current.state === "recovery-required" && current.gatewayInstanceRef === this.#gatewayInstanceRef) return this.#leases.releaseOwnRecovery(sessionRef, this.#gatewayInstanceRef);
|
|
165
165
|
throw new Error(current.state === "recovery-required" ? "session-recovery-required" : "session-owner-conflict");
|
|
166
166
|
}
|
|
167
167
|
if (active.operationRef) throw new Error("session-runtime-busy");
|
|
@@ -253,8 +253,10 @@ export class SessionLeaseStore {
|
|
|
253
253
|
return this.#acquireOwner(sessionRef, gatewayInstanceRef, runtimeInstanceRef, now);
|
|
254
254
|
}
|
|
255
255
|
|
|
256
|
-
|
|
256
|
+
// `ownGateway`: the calling Gateway, whose own recovery it may release.
|
|
257
|
+
releaseDeadOwnerForExplicitRecovery(sessionRef: string, now = new Date(), ownGateway?: string): SessionLeaseSnapshot {
|
|
257
258
|
if (!Number.isFinite(now.getTime())) throw new Error("session-lease-input-invalid");
|
|
259
|
+
if (ownGateway && this.inspect(sessionRef).state === "recovery-required" && this.inspect(sessionRef).gatewayInstanceRef === ownGateway) return this.releaseOwnRecovery(sessionRef, ownGateway, now);
|
|
258
260
|
return this.#withMutationLock(sessionRef, () => {
|
|
259
261
|
const current = this.inspect(sessionRef);
|
|
260
262
|
const terminalOwner = current.state === "terminal-owned"
|
|
@@ -329,6 +331,23 @@ export class SessionLeaseStore {
|
|
|
329
331
|
});
|
|
330
332
|
}
|
|
331
333
|
|
|
334
|
+
// A Gateway whose own runtime failed to open or to close left the lease in
|
|
335
|
+
// recovery under its own name. Nothing of it runs (the Gateway knows its
|
|
336
|
+
// live runtimes), so that Gateway may release it: archiving or reopening
|
|
337
|
+
// must not wait for the Gateway itself to exit. Another owner's recovery
|
|
338
|
+
// still needs proof that the owner is gone.
|
|
339
|
+
releaseOwnRecovery(sessionRef: string, gatewayInstanceRef: string, now = new Date()): SessionLeaseSnapshot {
|
|
340
|
+
if (!validRef(gatewayInstanceRef) || gatewayInstanceRef.startsWith(TERMINAL_OWNER_PREFIX) || !Number.isFinite(now.getTime())) throw new Error("session-lease-input-invalid");
|
|
341
|
+
return this.#withMutationLock(sessionRef, () => {
|
|
342
|
+
const current = this.inspect(sessionRef);
|
|
343
|
+
if (current.state === "released") return current;
|
|
344
|
+
if (current.state !== "recovery-required" || current.gatewayInstanceRef !== gatewayInstanceRef) throw new Error("session-recovery-required");
|
|
345
|
+
this.#append(sessionRef, { recordedAt: now.toISOString(), sessionRef, event: "released", ownerEpoch: current.ownerEpoch!,
|
|
346
|
+
gatewayInstanceRef, runtimeInstanceRef: current.runtimeInstanceRef!, reasonCode: null });
|
|
347
|
+
return this.inspect(sessionRef);
|
|
348
|
+
});
|
|
349
|
+
}
|
|
350
|
+
|
|
332
351
|
requireRecovery(sessionRef: string, ownerEpoch: string, gatewayInstanceRef: string, runtimeInstanceRef: string,
|
|
333
352
|
reasonCode: string, now = new Date()): SessionLeaseSnapshot {
|
|
334
353
|
if (!validRef(reasonCode)) throw new Error("session-lease-reason-invalid");
|
package/scripts/piagent-cli.mjs
CHANGED
|
@@ -51,6 +51,10 @@ if (invokedAs === "piagent") {
|
|
|
51
51
|
} else if (subcommand === "select-verification") {
|
|
52
52
|
script = "scripts/select-independent-verification.mjs";
|
|
53
53
|
forwardedArgs = forwardedArgs.slice(1);
|
|
54
|
+
} else if (subcommand && Object.hasOwn(scriptByCommand, `piagent-${subcommand}`)) {
|
|
55
|
+
// `piagent doctor` is `piagent-doctor`: members type it both ways.
|
|
56
|
+
script = scriptByCommand[`piagent-${subcommand}`];
|
|
57
|
+
forwardedArgs = forwardedArgs.slice(1);
|
|
54
58
|
} else if ([undefined, "help", "--help", "-h"].includes(subcommand)) {
|
|
55
59
|
// Subcommands are listed, their flags are not. Restating them here meant a
|
|
56
60
|
// second copy that drifts: this line still advertised the dashboard without
|
|
@@ -70,7 +74,7 @@ if (invokedAs === "piagent") {
|
|
|
70
74
|
}
|
|
71
75
|
|
|
72
76
|
if (!script) {
|
|
73
|
-
console.error(`Unknown Pi Agent command: ${invokedAs || "(unknown)"}`);
|
|
77
|
+
console.error(`Unknown Pi Agent command: ${[invokedAs || "(unknown)", invokedAs === "piagent" ? forwardedArgs[0] : ""].filter(Boolean).join(" ")}`);
|
|
74
78
|
console.error(`Expected one of: ${Object.keys(scriptByCommand).sort().join(", ")}`);
|
|
75
79
|
process.exit(2);
|
|
76
80
|
}
|