@standardagents/builder 0.40.0 → 0.40.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/dist/built-in-routes.js +117 -25
- package/dist/built-in-routes.js.map +1 -1
- package/dist/{index-9MaIifn3.d.ts → index-0NI3m5DR.d.ts} +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +64 -3
- package/dist/index.js.map +1 -1
- package/dist/plugin.d.ts +12 -1
- package/dist/plugin.js +47 -2
- package/dist/plugin.js.map +1 -1
- package/dist/runtime.d.ts +4 -2
- package/dist/runtime.js +17 -1
- package/dist/runtime.js.map +1 -1
- package/dist/test.d.ts +1 -1
- package/package.json +5 -5
package/dist/built-in-routes.js
CHANGED
|
@@ -11251,7 +11251,12 @@ function queueTool(flow, toolName, args = {}) {
|
|
|
11251
11251
|
}
|
|
11252
11252
|
async function injectMessage(flow, options) {
|
|
11253
11253
|
const messageId = options.id ?? crypto.randomUUID();
|
|
11254
|
-
const
|
|
11254
|
+
const wallClockTimestamp = Date.now() * TIMESTAMP_MULTIPLIER;
|
|
11255
|
+
const latestLiveTimestamp = flow.messageHistory.reduce(
|
|
11256
|
+
(latest, entry) => Math.max(latest, entry.created_at),
|
|
11257
|
+
0
|
|
11258
|
+
);
|
|
11259
|
+
const timestamp = options.beforeMessageId ? wallClockTimestamp : Math.max(wallClockTimestamp, latestLiveTimestamp + 1);
|
|
11255
11260
|
const silent = options.silent ?? false;
|
|
11256
11261
|
const forceTopLevel = options.forceTopLevel ?? false;
|
|
11257
11262
|
let message = {
|
|
@@ -68894,7 +68899,7 @@ var config_get_default = defineController2(async ({ config, env: env2, req }) =>
|
|
|
68894
68899
|
});
|
|
68895
68900
|
|
|
68896
68901
|
// src/version.ts
|
|
68897
|
-
var BUILDER_VERSION = "0.40.
|
|
68902
|
+
var BUILDER_VERSION = "0.40.2".length > 0 ? "0.40.2" : "dev";
|
|
68898
68903
|
|
|
68899
68904
|
// src/api/diagnostics.get.ts
|
|
68900
68905
|
init_LLMRequest();
|
|
@@ -76278,6 +76283,10 @@ var stream_default3 = defineController2(async (context) => {
|
|
|
76278
76283
|
|
|
76279
76284
|
// src/api/auth/device/[code]/_approval.ts
|
|
76280
76285
|
var CONFIRMATION_TTL_SECONDS = 5 * 60;
|
|
76286
|
+
var BUILT_IN_DEVICE_APPROVAL_BRAND = {
|
|
76287
|
+
name: "Standard Agents",
|
|
76288
|
+
description: "Connect a new device to your account."
|
|
76289
|
+
};
|
|
76281
76290
|
function escapeHtml(value) {
|
|
76282
76291
|
return value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
76283
76292
|
}
|
|
@@ -76294,18 +76303,85 @@ function page(title, body, ok) {
|
|
|
76294
76303
|
}
|
|
76295
76304
|
);
|
|
76296
76305
|
}
|
|
76297
|
-
function
|
|
76298
|
-
|
|
76306
|
+
function optionalPresentationText(value, maxLength) {
|
|
76307
|
+
return typeof value === "string" && value.trim() && value.trim().length <= maxLength ? value.trim() : void 0;
|
|
76308
|
+
}
|
|
76309
|
+
function safePresentationLogo(value, allowRelative) {
|
|
76310
|
+
const logoUrl = optionalPresentationText(value, 2048);
|
|
76311
|
+
if (!logoUrl) return void 0;
|
|
76312
|
+
if (allowRelative && logoUrl.startsWith("/") && !logoUrl.startsWith("//") && !logoUrl.includes("#") && !logoUrl.includes("\\")) {
|
|
76313
|
+
return logoUrl;
|
|
76314
|
+
}
|
|
76315
|
+
try {
|
|
76316
|
+
const parsed = new URL(logoUrl);
|
|
76317
|
+
if (parsed.protocol !== "https:" || parsed.username || parsed.password || parsed.hash) return void 0;
|
|
76318
|
+
return parsed.toString();
|
|
76319
|
+
} catch {
|
|
76320
|
+
return void 0;
|
|
76321
|
+
}
|
|
76322
|
+
}
|
|
76323
|
+
function normalizeRuntimeBrand(value, platformShape) {
|
|
76324
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return null;
|
|
76325
|
+
const record24 = value;
|
|
76326
|
+
const name15 = optionalPresentationText(record24.name, 100);
|
|
76327
|
+
if (!name15) return null;
|
|
76328
|
+
const description = optionalPresentationText(record24.description, 280);
|
|
76329
|
+
const logoValue = platformShape ? record24.logo_url : record24.logoUrl;
|
|
76330
|
+
const logoUrl = safePresentationLogo(logoValue, !platformShape);
|
|
76331
|
+
return {
|
|
76332
|
+
name: name15,
|
|
76333
|
+
...description ? { description } : {},
|
|
76334
|
+
...logoUrl ? { logoUrl } : {}
|
|
76335
|
+
};
|
|
76336
|
+
}
|
|
76337
|
+
async function resolveDeviceApprovalBrand(env2, config) {
|
|
76338
|
+
const configured = normalizeRuntimeBrand(config?.deviceApproval, false);
|
|
76339
|
+
const projectId = optionalPresentationText(
|
|
76340
|
+
env2.STANDARD_AGENTS_PROJECT_ID,
|
|
76341
|
+
128
|
|
76342
|
+
);
|
|
76343
|
+
if (isPlatformHosted(env2) && projectId) {
|
|
76344
|
+
try {
|
|
76345
|
+
const url = new URL("/partners/auth/brand", `${platformEndpoint(env2)}/`);
|
|
76346
|
+
url.searchParams.set("project_id", projectId);
|
|
76347
|
+
const response = await fetch(url, {
|
|
76348
|
+
headers: { Accept: "application/json" },
|
|
76349
|
+
signal: AbortSignal.timeout(1e3)
|
|
76350
|
+
});
|
|
76351
|
+
if (response.ok) {
|
|
76352
|
+
const payload = await response.json();
|
|
76353
|
+
const authoritative = normalizeRuntimeBrand(payload.instance, true);
|
|
76354
|
+
if (authoritative) return authoritative;
|
|
76355
|
+
}
|
|
76356
|
+
} catch {
|
|
76357
|
+
}
|
|
76358
|
+
}
|
|
76359
|
+
return configured ?? BUILT_IN_DEVICE_APPROVAL_BRAND;
|
|
76360
|
+
}
|
|
76361
|
+
function approvalCsp(req, brand) {
|
|
76362
|
+
let imageSource = "";
|
|
76363
|
+
if (brand.logoUrl) {
|
|
76364
|
+
const requestOrigin = new URL(req.url).origin;
|
|
76365
|
+
const logoOrigin = new URL(brand.logoUrl, requestOrigin).origin;
|
|
76366
|
+
imageSource = `; img-src ${logoOrigin === requestOrigin ? "'self'" : logoOrigin}`;
|
|
76367
|
+
}
|
|
76368
|
+
return `default-src 'none'; style-src 'unsafe-inline'; form-action 'self'; base-uri 'none'; frame-ancestors 'none'${imageSource}`;
|
|
76369
|
+
}
|
|
76370
|
+
function confirmationPage(req, confirmationToken, handoff, brand, identity) {
|
|
76299
76371
|
const handoffInput = handoff ? `<input type="hidden" name="handoff" value="${escapeHtml(handoff)}">` : "";
|
|
76300
|
-
const
|
|
76301
|
-
const
|
|
76372
|
+
const logo = brand.logoUrl ? `<img class="logo" src="${escapeHtml(brand.logoUrl)}" alt="">` : `<span class="logo-fallback" aria-hidden="true">${escapeHtml(brand.name.slice(0, 1).toUpperCase())}</span>`;
|
|
76373
|
+
const description = brand.description ? `<p class="description">${escapeHtml(brand.description)}</p>` : "";
|
|
76374
|
+
const secondaryIdentity = identity.displayEmail && identity.displayEmail !== identity.displayName ? `<span>${escapeHtml(identity.displayEmail)}</span>` : "";
|
|
76375
|
+
const html = `<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><meta name="referrer" content="no-referrer"><title>Connect device \xB7 ${escapeHtml(brand.name)}</title><style>
|
|
76376
|
+
:root{color-scheme:light dark;font-family:Inter,ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;background:#f6f7f9;color:#15171a}*{box-sizing:border-box}body{margin:0;min-height:100vh;display:grid;place-items:center;padding:28px;background:radial-gradient(circle at 50% 0,rgba(71,194,174,.12),transparent 38%),linear-gradient(#fbfcfd,#f2f4f6)}main{width:min(100%,480px)}.card{background:rgba(255,255,255,.92);border:1px solid #dfe3e8;border-radius:20px;padding:34px;box-shadow:0 24px 70px rgba(20,27,38,.12),0 2px 8px rgba(20,27,38,.06)}.brand{display:flex;align-items:center;gap:12px;margin-bottom:28px}.logo,.logo-fallback{width:38px;height:38px;border-radius:10px;display:grid;place-items:center;object-fit:contain}.logo-fallback{background:#171b21;color:#fff;font-weight:750}.brand strong{font-size:17px;letter-spacing:-.01em}h1{font-size:29px;line-height:1.18;letter-spacing:-.035em;margin:0 0 12px}p{margin:0;color:#5b6470;line-height:1.58}.description{margin-bottom:20px}.request{margin-top:18px}.identity{display:flex;align-items:center;gap:12px;margin-top:24px;padding:14px;border-radius:12px;background:#f2f4f6;border:1px solid #e3e6ea}.avatar{width:34px;height:34px;border-radius:50%;display:grid;place-items:center;background:#dfe4e8;color:#313841;font-weight:700}.identity-text{min-width:0;display:flex;flex-direction:column}.identity-label{font-size:11px;text-transform:uppercase;letter-spacing:.08em;color:#737d89}.identity strong,.identity span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.identity span{font-size:13px;color:#68727e}form{display:grid;gap:10px;margin-top:26px}button{appearance:none;border-radius:11px;padding:12px 16px;font:inherit;font-weight:700;cursor:pointer}.connect{border:1px solid #15191d;background:#15191d;color:#fff}.deny{border:1px solid transparent;background:transparent;color:#68727e}.deny:hover{background:#f1f3f5;color:#252a30}.disclosure{text-align:center;font-size:12px;color:#8a939d;margin:16px 0 0}@media(prefers-color-scheme:dark){:root{background:#090b0e;color:#f2f5f7}body{background:radial-gradient(circle at 50% 0,rgba(68,198,177,.12),transparent 38%),#090b0e}.card{background:rgba(17,20,25,.94);border-color:#292e36;box-shadow:0 28px 80px rgba(0,0,0,.42)}p{color:#a9b1bc}.identity{background:#191d23;border-color:#292f38}.avatar{background:#2b323b;color:#eef2f5}.identity-label,.identity span{color:#929ca8}.connect{background:#62d4c2;border-color:#62d4c2;color:#07110f}.deny{color:#9aa4af}.deny:hover{background:#1d2229;color:#e4e8ec}.disclosure{color:#747e8a}}
|
|
76377
|
+
</style></head><body><main><section class="card"><div class="brand">${logo}<strong>${escapeHtml(brand.name)}</strong></div><h1>Connect ${escapeHtml(brand.name)}?</h1>${description}<p class="request">A new device wants to connect to your account. Only continue if you started this sign-in.</p><div class="identity"><div class="avatar" aria-hidden="true">${escapeHtml(identity.displayName.slice(0, 1).toUpperCase())}</div><div class="identity-text"><span class="identity-label">Signed in as</span><strong>${escapeHtml(identity.displayName)}</strong>${secondaryIdentity}</div></div><form method="post" action=""><input type="hidden" name="confirmation_token" value="${escapeHtml(confirmationToken)}">${handoffInput}<button class="connect" type="submit" name="decision" value="approve">Connect device</button><button class="deny" type="submit" name="decision" value="deny">Not me</button></form></section><p class="disclosure">Authentication secured by Standard Agents</p></main></body></html>`;
|
|
76302
76378
|
return new Response(html, {
|
|
76303
76379
|
headers: {
|
|
76304
76380
|
"Content-Type": "text/html; charset=utf-8",
|
|
76305
76381
|
"Cache-Control": "no-store",
|
|
76306
76382
|
"Referrer-Policy": "no-referrer",
|
|
76307
76383
|
"X-Content-Type-Options": "nosniff",
|
|
76308
|
-
"Content-Security-Policy":
|
|
76384
|
+
"Content-Security-Policy": approvalCsp(req, brand)
|
|
76309
76385
|
}
|
|
76310
76386
|
});
|
|
76311
76387
|
}
|
|
@@ -76332,7 +76408,7 @@ async function resolveDeviceApprovalIdentity(req, env2) {
|
|
|
76332
76408
|
if (!payload || !payload.platform_user_id || !payload.role || !payload.jti || !projectOk) {
|
|
76333
76409
|
return outcome(env2, false, "signin_failed", {
|
|
76334
76410
|
title: "Sign in failed",
|
|
76335
|
-
body: "This sign-in link is invalid or has expired. Start again from your
|
|
76411
|
+
body: "This sign-in link is invalid or has expired. Start again from your device."
|
|
76336
76412
|
});
|
|
76337
76413
|
}
|
|
76338
76414
|
const platformProfile = {
|
|
@@ -76347,6 +76423,8 @@ async function resolveDeviceApprovalIdentity(req, env2) {
|
|
|
76347
76423
|
return {
|
|
76348
76424
|
confirmationSubject: `platform:${payload.platform_user_id}`,
|
|
76349
76425
|
handoff,
|
|
76426
|
+
displayName: payload.display_name?.trim() || payload.username?.trim() || payload.email?.trim() || "Your account",
|
|
76427
|
+
displayEmail: payload.email?.trim() || null,
|
|
76350
76428
|
platformProfile,
|
|
76351
76429
|
platformHandoff: {
|
|
76352
76430
|
jti: payload.jti,
|
|
@@ -76378,6 +76456,8 @@ async function resolveDeviceApprovalIdentity(req, env2) {
|
|
|
76378
76456
|
return {
|
|
76379
76457
|
confirmationSubject: `user:${authResult.user.id}`,
|
|
76380
76458
|
handoff: null,
|
|
76459
|
+
displayName: authResult.user.display_name?.trim() || authResult.user.username?.trim() || authResult.user.email?.trim() || "Your account",
|
|
76460
|
+
displayEmail: authResult.user.email?.trim() || null,
|
|
76381
76461
|
localUserId: authResult.user.id
|
|
76382
76462
|
};
|
|
76383
76463
|
}
|
|
@@ -76427,16 +76507,9 @@ async function verifyDeviceConfirmationToken(env2, code, confirmationSubject, to
|
|
|
76427
76507
|
return false;
|
|
76428
76508
|
}
|
|
76429
76509
|
}
|
|
76430
|
-
function isSameOriginApprovalPost(req) {
|
|
76431
|
-
const url = new URL(req.url);
|
|
76432
|
-
const origin = req.headers.get("Origin");
|
|
76433
|
-
if (origin && origin !== url.origin) return false;
|
|
76434
|
-
const fetchSite = req.headers.get("Sec-Fetch-Site");
|
|
76435
|
-
return !fetchSite || fetchSite === "same-origin" || fetchSite === "none";
|
|
76436
|
-
}
|
|
76437
76510
|
|
|
76438
76511
|
// src/api/auth/device/[code]/approve.get.ts
|
|
76439
|
-
var approve_get_default = defineController2(async ({ req, env: env2, params }) => {
|
|
76512
|
+
var approve_get_default = defineController2(async ({ req, env: env2, params, config }) => {
|
|
76440
76513
|
const code = params.code;
|
|
76441
76514
|
if (!code) {
|
|
76442
76515
|
return outcome(env2, false, "invalid_link", {
|
|
@@ -76457,7 +76530,8 @@ var approve_get_default = defineController2(async ({ req, env: env2, params }) =
|
|
|
76457
76530
|
body: "This instance cannot create a secure device confirmation. Contact its administrator."
|
|
76458
76531
|
});
|
|
76459
76532
|
}
|
|
76460
|
-
|
|
76533
|
+
const brand = await resolveDeviceApprovalBrand(env2, config);
|
|
76534
|
+
return confirmationPage(req, confirmationToken, identity.handoff, brand, identity);
|
|
76461
76535
|
});
|
|
76462
76536
|
|
|
76463
76537
|
// src/api/auth/device/[code]/approve.post.ts
|
|
@@ -76469,11 +76543,15 @@ var approve_post_default = defineController2(async ({ req, env: env2, params })
|
|
|
76469
76543
|
body: "This device link is malformed."
|
|
76470
76544
|
});
|
|
76471
76545
|
}
|
|
76472
|
-
if (!
|
|
76546
|
+
if (!isSameOriginBrowserRequest(req)) {
|
|
76473
76547
|
return Response.json({ error: "Cross-origin device approval refused" }, { status: 403 });
|
|
76474
76548
|
}
|
|
76475
76549
|
const form = await req.clone().formData().catch(() => null);
|
|
76476
76550
|
const confirmationToken = form?.get("confirmation_token")?.toString() ?? "";
|
|
76551
|
+
const decision = form?.get("decision")?.toString() || "approve";
|
|
76552
|
+
if (decision !== "approve" && decision !== "deny") {
|
|
76553
|
+
return Response.json({ error: "Invalid device confirmation decision" }, { status: 400 });
|
|
76554
|
+
}
|
|
76477
76555
|
if (!confirmationToken) {
|
|
76478
76556
|
return Response.json({ error: "Device confirmation token required" }, { status: 403 });
|
|
76479
76557
|
}
|
|
@@ -76490,31 +76568,45 @@ var approve_post_default = defineController2(async ({ req, env: env2, params })
|
|
|
76490
76568
|
if (!await consumeDeviceApprovalHandoff(env2, identity)) {
|
|
76491
76569
|
return outcome(env2, false, "signin_failed", {
|
|
76492
76570
|
title: "Sign in failed",
|
|
76493
|
-
body: "This sign-in link was already used or has expired. Start again from your
|
|
76571
|
+
body: "This sign-in link was already used or has expired. Start again from your device."
|
|
76494
76572
|
});
|
|
76495
76573
|
}
|
|
76496
|
-
const userId = await materializeDeviceApprovalUser(env2, identity);
|
|
76497
|
-
const token = generateApiKey();
|
|
76498
76574
|
const agentBuilderId = env2.AGENT_BUILDER.idFromName("singleton");
|
|
76499
76575
|
const agentBuilder = env2.AGENT_BUILDER.get(agentBuilderId);
|
|
76576
|
+
const codeHash = await hashToken(code);
|
|
76577
|
+
if (decision === "deny") {
|
|
76578
|
+
const denied = await agentBuilder.denyDeviceLogin(codeHash);
|
|
76579
|
+
if (!denied) {
|
|
76580
|
+
return outcome(env2, false, "expired", {
|
|
76581
|
+
title: "Link expired",
|
|
76582
|
+
body: "This device sign-in has expired or was already decided. Start again from your device."
|
|
76583
|
+
});
|
|
76584
|
+
}
|
|
76585
|
+
return outcome(env2, false, "denied", {
|
|
76586
|
+
title: "Connection denied",
|
|
76587
|
+
body: "The device was not connected. You can close this window."
|
|
76588
|
+
});
|
|
76589
|
+
}
|
|
76590
|
+
const userId = await materializeDeviceApprovalUser(env2, identity);
|
|
76591
|
+
const token = generateApiKey();
|
|
76500
76592
|
const ok = await agentBuilder.approveDeviceLogin({
|
|
76501
|
-
code_hash:
|
|
76593
|
+
code_hash: codeHash,
|
|
76502
76594
|
user_id: userId,
|
|
76503
76595
|
token,
|
|
76504
76596
|
token_hash: await hashToken(token),
|
|
76505
76597
|
key_prefix: token.slice(0, 12),
|
|
76506
76598
|
last_five: token.slice(-5),
|
|
76507
|
-
key_name: "
|
|
76599
|
+
key_name: "Device login"
|
|
76508
76600
|
});
|
|
76509
76601
|
if (!ok) {
|
|
76510
76602
|
return outcome(env2, false, "expired", {
|
|
76511
76603
|
title: "Link expired",
|
|
76512
|
-
body: "This device
|
|
76604
|
+
body: "This device sign-in has expired or was already decided. Start again from your device."
|
|
76513
76605
|
});
|
|
76514
76606
|
}
|
|
76515
76607
|
return outcome(env2, true, "done", {
|
|
76516
76608
|
title: "You're connected",
|
|
76517
|
-
body: "
|
|
76609
|
+
body: "The device is now connected. Return to the app that started this sign-in."
|
|
76518
76610
|
});
|
|
76519
76611
|
});
|
|
76520
76612
|
|