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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
|
- import { SimulatedUser } from '../../src/providers/simulatedUser';
- import type { ApiProvider, ProviderResponse } from '../../src/types';
- import * as timeUtils from '../../src/util/time';
- jest.mock('../../src/util/time', () => ({
- sleep: jest.fn().mockResolvedValue(undefined),
- }));
- jest.mock('../../src/fetch');
- describe('SimulatedUser', () => {
- let simulatedUser: SimulatedUser;
- let originalProvider: ApiProvider;
- beforeEach(() => {
- originalProvider = {
- id: () => 'test-agent',
- callApi: jest.fn().mockImplementation(async () => ({
- output: 'agent response',
- tokenUsage: { numRequests: 1 },
- })),
- };
- simulatedUser = new SimulatedUser({
- id: 'test-agent',
- config: {
- instructions: 'test instructions',
- maxTurns: 2,
- },
- });
- jest.clearAllMocks();
- });
- describe('id()', () => {
- it('should return the identifier', () => {
- expect(simulatedUser.id()).toBe('test-agent');
- });
- it('should use label as fallback identifier', () => {
- const userWithLabel = new SimulatedUser({
- label: 'label-agent',
- config: {},
- });
- expect(userWithLabel.id()).toBe('label-agent');
- });
- it('should use default identifier if no id or label provided', () => {
- const userWithoutId = new SimulatedUser({ config: {} });
- expect(userWithoutId.id()).toBe('agent-provider');
- });
- });
- describe('callApi()', () => {
- it('should simulate conversation between user and agent', async () => {
- const result = await simulatedUser.callApi('test prompt', {
- originalProvider,
- vars: { instructions: 'test instructions' },
- prompt: { raw: 'test', display: 'test', label: 'test' },
- });
- expect(result.output).toBeDefined();
- expect(result.output).toContain('User:');
- expect(result.output).toContain('Assistant:');
- expect(result.tokenUsage?.numRequests).toBe(2);
- expect(originalProvider.callApi).toHaveBeenCalledWith(expect.any(String));
- expect(timeUtils.sleep).not.toHaveBeenCalled();
- });
- it('should respect maxTurns configuration', async () => {
- const userWithMaxTurns = new SimulatedUser({
- config: {
- instructions: 'test instructions',
- maxTurns: 1,
- },
- });
- const result = await userWithMaxTurns.callApi('test prompt', {
- originalProvider,
- vars: { instructions: 'test instructions' },
- prompt: { raw: 'test', display: 'test', label: 'test' },
- });
- const messageCount = result.output?.split('---').length;
- expect(messageCount).toBe(2);
- expect(originalProvider.callApi).toHaveBeenCalledWith(expect.any(String));
- expect(timeUtils.sleep).not.toHaveBeenCalled();
- });
- it('should stop conversation when ###STOP### is received', async () => {
- const providerWithStop: ApiProvider = {
- id: () => 'test-agent',
- callApi: jest.fn().mockImplementation(
- async (): Promise<ProviderResponse> => ({
- output: 'stopping now ###STOP###',
- tokenUsage: { numRequests: 1 },
- }),
- ),
- };
- const result = await simulatedUser.callApi('test prompt', {
- originalProvider: providerWithStop,
- vars: { instructions: 'test instructions' },
- prompt: { raw: 'test', display: 'test', label: 'test' },
- });
- expect(result.output).toContain('###STOP###');
- expect(providerWithStop.callApi).toHaveBeenCalledWith(expect.any(String));
- expect(timeUtils.sleep).not.toHaveBeenCalled();
- });
- it('should throw error if originalProvider is not provided', async () => {
- await expect(
- simulatedUser.callApi('test', {
- vars: {},
- prompt: { raw: 'test', display: 'test', label: 'test' },
- }),
- ).rejects.toThrow('Expected originalProvider to be set');
- });
- it('should handle provider delay', async () => {
- const providerWithDelay = {
- ...originalProvider,
- delay: 100,
- };
- const result = await simulatedUser.callApi(
- 'test prompt',
- {
- originalProvider: providerWithDelay,
- vars: { instructions: 'test instructions' },
- prompt: { raw: 'test', display: 'test', label: 'test' },
- },
- { includeLogProbs: false },
- );
- expect(result.output).toBeDefined();
- expect(providerWithDelay.callApi).toHaveBeenCalledWith(expect.any(String));
- expect(timeUtils.sleep).toHaveBeenCalledWith(100);
- });
- });
- describe('toString()', () => {
- it('should return correct string representation', () => {
- expect(simulatedUser.toString()).toBe('AgentProvider');
- });
- });
- });
|