fix: update Rivet doc examples and stale peer dependency

- Fix security.mdx: move SDK/session setup from per-action to createVars
  to prevent resource leaks (new SDK + session was created on every
  submitPrompt call without cleanup)
- Add onSleep cleanup hook matching multiplayer.mdx pattern
- Update persist-rivet peer dependency from >=0.5.0 to >=2.0.0
  (rivetkit is at 2.0.42)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Nathan Flurry 2026-03-09 20:44:48 -07:00
parent c294ca85be
commit f96229abe6
2 changed files with 28 additions and 23 deletions

View file

@ -53,6 +53,27 @@ export const workspace = actor({
events: [] as Array<{ userId: string; prompt: string; createdAt: number }>, events: [] as Array<{ userId: string; prompt: string; createdAt: number }>,
}, },
createVars: async (c) => {
// Connect to Sandbox Agent from the actor (server-side only).
// Sandbox credentials never reach the client.
const sdk = await SandboxAgent.connect({
baseUrl: process.env.SANDBOX_URL!,
token: process.env.SANDBOX_TOKEN,
});
const session = await sdk.resumeOrCreateSession({ id: "default", agent: "claude" });
const unsubscribe = session.onEvent((event) => {
c.broadcast("session.event", {
eventIndex: event.eventIndex,
sender: event.sender,
payload: event.payload,
});
});
return { sdk, session, unsubscribe };
},
onBeforeConnect: async (c, params: ConnParams) => { onBeforeConnect: async (c, params: ConnParams) => {
const claims = await verifyWorkspaceToken(params.accessToken, c.key[0]); const claims = await verifyWorkspaceToken(params.accessToken, c.key[0]);
if (!claims) { if (!claims) {
@ -83,28 +104,7 @@ export const workspace = actor({
throw new UserError("Insufficient permissions", { code: "forbidden" }); throw new UserError("Insufficient permissions", { code: "forbidden" });
} }
// Connect to Sandbox Agent from the actor (server-side only). const result = await c.vars.session.prompt([
// Sandbox credentials never reach the client.
const sdk = await SandboxAgent.connect({
baseUrl: process.env.SANDBOX_URL!,
token: process.env.SANDBOX_TOKEN,
});
const session = await sdk.createSession({
agent: "claude",
sessionInit: { cwd: "/workspace" },
});
session.onEvent((event) => {
c.broadcast("session.event", {
userId: c.conn!.state.userId,
eventIndex: event.eventIndex,
sender: event.sender,
payload: event.payload,
});
});
const result = await session.prompt([
{ type: "text", text: prompt }, { type: "text", text: prompt },
]); ]);
@ -117,6 +117,11 @@ export const workspace = actor({
return { stopReason: result.stopReason }; return { stopReason: result.stopReason };
}, },
}, },
onSleep: async (c) => {
c.vars.unsubscribe?.();
await c.vars.sdk.dispose();
},
}); });
``` ```

View file

@ -20,7 +20,7 @@
"sandbox-agent": "workspace:*" "sandbox-agent": "workspace:*"
}, },
"peerDependencies": { "peerDependencies": {
"rivetkit": ">=0.5.0" "rivetkit": ">=2.0.0"
}, },
"peerDependenciesMeta": { "peerDependenciesMeta": {
"rivetkit": { "rivetkit": {