@piagent/platform 1.31.1 → 1.32.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/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 +12 -0
- package/docs-site/content/index.html +4 -4
- package/docs-site/content/whats-new.html +12 -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 +13 -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 +13 -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/request-stream.mjs +33 -4
- package/packages/piagent-core/package.json +1 -1
- package/packages/piagent-core/runtime/managed-failure.mjs +5 -0
- package/packages/piagent-webui/dist/client/assets/{MarkdownMessage-ZFXG_br8.js → MarkdownMessage-dCzZ2b6f.js} +1 -1
- package/packages/piagent-webui/dist/client/assets/{index-B3ODBFGj.js → index-CZ02zZjO.js} +5 -5
- package/packages/piagent-webui/dist/client/index.html +1 -1
- package/packages/piagent-webui/server/loopback-server.ts +1 -0
- package/packages/piagent-webui/server/session-auth.ts +16 -3
|
@@ -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-CZ02zZjO.js"></script>
|
|
11
11
|
<link rel="stylesheet" crossorigin href="/assets/index-B5XOKQy-.css">
|
|
12
12
|
</head>
|
|
13
13
|
<body>
|
|
@@ -112,6 +112,7 @@ export async function startLoopbackServer(options: {
|
|
|
112
112
|
// Charging every tab and every prior launch to one localhost IP lets a
|
|
113
113
|
// refresh or an unauthenticated local process lock out the active operator.
|
|
114
114
|
const browserSession = auth.authenticate(request, now);
|
|
115
|
+
if (browserSession && auth.renew(browserSession, now)) response.setHeader("Set-Cookie", auth.cookieHeader(browserSession));
|
|
115
116
|
const rateKey = browserSession ? `${remote}:${browserSession.id}` : `remote:${remote}`;
|
|
116
117
|
for (const [key, value] of rates) if (now - value.windowStart >= 60_000) rates.delete(key);
|
|
117
118
|
const rate = rates.get(rateKey) ?? { windowStart: now, requests: 0, bootstrapFailures: 0 };
|
|
@@ -20,20 +20,23 @@ function cookie(request: IncomingMessage, name: string): string | null {
|
|
|
20
20
|
return null;
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
export type BrowserSession = { id: string; csrf: string; expiresAt: number };
|
|
23
|
+
export type BrowserSession = { id: string; csrf: string; expiresAt: number; startedAt: number };
|
|
24
24
|
|
|
25
25
|
export class SessionAuthority {
|
|
26
26
|
readonly #initialBootstrap: string;
|
|
27
27
|
readonly #bootstrapTtlMs: number;
|
|
28
28
|
readonly #sessionTtlMs: number;
|
|
29
|
+
readonly #sessionMaxMs: number;
|
|
29
30
|
readonly #cookieSigningKey = randomBytes(32);
|
|
30
31
|
#cookieName = SESSION_COOKIE;
|
|
31
32
|
#bootstraps = new Map<string, number>();
|
|
32
33
|
#sessions = new Map<string, BrowserSession>();
|
|
33
34
|
|
|
34
|
-
constructor(options: { now?: number; bootstrapTtlMs?: number; sessionTtlMs?: number } = {}) {
|
|
35
|
+
constructor(options: { now?: number; bootstrapTtlMs?: number; sessionTtlMs?: number; sessionMaxMs?: number } = {}) {
|
|
35
36
|
this.#bootstrapTtlMs = options.bootstrapTtlMs ?? 60_000;
|
|
37
|
+
// 8 hours unused; a tab in use is renewed (renew), up to 7 days.
|
|
36
38
|
this.#sessionTtlMs = options.sessionTtlMs ?? 8 * 60 * 60_000;
|
|
39
|
+
this.#sessionMaxMs = options.sessionMaxMs ?? 7 * 24 * 60 * 60_000;
|
|
37
40
|
this.#initialBootstrap = this.issueBootstrapCapability(options.now ?? Date.now());
|
|
38
41
|
}
|
|
39
42
|
|
|
@@ -59,7 +62,7 @@ export class SessionAuthority {
|
|
|
59
62
|
const match = [...this.#bootstraps].find(([value, createdAt]) => now <= createdAt + this.#bootstrapTtlMs && equal(candidate, value));
|
|
60
63
|
if (!match) return null;
|
|
61
64
|
this.#bootstraps.delete(match[0]);
|
|
62
|
-
const session = { id: randomUUID(), csrf: secret(), expiresAt: now + this.#sessionTtlMs };
|
|
65
|
+
const session = { id: randomUUID(), csrf: secret(), expiresAt: now + this.#sessionTtlMs, startedAt: now };
|
|
63
66
|
this.#sessions.set(session.id, session);
|
|
64
67
|
return session;
|
|
65
68
|
}
|
|
@@ -79,6 +82,16 @@ export class SessionAuthority {
|
|
|
79
82
|
return session;
|
|
80
83
|
}
|
|
81
84
|
|
|
85
|
+
// A session ended 8 hours after its launch even while its tab was in use:
|
|
86
|
+
// a turn that ran or hung that long ended on the expired screen. An open
|
|
87
|
+
// tab asks every minute, so past half its time a request moves the expiry
|
|
88
|
+
// on, within the cap; true when the caller must send the cookie again.
|
|
89
|
+
renew(session: BrowserSession, now = Date.now()): boolean {
|
|
90
|
+
const next = Math.min(now + this.#sessionTtlMs, session.startedAt + this.#sessionMaxMs);
|
|
91
|
+
if (next - session.expiresAt < this.#sessionTtlMs / 2) return false;
|
|
92
|
+
session.expiresAt = next; return true;
|
|
93
|
+
}
|
|
94
|
+
|
|
82
95
|
authorizeMutation(request: IncomingMessage, now = Date.now()): BrowserSession | null {
|
|
83
96
|
const session = this.authenticate(request, now);
|
|
84
97
|
const csrf = request.headers["x-piagent-csrf"];
|