@standardagents/builder 0.27.6 → 0.27.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.
package/dist/runtime.d.ts CHANGED
@@ -3605,6 +3605,28 @@ declare class ProviderRegistryImpl {
3605
3605
  private providerOverrideFn;
3606
3606
  private providerOverrideRevision;
3607
3607
  setProviderOverride(fn: ProviderOverrideFn | null): void;
3608
+ /**
3609
+ * The env a provider resolves against for a given execution, scoped to the
3610
+ * THREAD rather than just the instance: thread env overrides win, then the
3611
+ * thread OWNER's user env, then instance/Worker env. This is what makes
3612
+ * per-user BYOK providers work — a credential a user installs in their own
3613
+ * account env (e.g. an OAuth token a companion service rotates) is honored
3614
+ * for that user's threads no matter which authorized actor plays the turn.
3615
+ *
3616
+ * Best-effort by design: a missing user id (super-admin/local threads) or
3617
+ * an older AgentBuilder DO without user-env storage simply contributes
3618
+ * nothing, leaving instance-env behavior untouched.
3619
+ */
3620
+ buildThreadScopedEnv(state: {
3621
+ env: Env;
3622
+ thread: {
3623
+ metadata?: {
3624
+ user_id?: string | null;
3625
+ env?: Record<string, unknown> | null;
3626
+ tenvs?: Record<string, unknown> | null;
3627
+ };
3628
+ };
3629
+ }): Promise<Env>;
3608
3630
  /**
3609
3631
  * Get provider for a model.
3610
3632
  *
package/dist/runtime.js CHANGED
@@ -890,6 +890,42 @@ var init_ProviderRegistry = __esm({
890
890
  this.providerOverrideFn = fn;
891
891
  this.providerOverrideRevision += 1;
892
892
  }
893
+ /**
894
+ * The env a provider resolves against for a given execution, scoped to the
895
+ * THREAD rather than just the instance: thread env overrides win, then the
896
+ * thread OWNER's user env, then instance/Worker env. This is what makes
897
+ * per-user BYOK providers work — a credential a user installs in their own
898
+ * account env (e.g. an OAuth token a companion service rotates) is honored
899
+ * for that user's threads no matter which authorized actor plays the turn.
900
+ *
901
+ * Best-effort by design: a missing user id (super-admin/local threads) or
902
+ * an older AgentBuilder DO without user-env storage simply contributes
903
+ * nothing, leaving instance-env behavior untouched.
904
+ */
905
+ async buildThreadScopedEnv(state) {
906
+ const threadEnv = state.thread.metadata?.env ?? state.thread.metadata?.tenvs ?? null;
907
+ const userId = state.thread.metadata?.user_id ?? null;
908
+ let userEnv = null;
909
+ if (userId) {
910
+ try {
911
+ const agentBuilderId = state.env.AGENT_BUILDER.idFromName("singleton");
912
+ const agentBuilder = state.env.AGENT_BUILDER.get(agentBuilderId);
913
+ if (typeof agentBuilder.getUserEnvEntries === "function") {
914
+ const entries = await agentBuilder.getUserEnvEntries(userId);
915
+ if (Array.isArray(entries) && entries.length > 0) {
916
+ userEnv = {};
917
+ for (const entry of entries) {
918
+ if (entry?.name) userEnv[entry.name] = entry.value;
919
+ }
920
+ }
921
+ }
922
+ } catch (error) {
923
+ console.warn("buildThreadScopedEnv: user env unavailable:", error instanceof Error ? error.message : String(error));
924
+ }
925
+ }
926
+ if (!userEnv && !threadEnv) return state.env;
927
+ return { ...state.env, ...userEnv ?? {}, ...threadEnv ?? {} };
928
+ }
893
929
  /**
894
930
  * Get provider for a model.
895
931
  *
@@ -1801,7 +1837,8 @@ var init_LLMRequest = __esm({
1801
1837
  */
1802
1838
  static async callModel(modelId, context, state, logId) {
1803
1839
  const { ProviderRegistry: ProviderRegistry2 } = await Promise.resolve().then(() => (init_providers(), providers_exports));
1804
- const { provider, modelName, modelDef, viaPlatform, platformProxyOrigin } = await ProviderRegistry2.getProvider(modelId, state.env, state.thread.instance);
1840
+ const providerEnv = await ProviderRegistry2.buildThreadScopedEnv(state);
1841
+ const { provider, modelName, modelDef, viaPlatform, platformProxyOrigin } = await ProviderRegistry2.getProvider(modelId, providerEnv, state.thread.instance);
1805
1842
  const streamAbort = new AbortController();
1806
1843
  const parentSignal = state.abortController?.signal;
1807
1844
  let onParentAbort;