agents 0.4.0 → 0.5.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.
package/dist/index.d.ts CHANGED
@@ -1,9 +1,13 @@
1
- import { AgentEmail } from "./internal_context.js";
1
+ import {
2
+ AgentEmail,
3
+ __DO_NOT_USE_WILL_BREAK__agentContext
4
+ } from "./internal_context.js";
2
5
  import { EmailResolver, createHeaderBasedEmailResolver } from "./email.js";
6
+ import { RetryOptions } from "./retries.js";
3
7
  import {
4
8
  l as TransportType,
5
9
  r as MCPConnectionState
6
- } from "./client-storage-Cvy5r9FG.js";
10
+ } from "./client-storage-D633wI1S.js";
7
11
  import {
8
12
  AgentMcpOAuthProvider,
9
13
  AgentsOAuthProvider
@@ -116,6 +120,7 @@ type QueueItem<T = string> = {
116
120
  payload: T;
117
121
  callback: keyof Agent<Cloudflare.Env>;
118
122
  created_at: number;
123
+ retry?: RetryOptions;
119
124
  };
120
125
  /**
121
126
  * Represents a scheduled task within an Agent
@@ -124,7 +129,8 @@ type QueueItem<T = string> = {
124
129
  type Schedule<T = string> = {
125
130
  /** Unique identifier for the schedule */ id: string /** Name of the method to be called */;
126
131
  callback: string /** Data to be passed to the callback */;
127
- payload: T;
132
+ payload: T /** Retry options for callback execution */;
133
+ retry?: RetryOptions;
128
134
  } & (
129
135
  | {
130
136
  /** Type of schedule for one-time execution at a specific time */ type: "scheduled" /** Timestamp when the task should execute */;
@@ -194,7 +200,8 @@ type AddMcpServerOptions = {
194
200
  transport?: {
195
201
  /** Custom headers for authentication (e.g., bearer tokens, CF Access) */ headers?: HeadersInit /** Transport type: "sse", "streamable-http", or "auto" (default) */;
196
202
  type?: TransportType;
197
- };
203
+ } /** Retry options for connection and reconnection attempts */;
204
+ retry?: RetryOptions;
198
205
  };
199
206
  /**
200
207
  * Default options for Agent configuration.
@@ -208,16 +215,26 @@ declare const DEFAULT_AGENT_STATIC_OPTIONS: {
208
215
  * and force-reset. Increase this if you have callbacks that legitimately
209
216
  * take longer than 30 seconds.
210
217
  */
211
- hungScheduleTimeoutSeconds: number;
218
+ hungScheduleTimeoutSeconds: number /** Default retry options for schedule(), queue(), and this.retry() */;
219
+ retry: {
220
+ maxAttempts: number;
221
+ baseDelayMs: number;
222
+ maxDelayMs: number;
223
+ };
212
224
  };
213
- type ResolvedAgentOptions = typeof DEFAULT_AGENT_STATIC_OPTIONS;
214
225
  /**
215
226
  * Configuration options for the Agent.
216
227
  * Override in subclasses via `static options`.
217
228
  * All fields are optional - defaults are applied at runtime.
218
229
  * Note: `hibernate` defaults to `true` if not specified.
219
230
  */
220
- type AgentStaticOptions = Partial<ResolvedAgentOptions>;
231
+ interface AgentStaticOptions {
232
+ hibernate?: boolean;
233
+ sendIdentityOnConnect?: boolean;
234
+ hungScheduleTimeoutSeconds?: number;
235
+ /** Default retry options for schedule(), queue(), and this.retry(). */
236
+ retry?: RetryOptions;
237
+ }
221
238
  declare function getCurrentAgent<
222
239
  T extends Agent<Cloudflare.Env> = Agent<Cloudflare.Env>
