Build and run a session-centered Geppetto JavaScript script.
This tutorial shows the hard-cut wrapper-first Geppetto JavaScript API:
const gp = require("geppetto");
The current public execution path is session-centered:
session.next().run() or session.next().runAsync().const settings = gp.inferenceProfiles.resolve("default");
console.log(settings.toJSON().chat.engine);
Hosts can configure the default registry. The example runner also accepts registry flags:
go run ./cmd/examples/geppetto-js-run run \
--script examples/js/geppetto/30_real_provider_multiturn.js \
--profile-registries "$HOME/.config/pinocchio/profiles.yaml" \
--profile default \
--timeout-ms 120000
const agent = gp.agent()
.name("getting-started")
.inference(settings)
.runDefaults({ timeoutMs: 120000 })
.build();
const session = agent.session()
.id("getting-started-chat")
.build();
Agents own provider/tool/event configuration. Sessions own conversational progression.
const result = session.next()
.system("Answer in one sentence.")
.user("What is a session-centered API?")
.run();
console.log(result.text());
const second = session.next()
.user("Summarize your previous answer in five words.")
.run();
console.log(second.text());
No public turn builder is required. session.next() uses the latest final turn as context and produces a new final turn.
const EventEmitter = require("events");
const events = new EventEmitter();
events.on("text-delta", ev => { if (ev.delta) process.stdout.write(ev.delta); });
const asyncAgent = gp.agent()
.inference(settings)
.events(events)
.build();
const asyncSession = asyncAgent.session().id("async-chat").build();
const handle = asyncSession.next()
.user("Write a short answer.")
.runAsync();
const asyncResult = await handle.promise;
handle.cancel() cancels the in-flight run. handle.close() releases the handle. Event listeners belong on the builder-level EventEmitter.
If the host provides storage, use gp.turnStores:
const store = gp.turnStores.default();
const durableAgent = gp.agent()
.inference(settings)
.store(store)
.build();
const durableSession = durableAgent.session()
.id("durable-chat")
.store(store)
.resumeLatest()
.build();
const durableResult = durableSession.next()
.user("Continue this durable conversation.")
.run();
resumeLatest() starts empty when there is no previous stored final turn. Use resumeLatest({ required: true }) for strict resume.
const fork = session.fork()
.id("getting-started-chat-fork")
.build();
const forkResult = fork.next()
.user("Give an alternative answer.")
.run();
Forks preserve imported history as base context and create new turn identities for derived runs.
Older scripts may refer to APIs that are no longer public:
gp.turn(...)agent.run(turn)agent.runAsync(turn)gp.turns.newTurn(...)gp.events.collector()createBuilder, createSession, and runInferenceUse agent.session(), session.next(), session.fork(), and storage-backed resumeLatest() instead.