Volter World

Search a synthetic page

Run an exact catalog release with the vendor's real SDK in a local World. 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. For a different vendor or release, use the twin you selected rather than copying this example's Tavily dependencies and fixtures.

Save package.json:

package.json
{
  "name": "search-app",
  "private": true,
  "type": "module",
  "dependencies": {
    "@tavily/core": "0.7.13"
  },
  "devDependencies": {
    "@volter/world": "3.0.158",
    "@volter/twin-tavily": "1.0.1",
    "@volter/world-core": "3.0.148",
    "@volter/world-runtime": "3.0.156",
    "@volter/world-console": "3.0.149"
  }
}

Save .env.example with an empty value:

.env.example
TAVILY_API_KEY=
npm install
./node_modules/.bin/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');
./node_modules/.bin/volter world up
./node_modules/.bin/volter world clock set 2026-01-15T12:00:00Z
./node_modules/.bin/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');
./node_modules/.bin/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

./node_modules/.bin/volter world log
./node_modules/.bin/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:

./node_modules/.bin/volter world reset
./node_modules/.bin/volter world clock set 2026-01-15T12:00:00Z
./node_modules/.bin/volter world run -- node seed-page.mjs
./node_modules/.bin/volter world run -- node search.mjs
./node_modules/.bin/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