@standardagents/builder 0.27.6 → 0.27.8-dev.b0d0355

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.
@@ -909,12 +909,64 @@ var init_ProviderRegistry = __esm({
909
909
  init_factory();
910
910
  ProviderRegistryImpl = class {
911
911
  providerCache = /* @__PURE__ */ new Map();
912
+ /** Why the last thread-scoped resolution did (not) contribute user env,
913
+ * keyed by the env object handed back — surfaced in missing-variable
914
+ * errors so a silent user-env failure is diagnosable from the log. */
915
+ scopeDiagnostics = /* @__PURE__ */ new WeakMap();
912
916
  providerOverrideFn = null;
913
917
  providerOverrideRevision = 0;
914
918
  setProviderOverride(fn) {
915
919
  this.providerOverrideFn = fn;
916
920
  this.providerOverrideRevision += 1;
917
921
  }
922
+ /**
923
+ * The env a provider resolves against for a given execution, scoped to the
924
+ * THREAD rather than just the instance: thread env overrides win, then the
925
+ * thread OWNER's user env, then instance/Worker env. This is what makes
926
+ * per-user BYOK providers work — a credential a user installs in their own
927
+ * account env (e.g. an OAuth token a companion service rotates) is honored
928
+ * for that user's threads no matter which authorized actor plays the turn.
929
+ *
930
+ * Best-effort by design: a missing user id (super-admin/local threads) or
931
+ * an older AgentBuilder DO without user-env storage simply contributes
932
+ * nothing, leaving instance-env behavior untouched.
933
+ */
934
+ async buildThreadScopedEnv(state) {
935
+ const threadEnv = state.thread.metadata?.env ?? state.thread.metadata?.tenvs ?? null;
936
+ const userId = state.thread.metadata?.user_id ?? null;
937
+ let userEnv = null;
938
+ let diagnostic = userId ? "" : "no thread user_id";
939
+ if (userId) {
940
+ try {
941
+ const agentBuilderId = state.env.AGENT_BUILDER.idFromName("singleton");
942
+ const agentBuilder = state.env.AGENT_BUILDER.get(agentBuilderId);
943
+ if (typeof agentBuilder.getUserEnvEntries === "function") {
944
+ const entries = await agentBuilder.getUserEnvEntries(userId);
945
+ if (Array.isArray(entries) && entries.length > 0) {
946
+ userEnv = {};
947
+ for (const entry of entries) {
948
+ if (entry?.name) userEnv[entry.name] = entry.value;
949
+ }
950
+ diagnostic = `user env: ${Object.keys(userEnv).length} entries`;
951
+ } else {
952
+ diagnostic = `user env empty for ${userId} (entries: ${Array.isArray(entries) ? entries.length : typeof entries})`;
953
+ }
954
+ } else {
955
+ diagnostic = "singleton has no getUserEnvEntries";
956
+ }
957
+ } catch (error) {
958
+ diagnostic = `user env lookup failed: ${error instanceof Error ? error.message : String(error)}`;
959
+ console.warn("buildThreadScopedEnv:", diagnostic);
960
+ }
961
+ }
962
+ if (!userEnv && !threadEnv) {
963
+ this.scopeDiagnostics.set(state.env, diagnostic);
964
+ return state.env;
965
+ }
966
+ const merged = { ...state.env, ...userEnv ?? {}, ...threadEnv ?? {} };
967
+ this.scopeDiagnostics.set(merged, diagnostic);
968
+ return merged;
969
+ }
918
970
  /**
919
971
  * Get provider for a model.
920
972
  *
@@ -952,8 +1004,9 @@ var init_ProviderRegistry = __esm({
952
1004
  if (providerDefinition) {
953
1005
  const resolved = resolveDefinedProviderConfig(providerDefinition, env2);
954
1006
  if (resolved.missing.length > 0) {
1007
+ const scopeNote = this.scopeDiagnostics.get(env2);
955
1008
  throw new Error(
956
- `Missing required environment variables for provider '${providerName}': ${resolved.missing.join(", ")}.`
1009
+ `Missing required environment variables for provider '${providerName}': ${resolved.missing.join(", ")}.` + (scopeNote ? ` [thread-scoped env: ${scopeNote}]` : "")
957
1010
  );
958
1011
  }
959
1012
  const config = resolved.providerConfig;
@@ -1826,7 +1879,8 @@ var init_LLMRequest = __esm({
1826
1879
  */
1827
1880
  static async callModel(modelId, context, state, logId) {
1828
1881
  const { ProviderRegistry: ProviderRegistry2 } = await Promise.resolve().then(() => (init_providers(), providers_exports));
1829
- const { provider, modelName, modelDef, viaPlatform, platformProxyOrigin } = await ProviderRegistry2.getProvider(modelId, state.env, state.thread.instance);
1882
+ const providerEnv = await ProviderRegistry2.buildThreadScopedEnv(state);
1883
+ const { provider, modelName, modelDef, viaPlatform, platformProxyOrigin } = await ProviderRegistry2.getProvider(modelId, providerEnv, state.thread.instance);
1830
1884
  const streamAbort = new AbortController();
1831
1885
  const parentSignal = state.abortController?.signal;
1832
1886
  let onParentAbort;
@@ -66192,7 +66246,7 @@ var config_get_default = defineController2(async ({ config, env: env2, req }) =>
66192
66246
  });
66193
66247
 
66194
66248
  // src/version.ts
66195
- var BUILDER_VERSION = "0.27.6".length > 0 ? "0.27.6" : "dev";
66249
+ var BUILDER_VERSION = "0.27.8-dev.b0d0355".length > 0 ? "0.27.8-dev.b0d0355" : "dev";
66196
66250
 
66197
66251
  // src/api/diagnostics.get.ts
66198
66252
  init_LLMRequest();