@standardagents/builder 0.40.0 → 0.40.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.
@@ -1590,6 +1590,7 @@ interface DurableAgentBuilderRpc {
1590
1590
  status: string;
1591
1591
  token?: string;
1592
1592
  } | null>;
1593
+ denyDeviceLogin(codeHash: string): Promise<boolean>;
1593
1594
  approveDeviceLogin(params: {
1594
1595
  code_hash: string;
1595
1596
  user_id: string;
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, HubClientInfo, ImageContextConfig, InjectMessageOptions, LLMProviderInterface, NamespaceResolutionError, PromptContent, PromptDefinition, PromptIncludePart, PromptPart, PromptToolConfig, Provider, ProviderContentPart, ProviderFilePart, ProviderImagePart, ProviderRegistry, ProviderTextPart, SessionToolBinding, SessionToolConfig, SideConfig, 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-9MaIifn3.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-0NI3m5DR.js';
5
5
  export { AgentType, DefinitionLoader, GlobalNamespaceContext, 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, defineHook, defineModel, definePrompt, defineProvider, defineTool, 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-BMnBYNwn.js';
7
7
  export { D as DiscoveryConfig, P as PackageDiscoveryService, d as discoverPackages } from './discovery-DZ7fv-b4.js';
package/dist/index.js CHANGED
@@ -11701,7 +11701,12 @@ function queueTool(flow, toolName, args = {}) {
11701
11701
  }
11702
11702
  async function injectMessage(flow, options) {
11703
11703
  const messageId = options.id ?? crypto.randomUUID();
11704
- const timestamp = Date.now() * TIMESTAMP_MULTIPLIER;
11704
+ const wallClockTimestamp = Date.now() * TIMESTAMP_MULTIPLIER;
11705
+ const latestLiveTimestamp = flow.messageHistory.reduce(
11706
+ (latest, entry) => Math.max(latest, entry.created_at),
11707
+ 0
11708
+ );
11709
+ const timestamp = options.beforeMessageId ? wallClockTimestamp : Math.max(wallClockTimestamp, latestLiveTimestamp + 1);
11705
11710
  const silent = options.silent ?? false;
11706
11711
  const forceTopLevel = options.forceTopLevel ?? false;
11707
11712
  let message = {
@@ -23823,7 +23828,8 @@ async function loadVirtualModule(id, context) {
23823
23828
  effectsDir,
23824
23829
  installedProviders,
23825
23830
  rou3Code,
23826
- hmr
23831
+ hmr,
23832
+ deviceApproval
23827
23833
  } = context;
23828
23834
  if (id === RESOLVED_VIRTUAL_TOOLS_ID) {
23829
23835
  const tools = await scanToolsDirectory(toolsDir);
@@ -23887,6 +23893,7 @@ export const config = {
23887
23893
  providersDir: "${relativeProvidersDir}",
23888
23894
  promptsDir: "${relativePromptsDir}",
23889
23895
  agentsDir: "${relativeAgentsDir}",
23896
+ deviceApproval: ${JSON.stringify(deviceApproval ?? null)},
23890
23897
  };`;
23891
23898
  }
23892
23899
  if (id === RESOLVED_VIRTUAL_MODELS_ID) {
@@ -24246,8 +24253,50 @@ function applyPluginEnvironmentConfig(config) {
24246
24253
  }
24247
24254
  }
24248
24255
 
24256
+ // src/plugin/device-approval.ts
24257
+ function requiredText(value, field, maxLength) {
24258
+ if (typeof value !== "string" || !value.trim() || value.trim().length > maxLength) {
24259
+ throw new Error(`deviceApproval.${field} must be a non-empty string of ${maxLength} characters or fewer`);
24260
+ }
24261
+ return value.trim();
24262
+ }
24263
+ function optionalText(value, field, maxLength) {
24264
+ if (value === void 0 || value === null || value === "") return void 0;
24265
+ if (typeof value !== "string" || !value.trim() || value.trim().length > maxLength) {
24266
+ throw new Error(`deviceApproval.${field} must be a string of ${maxLength} characters or fewer`);
24267
+ }
24268
+ return value.trim();
24269
+ }
24270
+ function safeLogoUrl(value) {
24271
+ const logoUrl = optionalText(value, "logoUrl", 2048);
24272
+ if (!logoUrl) return void 0;
24273
+ if (logoUrl.startsWith("/") && !logoUrl.startsWith("//") && !logoUrl.includes("#") && !logoUrl.includes("\\")) {
24274
+ return logoUrl;
24275
+ }
24276
+ try {
24277
+ const parsed = new URL(logoUrl);
24278
+ if (parsed.protocol !== "https:" || parsed.username || parsed.password || parsed.hash) throw new Error();
24279
+ return parsed.toString();
24280
+ } catch {
24281
+ throw new Error("deviceApproval.logoUrl must be a safe HTTPS or root-relative URL");
24282
+ }
24283
+ }
24284
+ function normalizeDeviceApprovalBrand(value) {
24285
+ if (value === void 0) return void 0;
24286
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
24287
+ throw new Error("deviceApproval must be an object");
24288
+ }
24289
+ const normalized = { name: requiredText(value.name, "name", 100) };
24290
+ const description = optionalText(value.description, "description", 280);
24291
+ const logoUrl = safeLogoUrl(value.logoUrl);
24292
+ if (description) normalized.description = description;
24293
+ if (logoUrl) normalized.logoUrl = logoUrl;
24294
+ return normalized;
24295
+ }
24296
+
24249
24297
  // src/plugin.ts
24250
24298
  function agentbuilder(options = {}) {
24299
+ const deviceApproval = normalizeDeviceApprovalBrand(options.deviceApproval);
24251
24300
  const toolsDir = options.toolsDir ? path9__default.resolve(process.cwd(), options.toolsDir) : path9__default.resolve(process.cwd(), "agents/tools");
24252
24301
  const hooksDir = options.hooksDir ? path9__default.resolve(process.cwd(), options.hooksDir) : path9__default.resolve(process.cwd(), "agents/hooks");
24253
24302
  const threadApiDir = options.apiDir ? path9__default.resolve(process.cwd(), options.apiDir) : path9__default.resolve(process.cwd(), "agents/api");
@@ -24338,7 +24387,8 @@ export { CodeExecutionBridge, DurableAgentBuilder, DurableThread, ThreadWatchdog
24338
24387
  effectsDir,
24339
24388
  installedProviders,
24340
24389
  rou3Code,
24341
- hmr
24390
+ hmr,
24391
+ deviceApproval
24342
24392
  };
24343
24393
  const devMiddlewareContext = {
24344
24394
  toolsDir,
@@ -30595,6 +30645,17 @@ ${result ?? error ?? "No result content."}${attachmentSummary}`;
30595
30645
  }
30596
30646
  return { status: row.status };
30597
30647
  }
30648
+ /** Deny a pending device login without creating a user or API key. */
30649
+ async denyDeviceLogin(codeHash) {
30650
+ await this.ensureMigrated();
30651
+ await this.sweepDeviceLogins();
30652
+ const cursor = await this.ctx.storage.sql.exec(
30653
+ `UPDATE device_logins SET status = 'denied', user_id = NULL, token = NULL
30654
+ WHERE code_hash = ? AND status = 'pending'`,
30655
+ codeHash
30656
+ );
30657
+ return cursor.rowsWritten > 0;
30658
+ }
30598
30659
  /** Approve a pending device login: mint a personal API key for the user and
30599
30660
  * park its plaintext for the single claim. Returns false when the code is
30600
30661
  * unknown, expired, or not pending. */