agents 0.0.0-7d9b939 → 0.0.0-7f4616c

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.
Files changed (82) hide show
  1. package/README.md +103 -5
  2. package/dist/ai-chat-agent.d.ts +16 -17
  3. package/dist/ai-chat-agent.js +532 -351
  4. package/dist/ai-chat-agent.js.map +1 -1
  5. package/dist/ai-chat-v5-migration-gdyLiTd8.js +155 -0
  6. package/dist/ai-chat-v5-migration-gdyLiTd8.js.map +1 -0
  7. package/dist/ai-chat-v5-migration.d.ts +7 -4
  8. package/dist/ai-chat-v5-migration.js +3 -19
  9. package/dist/ai-react.d.ts +20 -23
  10. package/dist/ai-react.js +259 -304
  11. package/dist/ai-react.js.map +1 -1
  12. package/dist/ai-types-BWW4umHY.d.ts +95 -0
  13. package/dist/ai-types-UZlfLOYP.js +20 -0
  14. package/dist/ai-types-UZlfLOYP.js.map +1 -0
  15. package/dist/ai-types.d.ts +6 -91
  16. package/dist/ai-types.js +3 -7
  17. package/dist/client-CZBVDDoO.js +786 -0
  18. package/dist/client-CZBVDDoO.js.map +1 -0
  19. package/dist/client-CmMi85Sj.d.ts +104 -0
  20. package/dist/client-CrWcaPgn.d.ts +5313 -0
  21. package/dist/client-DjR-lC16.js +117 -0
  22. package/dist/client-DjR-lC16.js.map +1 -0
  23. package/dist/client.d.ts +11 -92
  24. package/dist/client.js +4 -12
  25. package/dist/codemode/ai.d.ts +27 -0
  26. package/dist/codemode/ai.js +151 -0
  27. package/dist/codemode/ai.js.map +1 -0
  28. package/dist/do-oauth-client-provider-B2jr6UNq.js +93 -0
  29. package/dist/do-oauth-client-provider-B2jr6UNq.js.map +1 -0
  30. package/dist/do-oauth-client-provider-CCwGwnrA.d.ts +55 -0
  31. package/dist/index-DpH9o0ao.d.ts +568 -0
  32. package/dist/index-W4JUkafc.d.ts +54 -0
  33. package/dist/index.d.ts +56 -550
  34. package/dist/index.js +7 -31
  35. package/dist/mcp/client.d.ts +4 -11
  36. package/dist/mcp/client.js +3 -9
  37. package/dist/mcp/do-oauth-client-provider.d.ts +2 -42
  38. package/dist/mcp/do-oauth-client-provider.js +3 -7
  39. package/dist/mcp/index.d.ts +72 -94
  40. package/dist/mcp/index.js +831 -1013
  41. package/dist/mcp/index.js.map +1 -1
  42. package/dist/mcp/x402.d.ts +34 -0
  43. package/dist/mcp/x402.js +194 -0
  44. package/dist/mcp/x402.js.map +1 -0
  45. package/dist/mcp-BEwaCsxO.d.ts +61 -0
  46. package/dist/observability/index.d.ts +3 -46
  47. package/dist/observability/index.js +7 -11
  48. package/dist/react-LfPKBVtU.d.ts +113 -0
  49. package/dist/react.d.ts +10 -123
  50. package/dist/react.js +183 -112
  51. package/dist/react.js.map +1 -1
  52. package/dist/schedule.d.ts +13 -10
  53. package/dist/schedule.js +43 -31
  54. package/dist/schedule.js.map +1 -1
  55. package/dist/serializable-gtr9YMhp.d.ts +34 -0
  56. package/dist/serializable.d.ts +7 -32
  57. package/dist/serializable.js +1 -1
  58. package/dist/src-L3cHuAag.js +1231 -0
  59. package/dist/src-L3cHuAag.js.map +1 -0
  60. package/package.json +36 -11
  61. package/src/index.ts +289 -69
  62. package/dist/ai-chat-v5-migration.js.map +0 -1
  63. package/dist/ai-types.js.map +0 -1
  64. package/dist/chunk-AVYJQSLW.js +0 -17
  65. package/dist/chunk-AVYJQSLW.js.map +0 -1
  66. package/dist/chunk-LL2AFX7V.js +0 -109
  67. package/dist/chunk-LL2AFX7V.js.map +0 -1
  68. package/dist/chunk-MH46VMM4.js +0 -612
  69. package/dist/chunk-MH46VMM4.js.map +0 -1
  70. package/dist/chunk-QEVM4BVL.js +0 -116
  71. package/dist/chunk-QEVM4BVL.js.map +0 -1
  72. package/dist/chunk-UJVEAURM.js +0 -150
  73. package/dist/chunk-UJVEAURM.js.map +0 -1
  74. package/dist/chunk-YDUDMOL6.js +0 -1296
  75. package/dist/chunk-YDUDMOL6.js.map +0 -1
  76. package/dist/client-CvaJdLQA.d.ts +0 -5015
  77. package/dist/client.js.map +0 -1
  78. package/dist/index.js.map +0 -1
  79. package/dist/mcp/client.js.map +0 -1
  80. package/dist/mcp/do-oauth-client-provider.js.map +0 -1
  81. package/dist/observability/index.js.map +0 -1
  82. package/dist/serializable.js.map +0 -1
