Files
copilotkit__copilotkit/packages/shared/src/utils/conditions.ts
Tyler Slaton 96885b5959 refactor: consolidate V1/V2 packages into flat @copilotkit/* structure
Flatten all packages from packages/v1/* and packages/v2/* into packages/* —
every package now lives directly under the @copilotkit/ scope with no v1/v2
subdirectories.

- Move all v1 packages (react-core, react-ui, runtime, shared, etc.) from
  packages/v1/* to packages/*
- Absorb v2 react code into packages/react-core/src/v2/ (exported via /v2 subpath)
- Absorb v2 agent code into packages/runtime/src/agent/ (exported via /v2 subpath)
- Move v2 packages (core, angular, demo-agents, etc.) to packages/*
- Replace all @copilotkitnext/* imports with @copilotkit/* equivalents
- Keep @copilotkitnext/angular as the sole exception (angular remains on next)
- Update CI workflows, renovate config, release scripts for flat structure
- No public API surface changes — all exports fields are preserved

Co-authored-by: Alem Tuzlak <t.zlak@hotmail.com>
Signed-off-by: Tyler Slaton <tyler@copilotkit.ai>
2026-03-28 16:45:10 -07:00

117 lines
3.1 KiB
TypeScript

export type ComparisonRule =
| "EQUALS"
| "NOT_EQUALS"
| "GREATER_THAN"
| "LESS_THAN"
| "CONTAINS"
| "NOT_CONTAINS"
| "MATCHES"
| "STARTS_WITH"
| "ENDS_WITH";
export type LogicalRule = "AND" | "OR" | "NOT";
export type ExistenceRule = "EXISTS" | "NOT_EXISTS";
export type Rule = ComparisonRule | LogicalRule | ExistenceRule;
export interface BaseCondition {
rule: Rule;
path?: string;
}
export interface ComparisonCondition extends BaseCondition {
rule: ComparisonRule;
value: any;
}
export interface LogicalCondition extends BaseCondition {
rule: LogicalRule;
conditions: Condition[];
}
export interface ExistenceCondition extends BaseCondition {
rule: ExistenceRule;
}
export type Condition =
| ComparisonCondition
| LogicalCondition
| ExistenceCondition;
export function executeConditions({
conditions,
value,
}: {
conditions?: Condition[];
value: any;
}): boolean {
// If no conditions, consider it a pass
if (!conditions?.length) return true;
// Run all conditions (implicit AND)
return conditions.every((condition) => executeCondition(condition, value));
}
function executeCondition(condition: Condition, value: any): boolean {
const targetValue = condition.path
? getValueFromPath(value, condition.path)
: value;
switch (condition.rule) {
// Logical
case "AND":
return (condition as LogicalCondition).conditions.every((c) =>
executeCondition(c, value),
);
case "OR":
return (condition as LogicalCondition).conditions.some((c) =>
executeCondition(c, value),
);
case "NOT":
return !(condition as LogicalCondition).conditions.every((c) =>
executeCondition(c, value),
);
// Comparison
case "EQUALS":
return targetValue === (condition as ComparisonCondition).value;
case "NOT_EQUALS":
return targetValue !== (condition as ComparisonCondition).value;
case "GREATER_THAN":
return targetValue > (condition as ComparisonCondition).value;
case "LESS_THAN":
return targetValue < (condition as ComparisonCondition).value;
case "CONTAINS":
return (
Array.isArray(targetValue) &&
targetValue.includes((condition as ComparisonCondition).value)
);
case "NOT_CONTAINS":
return (
Array.isArray(targetValue) &&
!targetValue.includes((condition as ComparisonCondition).value)
);
case "MATCHES":
return new RegExp((condition as ComparisonCondition).value).test(
String(targetValue),
);
case "STARTS_WITH":
return String(targetValue).startsWith(
(condition as ComparisonCondition).value,
);
case "ENDS_WITH":
return String(targetValue).endsWith(
(condition as ComparisonCondition).value,
);
// Existence
case "EXISTS":
return targetValue !== undefined && targetValue !== null;
case "NOT_EXISTS":
return targetValue === undefined || targetValue === null;
}
}
function getValueFromPath(obj: any, path: string): any {
return path.split(".").reduce((acc, part) => acc?.[part], obj);
}