Volter World

Use a catalog twin

Take an exact catalog release into a local World and run the vendor's real SDK against it. This example uses Tavily search and extraction. Search returns synthetic stored pages; generated answer text is a labeled stub. It does not search the public web or evaluate answer quality.

Use Node 22.6 or newer and npm. No Tavily account, real API key or platform login is needed. Installation needs registry access. Start in an empty directory and save the files below.

Install the selected release

Choose a twin explains publishers, measurements and defaults. This example selects @volter/twin-tavily@1.0.1 from catalog snapshot 0.2.3.

Save package.json:

package.json
{
  "name": "search-app",
  "private": true,
  "type": "module",
  "dependencies": { "@tavily/core": "0.7.13" },
  "devDependencies": {
    "@volter/world": "3.0.63",
    "@volter/twin-tavily": "1.0.1"
  }
}

Save .env.example with an empty value:

.env.example
TAVILY_API_KEY=
npm install
npx volter world init --name search-app
tavily
COVERED:

Review the detected vendor. Inspect .volter/world.json: its service should name the selected package and version. Commit the config and lockfile. The catalog supplies discovery; the World config records which implementation this app runs.

Supply a synthetic page

Tavily searches public web content in production. This local example supplies its page content. The twin's /_twin/pages fixture API is explicitly twin-specific, not a Tavily production API. It creates stored data; a response handler must not pretend to create it.

Save seed-page.mjs:

seed-page.mjs
import assert from 'node:assert/strict';

const response = await fetch(`${process.env.TAVILY_TWIN_URL}/_twin/pages`, {
  method: 'POST',
  headers: { 'content-type': 'application/json' },
  body: JSON.stringify({
    url: 'https://schedule.example/yoga',
    title: 'Yoga schedule',
    content: 'Yoga starts Tuesday at 18:00.'
  })
});
assert.equal(response.status, 201);
console.log('synthetic page created');
npx volter world up
npx volter world clock set 2026-01-15T12:00:00Z
npx volter world run -- node seed-page.mjs
synthetic page created

The fixture is stored locally. The .example URL names the synthetic record; nothing fetches a real page at that address.

Run the real SDK

Save search.mjs. It uses the SDK's normal destination and the World's throwaway credential:

search.mjs
import assert from 'node:assert/strict';
import { tavily } from '@tavily/core';

const client = tavily({ apiKey: process.env.TAVILY_API_KEY });
const found = await client.search('yoga schedule', {
  maxResults: 3, includeAnswer: true, includeRawContent: 'text'
});
assert.equal(found.results[0].url, 'https://schedule.example/yoga');
assert.match(found.results[0].rawContent, /Tuesday at 18:00/);
assert.match(found.answer, /\[twin-stub\]/);
const extracted = await client.extract([
  'https://schedule.example/yoga', 'https://missing.example/page'
]);
assert.equal(extracted.results[0].url, 'https://schedule.example/yoga');
assert.match(extracted.results[0].rawContent, /Tuesday at 18:00/);
assert.equal(extracted.failedResults[0].url, 'https://missing.example/page');
console.log('search, extraction and missing-page checks passed');
npx volter world run -- node search.mjs
search, extraction and missing-page checks passed

These assertions check finding the fixture, reading its content and handling an absent page. They do not establish real search ranking, generated answer quality or support for every operation.

Inspect, repeat and stop

npx volter world log
npx volter world status

The log shows recorded state effects, rather than a transcript of every read. For the dashboard, see inspect a World.

Reset removes the run's state. Recreate the page and freeze the same clock before repeating:

npx volter world reset
npx volter world clock set 2026-01-15T12:00:00Z
npx volter world run -- node seed-page.mjs
npx volter world run -- node search.mjs
npx volter world down
search, extraction and missing-page checks passed
Stopped search-app

Seed and reset puts starting data in a project-owned seed. Shape the World for a test scripts stateless answers and faults. Update a twin covers changing the selected release deliberately.

View Markdown source

On this page