package/src/index.ts CHANGED
@@ -22,10 +22,12 @@ import {
22
22
  routePartykitRequest
23
23
  } from "partyserver";
24
24
  import { camelCaseToKebabCase } from "./client";
25
- import { MCPClientManager } from "./mcp/client";
26
- // import type { MCPClientConnection } from "./mcp/client-connection";
25
+ import { MCPClientManager, type MCPClientOAuthResult } from "./mcp/client";
26
+ import type { MCPConnectionState } from "./mcp/client-connection";
27
27
  import { DurableObjectOAuthClientProvider } from "./mcp/do-oauth-client-provider";
28
+ import type { TransportType } from "./mcp/types";
28
29
  import { genericObservability, type Observability } from "./observability";
30
+ import { DisposableStore } from "./core/events";
29
31
  import { MessageType } from "./ai-types";
30
32
 
31
33
  export type { Connection, ConnectionContext, WSMessage } from "partyserver";
@@ -197,6 +199,8 @@ function getNextCronTime(cron: string) {
197
199
  return interval.getNextDate();
198
200
  }
199
201
 
202
+ export type { TransportType } from "./mcp/types";
203
+
200
204
  /**
201
205
  * MCP Server state update message from server -> Client
202
206
  */
@@ -221,7 +225,7 @@ export type MCPServer = {
221
225
  // This state is specifically about the temporary process of getting a token (if needed).
222
226
  // Scope outside of that can't be relied upon because when the DO sleeps, there's no way
223
227
  // to communicate a change to a non-ready state.
224
- state: "authenticating" | "connecting" | "ready" | "discovering" | "failed";
228
+ state: MCPConnectionState;
225
229
  instructions: string | null;
226
230
  capabilities: ServerCapabilities | null;
227
231
  };
@@ -314,11 +318,15 @@ export class Agent<
314
318
  Props extends Record<string, unknown> = Record<string, unknown>
