agents 0.0.0-7f84d28 → 0.0.0-8157d08

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 (42) hide show
  1. package/dist/ai-chat-agent.d.ts +5 -4
  2. package/dist/ai-chat-agent.js +64 -26
  3. package/dist/ai-chat-agent.js.map +1 -1
  4. package/dist/ai-react.d.ts +9 -8
  5. package/dist/ai-react.js +27 -27
  6. package/dist/ai-react.js.map +1 -1
  7. package/dist/{chunk-BZXOAZUX.js → chunk-767EASBA.js} +5 -5
  8. package/dist/{chunk-BZXOAZUX.js.map → chunk-767EASBA.js.map} +1 -1
  9. package/dist/{chunk-Y67CHZBI.js → chunk-E3LCYPCB.js} +23 -18
  10. package/dist/chunk-E3LCYPCB.js.map +1 -0
  11. package/dist/{chunk-RIYR6FR6.js → chunk-JFRK72K3.js} +212 -79
  12. package/dist/chunk-JFRK72K3.js.map +1 -0
  13. package/dist/{chunk-QSGN3REV.js → chunk-NKZZ66QY.js} +8 -15
  14. package/dist/chunk-NKZZ66QY.js.map +1 -0
  15. package/dist/client.d.ts +6 -0
  16. package/dist/client.js +1 -1
  17. package/dist/index-CITGJflw.d.ts +486 -0
  18. package/dist/index.d.ts +25 -394
  19. package/dist/index.js +4 -4
  20. package/dist/mcp/client.d.ts +281 -9
  21. package/dist/mcp/client.js +1 -1
  22. package/dist/mcp/do-oauth-client-provider.js +1 -1
  23. package/dist/mcp/index.d.ts +6 -6
  24. package/dist/mcp/index.js +53 -49
  25. package/dist/mcp/index.js.map +1 -1
  26. package/dist/observability/index.d.ts +12 -0
  27. package/dist/observability/index.js +10 -0
  28. package/dist/observability/index.js.map +1 -0
  29. package/dist/react.d.ts +76 -10
  30. package/dist/react.js +16 -6
  31. package/dist/react.js.map +1 -1
  32. package/dist/schedule.d.ts +6 -6
  33. package/dist/schedule.js +4 -4
  34. package/dist/schedule.js.map +1 -1
  35. package/dist/serializable.d.ts +32 -0
  36. package/dist/serializable.js +1 -0
  37. package/dist/serializable.js.map +1 -0
  38. package/package.json +75 -71
  39. package/src/index.ts +215 -93
  40. package/dist/chunk-QSGN3REV.js.map +0 -1
  41. package/dist/chunk-RIYR6FR6.js.map +0 -1
  42. package/dist/chunk-Y67CHZBI.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/mcp/client.ts","../src/mcp/client-connection.ts","../src/mcp/sse-edge.ts"],"sourcesContent":["import type { Client } from \"@modelcontextprotocol/sdk/client/index.js\";\nimport type { SSEClientTransportOptions } from \"@modelcontextprotocol/sdk/client/sse.js\";\nimport type { RequestOptions } from \"@modelcontextprotocol/sdk/shared/protocol.js\";\nimport type {\n CallToolRequest,\n CallToolResultSchema,\n CompatibilityCallToolResultSchema,\n GetPromptRequest,\n Prompt,\n ReadResourceRequest,\n Resource,\n ResourceTemplate,\n Tool,\n} from \"@modelcontextprotocol/sdk/types.js\";\nimport { jsonSchema, type ToolSet } from \"ai\";\nimport { nanoid } from \"nanoid\";\nimport { MCPClientConnection } from \"./client-connection\";\nimport type { AgentsOAuthProvider } from \"./do-oauth-client-provider\";\n\n/**\n * Utility class that aggregates multiple MCP clients into one\n */\nexport class MCPClientManager {\n public mcpConnections: Record<string, MCPClientConnection> = {};\n private _callbackUrls: string[] = [];\n\n /**\n * @param _name Name of the MCP client\n * @param _version Version of the MCP Client\n * @param auth Auth paramters if being used to create a DurableObjectOAuthClientProvider\n */\n constructor(\n private _name: string,\n private _version: string\n ) {}\n\n /**\n * Connect to and register an MCP server\n *\n * @param transportConfig Transport config\n * @param clientConfig Client config\n * @param capabilities Client capabilities (i.e. if the client supports roots/sampling)\n */\n async connect(\n url: string,\n options: {\n // Allows you to reconnect to a server (in the case of an auth reconnect)\n reconnect?: {\n // server id\n id: string;\n oauthClientId?: string;\n oauthCode?: string;\n };\n // we're overriding authProvider here because we want to be able to access the auth URL\n transport?: SSEClientTransportOptions & {\n authProvider?: AgentsOAuthProvider;\n };\n client?: ConstructorParameters<typeof Client>[1];\n } = {}\n ): Promise<{\n id: string;\n authUrl?: string;\n clientId?: string;\n }> {\n const id = options.reconnect?.id ?? nanoid(8);\n\n if (!options.transport?.authProvider) {\n console.warn(\n \"No authProvider provided in the transport options. This client will only support unauthenticated remote MCP Servers\"\n );\n } else {\n options.transport.authProvider.serverId = id;\n // reconnect with auth\n if (options.reconnect?.oauthClientId) {\n options.transport.authProvider.clientId =\n options.reconnect?.oauthClientId;\n }\n }\n\n this.mcpConnections[id] = new MCPClientConnection(\n new URL(url),\n {\n name: this._name,\n version: this._version,\n },\n {\n client: options.client ?? {},\n transport: options.transport ?? {},\n }\n );\n\n await this.mcpConnections[id].init(options.reconnect?.oauthCode);\n\n const authUrl = options.transport?.authProvider?.authUrl;\n if (authUrl && options.transport?.authProvider?.redirectUrl) {\n this._callbackUrls.push(\n options.transport.authProvider.redirectUrl.toString()\n );\n return {\n authUrl,\n clientId: options.transport?.authProvider?.clientId,\n id,\n };\n }\n\n return {\n id,\n };\n }\n\n isCallbackRequest(req: Request): boolean {\n return (\n req.method === \"GET\" &&\n !!this._callbackUrls.find((url) => {\n return req.url.startsWith(url);\n })\n );\n }\n\n async handleCallbackRequest(req: Request) {\n const url = new URL(req.url);\n const urlMatch = this._callbackUrls.find((url) => {\n return req.url.startsWith(url);\n });\n if (!urlMatch) {\n throw new Error(\n `No callback URI match found for the request url: ${req.url}. Was the request matched with \\`isCallbackRequest()\\`?`\n );\n }\n const code = url.searchParams.get(\"code\");\n const clientId = url.searchParams.get(\"state\");\n const urlParams = urlMatch.split(\"/\");\n const serverId = urlParams[urlParams.length - 1];\n if (!code) {\n throw new Error(\"Unauthorized: no code provided\");\n }\n if (!clientId) {\n throw new Error(\"Unauthorized: no state provided\");\n }\n\n if (this.mcpConnections[serverId] === undefined) {\n throw new Error(`Could not find serverId: ${serverId}`);\n }\n\n if (this.mcpConnections[serverId].connectionState !== \"authenticating\") {\n throw new Error(\n \"Failed to authenticate: the client isn't in the `authenticating` state\"\n );\n }\n\n const conn = this.mcpConnections[serverId];\n if (!conn.options.transport.authProvider) {\n throw new Error(\n \"Trying to finalize authentication for a server connection without an authProvider\"\n );\n }\n\n conn.options.transport.authProvider.clientId = clientId;\n conn.options.transport.authProvider.serverId = serverId;\n\n // reconnect to server with authorization\n const serverUrl = conn.url.toString();\n await this.connect(serverUrl, {\n reconnect: {\n id: serverId,\n oauthClientId: clientId,\n oauthCode: code,\n },\n ...conn.options,\n });\n\n if (this.mcpConnections[serverId].connectionState === \"authenticating\") {\n throw new Error(\"Failed to authenticate: client failed to initialize\");\n }\n\n return { serverId };\n }\n\n /**\n * @returns namespaced list of tools\n */\n listTools(): NamespacedData[\"tools\"] {\n return getNamespacedData(this.mcpConnections, \"tools\");\n }\n\n /**\n * @returns a set of tools that you can use with the AI SDK\n */\n unstable_getAITools(): ToolSet {\n return Object.fromEntries(\n getNamespacedData(this.mcpConnections, \"tools\").map((tool) => {\n return [\n `${tool.serverId}_${tool.name}`,\n {\n description: tool.description,\n execute: async (args) => {\n const result = await this.callTool({\n arguments: args,\n name: tool.name,\n serverId: tool.serverId,\n });\n if (result.isError) {\n // @ts-expect-error TODO we should fix this\n throw new Error(result.content[0].text);\n }\n return result;\n },\n parameters: jsonSchema(tool.inputSchema),\n },\n ];\n })\n );\n }\n\n /**\n * Closes all connections to MCP servers\n */\n async closeAllConnections() {\n return Promise.all(\n Object.values(this.mcpConnections).map(async (connection) => {\n await connection.client.close();\n })\n );\n }\n\n /**\n * Closes a connection to an MCP server\n * @param id The id of the connection to close\n */\n async closeConnection(id: string) {\n if (!this.mcpConnections[id]) {\n throw new Error(`Connection with id \"${id}\" does not exist.`);\n }\n await this.mcpConnections[id].client.close();\n delete this.mcpConnections[id];\n }\n\n /**\n * @returns namespaced list of prompts\n */\n listPrompts(): NamespacedData[\"prompts\"] {\n return getNamespacedData(this.mcpConnections, \"prompts\");\n }\n\n /**\n * @returns namespaced list of tools\n */\n listResources(): NamespacedData[\"resources\"] {\n return getNamespacedData(this.mcpConnections, \"resources\");\n }\n\n /**\n * @returns namespaced list of resource templates\n */\n listResourceTemplates(): NamespacedData[\"resourceTemplates\"] {\n return getNamespacedData(this.mcpConnections, \"resourceTemplates\");\n }\n\n /**\n * Namespaced version of callTool\n */\n callTool(\n params: CallToolRequest[\"params\"] & { serverId: string },\n resultSchema?:\n | typeof CallToolResultSchema\n | typeof CompatibilityCallToolResultSchema,\n options?: RequestOptions\n ) {\n const unqualifiedName = params.name.replace(`${params.serverId}.`, \"\");\n return this.mcpConnections[params.serverId].client.callTool(\n {\n ...params,\n name: unqualifiedName,\n },\n resultSchema,\n options\n );\n }\n\n /**\n * Namespaced version of readResource\n */\n readResource(\n params: ReadResourceRequest[\"params\"] & { serverId: string },\n options: RequestOptions\n ) {\n return this.mcpConnections[params.serverId].client.readResource(\n params,\n options\n );\n }\n\n /**\n * Namespaced version of getPrompt\n */\n getPrompt(\n params: GetPromptRequest[\"params\"] & { serverId: string },\n options: RequestOptions\n ) {\n return this.mcpConnections[params.serverId].client.getPrompt(\n params,\n options\n );\n }\n}\n\ntype NamespacedData = {\n tools: (Tool & { serverId: string })[];\n prompts: (Prompt & { serverId: string })[];\n resources: (Resource & { serverId: string })[];\n resourceTemplates: (ResourceTemplate & { serverId: string })[];\n};\n\nexport function getNamespacedData<T extends keyof NamespacedData>(\n mcpClients: Record<string, MCPClientConnection>,\n type: T\n): NamespacedData[T] {\n const sets = Object.entries(mcpClients).map(([name, conn]) => {\n return { data: conn[type], name };\n });\n\n const namespacedData = sets.flatMap(({ name: serverId, data }) => {\n return data.map((item) => {\n return {\n ...item,\n // we add a serverId so we can easily pull it out and send the tool call to the right server\n serverId,\n };\n });\n });\n\n return namespacedData as NamespacedData[T]; // Type assertion needed due to TS limitations with conditional return types\n}\n","import { Client } from \"@modelcontextprotocol/sdk/client/index.js\";\nimport type { SSEClientTransportOptions } from \"@modelcontextprotocol/sdk/client/sse.js\";\nimport {\n // type ClientCapabilities,\n type ListPromptsResult,\n type ListResourcesResult,\n type ListResourceTemplatesResult,\n type ListToolsResult,\n // type Notification,\n type Prompt,\n PromptListChangedNotificationSchema,\n type Resource,\n ResourceListChangedNotificationSchema,\n type ResourceTemplate,\n type ServerCapabilities,\n type Tool,\n ToolListChangedNotificationSchema,\n} from \"@modelcontextprotocol/sdk/types.js\";\nimport type { AgentsOAuthProvider } from \"./do-oauth-client-provider\";\nimport { SSEEdgeClientTransport } from \"./sse-edge\";\n\nexport class MCPClientConnection {\n client: Client;\n connectionState:\n | \"authenticating\"\n | \"connecting\"\n | \"ready\"\n | \"discovering\"\n | \"failed\" = \"connecting\";\n instructions?: string;\n tools: Tool[] = [];\n prompts: Prompt[] = [];\n resources: Resource[] = [];\n resourceTemplates: ResourceTemplate[] = [];\n serverCapabilities: ServerCapabilities | undefined;\n\n constructor(\n public url: URL,\n info: ConstructorParameters<typeof Client>[0],\n public options: {\n transport: SSEClientTransportOptions & {\n authProvider?: AgentsOAuthProvider;\n };\n client: ConstructorParameters<typeof Client>[1];\n } = { client: {}, transport: {} }\n ) {\n this.client = new Client(info, options.client);\n }\n\n /**\n * Initialize a client connection\n *\n * @param code Optional OAuth code to initialize the connection with if auth hasn't been initialized\n * @returns\n */\n async init(code?: string) {\n try {\n const transport = new SSEEdgeClientTransport(\n this.url,\n this.options.transport\n );\n\n if (code) {\n await transport.finishAuth(code);\n }\n\n await this.client.connect(transport);\n // biome-ignore lint/suspicious/noExplicitAny: allow for the error check here\n } catch (e: any) {\n if (e.toString().includes(\"Unauthorized\")) {\n // unauthorized, we should wait for the user to authenticate\n this.connectionState = \"authenticating\";\n return;\n }\n this.connectionState = \"failed\";\n throw e;\n }\n\n this.connectionState = \"discovering\";\n\n this.serverCapabilities = await this.client.getServerCapabilities();\n if (!this.serverCapabilities) {\n throw new Error(\"The MCP Server failed to return server capabilities\");\n }\n\n const [instructions, tools, resources, prompts, resourceTemplates] =\n await Promise.all([\n this.client.getInstructions(),\n this.registerTools(),\n this.registerResources(),\n this.registerPrompts(),\n this.registerResourceTemplates(),\n ]);\n\n this.instructions = instructions;\n this.tools = tools;\n this.resources = resources;\n this.prompts = prompts;\n this.resourceTemplates = resourceTemplates;\n\n this.connectionState = \"ready\";\n }\n\n /**\n * Notification handler registration\n */\n async registerTools(): Promise<Tool[]> {\n if (!this.serverCapabilities || !this.serverCapabilities.tools) {\n return [];\n }\n\n if (this.serverCapabilities.tools.listChanged) {\n this.client.setNotificationHandler(\n ToolListChangedNotificationSchema,\n async (_notification) => {\n this.tools = await this.fetchTools();\n }\n );\n }\n\n return this.fetchTools();\n }\n\n async registerResources(): Promise<Resource[]> {\n if (!this.serverCapabilities || !this.serverCapabilities.resources) {\n return [];\n }\n\n if (this.serverCapabilities.resources.listChanged) {\n this.client.setNotificationHandler(\n ResourceListChangedNotificationSchema,\n async (_notification) => {\n this.resources = await this.fetchResources();\n }\n );\n }\n\n return this.fetchResources();\n }\n\n async registerPrompts(): Promise<Prompt[]> {\n if (!this.serverCapabilities || !this.serverCapabilities.prompts) {\n return [];\n }\n\n if (this.serverCapabilities.prompts.listChanged) {\n this.client.setNotificationHandler(\n PromptListChangedNotificationSchema,\n async (_notification) => {\n this.prompts = await this.fetchPrompts();\n }\n );\n }\n\n return this.fetchPrompts();\n }\n\n async registerResourceTemplates(): Promise<ResourceTemplate[]> {\n if (!this.serverCapabilities || !this.serverCapabilities.resources) {\n return [];\n }\n\n return this.fetchResourceTemplates();\n }\n\n async fetchTools() {\n let toolsAgg: Tool[] = [];\n let toolsResult: ListToolsResult = { tools: [] };\n do {\n toolsResult = await this.client\n .listTools({\n cursor: toolsResult.nextCursor,\n })\n .catch(capabilityErrorHandler({ tools: [] }, \"tools/list\"));\n toolsAgg = toolsAgg.concat(toolsResult.tools);\n } while (toolsResult.nextCursor);\n return toolsAgg;\n }\n\n async fetchResources() {\n let resourcesAgg: Resource[] = [];\n let resourcesResult: ListResourcesResult = { resources: [] };\n do {\n resourcesResult = await this.client\n .listResources({\n cursor: resourcesResult.nextCursor,\n })\n .catch(capabilityErrorHandler({ resources: [] }, \"resources/list\"));\n resourcesAgg = resourcesAgg.concat(resourcesResult.resources);\n } while (resourcesResult.nextCursor);\n return resourcesAgg;\n }\n\n async fetchPrompts() {\n let promptsAgg: Prompt[] = [];\n let promptsResult: ListPromptsResult = { prompts: [] };\n do {\n promptsResult = await this.client\n .listPrompts({\n cursor: promptsResult.nextCursor,\n })\n .catch(capabilityErrorHandler({ prompts: [] }, \"prompts/list\"));\n promptsAgg = promptsAgg.concat(promptsResult.prompts);\n } while (promptsResult.nextCursor);\n return promptsAgg;\n }\n\n async fetchResourceTemplates() {\n let templatesAgg: ResourceTemplate[] = [];\n let templatesResult: ListResourceTemplatesResult = {\n resourceTemplates: [],\n };\n do {\n templatesResult = await this.client\n .listResourceTemplates({\n cursor: templatesResult.nextCursor,\n })\n .catch(\n capabilityErrorHandler(\n { resourceTemplates: [] },\n \"resources/templates/list\"\n )\n );\n templatesAgg = templatesAgg.concat(templatesResult.resourceTemplates);\n } while (templatesResult.nextCursor);\n return templatesAgg;\n }\n}\n\nfunction capabilityErrorHandler<T>(empty: T, method: string) {\n return (e: { code: number }) => {\n // server is badly behaved and returning invalid capabilities. This commonly occurs for resource templates\n if (e.code === -32601) {\n console.error(\n `The server advertised support for the capability ${method.split(\"/\")[0]}, but returned \"Method not found\" for '${method}'.`\n );\n return empty;\n }\n throw e;\n };\n}\n","import type { OAuthClientProvider } from \"@modelcontextprotocol/sdk/client/auth.js\";\nimport {\n SSEClientTransport,\n type SSEClientTransportOptions,\n} from \"@modelcontextprotocol/sdk/client/sse.js\";\n\nexport class SSEEdgeClientTransport extends SSEClientTransport {\n private authProvider: OAuthClientProvider | undefined;\n /**\n * Creates a new EdgeSSEClientTransport, which overrides fetch to be compatible with the CF workers environment\n */\n constructor(url: URL, options: SSEClientTransportOptions) {\n const fetchOverride: typeof fetch = async (\n fetchUrl: RequestInfo | URL,\n fetchInit: RequestInit = {}\n ) => {\n // add auth headers\n const headers = await this.authHeaders();\n const workerOptions = {\n ...fetchInit,\n headers: {\n ...options.requestInit?.headers,\n ...fetchInit?.headers,\n ...headers,\n },\n };\n\n // Remove unsupported properties\n delete workerOptions.mode;\n\n // Call the original fetch with fixed options\n return (\n (options.eventSourceInit?.fetch?.(\n fetchUrl as URL | string,\n // @ts-expect-error Expects FetchLikeInit from EventSource but is compatible with RequestInit\n workerOptions\n ) as Promise<Response>) || fetch(fetchUrl, workerOptions)\n );\n };\n\n super(url, {\n ...options,\n eventSourceInit: {\n ...options.eventSourceInit,\n fetch: fetchOverride,\n },\n });\n this.authProvider = options.authProvider;\n }\n\n async authHeaders() {\n if (this.authProvider) {\n const tokens = await this.authProvider.tokens();\n if (tokens) {\n return {\n Authorization: `Bearer ${tokens.access_token}`,\n };\n }\n }\n }\n}\n"],"mappings":";AAcA,SAAS,kBAAgC;AACzC,SAAS,cAAc;;;ACfvB,SAAS,cAAc;AAEvB;AAAA,EAQE;AAAA,EAEA;AAAA,EAIA;AAAA,OACK;;;AChBP;AAAA,EACE;AAAA,OAEK;AAEA,IAAM,yBAAN,cAAqC,mBAAmB;AAAA;AAAA;AAAA;AAAA,EAK7D,YAAY,KAAU,SAAoC;AACxD,UAAM,gBAA8B,OAClC,UACA,YAAyB,CAAC,MACvB;AAEH,YAAM,UAAU,MAAM,KAAK,YAAY;AACvC,YAAM,gBAAgB;AAAA,QACpB,GAAG;AAAA,QACH,SAAS;AAAA,UACP,GAAG,QAAQ,aAAa;AAAA,UACxB,GAAG,WAAW;AAAA,UACd,GAAG;AAAA,QACL;AAAA,MACF;AAGA,aAAO,cAAc;AAGrB,aACG,QAAQ,iBAAiB;AAAA,QACxB;AAAA;AAAA,QAEA;AAAA,MACF,KAA2B,MAAM,UAAU,aAAa;AAAA,IAE5D;AAEA,UAAM,KAAK;AAAA,MACT,GAAG;AAAA,MACH,iBAAiB;AAAA,QACf,GAAG,QAAQ;AAAA,QACX,OAAO;AAAA,MACT;AAAA,IACF,CAAC;AACD,SAAK,eAAe,QAAQ;AAAA,EAC9B;AAAA,EAEA,MAAM,cAAc;AAClB,QAAI,KAAK,cAAc;AACrB,YAAM,SAAS,MAAM,KAAK,aAAa,OAAO;AAC9C,UAAI,QAAQ;AACV,eAAO;AAAA,UACL,eAAe,UAAU,OAAO,YAAY;AAAA,QAC9C;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;;;ADvCO,IAAM,sBAAN,MAA0B;AAAA,EAe/B,YACS,KACP,MACO,UAKH,EAAE,QAAQ,CAAC,GAAG,WAAW,CAAC,EAAE,GAChC;AARO;AAEA;AAhBT,2BAKe;AAEf,iBAAgB,CAAC;AACjB,mBAAoB,CAAC;AACrB,qBAAwB,CAAC;AACzB,6BAAwC,CAAC;AAavC,SAAK,SAAS,IAAI,OAAO,MAAM,QAAQ,MAAM;AAAA,EAC/C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,KAAK,MAAe;AACxB,QAAI;AACF,YAAM,YAAY,IAAI;AAAA,QACpB,KAAK;AAAA,QACL,KAAK,QAAQ;AAAA,MACf;AAEA,UAAI,MAAM;AACR,cAAM,UAAU,WAAW,IAAI;AAAA,MACjC;AAEA,YAAM,KAAK,OAAO,QAAQ,SAAS;AAAA,IAErC,SAAS,GAAQ;AACf,UAAI,EAAE,SAAS,EAAE,SAAS,cAAc,GAAG;AAEzC,aAAK,kBAAkB;AACvB;AAAA,MACF;AACA,WAAK,kBAAkB;AACvB,YAAM;AAAA,IACR;AAEA,SAAK,kBAAkB;AAEvB,SAAK,qBAAqB,MAAM,KAAK,OAAO,sBAAsB;AAClE,QAAI,CAAC,KAAK,oBAAoB;AAC5B,YAAM,IAAI,MAAM,qDAAqD;AAAA,IACvE;AAEA,UAAM,CAAC,cAAc,OAAO,WAAW,SAAS,iBAAiB,IAC/D,MAAM,QAAQ,IAAI;AAAA,MAChB,KAAK,OAAO,gBAAgB;AAAA,MAC5B,KAAK,cAAc;AAAA,MACnB,KAAK,kBAAkB;AAAA,MACvB,KAAK,gBAAgB;AAAA,MACrB,KAAK,0BAA0B;AAAA,IACjC,CAAC;AAEH,SAAK,eAAe;AACpB,SAAK,QAAQ;AACb,SAAK,YAAY;AACjB,SAAK,UAAU;AACf,SAAK,oBAAoB;AAEzB,SAAK,kBAAkB;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,gBAAiC;AACrC,QAAI,CAAC,KAAK,sBAAsB,CAAC,KAAK,mBAAmB,OAAO;AAC9D,aAAO,CAAC;AAAA,IACV;AAEA,QAAI,KAAK,mBAAmB,MAAM,aAAa;AAC7C,WAAK,OAAO;AAAA,QACV;AAAA,QACA,OAAO,kBAAkB;AACvB,eAAK,QAAQ,MAAM,KAAK,WAAW;AAAA,QACrC;AAAA,MACF;AAAA,IACF;AAEA,WAAO,KAAK,WAAW;AAAA,EACzB;AAAA,EAEA,MAAM,oBAAyC;AAC7C,QAAI,CAAC,KAAK,sBAAsB,CAAC,KAAK,mBAAmB,WAAW;AAClE,aAAO,CAAC;AAAA,IACV;AAEA,QAAI,KAAK,mBAAmB,UAAU,aAAa;AACjD,WAAK,OAAO;AAAA,QACV;AAAA,QACA,OAAO,kBAAkB;AACvB,eAAK,YAAY,MAAM,KAAK,eAAe;AAAA,QAC7C;AAAA,MACF;AAAA,IACF;AAEA,WAAO,KAAK,eAAe;AAAA,EAC7B;AAAA,EAEA,MAAM,kBAAqC;AACzC,QAAI,CAAC,KAAK,sBAAsB,CAAC,KAAK,mBAAmB,SAAS;AAChE,aAAO,CAAC;AAAA,IACV;AAEA,QAAI,KAAK,mBAAmB,QAAQ,aAAa;AAC/C,WAAK,OAAO;AAAA,QACV;AAAA,QACA,OAAO,kBAAkB;AACvB,eAAK,UAAU,MAAM,KAAK,aAAa;AAAA,QACzC;AAAA,MACF;AAAA,IACF;AAEA,WAAO,KAAK,aAAa;AAAA,EAC3B;AAAA,EAEA,MAAM,4BAAyD;AAC7D,QAAI,CAAC,KAAK,sBAAsB,CAAC,KAAK,mBAAmB,WAAW;AAClE,aAAO,CAAC;AAAA,IACV;AAEA,WAAO,KAAK,uBAAuB;AAAA,EACrC;AAAA,EAEA,MAAM,aAAa;AACjB,QAAI,WAAmB,CAAC;AACxB,QAAI,cAA+B,EAAE,OAAO,CAAC,EAAE;AAC/C,OAAG;AACD,oBAAc,MAAM,KAAK,OACtB,UAAU;AAAA,QACT,QAAQ,YAAY;AAAA,MACtB,CAAC,EACA,MAAM,uBAAuB,EAAE,OAAO,CAAC,EAAE,GAAG,YAAY,CAAC;AAC5D,iBAAW,SAAS,OAAO,YAAY,KAAK;AAAA,IAC9C,SAAS,YAAY;AACrB,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,iBAAiB;AACrB,QAAI,eAA2B,CAAC;AAChC,QAAI,kBAAuC,EAAE,WAAW,CAAC,EAAE;AAC3D,OAAG;AACD,wBAAkB,MAAM,KAAK,OAC1B,cAAc;AAAA,QACb,QAAQ,gBAAgB;AAAA,MAC1B,CAAC,EACA,MAAM,uBAAuB,EAAE,WAAW,CAAC,EAAE,GAAG,gBAAgB,CAAC;AACpE,qBAAe,aAAa,OAAO,gBAAgB,SAAS;AAAA,IAC9D,SAAS,gBAAgB;AACzB,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,eAAe;AACnB,QAAI,aAAuB,CAAC;AAC5B,QAAI,gBAAmC,EAAE,SAAS,CAAC,EAAE;AACrD,OAAG;AACD,sBAAgB,MAAM,KAAK,OACxB,YAAY;AAAA,QACX,QAAQ,cAAc;AAAA,MACxB,CAAC,EACA,MAAM,uBAAuB,EAAE,SAAS,CAAC,EAAE,GAAG,cAAc,CAAC;AAChE,mBAAa,WAAW,OAAO,cAAc,OAAO;AAAA,IACtD,SAAS,cAAc;AACvB,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,yBAAyB;AAC7B,QAAI,eAAmC,CAAC;AACxC,QAAI,kBAA+C;AAAA,MACjD,mBAAmB,CAAC;AAAA,IACtB;AACA,OAAG;AACD,wBAAkB,MAAM,KAAK,OAC1B,sBAAsB;AAAA,QACrB,QAAQ,gBAAgB;AAAA,MAC1B,CAAC,EACA;AAAA,QACC;AAAA,UACE,EAAE,mBAAmB,CAAC,EAAE;AAAA,UACxB;AAAA,QACF;AAAA,MACF;AACF,qBAAe,aAAa,OAAO,gBAAgB,iBAAiB;AAAA,IACtE,SAAS,gBAAgB;AACzB,WAAO;AAAA,EACT;AACF;AAEA,SAAS,uBAA0B,OAAU,QAAgB;AAC3D,SAAO,CAAC,MAAwB;AAE9B,QAAI,EAAE,SAAS,QAAQ;AACrB,cAAQ;AAAA,QACN,oDAAoD,OAAO,MAAM,GAAG,EAAE,CAAC,CAAC,0CAA0C,MAAM;AAAA,MAC1H;AACA,aAAO;AAAA,IACT;AACA,UAAM;AAAA,EACR;AACF;;;AD1NO,IAAM,mBAAN,MAAuB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAS5B,YACU,OACA,UACR;AAFQ;AACA;AAVV,SAAO,iBAAsD,CAAC;AAC9D,SAAQ,gBAA0B,CAAC;AAAA,EAUhC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASH,MAAM,QACJ,KACA,UAaI,CAAC,GAKJ;AACD,UAAM,KAAK,QAAQ,WAAW,MAAM,OAAO,CAAC;AAE5C,QAAI,CAAC,QAAQ,WAAW,cAAc;AACpC,cAAQ;AAAA,QACN;AAAA,MACF;AAAA,IACF,OAAO;AACL,cAAQ,UAAU,aAAa,WAAW;AAE1C,UAAI,QAAQ,WAAW,eAAe;AACpC,gBAAQ,UAAU,aAAa,WAC7B,QAAQ,WAAW;AAAA,MACvB;AAAA,IACF;AAEA,SAAK,eAAe,EAAE,IAAI,IAAI;AAAA,MAC5B,IAAI,IAAI,GAAG;AAAA,MACX;AAAA,QACE,MAAM,KAAK;AAAA,QACX,SAAS,KAAK;AAAA,MAChB;AAAA,MACA;AAAA,QACE,QAAQ,QAAQ,UAAU,CAAC;AAAA,QAC3B,WAAW,QAAQ,aAAa,CAAC;AAAA,MACnC;AAAA,IACF;AAEA,UAAM,KAAK,eAAe,EAAE,EAAE,KAAK,QAAQ,WAAW,SAAS;AAE/D,UAAM,UAAU,QAAQ,WAAW,cAAc;AACjD,QAAI,WAAW,QAAQ,WAAW,cAAc,aAAa;AAC3D,WAAK,cAAc;AAAA,QACjB,QAAQ,UAAU,aAAa,YAAY,SAAS;AAAA,MACtD;AACA,aAAO;AAAA,QACL;AAAA,QACA,UAAU,QAAQ,WAAW,cAAc;AAAA,QAC3C;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,MACL;AAAA,IACF;AAAA,EACF;AAAA,EAEA,kBAAkB,KAAuB;AACvC,WACE,IAAI,WAAW,SACf,CAAC,CAAC,KAAK,cAAc,KAAK,CAAC,QAAQ;AACjC,aAAO,IAAI,IAAI,WAAW,GAAG;AAAA,IAC/B,CAAC;AAAA,EAEL;AAAA,EAEA,MAAM,sBAAsB,KAAc;AACxC,UAAM,MAAM,IAAI,IAAI,IAAI,GAAG;AAC3B,UAAM,WAAW,KAAK,cAAc,KAAK,CAACA,SAAQ;AAChD,aAAO,IAAI,IAAI,WAAWA,IAAG;AAAA,IAC/B,CAAC;AACD,QAAI,CAAC,UAAU;AACb,YAAM,IAAI;AAAA,QACR,oDAAoD,IAAI,GAAG;AAAA,MAC7D;AAAA,IACF;AACA,UAAM,OAAO,IAAI,aAAa,IAAI,MAAM;AACxC,UAAM,WAAW,IAAI,aAAa,IAAI,OAAO;AAC7C,UAAM,YAAY,SAAS,MAAM,GAAG;AACpC,UAAM,WAAW,UAAU,UAAU,SAAS,CAAC;AAC/C,QAAI,CAAC,MAAM;AACT,YAAM,IAAI,MAAM,gCAAgC;AAAA,IAClD;AACA,QAAI,CAAC,UAAU;AACb,YAAM,IAAI,MAAM,iCAAiC;AAAA,IACnD;AAEA,QAAI,KAAK,eAAe,QAAQ,MAAM,QAAW;AAC/C,YAAM,IAAI,MAAM,4BAA4B,QAAQ,EAAE;AAAA,IACxD;AAEA,QAAI,KAAK,eAAe,QAAQ,EAAE,oBAAoB,kBAAkB;AACtE,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAEA,UAAM,OAAO,KAAK,eAAe,QAAQ;AACzC,QAAI,CAAC,KAAK,QAAQ,UAAU,cAAc;AACxC,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAEA,SAAK,QAAQ,UAAU,aAAa,WAAW;AAC/C,SAAK,QAAQ,UAAU,aAAa,WAAW;AAG/C,UAAM,YAAY,KAAK,IAAI,SAAS;AACpC,UAAM,KAAK,QAAQ,WAAW;AAAA,MAC5B,WAAW;AAAA,QACT,IAAI;AAAA,QACJ,eAAe;AAAA,QACf,WAAW;AAAA,MACb;AAAA,MACA,GAAG,KAAK;AAAA,IACV,CAAC;AAED,QAAI,KAAK,eAAe,QAAQ,EAAE,oBAAoB,kBAAkB;AACtE,YAAM,IAAI,MAAM,qDAAqD;AAAA,IACvE;AAEA,WAAO,EAAE,SAAS;AAAA,EACpB;AAAA;AAAA;AAAA;AAAA,EAKA,YAAqC;AACnC,WAAO,kBAAkB,KAAK,gBAAgB,OAAO;AAAA,EACvD;AAAA;AAAA;AAAA;AAAA,EAKA,sBAA+B;AAC7B,WAAO,OAAO;AAAA,MACZ,kBAAkB,KAAK,gBAAgB,OAAO,EAAE,IAAI,CAAC,SAAS;AAC5D,eAAO;AAAA,UACL,GAAG,KAAK,QAAQ,IAAI,KAAK,IAAI;AAAA,UAC7B;AAAA,YACE,aAAa,KAAK;AAAA,YAClB,SAAS,OAAO,SAAS;AACvB,oBAAM,SAAS,MAAM,KAAK,SAAS;AAAA,gBACjC,WAAW;AAAA,gBACX,MAAM,KAAK;AAAA,gBACX,UAAU,KAAK;AAAA,cACjB,CAAC;AACD,kBAAI,OAAO,SAAS;AAElB,sBAAM,IAAI,MAAM,OAAO,QAAQ,CAAC,EAAE,IAAI;AAAA,cACxC;AACA,qBAAO;AAAA,YACT;AAAA,YACA,YAAY,WAAW,KAAK,WAAW;AAAA,UACzC;AAAA,QACF;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,sBAAsB;AAC1B,WAAO,QAAQ;AAAA,MACb,OAAO,OAAO,KAAK,cAAc,EAAE,IAAI,OAAO,eAAe;AAC3D,cAAM,WAAW,OAAO,MAAM;AAAA,MAChC,CAAC;AAAA,IACH;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,gBAAgB,IAAY;AAChC,QAAI,CAAC,KAAK,eAAe,EAAE,GAAG;AAC5B,YAAM,IAAI,MAAM,uBAAuB,EAAE,mBAAmB;AAAA,IAC9D;AACA,UAAM,KAAK,eAAe,EAAE,EAAE,OAAO,MAAM;AAC3C,WAAO,KAAK,eAAe,EAAE;AAAA,EAC/B;AAAA;AAAA;AAAA;AAAA,EAKA,cAAyC;AACvC,WAAO,kBAAkB,KAAK,gBAAgB,SAAS;AAAA,EACzD;AAAA;AAAA;AAAA;AAAA,EAKA,gBAA6C;AAC3C,WAAO,kBAAkB,KAAK,gBAAgB,WAAW;AAAA,EAC3D;AAAA;AAAA;AAAA;AAAA,EAKA,wBAA6D;AAC3D,WAAO,kBAAkB,KAAK,gBAAgB,mBAAmB;AAAA,EACnE;AAAA;AAAA;AAAA;AAAA,EAKA,SACE,QACA,cAGA,SACA;AACA,UAAM,kBAAkB,OAAO,KAAK,QAAQ,GAAG,OAAO,QAAQ,KAAK,EAAE;AACrE,WAAO,KAAK,eAAe,OAAO,QAAQ,EAAE,OAAO;AAAA,MACjD;AAAA,QACE,GAAG;AAAA,QACH,MAAM;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,aACE,QACA,SACA;AACA,WAAO,KAAK,eAAe,OAAO,QAAQ,EAAE,OAAO;AAAA,MACjD;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,UACE,QACA,SACA;AACA,WAAO,KAAK,eAAe,OAAO,QAAQ,EAAE,OAAO;AAAA,MACjD;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;AASO,SAAS,kBACd,YACA,MACmB;AACnB,QAAM,OAAO,OAAO,QAAQ,UAAU,EAAE,IAAI,CAAC,CAAC,MAAM,IAAI,MAAM;AAC5D,WAAO,EAAE,MAAM,KAAK,IAAI,GAAG,KAAK;AAAA,EAClC,CAAC;AAED,QAAM,iBAAiB,KAAK,QAAQ,CAAC,EAAE,MAAM,UAAU,KAAK,MAAM;AAChE,WAAO,KAAK,IAAI,CAAC,SAAS;AACxB,aAAO;AAAA,QACL,GAAG;AAAA;AAAA,QAEH;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH,CAAC;AAED,SAAO;AACT;","names":["url"]}
