rule, similarity, llm_judge, metric) cover most use cases. If you need a custom scoring strategy, you can add a new executor function following the same pattern as the existing ones in src/main/eval-executors/.
1. Understand the existing pattern
Each eval type is a standalone async (or sync) function insrc/main/eval-executors/. There is no shared class hierarchy — each executor receives a typed config and returns a typed result:
2. Define the config and result types
Add your new config and result types tosrc/shared/eval-types.ts:
3. Implement the executor
Create a new file insrc/main/eval-executors/:
4. Wire it into the worker
Thesrc/workers/eval-worker.ts file dispatches to each executor based on eval.type. Add a case for your new type:
5. Add the config UI
Insrc/renderer/src/components/evals/, add a settings component for your config fields and register it in the eval case form — follow the pattern of the existing RuleConfig form component.
6. Add a DB migration (if needed)
If your executor needs additional columns in theeval_definitions settings blob, the config is stored as JSON so no column migration is required — just add your fields to the TypeScript interface.
7. Write tests
8. Update docs
Add your eval type to the Eval Framework section indocs/docs.json and create a new page at docs/eval-framework/my-custom.mdx following the pattern of the existing eval type pages.
Edit this page — Open a pull
request