315
319
  > extends Server<Env, Props> {
316
320
  private _state = DEFAULT_STATE as State;
321
+ private _disposables = new DisposableStore();
317
322
 
318
323
  private _ParentClass: typeof Agent<Env, State> =
319
324
  Object.getPrototypeOf(this).constructor;
320
325
 
321
- mcp: MCPClientManager = new MCPClientManager(this._ParentClass.name, "0.0.1");
326
+ readonly mcp: MCPClientManager = new MCPClientManager(
327
+ this._ParentClass.name,
328
+ "0.0.1"
329
+ );
322
330
 
323
331
  /**
324
332
  * Initial state for the Agent
@@ -411,8 +419,25 @@ export class Agent<
411
419
  constructor(ctx: AgentContext, env: Env) {
412
420
  super(ctx, env);
413
421
 
414
- // Auto-wrap custom methods with agent context
415
- this._autoWrapCustomMethods();
422
+ if (!wrappedClasses.has(this.constructor)) {
423
+ // Auto-wrap custom methods with agent context
424
+ this._autoWrapCustomMethods();
425
+ wrappedClasses.add(this.constructor);
426
+ }
427
+
428
+ // Broadcast server state after background connects (for OAuth servers)
429
+ this._disposables.add(
430
+ this.mcp.onConnected(async () => {
431
+ this.broadcastMcpServers();
432
+ })
433
+ );
434
+
435
+ // Emit MCP observability events
436
+ this._disposables.add(
437
+ this.mcp.onObservabilityEvent((event) => {
438
+ this.observability?.emit(event);
439
+ })
440
+ );
416
441
 
417
442
  this.sql`
418
443
  CREATE TABLE IF NOT EXISTS cf_agents_state (
@@ -468,22 +493,11 @@ export class Agent<
468
493
  return agentContext.run(
469
494
  { agent: this, connection: undefined, request, email: undefined },
470
495
  async () => {
471
- if (this.mcp.isCallbackRequest(request)) {
472
- await this.mcp.handleCallbackRequest(request);
473
-
474
- // after the MCP connection handshake, we can send updated mcp state
475
- this.broadcast(
476
- JSON.stringify({
477
- mcp: this.getMcpServers(),
478
- type: MessageType.CF_AGENT_MCP_SERVERS
479
- })
480
- );
481
-
482
- // We probably should let the user configure this response/redirect, but this is fine for now.
483
- return new Response("<script>window.close();</script>", {
484
- headers: { "content-type": "text/html" },
485
- status: 200
486
- });
496
+ // Check if this is an OAuth callback and restore state if needed
497
+ const callbackResult =
498
+ await this._handlePotentialOAuthCallback(request);
499
+ if (callbackResult) {
500
+ return callbackResult;
487
501
  }
488
502
 
489
503
  return this._tryCatch(() => _onRequest(request));
@@ -636,15 +650,20 @@ export class Agent<
636
650
  SELECT id, name, server_url, client_id, auth_url, callback_url, server_options FROM cf_agents_mcp_servers;
637
651
  `;
638
652
 
639
- this.broadcast(
640
- JSON.stringify({
641
- mcp: this.getMcpServers(),
642
- type: MessageType.CF_AGENT_MCP_SERVERS
643
- })
644
- );
653
+ this.broadcastMcpServers();
645
654
 
646
655
  // from DO storage, reconnect to all servers not currently in the oauth flow using our saved auth information
647
656
  if (servers && Array.isArray(servers) && servers.length > 0) {
657
+ // Restore callback URLs for OAuth-enabled servers
658
+ servers.forEach((server) => {
659
+ if (server.callback_url) {
660
+ // Register the full redirect URL including serverId to avoid ambiguous matches
661
+ this.mcp.registerCallbackUrl(
662
+ `${server.callback_url}/${server.id}`
663
+ );
664
+ }
665
+ });
666
+
648
667
  servers.forEach((server) => {
649
668
  this._connectToMcpServerInternal(
650
669
  server.name,
@@ -660,12 +679,7 @@ export class Agent<
660
679
  )
661
680
  .then(() => {
662
681
  // Broadcast updated MCP servers state after each server connects
663
- this.broadcast(
664
- JSON.stringify({
665
- mcp: this.getMcpServers(),
666
- type: MessageType.CF_AGENT_MCP_SERVERS
667
- })
668
- );
682
+ this.broadcastMcpServers();
669
683
  })
670
684
  .catch((error) => {
671
685
  console.error(
@@ -673,12 +687,7 @@ export class Agent<
673
687
  error
674
688
  );
675
689
  // Still broadcast even if connection fails, so clients know about the failure
676
- this.broadcast(
677
- JSON.stringify({
678
- mcp: this.getMcpServers(),
679
- type: MessageType.CF_AGENT_MCP_SERVERS
680
- })
681
- );
690
+ this.broadcastMcpServers();
682
691
  });
683
692
  });
684
693
  }
@@ -1371,6 +1380,8 @@ export class Agent<
1371
1380
  // delete all alarms
1372
1381
  await this.ctx.storage.deleteAlarm();
1373
1382
  await this.ctx.storage.deleteAll();
1383
+ this._disposables.dispose();
1384
+ await this.mcp.dispose?.();
1374
1385
  this.ctx.abort("destroyed"); // enforce that the agent is evicted
1375
1386
 
1376
1387
  this.observability?.emit(
@@ -1396,57 +1407,220 @@ export class Agent<
1396
1407
  /**
1397
1408
  * Connect to a new MCP Server
1398
1409
  *
1410
+ * @param serverName Name of the MCP server
1399
1411
  * @param url MCP Server SSE URL
1400
- * @param callbackHost Base host for the agent, used for the redirect URI.
1412
+ * @param callbackHost Base host for the agent, used for the redirect URI. If not provided, will be derived from the current request.
1401
1413
  * @param agentsPrefix agents routing prefix if not using `agents`
1402
- * @param options MCP client and transport (header) options
1414
+ * @param options MCP client and transport options
1403
1415
  * @returns authUrl
1404
1416
  */
1405
1417
  async addMcpServer(
1406
1418
  serverName: string,
1407
1419
  url: string,
1408
- callbackHost: string,
1420
+ callbackHost?: string,
1409
1421
  agentsPrefix = "agents",
1410
1422
  options?: {
1411
1423
  client?: ConstructorParameters<typeof Client>[1];
1412
1424
  transport?: {
1413
- headers: HeadersInit;
1425
+ headers?: HeadersInit;
1426
+ type?: TransportType;
1414
1427
  };
1415
1428
  }
1416
1429
  ): Promise<{ id: string; authUrl: string | undefined }> {
1417
- const callbackUrl = `${callbackHost}/${agentsPrefix}/${camelCaseToKebabCase(this._ParentClass.name)}/${this.name}/callback`;
1430
+ // If callbackHost is not provided, derive it from the current request
1431
+ let resolvedCallbackHost = callbackHost;
1432
+ if (!resolvedCallbackHost) {
1433
+ const { request } = getCurrentAgent();
1434
+ if (!request) {
1435
+ throw new Error(
1436
+ "callbackHost is required when not called within a request context"
1437
+ );
1438
+ }
1418
1439
 
1419
- const result = await this._connectToMcpServerInternal(
1420
- serverName,
1421
- url,
1422
- callbackUrl,
1423
- options
1424
- );
1440
+ // Extract the origin from the request
1441
+ const requestUrl = new URL(request.url);
1442
+ resolvedCallbackHost = `${requestUrl.protocol}//${requestUrl.host}`;
1443
+ }
1444
+
1445
+ const callbackUrl = `${resolvedCallbackHost}/${agentsPrefix}/${camelCaseToKebabCase(this._ParentClass.name)}/${this.name}/callback`;
1446
+
1447
+ // Generate a serverId upfront
1448
+ const serverId = nanoid(8);
1449
+
1450
+ // Persist to database BEFORE starting OAuth flow to survive DO hibernation
1425
1451
  this.sql`
1426
- INSERT
1427
- OR REPLACE INTO cf_agents_mcp_servers (id, name, server_url, client_id, auth_url, callback_url, server_options)
1452
+ INSERT OR REPLACE INTO cf_agents_mcp_servers (id, name, server_url, client_id, auth_url, callback_url, server_options)
1428
1453
  VALUES (
1429
- ${result.id},
1454
+ ${serverId},
1430
1455
  ${serverName},
1431
1456
  ${url},
1432
- ${result.clientId ?? null},
1433
- ${result.authUrl ?? null},
1457
+ ${null},
1458
+ ${null},
1434
1459
  ${callbackUrl},
1435
1460
  ${options ? JSON.stringify(options) : null}
1436
1461
  );
1437
1462
  `;
1438
1463
 
1439
- this.broadcast(
1440
- JSON.stringify({
1441
- mcp: this.getMcpServers(),
1442
- type: MessageType.CF_AGENT_MCP_SERVERS
1443
- })
1464
+ // _connectToMcpServerInternal will call mcp.connect which registers the callback URL
1465
+ const result = await this._connectToMcpServerInternal(
1466
+ serverName,
1467
+ url,
1468
+ callbackUrl,
1469
+ options,
1470
+ { id: serverId }
1444
1471
  );
1445
1472
 
1473
+ // Update database with OAuth client info if auth is required
1474
+ if (result.clientId || result.authUrl) {
1475
+ this.sql`
1476
+ UPDATE cf_agents_mcp_servers
1477
+ SET client_id = ${result.clientId ?? null}, auth_url = ${result.authUrl ?? null}
1478
+ WHERE id = ${serverId}
1479
+ `;
1480
+ }
1481
+
1482
+ this.broadcastMcpServers();
1483
+
1446
1484
  return result;
1447
1485
  }
1448
1486
 
1449
- async _connectToMcpServerInternal(
1487
+ /**
1488
+ * Handle potential OAuth callback requests after DO hibernation.
1489
+ * Detects OAuth callbacks, restores state from database, and processes the callback.
1490
+ * Returns a Response if this was an OAuth callback, otherwise returns undefined.
1491
+ */
1492
+ private async _handlePotentialOAuthCallback(
1493
+ request: Request
1494
+ ): Promise<Response | undefined> {
1495
+ // Quick check: must be GET with callback pattern and code parameter
1496
+ if (request.method !== "GET") {
1497
+ return undefined;
1498
+ }
1499
+
1500
+ const url = new URL(request.url);
1501
+ const hasCallbackPattern =
1502
+ url.pathname.includes("/callback/") && url.searchParams.has("code");
1503
+
1504
+ if (!hasCallbackPattern) {
1505
+ return undefined;
1506
+ }
1507
+
1508
+ // Extract serverId from callback URL
1509
+ const pathParts = url.pathname.split("/");
1510
+ const callbackIndex = pathParts.indexOf("callback");
1511
+ const serverId = callbackIndex !== -1 ? pathParts[callbackIndex + 1] : null;
1512
+
1513
+ if (!serverId) {
1514
+ return new Response("Invalid callback URL: missing serverId", {
1515
+ status: 400
1516
+ });
1517
+ }
1518
+
1519
+ // Check if callback is already registered AND connection exists (not hibernated)
1520
+ if (
1521
+ this.mcp.isCallbackRequest(request) &&
1522
+ this.mcp.mcpConnections[serverId]
1523
+ ) {
1524
+ // State already restored, handle normally
1525
+ return this._processOAuthCallback(request);
1526
+ }
1527
+
1528
+ // Need to restore from database after hibernation
1529
+ try {
1530
+ const server = this.sql<MCPServerRow>`
1531
+ SELECT id, name, server_url, client_id, auth_url, callback_url, server_options
1532
+ FROM cf_agents_mcp_servers
1533
+ WHERE id = ${serverId}
1534
+ `.find((s) => s.id === serverId);
1535
+
1536
+ if (!server) {
1537
+ return new Response(
1538
+ `OAuth callback failed: Server ${serverId} not found in database`,
1539
+ { status: 404 }
1540
+ );
1541
+ }
1542
+
1543
+ // Register callback URL (restores it after hibernation)
1544
+ if (!server.callback_url) {
1545
+ return new Response(
1546
+ `OAuth callback failed: No callback URL stored for server ${serverId}`,
1547
+ { status: 500 }
1548
+ );
1549
+ }
1550
+
1551
+ this.mcp.registerCallbackUrl(`${server.callback_url}/${server.id}`);
1552
+
1553
+ // Restore connection if not in memory
1554
+ if (!this.mcp.mcpConnections[serverId]) {
1555
+ let parsedOptions:
1556
+ | {
1557
+ client?: ConstructorParameters<typeof Client>[1];
1558
+ transport?: {
1559
+ headers?: HeadersInit;
1560
+ type?: TransportType;
1561
+ };
1562
+ }
1563
+ | undefined;
1564
+ try {
1565
+ parsedOptions = server.server_options
1566
+ ? JSON.parse(server.server_options)
1567
+ : undefined;
1568
+ } catch {
1569
+ return new Response(
1570
+ `OAuth callback failed: Invalid server options in database for ${serverId}`,
1571
+ { status: 500 }
1572
+ );
1573
+ }
1574
+
1575
+ await this._connectToMcpServerInternal(
1576
+ server.name,
1577
+ server.server_url,
1578
+ server.callback_url,
1579
+ parsedOptions,
1580
+ {
1581
+ id: server.id,
1582
+ oauthClientId: server.client_id ?? undefined
1583
+ }
1584
+ );
1585
+ }
1586
+
1587
+ // Now process the OAuth callback
1588
+ return this._processOAuthCallback(request);
1589
+ } catch (error) {
1590
+ const errorMsg = error instanceof Error ? error.message : "Unknown error";
1591
+ console.error(`Failed to restore MCP state for ${serverId}:`, error);
1592
+ return new Response(
1593
+ `OAuth callback failed during state restoration: ${errorMsg}`,
1594
+ { status: 500 }
1595
+ );
1596
+ }
1597
+ }
1598
+
1599
+ /**
1600
+ * Process an OAuth callback request (assumes state is already restored)
1601
+ */
1602
+ private async _processOAuthCallback(request: Request): Promise<Response> {
1603
+ const result = await this.mcp.handleCallbackRequest(request);
1604
+ this.broadcastMcpServers();
1605
+
1606
+ if (result.authSuccess) {
1607
+ // Start background connection if auth was successful
1608
+ this.mcp
1609
+ .establishConnection(result.serverId)
1610
+ .catch((error) => {
1611
+ console.error("Background connection failed:", error);
1612
+ })
1613
+ .finally(() => {
1614
+ // Broadcast after background connection resolves (success/failure)
1615
+ this.broadcastMcpServers();
1616
+ });
1617
+ }
1618
+
1619
+ // Handle OAuth callback response using MCPClientManager configuration
1620
+ return this.handleOAuthCallbackResponse(result, request);
1621
+ }
1622
+
1623
+ private async _connectToMcpServerInternal(
1450
1624
  _serverName: string,
1451
1625
  url: string,
1452
1626
  callbackUrl: string,
@@ -1462,6 +1636,7 @@ export class Agent<
1462
1636
  */
1463
1637
  transport?: {
1464
1638
  headers?: HeadersInit;
1639
+ type?: TransportType;
1465
1640
  };
1466
1641
  },
1467
1642
  reconnect?: {
@@ -1486,6 +1661,9 @@ export class Agent<
1486
1661
  }
1487
1662
  }
1488
1663
 
1664
+ // Use the transport type specified in options, or default to "auto"
1665
+ const transportType: TransportType = options?.transport?.type ?? "auto";
1666
+
1489
1667
  // allows passing through transport headers if necessary
1490
1668
  // this handles some non-standard bearer auth setups (i.e. MCP server behind CF access instead of OAuth)
1491
1669
  let headerTransportOpts: SSEClientTransportOptions = {};
@@ -1509,7 +1687,8 @@ export class Agent<
1509
1687
  reconnect,
1510
1688
  transport: {
1511
1689
  ...headerTransportOpts,
1512
- authProvider
1690
+ authProvider,
1691
+ type: transportType
1513
1692
  }
1514
1693
  });
