@copilotkitnext/angular 0.0.28 → 0.0.29

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/coverage/clover.xml +2008 -0
  2. package/coverage/coverage-final.json +44 -0
  3. package/coverage/lcov-report/base.css +224 -0
  4. package/coverage/lcov-report/block-navigation.js +87 -0
  5. package/coverage/lcov-report/favicon.png +0 -0
  6. package/coverage/lcov-report/index.html +251 -0
  7. package/coverage/lcov-report/prettify.css +1 -0
  8. package/coverage/lcov-report/prettify.js +2 -0
  9. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  10. package/coverage/lcov-report/sorter.js +210 -0
  11. package/coverage/lcov-report/src/components/chat/copilot-chat-assistant-message-buttons.ts.html +1039 -0
  12. package/coverage/lcov-report/src/components/chat/copilot-chat-assistant-message-renderer.ts.html +1411 -0
  13. package/coverage/lcov-report/src/components/chat/copilot-chat-assistant-message-toolbar.ts.html +145 -0
  14. package/coverage/lcov-report/src/components/chat/copilot-chat-assistant-message.ts.html +1486 -0
  15. package/coverage/lcov-report/src/components/chat/copilot-chat-audio-recorder.ts.html +811 -0
  16. package/coverage/lcov-report/src/components/chat/copilot-chat-buttons.ts.html +1009 -0
  17. package/coverage/lcov-report/src/components/chat/copilot-chat-input.ts.html +1519 -0
  18. package/coverage/lcov-report/src/components/chat/copilot-chat-input.types.ts.html +529 -0
  19. package/coverage/lcov-report/src/components/chat/copilot-chat-message-view-cursor.ts.html +196 -0
  20. package/coverage/lcov-report/src/components/chat/copilot-chat-message-view.ts.html +715 -0
  21. package/coverage/lcov-report/src/components/chat/copilot-chat-textarea.ts.html +634 -0
  22. package/coverage/lcov-report/src/components/chat/copilot-chat-tool-calls-view.ts.html +889 -0
  23. package/coverage/lcov-report/src/components/chat/copilot-chat-toolbar.ts.html +175 -0
  24. package/coverage/lcov-report/src/components/chat/copilot-chat-tools-menu.ts.html +625 -0
  25. package/coverage/lcov-report/src/components/chat/copilot-chat-user-message-branch-navigation.ts.html +403 -0
  26. package/coverage/lcov-report/src/components/chat/copilot-chat-user-message-buttons.ts.html +580 -0
  27. package/coverage/lcov-report/src/components/chat/copilot-chat-user-message-renderer.ts.html +181 -0
  28. package/coverage/lcov-report/src/components/chat/copilot-chat-user-message-toolbar.ts.html +184 -0
  29. package/coverage/lcov-report/src/components/chat/copilot-chat-user-message.ts.html +784 -0
  30. package/coverage/lcov-report/src/components/chat/copilot-chat-view-handlers.ts.html +127 -0
  31. package/coverage/lcov-report/src/components/chat/index.html +401 -0
  32. package/coverage/lcov-report/src/core/chat-configuration/chat-configuration.providers.ts.html +304 -0
  33. package/coverage/lcov-report/src/core/chat-configuration/chat-configuration.ts.html +580 -0
  34. package/coverage/lcov-report/src/core/chat-configuration/chat-configuration.types.ts.html +256 -0
  35. package/coverage/lcov-report/src/core/chat-configuration/index.html +146 -0
  36. package/coverage/lcov-report/src/core/copilotkit.providers.ts.html +262 -0
  37. package/coverage/lcov-report/src/core/copilotkit.ts.html +1612 -0
  38. package/coverage/lcov-report/src/core/copilotkit.types.ts.html +478 -0
  39. package/coverage/lcov-report/src/core/index.html +146 -0
  40. package/coverage/lcov-report/src/directives/copilotkit-agent-context.ts.html +499 -0
  41. package/coverage/lcov-report/src/directives/copilotkit-agent.ts.html +742 -0
  42. package/coverage/lcov-report/src/directives/copilotkit-chat-config.ts.html +781 -0
  43. package/coverage/lcov-report/src/directives/copilotkit-config.ts.html +328 -0
  44. package/coverage/lcov-report/src/directives/copilotkit-frontend-tool.ts.html +517 -0
  45. package/coverage/lcov-report/src/directives/copilotkit-human-in-the-loop.ts.html +925 -0
  46. package/coverage/lcov-report/src/directives/index.html +191 -0
  47. package/coverage/lcov-report/src/lib/directives/index.html +116 -0
  48. package/coverage/lcov-report/src/lib/directives/tooltip.ts.html +958 -0
  49. package/coverage/lcov-report/src/lib/index.html +116 -0
  50. package/coverage/lcov-report/src/lib/slots/copilot-slot.ts.html +526 -0
  51. package/coverage/lcov-report/src/lib/slots/index.html +146 -0
  52. package/coverage/lcov-report/src/lib/slots/slot.types.ts.html +274 -0
  53. package/coverage/lcov-report/src/lib/slots/slot.utils.ts.html +985 -0
  54. package/coverage/lcov-report/src/lib/utils.ts.html +112 -0
  55. package/coverage/lcov-report/src/testing/index.html +116 -0
  56. package/coverage/lcov-report/src/testing/testing.utils.ts.html +835 -0
  57. package/coverage/lcov-report/src/utils/agent.utils.ts.html +850 -0
  58. package/coverage/lcov-report/src/utils/chat-config.utils.ts.html +745 -0
  59. package/coverage/lcov-report/src/utils/frontend-tool.utils.ts.html +871 -0
  60. package/coverage/lcov-report/src/utils/human-in-the-loop.utils.ts.html +1150 -0
  61. package/coverage/lcov-report/src/utils/index.html +161 -0
  62. package/coverage/lcov-report/test-mocks/index.html +116 -0
  63. package/coverage/lcov-report/test-mocks/marked.ts.html +127 -0
  64. package/coverage/lcov.info +4216 -0
  65. package/package.json +3 -3
