mirror of
https://github.com/harivansh-afk/sandbox-agent.git
synced 2026-04-15 09:01:17 +00:00
chore: fix bad merge
This commit is contained in:
parent
1dd45908a3
commit
94353f7696
205 changed files with 19244 additions and 14866 deletions
115
docs/multiplayer.mdx
Normal file
115
docs/multiplayer.mdx
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
---
|
||||
title: "Multiplayer"
|
||||
description: "Use Rivet Actors to coordinate shared sessions."
|
||||
icon: "users"
|
||||
---
|
||||
|
||||
For multiplayer orchestration, use [Rivet Actors](https://rivet.dev/docs/actors).
|
||||
|
||||
Recommended model:
|
||||
|
||||
- One actor per collaborative workspace/thread.
|
||||
- The actor owns Sandbox Agent session lifecycle and persistence.
|
||||
- Clients connect to the actor and receive realtime broadcasts.
|
||||
|
||||
Use [actor keys](https://rivet.dev/docs/actors/keys) to map each workspace to one actor, [events](https://rivet.dev/docs/actors/events) for realtime updates, and [lifecycle hooks](https://rivet.dev/docs/actors/lifecycle) for cleanup.
|
||||
|
||||
## Example
|
||||
|
||||
<CodeGroup>
|
||||
|
||||
```ts Actor (server)
|
||||
import { actor, setup } from "rivetkit";
|
||||
import { SandboxAgent } from "sandbox-agent";
|
||||
import { RivetSessionPersistDriver, type RivetPersistState } from "@sandbox-agent/persist-rivet";
|
||||
|
||||
type WorkspaceState = RivetPersistState & {
|
||||
sandboxId: string;
|
||||
baseUrl: string;
|
||||
};
|
||||
|
||||
export const workspace = actor({
|
||||
createState: async () => {
|
||||
return {
|
||||
sandboxId: "sbx_123",
|
||||
baseUrl: "http://127.0.0.1:2468",
|
||||
} satisfies Partial<WorkspaceState>;
|
||||
},
|
||||
|
||||
createVars: async (c) => {
|
||||
const persist = new RivetSessionPersistDriver(c);
|
||||
const sdk = await SandboxAgent.connect({
|
||||
baseUrl: c.state.baseUrl,
|
||||
persist,
|
||||
});
|
||||
|
||||
const session = await sdk.resumeOrCreateSession({ id: "default", agent: "codex" });
|
||||
|
||||
const unsubscribe = session.onEvent((event) => {
|
||||
c.broadcast("session.event", event);
|
||||
});
|
||||
|
||||
return { sdk, session, unsubscribe };
|
||||
},
|
||||
|
||||
actions: {
|
||||
getSessionInfo: (c) => ({
|
||||
workspaceId: c.key[0],
|
||||
sandboxId: c.state.sandboxId,
|
||||
}),
|
||||
|
||||
prompt: async (c, input: { userId: string; text: string }) => {
|
||||
c.broadcast("chat.user", {
|
||||
userId: input.userId,
|
||||
text: input.text,
|
||||
createdAt: Date.now(),
|
||||
});
|
||||
|
||||
await c.vars.session.prompt([{ type: "text", text: input.text }]);
|
||||
},
|
||||
},
|
||||
|
||||
onSleep: async (c) => {
|
||||
c.vars.unsubscribe?.();
|
||||
await c.vars.sdk.dispose();
|
||||
},
|
||||
});
|
||||
|
||||
export const registry = setup({
|
||||
use: { workspace },
|
||||
});
|
||||
```
|
||||
|
||||
```ts Client (browser)
|
||||
import { createClient } from "rivetkit/client";
|
||||
import type { registry } from "./actors";
|
||||
|
||||
const client = createClient<typeof registry>({
|
||||
endpoint: process.env.NEXT_PUBLIC_RIVET_ENDPOINT!,
|
||||
});
|
||||
|
||||
const workspaceId = "workspace-42";
|
||||
const room = client.workspace.getOrCreate([workspaceId]);
|
||||
const conn = room.connect();
|
||||
|
||||
conn.on("chat.user", (event) => {
|
||||
console.log("user message", event);
|
||||
});
|
||||
|
||||
conn.on("session.event", (event) => {
|
||||
console.log("sandbox event", event);
|
||||
});
|
||||
|
||||
await conn.prompt({
|
||||
userId: "user-123",
|
||||
text: "Propose a refactor plan for auth middleware.",
|
||||
});
|
||||
```
|
||||
|
||||
</CodeGroup>
|
||||
|
||||
## Notes
|
||||
|
||||
- Keep sandbox calls actor-only. Browser clients should not call Sandbox Agent directly.
|
||||
- Use `@sandbox-agent/persist-rivet` so session history persists in actor state.
|
||||
- For client connection patterns, see [Rivet JavaScript client](https://rivet.dev/docs/clients/javascript).
|
||||
Loading…
Add table
Add a link
Reference in a new issue