Register
Login
Resources
Docs Blog Datasets Glossary Case Studies Tutorials & Webinars
Product
Data Engine LLMs Platform Enterprise
Pricing Explore
Connect to our Discord channel

hooks.js 2.7 KB

You have to be logged in to leave a comment. Sign In
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
  1. let counter = 0;
  2. /**
  3. * Handles different extension hooks for promptfoo.
  4. *
  5. * @param {string} hookName - The name of the hook being called. Can be one of
  6. * "beforeAll", "beforeEach", "afterEach", or "afterAll".
  7. * @param {Object} context - A dictionary containing contextual information for the hook.
  8. * The contents of this dictionary vary depending on the hook being called.
  9. * @returns {Object|undefined} The "beforeAll" and "beforeEach" hooks should return the context object,
  10. * while the "afterAll" and "afterEach" hooks should not return anything.
  11. */
  12. async function extensionHook(hookName, context) {
  13. if (hookName === 'beforeAll') {
  14. console.log(`Setting up test suite: ${context.suite.description || 'Unnamed suite'}`);
  15. console.log(`Total prompts: ${context.suite.prompts?.length || 0}`);
  16. console.log(`Total providers: ${context.suite.providers?.length || 0}`);
  17. console.log(`Total tests: ${context.suite.tests?.length || 0}`);
  18. // Add an additional test case to the suite:
  19. context.suite.tests.push({
  20. vars: {
  21. body: "It's a beautiful day",
  22. language: 'Spanish',
  23. },
  24. assert: [{ type: 'contains', value: 'Es un día hermoso.' }],
  25. });
  26. // Add an additional default assertion to the suite:
  27. context.suite.defaultTest.assert.push({ type: 'is-json' });
  28. return context;
  29. } else if (hookName === 'beforeEach') {
  30. console.log(`Preparing test`);
  31. // All languages are now pirate:
  32. context.test.vars.language = `Pirate ${context.test.vars.language}`;
  33. return context;
  34. } else if (hookName === 'afterEach') {
  35. console.log(
  36. `Completed test ${counter++}${context.result ? `, Result: ${context.result.success ? 'Pass' : 'Fail'}, Score: ${context.result.score}` : ''}`,
  37. );
  38. // Access sessionId if available (from multi-turn conversations or stateful tests)
  39. if (context.result?.metadata?.sessionId) {
  40. console.log(`Session ID: ${context.result.metadata.sessionId}`);
  41. }
  42. if (context.result?.metadata?.sessionIds) {
  43. console.log(`Session IDs: ${context.result.metadata.sessionIds}`);
  44. }
  45. } else if (hookName === 'afterAll') {
  46. console.log('Test suite completed');
  47. console.log(`Total tests run: ${context.results?.length || 0}`);
  48. const successes = context.results?.filter((r) => r.success).length || 0;
  49. const failures = context.results?.filter((r) => !r.success).length || 0;
  50. console.log(`Successes: ${successes}`);
  51. console.log(`Failures: ${failures}`);
  52. const totalTokenUsage =
  53. context.results?.reduce((sum, r) => sum + (r.response?.tokenUsage?.total || 0), 0) || 0;
  54. console.log(`Total token usage: ${totalTokenUsage}`);
  55. }
  56. }
  57. module.exports = extensionHook;
Tip!

Press p or to see the previous file or, n or to see the next file

Comments

Loading...