Token导航 LogoToken导航TokenDH.com
开发敏感数据github未标认证来源可访问clear审计异常

rivetkit-client-swiftrivetkit client Swift 命令行

Agent Skill

rivetkit-client-swift 用于记录任务执行中的错误、用户纠正、经验和能力缺口,适合在 Codex、Claude、Cursor、Gemini CLI 中希望让 Agent 持续沉淀问题、修正和最佳实践时使用。可结合来源仓库、安装命令和原始 README 继续核验具体用法。安装前建议确认权限范围、维护状态,以及是否会触发联网、命令执行或文件读写。

总安装

107,712

周安装

4,362

GitHub Stars

14

下载量

34,848
CodexClaudeCursorGemini CLI

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

GitHub

来源数

3

许可证

MIT

最后核验

2026-05-01

来源状态

来源可访问

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:rivetkit-client-swift(rivetkit client Swift 命令行)
来源仓库:https://github.com/rivet-dev/skills
仓库路径:skills/rivetkit-client-swift
安装命令:
npx skills add https://github.com/rivet-dev/skills --skill rivetkit-client-swift
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。不同来源提供的安装方式可能略有差异;本站展示可直接复制的安装命令,安装前请核对来源页面。

skills.shnpx skills
npx skills add https://github.com/rivet-dev/skills --skill rivetkit-client-swift

简介

Swift 客户端,用于通过无状态和有状态连接模式连接到 Rivet Actors。

  • 支持无状态操作调用和通过 AsyncStream 进行实时事件流的持久 WebSocket 连接
  • 提供带有 0-5 个位置参数的类型化操作调用,以及用于更大参数计数的原始 JSON 回退
  • 包括通过状态更改、错误、打开和关闭流进行连接生命周期监控
  • 支持自定义 onRequest 的低级 HTTP 和 WebSocket 访问
  • 和 onWebSocket
  • 处理程序
  • 需要显式端点配置;从环境变量或 URL 身份验证语法中读取可选的命名空间和令牌

SKILL.md

RivetKit Swift Client

Use this skill when building Swift clients that connect to Rivet Actors with RivetKitClient.

Version

RivetKit version: 2.2.0

Error Handling Policy

  • Prefer fail-fast behavior by default.
  • Avoid broad do/catch unless absolutely needed.
  • If a catch block is used, handle the error explicitly, at minimum by logging it.

Install

Add the Swift package dependency and import RivetKitClient:

// Package.swift
dependencies: [
    .package(url: "https://github.com/rivet-dev/rivetkit-swift", from: "2.0.0")
]

targets: [
    .target(
        name: "MyApp",
        dependencies: [
            .product(name: "RivetKitClient", package: "rivetkit-swift")
        ]
    )
]

Minimal Client

Endpoint URL

import RivetKitClient

let config = try ClientConfig(
    endpoint: "https://my-namespace:pk_...@api.rivet.dev"
)
let client = RivetKitClient(config: config)

let handle = client.getOrCreate("counter", ["my-counter"])
let count: Int = try await handle.action("increment", 1, as: Int.self)

Explicit Fields

import RivetKitClient

let config = try ClientConfig(
    endpoint: "https://api.rivet.dev",
    namespace: "my-namespace",
    token: "pk_..."
)
let client = RivetKitClient(config: config)

let handle = client.getOrCreate("counter", ["my-counter"])
let count: Int = try await handle.action("increment", 1, as: Int.self)

Stateless vs Stateful

import RivetKitClient

let config = try ClientConfig(endpoint: "http://localhost:6420")
let client = RivetKitClient(config: config)

let handle = client.getOrCreate("counter", ["my-counter"])

// Stateless: each call is independent
let current: Int = try await handle.action("getCount", as: Int.self)
print("Current count: \(current)")

// Stateful: keep a connection open for realtime events
let conn = handle.connect()

// Subscribe to events using AsyncStream
let eventTask = Task {
    for await count in await conn.events("count", as: Int.self) {
        print("Event: \(count)")
    }
}

_ = try await conn.action("increment", 1, as: Int.self)

eventTask.cancel()
await conn.dispose()
await client.dispose()

Getting Actors

import RivetKitClient

struct GameInput: Encodable {
    let mode: String
}

let config = try ClientConfig(endpoint: "http://localhost:6420")
let client = RivetKitClient(config: config)

// Get or create an actor
let room = client.getOrCreate("chatRoom", ["room-42"])

// Get an existing actor (fails if not found)
let existing = client.get("chatRoom", ["room-42"])

// Create a new actor with input
let created = try await client.create(
    "game",
    ["game-1"],
    options: CreateOptions(input: GameInput(mode: "ranked"))
)

// Get actor by ID
let byId = client.getForId("chatRoom", "actor-id")

// Resolve actor ID
let resolvedId = try await room.resolve()
print("Resolved ID: \(resolvedId)")

await client.dispose()

