@frayit/sdk
v1.2.0
Published
Official Frayit SDK for chat and voice services with behavioral risk detection.
Maintainers
Readme
@frayit/sdk
Official TypeScript SDK for Frayit chat moderation and voice services.
Server-side only for credentialed APIs. Do not expose clientId and clientSecret in browser bundles or game clients.
Install
npm install @frayit/sdkInitialize
import { FrayitClient } from "@frayit/sdk"
const client = new FrayitClient({
clientId: process.env.FRAYIT_CLIENT_ID!,
clientSecret: process.env.FRAYIT_CLIENT_SECRET!,
baseUrl: process.env.FRAYIT_BASE_URL!,
voiceTimeoutMs: 1500,
})
await client.initialize()Call initialize() once at service startup.
Chat APIs
evaluateChat
const result = await client.evaluateChat({
player_id: "player-123",
session_id: "session-1",
channel_id: "global",
message: "hello world",
})sendMessage
const result = await client.sendMessage({
player_id: "player-123",
session_id: "session-1",
channel_id: "global",
message: "gg wp",
})connectChat (Managed mode only)
const channel = await client.connectChat("player-123", "global", {
onMessage: (event) => console.log(event),
onError: (error) => console.error(error),
})
await channel.disconnect()Voice Backend APIs
Use these from your studio backend to issue LiveKit access and manage room state.
Join voice channel
const join = await client.joinVoiceChannel({
channel_id: "team-red",
player_id: "player-123",
session_id: "session-1",
max_participants: 8,
})
console.log(join.livekit_url, join.livekit_token)Server mute or unmute player
await client.setServerMute({
channel_id: "team-red",
player_id: "player-123",
muted: true,
})Get room state
const room = await client.getVoiceRoomState("team-red")
console.log(room.participant_count, room.participants)Leave and close room
await client.leaveVoiceChannel({
channel_id: "team-red",
player_id: "player-123",
})
await client.closeVoiceChannel("team-red")Client-Side Voice State Helpers
These helpers are local state only. They do not call network APIs.
client.setSelfMuted(true)
client.setSelfDeafened(false)
client.setPeerMutedLocally("player-456", true)
const canPlay = client.shouldPlayPeerAudio("player-456")
const isSelfMuted = client.isSelfMuted
const muteMap = client.getPeerMuteMapSnapshot()Production Architecture for Voice
- Your backend calls
joinVoiceChannel. - Backend sends only
livekit_urlandlivekit_tokento the game client. - Game client connects directly to LiveKit.
- Backend uses
setServerMute,getVoiceRoomState,leaveVoiceChannel, andcloseVoiceChannelfor control and moderation.
Config Options
| Option | Default | Description |
|---|---|---|
| chatTimeoutMs | 100 | Timeout for evaluateChat and sendMessage. |
| voiceTimeoutMs | 1500 | Timeout for voice APIs (join, leave, close, room, mute). |
| tokenRequestTimeoutMs | 5000 | Timeout for token endpoint. |
| tokenPrefetchWindowMs | 1800000 | Refresh token this many ms before expiry. |
| idleRefreshCheckIntervalMs | 30000 | Periodic background refresh check interval. |
| tokenFailureBackoffMs | 20000 | Backoff after failed refresh when token still valid. |
| maxRetries | 2 | Retry count for transient failures. |
| retryBaseDelayMs | 200 | Exponential backoff base delay. |
| circuitBreakerFailureThreshold | 5 | Consecutive failures before circuit opens (chat APIs). |
| circuitBreakerOpenDurationMs | 20000 | Open-state duration before half-open probe. |
Fail-Open Behavior (Chat APIs)
When Frayit is unreachable, evaluateChat() and sendMessage() return fail-open results so gameplay is not blocked.
Dispose
client.dispose()