1515
1694
 
@@ -1522,15 +1701,11 @@ export class Agent<
1522
1701
 
1523
1702
  async removeMcpServer(id: string) {
1524
1703
  this.mcp.closeConnection(id);
1704
+ this.mcp.unregisterCallbackUrl(id);
1525
1705
  this.sql`
1526
1706
  DELETE FROM cf_agents_mcp_servers WHERE id = ${id};
1527
1707
  `;
1528
- this.broadcast(
1529
- JSON.stringify({
1530
- mcp: this.getMcpServers(),
1531
- type: MessageType.CF_AGENT_MCP_SERVERS
1532
- })
1533
- );
1708
+ this.broadcastMcpServers();
1534
1709
  }
1535
1710
 
1536
1711
  getMcpServers(): MCPServersState {
@@ -1562,8 +1737,53 @@ export class Agent<
1562
1737
 
1563
1738
  return mcpState;
1564
1739
  }
1740
+
1741
+ private broadcastMcpServers() {
1742
+ this.broadcast(
1743
+ JSON.stringify({
1744
+ mcp: this.getMcpServers(),
1745
+ type: MessageType.CF_AGENT_MCP_SERVERS
1746
+ })
1747
+ );
1748
+ }
1749
+
1750
+ /**
1751
+ * Handle OAuth callback response using MCPClientManager configuration
1752
+ * @param result OAuth callback result
1753
+ * @param request The original request (needed for base URL)
1754
+ * @returns Response for the OAuth callback
1755
+ */
1756
+ private handleOAuthCallbackResponse(
1757
+ result: MCPClientOAuthResult,
1758
+ request: Request
1759
+ ): Response {
1760
+ const config = this.mcp.getOAuthCallbackConfig();
1761
+
1762
+ // Use custom handler if configured
1763
+ if (config?.customHandler) {
1764
+ return config.customHandler(result);
1765
+ }
1766
+
1767
+ // Use redirect URLs if configured
1768
+ if (config?.successRedirect && result.authSuccess) {
1769
+ return Response.redirect(config.successRedirect);
1770
+ }
1771
+
1772
+ if (config?.errorRedirect && !result.authSuccess) {
1773
+ return Response.redirect(
1774
+ `${config.errorRedirect}?error=${encodeURIComponent(result.authError || "Unknown error")}`
1775
+ );
1776
+ }
1777
+
1778
+ // Default behavior - redirect to base URL
1779
+ const baseUrl = new URL(request.url).origin;
1780
+ return Response.redirect(baseUrl);
1781
+ }
1565
1782
  }
