Vifu Hub SDK
@vifu/hub is the official browser utility for the Vifu Hub API. It lets a game use Vifu platform capabilities without handling backend URLs, provider keys, or host messaging directly.
Use The Vifu Hub SDK For
- AI text generation and tool-style game actions
- player-owned save and restore
- declared data, media, and bundled files
- external links opened through the host
- game-owned tools that model calls or runtime agents may request
- Runtime Agents for NPCs, tutors, companions, and other independent entities
- dictionary, speech, review, camera, and other declared platform capabilities
Do not call OpenAI, Anthropic, OpenRouter, Vifu platform API, LM Studio, Ollama, or other backend endpoints directly from deployed game JavaScript.
Install
npm
Use npm when your game has a bundler or build step:
npm install @vifu/hub@alphaimport * as hub from "@vifu/hub";
await hub.ready();AI
Use hub.ai.generateText(...) for the common case: one game asks Vifu AI for text, classification, or a tool-backed action. The game does not choose the backend provider; the active Vifu session owns provider routing, credentials, quota, and the player's selected Mind.
const result = await hub.ai.generateText({
model: "basic",
messages: [
{ role: "user", content: "Give the player a short hint." }
]
});
showHint(result.content);Model names are product-level aliases:
| Model | Use it for |
|---|---|
basic | Low-cost NPC text, hints, summaries, and simple classification. |
quality | Higher-quality story turns, planning, and reasoning. |
Backend provider names are intentionally not part of the game contract.
Tool Calls
Pass tools directly to generateText when the visible game actions only matter for this turn:
const result = await hub.ai.generateText({
model: "basic",
messages: [{ role: "user", content: "The player says: open blue door." }],
tools: {
openDoor: {
description: "Open a visible door by color.",
parameters: {
type: "object",
properties: {
color: { type: "string", enum: ["blue", "red", "green"] }
},
required: ["color"],
additionalProperties: false
},
execute: ({ color }) => openDoor(String(color))
}
},
maxSteps: 3
});This is the best default for existing games such as AIventure. You do not need to create a Runtime Agent just to expose one turn's tools.
Runtime Agents
Use a Runtime Agent only when a specific entity needs isolated tools, instructions, and run history. Examples: two NPCs speaking at the same time, a tutor and a director sharing a scene, or a companion that must not see an NPC's private tools.
const openDoorTool = hub.tool({
name: "open_door",
description: "Open a visible door by color.",
parameters: {
type: "object",
properties: {
color: { type: "string", enum: ["blue", "red", "green"] }
},
required: ["color"],
additionalProperties: false
},
execute: ({ color }) => openDoor(String(color))
});
const guard = hub.agent({
name: "Blue Door Guard",
kind: "npc",
instructions: "You guard the current puzzle room.",
tools: [openDoorTool]
});
const result = await hub.run(guard, "The player says: open blue door", {
state: currentRoomSummary(),
maxSteps: 3
});name is only a readable label. Vifu assigns the internal runtime id automatically. Omit mind when the user or host should choose the active Mind; set mind only when the game intentionally binds this entity to a specific Vifu Mind.
| Need | Use |
|---|---|
| Existing game with one active AI turn | hub.ai.generateText(...) |
| One turn with temporary game actions | hub.ai.generateText({ tools }) |
| Multiple independent NPCs, tutors, companions, or directors | hub.agent(...) and hub.run(...) |
Game State
hub.gameState.configure({
slotId: "autosave",
source: "door-quest",
serialize: ({ reason }) => ({
schema: "door-quest.save.v1",
reason,
roomId: currentRoom.id,
inventory: player.inventory
}),
restore: (stateBlob) => {
restoreGame(stateBlob);
}
});
await hub.gameState.restore();
await hub.gameState.save({ reason: "checkpoint" });Resources
Declare resources in manifest.json:
{
"name": "resource-demo",
"data": {
"world": { "src": "assets/world.json", "type": "json" }
},
"media": {
"intro": { "src": "assets/intro.mp3", "type": "audio" }
},
"bundle": {
"include": ["assets/**"]
}
}Read them through the Vifu Hub SDK:
const world = await hub.resources.readJson("world");
const introUrl = hub.resources.mediaUrl("intro");
const spriteUrl = hub.resources.fileUrl("assets/player.png");Game code should not construct /v1/assets/runtime-* URLs manually.
Status
console.log(hub.status());Outside Vifu, managed platform capabilities may be unavailable. Your game should still boot and remain playable with local fallback behavior.