223
240
  >(): {
@@ -254,8 +271,8 @@ declare class Agent<
254
271
  private _destroyed;
255
272
  /**
256
273
  * Stores raw state accessors for wrapped connections.
257
- * Used by setConnectionReadonly/isConnectionReadonly to read/write the
258
- * _cf_readonly flag without going through the user-facing state/setState.
274
+ * Used by internal flag methods (readonly, no-protocol) to read/write
275
+ * _cf_-prefixed keys without going through the user-facing state/setState.
259
276
  */
260
277
  private _rawStateAccessors;
261
278
  /**
@@ -286,8 +303,11 @@ declare class Agent<
286
303
  */
287
304
  static options: AgentStaticOptions;
288
305
  /**
289
- * Resolved options (merges defaults with subclass overrides)
306
+ * Resolved options (merges defaults with subclass overrides).
307
+ * Cached after first access — static options never change during the
308
+ * lifetime of a Durable Object instance.
290
309
  */
310
+ private _cachedOptions?;
291
311
  private get _resolvedOptions();
292
312
  /**
293
313
  * The observability implementation to use for the Agent
@@ -309,6 +329,14 @@ declare class Agent<
309
329
  * Check for workflows referencing unknown bindings and warn with migration suggestion.
310
330
  */
311
331
  private _checkOrphanedWorkflows;
332
+ /**
333
+ * Broadcast a protocol message only to connections that have protocol
334
+ * messages enabled. Connections where shouldSendProtocolMessages returned
335
+ * false are excluded automatically.
336
+ * @param msg The JSON-encoded protocol message
337
+ * @param excludeIds Additional connection IDs to exclude (e.g. the source)
338
+ */
339
+ private _broadcastProtocol;
312
340
  private _setStateInternal;
313
341
  /**
314
342
  * Update the Agent's state
@@ -317,11 +345,16 @@ declare class Agent<
317
345
  */
318
346
  setState(state: State): void;
319
347
  /**
320
- * Wraps connection.state and connection.setState so that the internal
321
- * _cf_readonly flag is hidden from user code and cannot be accidentally
322
- * overwritten. Must be called before any user code sees the connection.
348
+ * Wraps connection.state and connection.setState so that internal
349
+ * _cf_-prefixed flags (readonly, no-protocol) are hidden from user code
350
+ * and cannot be accidentally overwritten.
323
351
  *
324
352
  * Idempotent — safe to call multiple times on the same connection.
353
+ * After hibernation, the _rawStateAccessors WeakMap is empty but the
354
+ * connection's state getter still reads from the persisted WebSocket
355
+ * attachment. Calling this method re-captures the raw getter so that
356
+ * predicate methods (isConnectionReadonly, isConnectionProtocolEnabled)
357
+ * work correctly post-hibernation.
325
358
  */
326
359
  private _ensureConnectionWrapped;
327
360
  /**
@@ -331,7 +364,10 @@ declare class Agent<
331
364
  */
332
365
  setConnectionReadonly(connection: Connection$1, readonly?: boolean): void;
333
366
  /**
334
- * Check if a connection is marked as readonly
367
+ * Check if a connection is marked as readonly.
368
+ *
369
+ * Safe to call after hibernation — re-wraps the connection if the
370
+ * in-memory accessor cache was cleared.
335
371
  * @param connection The connection to check
336
372
  * @returns True if the connection is readonly
337
373
  */
@@ -346,6 +382,42 @@ declare class Agent<
346
382
  _connection: Connection$1,
347
383
  _ctx: ConnectionContext$1
348
384
  ): boolean;
385
+ /**
386
+ * Override this method to control whether protocol messages are sent to a
387
+ * connection. Protocol messages include identity (CF_AGENT_IDENTITY), state
388
+ * sync (CF_AGENT_STATE), and MCP server lists (CF_AGENT_MCP_SERVERS).
389
+ *
390
+ * When this returns `false` for a connection, that connection will not
391
+ * receive any protocol text frames — neither on connect nor via broadcasts.
392
+ * This is useful for binary-only clients (e.g. MQTT devices) that cannot
393
+ * handle JSON text frames.
394
+ *
395
+ * The connection can still send and receive regular messages, use RPC, and
396
+ * participate in all non-protocol communication.
397
+ *
398
+ * @param _connection The connection that is being established
399
+ * @param _ctx Connection context (includes the upgrade request)
400
+ * @returns True if protocol messages should be sent (default), false to suppress them
401
+ */
402
+ shouldSendProtocolMessages(
403
+ _connection: Connection$1,
404
+ _ctx: ConnectionContext$1
405
+ ): boolean;
406
+ /**
407
+ * Check if a connection has protocol messages enabled.
408
+ * Protocol messages include identity, state sync, and MCP server lists.
409
+ *
410
+ * Safe to call after hibernation — re-wraps the connection if the
411
+ * in-memory accessor cache was cleared.
412
+ * @param connection The connection to check
413
+ * @returns True if the connection receives protocol messages
414
+ */
415
+ isConnectionProtocolEnabled(connection: Connection$1): boolean;
416
+ /**
417
+ * Mark a connection as having protocol messages disabled.
418
+ * Called internally when shouldSendProtocolMessages returns false.
419
+ */
420
+ private _setConnectionNoProtocol;
349
421
  /**
350
422
  * Called before the Agent's state is persisted and broadcast.
351
423
  * Override to validate or reject an update by throwing an error.
@@ -423,54 +495,89 @@ declare class Agent<
423
495
  * Render content (not implemented in base class)
424
496
  */
425
497
  render(): void;
498
+ /**
499
+ * Retry an async operation with exponential backoff and jitter.
500
+ * Retries on all errors by default. Use `shouldRetry` to bail early on non-retryable errors.
501
+ *
502
+ * @param fn The async function to retry. Receives the current attempt number (1-indexed).
503
+ * @param options Retry configuration.
504
+ * @param options.maxAttempts Maximum number of attempts (including the first). Falls back to static options, then 3.
505
+ * @param options.baseDelayMs Base delay in ms for exponential backoff. Falls back to static options, then 100.
506
+ * @param options.maxDelayMs Maximum delay cap in ms. Falls back to static options, then 3000.
507
+ * @param options.shouldRetry Predicate called with the error and next attempt number. Return false to stop retrying immediately. Default: retry all errors.
508
+ * @returns The result of fn on success.
509
+ * @throws The last error if all attempts fail or shouldRetry returns false.
510
+ */
511
+ retry<T>(
512
+ fn: (attempt: number) => Promise<T>,
513
+ options?: RetryOptions & {
514
+ /** Return false to stop retrying a specific error. Receives the error and the next attempt number. Default: retry all errors. */ shouldRetry?: (
515
+ err: unknown,
516
+ nextAttempt: number
517
+ ) => boolean;
518
+ }
519
+ ): Promise<T>;
426
520
  /**
427
521
  * Queue a task to be executed in the future
428
- * @param payload Payload to pass to the callback
429
522
  * @param callback Name of the method to call
523
+ * @param payload Payload to pass to the callback
524
+ * @param options Options for the queued task
525
+ * @param options.retry Retry options for the callback execution
430
526
  * @returns The ID of the queued task
431
527
  */
