@@ -58,57 +58,16 @@ public class DefaultAroundAdvisorChain implements CallAroundAdvisorChain, Stream
5858
5959 private final ObservationRegistry observationRegistry ;
6060
61- DefaultAroundAdvisorChain (ObservationRegistry observationRegistry , List <Advisor > advisors ) {
62- Assert .notNull (advisors , "the advisors must be non-null" );
63- this .observationRegistry = observationRegistry ;
64- this .callAroundAdvisors = new ConcurrentLinkedDeque <>();
65- this .streamAroundAdvisors = new ConcurrentLinkedDeque <>();
66- this .pushAll (advisors );
67- }
68-
69- void pushAll (List <? extends Advisor > advisors ) {
70- Assert .notNull (advisors , "the advisors must be non-null" );
71- if (!CollectionUtils .isEmpty (advisors )) {
72- List <CallAroundAdvisor > callAroundAdvisors = advisors .stream ()
73- .filter (a -> a instanceof CallAroundAdvisor )
74- .map (a -> (CallAroundAdvisor ) a )
75- .toList ();
76-
77- if (!CollectionUtils .isEmpty (callAroundAdvisors )) {
78- callAroundAdvisors .forEach (this .callAroundAdvisors ::push );
79- }
61+ DefaultAroundAdvisorChain (ObservationRegistry observationRegistry , Deque <CallAroundAdvisor > callAroundAdvisors ,
62+ Deque <StreamAroundAdvisor > streamAroundAdvisors ) {
8063
81- List <StreamAroundAdvisor > streamAroundAdvisors = advisors .stream ()
82- .filter (a -> a instanceof StreamAroundAdvisor )
83- .map (a -> (StreamAroundAdvisor ) a )
84- .toList ();
85-
86- if (!CollectionUtils .isEmpty (streamAroundAdvisors )) {
87- streamAroundAdvisors .forEach (this .streamAroundAdvisors ::push );
88- }
89-
90- this .reOrder ();
91- }
92- }
64+ Assert .notNull (observationRegistry , "the observationRegistry must be non-null" );
65+ Assert .notNull (callAroundAdvisors , "the callAroundAdvisors must be non-null" );
66+ Assert .notNull (streamAroundAdvisors , "the streamAroundAdvisors must be non-null" );
9367
94- /**
95- * (Re)orders the advisors in priority order based on their Ordered attribute.
96- *
97- * Note: this can be thread unsafe if the advisors are dynamically modified in the
98- * prompt. To avoid this make sure to set advisors only in the ChatClient default
99- * (e.g.builder) section.
100- */
101- private void reOrder () {
102- //
103- ArrayList <CallAroundAdvisor > callAdvisors = new ArrayList <>(this .callAroundAdvisors );
104- OrderComparator .sort (callAdvisors );
105- this .callAroundAdvisors .clear ();
106- callAdvisors .forEach (this .callAroundAdvisors ::addLast );
107-
108- ArrayList <StreamAroundAdvisor > streamAdvisors = new ArrayList <>(this .streamAroundAdvisors );
109- OrderComparator .sort (streamAdvisors );
110- this .streamAroundAdvisors .clear ();
111- streamAdvisors .forEach (this .streamAroundAdvisors ::addLast );
68+ this .observationRegistry = observationRegistry ;
69+ this .callAroundAdvisors = callAroundAdvisors ;
70+ this .streamAroundAdvisors = streamAroundAdvisors ;
11271 }
11372
11473 @ Override
@@ -171,28 +130,65 @@ public static class Builder {
171130
172131 private final ObservationRegistry observationRegistry ;
173132
174- // TODO(dj): this has all advisors actually; the build step filters the around
175- // advisors
176- private final List < Advisor > aroundAdvisors = new ArrayList <>() ;
133+ private final Deque < CallAroundAdvisor > callAroundAdvisors ;
134+
135+ private final Deque < StreamAroundAdvisor > streamAroundAdvisors ;
177136
178137 public Builder (ObservationRegistry observationRegistry ) {
179138 this .observationRegistry = observationRegistry ;
139+ this .callAroundAdvisors = new ConcurrentLinkedDeque <>();
140+ this .streamAroundAdvisors = new ConcurrentLinkedDeque <>();
180141 }
181142
182143 public Builder push (Advisor aroundAdvisor ) {
183144 Assert .notNull (aroundAdvisor , "the aroundAdvisor must be non-null" );
184- this .aroundAdvisors .add (aroundAdvisor );
185- return this ;
145+ return this .pushAll (List .of (aroundAdvisor ));
186146 }
187147
188- public Builder pushAll (List <Advisor > aroundAdvisors ) {
189- Assert .notNull (aroundAdvisors , "the aroundAdvisors must be non-null" );
190- this .aroundAdvisors .addAll (aroundAdvisors );
148+ public Builder pushAll (List <? extends Advisor > advisors ) {
149+ Assert .notNull (advisors , "the advisors must be non-null" );
150+ if (!CollectionUtils .isEmpty (advisors )) {
151+ List <CallAroundAdvisor > callAroundAdvisors = advisors .stream ()
152+ .filter (a -> a instanceof CallAroundAdvisor )
153+ .map (a -> (CallAroundAdvisor ) a )
154+ .toList ();
155+
156+ if (!CollectionUtils .isEmpty (callAroundAdvisors )) {
157+ callAroundAdvisors .forEach (this .callAroundAdvisors ::push );
158+ }
159+
160+ List <StreamAroundAdvisor > streamAroundAdvisors = advisors .stream ()
161+ .filter (a -> a instanceof StreamAroundAdvisor )
162+ .map (a -> (StreamAroundAdvisor ) a )
163+ .toList ();
164+
165+ if (!CollectionUtils .isEmpty (streamAroundAdvisors )) {
166+ streamAroundAdvisors .forEach (this .streamAroundAdvisors ::push );
167+ }
168+
169+ this .reOrder ();
170+ }
191171 return this ;
192172 }
193173
174+ /**
175+ * (Re)orders the advisors in priority order based on their Ordered attribute.
176+ */
177+ private void reOrder () {
178+ ArrayList <CallAroundAdvisor > callAdvisors = new ArrayList <>(this .callAroundAdvisors );
179+ OrderComparator .sort (callAdvisors );
180+ this .callAroundAdvisors .clear ();
181+ callAdvisors .forEach (this .callAroundAdvisors ::addLast );
182+
183+ ArrayList <StreamAroundAdvisor > streamAdvisors = new ArrayList <>(this .streamAroundAdvisors );
184+ OrderComparator .sort (streamAdvisors );
185+ this .streamAroundAdvisors .clear ();
186+ streamAdvisors .forEach (this .streamAroundAdvisors ::addLast );
187+ }
188+
194189 public DefaultAroundAdvisorChain build () {
195- return new DefaultAroundAdvisorChain (this .observationRegistry , this .aroundAdvisors );
190+ return new DefaultAroundAdvisorChain (this .observationRegistry , this .callAroundAdvisors ,
191+ this .streamAroundAdvisors );
196192 }
197193
198194 }
0 commit comments