1566
1783
 
1784
+ // A set of classes that have been wrapped with agent context
1785
+ const wrappedClasses = new Set<typeof Agent.prototype.constructor>();
1786
+
1567
1787
  /**
1568
1788
  * Namespace for creating Agent instances
1569
1789
  * @template Agentic Type of the Agent class
@@ -1 +0,0 @@
1
- {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -1,17 +0,0 @@
1
- // src/ai-types.ts
2
- var MessageType = /* @__PURE__ */ ((MessageType2) => {
3
- MessageType2["CF_AGENT_CHAT_MESSAGES"] = "cf_agent_chat_messages";
4
- MessageType2["CF_AGENT_USE_CHAT_REQUEST"] = "cf_agent_use_chat_request";
5
- MessageType2["CF_AGENT_USE_CHAT_RESPONSE"] = "cf_agent_use_chat_response";
6
- MessageType2["CF_AGENT_CHAT_CLEAR"] = "cf_agent_chat_clear";
7
- MessageType2["CF_AGENT_CHAT_REQUEST_CANCEL"] = "cf_agent_chat_request_cancel";
8
- MessageType2["CF_AGENT_MCP_SERVERS"] = "cf_agent_mcp_servers";
9
- MessageType2["CF_AGENT_STATE"] = "cf_agent_state";
10
- MessageType2["RPC"] = "rpc";
11
- return MessageType2;
12
- })(MessageType || {});
13
-
14
- export {
15
- MessageType
16
- };
17
- //# sourceMappingURL=chunk-AVYJQSLW.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/ai-types.ts"],"sourcesContent":["import type { UIMessage } from \"ai\";\n\n/**\n * Enum for message types to improve type safety and maintainability\n */\nexport enum MessageType {\n CF_AGENT_CHAT_MESSAGES = \"cf_agent_chat_messages\",\n CF_AGENT_USE_CHAT_REQUEST = \"cf_agent_use_chat_request\",\n CF_AGENT_USE_CHAT_RESPONSE = \"cf_agent_use_chat_response\",\n CF_AGENT_CHAT_CLEAR = \"cf_agent_chat_clear\",\n CF_AGENT_CHAT_REQUEST_CANCEL = \"cf_agent_chat_request_cancel\",\n\n CF_AGENT_MCP_SERVERS = \"cf_agent_mcp_servers\",\n CF_AGENT_STATE = \"cf_agent_state\",\n RPC = \"rpc\"\n}\n\n/**\n * Types of messages sent from the Agent to clients\n */\nexport type OutgoingMessage<ChatMessage extends UIMessage = UIMessage> =\n | {\n /** Indicates this message is a command to clear chat history */\n type: MessageType.CF_AGENT_CHAT_CLEAR;\n }\n | {\n /** Indicates this message contains updated chat messages */\n type: MessageType.CF_AGENT_CHAT_MESSAGES;\n /** Array of chat messages */\n messages: ChatMessage[];\n }\n | {\n /** Indicates this message is a response to a chat request */\n type: MessageType.CF_AGENT_USE_CHAT_RESPONSE;\n /** Unique ID of the request this response corresponds to */\n id: string;\n /** Content body of the response */\n body: string;\n /** Whether this is the final chunk of the response */\n done: boolean;\n /** Whether this response contains an error */\n error?: boolean;\n }\n | {\n /** Indicates this message is a command to clear chat history */\n type: MessageType.CF_AGENT_CHAT_CLEAR;\n };\n\n/**\n * Types of messages sent from clients to the Agent\n */\nexport type IncomingMessage<ChatMessage extends UIMessage = UIMessage> =\n | {\n /** Indicates this message is a command to clear chat history */\n type: MessageType.CF_AGENT_CHAT_CLEAR;\n }\n | {\n /** Indicates this message is a request to the chat API */\n type: MessageType.CF_AGENT_USE_CHAT_REQUEST;\n /** Unique ID for this request */\n id: string;\n /** Request initialization options */\n init: Pick<\n RequestInit,\n | \"method\"\n | \"keepalive\"\n | \"headers\"\n | \"body\"\n | \"redirect\"\n | \"integrity\"\n | \"credentials\"\n | \"mode\"\n | \"referrer\"\n | \"referrerPolicy\"\n | \"window\"\n >;\n }\n | {\n /** Indicates this message is a command to clear chat history */\n type: MessageType.CF_AGENT_CHAT_CLEAR;\n }\n | {\n /** Indicates this message contains updated chat messages */\n type: MessageType.CF_AGENT_CHAT_MESSAGES;\n /** Array of chat messages */\n messages: ChatMessage[];\n }\n | {\n /** Indicates the user wants to stop generation of this message */\n type: MessageType.CF_AGENT_CHAT_REQUEST_CANCEL;\n id: string;\n };\n"],"mappings":";AAKO,IAAK,cAAL,kBAAKA,iBAAL;AACL,EAAAA,aAAA,4BAAyB;AACzB,EAAAA,aAAA,+BAA4B;AAC5B,EAAAA,aAAA,gCAA6B;AAC7B,EAAAA,aAAA,yBAAsB;AACtB,EAAAA,aAAA,kCAA+B;AAE/B,EAAAA,aAAA,0BAAuB;AACvB,EAAAA,aAAA,oBAAiB;AACjB,EAAAA,aAAA,SAAM;AATI,SAAAA;AAAA,GAAA;","names":["MessageType"]}
@@ -1,109 +0,0 @@
1
- // src/mcp/do-oauth-client-provider.ts
2
- var DurableObjectOAuthClientProvider = class {
3
- constructor(storage, clientName, baseRedirectUrl) {
4
- this.storage = storage;
5
- this.clientName = clientName;
6
- this.baseRedirectUrl = baseRedirectUrl;
7
- }
8
- get clientMetadata() {
9
- return {
10
- client_name: this.clientName,
11
- client_uri: this.clientUri,
12
- grant_types: ["authorization_code", "refresh_token"],
13
- redirect_uris: [this.redirectUrl],
14
- response_types: ["code"],
15
- token_endpoint_auth_method: "none"
16
- };
17
- }
18
- get clientUri() {
19
- return new URL(this.redirectUrl).origin;
20
- }
21
- get redirectUrl() {
22
- return `${this.baseRedirectUrl}/${this.serverId}`;
23
- }
24
- get clientId() {
25
- if (!this._clientId_) {
26
- throw new Error("Trying to access clientId before it was set");
27
- }
28
- return this._clientId_;
29
- }
30
- set clientId(clientId_) {
31
- this._clientId_ = clientId_;
32
- }
33
- get serverId() {
34
- if (!this._serverId_) {
35
- throw new Error("Trying to access serverId before it was set");
36
- }
37
- return this._serverId_;
38
- }
39
- set serverId(serverId_) {
40
- this._serverId_ = serverId_;
41
- }
42
- keyPrefix(clientId) {
43
- return `/${this.clientName}/${this.serverId}/${clientId}`;
44
- }
45
- clientInfoKey(clientId) {
46
- return `${this.keyPrefix(clientId)}/client_info/`;
47
- }
48
- async clientInformation() {
49
- if (!this._clientId_) {
50
- return void 0;
51
- }
52
- return await this.storage.get(
53
- this.clientInfoKey(this.clientId)
54
- ) ?? void 0;
55
- }
56
- async saveClientInformation(clientInformation) {
57
- await this.storage.put(
58
- this.clientInfoKey(clientInformation.client_id),
59
- clientInformation
60
- );
61
- this.clientId = clientInformation.client_id;
62
- }
63
- tokenKey(clientId) {
64
- return `${this.keyPrefix(clientId)}/token`;
65
- }
66
- async tokens() {
67
- if (!this._clientId_) {
68
- return void 0;
69
- }
70
- return await this.storage.get(this.tokenKey(this.clientId)) ?? void 0;
71
- }
72
- async saveTokens(tokens) {
73
- await this.storage.put(this.tokenKey(this.clientId), tokens);
74
- }
75
- get authUrl() {
76
- return this._authUrl_;
77
- }
78
- /**
79
- * Because this operates on the server side (but we need browser auth), we send this url back to the user
80
- * and require user interact to initiate the redirect flow
81
- */
82
- async redirectToAuthorization(authUrl) {
83
- const client_id = authUrl.searchParams.get("client_id");
84
- if (client_id) {
85
- authUrl.searchParams.append("state", client_id);
86
- }
87
- this._authUrl_ = authUrl.toString();
88
- }
89
- codeVerifierKey(clientId) {
90
- return `${this.keyPrefix(clientId)}/code_verifier`;
91
- }
92
- async saveCodeVerifier(verifier) {
93
- await this.storage.put(this.codeVerifierKey(this.clientId), verifier);
94
- }
95
- async codeVerifier() {
96
- const codeVerifier = await this.storage.get(
97
- this.codeVerifierKey(this.clientId)
98
- );
99
- if (!codeVerifier) {
100
- throw new Error("No code verifier found");
101
- }
102
- return codeVerifier;
103
- }
104
- };
105
-
106
- export {
107
- DurableObjectOAuthClientProvider
108
- };
109
- //# sourceMappingURL=chunk-LL2AFX7V.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/mcp/do-oauth-client-provider.ts"],"sourcesContent":["import type { OAuthClientProvider } from \"@modelcontextprotocol/sdk/client/auth.js\";\nimport type {\n OAuthClientInformation,\n OAuthClientInformationFull,\n OAuthClientMetadata,\n OAuthTokens\n} from \"@modelcontextprotocol/sdk/shared/auth.js\";\n\n// A slight extension to the standard OAuthClientProvider interface because `redirectToAuthorization` doesn't give us the interface we need\n// This allows us to track authentication for a specific server and associated dynamic client registration\nexport interface AgentsOAuthProvider extends OAuthClientProvider {\n authUrl: string | undefined;\n clientId: string | undefined;\n serverId: string | undefined;\n}\n\nexport class DurableObjectOAuthClientProvider implements AgentsOAuthProvider {\n private _authUrl_: string | undefined;\n private _serverId_: string | undefined;\n private _clientId_: string | undefined;\n\n constructor(\n public storage: DurableObjectStorage,\n public clientName: string,\n public baseRedirectUrl: string\n ) {}\n\n get clientMetadata(): OAuthClientMetadata {\n return {\n client_name: this.clientName,\n client_uri: this.clientUri,\n grant_types: [\"authorization_code\", \"refresh_token\"],\n redirect_uris: [this.redirectUrl],\n response_types: [\"code\"],\n token_endpoint_auth_method: \"none\"\n };\n }\n\n get clientUri() {\n return new URL(this.redirectUrl).origin;\n }\n\n get redirectUrl() {\n return `${this.baseRedirectUrl}/${this.serverId}`;\n }\n\n get clientId() {\n if (!this._clientId_) {\n throw new Error(\"Trying to access clientId before it was set\");\n }\n return this._clientId_;\n }\n\n set clientId(clientId_: string) {\n this._clientId_ = clientId_;\n }\n\n get serverId() {\n if (!this._serverId_) {\n throw new Error(\"Trying to access serverId before it was set\");\n }\n return this._serverId_;\n }\n\n set serverId(serverId_: string) {\n this._serverId_ = serverId_;\n }\n\n keyPrefix(clientId: string) {\n return `/${this.clientName}/${this.serverId}/${clientId}`;\n }\n\n clientInfoKey(clientId: string) {\n return `${this.keyPrefix(clientId)}/client_info/`;\n }\n\n async clientInformation(): Promise<OAuthClientInformation | undefined> {\n if (!this._clientId_) {\n return undefined;\n }\n return (\n (await this.storage.get<OAuthClientInformation>(\n this.clientInfoKey(this.clientId)\n )) ?? undefined\n );\n }\n\n async saveClientInformation(\n clientInformation: OAuthClientInformationFull\n ): Promise<void> {\n await this.storage.put(\n this.clientInfoKey(clientInformation.client_id),\n clientInformation\n );\n this.clientId = clientInformation.client_id;\n }\n\n tokenKey(clientId: string) {\n return `${this.keyPrefix(clientId)}/token`;\n }\n\n async tokens(): Promise<OAuthTokens | undefined> {\n if (!this._clientId_) {\n return undefined;\n }\n return (\n (await this.storage.get<OAuthTokens>(this.tokenKey(this.clientId))) ??\n undefined\n );\n }\n\n async saveTokens(tokens: OAuthTokens): Promise<void> {\n await this.storage.put(this.tokenKey(this.clientId), tokens);\n }\n\n get authUrl() {\n return this._authUrl_;\n }\n\n /**\n * Because this operates on the server side (but we need browser auth), we send this url back to the user\n * and require user interact to initiate the redirect flow\n */\n async redirectToAuthorization(authUrl: URL): Promise<void> {\n // We want to track the client ID in state here because the typescript SSE client sometimes does\n // a dynamic client registration AFTER generating this redirect URL.\n const client_id = authUrl.searchParams.get(\"client_id\");\n if (client_id) {\n authUrl.searchParams.append(\"state\", client_id);\n }\n this._authUrl_ = authUrl.toString();\n }\n\n codeVerifierKey(clientId: string) {\n return `${this.keyPrefix(clientId)}/code_verifier`;\n }\n\n async saveCodeVerifier(verifier: string): Promise<void> {\n await this.storage.put(this.codeVerifierKey(this.clientId), verifier);\n }\n\n async codeVerifier(): Promise<string> {\n const codeVerifier = await this.storage.get<string>(\n this.codeVerifierKey(this.clientId)\n );\n if (!codeVerifier) {\n throw new Error(\"No code verifier found\");\n }\n return codeVerifier;\n }\n}\n"],"mappings":"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","names":[]}