defineAnswerFlow
KIT · function · Runtime value
Compile a reusable answer workflow.
Reusable answer workflow. Requests own cells and repair budgets; models remain caller-owned. The flow runs at most maxRepairs + 1 rounds: one generation pass, then one repair round per failing item set, and finally an explicit accepted/fallback/blocked result per item.
Import
import { defineAnswerFlow } from '@jangts/agent-core/kits/answering';import { defineAnswerFlow } from '@jangts/agent-core/kits/answering';Other public entry points:@jangts/agent-core/types, @jangts/agent-core/kits/answering, @jangts/agent-core/kits.
Definition
Type parameters
| Type parameter | Constraint | Default type |
|---|---|---|
Data | — | — |
Value | — | — |
App | — | undefined |
Call
defineAnswerFlow<Data, Value, App = undefined>(definition: AnswerFlowDefinition<Data, Value, App>): Readonly<{ run(request: { inputIds: readonly string[]; items: readonly AnswerItem<Data>[]; }, context: OperationContext<App>): Promise<AnswerResult<Data, Value>[]>; }>Compile a reusable answer workflow.
Reusable answer workflow. Requests own cells and repair budgets; models remain caller-owned. The flow runs at most maxRepairs + 1 rounds: one generation pass, then one repair round per failing item set, and finally an explicit accepted/fallback/blocked result per item.
| Type parameter | Constraint | Default type |
|---|---|---|
Data | — | — |
Value | — | — |
App | — | undefined |
| Parameter | Type | Passing | Description |
|---|---|---|---|
definition | AnswerFlowDefinition<Data, Value, App> | Required | — |
Fields of definition
| Field | Type | Required | Description |
|---|---|---|---|
maxItems | number | Required | Read-only. Maximum items in one batch; must be a positive integer. |
maxRepairs | number | Required | Read-only. Repair rounds; the flow runs at most maxRepairs + 1 rounds in total. |
reviewPolicy | "required" | "off" | "optional" | undefined | Optional | Read-only. Review policy; defaults to optional, required blocks on an unresolved review. |
canInvoke | (context: OperationContext<App>) => boolean | Required | Request-level budget guard; must return boolean synchronously. |
generate | (input: { readonly items: readonly AnswerItem<Data>[]; readonly repairs?: ReadonlyMap<string, readonly AnswerIssue[]>; readonly previous?: ReadonlyMap<string, Value> | undefined; }, context: OperationContext<App>) => Promise<ReadonlyMap<string, Value>> | Required | Produces values for the items that still need one. repairs carries the issues of a failed attempt and previous its rejected values. |
check | (input: { readonly item: AnswerItem<Data>; readonly value: Value; }, context: OperationContext<App>) => AnswerCheck<Value> | Required | Local check for one generated value; must return synchronously. |
review | ((input: { readonly items: readonly { item: AnswerItem<Data>; value: Value; }[]; }, context: OperationContext<App>) => Promise<ReadonlyMap<string, AnswerCheck<Value>>>) | undefined | Optional | Batch review; returns one check per reviewed item and must cover the submitted items. |
fallback | (input: { readonly item: AnswerItem<Data>; readonly issues: readonly AnswerIssue[]; }, context: OperationContext<App>) => RecoveryResult<Value> | Required | Last resort for a failed item; handled supplies a replacement value. |
observe | ((input: { readonly stageId: string; readonly results: readonly AnswerResult<Data, Value>[]; }, context: OperationContext<App>) => MaybePromise<void>) | undefined | Optional | Observes a stage outcome; failures must not affect the flow result. |
Returns: Readonly<{ run(request: { inputIds: readonly string[]; items: readonly AnswerItem<Data>[]; }, context: OperationContext<App>): Promise<AnswerResult<Data, Value>[]>; }>.
Return value structure
| Field | Type | Required | Description |
|---|---|---|---|
run | (request: { inputIds: readonly string[]; items: readonly AnswerItem<Data>[]; }, context: OperationContext<App>) => Promise<AnswerResult<Data, Value>[]> | Required | Run one answer batch. |
Examples
- Answering Flow: item-by-item generation, review, and local repair: Preserve coverage relationships over a split question batch and repair failing items without regenerating the ones that passed.
First handle one question that has a source
Beginner · Node.js
The offline example uses already-read body text directly to show the flow contract; when switching to model generation, the same generate port still applies.
import { Answering } from '@jangts/agent-core/kits/answering';
const flow = Answering.defineAnswerFlow<{ source: string }, string, {}>({
maxItems: 4, maxRepairs: 0, reviewPolicy: 'off', canInvoke: () => true,
async generate({ items }) { return new Map(items.map(item => [item.id, item.data.source])); },
check: ({ value }) => ({ status: value.trim() ? 'passed' : 'failed', issues: [] }),
fallback: () => ({ handled: false }),
});
const result = await flow.run({ inputIds: ['question-1'], items: [{ id: 'explain', inputIds: ['question-1'], sourceStatus: 'ready', data: { source: '普通对象可以实现节点合同。' } }] }, { app: {}, signal: new AbortController().signal });
console.log(result[0].status, result[0].value);import { Answering } from '@jangts/agent-core/kits/answering';
const flow = Answering.defineAnswerFlow({
maxItems: 4, maxRepairs: 0, reviewPolicy: 'off', canInvoke: () => true,
async generate({ items }) { return new Map(items.map(item => [item.id, item.data.source])); },
check: ({ value }) => ({ status: value.trim() ? 'passed' : 'failed', issues: [] }),
fallback: () => ({ handled: false }),
});
const result = await flow.run({ inputIds: ['question-1'], items: [{ id: 'explain', inputIds: ['question-1'], sourceStatus: 'ready', data: { source: '普通对象可以实现节点合同。' } }] }, { app: {}, signal: new AbortController().signal });
console.log(result[0].status, result[0].value);Keep run unchanged and add review plus one local repair
Configuration · Node.js
The example triggers one real local repair with an empty draft; production review should rely on real evidence instead of substituting string equality for semantic review.
import { Answering } from '@jangts/agent-core/kits/answering';
const flow = Answering.defineAnswerFlow<{ source: string }, string, {}>({
maxItems: 4, maxRepairs: 1, reviewPolicy: 'required', canInvoke: () => true,
async generate({ items, repairs }) { return new Map(items.map(item => [item.id, repairs?.has(item.id) ? item.data.source : ''])); },
check: ({ value }) => ({ status: value.trim() ? 'passed' : 'failed', issues: value.trim() ? [] : [{ code: 'EMPTY', message: '需要非空回答' }] }),
async review({ items }) { return new Map(items.map(({ item, value }) => [item.id, { status: value === item.data.source ? 'passed' as const : 'failed' as const, issues: [] }])); },
fallback: () => ({ handled: true, value: '当前资料不足,暂时无法回答。' }),
});
const result = await flow.run({ inputIds: ['question-1'], items: [{ id: 'explain', inputIds: ['question-1'], sourceStatus: 'ready', data: { source: '普通对象可以实现节点合同。' } }] }, { app: {}, signal: new AbortController().signal });
console.log(result[0].status, result[0].checks);import { Answering } from '@jangts/agent-core/kits/answering';
const flow = Answering.defineAnswerFlow({
maxItems: 4, maxRepairs: 1, reviewPolicy: 'required', canInvoke: () => true,
async generate({ items, repairs }) { return new Map(items.map(item => [item.id, repairs?.has(item.id) ? item.data.source : ''])); },
check: ({ value }) => ({ status: value.trim() ? 'passed' : 'failed', issues: value.trim() ? [] : [{ code: 'EMPTY', message: '需要非空回答' }] }),
async review({ items }) { return new Map(items.map(({ item, value }) => [item.id, { status: value === item.data.source ? 'passed' : 'failed', issues: [] }])); },
fallback: () => ({ handled: true, value: '当前资料不足,暂时无法回答。' }),
});
const result = await flow.run({ inputIds: ['question-1'], items: [{ id: 'explain', inputIds: ['question-1'], sourceStatus: 'ready', data: { source: '普通对象可以实现节点合同。' } }] }, { app: {}, signal: new AbortController().signal });
console.log(result[0].status, result[0].checks);First validate multi-question coverage to avoid missing inputs
Extension · Node.js
import { Answering } from '@jangts/agent-core/kits/answering';
const items = [
{ id: 'define', inputIds: ['q1'], sourceStatus: 'ready' as const, data: { source: '定义节点' } },
{ id: 'run', inputIds: ['q2'], sourceStatus: 'unavailable' as const, data: { source: '' } },
];
Answering.validateAnswerBatch(['q1', 'q2'], items, 4);
console.log('两个问题均有明确处理项,包括资料不可用的项。');import { Answering } from '@jangts/agent-core/kits/answering';
const items = [
{ id: 'define', inputIds: ['q1'], sourceStatus: 'ready', data: { source: '定义节点' } },
{ id: 'run', inputIds: ['q2'], sourceStatus: 'unavailable', data: { source: '' } },
];
Answering.validateAnswerBatch(['q1', 'q2'], items, 4);
console.log('两个问题均有明确处理项,包括资料不可用的项。');