Actions support positional overloads for 0–5 args:

import RivetKitClient

let config = try ClientConfig(endpoint: "http://localhost:6420")
let client = RivetKitClient(config: config)
let handle = client.getOrCreate("counter", ["my-counter"])

let count: Int = try await handle.action("getCount")
let updated: String = try await handle.action("rename", "new-name")
let ok: Bool = try await handle.action("setScore", "user-1", 42)

print("Count: \(count), Updated: \(updated), OK: \(ok)")
await client.dispose()

If you need more than 5 arguments, use the raw JSON fallback:

import RivetKitClient

let config = try ClientConfig(endpoint: "http://localhost:6420")
let client = RivetKitClient(config: config)
let handle = client.getOrCreate("counter", ["my-counter"])

let args: [JSONValue] = [
    .string("user-1"),
    .number(.int(42)),
    .string("extra"),
    .string("more"),
    .string("args"),
    .string("here")
]
let ok: Bool = try await handle.action("setScore", args: args, as: Bool.self)
print("OK: \(ok)")

await client.dispose()

Connection Parameters

import RivetKitClient

struct ConnParams: Encodable {
    let authToken: String
}

let config = try ClientConfig(endpoint: "http://localhost:6420")
let client = RivetKitClient(config: config)

let chat = client.getOrCreate(
    "chatRoom",
    ["general"],
    options: GetOrCreateOptions(params: ConnParams(authToken: "jwt-token-here"))
)

let conn = chat.connect()

// Use the connection...
for await status in await conn.statusChanges() {
    print("Status: \(status.rawValue)")
    if status == .connected {
        break
    }
}

await conn.dispose()
await client.dispose()

Subscribing to Events

import RivetKitClient

let config = try ClientConfig(endpoint: "http://localhost:6420")
let client = RivetKitClient(config: config)
let conn = client.getOrCreate("chatRoom", ["general"]).connect()

// Subscribe to events using AsyncStream
let messageTask = Task {
    for await (from, body) in await conn.events("message", as: (String, String).self) {
        print("\(from): \(body)")
    }
}

// For one-time events, break after receiving
let gameOverTask = Task {
    for await _ in await conn.events("gameOver", as: Void.self) {
        print("done")
        break
    }
}

// Let it run for a bit
try await Task.sleep(for: .seconds(5))

// Cancel when done
messageTask.cancel()
gameOverTask.cancel()
await conn.dispose()
await client.dispose()

Event streams support 0–5 typed arguments. If you need raw values or more than 5 arguments, use JSONValue:

import RivetKitClient

let config = try ClientConfig(endpoint: "http://localhost:6420")
let client = RivetKitClient(config: config)
let conn = client.getOrCreate("chatRoom", ["general"]).connect()

let rawTask = Task {
    for await args in await conn.events("message") {
        print(args)
    }
}

try await Task.sleep(for: .seconds(5))
rawTask.cancel()
await conn.dispose()
await client.dispose()

Connection Lifecycle

import RivetKitClient

let config = try ClientConfig(endpoint: "http://localhost:6420")
let client = RivetKitClient(config: config)
let conn = client.getOrCreate("chatRoom", ["general"]).connect()

// Monitor status changes (immediately yields current status)
let statusTask = Task {
    for await status in await conn.statusChanges() {
        print("status: \(status.rawValue)")
    }
}

// Monitor errors
let errorTask = Task {
    for await error in await conn.errors() {
        print("error: \(error.group).\(error.code)")
    }
}

// Monitor open/close events
let openTask = Task {
    for await _ in await conn.opens() {
        print("connected")
    }
}

let closeTask = Task {
    for await _ in await conn.closes() {
        print("disconnected")
    }
}

// Check current status
let current = await conn.currentStatus
print("Current status: \(current.rawValue)")

// Let it run for a bit
try await Task.sleep(for: .seconds(5))

// Cleanup
statusTask.cancel()
errorTask.cancel()
openTask.cancel()
closeTask.cancel()
await conn.dispose()
await client.dispose()

Low-Level HTTP & WebSocket

For actors that implement onRequest or onWebSocket, you can call them directly:

import RivetKitClient

let config = try ClientConfig(endpoint: "http://localhost:6420")
let client = RivetKitClient(config: config)
let handle = client.getOrCreate("chatRoom", ["general"])

// Raw HTTP request
let response = try await handle.fetch("history")
let history: [String] = try response.json([String].self)
print("History: \(history)")

// Raw WebSocket connection
let websocket = try await handle.websocket(path: "stream")
try await websocket.send(text: "hello")
let message = try await websocket.receive()
print("Received: \(message)")

await client.dispose()

Calling from Backend

Use the same client in server-side Swift (Vapor, Hummingbird, etc.):

import RivetKitClient

let config = try ClientConfig(endpoint: "http://localhost:6420")
let client = RivetKitClient(config: config)

