@standardagents/builder 0.29.1 → 0.30.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.
@@ -13126,7 +13126,10 @@ var init_ThreadStateImpl = __esm({
13126
13126
  data: { deferred: true, toolCallId }
13127
13127
  };
13128
13128
  }
13129
- const local = await this._threadInstance.callClientTool(request);
13129
+ const local = await this._threadInstance.callClientTool(
13130
+ request,
13131
+ canPark && toolCallId ? { toolCallId, side } : void 0
13132
+ );
13130
13133
  if (local.ok || !this.isNoClient(local)) return local;
13131
13134
  const env2 = this._threadInstance.env;
13132
13135
  if (env2?.AGENT_BUILDER_THREAD) {
@@ -13676,10 +13679,35 @@ var init_ThreadStateImpl = __esm({
13676
13679
  return { parentThreadId, parentStub };
13677
13680
  }
13678
13681
  _getAgentBuilderStub() {
13679
- const env2 = this._threadInstance.env;
13682
+ const env2 = this._getRuntimeEnv();
13680
13683
  const agentBuilderId = env2.AGENT_BUILDER.idFromName("singleton");
13681
13684
  return env2.AGENT_BUILDER.get(agentBuilderId);
13682
13685
  }
13686
+ /**
13687
+ * Environment bindings for this state. In-DO construction uses the thread
13688
+ * instance's own env; stub-backed states (thread endpoints, the user
13689
+ * scope's `thread()`) have no `instance.env` over RPC and use the env the
13690
+ * dispatcher recorded in the runtime context instead.
13691
+ */
13692
+ _getRuntimeEnv() {
13693
+ const instanceEnv = this._threadInstance.env;
13694
+ const env2 = instanceEnv?.AGENT_BUILDER ? instanceEnv : this._runtimeContext.env;
13695
+ if (!env2?.AGENT_BUILDER) {
13696
+ throw new Error(
13697
+ "No runtime environment available on this ThreadState. Stub-backed states must be constructed with runtimeContext.env."
13698
+ );
13699
+ }
13700
+ return env2;
13701
+ }
13702
+ /** The per-user hub stub for this thread's user (user-scope surfaces). */
13703
+ _getUserHubStub(userId) {
13704
+ const env2 = this._getRuntimeEnv();
13705
+ const namespace = env2.AGENT_BUILDER_USER_HUB;
13706
+ if (!namespace) {
13707
+ throw new Error("User scope unavailable: AGENT_BUILDER_USER_HUB binding is missing.");
13708
+ }
13709
+ return namespace.get(namespace.idFromName(userId));
13710
+ }
13683
13711
  // ─────────────────────────────────────────────────────────────────────────
13684
13712
  // Skills — instance-global Agent Skills library, backed by the
13685
13713
  // DurableAgentBuilder singleton (skills are never stored per-thread or on
@@ -13696,7 +13724,67 @@ var init_ThreadStateImpl = __esm({
13696
13724
  const stub = this._getAgentBuilderStub();
13697
13725
  const user = await stub.getUserById(userId).catch(() => null);
13698
13726
  if (!user) return null;
13727
+ const inUserScope = this._runtimeContext.inUserScope === true;
13728
+ const agentId = this._metadata.agent_id;
13729
+ const hub = () => this._getUserHubStub(userId);
13730
+ const capabilities = {
13731
+ call: async (endpoint, payload) => {
13732
+ if (inUserScope) {
13733
+ throw new Error(
13734
+ "Reentrant user-scope call: this ThreadState was raised from user-scope code; state.user().call() is unavailable here."
13735
+ );
13736
+ }
13737
+ const path9 = endpoint.replace(/^\/+/, "");
13738
+ return hub().fetch(
13739
+ new Request(`https://user-hub/users/${encodeURIComponent(userId)}/endpoints/${path9}`, {
13740
+ method: "POST",
13741
+ headers: {
13742
+ "Content-Type": "application/json",
13743
+ // Runtime-internal caller channel — the public routes overwrite
13744
+ // this header, so only thread-scope code can present "thread".
13745
+ "X-Standard-Agents-Caller": "thread"
13746
+ },
13747
+ body: payload === void 0 ? void 0 : JSON.stringify(payload)
13748
+ })
13749
+ );
13750
+ },
13751
+ getValue: async (key) => {
13752
+ return await stub.getUserValue?.(userId, key);
13753
+ },
13754
+ setValue: async (key, value) => {
13755
+ await stub.setUserValue?.(userId, key, value);
13756
+ },
13757
+ emit: (event, data) => {
13758
+ const delivery = hub().broadcastUserEvent(userId, event, data).catch(() => {
13759
+ });
13760
+ this._pendingEventDeliveries.add(delivery);
13761
+ void delivery.finally(
13762
+ () => this._pendingEventDeliveries.delete(delivery)
13763
+ );
13764
+ },
13765
+ fetch: async (grant, input, init) => {
13766
+ const body = init?.body;
13767
+ if (body !== void 0 && body !== null && typeof body !== "string") {
13768
+ throw new Error("Grant fetch bodies must be strings in this runtime.");
13769
+ }
13770
+ return hub().fetch(
13771
+ new Request(`https://user-hub/users/${encodeURIComponent(userId)}/grant-fetch`, {
13772
+ method: "POST",
13773
+ headers: { "Content-Type": "application/json" },
13774
+ body: JSON.stringify({
13775
+ grant,
13776
+ url: String(input),
13777
+ method: init?.method ?? "GET",
13778
+ headers: init?.headers ? Object.fromEntries(new Headers(init.headers)) : {},
13779
+ body: body ?? null,
13780
+ caller: { kind: "agent", name: agentId }
13781
+ })
13782
+ })
13783
+ );
13784
+ }
13785
+ };
13699
13786
  return {
13787
+ ...capabilities,
13700
13788
  id: user.id,
13701
13789
  username: user.username,
13702
13790
  role: user.role,
@@ -66558,7 +66646,7 @@ var config_get_default = defineController2(async ({ config, env: env2, req }) =>
66558
66646
  });
66559
66647
 
66560
66648
  // src/version.ts
66561
- var BUILDER_VERSION = "0.29.1".length > 0 ? "0.29.1" : "dev";
66649
+ var BUILDER_VERSION = "0.30.0".length > 0 ? "0.30.0" : "dev";
66562
66650
 
66563
66651
  // src/api/diagnostics.get.ts
66564
66652
  init_LLMRequest();
@@ -72109,6 +72197,48 @@ var analyze_get_default2 = defineController2(async ({ req }) => {
72109
72197
  }
72110
72198
  });
72111
72199
 
72200
+ // src/users/dispatch.ts
72201
+ function userHubStub(env2, userId) {
72202
+ const namespace = env2.AGENT_BUILDER_USER_HUB;
72203
+ if (!namespace) return null;
72204
+ return namespace.get(namespace.idFromName(userId));
72205
+ }
72206
+ async function forwardToUserScope(req, env2, userId, scopePath, channel = "user") {
72207
+ const stub = userHubStub(env2, userId);
72208
+ if (!stub) {
72209
+ return Response.json(
72210
+ { error: "The user scope is not available on this runtime" },
72211
+ { status: 500 }
72212
+ );
72213
+ }
72214
+ const source = new URL(req.url);
72215
+ const target = new URL(
72216
+ `https://user-hub/users/${encodeURIComponent(userId)}/${scopePath}`
72217
+ );
72218
+ target.search = source.search;
72219
+ const forwarded = new Request(target.toString(), req);
72220
+ forwarded.headers.set("X-Standard-Agents-Caller", channel);
72221
+ return stub.fetch(forwarded);
72222
+ }
72223
+
72224
+ // src/api/users/[id]/[...rest].ts
72225
+ var rest_default = defineController2(async ({ req, env: env2, params }) => {
72226
+ const authResult = await requireAuth(req, env2);
72227
+ if (authResult instanceof Response) return authResult;
72228
+ const isAdmin = authResult.authType === "super_admin" || authResult.user?.role === "admin";
72229
+ if (!isAdmin) {
72230
+ return Response.json({ error: "Administrator access required" }, { status: 403 });
72231
+ }
72232
+ const rest = params._ ?? params.rest ?? params["*"] ?? "";
72233
+ return forwardToUserScope(
72234
+ req,
72235
+ env2,
72236
+ params.id,
72237
+ `endpoints/${rest}`,
72238
+ "admin"
72239
+ );
72240
+ });
72241
+
72112
72242
  // src/api/users/[id]/env.get.ts
72113
72243
  var env_get_default = defineController2(async ({ req, env: env2, params }) => {
72114
72244
  try {
@@ -72180,6 +72310,23 @@ var env_patch_default = defineController2(async ({ req, env: env2, params }) =>
72180
72310
  }
72181
72311
  });
72182
72312
 
72313
+ // src/api/users/[id]/stream.ts
72314
+ var stream_default2 = defineController2(async ({ req, env: env2, params }) => {
72315
+ const authResult = await requireAuth(req, env2);
72316
+ if (authResult instanceof Response) return authResult;
72317
+ const isAdmin = authResult.authType === "super_admin" || authResult.user?.role === "admin";
72318
+ if (!isAdmin) {
72319
+ return Response.json({ error: "Administrator access required" }, { status: 403 });
72320
+ }
72321
+ if (req.headers.get("upgrade")?.toLowerCase() !== "websocket") {
72322
+ return Response.json(
72323
+ { error: "This endpoint only supports WebSocket connections" },
72324
+ { status: 426 }
72325
+ );
72326
+ }
72327
+ return forwardToUserScope(req, env2, params.id, "stream", "admin");
72328
+ });
72329
+
72183
72330
  // src/api/variables/agents/[name].get.ts
72184
72331
  var name_get_default6 = defineController2(async ({ params, url, prompts, agents, tools, models, env: env2, req }) => {
72185
72332
  const agentName = params.name ? decodeURIComponent(params.name) : "";
@@ -72400,6 +72547,25 @@ var start_get_default = defineController2(async ({ req, env: env2 }) => {
72400
72547
  });
72401
72548
  });
72402
72549
 
72550
+ // src/api/users/me/[...rest].ts
72551
+ var rest_default2 = defineController2(async ({ req, env: env2, params }) => {
72552
+ const authResult = await requireAuth(req, env2);
72553
+ if (authResult instanceof Response) return authResult;
72554
+ if (authResult.authType === "super_admin") {
72555
+ return Response.json(
72556
+ { error: "Super admin sessions have no user scope. Sign in as a user account." },
72557
+ { status: 400 }
72558
+ );
72559
+ }
72560
+ const rest = params._ ?? params.rest ?? params["*"] ?? "";
72561
+ return forwardToUserScope(
72562
+ req,
72563
+ env2,
72564
+ authResult.user.id,
72565
+ `endpoints/${rest}`
72566
+ );
72567
+ });
72568
+
72403
72569
  // src/api/users/me/env.get.ts
72404
72570
  var env_get_default2 = defineController2(async ({ req, env: env2 }) => {
72405
72571
  try {
@@ -72638,6 +72804,25 @@ var index_post_default8 = defineController2(async ({ req, env: env2 }) => {
72638
72804
  }
72639
72805
  });
72640
72806
 
72807
+ // src/api/users/me/stream.ts
72808
+ var stream_default3 = defineController2(async ({ req, env: env2 }) => {
72809
+ const authResult = await requireAuth(req, env2);
72810
+ if (authResult instanceof Response) return authResult;
72811
+ if (authResult.authType === "super_admin") {
72812
+ return Response.json(
72813
+ { error: "Super admin sessions have no user scope. Sign in as a user account." },
72814
+ { status: 400 }
72815
+ );
72816
+ }
72817
+ if (req.headers.get("upgrade")?.toLowerCase() !== "websocket") {
72818
+ return Response.json(
72819
+ { error: "This endpoint only supports WebSocket connections" },
72820
+ { status: 426 }
72821
+ );
72822
+ }
72823
+ return forwardToUserScope(req, env2, authResult.user.id, "stream");
72824
+ });
72825
+
72641
72826
  // src/api/auth/device/[code]/approve.get.ts
72642
72827
  function page(title, body, ok) {
72643
72828
  return new Response(
@@ -73853,20 +74038,24 @@ var routeHandlers = {
73853
74038
  "GET:/threads/:id/subagents": subagents_get_default,
73854
74039
  "POST:/threads/:id/tool-result": tool_result_post_default,
73855
74040
  "GET:/unpack/:packageId/analyze": analyze_get_default2,
74041
+ "GET:/users/:id/**": rest_default,
73856
74042
  "GET:/users/:id/env": env_get_default,
73857
74043
  "PATCH:/users/:id/env": env_patch_default,
74044
+ "GET:/users/:id/stream": stream_default2,
73858
74045
  "GET:/variables/agents/:name": name_get_default6,
73859
74046
  "GET:/variables/prompts/:name": name_get_default7,
73860
74047
  "GET:/variables/tools/:name": name_get_default8,
73861
74048
  "POST:/auth/device/start": start_post_default,
73862
74049
  "GET:/auth/sa/callback": callback_get_default,
73863
74050
  "GET:/auth/sa/start": start_get_default,
74051
+ "GET:/users/me/**": rest_default2,
73864
74052
  "GET:/users/me/env": env_get_default2,
73865
74053
  "PATCH:/users/me/env": env_patch_default2,
73866
74054
  "GET:/users/me/hub": hub_default,
73867
74055
  "DELETE:/users/me/kv": index_delete_default,
73868
74056
  "GET:/users/me/kv": index_get_default4,
73869
74057
  "POST:/users/me/kv": index_post_default8,
74058
+ "GET:/users/me/stream": stream_default3,
73870
74059
  "GET:/auth/device/:code/approve": approve_get_default,
73871
74060
  "GET:/skills/:name/files/**": path_get_default,
73872
74061
  "DELETE:/threads/:id/fs/**": path_default3,