rivetkit 2.0.8 → 2.0.10

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 (125) hide show
  1. package/dist/tsup/{chunk-2FAWAPRT.js → chunk-346X2XU4.js} +2 -2
  2. package/dist/tsup/{chunk-SFRRXLRM.js → chunk-7E5K3375.js} +2 -2
  3. package/dist/tsup/{chunk-3WRAGTDC.cjs → chunk-CA3X5M6H.cjs} +92 -39
  4. package/dist/tsup/{chunk-PVKV2O2E.js.map → chunk-CA3X5M6H.cjs.map} +1 -1
  5. package/dist/tsup/{chunk-L5MHM6JJ.cjs → chunk-DVPXSB4B.cjs} +12 -12
  6. package/dist/tsup/{chunk-L5MHM6JJ.cjs.map → chunk-DVPXSB4B.cjs.map} +1 -1
  7. package/dist/tsup/{chunk-DQVVH5ZK.cjs → chunk-GIFHYL7A.cjs} +5 -6
  8. package/dist/tsup/chunk-GIFHYL7A.cjs.map +1 -0
  9. package/dist/tsup/{chunk-N7OVEOMU.js → chunk-H7E2UU23.js} +38 -15
  10. package/dist/tsup/chunk-H7E2UU23.js.map +1 -0
  11. package/dist/tsup/{chunk-A6TV3QU6.js → chunk-HI55LHM3.js} +5 -6
  12. package/dist/tsup/chunk-HI55LHM3.js.map +1 -0
  13. package/dist/tsup/{chunk-FGOZELKN.cjs → chunk-I3FB346I.cjs} +112 -58
  14. package/dist/tsup/chunk-I3FB346I.cjs.map +1 -0
  15. package/dist/tsup/{chunk-DOZBWJRI.js → chunk-KGDZYQYE.js} +2 -2
  16. package/dist/tsup/{chunk-KYEEAVJO.cjs → chunk-KH5WFDUK.cjs} +6 -6
  17. package/dist/tsup/{chunk-KYEEAVJO.cjs.map → chunk-KH5WFDUK.cjs.map} +1 -1
  18. package/dist/tsup/{chunk-WP7YG7S5.js → chunk-KL4V2ULR.js} +5 -4
  19. package/dist/tsup/chunk-KL4V2ULR.js.map +1 -0
  20. package/dist/tsup/{chunk-S6EAEZQA.js → chunk-MLQIYKAZ.js} +106 -52
  21. package/dist/tsup/chunk-MLQIYKAZ.js.map +1 -0
  22. package/dist/tsup/{chunk-3ZMJUIL3.js → chunk-N3A5GYJU.js} +3 -3
  23. package/dist/tsup/{chunk-CKSA7NOS.cjs → chunk-PDFL7FBL.cjs} +717 -380
  24. package/dist/tsup/chunk-PDFL7FBL.cjs.map +1 -0
  25. package/dist/tsup/{chunk-ESD2JX3L.cjs → chunk-PPLR53PP.cjs} +3 -3
  26. package/dist/tsup/{chunk-ESD2JX3L.cjs.map → chunk-PPLR53PP.cjs.map} +1 -1
  27. package/dist/tsup/{chunk-6INXQCH7.cjs → chunk-PSCDCEXM.cjs} +17 -12
  28. package/dist/tsup/chunk-PSCDCEXM.cjs.map +1 -0
  29. package/dist/tsup/{chunk-PVKV2O2E.js → chunk-QRFXXTLG.js} +96 -43
  30. package/dist/tsup/chunk-QRFXXTLG.js.map +1 -0
  31. package/dist/tsup/{chunk-RM2V2IRK.js → chunk-R2S45MO6.js} +14 -9
  32. package/dist/tsup/chunk-R2S45MO6.js.map +1 -0
  33. package/dist/tsup/{chunk-QGUQB3NC.cjs → chunk-SIWYIRXP.cjs} +7 -6
  34. package/dist/tsup/chunk-SIWYIRXP.cjs.map +1 -0
  35. package/dist/tsup/{chunk-E77RVI3P.js → chunk-VJRXZPTT.js} +601 -264
  36. package/dist/tsup/chunk-VJRXZPTT.js.map +1 -0
  37. package/dist/tsup/{chunk-KDNB2BQX.cjs → chunk-VZMXAZKC.cjs} +229 -206
  38. package/dist/tsup/chunk-VZMXAZKC.cjs.map +1 -0
  39. package/dist/tsup/{chunk-TPJNKVFB.cjs → chunk-YKVTF7MP.cjs} +7 -7
  40. package/dist/tsup/{chunk-TPJNKVFB.cjs.map → chunk-YKVTF7MP.cjs.map} +1 -1
  41. package/dist/tsup/client/mod.cjs +9 -9
  42. package/dist/tsup/client/mod.d.cts +2 -2
  43. package/dist/tsup/client/mod.d.ts +2 -2
  44. package/dist/tsup/client/mod.js +8 -8
  45. package/dist/tsup/common/log.cjs +3 -3
  46. package/dist/tsup/common/log.js +2 -2
  47. package/dist/tsup/common/websocket.cjs +4 -4
  48. package/dist/tsup/common/websocket.js +3 -3
  49. package/dist/tsup/{conn-ChAuuTr0.d.cts → conn-Cc9WHuN4.d.cts} +196 -185
  50. package/dist/tsup/{conn-CjUkMEcm.d.ts → conn-DfPG71FA.d.ts} +196 -185
  51. package/dist/tsup/driver-helpers/mod.cjs +7 -5
  52. package/dist/tsup/driver-helpers/mod.cjs.map +1 -1
  53. package/dist/tsup/driver-helpers/mod.d.cts +4 -2
  54. package/dist/tsup/driver-helpers/mod.d.ts +4 -2
  55. package/dist/tsup/driver-helpers/mod.js +9 -7
  56. package/dist/tsup/driver-test-suite/mod.cjs +116 -102
  57. package/dist/tsup/driver-test-suite/mod.cjs.map +1 -1
  58. package/dist/tsup/driver-test-suite/mod.d.cts +3 -2
  59. package/dist/tsup/driver-test-suite/mod.d.ts +3 -2
  60. package/dist/tsup/driver-test-suite/mod.js +61 -47
  61. package/dist/tsup/driver-test-suite/mod.js.map +1 -1
  62. package/dist/tsup/inspector/mod.cjs +6 -6
  63. package/dist/tsup/inspector/mod.d.cts +6 -6
  64. package/dist/tsup/inspector/mod.d.ts +6 -6
  65. package/dist/tsup/inspector/mod.js +5 -5
  66. package/dist/tsup/mod.cjs +10 -10
  67. package/dist/tsup/mod.d.cts +8 -39
  68. package/dist/tsup/mod.d.ts +8 -39
  69. package/dist/tsup/mod.js +9 -9
  70. package/dist/tsup/test/mod.cjs +11 -11
  71. package/dist/tsup/test/mod.d.cts +1 -1
  72. package/dist/tsup/test/mod.d.ts +1 -1
  73. package/dist/tsup/test/mod.js +10 -10
  74. package/dist/tsup/utils.cjs +2 -2
  75. package/dist/tsup/utils.d.cts +2 -1
  76. package/dist/tsup/utils.d.ts +2 -1
  77. package/dist/tsup/utils.js +1 -1
  78. package/package.json +4 -5
  79. package/src/actor/driver.ts +2 -2
  80. package/src/actor/instance.ts +4 -4
  81. package/src/actor/protocol/serde.ts +75 -3
  82. package/src/actor/router-endpoints.ts +6 -6
  83. package/src/actor/router.ts +2 -2
  84. package/src/client/actor-conn.ts +24 -3
  85. package/src/client/config.ts +18 -25
  86. package/src/driver-helpers/mod.ts +5 -1
  87. package/src/driver-test-suite/mod.ts +65 -43
  88. package/src/driver-test-suite/utils.ts +4 -1
  89. package/src/drivers/default.ts +11 -9
  90. package/src/drivers/engine/actor-driver.ts +40 -39
  91. package/src/drivers/engine/config.ts +9 -22
  92. package/src/drivers/engine/mod.ts +9 -8
  93. package/src/drivers/file-system/global-state.ts +4 -4
  94. package/src/engine-process/log.ts +5 -0
  95. package/src/engine-process/mod.ts +316 -0
  96. package/src/inspector/utils.ts +6 -4
  97. package/src/manager/driver.ts +3 -3
  98. package/src/manager/gateway.ts +29 -11
  99. package/src/manager/router-schema.ts +20 -0
  100. package/src/manager/router.ts +139 -58
  101. package/src/registry/mod.ts +146 -120
  102. package/src/registry/run-config.ts +116 -47
  103. package/src/registry/serve.ts +3 -1
  104. package/src/remote-manager-driver/mod.ts +3 -2
  105. package/src/serde.ts +18 -3
  106. package/src/test/config.ts +2 -2
  107. package/src/test/mod.ts +6 -3
  108. package/src/utils.ts +2 -0
  109. package/dist/tsup/chunk-3WRAGTDC.cjs.map +0 -1
  110. package/dist/tsup/chunk-6INXQCH7.cjs.map +0 -1
  111. package/dist/tsup/chunk-A6TV3QU6.js.map +0 -1
  112. package/dist/tsup/chunk-CKSA7NOS.cjs.map +0 -1
  113. package/dist/tsup/chunk-DQVVH5ZK.cjs.map +0 -1
  114. package/dist/tsup/chunk-E77RVI3P.js.map +0 -1
  115. package/dist/tsup/chunk-FGOZELKN.cjs.map +0 -1
  116. package/dist/tsup/chunk-KDNB2BQX.cjs.map +0 -1
  117. package/dist/tsup/chunk-N7OVEOMU.js.map +0 -1
  118. package/dist/tsup/chunk-QGUQB3NC.cjs.map +0 -1
  119. package/dist/tsup/chunk-RM2V2IRK.js.map +0 -1
  120. package/dist/tsup/chunk-S6EAEZQA.js.map +0 -1
  121. package/dist/tsup/chunk-WP7YG7S5.js.map +0 -1
  122. /package/dist/tsup/{chunk-2FAWAPRT.js.map → chunk-346X2XU4.js.map} +0 -0
  123. /package/dist/tsup/{chunk-SFRRXLRM.js.map → chunk-7E5K3375.js.map} +0 -0
  124. /package/dist/tsup/{chunk-DOZBWJRI.js.map → chunk-KGDZYQYE.js.map} +0 -0
  125. /package/dist/tsup/{chunk-3ZMJUIL3.js.map → chunk-N3A5GYJU.js.map} +0 -0