@@ -0,0 +1,871 @@
1
+
2
+ <!doctype html>
3
+ <html lang="en">
4
+
5
+ <head>
6
+ <title>Code coverage report for src/utils/frontend-tool.utils.ts</title>
7
+ <meta charset="utf-8" />
8
+ <link rel="stylesheet" href="../../prettify.css" />
9
+ <link rel="stylesheet" href="../../base.css" />
10
+ <link rel="shortcut icon" type="image/x-icon" href="../../favicon.png" />
11
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
12
+ <style type='text/css'>
13
+ .coverage-summary .sorter {
14
+ background-image: url(../../sort-arrow-sprite.png);
15
+ }
16
+ </style>
17
+ </head>
18
+
19
+ <body>
20
+ <div class='wrapper'>
21
+ <div class='pad1'>
22
+ <h1><a href="../../index.html">All files</a> / <a href="index.html">src/utils</a> frontend-tool.utils.ts</h1>
23
+ <div class='clearfix'>
24
+
25
+ <div class='fl pad1y space-right2'>
26
+ <span class="strong">90.9% </span>
27
+ <span class="quiet">Statements</span>
28
+ <span class='fraction'>60/66</span>
29
+ </div>
30
+
31
+
32
+ <div class='fl pad1y space-right2'>
33
+ <span class="strong">90.9% </span>
34
+ <span class="quiet">Branches</span>
35
+ <span class='fraction'>20/22</span>
36
+ </div>
37
+
38
+
39
+ <div class='fl pad1y space-right2'>
40
+ <span class="strong">83.33% </span>
41
+ <span class="quiet">Functions</span>
42
+ <span class='fraction'>10/12</span>
43
+ </div>
44
+
45
+
46
+ <div class='fl pad1y space-right2'>
47
+ <span class="strong">93.54% </span>
48
+ <span class="quiet">Lines</span>
49
+ <span class='fraction'>58/62</span>
50
+ </div>
51
+
52
+
53
+ </div>
54
+ <p class="quiet">
55
+ Press <em>n</em> or <em>j</em> to go to the next uncovered block, <em>b</em>, <em>p</em> or <em>k</em> for the previous block.
56
+ </p>
57
+ <template id="filterTemplate">
58
+ <div class="quiet">
59
+ Filter:
60
+ <input type="search" id="fileSearch">
61
+ </div>
62
+ </template>
63
+ </div>
64
+ <div class='status-line high'></div>
65
+ <pre><table class="coverage">
66
+ <tr><td class="line-count quiet"><a name='L1'></a><a href='#L1'>1</a>
67
+ <a name='L2'></a><a href='#L2'>2</a>
68
+ <a name='L3'></a><a href='#L3'>3</a>
69
+ <a name='L4'></a><a href='#L4'>4</a>
70
+ <a name='L5'></a><a href='#L5'>5</a>
71
+ <a name='L6'></a><a href='#L6'>6</a>
72
+ <a name='L7'></a><a href='#L7'>7</a>
73
+ <a name='L8'></a><a href='#L8'>8</a>
74
+ <a name='L9'></a><a href='#L9'>9</a>
75
+ <a name='L10'></a><a href='#L10'>10</a>
76
+ <a name='L11'></a><a href='#L11'>11</a>
77
+ <a name='L12'></a><a href='#L12'>12</a>
78
+ <a name='L13'></a><a href='#L13'>13</a>
79
+ <a name='L14'></a><a href='#L14'>14</a>
80
+ <a name='L15'></a><a href='#L15'>15</a>
81
+ <a name='L16'></a><a href='#L16'>16</a>
82
+ <a name='L17'></a><a href='#L17'>17</a>
83
+ <a name='L18'></a><a href='#L18'>18</a>
84
+ <a name='L19'></a><a href='#L19'>19</a>
85
+ <a name='L20'></a><a href='#L20'>20</a>
86
+ <a name='L21'></a><a href='#L21'>21</a>
87
+ <a name='L22'></a><a href='#L22'>22</a>
88
+ <a name='L23'></a><a href='#L23'>23</a>
89
+ <a name='L24'></a><a href='#L24'>24</a>
90
+ <a name='L25'></a><a href='#L25'>25</a>
91
+ <a name='L26'></a><a href='#L26'>26</a>
92
+ <a name='L27'></a><a href='#L27'>27</a>
93
+ <a name='L28'></a><a href='#L28'>28</a>
94
+ <a name='L29'></a><a href='#L29'>29</a>
95
+ <a name='L30'></a><a href='#L30'>30</a>
96
+ <a name='L31'></a><a href='#L31'>31</a>
97
+ <a name='L32'></a><a href='#L32'>32</a>
98
+ <a name='L33'></a><a href='#L33'>33</a>
99
+ <a name='L34'></a><a href='#L34'>34</a>
100
+ <a name='L35'></a><a href='#L35'>35</a>
101
+ <a name='L36'></a><a href='#L36'>36</a>
102
+ <a name='L37'></a><a href='#L37'>37</a>
103
+ <a name='L38'></a><a href='#L38'>38</a>
104
+ <a name='L39'></a><a href='#L39'>39</a>
105
+ <a name='L40'></a><a href='#L40'>40</a>
106
+ <a name='L41'></a><a href='#L41'>41</a>
107
+ <a name='L42'></a><a href='#L42'>42</a>
108
+ <a name='L43'></a><a href='#L43'>43</a>
109
+ <a name='L44'></a><a href='#L44'>44</a>
110
+ <a name='L45'></a><a href='#L45'>45</a>
111
+ <a name='L46'></a><a href='#L46'>46</a>
112
+ <a name='L47'></a><a href='#L47'>47</a>
113
+ <a name='L48'></a><a href='#L48'>48</a>
114
+ <a name='L49'></a><a href='#L49'>49</a>
115
+ <a name='L50'></a><a href='#L50'>50</a>
116
+ <a name='L51'></a><a href='#L51'>51</a>
117
+ <a name='L52'></a><a href='#L52'>52</a>
118
+ <a name='L53'></a><a href='#L53'>53</a>
119
+ <a name='L54'></a><a href='#L54'>54</a>
120
+ <a name='L55'></a><a href='#L55'>55</a>
121
+ <a name='L56'></a><a href='#L56'>56</a>
122
+ <a name='L57'></a><a href='#L57'>57</a>
123
+ <a name='L58'></a><a href='#L58'>58</a>
124
+ <a name='L59'></a><a href='#L59'>59</a>
125
+ <a name='L60'></a><a href='#L60'>60</a>
126
+ <a name='L61'></a><a href='#L61'>61</a>
127
+ <a name='L62'></a><a href='#L62'>62</a>
128
+ <a name='L63'></a><a href='#L63'>63</a>
129
+ <a name='L64'></a><a href='#L64'>64</a>
130
+ <a name='L65'></a><a href='#L65'>65</a>
131
+ <a name='L66'></a><a href='#L66'>66</a>
132
+ <a name='L67'></a><a href='#L67'>67</a>
133
+ <a name='L68'></a><a href='#L68'>68</a>
134
+ <a name='L69'></a><a href='#L69'>69</a>
135
+ <a name='L70'></a><a href='#L70'>70</a>
136
+ <a name='L71'></a><a href='#L71'>71</a>
137
+ <a name='L72'></a><a href='#L72'>72</a>
138
+ <a name='L73'></a><a href='#L73'>73</a>
139
+ <a name='L74'></a><a href='#L74'>74</a>
140
+ <a name='L75'></a><a href='#L75'>75</a>
141
+ <a name='L76'></a><a href='#L76'>76</a>
142
+ <a name='L77'></a><a href='#L77'>77</a>
143
+ <a name='L78'></a><a href='#L78'>78</a>
144
+ <a name='L79'></a><a href='#L79'>79</a>
145
+ <a name='L80'></a><a href='#L80'>80</a>
146
+ <a name='L81'></a><a href='#L81'>81</a>
147
+ <a name='L82'></a><a href='#L82'>82</a>
148
+ <a name='L83'></a><a href='#L83'>83</a>
149
+ <a name='L84'></a><a href='#L84'>84</a>
150
+ <a name='L85'></a><a href='#L85'>85</a>
151
+ <a name='L86'></a><a href='#L86'>86</a>
152
+ <a name='L87'></a><a href='#L87'>87</a>
153
+ <a name='L88'></a><a href='#L88'>88</a>
154
+ <a name='L89'></a><a href='#L89'>89</a>
155
+ <a name='L90'></a><a href='#L90'>90</a>
156
+ <a name='L91'></a><a href='#L91'>91</a>
157
+ <a name='L92'></a><a href='#L92'>92</a>
158
+ <a name='L93'></a><a href='#L93'>93</a>
159
+ <a name='L94'></a><a href='#L94'>94</a>
160
+ <a name='L95'></a><a href='#L95'>95</a>
161
+ <a name='L96'></a><a href='#L96'>96</a>
162
+ <a name='L97'></a><a href='#L97'>97</a>
163
+ <a name='L98'></a><a href='#L98'>98</a>
164
+ <a name='L99'></a><a href='#L99'>99</a>
165
+ <a name='L100'></a><a href='#L100'>100</a>
166
+ <a name='L101'></a><a href='#L101'>101</a>
167
+ <a name='L102'></a><a href='#L102'>102</a>
168
+ <a name='L103'></a><a href='#L103'>103</a>
169
+ <a name='L104'></a><a href='#L104'>104</a>
170
+ <a name='L105'></a><a href='#L105'>105</a>
171
+ <a name='L106'></a><a href='#L106'>106</a>
172
+ <a name='L107'></a><a href='#L107'>107</a>
173
+ <a name='L108'></a><a href='#L108'>108</a>
174
+ <a name='L109'></a><a href='#L109'>109</a>
175
+ <a name='L110'></a><a href='#L110'>110</a>
176
+ <a name='L111'></a><a href='#L111'>111</a>
177
+ <a name='L112'></a><a href='#L112'>112</a>
178
+ <a name='L113'></a><a href='#L113'>113</a>
179
+ <a name='L114'></a><a href='#L114'>114</a>
180
+ <a name='L115'></a><a href='#L115'>115</a>
181
+ <a name='L116'></a><a href='#L116'>116</a>
182
+ <a name='L117'></a><a href='#L117'>117</a>
183
+ <a name='L118'></a><a href='#L118'>118</a>
184
+ <a name='L119'></a><a href='#L119'>119</a>
185
+ <a name='L120'></a><a href='#L120'>120</a>
186
+ <a name='L121'></a><a href='#L121'>121</a>
187
+ <a name='L122'></a><a href='#L122'>122</a>
188
+ <a name='L123'></a><a href='#L123'>123</a>
189
+ <a name='L124'></a><a href='#L124'>124</a>
190
+ <a name='L125'></a><a href='#L125'>125</a>
191
+ <a name='L126'></a><a href='#L126'>126</a>
192
+ <a name='L127'></a><a href='#L127'>127</a>
193
+ <a name='L128'></a><a href='#L128'>128</a>
194
+ <a name='L129'></a><a href='#L129'>129</a>
195
+ <a name='L130'></a><a href='#L130'>130</a>
196
+ <a name='L131'></a><a href='#L131'>131</a>
197
+ <a name='L132'></a><a href='#L132'>132</a>
198
+ <a name='L133'></a><a href='#L133'>133</a>
199
+ <a name='L134'></a><a href='#L134'>134</a>
200
+ <a name='L135'></a><a href='#L135'>135</a>
201
+ <a name='L136'></a><a href='#L136'>136</a>
202
+ <a name='L137'></a><a href='#L137'>137</a>
203
+ <a name='L138'></a><a href='#L138'>138</a>
204
+ <a name='L139'></a><a href='#L139'>139</a>
205
+ <a name='L140'></a><a href='#L140'>140</a>
206
+ <a name='L141'></a><a href='#L141'>141</a>
207
+ <a name='L142'></a><a href='#L142'>142</a>
208
+ <a name='L143'></a><a href='#L143'>143</a>
209
+ <a name='L144'></a><a href='#L144'>144</a>
210
+ <a name='L145'></a><a href='#L145'>145</a>
211
+ <a name='L146'></a><a href='#L146'>146</a>
212
+ <a name='L147'></a><a href='#L147'>147</a>
213
+ <a name='L148'></a><a href='#L148'>148</a>
214
+ <a name='L149'></a><a href='#L149'>149</a>
215
+ <a name='L150'></a><a href='#L150'>150</a>
216
+ <a name='L151'></a><a href='#L151'>151</a>
217
+ <a name='L152'></a><a href='#L152'>152</a>
218
+ <a name='L153'></a><a href='#L153'>153</a>
219
+ <a name='L154'></a><a href='#L154'>154</a>
220
+ <a name='L155'></a><a href='#L155'>155</a>
221
+ <a name='L156'></a><a href='#L156'>156</a>
222
+ <a name='L157'></a><a href='#L157'>157</a>
223
+ <a name='L158'></a><a href='#L158'>158</a>
224
+ <a name='L159'></a><a href='#L159'>159</a>
225
+ <a name='L160'></a><a href='#L160'>160</a>
226
+ <a name='L161'></a><a href='#L161'>161</a>
227
+ <a name='L162'></a><a href='#L162'>162</a>
228
+ <a name='L163'></a><a href='#L163'>163</a>
229
+ <a name='L164'></a><a href='#L164'>164</a>
230
+ <a name='L165'></a><a href='#L165'>165</a>
231
+ <a name='L166'></a><a href='#L166'>166</a>
232
+ <a name='L167'></a><a href='#L167'>167</a>
233
+ <a name='L168'></a><a href='#L168'>168</a>
234
+ <a name='L169'></a><a href='#L169'>169</a>
235
+ <a name='L170'></a><a href='#L170'>170</a>
236
+ <a name='L171'></a><a href='#L171'>171</a>
237
+ <a name='L172'></a><a href='#L172'>172</a>
238
+ <a name='L173'></a><a href='#L173'>173</a>
239
+ <a name='L174'></a><a href='#L174'>174</a>
240
+ <a name='L175'></a><a href='#L175'>175</a>
241
+ <a name='L176'></a><a href='#L176'>176</a>
242
+ <a name='L177'></a><a href='#L177'>177</a>
243
+ <a name='L178'></a><a href='#L178'>178</a>
244
+ <a name='L179'></a><a href='#L179'>179</a>
245
+ <a name='L180'></a><a href='#L180'>180</a>
246
+ <a name='L181'></a><a href='#L181'>181</a>
247
+ <a name='L182'></a><a href='#L182'>182</a>
248
+ <a name='L183'></a><a href='#L183'>183</a>
249
+ <a name='L184'></a><a href='#L184'>184</a>
250
+ <a name='L185'></a><a href='#L185'>185</a>
251
+ <a name='L186'></a><a href='#L186'>186</a>
252
+ <a name='L187'></a><a href='#L187'>187</a>
253
+ <a name='L188'></a><a href='#L188'>188</a>
254
+ <a name='L189'></a><a href='#L189'>189</a>
255
+ <a name='L190'></a><a href='#L190'>190</a>
256
+ <a name='L191'></a><a href='#L191'>191</a>
257
+ <a name='L192'></a><a href='#L192'>192</a>
258
+ <a name='L193'></a><a href='#L193'>193</a>
259
+ <a name='L194'></a><a href='#L194'>194</a>
260
+ <a name='L195'></a><a href='#L195'>195</a>
261
+ <a name='L196'></a><a href='#L196'>196</a>
262
+ <a name='L197'></a><a href='#L197'>197</a>
263
+ <a name='L198'></a><a href='#L198'>198</a>
264
+ <a name='L199'></a><a href='#L199'>199</a>
265
+ <a name='L200'></a><a href='#L200'>200</a>
266
+ <a name='L201'></a><a href='#L201'>201</a>
267
+ <a name='L202'></a><a href='#L202'>202</a>
268
+ <a name='L203'></a><a href='#L203'>203</a>
269
+ <a name='L204'></a><a href='#L204'>204</a>
270
+ <a name='L205'></a><a href='#L205'>205</a>
271
+ <a name='L206'></a><a href='#L206'>206</a>
272
+ <a name='L207'></a><a href='#L207'>207</a>
273
+ <a name='L208'></a><a href='#L208'>208</a>
274
+ <a name='L209'></a><a href='#L209'>209</a>
275
+ <a name='L210'></a><a href='#L210'>210</a>
276
+ <a name='L211'></a><a href='#L211'>211</a>
277
+ <a name='L212'></a><a href='#L212'>212</a>
278
+ <a name='L213'></a><a href='#L213'>213</a>
279
+ <a name='L214'></a><a href='#L214'>214</a>
280
+ <a name='L215'></a><a href='#L215'>215</a>
281
+ <a name='L216'></a><a href='#L216'>216</a>
282
+ <a name='L217'></a><a href='#L217'>217</a>
283
+ <a name='L218'></a><a href='#L218'>218</a>
284
+ <a name='L219'></a><a href='#L219'>219</a>
285
+ <a name='L220'></a><a href='#L220'>220</a>
286
+ <a name='L221'></a><a href='#L221'>221</a>
287
+ <a name='L222'></a><a href='#L222'>222</a>
288
+ <a name='L223'></a><a href='#L223'>223</a>
289
+ <a name='L224'></a><a href='#L224'>224</a>
290
+ <a name='L225'></a><a href='#L225'>225</a>
291
+ <a name='L226'></a><a href='#L226'>226</a>
292
+ <a name='L227'></a><a href='#L227'>227</a>
293
+ <a name='L228'></a><a href='#L228'>228</a>
294
+ <a name='L229'></a><a href='#L229'>229</a>
295
+ <a name='L230'></a><a href='#L230'>230</a>
296
+ <a name='L231'></a><a href='#L231'>231</a>
297
+ <a name='L232'></a><a href='#L232'>232</a>
298
+ <a name='L233'></a><a href='#L233'>233</a>
299
+ <a name='L234'></a><a href='#L234'>234</a>
300
+ <a name='L235'></a><a href='#L235'>235</a>
301
+ <a name='L236'></a><a href='#L236'>236</a>
302
+ <a name='L237'></a><a href='#L237'>237</a>
303
+ <a name='L238'></a><a href='#L238'>238</a>
304
+ <a name='L239'></a><a href='#L239'>239</a>
305
+ <a name='L240'></a><a href='#L240'>240</a>
306
+ <a name='L241'></a><a href='#L241'>241</a>
307
+ <a name='L242'></a><a href='#L242'>242</a>
308
+ <a name='L243'></a><a href='#L243'>243</a>
309
+ <a name='L244'></a><a href='#L244'>244</a>
310
+ <a name='L245'></a><a href='#L245'>245</a>
311
+ <a name='L246'></a><a href='#L246'>246</a>
312
+ <a name='L247'></a><a href='#L247'>247</a>
313
+ <a name='L248'></a><a href='#L248'>248</a>
314
+ <a name='L249'></a><a href='#L249'>249</a>
315
+ <a name='L250'></a><a href='#L250'>250</a>
316
+ <a name='L251'></a><a href='#L251'>251</a>
317
+ <a name='L252'></a><a href='#L252'>252</a>
318
+ <a name='L253'></a><a href='#L253'>253</a>
319
+ <a name='L254'></a><a href='#L254'>254</a>
320
+ <a name='L255'></a><a href='#L255'>255</a>
321
+ <a name='L256'></a><a href='#L256'>256</a>
322
+ <a name='L257'></a><a href='#L257'>257</a>
323
+ <a name='L258'></a><a href='#L258'>258</a>
324
+ <a name='L259'></a><a href='#L259'>259</a>
325
+ <a name='L260'></a><a href='#L260'>260</a>
326
+ <a name='L261'></a><a href='#L261'>261</a>
327
+ <a name='L262'></a><a href='#L262'>262</a>
328
+ <a name='L263'></a><a href='#L263'>263</a></td><td class="line-coverage quiet"><span class="cline-any cline-yes">2x</span>
329
+ <span class="cline-any cline-yes">2x</span>
330
+ <span class="cline-any cline-neutral">&nbsp;</span>
331
+ <span class="cline-any cline-neutral">&nbsp;</span>
332
+ <span class="cline-any cline-neutral">&nbsp;</span>
333
+ <span class="cline-any cline-neutral">&nbsp;</span>
334
+ <span class="cline-any cline-neutral">&nbsp;</span>
335
+ <span class="cline-any cline-neutral">&nbsp;</span>
336
+ <span class="cline-any cline-neutral">&nbsp;</span>
337
+ <span class="cline-any cline-neutral">&nbsp;</span>
338
+ <span class="cline-any cline-neutral">&nbsp;</span>
339
+ <span class="cline-any cline-neutral">&nbsp;</span>
340
+ <span class="cline-any cline-neutral">&nbsp;</span>
341
+ <span class="cline-any cline-neutral">&nbsp;</span>
342
+ <span class="cline-any cline-neutral">&nbsp;</span>
343
+ <span class="cline-any cline-neutral">&nbsp;</span>
344
+ <span class="cline-any cline-neutral">&nbsp;</span>
345
+ <span class="cline-any cline-neutral">&nbsp;</span>
346
+ <span class="cline-any cline-neutral">&nbsp;</span>
347
+ <span class="cline-any cline-neutral">&nbsp;</span>
348
+ <span class="cline-any cline-neutral">&nbsp;</span>
349
+ <span class="cline-any cline-neutral">&nbsp;</span>
350
+ <span class="cline-any cline-neutral">&nbsp;</span>
351
+ <span class="cline-any cline-neutral">&nbsp;</span>
352
+ <span class="cline-any cline-neutral">&nbsp;</span>
353
+ <span class="cline-any cline-neutral">&nbsp;</span>
354
+ <span class="cline-any cline-neutral">&nbsp;</span>
355
+ <span class="cline-any cline-neutral">&nbsp;</span>
356
+ <span class="cline-any cline-neutral">&nbsp;</span>
357
+ <span class="cline-any cline-neutral">&nbsp;</span>
358
+ <span class="cline-any cline-neutral">&nbsp;</span>
359
+ <span class="cline-any cline-neutral">&nbsp;</span>
360
+ <span class="cline-any cline-neutral">&nbsp;</span>
361
+ <span class="cline-any cline-neutral">&nbsp;</span>
362
+ <span class="cline-any cline-neutral">&nbsp;</span>
363
+ <span class="cline-any cline-neutral">&nbsp;</span>
364
+ <span class="cline-any cline-neutral">&nbsp;</span>
365
+ <span class="cline-any cline-neutral">&nbsp;</span>
366
+ <span class="cline-any cline-neutral">&nbsp;</span>
367
+ <span class="cline-any cline-neutral">&nbsp;</span>
368
+ <span class="cline-any cline-neutral">&nbsp;</span>
369
+ <span class="cline-any cline-yes">2x</span>
370
+ <span class="cline-any cline-neutral">&nbsp;</span>
371
+ <span class="cline-any cline-neutral">&nbsp;</span>
372
+ <span class="cline-any cline-neutral">&nbsp;</span>
373
+ <span class="cline-any cline-neutral">&nbsp;</span>
374
+ <span class="cline-any cline-yes">9x</span>
375
+ <span class="cline-any cline-neutral">&nbsp;</span>
376
+ <span class="cline-any cline-neutral">&nbsp;</span>
377
+ <span class="cline-any cline-yes">9x</span>
378
+ <span class="cline-any cline-yes">6x</span>
379
+ <span class="cline-any cline-yes">6x</span>
380
+ <span class="cline-any cline-neutral">&nbsp;</span>
381
+ <span class="cline-any cline-yes">6x</span>
382
+ <span class="cline-any cline-yes">1x</span>
383
+ <span class="cline-any cline-neutral">&nbsp;</span>
384
+ <span class="cline-any cline-yes">5x</span>
385
+ <span class="cline-any cline-neutral">&nbsp;</span>
386
+ <span class="cline-any cline-neutral">&nbsp;</span>
387
+ <span class="cline-any cline-neutral">&nbsp;</span>
388
+ <span class="cline-any cline-neutral">&nbsp;</span>
389
+ <span class="cline-any cline-yes">5x</span>
390
+ <span class="cline-any cline-neutral">&nbsp;</span>
391
+ <span class="cline-any cline-neutral">&nbsp;</span>
392
+ <span class="cline-any cline-neutral">&nbsp;</span>
393
+ <span class="cline-any cline-neutral">&nbsp;</span>
394
+ <span class="cline-any cline-yes">9x</span>
395
+ <span class="cline-any cline-yes">9x</span>
396
+ <span class="cline-any cline-neutral">&nbsp;</span>
397
+ <span class="cline-any cline-neutral">&nbsp;</span>
398
+ <span class="cline-any cline-neutral">&nbsp;</span>
399
+ <span class="cline-any cline-neutral">&nbsp;</span>
400
+ <span class="cline-any cline-neutral">&nbsp;</span>
401
+ <span class="cline-any cline-neutral">&nbsp;</span>
402
+ <span class="cline-any cline-neutral">&nbsp;</span>
403
+ <span class="cline-any cline-neutral">&nbsp;</span>
404
+ <span class="cline-any cline-neutral">&nbsp;</span>
405
+ <span class="cline-any cline-neutral">&nbsp;</span>
406
+ <span class="cline-any cline-neutral">&nbsp;</span>
407
+ <span class="cline-any cline-neutral">&nbsp;</span>
408
+ <span class="cline-any cline-neutral">&nbsp;</span>
409
+ <span class="cline-any cline-neutral">&nbsp;</span>
410
+ <span class="cline-any cline-neutral">&nbsp;</span>
411
+ <span class="cline-any cline-neutral">&nbsp;</span>
412
+ <span class="cline-any cline-neutral">&nbsp;</span>
413
+ <span class="cline-any cline-neutral">&nbsp;</span>
414
+ <span class="cline-any cline-neutral">&nbsp;</span>
415
+ <span class="cline-any cline-neutral">&nbsp;</span>
416
+ <span class="cline-any cline-neutral">&nbsp;</span>
417
+ <span class="cline-any cline-neutral">&nbsp;</span>
418
+ <span class="cline-any cline-neutral">&nbsp;</span>
419
+ <span class="cline-any cline-neutral">&nbsp;</span>
420
+ <span class="cline-any cline-neutral">&nbsp;</span>
421
+ <span class="cline-any cline-neutral">&nbsp;</span>
422
+ <span class="cline-any cline-neutral">&nbsp;</span>
423
+ <span class="cline-any cline-neutral">&nbsp;</span>
424
+ <span class="cline-any cline-neutral">&nbsp;</span>
425
+ <span class="cline-any cline-neutral">&nbsp;</span>
426
+ <span class="cline-any cline-yes">2x</span>
427
+ <span class="cline-any cline-neutral">&nbsp;</span>
428
+ <span class="cline-any cline-neutral">&nbsp;</span>
429
+ <span class="cline-any cline-yes">4x</span>
430
+ <span class="cline-any cline-yes">4x</span>
431
+ <span class="cline-any cline-neutral">&nbsp;</span>
432
+ <span class="cline-any cline-neutral">&nbsp;</span>
433
+ <span class="cline-any cline-yes">4x</span>
434
+ <span class="cline-any cline-neutral">&nbsp;</span>
435
+ <span class="cline-any cline-neutral">&nbsp;</span>
436
+ <span class="cline-any cline-yes">4x</span>
437
+ <span class="cline-any cline-yes">2x</span>
438
+ <span class="cline-any cline-yes">2x</span>
439
+ <span class="cline-any cline-neutral">&nbsp;</span>
440
+ <span class="cline-any cline-yes">2x</span>
441
+ <span class="cline-any cline-no">&nbsp;</span>
442
+ <span class="cline-any cline-neutral">&nbsp;</span>
443
+ <span class="cline-any cline-yes">2x</span>
444
+ <span class="cline-any cline-neutral">&nbsp;</span>
445
+ <span class="cline-any cline-neutral">&nbsp;</span>
446
+ <span class="cline-any cline-neutral">&nbsp;</span>
447
+ <span class="cline-any cline-neutral">&nbsp;</span>
448
+ <span class="cline-any cline-yes">2x</span>
449
+ <span class="cline-any cline-neutral">&nbsp;</span>
450
+ <span class="cline-any cline-neutral">&nbsp;</span>
451
+ <span class="cline-any cline-neutral">&nbsp;</span>
452
+ <span class="cline-any cline-neutral">&nbsp;</span>
453
+ <span class="cline-any cline-yes">4x</span>
454
+ <span class="cline-any cline-yes">4x</span>
455
+ <span class="cline-any cline-neutral">&nbsp;</span>
456
+ <span class="cline-any cline-neutral">&nbsp;</span>
457
+ <span class="cline-any cline-yes">4x</span>
458
+ <span class="cline-any cline-neutral">&nbsp;</span>
459
+ <span class="cline-any cline-neutral">&nbsp;</span>
460
+ <span class="cline-any cline-neutral">&nbsp;</span>
461
+ <span class="cline-any cline-neutral">&nbsp;</span>
462
+ <span class="cline-any cline-neutral">&nbsp;</span>
463
+ <span class="cline-any cline-neutral">&nbsp;</span>
464
+ <span class="cline-any cline-neutral">&nbsp;</span>
465
+ <span class="cline-any cline-neutral">&nbsp;</span>
466
+ <span class="cline-any cline-neutral">&nbsp;</span>
467
+ <span class="cline-any cline-neutral">&nbsp;</span>
468
+ <span class="cline-any cline-neutral">&nbsp;</span>
469
+ <span class="cline-any cline-neutral">&nbsp;</span>
470
+ <span class="cline-any cline-neutral">&nbsp;</span>
471
+ <span class="cline-any cline-yes">2x</span>
472
+ <span class="cline-any cline-neutral">&nbsp;</span>
473
+ <span class="cline-any cline-neutral">&nbsp;</span>
474
+ <span class="cline-any cline-neutral">&nbsp;</span>
475
+ <span class="cline-any cline-neutral">&nbsp;</span>
476
+ <span class="cline-any cline-yes">23x</span>
477
+ <span class="cline-any cline-neutral">&nbsp;</span>
478
+ <span class="cline-any cline-neutral">&nbsp;</span>
479
+ <span class="cline-any cline-yes">23x</span>
480
+ <span class="cline-any cline-yes">23x</span>
481
+ <span class="cline-any cline-yes">23x</span>
482
+ <span class="cline-any cline-yes">11x</span>
483
+ <span class="cline-any cline-neutral">&nbsp;</span>
484
+ <span class="cline-any cline-neutral">&nbsp;</span>
485
+ <span class="cline-any cline-neutral">&nbsp;</span>
486
+ <span class="cline-any cline-neutral">&nbsp;</span>
487
+ <span class="cline-any cline-neutral">&nbsp;</span>
488
+ <span class="cline-any cline-neutral">&nbsp;</span>
489
+ <span class="cline-any cline-neutral">&nbsp;</span>
490
+ <span class="cline-any cline-neutral">&nbsp;</span>
491
+ <span class="cline-any cline-neutral">&nbsp;</span>
492
+ <span class="cline-any cline-neutral">&nbsp;</span>
493
+ <span class="cline-any cline-neutral">&nbsp;</span>
494
+ <span class="cline-any cline-neutral">&nbsp;</span>
495
+ <span class="cline-any cline-neutral">&nbsp;</span>
496
+ <span class="cline-any cline-neutral">&nbsp;</span>
497
+ <span class="cline-any cline-neutral">&nbsp;</span>
498
+ <span class="cline-any cline-neutral">&nbsp;</span>
499
+ <span class="cline-any cline-neutral">&nbsp;</span>
500
+ <span class="cline-any cline-neutral">&nbsp;</span>
501
+ <span class="cline-any cline-neutral">&nbsp;</span>
502
+ <span class="cline-any cline-neutral">&nbsp;</span>
503
+ <span class="cline-any cline-neutral">&nbsp;</span>
504
+ <span class="cline-any cline-neutral">&nbsp;</span>
505
+ <span class="cline-any cline-neutral">&nbsp;</span>
506
+ <span class="cline-any cline-neutral">&nbsp;</span>
507
+ <span class="cline-any cline-neutral">&nbsp;</span>
508
+ <span class="cline-any cline-neutral">&nbsp;</span>
509
+ <span class="cline-any cline-neutral">&nbsp;</span>
510
+ <span class="cline-any cline-neutral">&nbsp;</span>
511
+ <span class="cline-any cline-neutral">&nbsp;</span>
512
+ <span class="cline-any cline-neutral">&nbsp;</span>
513
+ <span class="cline-any cline-neutral">&nbsp;</span>
514
+ <span class="cline-any cline-neutral">&nbsp;</span>
515
+ <span class="cline-any cline-neutral">&nbsp;</span>
516
+ <span class="cline-any cline-neutral">&nbsp;</span>
517
+ <span class="cline-any cline-neutral">&nbsp;</span>
518
+ <span class="cline-any cline-neutral">&nbsp;</span>
519
+ <span class="cline-any cline-neutral">&nbsp;</span>
520
+ <span class="cline-any cline-neutral">&nbsp;</span>
521
+ <span class="cline-any cline-yes">2x</span>
522
+ <span class="cline-any cline-neutral">&nbsp;</span>
523
+ <span class="cline-any cline-neutral">&nbsp;</span>
524
+ <span class="cline-any cline-neutral">&nbsp;</span>
525
+ <span class="cline-any cline-neutral">&nbsp;</span>
526
+ <span class="cline-any cline-neutral">&nbsp;</span>
527
+ <span class="cline-any cline-neutral">&nbsp;</span>
528
+ <span class="cline-any cline-yes">6x</span>
529
+ <span class="cline-any cline-yes">6x</span>
530
+ <span class="cline-any cline-neutral">&nbsp;</span>
531
+ <span class="cline-any cline-yes">6x</span>
532
+ <span class="cline-any cline-neutral">&nbsp;</span>
533
+ <span class="cline-any cline-yes">6x</span>
534
+ <span class="cline-any cline-neutral">&nbsp;</span>
535
+ <span class="cline-any cline-yes">8x</span>
536
+ <span class="cline-any cline-yes">2x</span>
537
+ <span class="cline-any cline-neutral">&nbsp;</span>
538
+ <span class="cline-any cline-neutral">&nbsp;</span>
539
+ <span class="cline-any cline-neutral">&nbsp;</span>
540
+ <span class="cline-any cline-yes">8x</span>
541
+ <span class="cline-any cline-yes">8x</span>
542
+ <span class="cline-any cline-yes">8x</span>
543
+ <span class="cline-any cline-neutral">&nbsp;</span>
544
+ <span class="cline-any cline-yes">8x</span>
545
+ <span class="cline-any cline-neutral">&nbsp;</span>
546
+ <span class="cline-any cline-neutral">&nbsp;</span>
547
+ <span class="cline-any cline-neutral">&nbsp;</span>
548
+ <span class="cline-any cline-neutral">&nbsp;</span>
549
+ <span class="cline-any cline-neutral">&nbsp;</span>
550
+ <span class="cline-any cline-neutral">&nbsp;</span>
551
+ <span class="cline-any cline-neutral">&nbsp;</span>
552
+ <span class="cline-any cline-neutral">&nbsp;</span>
553
+ <span class="cline-any cline-yes">8x</span>
554
+ <span class="cline-any cline-neutral">&nbsp;</span>
555
+ <span class="cline-any cline-neutral">&nbsp;</span>
556
+ <span class="cline-any cline-yes">8x</span>
557
+ <span class="cline-any cline-yes">1x</span>
558
+ <span class="cline-any cline-yes">1x</span>
559
+ <span class="cline-any cline-neutral">&nbsp;</span>
560
+ <span class="cline-any cline-neutral">&nbsp;</span>
561
+ <span class="cline-any cline-neutral">&nbsp;</span>
562
+ <span class="cline-any cline-neutral">&nbsp;</span>
563
+ <span class="cline-any cline-yes">1x</span>
564
+ <span class="cline-any cline-yes">1x</span>
565
+ <span class="cline-any cline-no">&nbsp;</span>
566
+ <span class="cline-any cline-no">&nbsp;</span>
567
+ <span class="cline-any cline-no">&nbsp;</span>
568
+ <span class="cline-any cline-neutral">&nbsp;</span>
569
+ <span class="cline-any cline-yes">1x</span>
570
+ <span class="cline-any cline-neutral">&nbsp;</span>
571
+ <span class="cline-any cline-neutral">&nbsp;</span>
572
+ <span class="cline-any cline-neutral">&nbsp;</span>
573
+ <span class="cline-any cline-yes">8x</span>
574
+ <span class="cline-any cline-neutral">&nbsp;</span>
575
+ <span class="cline-any cline-neutral">&nbsp;</span>
576
+ <span class="cline-any cline-yes">6x</span>
577
+ <span class="cline-any cline-yes">7x</span>
578
+ <span class="cline-any cline-yes">6x</span>
579
+ <span class="cline-any cline-yes">6x</span>
580
+ <span class="cline-any cline-neutral">&nbsp;</span>
581
+ <span class="cline-any cline-neutral">&nbsp;</span>
582
+ <span class="cline-any cline-neutral">&nbsp;</span>
583
+ <span class="cline-any cline-neutral">&nbsp;</span>
584
+ <span class="cline-any cline-yes">6x</span>
585
+ <span class="cline-any cline-neutral">&nbsp;</span>
586
+ <span class="cline-any cline-neutral">&nbsp;</span>
587
+ <span class="cline-any cline-yes">6x</span>
588
+ <span class="cline-any cline-neutral">&nbsp;</span>
589
+ <span class="cline-any cline-yes">6x</span>
590
+ <span class="cline-any cline-neutral">&nbsp;</span></td><td class="text"><pre class="prettyprint lang-js">import { DestroyRef, inject } from '@angular/core';
591
+ import { CopilotKit } from '../core/copilotkit';
592
+ import { AngularFrontendTool, AngularToolCallRender, ToolCallRender } from '../core/copilotkit.types';
593
+ import type { z } from 'zod';
594
+ &nbsp;
595
+ /**
596
+ * Explicitly adds a frontend tool to CopilotKit.
597
+ * Requires CopilotKit to be passed as a parameter.
598
+ *
599
+ * @param service - The CopilotKit instance
600
+ * @param tool - The tool to add
601
+ * @returns A cleanup function that removes the tool
602
+ *
603
+ * @example
604
+ * ```typescript
605
+ * export class MyComponent implements OnInit, OnDestroy {
606
+ * private cleanupFns: Array&lt;() =&gt; void&gt; = [];
607
+ *
608
+ * constructor(private copilotkit: CopilotKit) {}
609
+ *
610
+ * ngOnInit() {
611
+ * const cleanup = addFrontendTool(this.copilotkit, {
612
+ * name: 'calculator',
613
+ * description: 'Performs calculations',
614
+ * parameters: z.object({
615
+ * expression: z.string()
616
+ * }),
617
+ * handler: async (args) =&gt; {
618
+ * return eval(args.expression);
619
+ * }
620
+ * });
621
+ *
622
+ * this.cleanupFns.push(cleanup);
623
+ * }
624
+ *
625
+ * ngOnDestroy() {
626
+ * this.cleanupFns.forEach(fn =&gt; fn());
627
+ * }
628
+ * }
629
+ * ```
630
+ */
631
+ export function addFrontendTool&lt;T extends Record&lt;string, any&gt; = Record&lt;string, any&gt;&gt;(
632
+ service: CopilotKit,
633
+ tool: AngularFrontendTool&lt;T&gt;
634
+ ): () =&gt; void {
635
+ // Add the tool to CopilotKit
636
+ service.copilotkit.addTool(tool);
637
+
638
+ // Register the render if provided
639
+ if (tool.render) {
640
+ const currentRenders = service.currentRenderToolCalls();
641
+ const existingIndex = currentRenders.findIndex((r: ToolCallRender) =&gt; r.name === tool.name);
642
+
643
+ if (existingIndex !== -1) {
644
+ console.error(`Tool with name '${tool.name}' already has a render. Skipping.`);
645
+ } else {
646
+ const renderEntry: AngularToolCallRender = {
647
+ name: tool.name,
648
+ render: tool.render
649
+ };
650
+
651
+ service.setCurrentRenderToolCalls([...currentRenders, renderEntry]);
652
+ }
653
+ }
654
+
655
+ // Return cleanup function
656
+ return () =&gt; {
657
+ removeFrontendTool(service, tool.name);
658
+ };
659
+ }
660
+ &nbsp;
661
+ /**
662
+ * Registers a frontend tool with CopilotKit and automatically removes it when the component/service is destroyed.
663
+ * Must be called within an injection context.
664
+ *
665
+ * @param tool - The tool to register
666
+ * @returns The tool name
667
+ *
668
+ * @example
669
+ * ```typescript
670
+ * export class MyComponent implements OnInit {
671
+ * ngOnInit() {
672
+ * // Automatically cleaned up on component destroy
673
+ * registerFrontendTool({
674
+ * name: 'search',
675
+ * description: 'Search for items',
676
+ * parameters: z.object({
677
+ * query: z.string()
678
+ * }),
679
+ * handler: async (args) =&gt; {
680
+ * return this.searchService.search(args.query);
681
+ * },
682
+ * render: SearchResultsComponent
683
+ * });
684
+ * }
685
+ * }
686
+ * ```
687
+ */
688
+ export function registerFrontendTool&lt;T extends Record&lt;string, any&gt; = Record&lt;string, any&gt;&gt;(
689
+ tool: AngularFrontendTool&lt;T&gt;
690
+ ): string {
691
+ const service = inject(CopilotKit);
692
+ const destroyRef = inject(DestroyRef);
693
+
694
+ // Add the tool
695
+ service.copilotkit.addTool(tool);
696
+
697
+ // Register the render if provided
698
+ if (tool.render) {
699
+ const currentRenders = service.currentRenderToolCalls();
700
+ const existingIndex = currentRenders.findIndex(<span class="fstat-no" title="function not covered" >(r</span>: ToolCallRender) =&gt; <span class="cstat-no" title="statement not covered" >r.name === tool.name)</span>;
701
+
702
+ <span class="missing-if-branch" title="if path not taken" >I</span>if (existingIndex !== -1) {
703
+ <span class="cstat-no" title="statement not covered" > console.error(`Tool with name '${tool.name}' already has a render. Skipping.`);</span>
704
+ } else {
705
+ const renderEntry: AngularToolCallRender = {
706
+ name: tool.name,
707
+ render: tool.render
708
+ };
709
+
710
+ service.setCurrentRenderToolCalls([...currentRenders, renderEntry]);
711
+ }
712
+ }
713
+
714
+ // Register cleanup with Angular's DestroyRef
715
+ destroyRef.onDestroy(() =&gt; {
716
+ removeFrontendTool(service, tool.name);
717
+ });
718
+
719
+ return tool.name;
720
+ }
721
+ &nbsp;
722
+ /**
723
+ * Explicitly removes a frontend tool from CopilotKit.
724
+ *
725
+ * @param service - The CopilotKit instance
726
+ * @param toolName - The name of the tool to remove
727
+ *
728
+ * @example
729
+ * ```typescript
730
+ * removeFrontendTool(this.copilotkit, 'calculator');
731
+ * ```
732
+ */
733
+ export function removeFrontendTool(
734
+ service: CopilotKit,
735
+ toolName: string
736
+ ): void {
737
+ // Remove the tool
738
+ service.copilotkit.removeTool(toolName);
739
+
740
+ // Remove the render if it exists
741
+ const currentRenders = service.currentRenderToolCalls();
742
+ const filtered = currentRenders.filter((r: ToolCallRender) =&gt; r.name !== toolName);
743
+ if (filtered.length !== currentRenders.length) {
744
+ service.setCurrentRenderToolCalls(filtered);
745
+ }
746
+ }
747
+ &nbsp;
748
+ /**
749
+ * Creates a frontend tool with dynamic parameters that can change over time.
750
+ * Uses Angular signals for reactivity.
751
+ *
752
+ * @param name - Tool name
753
+ * @param description - Tool description
754
+ * @param parameters - Zod schema for parameters
755
+ * @param handler - Signal or function that provides the handler
756
+ * @param render - Optional render component or template
757
+ * @returns Object with update and destroy methods
758
+ *
759
+ * @example
760
+ * ```typescript
761
+ * export class MyComponent {
762
+ * private toolConfig = signal({
763
+ * handler: async (args: any) =&gt; this.processDefault(args)
764
+ * });
765
+ *
766
+ * ngOnInit() {
767
+ * const tool = createDynamicFrontendTool(
768
+ * 'processor',
769
+ * 'Processes data',
770
+ * z.object({ data: z.string() }),
771
+ * () =&gt; this.toolConfig().handler
772
+ * );
773
+ *
774
+ * // Later, update the handler
775
+ * this.toolConfig.set({
776
+ * handler: async (args: any) =&gt; this.processAdvanced(args)
777
+ * });
778
+ * tool.update();
779
+ * }
780
+ * }
781
+ * ```
782
+ */
783
+ export function createDynamicFrontendTool&lt;T extends Record&lt;string, any&gt; = Record&lt;string, any&gt;&gt;(
784
+ name: string,
785
+ description: string | (() =&gt; string),
786
+ parameters: z.ZodSchema&lt;T&gt;,
787
+ handler: () =&gt; ((args: T) =&gt; Promise&lt;any&gt;),
788
+ render?: () =&gt; any
789
+ ): { update: () =&gt; void; destroy: () =&gt; void } {
790
+ const service = inject(CopilotKit);
791
+ const destroyRef = inject(DestroyRef);
792
+
793
+ let isRegistered = false;
794
+
795
+ const update = () =&gt; {
796
+ // Remove old tool if registered
797
+ if (isRegistered) {
798
+ service.copilotkit.removeTool(name);
799
+ }
800
+
801
+ // Create new tool configuration
802
+ const desc = typeof description === 'function' ? description() : description;
803
+ const currentHandler = handler();
804
+ const currentRender = render ? render() : undefined;
805
+
806
+ const tool: AngularFrontendTool&lt;T&gt; = {
807
+ name,
808
+ description: desc,
809
+ parameters,
810
+ handler: currentHandler,
811
+ render: currentRender
812
+ };
813
+
814
+ // Add the tool
815
+ service.copilotkit.addTool(tool);
816
+
817
+ // Update render if provided
818
+ if (currentRender) {
819
+ const currentRenders = service.currentRenderToolCalls();
820
+ const renderEntry: AngularToolCallRender = {
821
+ name: name,
822
+ render: currentRender
823
+ };
824
+
825
+ const existingIndex = currentRenders.findIndex(<span class="fstat-no" title="function not covered" >(r</span>: ToolCallRender) =&gt; <span class="cstat-no" title="statement not covered" >r.name === name)</span>;
826
+ <span class="missing-if-branch" title="if path not taken" >I</span>if (existingIndex !== -1) {
827
+ const updated = <span class="cstat-no" title="statement not covered" >[...currentRenders];</span>
828
+ <span class="cstat-no" title="statement not covered" > updated[existingIndex] = renderEntry;</span>
829
+ <span class="cstat-no" title="statement not covered" > service.setCurrentRenderToolCalls(updated);</span>
830
+ } else {
831
+ service.setCurrentRenderToolCalls([...currentRenders, renderEntry]);
832
+ }
833
+ }
834
+
835
+ isRegistered = true;
836
+ };
837
+
838
+ const destroy = () =&gt; {
839
+ if (isRegistered) {
840
+ removeFrontendTool(service, name);
841
+ isRegistered = false;
842
+ }
843
+ };
844
+
845
+ // Initial setup
846
+ update();
847
+
848
+ // Register cleanup
849
+ destroyRef.onDestroy(destroy);
850
+
851
+ return { update, destroy };
852
+ }</pre></td></tr></table></pre>
853
+
854
+ <div class='push'></div><!-- for sticky footer -->
855
+ </div><!-- /wrapper -->
856
+ <div class='footer quiet pad2 space-top1 center small'>
857
+ Code coverage generated by
858
+ <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
859
+ at 2025-09-15T01:22:45.642Z
860
+ </div>
861
+ <script src="../../prettify.js"></script>
862
+ <script>
863
+ window.onload = function () {
864
+ prettyPrint();
865
+ };
866
+ </script>
867
+ <script src="../../sorter.js"></script>
868
+ <script src="../../block-navigation.js"></script>
869
+ </body>
870
+ </html>
871
+