@standardagents/builder 0.17.2 → 0.18.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/dist/built-in-routes.js +527 -266
- package/dist/built-in-routes.js.map +1 -1
- package/dist/client/ApiKeysView.js +1 -1
- package/dist/client/CenteredContentView.js +1 -1
- package/dist/client/CompositionView.js +1 -1
- package/dist/client/ConfirmDialog.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/client/CopyButton.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/client/DataTable.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/client/JsonViewer.js +1 -1
- package/dist/client/LoginView.js +1 -1
- package/dist/client/MarketplaceView.js +1 -1
- package/dist/client/Modal.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/client/ModelModal.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/client/ModelsView.js +1 -1
- package/dist/client/PromptEditView.js +1 -1
- package/dist/client/PromptModal.js +1 -1
- package/dist/client/PromptsView.js +1 -1
- package/dist/client/ProvidersView.js +2 -2
- package/dist/client/ThreadInspectorPane.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/client/ToolsView.js +1 -1
- package/dist/client/UsersView.js +1 -1
- package/dist/client/VariablesView.js +1 -1
- package/dist/client/assets/index.css +1 -1
- package/dist/client/index.js +4 -4
- package/dist/index.js +500 -52
- package/dist/index.js.map +1 -1
- package/dist/plugin.js +92 -7
- package/dist/plugin.js.map +1 -1
- package/dist/runtime.d.ts +72 -4
- package/dist/runtime.js +408 -45
- package/dist/runtime.js.map +1 -1
- package/package.json +4 -4
package/dist/plugin.js
CHANGED
|
@@ -7205,8 +7205,10 @@ import { isThreadEndpoint } from "@standardagents/spec";
|
|
|
7205
7205
|
const PUBLIC_ROUTES = [
|
|
7206
7206
|
'/api/auth/bootstrap',
|
|
7207
7207
|
'/api/auth/login',
|
|
7208
|
-
'/api/auth/bootstrap',
|
|
7209
7208
|
'/api/auth/config',
|
|
7209
|
+
'/api/auth/platform-replica',
|
|
7210
|
+
'/api/auth/sa/start', // Login with Standard Agents (OAuth) \u2014 unauthenticated entry
|
|
7211
|
+
'/api/auth/sa/callback', // OAuth callback (sets the session cookie)
|
|
7210
7212
|
'/api/config',
|
|
7211
7213
|
'/api/auth/oauth/github',
|
|
7212
7214
|
'/api/auth/oauth/google',
|
|
@@ -7219,15 +7221,31 @@ const PUBLIC_ROUTES = [
|
|
|
7219
7221
|
'/api/hooks' // Hook metadata is safe to expose publicly
|
|
7220
7222
|
];
|
|
7221
7223
|
|
|
7224
|
+
// True when the platform deployed this instance (injects STANDARD_AGENTS_HOSTED).
|
|
7225
|
+
// Hosted instances are internet-reachable and multi-tenant, so the thread data
|
|
7226
|
+
// API and event/stream WebSockets must NOT be anonymously public the way they
|
|
7227
|
+
// are in single-user local dev \u2014 they require a session (admin) or API key (SDK).
|
|
7228
|
+
function isHostedInstance(env) {
|
|
7229
|
+
const value = env && env.STANDARD_AGENTS_HOSTED;
|
|
7230
|
+
if (typeof value === 'string') {
|
|
7231
|
+
const trimmed = value.trim().toLowerCase();
|
|
7232
|
+
return trimmed !== '' && trimmed !== '0' && trimmed !== 'false';
|
|
7233
|
+
}
|
|
7234
|
+
return Boolean(value);
|
|
7235
|
+
}
|
|
7236
|
+
|
|
7222
7237
|
// Check if a route is public (no auth required)
|
|
7223
|
-
function isPublicRoute(routePath) {
|
|
7238
|
+
function isPublicRoute(routePath, hosted) {
|
|
7224
7239
|
// Exact match for auth routes
|
|
7225
7240
|
if (PUBLIC_ROUTES.includes(routePath)) {
|
|
7226
7241
|
return true;
|
|
7227
7242
|
}
|
|
7228
7243
|
|
|
7229
|
-
// Thread routes are
|
|
7230
|
-
|
|
7244
|
+
// Thread routes (REST + message/log stream WebSockets) are public in local
|
|
7245
|
+
// single-user dev, but on a hosted deployment they require auth \u2014 requireAuth
|
|
7246
|
+
// accepts the admin's session (cookie or token) or the SDK's API key, so this
|
|
7247
|
+
// only blocks anonymous access to another tenant's threads/messages/files.
|
|
7248
|
+
if (!hosted && (routePath.startsWith('/api/threads/') || routePath === '/api/threads')) {
|
|
7231
7249
|
return true;
|
|
7232
7250
|
}
|
|
7233
7251
|
|
|
@@ -7236,16 +7254,25 @@ function isPublicRoute(routePath) {
|
|
|
7236
7254
|
return true;
|
|
7237
7255
|
}
|
|
7238
7256
|
|
|
7239
|
-
// Platform proxy routes handle their own auth.
|
|
7257
|
+
// Platform proxy routes handle their own auth in local dev only.
|
|
7258
|
+
if (hosted && (routePath.startsWith('/api/platform/') || routePath === '/api/platform')) {
|
|
7259
|
+
return false;
|
|
7260
|
+
}
|
|
7240
7261
|
if (routePath.startsWith('/api/platform/') || routePath === '/api/platform') {
|
|
7241
7262
|
return true;
|
|
7242
7263
|
}
|
|
7243
7264
|
|
|
7244
|
-
// Platform session proxy and auth bridge
|
|
7265
|
+
// Platform session proxy and auth bridge are local-dev helpers only.
|
|
7266
|
+
if (hosted && (routePath.startsWith('/api/platform-session/') || routePath === '/api/platform-session')) {
|
|
7267
|
+
return false;
|
|
7268
|
+
}
|
|
7245
7269
|
if (routePath.startsWith('/api/platform-session/') || routePath === '/api/platform-session') {
|
|
7246
7270
|
return true;
|
|
7247
7271
|
}
|
|
7248
7272
|
|
|
7273
|
+
if (hosted && (routePath.startsWith('/api/platform-auth/') || routePath === '/api/platform-auth')) {
|
|
7274
|
+
return false;
|
|
7275
|
+
}
|
|
7249
7276
|
if (routePath.startsWith('/api/platform-auth/') || routePath === '/api/platform-auth') {
|
|
7250
7277
|
return true;
|
|
7251
7278
|
}
|
|
@@ -7253,6 +7280,36 @@ function isPublicRoute(routePath) {
|
|
|
7253
7280
|
return false;
|
|
7254
7281
|
}
|
|
7255
7282
|
|
|
7283
|
+
function platformEndpoint(env) {
|
|
7284
|
+
const configured =
|
|
7285
|
+
env && (env.PLATFORM_ENDPOINT || env.STANDARD_AGENTS_PLATFORM_URL || env.PLATFORM_URL || env.STANDARD_AGENTS_PUBLIC_URL);
|
|
7286
|
+
if (typeof configured === 'string' && configured.trim()) {
|
|
7287
|
+
return configured.trim().replace(/\\/+$/, '');
|
|
7288
|
+
}
|
|
7289
|
+
return 'https://platform.standardagents.ai';
|
|
7290
|
+
}
|
|
7291
|
+
|
|
7292
|
+
function hostedInstanceRedirectId(request, env) {
|
|
7293
|
+
const configured = env && (env.STANDARD_AGENTS_PROJECT_ID || env.STANDARD_AGENTS_INSTANCE_ID || env.STANDARD_AGENTS_INSTANCE_SUBDOMAIN);
|
|
7294
|
+
if (typeof configured === 'string' && configured.trim()) {
|
|
7295
|
+
return configured.trim();
|
|
7296
|
+
}
|
|
7297
|
+
return new URL(request.url).hostname;
|
|
7298
|
+
}
|
|
7299
|
+
|
|
7300
|
+
function platformLoginUrl(request, env) {
|
|
7301
|
+
const requestUrl = new URL(request.url);
|
|
7302
|
+
const url = new URL('/login', platformEndpoint(env));
|
|
7303
|
+
url.searchParams.set('redirect', hostedInstanceRedirectId(request, env));
|
|
7304
|
+
url.searchParams.set('return_to', requestUrl.pathname + requestUrl.search || '/');
|
|
7305
|
+
return url.toString();
|
|
7306
|
+
}
|
|
7307
|
+
|
|
7308
|
+
function isHtmlNavigationRequest(request) {
|
|
7309
|
+
if (request.method !== 'GET' && request.method !== 'HEAD') return false;
|
|
7310
|
+
return (request.headers.get('Accept') || '').includes('text/html');
|
|
7311
|
+
}
|
|
7312
|
+
|
|
7256
7313
|
// CORS headers for API responses
|
|
7257
7314
|
const CORS_HEADERS = {
|
|
7258
7315
|
"Access-Control-Allow-Origin": "*",
|
|
@@ -7329,7 +7386,7 @@ ${packedThreadRouteCode}
|
|
|
7329
7386
|
|
|
7330
7387
|
if (routeMatch) {
|
|
7331
7388
|
// Check if authentication is required for this route
|
|
7332
|
-
const publicRoute = isPublicRoute(routePath);
|
|
7389
|
+
const publicRoute = isPublicRoute(routePath, isHostedInstance(env));
|
|
7333
7390
|
const isApiRoute = routePath.startsWith('/api/');
|
|
7334
7391
|
|
|
7335
7392
|
let authContext = null;
|
|
@@ -7344,6 +7401,21 @@ ${packedThreadRouteCode}
|
|
|
7344
7401
|
}
|
|
7345
7402
|
|
|
7346
7403
|
authContext = authResult;
|
|
7404
|
+
|
|
7405
|
+
if (routePath.startsWith('/api/threads/')) {
|
|
7406
|
+
const threadId = routeMatch.params?.id || routeMatch.params?.threadId;
|
|
7407
|
+
if (threadId) {
|
|
7408
|
+
const agentBuilderId = env.AGENT_BUILDER.idFromName('singleton');
|
|
7409
|
+
const agentBuilder = env.AGENT_BUILDER.get(agentBuilderId);
|
|
7410
|
+
const thread = await agentBuilder.getThread(threadId);
|
|
7411
|
+
if (!thread) {
|
|
7412
|
+
return addCorsHeaders(Response.json({ error: \`Thread not found: \${threadId}\` }, { status: 404 }));
|
|
7413
|
+
}
|
|
7414
|
+
if (authContext.user.role !== 'admin' && (thread.user_id === null || thread.user_id !== authContext.user.id)) {
|
|
7415
|
+
return addCorsHeaders(Response.json({ error: "Forbidden: You don't have access to this thread" }, { status: 403 }));
|
|
7416
|
+
}
|
|
7417
|
+
}
|
|
7418
|
+
}
|
|
7347
7419
|
}
|
|
7348
7420
|
|
|
7349
7421
|
let controller = await routeMatch.data();
|
|
@@ -7379,6 +7451,19 @@ ${packedThreadRouteCode}
|
|
|
7379
7451
|
});
|
|
7380
7452
|
}
|
|
7381
7453
|
|
|
7454
|
+
// Hosted browser navigations do not render a local login page. Redirect
|
|
7455
|
+
// anonymous users directly to the platform, where the instance membership is
|
|
7456
|
+
// resolved and returned as a signed handoff token.
|
|
7457
|
+
if (isHostedInstance(env) && isHtmlNavigationRequest(request)) {
|
|
7458
|
+
const authResult = await requireAuth(request, env);
|
|
7459
|
+
if (authResult instanceof Response) {
|
|
7460
|
+
return new Response(null, {
|
|
7461
|
+
status: 302,
|
|
7462
|
+
headers: { Location: platformLoginUrl(request, env) },
|
|
7463
|
+
});
|
|
7464
|
+
}
|
|
7465
|
+
}
|
|
7466
|
+
|
|
7382
7467
|
// Serve UI for all other routes (SPA fallback)
|
|
7383
7468
|
return serveUI(routePath, env);
|
|
7384
7469
|
}
|