agents 0.11.2 → 0.11.4

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/index.js CHANGED
@@ -2,9 +2,9 @@ import { MessageType } from "./types.js";
2
2
  import { camelCaseToKebabCase } from "./utils.js";
3
3
  import { createHeaderBasedEmailResolver, signAgentHeaders } from "./email.js";
4
4
  import { __DO_NOT_USE_WILL_BREAK__agentContext } from "./internal_context.js";
5
- import { i as _classPrivateFieldInitSpec, n as _classPrivateFieldSet2, t as _classPrivateFieldGet2 } from "./classPrivateFieldGet2-BVdP0e3Z.js";
5
+ import { i as _classPrivateFieldInitSpec, n as _classPrivateFieldSet2, t as _classPrivateFieldGet2 } from "./classPrivateFieldGet2-DAZNVUKb.js";
6
6
  import { isErrorRetryable, tryN, validateRetryOptions } from "./retries.js";
7
- import { o as RPC_DO_PREFIX, r as MCPConnectionState, s as DisposableStore, t as MCPClientManager } from "./client-PEDsNnfY.js";
7
+ import { o as RPC_DO_PREFIX, r as MCPConnectionState, s as DisposableStore, t as MCPClientManager } from "./client-B_xdiZbn.js";
8
8
  import { DurableObjectOAuthClientProvider } from "./mcp/do-oauth-client-provider.js";
9
9
  import { genericObservability } from "./observability/index.js";
10
10
  import { AsyncLocalStorage } from "node:async_hooks";
@@ -19,13 +19,13 @@ let _Symbol$dispose;
19
19
  * Type guard for RPC request messages
20
20
  */
21
21
  function isRPCRequest(msg) {
22
- return typeof msg === "object" && msg !== null && "type" in msg && msg.type === MessageType.RPC && "id" in msg && typeof msg.id === "string" && "method" in msg && typeof msg.method === "string" && "args" in msg && Array.isArray(msg.args);
22
+ return typeof msg === "object" && msg !== null && "type" in msg && msg.type === "rpc" && "id" in msg && typeof msg.id === "string" && "method" in msg && typeof msg.method === "string" && "args" in msg && Array.isArray(msg.args);
23
23
  }
24
24
  /**
25
25
  * Type guard for state update messages
26
26
  */
27
27
  function isStateUpdateMessage(msg) {
28
- return typeof msg === "object" && msg !== null && "type" in msg && msg.type === MessageType.CF_AGENT_STATE && "state" in msg;
28
+ return typeof msg === "object" && msg !== null && "type" in msg && msg.type === "cf_agent_state" && "state" in msg;
29
29
  }
30
30
  const callableMetadata = /* @__PURE__ */ new WeakMap();
