createContextProcessingNode
SUPPORT · function · Runtime value
Create one node that runs the complete context policy and returns the built context.
Use this when the graph does not need to route between selection and reduction phases.
Import
import { createContextProcessingNode } from '@jangts/agent-core/support';import { createContextProcessingNode } from '@jangts/agent-core/support';Other public entry points:@jangts/agent-core/support, @jangts/agent-core/support/context.
Definition
Type parameters
| Type parameter | Constraint | Default type |
|---|---|---|
State | — | — |
Result | — | — |
App | — | undefined |
Call
createContextProcessingNode<State, Result, App = undefined>(definition: ContextProcessingNodeDefinition<State, Result, App>): WorkflowNode<State, Result, App>Create one node that runs the complete context policy and returns the built context.
Use this when the graph does not need to route between selection and reduction phases.
| Type parameter | Constraint | Default type |
|---|---|---|
State | — | — |
Result | — | — |
App | — | undefined |
| Parameter | Type | Passing | Description |
|---|---|---|---|
definition | ContextProcessingNodeDefinition<State, Result, App> | Required | — |
Fields of definition
| Field | Type | Required | Description |
|---|---|---|---|
id | string | Required | Read-only. Stable node id referenced by routes and error handling. |
description | string | Required | Read-only. Required explanation of what the node does; also used in diagnostics. |
name | string | undefined | Optional | Read-only. Display name; defaults to id when omitted. |
requires | readonly (keyof State & string)[] | undefined | Optional | Read-only. State keys that must be present before this node runs; enforced by the engine. |
provides | readonly (keyof State & string)[] | undefined | Optional | Read-only. State keys this node is expected to produce; validated after run. |
routes | readonly WorkflowRoute<State, Result, App>[] | Required | Read-only. Candidate successors, evaluated in order. A getter must be pure; registration reads it once. |
startsRound | boolean | undefined | Optional | Read-only. Reserves a fresh round on entry. Use it for steps that may legitimately repeat; entering such a node when the round budget is exhausted fails with the configured exhausted error. |
onErrorNodeId | string | undefined | Optional | Read-only. Node entered when run/provides/route fails; contract errors always propagate instead. |
onErrorRouteId | string | undefined | Optional | Read-only. Route id reported with the recovery transition. |
plan | (state: Readonly<State>, context: WorkflowContext<App>) => ContextPlan | Required | Read-only. Builds the context plan; must be synchronous so budget failures surface before any I/O. |
request | (ModelPrepareRequest<string | ModelTransportDefinition<unknown>> & { modelId?: string; }) | ((state: Readonly<State>, context: WorkflowContext<App>) => ModelPrepareRequest<string | ModelTransportDefinition> & { modelId?: string; }) | undefined | Optional | Read-only. Model preparation request, either static or derived from the current node state. |
update | (result: ContextNodeResult, state: Readonly<State>) => Partial<State> | Required | Read-only. Maps the node result to the state fields to commit; return only changed fields. |
prepared | ((state: Readonly<State>, context: WorkflowContext<App>) => PreparedModelCall) | undefined | Optional | Read-only. Optional prebuilt model call, used instead of preparing request. |
policy | ContextPolicy | undefined | Optional | Read-only. Processing policy; omitted means validate (no reduction, audit checks only). |
compressors | readonly ContextCompressor[] | undefined | Optional | Read-only. Compressors referenced by compression steps; validated against the policy at creation. |
selectors | readonly ContextSelector[] | undefined | Optional | Read-only. Selectors referenced by model-driven selection; validated against the policy at creation. |
timeoutMs | number | undefined | Optional | Read-only. Per-node timeout in milliseconds; defaults to the Core call timeout. |
Returns: WorkflowNode<State, Result, App>.
Return value structure
| Field | Type | Required | Description |
|---|---|---|---|
id | string | Required | Read-only. Stable node id referenced by routes and error handling. |
description | string | Required | Read-only. Required explanation of what the node does; also used in diagnostics. |
name | string | undefined | Optional | Read-only. Display name; defaults to id when omitted. |
report | ((update: void | Readonly<Partial<State>>, context: NodeReportingContext) => WorkflowNodeReport) | undefined | Optional | Read-only. Optional application-reported detail, collected only when content logging is enabled. |
startsRound | boolean | undefined | Optional | Read-only. Reserves a fresh round on entry. Use it for steps that may legitimately repeat; entering such a node when the round budget is exhausted fails with the configured exhausted error. |
onErrorNodeId | string | undefined | Optional | Read-only. Node entered when run/provides/route fails; contract errors always propagate instead. |
onErrorRouteId | string | undefined | Optional | Read-only. Route id reported with the recovery transition. |
requires | readonly (keyof State & string)[] | undefined | Optional | Read-only. State keys that must be present before this node runs; enforced by the engine. |
provides | readonly (keyof State & string)[] | undefined | Optional | Read-only. State keys this node is expected to produce; validated after run. |
routes | readonly WorkflowRoute<State, Result, App>[] | Required | Read-only. Candidate successors, evaluated in order. A getter must be pure; registration reads it once. |
run | ((state: Readonly<State>, context: WorkflowContext<App>) => void | Partial<State> | Promise<void | Partial<State>>) | undefined | Optional | Read-only. Return only changed fields. Core commits them after cancellation and output checks. |
Examples
- Context processing is an ordinary Workflow node: Integrate selection, trimming, and compression through normal nodes and routes; Core records and schedules them uniformly.
Validate and assemble only, without compression yet
Beginner · Node.js
import { AgentCoreEngine, defineWorkflow, route } from '@jangts/agent-core/engine';
import { Support } from '@jangts/agent-core';
import type { BuiltContext, PreparedModelCall } from '@jangts/agent-core/types';
type State = { question: string; input?: BuiltContext; prepared?: PreparedModelCall; answer?: string };
const builder = Support.defineContextFragments<State>([
{ id: 'question', sourceId: 'request', trust: 'user', lifetime: 'turn', role: 'user', maxChars: 1000, format: state => state.question },
], { maxInputChars: 2000 });
const prepare = Support.createContextProcessingNode<State, string>({
id: 'prepare', description: '装配并校验输入', startsRound: true,
plan: state => builder.plan({ input: state }),
update: result => ({ input: result.input, prepared: result.prepared }),
routes: [route.to('reply')],
});
const workflow = defineWorkflow<State, string>({ id: 'chat', nodes: [prepare, {
id: 'reply', description: '使用同次准备回答', requires: ['input', 'prepared'],
async run(state, { model }) { const { value } = await model.invoke({ input: state.input!, prepared: state.prepared! }); return { answer: String(value) }; },
routes: [route.deliver('answer')],
}] });
const agent = new AgentCoreEngine({ workflow, model: { provider: { async *stream() { yield '服务正常'; } } } });
console.log(await agent.run({ question: '状态?' }));import { AgentCoreEngine, defineWorkflow, route } from '@jangts/agent-core/engine';
import { Support } from '@jangts/agent-core';
const builder = Support.defineContextFragments([
{ id: 'question', sourceId: 'request', trust: 'user', lifetime: 'turn', role: 'user', maxChars: 1000, format: state => state.question },
], { maxInputChars: 2000 });
const prepare = Support.createContextProcessingNode({
id: 'prepare', description: '装配并校验输入', startsRound: true,
plan: state => builder.plan({ input: state }),
update: result => ({ input: result.input, prepared: result.prepared }),
routes: [route.to('reply')],
});
const workflow = defineWorkflow({ id: 'chat', nodes: [prepare, {
id: 'reply', description: '使用同次准备回答', requires: ['input', 'prepared'],
async run(state, { model }) { const { value } = await model.invoke({ input: state.input, prepared: state.prepared }); return { answer: String(value) }; },
routes: [route.deliver('answer')],
}] });
const agent = new AgentCoreEngine({ workflow, model: { provider: { async *stream() { yield '服务正常'; } } } });
console.log(await agent.run({ question: '状态?' }));Add a history trimming policy to the same node contract
Configuration · Node.js
Put this node back into the same Workflow as the previous example; each run just adds history to State, and the model reply node does not change its interface. In a complete flow the reply target must exist.
import { Support } from '@jangts/agent-core';
import { route } from '@jangts/agent-core/engine';
import type { BuiltContext, PreparedModelCall } from '@jangts/agent-core/types';
type State = { question: string; history: { role: string; content: string }[]; input?: BuiltContext; prepared?: PreparedModelCall };
const builder = Support.defineContextFragments<State>([
{ id: 'question', sourceId: 'request', trust: 'user', lifetime: 'turn', role: 'user', maxChars: 1000, format: state => state.question },
{ id: 'history', sourceId: 'conversation', trust: 'user', lifetime: 'turn', role: 'user', maxChars: 10000, format: state => ({ messages: state.history }) },
], { maxInputChars: 1200 });
const prepare = Support.createContextProcessingNode<State, string>({
id: 'prepare', description: '按需要裁切旧历史', startsRound: true,
plan: state => builder.plan({ input: state }),
policy: { mode: 'reduce', steps: [{ id: 'recent', kind: 'trim', fragmentId: 'history', field: 'messages',
targetChars: 700, grouping: { kind: 'user-turn' }, keepGroups: 1 }] },
update: result => ({ input: result.input, prepared: result.prepared }),
routes: [route.to('reply')],
});
console.log(prepare.id);import { Support } from '@jangts/agent-core';
import { route } from '@jangts/agent-core/engine';
const builder = Support.defineContextFragments([
{ id: 'question', sourceId: 'request', trust: 'user', lifetime: 'turn', role: 'user', maxChars: 1000, format: state => state.question },
{ id: 'history', sourceId: 'conversation', trust: 'user', lifetime: 'turn', role: 'user', maxChars: 10000, format: state => ({ messages: state.history }) },
], { maxInputChars: 1200 });
const prepare = Support.createContextProcessingNode({
id: 'prepare', description: '按需要裁切旧历史', startsRound: true,
plan: state => builder.plan({ input: state }),
policy: { mode: 'reduce', steps: [{ id: 'recent', kind: 'trim', fragmentId: 'history', field: 'messages',
targetChars: 700, grouping: { kind: 'user-turn' }, keepGroups: 1 }] },
update: result => ({ input: result.input, prepared: result.prepared }),
routes: [route.to('reply')],
});
console.log(prepare.id);