@@ -14,7 +14,7 @@ import {
14
14
  } from "@/common/actor-router-consts";
15
15
  import { deconstructError, noopNext } from "@/common/utils";
16
16
  import type { UniversalWebSocket, UpgradeWebSocketArgs } from "@/mod";
17
- import type { RunConfig } from "@/registry/run-config";
17
+ import type { RunnerConfig } from "@/registry/run-config";
18
18
  import { promiseWithResolvers, stringifyError } from "@/utils";
19
19
  import type { ManagerDriver } from "./driver";
20
20
  import { logger } from "./log";
@@ -27,7 +27,7 @@ import { logger } from "./log";
27
27
  * - HTTP requests: Uses x-rivet-target and x-rivet-actor headers for routing
28
28
  */
29
29
  export async function actorGateway(
30
- runConfig: RunConfig,
30
+ runConfig: RunnerConfig,
31
31
  managerDriver: ManagerDriver,
32
32
  c: HonoContext,
33
33
  next: Next,
@@ -37,22 +37,38 @@ export async function actorGateway(
37
37
  return next();
38
38
  }
39
39
 
40
+ // Strip basePath from the request path
41
+ let strippedPath = c.req.path;
42
+ if (runConfig.basePath && strippedPath.startsWith(runConfig.basePath)) {
43
+ strippedPath = strippedPath.slice(runConfig.basePath.length);
44
+ // Ensure the path starts with /
45
+ if (!strippedPath.startsWith("/")) {
46
+ strippedPath = "/" + strippedPath;
47
+ }
48
+ }
49
+
40
50
  // Check if this is a WebSocket upgrade request
41
51
  if (c.req.header("upgrade") === "websocket") {
42
- return await handleWebSocketGateway(runConfig, managerDriver, c);
52
+ return await handleWebSocketGateway(
53
+ runConfig,
54
+ managerDriver,
55
+ c,
56
+ strippedPath,
57
+ );
43
58
  }
44
59
 
45
60
  // Handle regular HTTP requests
46
- return await handleHttpGateway(managerDriver, c, next);
61
+ return await handleHttpGateway(managerDriver, c, next, strippedPath);
47
62
  }