31
31
  /**
@@ -535,7 +535,7 @@ var Agent = class Agent extends Server {
535
535
  if (isStateUpdateMessage(parsed)) {
536
536
  if (this.isConnectionReadonly(connection)) {
537
537
  connection.send(JSON.stringify({
538
- type: MessageType.CF_AGENT_STATE_ERROR,
538
+ type: "cf_agent_state_error",
539
539
  error: "Connection is readonly"
540
540
  }));
541
541
  return;
@@ -545,7 +545,7 @@ var Agent = class Agent extends Server {
545
545
  } catch (e) {
546
546
  console.error("[Agent] State update rejected:", e);
547
547
  connection.send(JSON.stringify({
548
- type: MessageType.CF_AGENT_STATE_ERROR,
548
+ type: "cf_agent_state_error",
549
549
  error: "State update rejected"
550
550
  }));
551
551
  }
@@ -586,7 +586,7 @@ var Agent = class Agent extends Server {
586
586
  id,
587
587
  result,
588
588
  success: true,
589
- type: MessageType.RPC
589
+ type: "rpc"
590
590
  };
591
591
  connection.send(JSON.stringify(response));
592
592
  } catch (e) {
@@ -594,7 +594,7 @@ var Agent = class Agent extends Server {
594
594
  error: e instanceof Error ? e.message : "Unknown error occurred",
595
595
  id: parsed.id,
596
596
  success: false,
597
- type: MessageType.RPC
597
+ type: "rpc"
598
598
  };
599
599
  connection.send(JSON.stringify(response));
600
600
  console.error("RPC error:", e);
@@ -630,16 +630,16 @@ var Agent = class Agent extends Server {
630
630
  connection.send(JSON.stringify({
631
631
  name: this.name,
632
632
  agent: camelCaseToKebabCase(this._ParentClass.name),
633
- type: MessageType.CF_AGENT_IDENTITY
633
+ type: "cf_agent_identity"
634
634
  }));
635
635
  }
636
636
  if (this.state) connection.send(JSON.stringify({
637
637
  state: this.state,
638
- type: MessageType.CF_AGENT_STATE
638
+ type: "cf_agent_state"
639
639
  }));
640
640
  connection.send(JSON.stringify({
641
641
  mcp: this.getMcpServers(),
642
- type: MessageType.CF_AGENT_MCP_SERVERS
642
+ type: "cf_agent_mcp_servers"
643
643
  }));
644
644
  } else this._setConnectionNoProtocol(connection);
645
645
  this._emit("connect", { connectionId: connection.id });
@@ -718,10 +718,23 @@ var Agent = class Agent extends Server {
718
718
  * @param excludeIds Additional connection IDs to exclude (e.g. the source)
719
719
  */
720
720
  _broadcastProtocol(msg, excludeIds = []) {
721
+ if (this._isFacet) return;
721
722
  const exclude = [...excludeIds];
722
723
  for (const conn of this.getConnections()) if (!this.isConnectionProtocolEnabled(conn)) exclude.push(conn.id);
723
724
  this.broadcast(msg, exclude);
724
725
  }