432
- queue<T = unknown>(callback: keyof this, payload: T): Promise<string>;
528
+ queue<T = unknown>(
529
+ callback: keyof this,
530
+ payload: T,
531
+ options?: {
532
+ retry?: RetryOptions;
533
+ }
534
+ ): Promise<string>;
433
535
  private _flushingQueue;
434
536
  private _flushQueue;
435
537
  /**
436
538
  * Dequeue a task by ID
437
539
  * @param id ID of the task to dequeue
438
540
  */
439
- dequeue(id: string): Promise<void>;
541
+ dequeue(id: string): void;
440
542
  /**
441
543
  * Dequeue all tasks
442
544
  */
443
- dequeueAll(): Promise<void>;
545
+ dequeueAll(): void;
444
546
  /**
445
547
  * Dequeue all tasks by callback
446
548
  * @param callback Name of the callback to dequeue
447
549
  */
448
- dequeueAllByCallback(callback: string): Promise<void>;
550
+ dequeueAllByCallback(callback: string): void;
449
551
  /**
450
552
  * Get a queued task by ID
451
553
  * @param id ID of the task to get
452
554
  * @returns The task or undefined if not found
453
555
  */
454
- getQueue(id: string): Promise<QueueItem<string> | undefined>;
556
+ getQueue(id: string): QueueItem<string> | undefined;
455
557
  /**
456
558
  * Get all queues by key and value
457
559
  * @param key Key to filter by
458
560
  * @param value Value to filter by
459
561
  * @returns Array of matching QueueItem objects
460
562
  */
461
- getQueues(key: string, value: string): Promise<QueueItem<string>[]>;
563
+ getQueues(key: string, value: string): QueueItem<string>[];
462
564
  /**
463
565
  * Schedule a task to be executed in the future
464
566
  * @template T Type of the payload data
465
567
  * @param when When to execute the task (Date, seconds delay, or cron expression)
466
568
  * @param callback Name of the method to call
467
569
  * @param payload Data to pass to the callback
570
+ * @param options Options for the scheduled task
571
+ * @param options.retry Retry options for the callback execution
468
572
  * @returns Schedule object representing the scheduled task
469
573
  */
470
574
  schedule<T = string>(
471
575
  when: Date | string | number,
472
576
  callback: keyof this,
473
- payload?: T
577
+ payload?: T,
578
+ options?: {
579
+ retry?: RetryOptions;
580
+ }
474
581
  ): Promise<Schedule<T>>;
475
582
  /**
476
583
  * Schedule a task to run repeatedly at a fixed interval
@@ -478,12 +585,17 @@ declare class Agent<
478
585
  * @param intervalSeconds Number of seconds between executions
479
586
  * @param callback Name of the method to call
480
587
  * @param payload Data to pass to the callback
588
+ * @param options Options for the scheduled task
589
+ * @param options.retry Retry options for the callback execution
481
590
  * @returns Schedule object representing the scheduled task
482
591
  */
483
592
  scheduleEvery<T = string>(
484
593
  intervalSeconds: number,
485
594
  callback: keyof this,
486
- payload?: T
595
+ payload?: T,
596
+ options?: {
597
+ retry?: RetryOptions;
598
+ }
487
599
  ): Promise<Schedule<T>>;
488
600
  /**
489
601
  * Get a scheduled task by ID
@@ -491,7 +603,7 @@ declare class Agent<
491
603
  * @param id ID of the scheduled task
492
604
  * @returns The Schedule object or undefined if not found
493
605
  */
494
- getSchedule<T = string>(id: string): Promise<Schedule<T> | undefined>;
606
+ getSchedule<T = string>(id: string): Schedule<T> | undefined;
495
607
  /**
496
608
  * Get scheduled tasks matching the given criteria
497
609
  * @template T Type of the payload data
@@ -1128,12 +1240,14 @@ export {
1128
1240
  QueueItem,
1129
1241
  RPCRequest,
1130
1242
  RPCResponse,
1243
+ type RetryOptions,
1131
1244
  Schedule,
1132
1245
  SqlError,
1133
1246
  StateUpdateMessage,
1134
1247
  StreamingResponse,
1135
1248
  type TransportType,
1136
1249
  type WSMessage,
1250
+ __DO_NOT_USE_WILL_BREAK__agentContext,
1137
1251
  callable,
1138
1252
  createHeaderBasedEmailResolver,
1139
1253
  getAgentByName,