let handle = client.getOrCreate("counter", ["server-counter"])
let count: Int = try await handle.action("increment", 1, as: Int.self)
print("Count: \(count)")

await client.dispose()

Error Handling

import RivetKitClient

let config = try ClientConfig(endpoint: "http://localhost:6420")
let client = RivetKitClient(config: config)

do {
    _ = try await client.getOrCreate("user", ["user-123"])
        .action("updateUsername", "ab", as: String.self)
} catch let error as ActorError {
    print("Error code: \(error.code)")
    print("Metadata: \(String(describing: error.metadata))")
}

await client.dispose()

If you need an untyped response, you can decode to JSONValue:

import RivetKitClient

let config = try ClientConfig(endpoint: "http://localhost:6420")
let client = RivetKitClient(config: config)
let handle = client.getOrCreate("data", ["raw"])

let value: JSONValue = try await handle.action("getRawPayload")
print("Raw value: \(value)")

await client.dispose()

Concepts

Keys

Keys uniquely identify actor instances. Use compound keys (arrays) for hierarchical addressing:

import RivetKitClient

let config = try ClientConfig(endpoint: "http://localhost:6420")
let client = RivetKitClient(config: config)

// Use compound keys for hierarchical addressing
let room = client.getOrCreate("chatRoom", ["org-acme", "general"])
let actorId = try await room.resolve()
print("Actor ID: \(actorId)")

await client.dispose()

Don't build keys with string interpolation like "org:\(userId)" when userId contains user data. Use arrays instead to prevent key injection attacks.

Environment Variables

ClientConfig reads optional values from environment variables:

  • RIVET_NAMESPACE - Namespace (can also be in endpoint URL)
  • RIVET_TOKEN - Authentication token (can also be in endpoint URL)
  • RIVET_RUNNER - Runner name (defaults to "default")

The endpoint parameter is always required. There is no default endpoint.

Endpoint Format

Endpoints support URL auth syntax:

https://namespace:token@api.rivet.dev

You can also pass the endpoint without auth and provide RIVET_NAMESPACE and RIVET_TOKEN separately. For serverless deployments, set the endpoint to your app's /api/rivet URL. See Endpoints for details.

API Reference

Client

  • RivetKitClient(config:) - Create a client with a config
  • ClientConfig - Configure endpoint, namespace, and token
  • client.get() / getOrCreate() / getForId() / create() - Get actor handles
  • client.dispose() - Dispose the client and all connections

ActorHandle

  • handle.action(name, args..., as:) - Stateless action call
  • handle.connect() - Create a stateful connection
  • handle.resolve() - Get the actor ID
  • handle.getGatewayUrl() - Get the raw gateway URL
  • handle.fetch(path, request:) - Raw HTTP request
  • handle.websocket(path:) - Raw WebSocket connection

ActorConnection

  • conn.action(name, args..., as:) - Action call over WebSocket
  • conn.events(name, as:) - AsyncStream of typed events
  • conn.statusChanges() - AsyncStream of status changes
  • conn.errors() - AsyncStream of connection errors
  • conn.opens() - AsyncStream that yields on connection open
  • conn.closes() - AsyncStream that yields on connection close
  • conn.currentStatus - Current connection status
  • conn.dispose() - Close the connection

Types

  • ActorConnStatus - Connection status enum (.idle, .connecting, .connected, .disconnected, .disposed)
  • ActorError - Typed actor errors with group, code, message, metadata
  • JSONValue - Raw JSON value for untyped responses

Need More Than the Client?

If you need more about Rivet Actors, registries, or server-side RivetKit, add the main skill:

npx skills add rivet-dev/skills

Then use the rivetkit skill for backend guidance.

适合场景

01

用户想查找某类 Agent Skill 时

02

需要根据任务场景推荐可安装能力包时

03

需要对比不同来源的安装命令和来源信息时

04

需要参考平台分布和安装热度时

能力概览

能力 1

按任务关键词查找相关 Skills

能力 2

展示可复制的安装命令

能力 3

保留来源站点、仓库和原始说明,方便继续核验

能力 4

补充不同宿主或平台的使用分布数据

能力 5

展示第三方安全扫描或审计结果

安装后应在对应宿主中按原始 README 的触发条件使用;具体调用方式请以来源页面和 README 为准。

平台分布

github-copilot

26.94%
按下载量换算9,388

Claude Code

22.7%
按下载量换算7,910

Cursor

18.34%
按下载量换算6,391

Codex

12.96%
按下载量换算4,516

Gemini CLI

6.9%
按下载量换算2,405

continue

3%
按下载量换算1,045

安全审计

Gen Agent Trust Hub

通过

Socket

通过

Snyk

未通过

权限和风险

敏感数据

该 Skill 可能接触密钥、Token、环境变量或敏感配置,应进入高风险复核队列,默认不自动发布。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。来源安全扫描存在 warning/failed 结果,不能写成本站确认安全。

来源信息

继续浏览同类 Skills