726
+ /**
727
+ * When running as a facet, the parent DO owns the WebSocket registry
728
+ * (`ctx.getWebSockets()`). Iterating from the child isolate throws
729
+ * "Cannot perform I/O on behalf of a different Durable Object".
730
+ * Downstream callers (e.g. chat-streaming paths) invoke
731
+ * `this.broadcast()` directly, bypassing `_broadcastProtocol`'s
732
+ * guard, so override at the base to catch every path.
733
+ */
734
+ broadcast(msg, without) {
735
+ if (this._isFacet) return;
736
+ super.broadcast(msg, without);
737
+ }
725
738
  _setStateInternal(nextState, source = "server") {
726
739
  this.validateStateChange(nextState, source);
727
740
  this._state = nextState;
@@ -731,7 +744,7 @@ var Agent = class Agent extends Server {
731
744
  `;
732
745
  this._broadcastProtocol(JSON.stringify({
733
746
  state: nextState,
734
- type: MessageType.CF_AGENT_STATE
747
+ type: "cf_agent_state"
735
748
  }), source !== "server" ? [source.id] : []);
736
749
  const { connection, request, email } = __DO_NOT_USE_WILL_BREAK__agentContext.getStore() || {};
737
750
  this.ctx.waitUntil((async () => {
@@ -1801,7 +1814,7 @@ var Agent = class Agent extends Server {
1801
1814
  if (this._runFiberRecoveryInProgress) return;
1802
1815
  this._runFiberRecoveryInProgress = true;
1803
1816
  try {
1804
- const rows = this.sql`SELECT id, name, snapshot FROM cf_agents_runs`;
1817
+ const rows = this.sql`SELECT id, name, snapshot, created_at FROM cf_agents_runs`;
1805
1818
  for (const row of rows) {
1806
1819
  if (this._runFiberActiveFibers.has(row.id)) continue;
1807
1820
  let snapshot = null;
@@ -1813,7 +1826,8 @@ var Agent = class Agent extends Server {
1813
1826
  const ctx = {
1814
1827
  id: row.id,
1815
1828
  name: row.name,
1816
- snapshot
1829
+ snapshot,
1830
+ createdAt: row.created_at
1817
1831
  };
1818
1832
  try {
1819
1833
  if (!await this._handleInternalFiberRecovery(ctx)) await this.onFiberRecovered(ctx);
@@ -1987,14 +2001,26 @@ var Agent = class Agent extends Server {
1987
2001
  await this._scheduleNextAlarm();
1988
2002
  }
1989
2003
  /**
1990
- * Marks this agent as running inside a facet (sub-agent). Once set,
1991
- * scheduling methods throw a clear error instead of crashing on
1992
- * `setAlarm()` (which is not supported in facets).
1993
- * @internal
2004
+ * Initialize this agent as a facet in a single RPC.
2005
+ *
2006
+ * Runs entirely inside the child's isolate, so every storage write
2007
+ * and `onStart()` I/O is owned by the child DO. This replaces the
2008
+ * previous "construct a Request in the parent DO and `stub.fetch()`
2009
+ * it on the child" handshake, whose native I/O was tied to the
2010
+ * parent and triggered "Cannot perform I/O on behalf of a different
2011
+ * Durable Object" on the child.
2012
+ *
2013
+ * Order matters: set `_isFacet` BEFORE triggering initialization, so
2014
+ * the first `onStart()` run (which calls `broadcastMcpServers`) sees
2015
+ * the flag and skips broadcasts that would touch the parent DO's
2016
+ * WebSocket registry.
2017
+ *
2018
+ * @internal Called by {@link subAgent}.
1994
2019
  */
1995
- async _cf_markAsFacet() {
2020
+ async _cf_initAsFacet(name) {
1996
2021
  this._isFacet = true;
1997
- await this.ctx.storage.put("cf_agents_is_facet", true);
2022
+ await Promise.all([this.ctx.storage.put("cf_agents_is_facet", true), this.ctx.storage.put("__ps_name", name)]);
2023
+ await this.__unsafe_ensureInitialized();
1998
2024
  }
1999
2025
  /**
2000
2026
  * Get or create a named sub-agent — a child Durable Object (facet)
@@ -2004,7 +2030,7 @@ var Agent = class Agent extends Server {
2004
2030
  * entry point. The first call for a given name triggers the child's
2005
2031
  * `onStart()`. Subsequent calls return the existing instance.
2006
2032
  *
2007
- * @experimental Requires the `"experimental"` compatibility flag.
2033
+ * @experimental The API surface may change before stabilizing.
2008
2034
  *
2009
2035
  * @param cls The Agent subclass (must be exported from the worker)
2010
2036
  * @param name Unique name for this child instance
@@ -2018,14 +2044,11 @@ var Agent = class Agent extends Server {
2018
2044
  */
2019
2045
  async subAgent(cls, name) {
2020
2046
  const ctx = this.ctx;
2021
- if (!ctx.facets || !ctx.exports) throw new Error("subAgent() requires the \"experimental\" compatibility flag. Add it to your wrangler.jsonc compatibility_flags.");
2047
+ if (!ctx.facets || !ctx.exports) throw new Error("subAgent() is not supported in this runtime — `ctx.facets` / `ctx.exports` are unavailable. Update to the latest `compatibility_date` in your wrangler.jsonc.");
2022
2048
  if (!ctx.exports[cls.name]) throw new Error(`Sub-agent class "${cls.name}" not found in worker exports. Make sure the class is exported from your worker entry point and that the export name matches the class name.`);
2023
2049
  const facetKey = `${cls.name}\0${name}`;
2024
2050
  const stub = ctx.facets.get(facetKey, () => ({ class: ctx.exports[cls.name] }));
2025
- const req = new Request("http://dummy-example.cloudflare.com/cdn-cgi/partyserver/set-name/");
2026
- req.headers.set("x-partykit-room", name);
2027
- await stub.fetch(req).then((res) => res.text());
2028
- await stub._cf_markAsFacet();
2051
+ await stub._cf_initAsFacet(name);
2029
2052
  return stub;
2030
2053
  }
2031
2054
  /**
@@ -2034,7 +2057,7 @@ var Agent = class Agent extends Server {
2034
2057
  * Pending RPC calls receive the reason as an error.
2035
2058
  * Transitively aborts the child's own children.
2036
2059
  *
2037
- * @experimental Requires the `"experimental"` compatibility flag.
2060
+ * @experimental The API surface may change before stabilizing.
2038
2061
  *
2039
2062
  * @param cls The Agent subclass used when creating the child
2040
2063
  * @param name Name of the child to abort
@@ -2042,7 +2065,7 @@ var Agent = class Agent extends Server {
2042
2065
  */
2043
2066
  abortSubAgent(cls, name, reason) {
2044
2067
  const ctx = this.ctx;
2045
- if (!ctx.facets) throw new Error("abortSubAgent() requires the \"experimental\" compatibility flag.");
2068
+ if (!ctx.facets) throw new Error("abortSubAgent() is not supported in this runtime — `ctx.facets` is unavailable. Update to the latest `compatibility_date` in your wrangler.jsonc.");
2046
2069
  const facetKey = `${cls.name}\0${name}`;
2047
2070
  ctx.facets.abort(facetKey, reason);
2048
2071
  }
@@ -2050,14 +2073,14 @@ var Agent = class Agent extends Server {
2050
2073
  * Delete a sub-agent: abort it if running, then permanently wipe its
2051
2074
  * storage. Transitively deletes the child's own children.
2052
2075
  *
2053
- * @experimental Requires the `"experimental"` compatibility flag.
2076
+ * @experimental The API surface may change before stabilizing.
2054
2077
  *
2055
2078
  * @param cls The Agent subclass used when creating the child
2056
2079
  * @param name Name of the child to delete
2057
2080
  */
2058
2081
  deleteSubAgent(cls, name) {
2059
2082
  const ctx = this.ctx;
2060
- if (!ctx.facets) throw new Error("deleteSubAgent() requires the \"experimental\" compatibility flag.");
2083
+ if (!ctx.facets) throw new Error("deleteSubAgent() is not supported in this runtime — `ctx.facets` is unavailable. Update to the latest `compatibility_date` in your wrangler.jsonc.");
2061
2084
  const facetKey = `${cls.name}\0${name}`;
2062
2085
  ctx.facets.delete(facetKey);
2063
2086
  }
@@ -3011,7 +3034,7 @@ var Agent = class Agent extends Server {
3011
3034
  broadcastMcpServers() {
3012
3035
  this._broadcastProtocol(JSON.stringify({
3013
3036
  mcp: this.getMcpServers(),
3014
- type: MessageType.CF_AGENT_MCP_SERVERS
3037
+ type: "cf_agent_mcp_servers"
3015
3038
  }));
3016
3039
  }
3017
3040
  /**
@@ -3202,7 +3225,7 @@ var StreamingResponse = class {
3202
3225
  id: this._id,
3203
3226
  result: chunk,
3204
3227
  success: true,
3205
- type: MessageType.RPC
3228
+ type: "rpc"
3206
3229
  };
3207
3230
  this._connection.send(JSON.stringify(response));
3208
3231
  return true;
@@ -3220,7 +3243,7 @@ var StreamingResponse = class {
3220
3243
  id: this._id,
3221
3244
  result: finalChunk,
3222
3245
  success: true,
3223
- type: MessageType.RPC
3246
+ type: "rpc"
3224
3247
  };
3225
3248
  this._connection.send(JSON.stringify(response));
3226
3249
  return true;
@@ -3237,7 +3260,7 @@ var StreamingResponse = class {
3237
3260
  error: message,
3238
3261
  id: this._id,
3239
3262
  success: false,
3240
- type: MessageType.RPC
3263
+ type: "rpc"
3241
3264
  };
3242
3265
  this._connection.send(JSON.stringify(response));
3243
3266
  return true;