feat: add workflow action runtime policies

This commit is contained in:
Xin Wang
2026-07-31 23:30:04 +08:00
parent c2f0f5eb04
commit f155f98e6e
10 changed files with 445 additions and 71 deletions

View File

@@ -10,6 +10,8 @@ export type WorkflowNodeType = "start" | "agent" | "action" | "handoff" | "end";
export type ContextPolicy = "inherit" | "fresh";
export type KnowledgeMode = "automatic" | "on_demand" | "disabled";
export type AgentEntryMode = "wait_user" | "generate" | "fixed_speech";
export type ActionResultAssignmentMode = "inherit" | "override" | "none";
export type ActionUserInputPolicy = "queue" | "block";
export type EdgeMode = "llm" | "expression" | "always";
export type ExpressionOperator =
| "eq"
@@ -44,7 +46,9 @@ export type WorkflowNodeData = {
turnConfig?: TurnConfig;
toolId?: string;
arguments?: Record<string, unknown>;
resultAssignmentMode?: ActionResultAssignmentMode;
resultAssignments?: Record<string, string>;
userInputPolicy?: ActionUserInputPolicy;
targetType?: "ai" | "human" | "queue" | "phone";
target?: string;
message?: string;
@@ -52,6 +56,33 @@ export type WorkflowNodeData = {
[key: string]: unknown;
};
/**
* Resolve how an Action writes tool results while preserving workflows saved
* before resultAssignmentMode existed. Those nodes explicitly passed an empty
* mapping at runtime, so an absent/empty mapping means "none", not "inherit".
*/
export function actionResultAssignmentMode(
data: WorkflowNodeData,
): ActionResultAssignmentMode {
if (
data.resultAssignmentMode === "inherit" ||
data.resultAssignmentMode === "override" ||
data.resultAssignmentMode === "none"
) {
return data.resultAssignmentMode;
}
return Object.keys(data.resultAssignments ?? {}).length > 0
? "override"
: "none";
}
/** Older Action nodes allowed input to continue, which matches queue. */
export function actionUserInputPolicy(
data: WorkflowNodeData,
): ActionUserInputPolicy {
return data.userInputPolicy === "block" ? "block" : "queue";
}
export type ExpressionRule = {
variable: string;
operator: ExpressionOperator;