@@ -1,22 +1,22 @@
1
+ import {
2
+ MCPClientManager
3
+ } from "./chunk-E3LCYPCB.js";
1
4
  import {
2
5
  DurableObjectOAuthClientProvider
3
- } from "./chunk-BZXOAZUX.js";
6
+ } from "./chunk-767EASBA.js";
4
7
  import {
5
8
  camelCaseToKebabCase
6
- } from "./chunk-QSGN3REV.js";
7
- import {
8
- MCPClientManager
9
- } from "./chunk-Y67CHZBI.js";
9
+ } from "./chunk-NKZZ66QY.js";
10
10
 
11
11
  // src/index.ts
12
+ import { AsyncLocalStorage } from "async_hooks";
13
+ import { parseCronExpression } from "cron-schedule";
14
+ import { nanoid } from "nanoid";
12
15
  import {
13
- Server,
16
+ getServerByName,
14
17
  routePartykitRequest,
15
- getServerByName
18
+ Server
16
19
  } from "partyserver";
17
- import { parseCronExpression } from "cron-schedule";
18
- import { nanoid } from "nanoid";
19
- import { AsyncLocalStorage } from "node:async_hooks";
20
20
  function isRPCRequest(msg) {
21
21
  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);
22
22
  }
@@ -62,6 +62,10 @@ var Agent = class extends Server {
62
62
  * Override to provide default state values
63
63
  */
64
64
  this.initialState = DEFAULT_STATE;
65
+ /**
66
+ * The observability implementation to use for the Agent
67
+ */
68
+ this.observability = genericObservability;
65
69
  /**
66
70
  * Method called when an alarm fires.
67
71
  * Executes any scheduled tasks that are due.
@@ -85,6 +89,16 @@ var Agent = class extends Server {
85
89
  { agent: this, connection: void 0, request: void 0 },
86
90
  async () => {
87
91
  try {
92
+ this.observability?.emit(
93
+ {
94
+ displayMessage: `Schedule ${row.id} executed`,
95
+ id: nanoid(),
96
+ payload: row,
97
+ timestamp: Date.now(),
98
+ type: "schedule:execute"
99
+ },
100
+ this.ctx
101
+ );
88
102
  await callback.bind(this)(JSON.parse(row.payload), row);
89
103
  } catch (e) {
90
104
  console.error(`error executing callback "${row.callback}"`, e);
@@ -148,13 +162,13 @@ var Agent = class extends Server {
148
162
  await this.mcp.handleCallbackRequest(request);
149
163
  this.broadcast(
150
164
  JSON.stringify({
151
- type: "cf_agent_mcp_servers",
152
- mcp: this._getMcpServerStateInternal()
165
+ mcp: this.getMcpServers(),
166
+ type: "cf_agent_mcp_servers"
153
167
  })
154
168
  );
155
169
  return new Response("<script>window.close();</script>", {
156
- status: 200,
157
- headers: { "content-type": "text/html" }
170
+ headers: { "content-type": "text/html" },
171
+ status: 200
158
172
  });
159
173
  }
160
174
  return this._tryCatch(() => _onRequest(request));
@@ -172,7 +186,7 @@ var Agent = class extends Server {
172
186
  let parsed;
173
187
  try {
174
188
  parsed = JSON.parse(message);
175
- } catch (e) {
189
+ } catch (_e) {
176
190
  return this._tryCatch(() => _onMessage(connection, message));
177
191
  }
178
192
  if (isStateUpdateMessage(parsed)) {
@@ -196,20 +210,35 @@ var Agent = class extends Server {
196
210
  return;
197
211
  }
198
212
  const result = await methodFn.apply(this, args);
213
+ this.observability?.emit(
214
+ {
215
+ displayMessage: `RPC call to ${method}`,
216
+ id: nanoid(),
217
+ payload: {
218
+ args,
219
+ method,
220
+ streaming: metadata?.streaming,
221
+ success: true
222
+ },
223
+ timestamp: Date.now(),
224
+ type: "rpc"
225
+ },
226
+ this.ctx
227
+ );
199
228
  const response = {
200
- type: "rpc",
229
+ done: true,
201
230
  id,
202
- success: true,
203
231
  result,
204
- done: true
232
+ success: true,
233
+ type: "rpc"
205
234
  };
206
235
  connection.send(JSON.stringify(response));
207
236
  } catch (e) {
208
237
  const response = {
209
- type: "rpc",
238
+ error: e instanceof Error ? e.message : "Unknown error occurred",
210
239
  id: parsed.id,
211
240
  success: false,
212
- error: e instanceof Error ? e.message : "Unknown error occurred"
241
+ type: "rpc"
213
242
  };
214
243
  connection.send(JSON.stringify(response));
215
244
  console.error("RPC error:", e);
@@ -229,17 +258,29 @@ var Agent = class extends Server {
229
258
  if (this.state) {
230
259
  connection.send(
231
260
  JSON.stringify({
232
- type: "cf_agent_state",
233
- state: this.state
261
+ state: this.state,
262
+ type: "cf_agent_state"
234
263
  })
235
264
  );
236
265
  }
237
266
  connection.send(
238
267
  JSON.stringify({
239
- type: "cf_agent_mcp_servers",
240
- mcp: this._getMcpServerStateInternal()
268
+ mcp: this.getMcpServers(),
269
+ type: "cf_agent_mcp_servers"
241
270
  })
242
271
  );
272
+ this.observability?.emit(
273
+ {
274
+ displayMessage: "Connection established",
275
+ id: nanoid(),
276
+ payload: {
277
+ connectionId: connection.id
278
+ },
279
+ timestamp: Date.now(),
280
+ type: "connect"
281
+ },
282
+ this.ctx
283
+ );
243
284
  return this._tryCatch(() => _onConnect(connection, ctx2));
244
285
  }, 20);
245
286
  }
@@ -253,7 +294,7 @@ var Agent = class extends Server {
253
294
  const servers = this.sql`
254
295
  SELECT id, name, server_url, client_id, auth_url, callback_url, server_options FROM cf_agents_mcp_servers;
255
296
  `;
256
- await Promise.allSettled(
297
+ Promise.allSettled(
257
298
  servers.map((server) => {
258
299
  return this._connectToMcpServerInternal(
259
300
  server.name,
@@ -266,13 +307,14 @@ var Agent = class extends Server {
266
307
  }
267
308
  );
268
309
  })
269
- );
270
- this.broadcast(
271
- JSON.stringify({
272
- type: "cf_agent_mcp_servers",
273
- mcp: this._getMcpServerStateInternal()
274
- })
275
- );
310
+ ).then((_results) => {
311
+ this.broadcast(
312
+ JSON.stringify({
313
+ mcp: this.getMcpServers(),
314
+ type: "cf_agent_mcp_servers"
315
+ })
316
+ );
317
+ });
276
318
  await this._tryCatch(() => _onStart());
277
319
  }
278
320
  );
@@ -324,6 +366,7 @@ var Agent = class extends Server {
324
366
  }
325
367
  }
326
368
  _setStateInternal(state, source = "server") {
369
+ const previousState = this._state;
327
370
  this._state = state;
328
371
  this.sql`
329
372
  INSERT OR REPLACE INTO cf_agents_state (id, state)
@@ -335,8 +378,8 @@ var Agent = class extends Server {
335
378
  `;
336
379
  this.broadcast(
337
380
  JSON.stringify({
338
- type: "cf_agent_state",
339
- state
381
+ state,
382
+ type: "cf_agent_state"
340
383
  }),
341
384
  source !== "server" ? [source.id] : []
342
385
  );
@@ -345,6 +388,19 @@ var Agent = class extends Server {
345
388
  return agentContext.run(
346
389
  { agent: this, connection, request },
347
390
  async () => {
391
+ this.observability?.emit(
392
+ {
393
+ displayMessage: "State updated",
394
+ id: nanoid(),
395
+ payload: {
396
+ previousState,
397
+ state
398
+ },
399
+ timestamp: Date.now(),
400
+ type: "state:update"
401
+ },
402
+ this.ctx
403
+ );
348
404
  return this.onStateUpdate(state, source);
349
405
  }
350
406
  );
@@ -362,12 +418,14 @@ var Agent = class extends Server {
362
418
  * @param state Updated state
363
419
  * @param source Source of the state update ("server" or a client connection)
364
420
  */
421
+ // biome-ignore lint/correctness/noUnusedFunctionParameters: overridden later
365
422
  onStateUpdate(state, source) {
366
423
  }
367
424
  /**
368
425
  * Called when the Agent receives an email
369
426
  * @param email Email message to process
370
427
  */
428
+ // biome-ignore lint/correctness/noUnusedFunctionParameters: overridden later
371
429
  onEmail(email) {
372
430
  return agentContext.run(
373
431
  { agent: this, connection: void 0, request: void 0 },
@@ -418,6 +476,16 @@ var Agent = class extends Server {
418
476
  */
419
477
  async schedule(when, callback, payload) {
420
478
  const id = nanoid(9);
479
+ const emitScheduleCreate = (schedule) => this.observability?.emit(
480
+ {
481
+ displayMessage: `Schedule ${schedule.id} created`,
482
+ id: nanoid(),
483
+ payload: schedule,
484
+ timestamp: Date.now(),
485
+ type: "schedule:create"
486
+ },
487
+ this.ctx
488
+ );
421
489
  if (typeof callback !== "string") {
422
490
  throw new Error("Callback must be a string");
423
491
  }
@@ -433,13 +501,15 @@ var Agent = class extends Server {
433
501
  )}, 'scheduled', ${timestamp})
434
502
  `;
435
503
  await this._scheduleNextAlarm();
436
- return {
437
- id,
504
+ const schedule = {
438
505
  callback,
506
+ id,
439
507
  payload,
440
508
  time: timestamp,
441
509
  type: "scheduled"
442
510
  };
511
+ emitScheduleCreate(schedule);
512
+ return schedule;
443
513
  }
444
514
  if (typeof when === "number") {
445
515
  const time = new Date(Date.now() + when * 1e3);
@@ -451,14 +521,16 @@ var Agent = class extends Server {
451
521
  )}, 'delayed', ${when}, ${timestamp})
452
522
  `;
453
523
  await this._scheduleNextAlarm();
454
- return {
455
- id,
524
+ const schedule = {
456
525
  callback,
457
- payload,
458
526
  delayInSeconds: when,
527
+ id,
528
+ payload,
459
529
  time: timestamp,
460
530
  type: "delayed"
461
531
  };
532
+ emitScheduleCreate(schedule);
533
+ return schedule;
462
534
  }
463
535
  if (typeof when === "string") {
464
536
  const nextExecutionTime = getNextCronTime(when);
@@ -470,14 +542,16 @@ var Agent = class extends Server {
470
542
  )}, 'cron', ${when}, ${timestamp})
471
543
  `;
472
544
  await this._scheduleNextAlarm();
473
- return {
474
- id,
545
+ const schedule = {
475
546
  callback,
476
- payload,
477
547
  cron: when,
548
+ id,
549
+ payload,
478
550
  time: timestamp,
479
551
  type: "cron"
480
552
  };
553
+ emitScheduleCreate(schedule);
554
+ return schedule;
481
555
  }
482
556
  throw new Error("Invalid schedule type");
483
557
  }
@@ -535,6 +609,19 @@ var Agent = class extends Server {
535
609
  * @returns true if the task was cancelled, false otherwise
536
610
  */
537
611
  async cancelSchedule(id) {
612
+ const schedule = await this.getSchedule(id);
613
+ if (schedule) {
614
+ this.observability?.emit(
615
+ {
616
+ displayMessage: `Schedule ${id} cancelled`,
617
+ id: nanoid(),
618
+ payload: schedule,
619
+ timestamp: Date.now(),
620
+ type: "schedule:cancel"
621
+ },
622
+ this.ctx
623
+ );
624
+ }
538
625
  this.sql`DELETE FROM cf_agents_schedules WHERE id = ${id}`;
539
626
  await this._scheduleNextAlarm();
540
627
  return true;
@@ -561,7 +648,22 @@ var Agent = class extends Server {
561
648
  this.sql`DROP TABLE IF EXISTS cf_agents_mcp_servers`;
562
649
  await this.ctx.storage.deleteAlarm();
563
650
  await this.ctx.storage.deleteAll();
651
+ this.ctx.abort("destroyed");
652
+ this.observability?.emit(
653
+ {
654
+ displayMessage: "Agent destroyed",
655
+ id: nanoid(),
656
+ payload: {},
657
+ timestamp: Date.now(),
658
+ type: "destroy"
659
+ },
660
+ this.ctx
661
+ );
564
662
  }
663
+ /**
664
+ * Get all methods marked as callable on this Agent
665
+ * @returns A map of method names to their metadata
666
+ */
565
667
  _isCallable(method) {
566
668
  return callableMetadata.has(this[method]);
567
669
  }
@@ -582,15 +684,28 @@ var Agent = class extends Server {
582
684
  callbackUrl,
583
685
  options
584
686
  );
687
+ this.sql`
688
+ INSERT
689
+ OR REPLACE INTO cf_agents_mcp_servers (id, name, server_url, client_id, auth_url, callback_url, server_options)
690
+ VALUES (
691
+ ${result.id},
692
+ ${serverName},
693
+ ${url},
694
+ ${result.clientId ?? null},
695
+ ${result.authUrl ?? null},
696
+ ${callbackUrl},
697
+ ${options ? JSON.stringify(options) : null}
698
+ );
699
+ `;
585
700
  this.broadcast(
586
701
  JSON.stringify({
587
- type: "cf_agent_mcp_servers",
588
- mcp: this._getMcpServerStateInternal()
702
+ mcp: this.getMcpServers(),
703
+ type: "cf_agent_mcp_servers"
589
704
  })
590
705
  );
591
706
  return result;
592
707
  }
593
- async _connectToMcpServerInternal(serverName, url, callbackUrl, options, reconnect) {
708
+ async _connectToMcpServerInternal(_serverName, url, callbackUrl, options, reconnect) {
594
709
  const authProvider = new DurableObjectOAuthClientProvider(
595
710
  this.ctx.storage,
596
711
  this.name,
@@ -617,28 +732,17 @@ var Agent = class extends Server {
617
732
  };
618
733
  }
619
734
  const { id, authUrl, clientId } = await this.mcp.connect(url, {
735
+ client: options?.client,
620
736
  reconnect,
621
737
  transport: {
622
738
  ...headerTransportOpts,
623
739
  authProvider
624
- },
625
- client: options?.client
740
+ }
626
741
  });
627
- this.sql`
628
- INSERT OR REPLACE INTO cf_agents_mcp_servers (id, name, server_url, client_id, auth_url, callback_url, server_options)
629
- VALUES (
630
- ${id},
631
- ${serverName},
632
- ${url},
633
- ${clientId ?? null},
634
- ${authUrl ?? null},
635
- ${callbackUrl},
636
- ${options ? JSON.stringify(options) : null}
637
- );
638
- `;
639
742
  return {
640
- id,
641
- authUrl
743
+ authUrl,
744
+ clientId,
745
+ id
642
746
  };
643
747
  }
644
748
  async removeMcpServer(id) {
@@ -648,27 +752,31 @@ var Agent = class extends Server {
648
752
  `;
649
753
  this.broadcast(
650
754
  JSON.stringify({
651
- type: "cf_agent_mcp_servers",
652
- mcp: this._getMcpServerStateInternal()
755
+ mcp: this.getMcpServers(),
756
+ type: "cf_agent_mcp_servers"
653
757
  })
654
758
  );
655
759
  }
656
- _getMcpServerStateInternal() {
760
+ getMcpServers() {
657
761
  const mcpState = {
658
- servers: {},
659
- tools: this.mcp.listTools(),
660
762
  prompts: this.mcp.listPrompts(),
661
- resources: this.mcp.listResources()
763
+ resources: this.mcp.listResources(),
764
+ servers: {},
765
+ tools: this.mcp.listTools()
662
766
  };
663
767
  const servers = this.sql`
664
768
  SELECT id, name, server_url, client_id, auth_url, callback_url, server_options FROM cf_agents_mcp_servers;
665
769
  `;
666
770
  for (const server of servers) {
771
+ const serverConn = this.mcp.mcpConnections[server.id];
667
772
  mcpState.servers[server.id] = {
773
+ auth_url: server.auth_url,
774
+ capabilities: serverConn?.serverCapabilities ?? null,
775
+ instructions: serverConn?.instructions ?? null,
668
776
  name: server.name,
669
777
  server_url: server.server_url,
670
- auth_url: server.auth_url,
671
- state: this.mcp.mcpConnections[server.id].connectionState
778
+ // mark as "authenticating" because the server isn't automatically connected, so it's pending authenticating
779
+ state: serverConn?.connectionState ?? "authenticating"
672
780
  };
673
781
  }
674
782
  return mcpState;
@@ -684,9 +792,9 @@ Agent.options = {
684
792
  };
685
793
  async function routeAgentRequest(request, env, options) {
686
794
  const corsHeaders = options?.cors === true ? {
687
- "Access-Control-Allow-Origin": "*",
688
- "Access-Control-Allow-Methods": "GET, POST, HEAD, OPTIONS",
689
795
  "Access-Control-Allow-Credentials": "true",
796
+ "Access-Control-Allow-Methods": "GET, POST, HEAD, OPTIONS",
797
+ "Access-Control-Allow-Origin": "*",
690
798
  "Access-Control-Max-Age": "86400"
691
799
  } : options?.cors;
692
800
  if (request.method === "OPTIONS") {
@@ -717,7 +825,7 @@ async function routeAgentRequest(request, env, options) {
717
825
  }
718
826
  return response;
719
827
  }
720
- async function routeAgentEmail(email, env, options) {
828
+ async function routeAgentEmail(_email, _env, _options) {
721
829
  }
722
830
  async function getAgentByName(namespace, name, options) {
723
831
  return getServerByName(namespace, name, options);
@@ -737,11 +845,11 @@ var StreamingResponse = class {
737
845
  throw new Error("StreamingResponse is already closed");
738
846
  }
739
847
  const response = {
740
- type: "rpc",
848
+ done: false,
741
849
  id: this._id,
742
- success: true,
743
850
  result: chunk,
744
- done: false
851
+ success: true,
852
+ type: "rpc"
745
853
  };
746
854
  this._connection.send(JSON.stringify(response));
747
855
  }
@@ -755,17 +863,42 @@ var StreamingResponse = class {
755
863
  }
756
864
  this._closed = true;
757
865
  const response = {
758
- type: "rpc",
866
+ done: true,
759
867
  id: this._id,
760
- success: true,
761
868
  result: finalChunk,
762
- done: true
869
+ success: true,
870
+ type: "rpc"
763
871
  };
764
872
  this._connection.send(JSON.stringify(response));
765
873
  }
766
874
  };
767
875
 
876
+ // src/observability/index.ts
877
+ var genericObservability = {
878
+ emit(event) {
879
+ if (isLocalMode()) {
880
+ console.log(event.displayMessage);
881
+ return;
882
+ }
883
+ console.log(event);
884
+ }
885
+ };
886
+ var localMode = false;
887
+ function isLocalMode() {
888
+ if (localMode) {
889
+ return true;
890
+ }
891
+ const { request } = getCurrentAgent();
892
+ if (!request) {
893
+ return false;
894
+ }
895
+ const url = new URL(request.url);
896
+ localMode = url.hostname === "localhost";
897
+ return localMode;
898
+ }
899
+
768
900
  export {
901
+ genericObservability,
769
902
  unstable_callable,
770
903
  getCurrentAgent,
771
904
  Agent,
@@ -774,4 +907,4 @@ export {
774
907
  getAgentByName,
775
908
  StreamingResponse
776
909
  };
777
- //# sourceMappingURL=chunk-RIYR6FR6.js.map
910
+ //# sourceMappingURL=chunk-JFRK72K3.js.map