INVOKE MODELS FROM MODELS
This guide shows you how to use context.runModel() to invoke one model's
method from inside another model's execute function.
Declare the dependency
Your extension's manifest must list the target model's extension in
dependencies. Without this declaration, runModel rejects the call at
runtime.
# manifest.yaml
name: "@mycollective/orchestrator"
version: "2026.07.10.1"
dependencies:
- "@mycollective/worker-model"
models:
- orchestrator.tsInvoke by definition name
If the target model already has a definition in the repository, pass its name as
definition:
const result = await context.runModel!({
definition: "my-worker",
method: "process",
arguments: { input: "some-value" },
});
if (result.ok) {
context.logger.info(`Worker produced ${result.resources.length} resource(s)`);
} else {
context.logger.error(`Worker failed: ${result.error.message}`);
}Invoke by model type
If no definition exists, pass the model type and a definition name. Swamp
auto-creates the definition in .swamp/auto-definitions/:
const result = await context.runModel!({
modelType: "@mycollective/worker-model",
name: "us-east-worker",
method: "execute",
arguments: { region: "us-east-1" },
});Handle the result
runModel returns a discriminated union and does not throw. Check result.ok
before accessing result.resources:
const result = await context.runModel!({
definition: "target",
method: "method",
arguments: args,
});
if (!result.ok) {
context.logger.error(result.error.message);
return { dataHandles: [] };
}
// result.resources is DataHandle[] — references to the target's output
const records = await context.readModelData!("target");
for (const handle of result.resources) {
const record = records.find((r) => r.name === handle.name);
// process record?.attributes
}Data ownership
Data written by the invoked model belongs to the target model's definition, not
the caller's. The DataHandle references in result.resources point to data
under the target's namespace, so context.readResource cannot read them. To use
that data in the caller's output, read it with context.readModelData and write
a derived resource under the caller's own spec.
Limits
A single top-level method execution enforces:
- Maximum call depth of 10
- Maximum 100 total
runModelinvocations - Cycle detection — a model cannot invoke itself, directly or transitively
- Vault isolation — the invoked model sees only its own extension's vault bindings
Exceeding any limit causes runModel to return
{ ok: false, error: { message } }.
Remote workers
runModel is not available on remote workers. On a worker, the call returns
{ ok: false } with an error message instead of running the target. If your
model's method may run on a worker, move the invocation to a local orchestrator
model, or chain the models as model_method steps in a workflow.
Refer to the
model reference for the
full runModel signature, and
Models, Types, and Methods
for the design rationale.