Practical guide to composing engines and app-owned runtime behavior from JavaScript.
This guide shows the intended split after the engine-profile hard cut:
InferenceSettingsgo run ./cmd/examples/geppetto-js-lab --script <your-script.js>
For most scripts:
gp.runnerconst gp = require("geppetto");
const engine = gp.engines.fromConfig({
apiType: "openai",
model: "gpt-4.1-mini",
apiKey: "test-openai-key",
});
const runtime = gp.runner.resolveRuntime({
systemPrompt: "Answer in one short line.",
runtimeKey: "demo",
});
const out = gp.runner.run({
engine,
runtime,
prompt: "hello",
});
Engine profiles now configure engine settings only.
Resolve one:
const resolved = gp.profiles.resolve({ profileSlug: "assistant" });
console.log(resolved.inferenceSettings.chat.engine);
Build an engine from it:
const engine = gp.engines.fromResolvedProfile(resolved);
Or skip the explicit resolve step:
const engine = gp.engines.fromProfile({ profileSlug: "assistant" });
The runtime object belongs to the application side.
Use it for:
systemPromptruntimeKeyExample:
const runtime = gp.runner.resolveRuntime({
systemPrompt: "Be terse.",
middlewares: [gp.middlewares.go("reorderToolResults")],
toolNames: ["search_docs"],
runtimeKey: "assistant-terse",
});
Do not expect gp.runner.resolveRuntime(...) to resolve engine profiles. That was removed intentionally.
This is the target shape:
const gp = require("geppetto");
const resolved = gp.profiles.resolve({ profileSlug: "assistant" });
const engine = gp.engines.fromResolvedProfile(resolved);
const runtime = gp.runner.resolveRuntime({
systemPrompt: "App-owned prompt",
runtimeKey: resolved.profileSlug,
metadata: {
profileSlug: resolved.profileSlug,
profileRegistry: resolved.registrySlug,
},
});
const handle = gp.runner.start({
engine,
runtime,
prompt: "hello",
});
If the host did not provide a registry, connect one from JS:
const gp = require("geppetto");
gp.profiles.connectStack([
"examples/js/geppetto/profiles/10-provider-openai.yaml",
"examples/js/geppetto/profiles/20-team-agent.yaml",
"examples/js/geppetto/profiles/30-user-overrides.yaml",
]);
const resolved = gp.profiles.resolve({ profileSlug: "assistant" });
console.log(resolved.registrySlug, resolved.inferenceSettings.chat.engine);
The older mixed model is gone:
effectiveRuntime on resolved profilesruntimeKey or runtimeFingerprintresolvedProfile builder optionuseResolvedProfile(...)runner.resolveRuntime({ profile: ... })If you need those behaviors, implement them explicitly in the host script or application code. That is now the intended architecture.