@mastra/hono 1.3.5-alpha.0 → 1.4.0-alpha.2

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/CHANGELOG.md CHANGED
@@ -1,5 +1,28 @@
1
1
  # @mastra/hono
2
2
 
3
+ ## 1.4.0-alpha.2
4
+
5
+ ### Minor Changes
6
+
7
+ - Add browser streaming WebSocket support for Hono server adapter ([#14938](https://github.com/mastra-ai/mastra/pull/14938))
8
+ - New `setupBrowserStream()` function for real-time screencast streaming
9
+ - WebSocket route at `/browser/:agentId/stream` for viewer connections
10
+ - Browser close endpoint at `/api/agents/:agentId/browser/close`
11
+
12
+ ### Patch Changes
13
+
14
+ - Updated dependencies [[`cb15509`](https://github.com/mastra-ai/mastra/commit/cb15509b58f6a83e11b765c945082afc027db972), [`cb15509`](https://github.com/mastra-ai/mastra/commit/cb15509b58f6a83e11b765c945082afc027db972), [`80c5668`](https://github.com/mastra-ai/mastra/commit/80c5668e365470d3a96d3e953868fd7a643ff67c), [`3d478c1`](https://github.com/mastra-ai/mastra/commit/3d478c1e13f17b80f330ac49d7aa42ef929b93ff), [`f03f37a`](https://github.com/mastra-ai/mastra/commit/f03f37a5e5880f2bb2700514405e311f840c53d2), [`eecd0eb`](https://github.com/mastra-ai/mastra/commit/eecd0ebde7b54bbfe32e7ebbf5fe2c59b29dd685), [`6039f17`](https://github.com/mastra-ai/mastra/commit/6039f176f9c457304825ff1df8c83b8e457376c0), [`06b928d`](https://github.com/mastra-ai/mastra/commit/06b928dfc2f5630d023467476cc5919dfa858d0a), [`6a8d984`](https://github.com/mastra-ai/mastra/commit/6a8d9841f2933456ee1598099f488d742b600054)]:
15
+ - @mastra/core@1.22.0-alpha.2
16
+ - @mastra/server@1.22.0-alpha.2
17
+
18
+ ## 1.3.5-alpha.1
19
+
20
+ ### Patch Changes
21
+
22
+ - Updated dependencies [[`81e4259`](https://github.com/mastra-ai/mastra/commit/81e425939b4ceeb4f586e9b6d89c3b1c1f2d2fe7), [`951b8a1`](https://github.com/mastra-ai/mastra/commit/951b8a1b5ef7e1474c59dc4f2b9fc1a8b1e508b6)]:
23
+ - @mastra/core@1.22.0-alpha.1
24
+ - @mastra/server@1.22.0-alpha.1
25
+
3
26
  ## 1.3.5-alpha.0
4
27
 
5
28
  ### Patch Changes
@@ -0,0 +1,35 @@
1
+ import type { BrowserStreamConfig, BrowserStreamResult } from '@mastra/server/browser-stream';
2
+ import type { Env, Hono, Schema } from 'hono';
3
+ /**
4
+ * Set up WebSocket-based browser stream endpoint for real-time screencast viewing.
5
+ *
6
+ * Creates a WebSocket route at `/browser/:agentId/stream` that:
7
+ * - Accepts viewer connections
8
+ * - Starts screencast when first viewer connects
9
+ * - Broadcasts frames to all connected viewers
10
+ * - Stops screencast when last viewer disconnects
11
+ *
12
+ * **Note**: Requires `ws` package to be installed. If not available, returns null
13
+ * and logs a warning. Browser streaming will be disabled but everything else works.
14
+ *
15
+ * @param app - The Hono application instance
16
+ * @param config - Configuration for browser stream
17
+ * @returns Object containing injectWebSocket function and registry instance, or null if ws is not available
18
+ *
19
+ * @example
20
+ * ```typescript
21
+ * import { Hono } from 'hono';
22
+ * import { serve } from '@hono/node-server';
23
+ * import { setupBrowserStream } from '@mastra/hono';
24
+ *
25
+ * const app = new Hono();
26
+ * const browserStream = await setupBrowserStream(app, {
27
+ * getToolset: (agentId) => browserToolsets.get(agentId),
28
+ * });
29
+ *
30
+ * const server = serve({ fetch: app.fetch, port: 4111 });
31
+ * browserStream?.injectWebSocket(server);
32
+ * ```
33
+ */
34
+ export declare function setupBrowserStream<E extends Env, S extends Schema, B extends string>(app: Hono<E, S, B>, config: BrowserStreamConfig): Promise<BrowserStreamResult | null>;
35
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/browser-stream/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AAC9F,OAAO,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAE9C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAsB,kBAAkB,CAAC,CAAC,SAAS,GAAG,EAAE,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,MAAM,EACxF,GAAG,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAClB,MAAM,EAAE,mBAAmB,GAC1B,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAAC,CA0GrC"}
package/dist/index.cjs CHANGED
@@ -4,6 +4,7 @@ var serverAdapter = require('@mastra/server/server-adapter');
4
4
  var fetchToNode = require('fetch-to-node');
5
5
  var requestContext = require('@mastra/core/request-context');
6
6
  var auth = require('@mastra/server/auth');
7
+ var browserStream = require('@mastra/server/browser-stream');
7
8
 
8
9
  // src/index.ts
9
10
 
@@ -460,6 +461,83 @@ function createAuthMiddleware({ mastra, requiresAuth = true }) {
460
461
  return c.json(result.body, result.status);
461
462
  };
462
463
  }
464
+ async function setupBrowserStream(app, config2) {
465
+ let createNodeWebSocket;
466
+ try {
467
+ const mod = "@hono/node-ws";
468
+ const honoNodeWs = await import(
469
+ /* @vite-ignore */
470
+ /* webpackIgnore: true */
471
+ mod
472
+ );
473
+ createNodeWebSocket = honoNodeWs.createNodeWebSocket;
474
+ } catch {
475
+ return null;
476
+ }
477
+ const { injectWebSocket, upgradeWebSocket } = createNodeWebSocket({ app });
478
+ const registry2 = new browserStream.ViewerRegistry();
479
+ app.get(
480
+ "/browser/:agentId/stream",
481
+ upgradeWebSocket((c) => {
482
+ const agentId = c.req.param("agentId");
483
+ const threadId = c.req.query("threadId");
484
+ const viewerKey = threadId ? `${agentId}:${threadId}` : agentId;
485
+ return {
486
+ onOpen(_event, ws) {
487
+ ws.send(JSON.stringify({ status: "connected" }));
488
+ void registry2.addViewer(viewerKey, ws, config2.getToolset, agentId, threadId);
489
+ },
490
+ onMessage(event, _ws) {
491
+ const data = typeof event.data === "string" ? event.data : null;
492
+ if (data) {
493
+ browserStream.handleInputMessage(data, config2.getToolset, agentId, threadId);
494
+ }
495
+ },
496
+ onClose(_event, ws) {
497
+ void registry2.removeViewer(viewerKey, ws);
498
+ },
499
+ onError(event, ws) {
500
+ console.error("[BrowserStream] WebSocket error:", event);
501
+ void registry2.removeViewer(viewerKey, ws);
502
+ }
503
+ };
504
+ })
505
+ );
506
+ app.post("/api/agents/:agentId/browser/close", async (c) => {
507
+ const agentId = c.req.param("agentId");
508
+ if (!agentId) {
509
+ return c.json({ error: "Agent ID is required" }, 400);
510
+ }
511
+ const toolset = config2.getToolset(agentId);
512
+ if (!toolset) {
513
+ return c.json({ error: "No browser session for this agent" }, 404);
514
+ }
515
+ try {
516
+ let threadId;
517
+ try {
518
+ const body = await c.req.json();
519
+ threadId = body?.threadId;
520
+ } catch {
521
+ }
522
+ const scope = toolset.getScope();
523
+ const viewerKey = threadId ? `${agentId}:${threadId}` : agentId;
524
+ if (scope === "thread" && threadId) {
525
+ await registry2.closeBrowserSession(viewerKey);
526
+ if ("closeThreadSession" in toolset && typeof toolset.closeThreadSession === "function") {
527
+ await toolset.closeThreadSession(threadId);
528
+ }
529
+ } else {
530
+ await registry2.closeBrowserSession(viewerKey);
531
+ await toolset.close();
532
+ }
533
+ return c.json({ success: true });
534
+ } catch (error) {
535
+ console.error(`[BrowserStream] Error closing browser for ${agentId}:`, error);
536
+ return c.json({ error: "Failed to close browser" }, 500);
537
+ }
538
+ });
539
+ return { injectWebSocket, registry: registry2 };
540
+ }
463
541
 
464
542
  // src/index.ts
465
543
  var _hasPermissionPromise;
@@ -965,5 +1043,6 @@ var MastraServer = class extends serverAdapter.MastraServer {
965
1043
 
966
1044
  exports.MastraServer = MastraServer;
967
1045
  exports.createAuthMiddleware = createAuthMiddleware;
1046
+ exports.setupBrowserStream = setupBrowserStream;
968
1047
  //# sourceMappingURL=index.cjs.map
969
1048
  //# sourceMappingURL=index.cjs.map