@standardagents/builder 0.41.6 → 0.41.7

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.
@@ -1267,15 +1267,6 @@ interface RouterThreadAccess {
1267
1267
  thread: Record<string, unknown>;
1268
1268
  }
1269
1269
 
1270
- /**
1271
- * Router and endpoint definition module for AgentBuilder.
1272
- *
1273
- * This module re-exports endpoint types from @standardagents/spec and provides
1274
- * the runtime router implementation for handling HTTP requests.
1275
- *
1276
- * @module
1277
- */
1278
-
1279
1270
  /**
1280
1271
  * Durable Object namespace interface.
1281
1272
  * This is Cloudflare-specific and used by the builder runtime.
@@ -1580,6 +1571,9 @@ interface DurableUserHubRpc {
1580
1571
  limit: number;
1581
1572
  offset: number;
1582
1573
  }>;
1574
+ setGrant(userId: string, grant: _standardagents_spec.CredentialGrant, secret: string): Promise<void>;
1575
+ deleteGrant(userId: string, name: string): Promise<void>;
1576
+ listGrants(userId: string): Promise<Array<_standardagents_spec.CredentialGrant>>;
1583
1577
  }
1584
1578
  /**
1585
1579
  * Thread registry entry from DurableAgentBuilder.
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { ModelDefinition, AgentDefinition } from './runtime.js';
2
2
  export { AgentBuilderEnv, AgentBuilderEvent, BroadcastOptions, CodeExecutionBridge, DurableAgentBuilder, DurableThread, DurableUserHub, FlowStateSdk, FlowStateWithSdk, HandlerSide, HubClientInfo, HumanSide, ImageContextConfig, InjectMessageOptions, LLMProviderInterface, NamespaceResolutionError, PromptContent, PromptDefinition, PromptIncludePart, PromptPart, PromptSide, PromptToolConfig, Provider, ProviderContentPart, ProviderFilePart, ProviderImagePart, ProviderRegistry, ProviderTextPart, SessionToolBinding, SessionToolConfig, SideConfig, SubagentRelationship, SubagentToolConfig, SubpromptConfig, ThreadEventPayload, ThreadRegistryEntry, ThreadWatchdog, ThreadWatchdogState, ToolConfig, UpdateThreadParams, User, WatchdogCheckin, WatchdogProbeResult, applyRuntimeCors, buildImageDescription, canAccessThread, cat, createNamespaceContext, emitThreadEvent, enhanceFlowState, exists, find, forceTurn, generateImageDescription, getFileStats, getMessages, getMessagesToSummarize, getShortName, getThumbnail, getUnsummarizedImageAttachments, getVisibleAgentNames, getVisibleModelNames, getVisiblePromptNames, getVisibleToolNames, grep, hasImageAttachments, head, injectMessage, isAdminOnlyApiRoute, isHostedInstance, isPublicApiRoute, isQualifiedName, isSameOriginBrowserRequest, isTrustedLocalDevelopmentRequest, linkFile, mkdir, move, optimizeImageContext, parseQualifiedName, qualifyName, queueTool, readFile, readdir, reloadHistory, rename, replaceImagesWithDescriptions, resolveAgent, resolveHook, resolveModel, resolvePrompt, resolveTool, rmdir, runtimeCorsHeaders, runtimePreflightResponse, stat, tail, unlink, updateThread, writeFile, writeImage } from './runtime.js';
3
3
  export { AgentPluginOptions, agentbuilder, builder } from './plugin.js';
4
- export { w as Agent, J as AttachmentRef, j as AuthContext, A as AuthUser, f as BuilderThreadEndpointHandler, C as CLIENT_STREAM_CHUNK_BYTES, u as ClientDuplex, v as ClientForwarding, q as ClientStreamRequest, t as ClientStreamResponse, o as ClientToolRequest, p as ClientToolResponse, B as Controller, a as ControllerContext, G as Env, H as FileRecord, N as FileStats, D as FlowResult, F as FlowState, K as GrepResult, P as ImageContentPart, I as ImageMetadata, L as LLMResponse, M as Message, U as MessageContent, Q as MultimodalContent, R as RequestContext, S as StorageBackend, E as TelemetryEvent, O as TextContentPart, b as ThreadEndpointContext, e as ThreadEnv, x as ThreadInstance, y as ThreadMetadata, T as ToolCall, z as ToolResult, g as authenticate, k as callClient, l as callClientStream, c as createThreadEndpointHandler, n as decodeStreamChunk, d as defineController, m as encodeStreamChunk, i as endpointCallerFromAuth, h as requireAdmin, r as requireAuth, s as supportsClientForwarding } from './index-By8TkPrK.js';
4
+ export { w as Agent, J as AttachmentRef, j as AuthContext, A as AuthUser, f as BuilderThreadEndpointHandler, C as CLIENT_STREAM_CHUNK_BYTES, u as ClientDuplex, v as ClientForwarding, q as ClientStreamRequest, t as ClientStreamResponse, o as ClientToolRequest, p as ClientToolResponse, B as Controller, a as ControllerContext, G as Env, H as FileRecord, N as FileStats, D as FlowResult, F as FlowState, K as GrepResult, P as ImageContentPart, I as ImageMetadata, L as LLMResponse, M as Message, U as MessageContent, Q as MultimodalContent, R as RequestContext, S as StorageBackend, E as TelemetryEvent, O as TextContentPart, b as ThreadEndpointContext, e as ThreadEnv, x as ThreadInstance, y as ThreadMetadata, T as ToolCall, z as ToolResult, g as authenticate, k as callClient, l as callClientStream, c as createThreadEndpointHandler, n as decodeStreamChunk, d as defineController, m as encodeStreamChunk, i as endpointCallerFromAuth, h as requireAdmin, r as requireAuth, s as supportsClientForwarding } from './index-PSu6cMEz.js';
5
5
  export { AgentType, DefineHandlerOptions, DefinitionLoader, GlobalNamespaceContext, HANDLER_SYMBOL, HandlerDefinition, HookExecutionContext, HookExecutionSource, HookSignatures, ImageContent, ModelCapabilities, ModelProvider, NamespaceContext, PackageSignature, PackedExports, PackedMeta, PackedMetadata, PackedNamespaceContext, ParentHookRequirement, ParentHookStage, PromptInput, PromptTextPart, ProviderAssistantMessage, ProviderConfigSlot, ProviderConfigSlots, ProviderConfigValueSource, ProviderDefinition, ProviderError, ProviderErrorCode, ProviderFactory, ProviderFactoryConfig, ProviderFinishReason, ProviderGeneratedImage, ProviderMessage, ProviderMessageContent, ProviderMethodOverrides, ModelCapabilities as ProviderModelCapabilities, ProviderOverride, ProviderOverrideContext, ProviderReasoningDetail, ProviderRequest, ProviderResponse, ProviderStreamChunk, ProviderSyncOverride, ProviderSystemMessage, ProviderTool, ProviderToolCallPart, ProviderToolMessage, ProviderToolResultContent, ProviderUsage, ProviderUserMessage, ReasoningConfig, StructuredPrompt, TextContent, ThreadHookName, Tool, ToolArgs, ToolArgsNode, ToolArgsRawShape, ToolContent, belongsToPackage, defineAgent, defineHandler, defineHook, defineModel, definePrompt, defineProvider, defineTool, isHandler, isPacked, isVisibleInNamespace, mapReasoningLevel, providerConst, providerEnv, providerValue } from '@standardagents/spec';
6
6
  export { C as ConstituentItem, D as DiscoveredPackage, N as NamespacedRegistry, P as PackingAnalysis, a as PackingOptions, b as PackingResult, c as UnpackOptions, d as UnpackResult } from './types-D1ABHvAH.js';
7
7
  export { D as DiscoveryConfig, P as PackageDiscoveryService, d as discoverPackages } from './discovery-CIGNVJfG.js';
package/dist/index.js CHANGED
@@ -39490,6 +39490,105 @@ function createExecutionChain() {
39490
39490
  }
39491
39491
 
39492
39492
  // src/users/grants.ts
39493
+ var INSTANCE_GRANTS_MAX_BYTES = 64 * 1024;
39494
+ var INSTANCE_GRANTS_MAX_COUNT = 64;
39495
+ var GRANT_NAME = /^[a-z0-9][a-z0-9._-]{0,127}$/;
39496
+ var HEADER_NAME = /^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/;
39497
+ var QUERY_NAME = /^[A-Za-z0-9._~-]{1,128}$/;
39498
+ var SUPPORTED_KINDS = /* @__PURE__ */ new Set(["bearer", "header", "query", "basic"]);
39499
+ var RECORD_KEYS = /* @__PURE__ */ new Set(["name", "kind", "origins", "inject", "allow", "metadata", "secret"]);
39500
+ var ALLOW_KEYS = /* @__PURE__ */ new Set(["tools", "endpoints", "userEndpoints", "agents"]);
39501
+ var INJECT_KEYS = /* @__PURE__ */ new Set(["header", "format", "query"]);
39502
+ function parseInstanceCredentialGrants(value) {
39503
+ const records = /* @__PURE__ */ new Map();
39504
+ if (typeof value !== "string" || value.length === 0 || value.length > INSTANCE_GRANTS_MAX_BYTES) {
39505
+ return records;
39506
+ }
39507
+ let parsed;
39508
+ try {
39509
+ parsed = JSON.parse(value);
39510
+ } catch {
39511
+ return records;
39512
+ }
39513
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return records;
39514
+ const envelope = parsed;
39515
+ if (envelope.version !== 1 || !Array.isArray(envelope.grants) || envelope.grants.length > INSTANCE_GRANTS_MAX_COUNT) {
39516
+ return records;
39517
+ }
39518
+ for (const candidate of envelope.grants) {
39519
+ const record = validateCredentialGrantRecord(candidate);
39520
+ if (!record || records.has(record.grant.name)) return /* @__PURE__ */ new Map();
39521
+ records.set(record.grant.name, record);
39522
+ }
39523
+ return records;
39524
+ }
39525
+ function validateCredentialGrantRecord(value, routeName) {
39526
+ if (!value || typeof value !== "object" || Array.isArray(value)) return null;
39527
+ const input = value;
39528
+ if (Object.keys(input).some((key) => !RECORD_KEYS.has(key))) return null;
39529
+ const name = input.name;
39530
+ if (typeof name !== "string" || !GRANT_NAME.test(name)) return null;
39531
+ if (input.name !== void 0 && input.name !== name) return null;
39532
+ if (typeof input.secret !== "string" || input.secret.length === 0 || input.secret.length > 16 * 1024) return null;
39533
+ if (typeof input.kind !== "string" || !SUPPORTED_KINDS.has(input.kind)) return null;
39534
+ if ((input.kind === "bearer" || input.kind === "header") && /[\r\n]/.test(input.secret)) return null;
39535
+ if (!Array.isArray(input.origins) || input.origins.length === 0 || input.origins.length > 64) return null;
39536
+ const origins = [];
39537
+ for (const origin of input.origins) {
39538
+ if (typeof origin !== "string" || origin.length > 512) return null;
39539
+ if (origin.startsWith("*.")) {
39540
+ if (!/^\*\.[a-z0-9.-]+$/i.test(origin)) return null;
39541
+ } else {
39542
+ try {
39543
+ const url = new URL(origin);
39544
+ if (url.origin !== origin || url.protocol !== "https:" || url.username || url.password) return null;
39545
+ } catch {
39546
+ return null;
39547
+ }
39548
+ }
39549
+ origins.push(origin);
39550
+ }
39551
+ if (!input.allow || typeof input.allow !== "object" || Array.isArray(input.allow)) return null;
39552
+ const allowInput = input.allow;
39553
+ if (Object.keys(allowInput).some((key) => !ALLOW_KEYS.has(key))) return null;
39554
+ const allow = {};
39555
+ for (const key of ["tools", "endpoints", "userEndpoints", "agents"]) {
39556
+ const list = allowInput[key];
39557
+ if (list === void 0) continue;
39558
+ if (!Array.isArray(list) || list.length > 128 || !list.every((item) => typeof item === "string" && item.length > 0 && item.length <= 256)) {
39559
+ return null;
39560
+ }
39561
+ allow[key] = [...list];
39562
+ }
39563
+ if (Object.keys(allow).length === 0) return null;
39564
+ const inject = input.inject;
39565
+ if (inject !== void 0 && (!inject || typeof inject !== "object" || Array.isArray(inject))) return null;
39566
+ if (inject !== void 0) {
39567
+ const injection = inject;
39568
+ if (Object.keys(injection).some((key) => !INJECT_KEYS.has(key))) return null;
39569
+ if (injection.header !== void 0 && (typeof injection.header !== "string" || !HEADER_NAME.test(injection.header))) return null;
39570
+ if (injection.format !== void 0 && (typeof injection.format !== "string" || injection.format.length > 1024 || /[\r\n]/.test(injection.format))) return null;
39571
+ if (injection.query !== void 0 && (typeof injection.query !== "string" || !QUERY_NAME.test(injection.query))) return null;
39572
+ }
39573
+ const metadata = input.metadata;
39574
+ if (metadata !== void 0 && (!metadata || typeof metadata !== "object" || Array.isArray(metadata))) return null;
39575
+ if (metadata !== void 0) {
39576
+ try {
39577
+ if (JSON.stringify(metadata).length > 16 * 1024) return null;
39578
+ } catch {
39579
+ return null;
39580
+ }
39581
+ }
39582
+ const grant = {
39583
+ name,
39584
+ kind: input.kind,
39585
+ origins,
39586
+ allow,
39587
+ ...inject === void 0 ? {} : { inject },
39588
+ ...metadata === void 0 ? {} : { metadata }
39589
+ };
39590
+ return { grant, secret: input.secret };
39591
+ }
39493
39592
  function originAllowed(origins, target) {
39494
39593
  if (!Array.isArray(origins)) return false;
39495
39594
  for (const allowed of origins) {
@@ -39835,14 +39934,20 @@ var DurableUserHub = class extends DurableObject {
39835
39934
  `SELECT name, config FROM user_grants WHERE user_id = ? ORDER BY name ASC`,
39836
39935
  userId
39837
39936
  );
39838
- return cursor.toArray().map((row) => {
39937
+ const grants = /* @__PURE__ */ new Map();
39938
+ for (const record of parseInstanceCredentialGrants(this.env.AGENT_BUILDER_CREDENTIAL_GRANTS).values()) {
39939
+ const { name, ...config } = record.grant;
39940
+ grants.set(name, { name, ...config });
39941
+ }
39942
+ for (const row of cursor.toArray()) {
39839
39943
  let config = {};
39840
39944
  try {
39841
39945
  config = JSON.parse(row.config);
39842
39946
  } catch {
39843
39947
  }
39844
- return { name: row.name, ...config };
39845
- });
39948
+ grants.set(row.name, { name: row.name, ...config });
39949
+ }
39950
+ return [...grants.values()].sort((a, b) => a.name.localeCompare(b.name));
39846
39951
  }
39847
39952
  /** Perform a privileged fetch with the grant's credential injected. */
39848
39953
  async grantFetch(userId, grantName, req) {
@@ -39852,15 +39957,24 @@ var DurableUserHub = class extends DurableObject {
39852
39957
  userId,
39853
39958
  grantName
39854
39959
  );
39855
- const row = cursor.toArray()[0];
39856
- if (!row) {
39960
+ const stored = cursor.toArray()[0];
39961
+ const instance = stored ? null : parseInstanceCredentialGrants(this.env.AGENT_BUILDER_CREDENTIAL_GRANTS).get(grantName) ?? null;
39962
+ if (!stored && !instance) {
39857
39963
  return Response.json({ error: "grant_not_found", grant: grantName }, { status: 404 });
39858
39964
  }
39859
39965
  let config;
39860
- try {
39861
- config = JSON.parse(row.config);
39862
- } catch {
39863
- return Response.json({ error: "grant_config_invalid" }, { status: 500 });
39966
+ let secret;
39967
+ if (stored) {
39968
+ try {
39969
+ config = JSON.parse(stored.config);
39970
+ } catch {
39971
+ return Response.json({ error: "grant_config_invalid" }, { status: 500 });
39972
+ }
39973
+ secret = stored.secret;
39974
+ } else {
39975
+ const { name: _name, ...instanceConfig } = instance.grant;
39976
+ config = instanceConfig;
39977
+ secret = instance.secret;
39864
39978
  }
39865
39979
  let target;
39866
39980
  try {
@@ -39875,7 +39989,7 @@ var DurableUserHub = class extends DurableObject {
39875
39989
  return Response.json({ error: "grant_caller_denied" }, { status: 403 });
39876
39990
  }
39877
39991
  const headers = new Headers(req.headers);
39878
- if (!injectGrantCredential(config, row.secret, target, headers)) {
39992
+ if (!injectGrantCredential(config, secret, target, headers)) {
39879
39993
  return Response.json({ error: "grant_kind_unsupported" }, { status: 501 });
39880
39994
  }
39881
39995
  try {