48
63
 
49
64
  /**
50
65
  * Handle WebSocket requests using sec-websocket-protocol for routing
51
66
  */
52
67
  async function handleWebSocketGateway(
53
- runConfig: RunConfig,
68
+ runConfig: RunnerConfig,
54
69
  managerDriver: ManagerDriver,
55
70
  c: HonoContext,
71
+ strippedPath: string,
56
72
  ) {
57
73
  const upgradeWebSocket = runConfig.getUpgradeWebSocket?.();
58
74
  if (!upgradeWebSocket) {
@@ -100,7 +116,7 @@ async function handleWebSocketGateway(
100
116
  logger().debug({
101
117
  msg: "proxying websocket to actor",
102
118
  actorId,
103
- path: c.req.path,
119
+ path: strippedPath,
104
120
  encoding: encodingRaw,
105
121
  });
106
122
 
@@ -109,8 +125,8 @@ async function handleWebSocketGateway(
109
125
 
110
126
  // Include query string if present
111
127
  const pathWithQuery = c.req.url.includes("?")
112
- ? c.req.path + c.req.url.substring(c.req.url.indexOf("?"))
113
- : c.req.path;
128
+ ? strippedPath + c.req.url.substring(c.req.url.indexOf("?"))
129
+ : strippedPath;
114
130
 
115
131
  return await managerDriver.proxyWebSocket(
116
132
  c,
@@ -130,6 +146,7 @@ async function handleHttpGateway(
130
146
  managerDriver: ManagerDriver,
131
147
  c: HonoContext,
132
148
  next: Next,
149
+ strippedPath: string,
133
150
  ) {
134
151
  const target = c.req.header(HEADER_RIVET_TARGET);
135
152
  const actorId = c.req.header(HEADER_RIVET_ACTOR);
@@ -145,7 +162,7 @@ async function handleHttpGateway(
145
162
  logger().debug({
146
163
  msg: "proxying request to actor",
147
164
  actorId,
148
- path: c.req.path,
165
+ path: strippedPath,
149
166
  method: c.req.method,
150
167
  });
151
168
 
@@ -156,14 +173,15 @@ async function handleHttpGateway(
156
173
 
157
174
  // Build the proxy request with the actor URL format
158
175
  const url = new URL(c.req.url);
159
- const proxyUrl = new URL(`http://actor${url.pathname}${url.search}`);
176
+ const proxyUrl = new URL(`http://actor${strippedPath}${url.search}`);
160
177
 
161
178
  const proxyRequest = new Request(proxyUrl, {
162
179
  method: c.req.raw.method,
163
180
  headers: proxyHeaders,
164
181
  body: c.req.raw.body,
165
182
  signal: c.req.raw.signal,
166
- });
183
+ duplex: "half",
184
+ } as RequestInit);
167
185
 
168
186
  return await managerDriver.proxyRequest(c, proxyRequest, actorId);
169
187
  }
@@ -0,0 +1,20 @@
1
+ import { z } from "zod";
2
+
3
+ export const ServerlessStartHeadersSchema = z.object({
4
+ endpoint: z.string({ required_error: "x-rivet-endpoint header is required" }),
5
+ token: z
6
+ .string({ invalid_type_error: "x-rivet-token header must be a string" })
7
+ .optional(),
8
+ totalSlots: z.coerce
9
+ .number({
10
+ invalid_type_error: "x-rivet-total-slots header must be a number",
11
+ })
12
+ .int("x-rivet-total-slots header must be an integer")
13
+ .gte(1, "x-rivet-total-slots header must be positive"),
14
+ runnerName: z.string({
15
+ required_error: "x-rivet-runner-name header is required",
16
+ }),
17
+ namespace: z.string({
18
+ required_error: "x-rivet-namespace-id header is required",
19
+ }),
20
+ });
@@ -2,18 +2,18 @@ import { createRoute, OpenAPIHono } from "@hono/zod-openapi";
2
2
  import * as cbor from "cbor-x";
3
3
  import {
4
4
  Hono,
5
- Context as HonoContext,
5
+ type Context as HonoContext,
6
6
  type MiddlewareHandler,
7
- Next,
7
+ type Next,
8
8
  } from "hono";
9
9
  import { cors as corsMiddleware } from "hono/cors";
10
10
  import { createMiddleware } from "hono/factory";
11
11
  import { streamSSE } from "hono/streaming";
12
12
  import invariant from "invariant";
13
13
  import { z } from "zod";
14
- import { ActorNotFound, Unsupported } from "@/actor/errors";
14
+ import { ActorNotFound, InvalidRequest, Unsupported } from "@/actor/errors";
15
15
  import { serializeActorKey } from "@/actor/keys";
16
- import type { Encoding, Transport } from "@/client/mod";
16
+ import type { Client, Encoding, Transport } from "@/client/mod";
17
17
  import {
18
18
  WS_PROTOCOL_ACTOR,
19
19
  WS_PROTOCOL_CONN_ID,
@@ -28,7 +28,12 @@ import {
28
28
  handleRouteNotFound,
29
29
  loggerMiddleware,
30
30
  } from "@/common/router";
31
- import { deconstructError, noopNext, stringifyError } from "@/common/utils";
31
+ import {
32
+ assertUnreachable,
33
+ deconstructError,
34
+ noopNext,
35
+ stringifyError,
36
+ } from "@/common/utils";
32
37
  import { type ActorDriver, HEADER_ACTOR_ID } from "@/driver-helpers/mod";
33
38
  import type {
34
39
  TestInlineDriverCallRequest,
@@ -50,11 +55,14 @@ import {
50
55
  type Actor as ApiActor,
51
56
  } from "@/manager-api/actors";
52
57
  import { RivetIdSchema } from "@/manager-api/common";
58
+ import type { AnyClient } from "@/mod";
53
59
  import type { RegistryConfig } from "@/registry/config";
54
- import type { RunConfig } from "@/registry/run-config";
60
+ import type { DriverConfig, RunnerConfig } from "@/registry/run-config";
61
+ import { VERSION } from "@/utils";
55
62
  import type { ActorOutput, ManagerDriver } from "./driver";
56
63
  import { actorGateway, createTestWebSocketProxy } from "./gateway";
57
64
  import { logger } from "./log";
65
+ import { ServerlessStartHeadersSchema } from "./router-schema";
58
66
 
59
67
  function buildOpenApiResponses<T>(schema: T) {
60
68
  return {
@@ -77,81 +85,170 @@ function buildOpenApiResponses<T>(schema: T) {
77
85
 
78
86
  export function createManagerRouter(
79
87
  registryConfig: RegistryConfig,
80
- runConfig: RunConfig,
88
+ runConfig: RunnerConfig,
81
89
  managerDriver: ManagerDriver,
82
- serverlessActorDriverBuilder: (() => ActorDriver) | undefined,
83
- ): { router: Hono; openapi: OpenAPIHono; cors: MiddlewareHandler } {
90
+ driverConfig: DriverConfig,
91
+ client: AnyClient,
92
+ ): { router: Hono; openapi: OpenAPIHono } {
84
93
  const router = new OpenAPIHono({ strict: false }).basePath(
85
94
  runConfig.basePath,
86
95
  );
87
96
 
88
97
  router.use("*", loggerMiddleware(logger()));
89
98
 
90
- const cors = runConfig.cors
91
- ? corsMiddleware(runConfig.cors)
92
- : createMiddleware((_c, next) => next());
99
+ // HACK: Add Sec-WebSocket-Protocol header to fix KIT-339
100
+ //
101
+ // Some Deno WebSocket providers do not auto-set the protocol, which
102
+ // will cause some WebSocket clients to fail
103
+ router.use(
104
+ "*",
105
+ createMiddleware(async (c, next) => {
106
+ const upgrade = c.req.header("upgrade");
107
+ const isWebSocket = upgrade?.toLowerCase() === "websocket";
108
+ const isGet = c.req.method === "GET";
109
+
110
+ if (isGet && isWebSocket) {
111
+ c.header("Sec-WebSocket-Protocol", "rivet");
112
+ }
93
113
 
94
- if (serverlessActorDriverBuilder) {
95
- addServerlessRoutes(serverlessActorDriverBuilder, router, cors);
114
+ await next();
115
+ }),
116
+ );
117
+
118
+ if (runConfig.runnerKind === "serverless") {
119
+ addServerlessRoutes(
120
+ driverConfig,
121
+ registryConfig,
122
+ runConfig,
123
+ managerDriver,
124
+ client,
125
+ router,
126
+ );
127
+ } else if (runConfig.runnerKind === "normal") {
128
+ addManagerRoutes(registryConfig, runConfig, managerDriver, router);
96
129
  } else {
97
- addManagerRoutes(registryConfig, runConfig, managerDriver, router, cors);
130
+ assertUnreachable(runConfig.runnerKind);
98
131
  }
99
132
 
100
133
  // Error handling
101
134
  router.notFound(handleRouteNotFound);
102
135
  router.onError(handleRouteError);
103
136
 
104
- return { router: router as Hono, openapi: router, cors };
137
+ return { router: router as Hono, openapi: router };
105
138
  }
106
139
 
107
140
  function addServerlessRoutes(
108
- serverlessActorDriverBuilder: (
109
- token: string | undefined,
110
- totalSlots: number | undefined,
111
- ) => ActorDriver,
141
+ driverConfig: DriverConfig,
142
+ registryConfig: RegistryConfig,
143
+ runConfig: RunnerConfig,
144
+ managerDriver: ManagerDriver,
145
+ client: AnyClient,
112
146
  router: OpenAPIHono,
113
- cors: MiddlewareHandler,
114
147
  ) {
148
+ // Apply CORS
149
+ if (runConfig.cors) router.use("*", corsMiddleware(runConfig.cors));
150
+
115
151
  // GET /
116
- router.get("/", cors, (c) => {
152
+ router.get("/", (c) => {
117
153
  return c.text(
118
154
  "This is a RivetKit server.\n\nLearn more at https://rivetkit.org",
119
155
  );
120
156
  });
121
157
 
122
158
  // Serverless start endpoint
123
- router.get("/start", cors, async (c) => {
124
- const token = c.req.header("x-rivet-token");
125
- let totalSlots: number | undefined = parseInt(
126
- c.req.header("x-rivetkit-total-slots") as any,
127
- );
128
- if (isNaN(totalSlots)) totalSlots = undefined;
159
+ router.get("/start", async (c) => {
160
+ // Parse headers
161
+ const parseResult = ServerlessStartHeadersSchema.safeParse({
162
+ endpoint: c.req.header("x-rivet-endpoint"),
163
+ token: c.req.header("x-rivet-token") ?? undefined,
164
+ totalSlots: c.req.header("x-rivet-total-slots"),
165
+ runnerName: c.req.header("x-rivet-runner-name"),
166
+ namespace: c.req.header("x-rivet-namespace-id"),
167
+ });
168
+ if (!parseResult.success) {
169
+ throw new InvalidRequest(
170
+ parseResult.error.issues[0]?.message ??
171
+ "invalid serverless start headers",
172
+ );
173
+ }
174
+ const { endpoint, token, totalSlots, runnerName, namespace } =
175
+ parseResult.data;
176
+
177
+ logger().debug({
178
+ msg: "received serverless runner start request",
179
+ endpoint,
180
+ totalSlots,
181
+ runnerName,
182
+ namespace,
183
+ });
129
184
 
130
- const actorDriver = serverlessActorDriverBuilder(token, totalSlots);
185
+ // Override config
186
+ //
187
+ // We can't do a structuredClone here since this holds functions
188
+ const newRunConfig = Object.assign({}, runConfig);
189
+ newRunConfig.endpoint = endpoint;
190
+ newRunConfig.token = token;
191
+ newRunConfig.totalSlots = totalSlots;
192
+ newRunConfig.runnerName = runnerName;
193
+ newRunConfig.namespace = namespace;
194
+
195
+ // Create new actor driver with updated config
196
+ const actorDriver = driverConfig.actor(
197
+ registryConfig,
198
+ newRunConfig,
199
+ managerDriver,
200
+ client,
201
+ );
131
202
  invariant(
132
203
  actorDriver.serverlessHandleStart,
133
204
  "missing serverlessHandleStart on ActorDriver",
134
205
  );
206
+
135
207
  return await actorDriver.serverlessHandleStart(c);
136
208
  });
137
209
 
138
- router.get("/health", cors, (c) => {
139
- return c.text("ok");
210
+ router.get("/health", (c) => {
211
+ return c.json({
212
+ status: "ok",
213
+ runtime: "rivetkit",
214
+ version: VERSION,
215
+ });
140
216
  });
141
217
  }
142
218
 
143
219
  function addManagerRoutes(
144
220
  registryConfig: RegistryConfig,
145
- runConfig: RunConfig,
221
+ runConfig: RunnerConfig,
146
222
  managerDriver: ManagerDriver,
147
223
  router: OpenAPIHono,
148
- cors: MiddlewareHandler,
149
224
  ) {
225
+ // Serve inspector BEFORE the rest of the routes, since this has a special
226
+ // CORS config that should take precedence for the `/inspector` path
227
+ if (isInspectorEnabled(runConfig, "manager")) {
228
+ if (!managerDriver.inspector) {
229
+ throw new Unsupported("inspector");
230
+ }
231
+ router.route(
232
+ "/inspect",
233
+ new Hono<{ Variables: { inspector: any } }>()
234
+ .use(corsMiddleware(runConfig.inspector.cors))
235
+ .use(secureInspector(runConfig))
236
+ .use((c, next) => {
237
+ c.set("inspector", managerDriver.inspector!);
238
+ return next();
239
+ })
240
+ .route("/", createManagerInspectorRouter()),
241
+ );
242
+ }
243
+
244
+ // Apply CORS
245
+ if (runConfig.cors) router.use("*", corsMiddleware(runConfig.cors));
246
+
150
247
  // Actor gateway
151
- router.use("*", cors, actorGateway.bind(undefined, runConfig, managerDriver));
248
+ router.use("*", actorGateway.bind(undefined, runConfig, managerDriver));
152
249
 
153
250
  // GET /
154
- router.get("/", cors, (c) => {
251
+ router.get("/", (c) => {
155
252
  return c.text(
156
253
  "This is a RivetKit server.\n\nLearn more at https://rivetkit.org",
157
254
  );
@@ -160,7 +257,6 @@ function addManagerRoutes(
160
257
  // GET /actors
161
258
  {
162
259
  const route = createRoute({
163
- middleware: [cors],
164
260
  method: "get",
165
261
  path: "/actors",
166
262
  request: {
@@ -233,7 +329,6 @@ function addManagerRoutes(
233
329
  // PUT /actors
234
330
  {
235
331
  const route = createRoute({
236
- middleware: [cors],
237
332
  method: "put",
238
333
  path: "/actors",
239
334
  request: {
@@ -286,7 +381,6 @@ function addManagerRoutes(
286
381
  // POST /actors
287
382
  {
288
383
  const route = createRoute({
289
- middleware: [cors],
290
384
  method: "post",
291
385
  path: "/actors",
292
386
  request: {
@@ -326,7 +420,6 @@ function addManagerRoutes(
326
420
  // // DELETE /actors/{actor_id}
327
421
  // {
328
422
  // const route = createRoute({
329
- // middleware: [cors],
330
423
  // method: "delete",
331
424
  // path: "/actors/{actor_id}",
332
425
  // request: {
@@ -547,31 +640,19 @@ function addManagerRoutes(
547
640
  });
548
641
  }
549
642
 
550
- router.get("/health", cors, (c) => {
551
- return c.text("ok");
643
+ router.get("/health", (c) => {
644
+ return c.json({
645
+ status: "ok",
646
+ rivetkit: {
647
+ version: VERSION,
648
+ },
649
+ });
552
650
  });
553
651
 
554
652
  managerDriver.modifyManagerRouter?.(
555
653
  registryConfig,
556
654
  router as unknown as Hono,
557
655
  );
558
-
559
- if (isInspectorEnabled(runConfig, "manager")) {
560
- if (!managerDriver.inspector) {
561
- throw new Unsupported("inspector");
562
- }
563
- router.route(
564
- "/inspect",
565
- new Hono<{ Variables: { inspector: any } }>()
566
- .use(corsMiddleware(runConfig.inspector.cors))
567
- .use(secureInspector(runConfig))
568
- .use((c, next) => {
569
- c.set("inspector", managerDriver.inspector!);
570
- return next();
571
- })
572
- .route("/", createManagerInspectorRouter()),
573
- );
574
- }
575
656
  }
576
657
 
577
658
  function createApiActor(actor: ActorOutput): ApiActor {