Skip to content
中文

ModelRunner: input can be shortened while the output contract stays the same ​

Execute one model interaction through the real Provider port and return a value plus the invocation for this call.

invoke('text') and invoke({input: 'text'}) both return ModelResult<string>; shortening the input does not produce a second output format. Structured transports only change the type of value and do not switch to a bare result. Errors are delivered through Promise rejection.

The Runner is a request-level execution object: call counts and the journal accumulate, so a Runner whose budget is exhausted should not be treated as a permanent singleton. Stable model configuration can be bound to the Engine, and each Workflow execution receives an in-request Runner.

Defaults come from modelRunnerDefaults and are the runtime baseline when arguments are missing, not supplier capacity or the best values for all scenarios. Character body text, transport declarations, output characters, and token reservations are different budgets. Without an explicit token counter, do not guess a character/token ratio. lastCall is a snapshot of the most recently completed call and cannot be used to correlate concurrent requests; use the invocation returned by each call instead.

Progressive examples for the same business case ​

Two inputs for the same output ​

Beginner · Node.js

ts
import { ModelRunner } from '@jangts/agent-core/model';
const provider = {
  async *stream(messages: readonly { content: string }[]) {
    yield '收到:' + messages.at(-1)!.content;
  },
};
const runner = new ModelRunner({ provider });
const first = await runner.invoke('你好');
const second = await runner.invoke({ input: '你好' });
console.log(first.value, second.value);
console.log(first.invocation.invocationId);
js
import { ModelRunner } from '@jangts/agent-core/model';
const provider = {
    async *stream(messages) {
        yield '收到:' + messages.at(-1).content;
    },
};
const runner = new ModelRunner({ provider });
const first = await runner.invoke('你好');
const second = await runner.invoke({ input: '你好' });
console.log(first.value, second.value);
console.log(first.invocation.invocationId);

Add budget and request cancellation ​

Configuration · Node.js

ts
import { ModelRunner } from '@jangts/agent-core/model';
const provider = {
  async *stream(messages: readonly { content: string }[]) {
    yield '收到:' + messages.at(-1)!.content;
  },
};
const runner = new ModelRunner({ provider, maxCalls: 2, maxInputChars: 4000,
  maxOutputChars: 2000, callTimeoutMs: 15000,
  execution: { signal: AbortSignal.timeout(20000) },
});
const result = await runner.invoke({ input: '你好', stageId: 'reply', maxOutputTokens: 600 });
console.log(result.value, runner.remainingCalls);
js
import { ModelRunner } from '@jangts/agent-core/model';
const provider = {
    async *stream(messages) {
        yield '收到:' + messages.at(-1).content;
    },
};
const runner = new ModelRunner({ provider, maxCalls: 2, maxInputChars: 4000,
    maxOutputChars: 2000, callTimeoutMs: 15000,
    execution: { signal: AbortSignal.timeout(20000) },
});
const result = await runner.invoke({ input: '你好', stageId: 'reply', maxOutputTokens: 600 });
console.log(result.value, runner.remainingCalls);

Add an independent ordered output receiver ​

Extension · Node.js

sink.output is awaited in order. model.output is a proposal that has not been fully validated, so tool operations proposed by the model must not be executed here.

ts
import { ModelRunner } from '@jangts/agent-core/model';
const provider = {
  async *stream(messages: readonly { content: string }[]) {
    yield '收到:' + messages.at(-1)!.content;
  },
};
const events: string[] = [];
const runner = new ModelRunner({ provider, sink: {
  async output(event) { events.push(event.type); },
} });
const result = await runner.invoke('你好');
console.log(result.value, events);
js
import { ModelRunner } from '@jangts/agent-core/model';
const provider = {
    async *stream(messages) {
        yield '收到:' + messages.at(-1).content;
    },
};
const events = [];
const runner = new ModelRunner({ provider, sink: {
        async output(event) { events.push(event.type); },
    } });
const result = await runner.invoke('你好');
console.log(result.value, events);

Policies & implementations ​

API reference, usage examples and developer guides.