From 65c55809dd98e01981d64d949e277a7acac23571 Mon Sep 17 00:00:00 2001 From: Kacper Wojciechowski <39823706+jog1t@users.noreply.github.com> Date: Wed, 17 Sep 2025 22:15:22 +0200 Subject: [PATCH] fix(inspector): allow connection to inspector when using engine driver --- .../src/actor-handler-do.ts | 10 ++++++- packages/rivetkit/src/actor/router.ts | 4 +-- .../rivetkit/src/driver-test-suite/mod.ts | 2 ++ .../src/drivers/file-system/manager.ts | 8 +++--- packages/rivetkit/src/inspector/config.ts | 11 +++++++- packages/rivetkit/src/inspector/mod.ts | 1 + packages/rivetkit/src/inspector/utils.ts | 27 ++++++++++++++++--- packages/rivetkit/src/manager/driver.ts | 7 +++++ packages/rivetkit/src/manager/router.ts | 4 +-- packages/rivetkit/src/registry/mod.ts | 17 +++++++----- .../rivetkit/src/remote-manager-driver/mod.ts | 5 ++++ packages/rivetkit/src/test/mod.ts | 6 ++++- 12 files changed, 81 insertions(+), 21 deletions(-) diff --git a/packages/cloudflare-workers/src/actor-handler-do.ts b/packages/cloudflare-workers/src/actor-handler-do.ts index de869ef32..82c8d0545 100644 --- a/packages/cloudflare-workers/src/actor-handler-do.ts +++ b/packages/cloudflare-workers/src/actor-handler-do.ts @@ -3,7 +3,7 @@ import type { ExecutionContext } from "hono"; import invariant from "invariant"; import type { ActorKey, ActorRouter, Registry, RunConfig } from "rivetkit"; import { createActorRouter, createClientWithDriver } from "rivetkit"; -import type { ActorDriver } from "rivetkit/driver-helpers"; +import type { ActorDriver, ManagerDriver } from "rivetkit/driver-helpers"; import { serializeEmptyPersistData } from "rivetkit/driver-helpers"; import { promiseWithResolvers } from "rivetkit/utils"; import { @@ -121,6 +121,8 @@ export function createActorDurableObject( runConfig, ); + configureInspectorAccessToken(registry.config, managerDriver); + // Create inline client const inlineClient = createClientWithDriver(managerDriver); @@ -187,3 +189,9 @@ export function createActorDurableObject( } }; } +function configureInspectorAccessToken( + config: any, + managerDriver: ManagerDriver, +) { + throw new Error("Function not implemented."); +} diff --git a/packages/rivetkit/src/actor/router.ts b/packages/rivetkit/src/actor/router.ts index 2f4104530..0e313f9e5 100644 --- a/packages/rivetkit/src/actor/router.ts +++ b/packages/rivetkit/src/actor/router.ts @@ -34,7 +34,7 @@ import { type ActorInspectorRouterEnv, createActorInspectorRouter, } from "@/inspector/actor"; -import { secureInspector } from "@/inspector/utils"; +import { isInspectorEnabled, secureInspector } from "@/inspector/utils"; import type { RunConfig } from "@/registry/run-config"; import type { ActorDriver } from "./driver"; import { InternalError } from "./errors"; @@ -206,7 +206,7 @@ export function createActorRouter( } }); - if (runConfig.inspector.enabled) { + if (isInspectorEnabled(runConfig, "actor")) { router.route( "/inspect", new Hono() diff --git a/packages/rivetkit/src/driver-test-suite/mod.ts b/packages/rivetkit/src/driver-test-suite/mod.ts index 496483a88..bfe87bf52 100644 --- a/packages/rivetkit/src/driver-test-suite/mod.ts +++ b/packages/rivetkit/src/driver-test-suite/mod.ts @@ -4,6 +4,7 @@ import { bundleRequire } from "bundle-require"; import invariant from "invariant"; import { describe } from "vitest"; import type { Transport } from "@/client/mod"; +import { configureInspectorAccessToken } from "@/inspector/utils"; import { createManagerRouter } from "@/manager/router"; import type { DriverConfig, Registry, RunConfig } from "@/mod"; import { RunConfigSchema } from "@/registry/run-config"; @@ -193,6 +194,7 @@ export async function createTestRuntime( // Create router const managerDriver = driver.manager(registry.config, config); + configureInspectorAccessToken(config, managerDriver); const { router } = createManagerRouter( registry.config, config, diff --git a/packages/rivetkit/src/drivers/file-system/manager.ts b/packages/rivetkit/src/drivers/file-system/manager.ts index 47e34d023..ac187c29a 100644 --- a/packages/rivetkit/src/drivers/file-system/manager.ts +++ b/packages/rivetkit/src/drivers/file-system/manager.ts @@ -57,10 +57,6 @@ export class FileSystemManagerDriver implements ManagerDriver { this.#driverConfig = driverConfig; if (runConfig.inspector.enabled) { - if (!this.#runConfig.inspector.token()) { - this.#runConfig.inspector.token = () => - this.#state.getOrCreateInspectorAccessToken(); - } const startedAt = new Date().toISOString(); function transformActor(actorState: schema.ActorState): Actor { return { @@ -317,4 +313,8 @@ export class FileSystemManagerDriver implements ManagerDriver { data: this.#state.storagePath, }; } + + getOrCreateInspectorAccessToken() { + return this.#state.getOrCreateInspectorAccessToken(); + } } diff --git a/packages/rivetkit/src/inspector/config.ts b/packages/rivetkit/src/inspector/config.ts index cbcc26298..80e529177 100644 --- a/packages/rivetkit/src/inspector/config.ts +++ b/packages/rivetkit/src/inspector/config.ts @@ -56,7 +56,16 @@ const defaultCors: CorsOptions = { export const InspectorConfigSchema = z .object({ - enabled: z.boolean().optional().default(defaultEnabled), + enabled: z + .boolean() + .or( + z.object({ + actor: z.boolean().optional().default(true), + manager: z.boolean().optional().default(true), + }), + ) + .optional() + .default(defaultEnabled), /** CORS configuration for the router. Uses Hono's CORS middleware options. */ cors: z .custom() diff --git a/packages/rivetkit/src/inspector/mod.ts b/packages/rivetkit/src/inspector/mod.ts index 10f49da79..da4942a6e 100644 --- a/packages/rivetkit/src/inspector/mod.ts +++ b/packages/rivetkit/src/inspector/mod.ts @@ -1,2 +1,3 @@ export * from "./protocol/common"; export * from "./protocol/mod"; +export * from "./utils"; diff --git a/packages/rivetkit/src/inspector/utils.ts b/packages/rivetkit/src/inspector/utils.ts index 06d9c31e2..96e6bde8b 100644 --- a/packages/rivetkit/src/inspector/utils.ts +++ b/packages/rivetkit/src/inspector/utils.ts @@ -1,5 +1,6 @@ import crypto from "node:crypto"; import { createMiddleware } from "hono/factory"; +import type { ManagerDriver } from "@/driver-helpers/mod"; import type { RunConfig } from "@/mod"; import type { RunConfigInput } from "@/registry/run-config"; import { inspectorLogger } from "./log"; @@ -28,10 +29,6 @@ export function compareSecrets(providedSecret: string, validSecret: string) { export const secureInspector = (runConfig: RunConfig) => createMiddleware(async (c, next) => { - if (!runConfig.inspector.enabled) { - return c.text("Inspector is not enabled", 503); - } - const userToken = c.req.header("Authorization")?.replace("Bearer ", ""); if (!userToken) { return c.text("Unauthorized", 401); @@ -74,3 +71,25 @@ export function getInspectorUrl(runConfig: RunConfigInput | undefined) { return url.href; } + +export const isInspectorEnabled = ( + runConfig: RunConfig, + context: "actor" | "manager", +) => { + if (typeof runConfig.inspector?.enabled === "boolean") { + return runConfig.inspector.enabled; + } else if (typeof runConfig.inspector?.enabled === "object") { + return runConfig.inspector.enabled[context]; + } + return false; +}; + +export const configureInspectorAccessToken = ( + runConfig: RunConfig, + managerDriver: ManagerDriver, +) => { + if (!runConfig.inspector?.token()) { + const token = managerDriver.getOrCreateInspectorAccessToken(); + runConfig.inspector.token = () => token; + } +}; diff --git a/packages/rivetkit/src/manager/driver.ts b/packages/rivetkit/src/manager/driver.ts index bd8916c35..802e3f210 100644 --- a/packages/rivetkit/src/manager/driver.ts +++ b/packages/rivetkit/src/manager/driver.ts @@ -45,6 +45,13 @@ export interface ManagerDriver { * @internal */ readonly inspector?: ManagerInspector; + + /** + * Get or create the inspector access token. + * @internal + * @returns creates or returns existing inspector access token + */ + getOrCreateInspectorAccessToken: () => string; } export interface ManagerDisplayInformation { diff --git a/packages/rivetkit/src/manager/router.ts b/packages/rivetkit/src/manager/router.ts index 01f44abea..137a2f691 100644 --- a/packages/rivetkit/src/manager/router.ts +++ b/packages/rivetkit/src/manager/router.ts @@ -27,7 +27,7 @@ import type { TestInlineDriverCallResponse, } from "@/driver-test-suite/test-inline-client-driver"; import { createManagerInspectorRouter } from "@/inspector/manager"; -import { secureInspector } from "@/inspector/utils"; +import { isInspectorEnabled, secureInspector } from "@/inspector/utils"; import { type ActorsCreateRequest, ActorsCreateRequestSchema, @@ -436,7 +436,7 @@ export function createManagerRouter( router as unknown as Hono, ); - if (runConfig.inspector?.enabled) { + if (isInspectorEnabled(runConfig, "manager")) { if (!managerDriver.inspector) { throw new Unsupported("inspector"); } diff --git a/packages/rivetkit/src/registry/mod.ts b/packages/rivetkit/src/registry/mod.ts index e875002f4..8aafa0993 100644 --- a/packages/rivetkit/src/registry/mod.ts +++ b/packages/rivetkit/src/registry/mod.ts @@ -1,7 +1,11 @@ import { type Client, createClientWithDriver } from "@/client/client"; import { configureBaseLogger, configureDefaultLogger } from "@/common/log"; import { chooseDefaultDriver } from "@/drivers/default"; -import { getInspectorUrl } from "@/inspector/utils"; +import { + configureInspectorAccessToken, + getInspectorUrl, + isInspectorEnabled, +} from "@/inspector/utils"; import { createManagerRouter } from "@/manager/router"; import pkg from "../../package.json" with { type: "json" }; import { @@ -58,11 +62,11 @@ export class Registry { // TODO: Find cleaner way of disabling by default if (driver.name === "engine") { - config.inspector.enabled = false; + config.inspector.enabled = { manager: false, actor: true }; config.disableServer = true; } if (driver.name === "cloudflare-workers") { - config.inspector.enabled = false; + config.inspector.enabled = { manager: false, actor: true }; config.disableServer = true; config.disableActorDriver = true; config.noWelcome = true; @@ -76,6 +80,7 @@ export class Registry { // Create router const managerDriver = driver.manager(this.#config, config); + configureInspectorAccessToken(config, managerDriver); const { router: hono } = createManagerRouter( this.#config, config, @@ -92,7 +97,7 @@ export class Registry { definitions: Object.keys(this.#config.use).length, ...driverLog, }); - if (config.inspector?.enabled && managerDriver.inspector) { + if (isInspectorEnabled(config, "manager") && managerDriver.inspector) { logger().info({ msg: "inspector ready", url: getInspectorUrl(config) }); } @@ -106,8 +111,8 @@ export class Registry { const padding = " ".repeat(Math.max(0, 13 - k.length)); console.log(` - ${k}:${padding}${v}`); } - if (config.inspector?.enabled && managerDriver.inspector) { - console.log(` - Inspector: ${getInspectorUrl(config)}`); + if (isInspectorEnabled(config, "manager") && managerDriver.inspector) { + console.log(` - Inspector: ${getInspectorUrl(config)}`); } console.log(); } diff --git a/packages/rivetkit/src/remote-manager-driver/mod.ts b/packages/rivetkit/src/remote-manager-driver/mod.ts index 397c9bf00..2c352f557 100644 --- a/packages/rivetkit/src/remote-manager-driver/mod.ts +++ b/packages/rivetkit/src/remote-manager-driver/mod.ts @@ -2,6 +2,7 @@ import * as cbor from "cbor-x"; import type { Context as HonoContext } from "hono"; import invariant from "invariant"; import { deserializeActorKey, serializeActorKey } from "@/actor/keys"; +import { generateRandomString } from "@/actor/utils"; import type { ClientConfig } from "@/client/client"; import { noopNext } from "@/common/utils"; import type { @@ -252,4 +253,8 @@ export class RemoteManagerDriver implements ManagerDriver { displayInformation(): ManagerDisplayInformation { return { name: "Remote", properties: {} }; } + + getOrCreateInspectorAccessToken() { + return generateRandomString(); + } } diff --git a/packages/rivetkit/src/test/mod.ts b/packages/rivetkit/src/test/mod.ts index 9accdb83f..153b5beec 100644 --- a/packages/rivetkit/src/test/mod.ts +++ b/packages/rivetkit/src/test/mod.ts @@ -5,7 +5,10 @@ import { type TestContext, vi } from "vitest"; import { type Client, createClient } from "@/client/mod"; import { chooseDefaultDriver } from "@/drivers/default"; import { createFileSystemOrMemoryDriver } from "@/drivers/file-system/mod"; -import { getInspectorUrl } from "@/inspector/utils"; +import { + configureInspectorAccessToken, + getInspectorUrl, +} from "@/inspector/utils"; import { createManagerRouter } from "@/manager/router"; import type { Registry } from "@/registry/mod"; import { RunConfigSchema } from "@/registry/run-config"; @@ -27,6 +30,7 @@ function serve(registry: Registry, inputConfig?: InputConfig): ServerType { const runConfig = RunConfigSchema.parse(inputConfig); const driver = inputConfig.driver ?? createFileSystemOrMemoryDriver(false); const managerDriver = driver.manager(registry.config, config); + configureInspectorAccessToken(config, managerDriver); const { router } = createManagerRouter( registry.config, runConfig,