@copilotkitnext/angular 0.0.2 → 0.0.5

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 (173) hide show
  1. package/README.md +3 -3
  2. package/dist/README.md +3 -3
  3. package/dist/components/chat/copilot-chat-assistant-message.component.d.ts +10 -10
  4. package/dist/components/chat/copilot-chat-message-view.component.d.ts +42 -42
  5. package/dist/components/chat/copilot-chat-view.component.d.ts +14 -14
  6. package/dist/core/copilotkit.providers.d.ts +1 -1
  7. package/dist/core/copilotkit.service.d.ts +5 -5
  8. package/dist/core/copilotkit.types.d.ts +8 -10
  9. package/dist/directives/copilotkit-frontend-tool.directive.d.ts +1 -1
  10. package/dist/esm2022/components/chat/copilot-chat-assistant-message-buttons.component.mjs +384 -0
  11. package/dist/esm2022/components/chat/copilot-chat-assistant-message-renderer.component.mjs +286 -0
  12. package/dist/esm2022/components/chat/copilot-chat-assistant-message-toolbar.component.mjs +27 -0
  13. package/dist/esm2022/components/chat/copilot-chat-assistant-message.component.mjs +433 -0
  14. package/dist/esm2022/components/chat/copilot-chat-assistant-message.types.mjs +2 -0
  15. package/dist/esm2022/components/chat/copilot-chat-audio-recorder.component.mjs +202 -0
  16. package/dist/esm2022/components/chat/copilot-chat-buttons.component.mjs +321 -0
  17. package/dist/esm2022/components/chat/copilot-chat-input-defaults.mjs +38 -0
  18. package/dist/esm2022/components/chat/copilot-chat-input.component.mjs +666 -0
  19. package/dist/esm2022/components/chat/copilot-chat-input.types.mjs +10 -0
  20. package/dist/esm2022/components/chat/copilot-chat-message-view-cursor.component.mjs +45 -0
  21. package/dist/esm2022/components/chat/copilot-chat-message-view.component.mjs +296 -0
  22. package/dist/esm2022/components/chat/copilot-chat-message-view.types.mjs +2 -0
  23. package/dist/esm2022/components/chat/copilot-chat-textarea.component.mjs +188 -0
  24. package/dist/esm2022/components/chat/copilot-chat-tool-calls-view.component.mjs +216 -0
  25. package/dist/esm2022/components/chat/copilot-chat-toolbar.component.mjs +25 -0
  26. package/dist/esm2022/components/chat/copilot-chat-tools-menu.component.mjs +199 -0
  27. package/dist/esm2022/components/chat/copilot-chat-user-message-branch-navigation.component.mjs +137 -0
  28. package/dist/esm2022/components/chat/copilot-chat-user-message-buttons.component.mjs +207 -0
  29. package/dist/esm2022/components/chat/copilot-chat-user-message-renderer.component.mjs +35 -0
  30. package/dist/esm2022/components/chat/copilot-chat-user-message-toolbar.component.mjs +34 -0
  31. package/dist/esm2022/components/chat/copilot-chat-user-message.component.mjs +341 -0
  32. package/dist/esm2022/components/chat/copilot-chat-user-message.types.mjs +2 -0
  33. package/dist/esm2022/components/chat/copilot-chat-view-disclaimer.component.mjs +52 -0
  34. package/dist/esm2022/components/chat/copilot-chat-view-feather.component.mjs +55 -0
  35. package/dist/esm2022/components/chat/copilot-chat-view-handlers.service.mjs +19 -0
  36. package/dist/esm2022/components/chat/copilot-chat-view-input-container.component.mjs +110 -0
  37. package/dist/esm2022/components/chat/copilot-chat-view-scroll-to-bottom-button.component.mjs +93 -0
  38. package/dist/esm2022/components/chat/copilot-chat-view-scroll-view.component.mjs +443 -0
  39. package/dist/esm2022/components/chat/copilot-chat-view.component.mjs +479 -0
  40. package/dist/esm2022/components/chat/copilot-chat-view.types.mjs +2 -0
  41. package/dist/esm2022/components/chat/copilot-chat.component.mjs +214 -0
  42. package/dist/esm2022/components/copilotkit-tool-render.component.mjs +153 -0
  43. package/dist/esm2022/copilotkitnext-angular.mjs +5 -0
  44. package/dist/esm2022/core/chat-configuration/chat-configuration.providers.mjs +65 -0
  45. package/dist/esm2022/core/chat-configuration/chat-configuration.service.mjs +145 -0
  46. package/dist/esm2022/core/chat-configuration/chat-configuration.types.mjs +26 -0
  47. package/dist/esm2022/core/copilotkit.providers.mjs +34 -0
  48. package/dist/esm2022/core/copilotkit.service.mjs +426 -0
  49. package/dist/esm2022/core/copilotkit.types.mjs +13 -0
  50. package/dist/esm2022/directives/copilotkit-agent-context.directive.mjs +130 -0
  51. package/dist/esm2022/directives/copilotkit-agent.directive.mjs +217 -0
  52. package/dist/esm2022/directives/copilotkit-chat-config.directive.mjs +218 -0
  53. package/dist/esm2022/directives/copilotkit-config.directive.mjs +94 -0
  54. package/dist/esm2022/directives/copilotkit-frontend-tool.directive.mjs +128 -0
  55. package/dist/esm2022/directives/copilotkit-human-in-the-loop.directive.mjs +265 -0
  56. package/dist/esm2022/directives/stick-to-bottom.directive.mjs +181 -0
  57. package/dist/esm2022/index.mjs +70 -0
  58. package/dist/esm2022/lib/directives/tooltip.directive.mjs +211 -0
  59. package/dist/esm2022/lib/slots/copilot-slot.component.mjs +144 -0
  60. package/dist/esm2022/lib/slots/slot.types.mjs +6 -0
  61. package/dist/esm2022/lib/slots/slot.utils.mjs +222 -0
  62. package/dist/esm2022/lib/utils.mjs +10 -0
  63. package/dist/esm2022/services/resize-observer.service.mjs +152 -0
  64. package/dist/esm2022/services/scroll-position.service.mjs +124 -0
  65. package/dist/esm2022/types/frontend-tool.mjs +2 -0
  66. package/dist/esm2022/types/human-in-the-loop.mjs +2 -0
  67. package/dist/esm2022/utils/agent-context.utils.mjs +114 -0
  68. package/dist/esm2022/utils/agent.utils.mjs +204 -0
  69. package/dist/esm2022/utils/chat-config.utils.mjs +186 -0
  70. package/dist/esm2022/utils/copilotkit.utils.mjs +20 -0
  71. package/dist/esm2022/utils/frontend-tool.utils.mjs +224 -0
  72. package/dist/esm2022/utils/human-in-the-loop.utils.mjs +293 -0
  73. package/dist/fesm2022/copilotkitnext-angular.mjs +174 -187
  74. package/dist/fesm2022/copilotkitnext-angular.mjs.map +1 -1
  75. package/dist/utils/frontend-tool.utils.d.ts +1 -1
  76. package/package.json +23 -20
  77. package/vitest.config.mts +32 -21
  78. package/.turbo/turbo-build.log +0 -38
  79. package/.turbo/turbo-check-types.log +0 -0
  80. package/.turbo/turbo-test.log +0 -71
  81. package/ng-package.json +0 -19
  82. package/src/components/chat/__tests__/copilot-chat-assistant-message.component.spec.ts +0 -282
  83. package/src/components/chat/__tests__/copilot-chat-input.component.spec.ts +0 -419
  84. package/src/components/chat/__tests__/copilot-chat-message-view.component.spec.ts +0 -372
  85. package/src/components/chat/__tests__/copilot-chat-user-message.component.spec.ts +0 -249
  86. package/src/components/chat/copilot-chat-assistant-message-buttons.component.ts +0 -292
  87. package/src/components/chat/copilot-chat-assistant-message-renderer.component.ts +0 -472
  88. package/src/components/chat/copilot-chat-assistant-message-toolbar.component.ts +0 -29
  89. package/src/components/chat/copilot-chat-assistant-message.component.ts +0 -463
  90. package/src/components/chat/copilot-chat-assistant-message.types.ts +0 -50
  91. package/src/components/chat/copilot-chat-audio-recorder.component.ts +0 -241
  92. package/src/components/chat/copilot-chat-buttons.component.ts +0 -308
  93. package/src/components/chat/copilot-chat-buttons.component.ts.bak +0 -471
  94. package/src/components/chat/copilot-chat-input-defaults.ts +0 -47
  95. package/src/components/chat/copilot-chat-input.component.ts +0 -512
  96. package/src/components/chat/copilot-chat-input.types.ts +0 -148
  97. package/src/components/chat/copilot-chat-message-view-cursor.component.ts +0 -51
  98. package/src/components/chat/copilot-chat-message-view.component.ts +0 -233
  99. package/src/components/chat/copilot-chat-message-view.types.ts +0 -39
  100. package/src/components/chat/copilot-chat-textarea.component.ts +0 -220
  101. package/src/components/chat/copilot-chat-tool-calls-view.component.ts +0 -261
  102. package/src/components/chat/copilot-chat-toolbar.component.ts +0 -35
  103. package/src/components/chat/copilot-chat-tools-menu.component.ts +0 -185
  104. package/src/components/chat/copilot-chat-user-message-branch-navigation.component.ts +0 -121
  105. package/src/components/chat/copilot-chat-user-message-buttons.component.ts +0 -170
  106. package/src/components/chat/copilot-chat-user-message-renderer.component.ts +0 -37
  107. package/src/components/chat/copilot-chat-user-message-toolbar.component.ts +0 -37
  108. package/src/components/chat/copilot-chat-user-message.component.ts +0 -247
  109. package/src/components/chat/copilot-chat-user-message.types.ts +0 -42
  110. package/src/components/chat/copilot-chat-view-disclaimer.component.ts +0 -51
  111. package/src/components/chat/copilot-chat-view-feather.component.ts +0 -47
  112. package/src/components/chat/copilot-chat-view-handlers.service.ts +0 -14
  113. package/src/components/chat/copilot-chat-view-input-container.component.ts +0 -87
  114. package/src/components/chat/copilot-chat-view-scroll-to-bottom-button.component.ts +0 -79
  115. package/src/components/chat/copilot-chat-view-scroll-view.component.ts +0 -322
  116. package/src/components/chat/copilot-chat-view.component.ts +0 -420
  117. package/src/components/chat/copilot-chat-view.types.ts +0 -52
  118. package/src/components/chat/copilot-chat.component.ts +0 -232
  119. package/src/components/copilotkit-tool-render.component.ts +0 -169
  120. package/src/core/__tests__/copilotkit.service.spec.ts +0 -1051
  121. package/src/core/__tests__/copilotkit.service.wildcard.spec.ts +0 -316
  122. package/src/core/chat-configuration/__tests__/chat-configuration.service.spec.ts +0 -287
  123. package/src/core/chat-configuration/chat-configuration.providers.ts +0 -71
  124. package/src/core/chat-configuration/chat-configuration.service.ts +0 -162
  125. package/src/core/chat-configuration/chat-configuration.types.ts +0 -57
  126. package/src/core/copilotkit.providers.ts +0 -59
  127. package/src/core/copilotkit.service.ts +0 -542
  128. package/src/core/copilotkit.types.ts +0 -132
  129. package/src/directives/__tests__/copilotkit-agent-context.directive.spec.ts +0 -384
  130. package/src/directives/__tests__/copilotkit-agent.directive.spec.ts +0 -253
  131. package/src/directives/__tests__/copilotkit-chat-config.directive.spec.ts +0 -385
  132. package/src/directives/__tests__/copilotkit-config.directive.spec.ts +0 -69
  133. package/src/directives/__tests__/copilotkit-frontend-tool-simple.directive.spec.ts +0 -60
  134. package/src/directives/__tests__/copilotkit-frontend-tool.directive.spec.ts +0 -108
  135. package/src/directives/__tests__/copilotkit-human-in-the-loop.directive.spec.ts +0 -452
  136. package/src/directives/copilotkit-agent-context.directive.ts +0 -138
  137. package/src/directives/copilotkit-agent.directive.ts +0 -225
  138. package/src/directives/copilotkit-chat-config.directive.ts +0 -241
  139. package/src/directives/copilotkit-config.directive.ts +0 -81
  140. package/src/directives/copilotkit-frontend-tool.directive.ts +0 -145
  141. package/src/directives/copilotkit-human-in-the-loop.directive.ts +0 -281
  142. package/src/directives/stick-to-bottom.directive.ts +0 -204
  143. package/src/index.ts +0 -105
  144. package/src/lib/directives/tooltip.directive.ts +0 -292
  145. package/src/lib/slots/__tests__/slot.utils.spec.ts +0 -377
  146. package/src/lib/slots/copilot-slot.component.ts +0 -135
  147. package/src/lib/slots/index.ts +0 -3
  148. package/src/lib/slots/slot.types.ts +0 -64
  149. package/src/lib/slots/slot.utils.ts +0 -289
  150. package/src/lib/utils.ts +0 -10
  151. package/src/public-api.ts +0 -1
  152. package/src/services/resize-observer.service.ts +0 -181
  153. package/src/services/scroll-position.service.ts +0 -169
  154. package/src/styles/globals.css +0 -266
  155. package/src/styles/index.css +0 -3
  156. package/src/test-setup.ts +0 -15
  157. package/src/testing/index.ts +0 -3
  158. package/src/testing/testing.utils.ts +0 -248
  159. package/src/types/frontend-tool.ts +0 -44
  160. package/src/types/human-in-the-loop.ts +0 -52
  161. package/src/utils/__tests__/agent.utils.spec.ts +0 -234
  162. package/src/utils/__tests__/chat-config.utils.spec.ts +0 -306
  163. package/src/utils/__tests__/frontend-tool-inject.spec.ts +0 -350
  164. package/src/utils/__tests__/frontend-tool-integration.spec.ts +0 -199
  165. package/src/utils/__tests__/frontend-tool.utils.spec.ts +0 -272
  166. package/src/utils/__tests__/human-in-the-loop.utils.spec.ts +0 -365
  167. package/src/utils/agent-context.utils.ts +0 -133
  168. package/src/utils/agent.utils.ts +0 -239
  169. package/src/utils/chat-config.utils.ts +0 -221
  170. package/src/utils/copilotkit.utils.ts +0 -20
  171. package/src/utils/frontend-tool.utils.ts +0 -266
  172. package/src/utils/human-in-the-loop.utils.ts +0 -359
  173. package/tsconfig.spec.json +0 -12
@@ -0,0 +1,94 @@
1
+ import { Directive, Input, Inject } from "@angular/core";
2
+ import { CopilotKitService } from "../core/copilotkit.service";
3
+ import * as i0 from "@angular/core";
4
+ import * as i1 from "../core/copilotkit.service";
5
+ /**
6
+ * Directive to configure CopilotKit runtime settings declaratively in templates.
7
+ *
8
+ * @example
9
+ * ```html
10
+ * <div [copilotkitConfig]="{
11
+ * runtimeUrl: 'https://api.example.com',
12
+ * headers: { 'Authorization': 'Bearer token' }
13
+ * }">
14
+ * <!-- Your app content -->
15
+ * </div>
16
+ * ```
17
+ *
18
+ * Or with individual inputs:
19
+ * ```html
20
+ * <div copilotkitConfig
21
+ * [runtimeUrl]="apiUrl"
22
+ * [headers]="authHeaders"
23
+ * [agents]="myAgents">
24
+ * <!-- Your app content -->
25
+ * </div>
26
+ * ```
27
+ */
28
+ export class CopilotKitConfigDirective {
29
+ copilotkit;
30
+ constructor(copilotkit) {
31
+ this.copilotkit = copilotkit;
32
+ }
33
+ copilotkitConfig;
34
+ runtimeUrl;
35
+ headers;
36
+ properties;
37
+ agents;
38
+ ngOnChanges(changes) {
39
+ // Handle combined config object
40
+ if (changes['copilotkitConfig']) {
41
+ const config = this.copilotkitConfig;
42
+ if (config) {
43
+ if (config.runtimeUrl !== undefined) {
44
+ this.copilotkit.setRuntimeUrl(config.runtimeUrl);
45
+ }
46
+ if (config.headers) {
47
+ this.copilotkit.setHeaders(config.headers);
48
+ }
49
+ if (config.properties) {
50
+ this.copilotkit.setProperties(config.properties);
51
+ }
52
+ if (config.agents) {
53
+ this.copilotkit.setAgents(config.agents);
54
+ }
55
+ }
56
+ }
57
+ // Handle individual inputs
58
+ if (changes['runtimeUrl'] && !this.copilotkitConfig) {
59
+ this.copilotkit.setRuntimeUrl(this.runtimeUrl);
60
+ }
61
+ if (changes['headers'] && !this.copilotkitConfig) {
62
+ this.copilotkit.setHeaders(this.headers || {});
63
+ }
64
+ if (changes['properties'] && !this.copilotkitConfig) {
65
+ this.copilotkit.setProperties(this.properties || {});
66
+ }
67
+ if (changes['agents'] && !this.copilotkitConfig) {
68
+ this.copilotkit.setAgents(this.agents || {});
69
+ }
70
+ }
71
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: CopilotKitConfigDirective, deps: [{ token: CopilotKitService }], target: i0.ɵɵFactoryTarget.Directive });
72
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.13", type: CopilotKitConfigDirective, isStandalone: true, selector: "[copilotkitConfig]", inputs: { copilotkitConfig: "copilotkitConfig", runtimeUrl: "runtimeUrl", headers: "headers", properties: "properties", agents: "agents" }, usesOnChanges: true, ngImport: i0 });
73
+ }
74
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: CopilotKitConfigDirective, decorators: [{
75
+ type: Directive,
76
+ args: [{
77
+ selector: "[copilotkitConfig]",
78
+ standalone: true,
79
+ }]
80
+ }], ctorParameters: () => [{ type: i1.CopilotKitService, decorators: [{
81
+ type: Inject,
82
+ args: [CopilotKitService]
83
+ }] }], propDecorators: { copilotkitConfig: [{
84
+ type: Input
85
+ }], runtimeUrl: [{
86
+ type: Input
87
+ }], headers: [{
88
+ type: Input
89
+ }], properties: [{
90
+ type: Input
91
+ }], agents: [{
92
+ type: Input
93
+ }] } });
94
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29waWxvdGtpdC1jb25maWcuZGlyZWN0aXZlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2RpcmVjdGl2ZXMvY29waWxvdGtpdC1jb25maWcuZGlyZWN0aXZlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUE0QixNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDbkYsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sNEJBQTRCLENBQUM7OztBQUcvRDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXNCRztBQUtILE1BQU0sT0FBTyx5QkFBeUI7SUFDb0I7SUFBeEQsWUFBd0QsVUFBNkI7UUFBN0IsZUFBVSxHQUFWLFVBQVUsQ0FBbUI7SUFBRyxDQUFDO0lBRWhGLGdCQUFnQixDQUt2QjtJQUVPLFVBQVUsQ0FBVTtJQUNwQixPQUFPLENBQTBCO0lBQ2pDLFVBQVUsQ0FBMkI7SUFDckMsTUFBTSxDQUFpQztJQUVoRCxXQUFXLENBQUMsT0FBc0I7UUFDaEMsZ0NBQWdDO1FBQ2hDLElBQUksT0FBTyxDQUFDLGtCQUFrQixDQUFDLEVBQUUsQ0FBQztZQUNoQyxNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUM7WUFDckMsSUFBSSxNQUFNLEVBQUUsQ0FBQztnQkFDWCxJQUFJLE1BQU0sQ0FBQyxVQUFVLEtBQUssU0FBUyxFQUFFLENBQUM7b0JBQ3BDLElBQUksQ0FBQyxVQUFVLENBQUMsYUFBYSxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsQ0FBQztnQkFDbkQsQ0FBQztnQkFDRCxJQUFJLE1BQU0sQ0FBQyxPQUFPLEVBQUUsQ0FBQztvQkFDbkIsSUFBSSxDQUFDLFVBQVUsQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDO2dCQUM3QyxDQUFDO2dCQUNELElBQUksTUFBTSxDQUFDLFVBQVUsRUFBRSxDQUFDO29CQUN0QixJQUFJLENBQUMsVUFBVSxDQUFDLGFBQWEsQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLENBQUM7Z0JBQ25ELENBQUM7Z0JBQ0QsSUFBSSxNQUFNLENBQUMsTUFBTSxFQUFFLENBQUM7b0JBQ2xCLElBQUksQ0FBQyxVQUFVLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQztnQkFDM0MsQ0FBQztZQUNILENBQUM7UUFDSCxDQUFDO1FBRUQsMkJBQTJCO1FBQzNCLElBQUksT0FBTyxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLGdCQUFnQixFQUFFLENBQUM7WUFDcEQsSUFBSSxDQUFDLFVBQVUsQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQ2pELENBQUM7UUFDRCxJQUFJLE9BQU8sQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO1lBQ2pELElBQUksQ0FBQyxVQUFVLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxPQUFPLElBQUksRUFBRSxDQUFDLENBQUM7UUFDakQsQ0FBQztRQUNELElBQUksT0FBTyxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLGdCQUFnQixFQUFFLENBQUM7WUFDcEQsSUFBSSxDQUFDLFVBQVUsQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLFVBQVUsSUFBSSxFQUFFLENBQUMsQ0FBQztRQUN2RCxDQUFDO1FBQ0QsSUFBSSxPQUFPLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztZQUNoRCxJQUFJLENBQUMsVUFBVSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsTUFBTSxJQUFJLEVBQUUsQ0FBQyxDQUFDO1FBQy9DLENBQUM7SUFDSCxDQUFDO3dHQWhEVSx5QkFBeUIsa0JBQ2hCLGlCQUFpQjs0RkFEMUIseUJBQXlCOzs0RkFBekIseUJBQXlCO2tCQUpyQyxTQUFTO21CQUFDO29CQUNULFFBQVEsRUFBRSxvQkFBb0I7b0JBQzlCLFVBQVUsRUFBRSxJQUFJO2lCQUNqQjs7MEJBRWMsTUFBTTsyQkFBQyxpQkFBaUI7eUNBRTVCLGdCQUFnQjtzQkFBeEIsS0FBSztnQkFPRyxVQUFVO3NCQUFsQixLQUFLO2dCQUNHLE9BQU87c0JBQWYsS0FBSztnQkFDRyxVQUFVO3NCQUFsQixLQUFLO2dCQUNHLE1BQU07c0JBQWQsS0FBSyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IERpcmVjdGl2ZSwgSW5wdXQsIE9uQ2hhbmdlcywgU2ltcGxlQ2hhbmdlcywgSW5qZWN0IH0gZnJvbSBcIkBhbmd1bGFyL2NvcmVcIjtcbmltcG9ydCB7IENvcGlsb3RLaXRTZXJ2aWNlIH0gZnJvbSBcIi4uL2NvcmUvY29waWxvdGtpdC5zZXJ2aWNlXCI7XG5pbXBvcnQgeyBBYnN0cmFjdEFnZW50IH0gZnJvbSBcIkBhZy11aS9jbGllbnRcIjtcblxuLyoqXG4gKiBEaXJlY3RpdmUgdG8gY29uZmlndXJlIENvcGlsb3RLaXQgcnVudGltZSBzZXR0aW5ncyBkZWNsYXJhdGl2ZWx5IGluIHRlbXBsYXRlcy5cbiAqIFxuICogQGV4YW1wbGVcbiAqIGBgYGh0bWxcbiAqIDxkaXYgW2NvcGlsb3RraXRDb25maWddPVwie1xuICogICBydW50aW1lVXJsOiAnaHR0cHM6Ly9hcGkuZXhhbXBsZS5jb20nLFxuICogICBoZWFkZXJzOiB7ICdBdXRob3JpemF0aW9uJzogJ0JlYXJlciB0b2tlbicgfVxuICogfVwiPlxuICogICA8IS0tIFlvdXIgYXBwIGNvbnRlbnQgLS0+XG4gKiA8L2Rpdj5cbiAqIGBgYFxuICogXG4gKiBPciB3aXRoIGluZGl2aWR1YWwgaW5wdXRzOlxuICogYGBgaHRtbFxuICogPGRpdiBjb3BpbG90a2l0Q29uZmlnXG4gKiAgICAgIFtydW50aW1lVXJsXT1cImFwaVVybFwiXG4gKiAgICAgIFtoZWFkZXJzXT1cImF1dGhIZWFkZXJzXCJcbiAqICAgICAgW2FnZW50c109XCJteUFnZW50c1wiPlxuICogICA8IS0tIFlvdXIgYXBwIGNvbnRlbnQgLS0+XG4gKiA8L2Rpdj5cbiAqIGBgYFxuICovXG5ARGlyZWN0aXZlKHtcbiAgc2VsZWN0b3I6IFwiW2NvcGlsb3RraXRDb25maWddXCIsXG4gIHN0YW5kYWxvbmU6IHRydWUsXG59KVxuZXhwb3J0IGNsYXNzIENvcGlsb3RLaXRDb25maWdEaXJlY3RpdmUgaW1wbGVtZW50cyBPbkNoYW5nZXMge1xuICBjb25zdHJ1Y3RvcihASW5qZWN0KENvcGlsb3RLaXRTZXJ2aWNlKSBwcml2YXRlIHJlYWRvbmx5IGNvcGlsb3RraXQ6IENvcGlsb3RLaXRTZXJ2aWNlKSB7fVxuXG4gIEBJbnB1dCgpIGNvcGlsb3RraXRDb25maWc/OiB7XG4gICAgcnVudGltZVVybD86IHN0cmluZztcbiAgICBoZWFkZXJzPzogUmVjb3JkPHN0cmluZywgc3RyaW5nPjtcbiAgICBwcm9wZXJ0aWVzPzogUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG4gICAgYWdlbnRzPzogUmVjb3JkPHN0cmluZywgQWJzdHJhY3RBZ2VudD47XG4gIH07XG5cbiAgQElucHV0KCkgcnVudGltZVVybD86IHN0cmluZztcbiAgQElucHV0KCkgaGVhZGVycz86IFJlY29yZDxzdHJpbmcsIHN0cmluZz47XG4gIEBJbnB1dCgpIHByb3BlcnRpZXM/OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbiAgQElucHV0KCkgYWdlbnRzPzogUmVjb3JkPHN0cmluZywgQWJzdHJhY3RBZ2VudD47XG5cbiAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcyk6IHZvaWQge1xuICAgIC8vIEhhbmRsZSBjb21iaW5lZCBjb25maWcgb2JqZWN0XG4gICAgaWYgKGNoYW5nZXNbJ2NvcGlsb3RraXRDb25maWcnXSkge1xuICAgICAgY29uc3QgY29uZmlnID0gdGhpcy5jb3BpbG90a2l0Q29uZmlnO1xuICAgICAgaWYgKGNvbmZpZykge1xuICAgICAgICBpZiAoY29uZmlnLnJ1bnRpbWVVcmwgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHRoaXMuY29waWxvdGtpdC5zZXRSdW50aW1lVXJsKGNvbmZpZy5ydW50aW1lVXJsKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoY29uZmlnLmhlYWRlcnMpIHtcbiAgICAgICAgICB0aGlzLmNvcGlsb3RraXQuc2V0SGVhZGVycyhjb25maWcuaGVhZGVycyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGNvbmZpZy5wcm9wZXJ0aWVzKSB7XG4gICAgICAgICAgdGhpcy5jb3BpbG90a2l0LnNldFByb3BlcnRpZXMoY29uZmlnLnByb3BlcnRpZXMpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChjb25maWcuYWdlbnRzKSB7XG4gICAgICAgICAgdGhpcy5jb3BpbG90a2l0LnNldEFnZW50cyhjb25maWcuYWdlbnRzKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIC8vIEhhbmRsZSBpbmRpdmlkdWFsIGlucHV0c1xuICAgIGlmIChjaGFuZ2VzWydydW50aW1lVXJsJ10gJiYgIXRoaXMuY29waWxvdGtpdENvbmZpZykge1xuICAgICAgdGhpcy5jb3BpbG90a2l0LnNldFJ1bnRpbWVVcmwodGhpcy5ydW50aW1lVXJsKTtcbiAgICB9XG4gICAgaWYgKGNoYW5nZXNbJ2hlYWRlcnMnXSAmJiAhdGhpcy5jb3BpbG90a2l0Q29uZmlnKSB7XG4gICAgICB0aGlzLmNvcGlsb3RraXQuc2V0SGVhZGVycyh0aGlzLmhlYWRlcnMgfHwge30pO1xuICAgIH1cbiAgICBpZiAoY2hhbmdlc1sncHJvcGVydGllcyddICYmICF0aGlzLmNvcGlsb3RraXRDb25maWcpIHtcbiAgICAgIHRoaXMuY29waWxvdGtpdC5zZXRQcm9wZXJ0aWVzKHRoaXMucHJvcGVydGllcyB8fCB7fSk7XG4gICAgfVxuICAgIGlmIChjaGFuZ2VzWydhZ2VudHMnXSAmJiAhdGhpcy5jb3BpbG90a2l0Q29uZmlnKSB7XG4gICAgICB0aGlzLmNvcGlsb3RraXQuc2V0QWdlbnRzKHRoaXMuYWdlbnRzIHx8IHt9KTtcbiAgICB9XG4gIH1cbn0iXX0=
@@ -0,0 +1,128 @@
1
+ import { Directive, Input, isDevMode, Inject, } from "@angular/core";
2
+ import { CopilotKitService } from "../core/copilotkit.service";
3
+ import * as i0 from "@angular/core";
4
+ import * as i1 from "../core/copilotkit.service";
5
+ export class CopilotKitFrontendToolDirective {
6
+ copilotkit;
7
+ isRegistered = false;
8
+ constructor(copilotkit) {
9
+ this.copilotkit = copilotkit;
10
+ }
11
+ name;
12
+ description;
13
+ parameters;
14
+ handler;
15
+ render;
16
+ followUp;
17
+ // Alternative: Accept a full tool object
18
+ tool;
19
+ ngOnInit() {
20
+ this.registerTool();
21
+ }
22
+ ngOnChanges(_changes) {
23
+ if (this.isRegistered) {
24
+ // Re-register the tool if any properties change
25
+ this.unregisterTool();
26
+ this.registerTool();
27
+ }
28
+ }
29
+ ngOnDestroy() {
30
+ this.unregisterTool();
31
+ }
32
+ registerTool() {
33
+ const tool = this.getTool();
34
+ if (!tool.name) {
35
+ if (isDevMode()) {
36
+ console.warn('CopilotKitFrontendToolDirective: "name" is required. ' +
37
+ 'Please provide a name via [name]="toolName" or ' +
38
+ "[copilotkitFrontendTool]=\"{ name: 'toolName', ... }\"");
39
+ }
40
+ return; // Don't register if no name
41
+ }
42
+ // Register the tool with CopilotKit
43
+ this.copilotkit.copilotkit.addTool(tool);
44
+ // Register the render if provided
45
+ if (tool.render) {
46
+ const currentRenders = this.copilotkit.currentRenderToolCalls();
47
+ const renderEntry = {
48
+ name: tool.name,
49
+ render: tool.render,
50
+ };
51
+ // Check for duplicate
52
+ const existingIndex = currentRenders.findIndex((r) => r.name === tool.name);
53
+ if (existingIndex !== -1) {
54
+ if (isDevMode()) {
55
+ console.warn(`[CopilotKit] Tool "${tool.name}" already has a render. ` +
56
+ `The previous render will be replaced. ` +
57
+ `This may indicate a duplicate tool registration.`);
58
+ }
59
+ const updated = [...currentRenders];
60
+ updated[existingIndex] = renderEntry;
61
+ this.copilotkit.setCurrentRenderToolCalls(updated);
62
+ }
63
+ else {
64
+ this.copilotkit.setCurrentRenderToolCalls([...currentRenders, renderEntry]);
65
+ }
66
+ }
67
+ this.isRegistered = true;
68
+ }
69
+ unregisterTool() {
70
+ if (!this.isRegistered)
71
+ return;
72
+ const tool = this.getTool();
73
+ if (tool.name) {
74
+ // Remove the tool
75
+ this.copilotkit.copilotkit.removeTool(tool.name);
76
+ // Remove the render if it exists
77
+ const currentRenders = this.copilotkit.currentRenderToolCalls();
78
+ const filtered = currentRenders.filter((r) => r.name !== tool.name);
79
+ if (filtered.length !== currentRenders.length) {
80
+ this.copilotkit.setCurrentRenderToolCalls(filtered);
81
+ }
82
+ }
83
+ this.isRegistered = false;
84
+ }
85
+ getTool() {
86
+ // If full tool object is provided, use it
87
+ if (this.tool) {
88
+ return this.tool;
89
+ }
90
+ // Otherwise, construct from individual inputs
91
+ return {
92
+ name: this.name,
93
+ description: this.description,
94
+ parameters: this.parameters,
95
+ handler: this.handler,
96
+ render: this.render,
97
+ followUp: this.followUp,
98
+ };
99
+ }
100
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: CopilotKitFrontendToolDirective, deps: [{ token: CopilotKitService }], target: i0.ɵɵFactoryTarget.Directive });
101
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.13", type: CopilotKitFrontendToolDirective, isStandalone: true, selector: "[copilotkitFrontendTool]", inputs: { name: "name", description: "description", parameters: "parameters", handler: "handler", render: "render", followUp: "followUp", tool: ["copilotkitFrontendTool", "tool"] }, usesOnChanges: true, ngImport: i0 });
102
+ }
103
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: CopilotKitFrontendToolDirective, decorators: [{
104
+ type: Directive,
105
+ args: [{
106
+ selector: "[copilotkitFrontendTool]",
107
+ standalone: true,
108
+ }]
109
+ }], ctorParameters: () => [{ type: i1.CopilotKitService, decorators: [{
110
+ type: Inject,
111
+ args: [CopilotKitService]
112
+ }] }], propDecorators: { name: [{
113
+ type: Input
114
+ }], description: [{
115
+ type: Input
116
+ }], parameters: [{
117
+ type: Input
118
+ }], handler: [{
119
+ type: Input
120
+ }], render: [{
121
+ type: Input
122
+ }], followUp: [{
123
+ type: Input
124
+ }], tool: [{
125
+ type: Input,
126
+ args: ["copilotkitFrontendTool"]
127
+ }] } });
128
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29waWxvdGtpdC1mcm9udGVuZC10b29sLmRpcmVjdGl2ZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9kaXJlY3RpdmVzL2NvcGlsb3RraXQtZnJvbnRlbmQtdG9vbC5kaXJlY3RpdmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLFNBQVMsRUFDVCxLQUFLLEVBT0wsU0FBUyxFQUNULE1BQU0sR0FDUCxNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQzs7O0FBWS9ELE1BQU0sT0FBTywrQkFBK0I7SUFRSTtJQUh0QyxZQUFZLEdBQUcsS0FBSyxDQUFDO0lBRTdCLFlBQzhDLFVBQTZCO1FBQTdCLGVBQVUsR0FBVixVQUFVLENBQW1CO0lBQ3hFLENBQUM7SUFFSyxJQUFJLENBQVU7SUFDZCxXQUFXLENBQVU7SUFDckIsVUFBVSxDQUFrQjtJQUM1QixPQUFPLENBQTZCO0lBQ3BDLE1BQU0sQ0FBZ0M7SUFDdEMsUUFBUSxDQUFXO0lBRTVCLHlDQUF5QztJQUNSLElBQUksQ0FBMEI7SUFFL0QsUUFBUTtRQUNOLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztJQUN0QixDQUFDO0lBRUQsV0FBVyxDQUFDLFFBQXVCO1FBQ2pDLElBQUksSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO1lBQ3RCLGdEQUFnRDtZQUNoRCxJQUFJLENBQUMsY0FBYyxFQUFFLENBQUM7WUFDdEIsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO1FBQ3RCLENBQUM7SUFDSCxDQUFDO0lBRUQsV0FBVztRQUNULElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztJQUN4QixDQUFDO0lBRU8sWUFBWTtRQUNsQixNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7UUFFNUIsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUNmLElBQUksU0FBUyxFQUFF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QUFVO1lBQzNCLE9BQU8sRUFBRSxJQUFJLENBQUMsT0FBTztZQUNyQixNQUFNLEVBQUUsSUFBSSxDQUFDLE1BQU07WUFDbkIsUUFBUSxFQUFFLElBQUksQ0FBQyxRQUFRO1NBQ3hCLENBQUM7SUFDSixDQUFDO3dHQXRIVSwrQkFBK0Isa0JBUWhDLGlCQUFpQjs0RkFSaEIsK0JBQStCOzs0RkFBL0IsK0JBQStCO2tCQUozQyxTQUFTO21CQUFDO29CQUNULFFBQVEsRUFBRSwwQkFBMEI7b0JBQ3BDLFVBQVUsRUFBRSxJQUFJO2lCQUNqQjs7MEJBU0ksTUFBTTsyQkFBQyxpQkFBaUI7eUNBR2xCLElBQUk7c0JBQVosS0FBSztnQkFDRyxXQUFXO3NCQUFuQixLQUFLO2dCQUNHLFVBQVU7c0JBQWxCLEtBQUs7Z0JBQ0csT0FBTztzQkFBZixLQUFLO2dCQUNHLE1BQU07c0JBQWQsS0FBSztnQkFDRyxRQUFRO3NCQUFoQixLQUFLO2dCQUcyQixJQUFJO3NCQUFwQyxLQUFLO3VCQUFDLHdCQUF3QiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIERpcmVjdGl2ZSxcbiAgSW5wdXQsXG4gIE9uSW5pdCxcbiAgT25DaGFuZ2VzLFxuICBPbkRlc3Ryb3ksXG4gIFNpbXBsZUNoYW5nZXMsXG4gIFRlbXBsYXRlUmVmLFxuICBUeXBlLFxuICBpc0Rldk1vZGUsXG4gIEluamVjdCxcbn0gZnJvbSBcIkBhbmd1bGFyL2NvcmVcIjtcbmltcG9ydCB7IENvcGlsb3RLaXRTZXJ2aWNlIH0gZnJvbSBcIi4uL2NvcmUvY29waWxvdGtpdC5zZXJ2aWNlXCI7XG5pbXBvcnQgdHlwZSB7XG4gIEFuZ3VsYXJGcm9udGVuZFRvb2wsXG4gIEFuZ3VsYXJUb29sQ2FsbFJlbmRlcixcbiAgVG9vbENhbGxSZW5kZXIsXG59IGZyb20gXCIuLi9jb3JlL2NvcGlsb3RraXQudHlwZXNcIjtcbmltcG9ydCB0eXBlIHsgeiB9IGZyb20gXCJ6b2RcIjtcblxuQERpcmVjdGl2ZSh7XG4gIHNlbGVjdG9yOiBcIltjb3BpbG90a2l0RnJvbnRlbmRUb29sXVwiLFxuICBzdGFuZGFsb25lOiB0cnVlLFxufSlcbmV4cG9ydCBjbGFzcyBDb3BpbG90S2l0RnJvbnRlbmRUb29sRGlyZWN0aXZlPFxuICAgIFQgZXh0ZW5kcyBSZWNvcmQ8c3RyaW5nLCBhbnk+ID0gUmVjb3JkPHN0cmluZywgYW55PixcbiAgPlxuICBpbXBsZW1lbnRzIE9uSW5pdCwgT25DaGFuZ2VzLCBPbkRlc3Ryb3lcbntcbiAgcHJpdmF0ZSBpc1JlZ2lzdGVyZWQgPSBmYWxzZTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBASW5qZWN0KENvcGlsb3RLaXRTZXJ2aWNlKSBwcml2YXRlIHJlYWRvbmx5IGNvcGlsb3RraXQ6IENvcGlsb3RLaXRTZXJ2aWNlXG4gICkge31cblxuICBASW5wdXQoKSBuYW1lITogc3RyaW5nO1xuICBASW5wdXQoKSBkZXNjcmlwdGlvbj86IHN0cmluZztcbiAgQElucHV0KCkgcGFyYW1ldGVycz86IHouWm9kU2NoZW1hPFQ+O1xuICBASW5wdXQoKSBoYW5kbGVyPzogKGFyZ3M6IFQpID0+IFByb21pc2U8YW55PjtcbiAgQElucHV0KCkgcmVuZGVyPzogVHlwZTxhbnk+IHwgVGVtcGxhdGVSZWY8YW55PjtcbiAgQElucHV0KCkgZm9sbG93VXA/OiBib29sZWFuO1xuXG4gIC8vIEFsdGVybmF0aXZlOiBBY2NlcHQgYSBmdWxsIHRvb2wgb2JqZWN0XG4gIEBJbnB1dChcImNvcGlsb3RraXRGcm9udGVuZFRvb2xcIikgdG9vbD86IEFuZ3VsYXJGcm9udGVuZFRvb2w8VD47XG5cbiAgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgdGhpcy5yZWdpc3RlclRvb2woKTtcbiAgfVxuXG4gIG5nT25DaGFuZ2VzKF9jaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuaXNSZWdpc3RlcmVkKSB7XG4gICAgICAvLyBSZS1yZWdpc3RlciB0aGUgdG9vbCBpZiBhbnkgcHJvcGVydGllcyBjaGFuZ2VcbiAgICAgIHRoaXMudW5yZWdpc3RlclRvb2woKTtcbiAgICAgIHRoaXMucmVnaXN0ZXJUb29sKCk7XG4gICAgfVxuICB9XG5cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgdGhpcy51bnJlZ2lzdGVyVG9vbCgpO1xuICB9XG5cbiAgcHJpdmF0ZSByZWdpc3RlclRvb2woKTogdm9pZCB7XG4gICAgY29uc3QgdG9vbCA9IHRoaXMuZ2V0VG9vbCgpO1xuXG4gICAgaWYgKCF0b29sLm5hbWUpIHtcbiAgICAgIGlmIChpc0Rldk1vZGUoKSkge1xuICAgICAgICBjb25zb2xlLndhcm4oXG4gICAgICAgICAgJ0NvcGlsb3RLaXRGcm9udGVuZFRvb2xEaXJlY3RpdmU6IFwibmFtZVwiIGlzIHJlcXVpcmVkLiAnICtcbiAgICAgICAgICAgICdQbGVhc2UgcHJvdmlkZSBhIG5hbWUgdmlhIFtuYW1lXT1cInRvb2xOYW1lXCIgb3IgJyArXG4gICAgICAgICAgICBcIltjb3BpbG90a2l0RnJvbnRlbmRUb29sXT1cXFwieyBuYW1lOiAndG9vbE5hbWUnLCAuLi4gfVxcXCJcIlxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgcmV0dXJuOyAvLyBEb24ndCByZWdpc3RlciBpZiBubyBuYW1lXG4gICAgfVxuXG4gICAgLy8gUmVnaXN0ZXIgdGhlIHRvb2wgd2l0aCBDb3BpbG90S2l0XG4gICAgdGhpcy5jb3BpbG90a2l0LmNvcGlsb3RraXQuYWRkVG9vbCh0b29sKTtcblxuICAgIC8vIFJlZ2lzdGVyIHRoZSByZW5kZXIgaWYgcHJvdmlkZWRcbiAgICBpZiAodG9vbC5yZW5kZXIpIHtcbiAgICAgIGNvbnN0IGN1cnJlbnRSZW5kZXJzID0gdGhpcy5jb3BpbG90a2l0LmN1cnJlbnRSZW5kZXJUb29sQ2FsbHMoKTtcbiAgICAgIGNvbnN0IHJlbmRlckVudHJ5OiBBbmd1bGFyVG9vbENhbGxSZW5kZXIgPSB7XG4gICAgICAgIG5hbWU6IHRvb2wubmFtZSxcbiAgICAgICAgcmVuZGVyOiB0b29sLnJlbmRlcixcbiAgICAgIH07XG5cbiAgICAgIC8vIENoZWNrIGZvciBkdXBsaWNhdGVcbiAgICAgIGNvbnN0IGV4aXN0aW5nSW5kZXggPSBjdXJyZW50UmVuZGVycy5maW5kSW5kZXgoKHI6IFRvb2xDYWxsUmVuZGVyKSA9PiByLm5hbWUgPT09IHRvb2wubmFtZSk7XG4gICAgICBpZiAoZXhpc3RpbmdJbmRleCAhPT0gLTEpIHtcbiAgICAgICAgaWYgKGlzRGV2TW9kZSgpKSB7XG4gICAgICAgICAgY29uc29sZS53YXJuKFxuICAgICAgICAgICAgYFtDb3BpbG90S2l0XSBUb29sIFwiJHt0b29sLm5hbWV9XCIgYWxyZWFkeSBoYXMgYSByZW5kZXIuIGAgK1xuICAgICAgICAgICAgICBgVGhlIHByZXZpb3VzIHJlbmRlciB3aWxsIGJlIHJlcGxhY2VkLiBgICtcbiAgICAgICAgICAgICAgYFRoaXMgbWF5IGluZGljYXRlIGEgZHVwbGljYXRlIHRvb2wgcmVnaXN0cmF0aW9uLmBcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHVwZGF0ZWQgPSBbLi4uY3VycmVudFJlbmRlcnNdO1xuICAgICAgICB1cGRhdGVkW2V4aXN0aW5nSW5kZXhdID0gcmVuZGVyRW50cnk7XG4gICAgICAgIHRoaXMuY29waWxvdGtpdC5zZXRDdXJyZW50UmVuZGVyVG9vbENhbGxzKHVwZGF0ZWQpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5jb3BpbG90a2l0LnNldEN1cnJlbnRSZW5kZXJUb29sQ2FsbHMoWy4uLmN1cnJlbnRSZW5kZXJzLCByZW5kZXJFbnRyeV0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMuaXNSZWdpc3RlcmVkID0gdHJ1ZTtcbiAgfVxuXG4gIHByaXZhdGUgdW5yZWdpc3RlclRvb2woKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLmlzUmVnaXN0ZXJlZCkgcmV0dXJuO1xuXG4gICAgY29uc3QgdG9vbCA9IHRoaXMuZ2V0VG9vbCgpO1xuXG4gICAgaWYgKHRvb2wubmFtZSkge1xuICAgICAgLy8gUmVtb3ZlIHRoZSB0b29sXG4gICAgICB0aGlzLmNvcGlsb3RraXQuY29waWxvdGtpdC5yZW1vdmVUb29sKHRvb2wubmFtZSk7XG5cbiAgICAgIC8vIFJlbW92ZSB0aGUgcmVuZGVyIGlmIGl0IGV4aXN0c1xuICAgICAgY29uc3QgY3VycmVudFJlbmRlcnMgPSB0aGlzLmNvcGlsb3RraXQuY3VycmVudFJlbmRlclRvb2xDYWxscygpO1xuICAgICAgY29uc3QgZmlsdGVyZWQgPSBjdXJyZW50UmVuZGVycy5maWx0ZXIoKHI6IFRvb2xDYWxsUmVuZGVyKSA9PiByLm5hbWUgIT09IHRvb2wubmFtZSk7XG4gICAgICBpZiAoZmlsdGVyZWQubGVuZ3RoICE9PSBjdXJyZW50UmVuZGVycy5sZW5ndGgpIHtcbiAgICAgICAgdGhpcy5jb3BpbG90a2l0LnNldEN1cnJlbnRSZW5kZXJUb29sQ2FsbHMoZmlsdGVyZWQpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMuaXNSZWdpc3RlcmVkID0gZmFsc2U7XG4gIH1cblxuICBwcml2YXRlIGdldFRvb2woKTogQW5ndWxhckZyb250ZW5kVG9vbDxUPiB7XG4gICAgLy8gSWYgZnVsbCB0b29sIG9iamVjdCBpcyBwcm92aWRlZCwgdXNlIGl0XG4gICAgaWYgKHRoaXMudG9vbCkge1xuICAgICAgcmV0dXJuIHRoaXMudG9vbDtcbiAgICB9XG5cbiAgICAvLyBPdGhlcndpc2UsIGNvbnN0cnVjdCBmcm9tIGluZGl2aWR1YWwgaW5wdXRzXG4gICAgcmV0dXJuIHtcbiAgICAgIG5hbWU6IHRoaXMubmFtZSxcbiAgICAgIGRlc2NyaXB0aW9uOiB0aGlzLmRlc2NyaXB0aW9uLFxuICAgICAgcGFyYW1ldGVyczogdGhpcy5wYXJhbWV0ZXJzLFxuICAgICAgaGFuZGxlcjogdGhpcy5oYW5kbGVyLFxuICAgICAgcmVuZGVyOiB0aGlzLnJlbmRlcixcbiAgICAgIGZvbGxvd1VwOiB0aGlzLmZvbGxvd1VwLFxuICAgIH07XG4gIH1cbn1cbiJdfQ==
@@ -0,0 +1,265 @@
1
+ import { Directive, Input, Output, EventEmitter, signal, isDevMode, Inject, } from "@angular/core";
2
+ import { CopilotKitService } from "../core/copilotkit.service";
3
+ import { ToolCallStatus } from "../core/copilotkit.types";
4
+ import * as i0 from "@angular/core";
5
+ import * as i1 from "../core/copilotkit.service";
6
+ /**
7
+ * Directive for declaratively creating human-in-the-loop tools.
8
+ * Provides reactive outputs for status changes and response events.
9
+ *
10
+ * @example
11
+ * ```html
12
+ * <!-- Basic usage -->
13
+ * <div copilotkitHumanInTheLoop
14
+ * [name]="'requireApproval'"
15
+ * [description]="'Requires user approval'"
16
+ * [args]="argsSchema"
17
+ * [render]="approvalComponent"
18
+ * (statusChange)="onStatusChange($event)"
19
+ * (responseProvided)="onResponse($event)">
20
+ * </div>
21
+ *
22
+ * <!-- With template -->
23
+ * <div copilotkitHumanInTheLoop
24
+ * [name]="'requireApproval'"
25
+ * [description]="'Requires user approval'"
26
+ * [args]="argsSchema"
27
+ * [render]="approvalTemplate"
28
+ * [(status)]="approvalStatus">
29
+ * </div>
30
+ *
31
+ * <ng-template #approvalTemplate let-props>
32
+ * <div *ngIf="props.status === 'executing'">
33
+ * <p>{{ props.args.action }}</p>
34
+ * <button (click)="props.respond('approved')">Approve</button>
35
+ * <button (click)="props.respond('rejected')">Reject</button>
36
+ * </div>
37
+ * </ng-template>
38
+ * ```
39
+ */
40
+ export class CopilotKitHumanInTheLoopDirective {
41
+ copilotkit;
42
+ toolId;
43
+ statusSignal = signal(ToolCallStatus.InProgress);
44
+ resolvePromise = null;
45
+ _status = ToolCallStatus.InProgress;
46
+ constructor(copilotkit) {
47
+ this.copilotkit = copilotkit;
48
+ }
49
+ /**
50
+ * The name of the human-in-the-loop tool.
51
+ */
52
+ name;
53
+ /**
54
+ * Description of what the tool does.
55
+ */
56
+ description;
57
+ /**
58
+ * Zod schema for the tool parameters.
59
+ */
60
+ parameters;
61
+ /**
62
+ * Component class or template to render for user interaction.
63
+ */
64
+ render;
65
+ /**
66
+ * Whether the tool should be registered (default: true).
67
+ */
68
+ enabled = true;
69
+ /**
70
+ * Alternative input using the directive selector.
71
+ * Allows: [copilotkitHumanInTheLoop]="config"
72
+ */
73
+ set config(value) {
74
+ if (value) {
75
+ if (value.name)
76
+ this.name = value.name;
77
+ if (value.description)
78
+ this.description = value.description;
79
+ if ("parameters" in value && value.parameters)
80
+ this.parameters = value.parameters;
81
+ if ("render" in value && value.render)
82
+ this.render = value.render;
83
+ }
84
+ }
85
+ /**
86
+ * Emits when the status changes.
87
+ */
88
+ statusChange = new EventEmitter();
89
+ /**
90
+ * Two-way binding for status.
91
+ */
92
+ get status() {
93
+ return this._status;
94
+ }
95
+ set status(value) {
96
+ // Input setter for two-way binding (though typically read-only)
97
+ this._status = value;
98
+ }
99
+ /**
100
+ * Emits when a response is provided by the user.
101
+ */
102
+ responseProvided = new EventEmitter();
103
+ /**
104
+ * Emits when the tool execution starts.
105
+ */
106
+ executionStarted = new EventEmitter();
107
+ /**
108
+ * Emits when the tool execution completes.
109
+ */
110
+ executionCompleted = new EventEmitter();
111
+ ngOnInit() {
112
+ if (this.enabled) {
113
+ this.registerTool();
114
+ }
115
+ }
116
+ ngOnChanges(changes) {
117
+ const relevantChanges = changes["name"] ||
118
+ changes["description"] ||
119
+ changes["args"] ||
120
+ changes["render"] ||
121
+ changes["enabled"];
122
+ if (relevantChanges && !relevantChanges.firstChange) {
123
+ // Re-register the tool with new configuration
124
+ this.unregisterTool();
125
+ if (this.enabled) {
126
+ this.registerTool();
127
+ }
128
+ }
129
+ }
130
+ ngOnDestroy() {
131
+ this.unregisterTool();
132
+ }
133
+ /**
134
+ * Programmatically trigger a response.
135
+ * Useful when the directive is used as a controller.
136
+ */
137
+ respond(result) {
138
+ this.handleResponse(result);
139
+ }
140
+ registerTool() {
141
+ if (!this.name || !this.description || !this.parameters || !this.render) {
142
+ if (isDevMode()) {
143
+ throw new Error("CopilotKitHumanInTheLoopDirective: Missing required inputs. " +
144
+ "Required: name, description, parameters, and render.");
145
+ }
146
+ return;
147
+ }
148
+ // Create handler that returns a Promise
149
+ const handler = async (args) => {
150
+ return new Promise((resolve) => {
151
+ this.updateStatus(ToolCallStatus.Executing);
152
+ this.resolvePromise = resolve;
153
+ this.executionStarted.emit(args);
154
+ });
155
+ };
156
+ // Create the frontend tool with enhanced render
157
+ const frontendTool = {
158
+ name: this.name,
159
+ description: this.description,
160
+ parameters: this.parameters,
161
+ handler,
162
+ render: this.render, // Will be enhanced by the render component
163
+ };
164
+ // Add the tool (returns void, so we use the tool name as ID)
165
+ this.copilotkit.copilotkit.addTool(frontendTool);
166
+ this.toolId = this.name;
167
+ // Register the render with respond capability
168
+ this.copilotkit.registerToolRender(this.name, {
169
+ name: this.name,
170
+ render: this.createEnhancedRender(),
171
+ });
172
+ }
173
+ unregisterTool() {
174
+ if (this.toolId) {
175
+ this.copilotkit.copilotkit.removeTool(this.toolId);
176
+ this.copilotkit.unregisterToolRender(this.name);
177
+ this.toolId = undefined;
178
+ }
179
+ }
180
+ createEnhancedRender() {
181
+ // If it's a template, we need to wrap it with our respond function
182
+ // This is handled by returning a special marker that the render component
183
+ // will recognize and enhance with the respond function
184
+ // Store reference to this directive instance for the render component
185
+ this.render.__humanInTheLoopDirective = this;
186
+ this.render.__humanInTheLoopStatus = this.statusSignal;
187
+ return this.render;
188
+ }
189
+ handleResponse(result) {
190
+ if (this.resolvePromise) {
191
+ this.resolvePromise(result);
192
+ this.updateStatus(ToolCallStatus.Complete);
193
+ this.resolvePromise = null;
194
+ this.responseProvided.emit(result);
195
+ this.executionCompleted.emit(result);
196
+ }
197
+ }
198
+ updateStatus(status) {
199
+ this._status = status;
200
+ this.statusSignal.set(status);
201
+ this.statusChange.emit(status);
202
+ }
203
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: CopilotKitHumanInTheLoopDirective, deps: [{ token: CopilotKitService }], target: i0.ɵɵFactoryTarget.Directive });
204
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.13", type: CopilotKitHumanInTheLoopDirective, isStandalone: true, selector: "[copilotkitHumanInTheLoop]", inputs: { name: "name", description: "description", parameters: "parameters", render: "render", enabled: "enabled", config: ["copilotkitHumanInTheLoop", "config"], status: "status" }, outputs: { statusChange: "statusChange", responseProvided: "responseProvided", executionStarted: "executionStarted", executionCompleted: "executionCompleted" }, usesOnChanges: true, ngImport: i0 });
205
+ }
206
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: CopilotKitHumanInTheLoopDirective, decorators: [{
207
+ type: Directive,
208
+ args: [{
209
+ selector: "[copilotkitHumanInTheLoop]",
210
+ standalone: true,
211
+ }]
212
+ }], ctorParameters: () => [{ type: i1.CopilotKitService, decorators: [{
213
+ type: Inject,
214
+ args: [CopilotKitService]
215
+ }] }], propDecorators: { name: [{
216
+ type: Input
217
+ }], description: [{
218
+ type: Input
219
+ }], parameters: [{
220
+ type: Input
221
+ }], render: [{
222
+ type: Input
223
+ }], enabled: [{
224
+ type: Input
225
+ }], config: [{
226
+ type: Input,
227
+ args: ["copilotkitHumanInTheLoop"]
228
+ }], statusChange: [{
229
+ type: Output
230
+ }], status: [{
231
+ type: Input
232
+ }], responseProvided: [{
233
+ type: Output
234
+ }], executionStarted: [{
235
+ type: Output
236
+ }], executionCompleted: [{
237
+ type: Output
238
+ }] } });
239
+ /**
240
+ * Helper directive to provide respond function in templates.
241
+ * This would be used internally by the tool render component.
242
+ *
243
+ * @internal
244
+ */
245
+ export class CopilotKitHumanInTheLoopRespondDirective {
246
+ copilotkitHumanInTheLoopRespond;
247
+ /**
248
+ * Convenience method for templates to call respond.
249
+ */
250
+ respond(result) {
251
+ this.copilotkitHumanInTheLoopRespond?.(result);
252
+ }
253
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: CopilotKitHumanInTheLoopRespondDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
254
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.13", type: CopilotKitHumanInTheLoopRespondDirective, isStandalone: true, selector: "[copilotkitHumanInTheLoopRespond]", inputs: { copilotkitHumanInTheLoopRespond: "copilotkitHumanInTheLoopRespond" }, ngImport: i0 });
255
+ }
256
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: CopilotKitHumanInTheLoopRespondDirective, decorators: [{
257
+ type: Directive,
258
+ args: [{
259
+ selector: "[copilotkitHumanInTheLoopRespond]",
260
+ standalone: true,
261
+ }]
262
+ }], propDecorators: { copilotkitHumanInTheLoopRespond: [{
263
+ type: Input
264
+ }] } });
265
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29waWxvdGtpdC1odW1hbi1pbi10aGUtbG9vcC5kaXJlY3RpdmUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvZGlyZWN0aXZlcy9jb3BpbG90a2l0LWh1bWFuLWluLXRoZS1sb29wLmRpcmVjdGl2ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsU0FBUyxFQUNULEtBQUssRUFDTCxNQUFNLEVBQ04sWUFBWSxFQU9aLE1BQU0sRUFDTixTQUFTLEVBQ1QsTUFBTSxHQUNQLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBTS9ELE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQzs7O0FBRzFEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FpQ0c7QUFLSCxNQUFNLE9BQU8saUNBQWlDO0lBV0U7SUFOdEMsTUFBTSxDQUFVO0lBQ2hCLFlBQVksR0FBRyxNQUFNLENBQWlCLGNBQWMsQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUNqRSxjQUFjLEdBQXVDLElBQUksQ0FBQztJQUMxRCxPQUFPLEdBQW1CLGNBQWMsQ0FBQyxVQUFVLENBQUM7SUFFNUQsWUFDOEMsVUFBNkI7UUFBN0IsZUFBVSxHQUFWLFVBQVUsQ0FBbUI7SUFDeEUsQ0FBQztJQUVKOztPQUVHO0lBQ00sSUFBSSxDQUFVO0lBRXZCOztPQUVHO0lBQ00sV0FBVyxDQUFVO0lBRTlCOztPQUVHO0lBQ00sVUFBVSxDQUFrQjtJQUVyQzs7T0FFRztJQUNNLE1BQU0sQ0FBbUQ7SUFFbEU7O09BRUc7SUFDTSxPQUFPLEdBQUcsSUFBSSxDQUFDO0lBRXhCOzs7T0FHRztJQUNILElBQ0ksTUFBTSxDQUFDLEtBQW9EO1FBQzdELElBQUksS0FBSyxFQUFFLENBQUM7WUFDVixJQUFJLEtBQUssQ0FBQyxJQUFJO2dCQUFFLElBQUksQ0FBQyxJQUFJLEdBQUcsS0FBSyxD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Ozs7R0FLRztBQUtILE1BQU0sT0FBTyx3Q0FBd0M7SUFDMUMsK0JBQStCLENBQXNDO0lBRTlFOztPQUVHO0lBQ0gsT0FBTyxDQUFDLE1BQWU7UUFDckIsSUFBSSxDQUFDLCtCQUErQixFQUFFLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDakQsQ0FBQzt3R0FSVSx3Q0FBd0M7NEZBQXhDLHdDQUF3Qzs7NEZBQXhDLHdDQUF3QztrQkFKcEQsU0FBUzttQkFBQztvQkFDVCxRQUFRLEVBQUUsbUNBQW1DO29CQUM3QyxVQUFVLEVBQUUsSUFBSTtpQkFDakI7OEJBRVUsK0JBQStCO3NCQUF2QyxLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgRGlyZWN0aXZlLFxuICBJbnB1dCxcbiAgT3V0cHV0LFxuICBFdmVudEVtaXR0ZXIsXG4gIE9uSW5pdCxcbiAgT25DaGFuZ2VzLFxuICBPbkRlc3Ryb3ksXG4gIFNpbXBsZUNoYW5nZXMsXG4gIFRlbXBsYXRlUmVmLFxuICBUeXBlLFxuICBzaWduYWwsXG4gIGlzRGV2TW9kZSxcbiAgSW5qZWN0LFxufSBmcm9tIFwiQGFuZ3VsYXIvY29yZVwiO1xuaW1wb3J0IHsgQ29waWxvdEtpdFNlcnZpY2UgfSBmcm9tIFwiLi4vY29yZS9jb3BpbG90a2l0LnNlcnZpY2VcIjtcbmltcG9ydCB0eXBlIHtcbiAgQW5ndWxhckh1bWFuSW5UaGVMb29wLFxuICBIdW1hbkluVGhlTG9vcFByb3BzLFxuICBBbmd1bGFyRnJvbnRlbmRUb29sLFxufSBmcm9tIFwiLi4vY29yZS9jb3BpbG90a2l0LnR5cGVzXCI7XG5pbXBvcnQgeyBUb29sQ2FsbFN0YXR1cyB9IGZyb20gXCIuLi9jb3JlL2NvcGlsb3RraXQudHlwZXNcIjtcbmltcG9ydCAqIGFzIHogZnJvbSBcInpvZFwiO1xuXG4vKipcbiAqIERpcmVjdGl2ZSBmb3IgZGVjbGFyYXRpdmVseSBjcmVhdGluZyBodW1hbi1pbi10aGUtbG9vcCB0b29scy5cbiAqIFByb3ZpZGVzIHJlYWN0aXZlIG91dHB1dHMgZm9yIHN0YXR1cyBjaGFuZ2VzIGFuZCByZXNwb25zZSBldmVudHMuXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYGh0bWxcbiAqIDwhLS0gQmFzaWMgdXNhZ2UgLS0+XG4gKiA8ZGl2IGNvcGlsb3RraXRIdW1hbkluVGhlTG9vcFxuICogICAgICBbbmFtZV09XCIncmVxdWlyZUFwcHJvdmFsJ1wiXG4gKiAgICAgIFtkZXNjcmlwdGlvbl09XCInUmVxdWlyZXMgdXNlciBhcHByb3ZhbCdcIlxuICogICAgICBbYXJnc109XCJhcmdzU2NoZW1hXCJcbiAqICAgICAgW3JlbmRlcl09XCJhcHByb3ZhbENvbXBvbmVudFwiXG4gKiAgICAgIChzdGF0dXNDaGFuZ2UpPVwib25TdGF0dXNDaGFuZ2UoJGV2ZW50KVwiXG4gKiAgICAgIChyZXNwb25zZVByb3ZpZGVkKT1cIm9uUmVzcG9uc2UoJGV2ZW50KVwiPlxuICogPC9kaXY+XG4gKlxuICogPCEtLSBXaXRoIHRlbXBsYXRlIC0tPlxuICogPGRpdiBjb3BpbG90a2l0SHVtYW5JblRoZUxvb3BcbiAqICAgICAgW25hbWVdPVwiJ3JlcXVpcmVBcHByb3ZhbCdcIlxuICogICAgICBbZGVzY3JpcHRpb25dPVwiJ1JlcXVpcmVzIHVzZXIgYXBwcm92YWwnXCJcbiAqICAgICAgW2FyZ3NdPVwiYXJnc1NjaGVtYVwiXG4gKiAgICAgIFtyZW5kZXJdPVwiYXBwcm92YWxUZW1wbGF0ZVwiXG4gKiAgICAgIFsoc3RhdHVzKV09XCJhcHByb3ZhbFN0YXR1c1wiPlxuICogPC9kaXY+XG4gKlxuICogPG5nLXRlbXBsYXRlICNhcHByb3ZhbFRlbXBsYXRlIGxldC1wcm9wcz5cbiAqICAgPGRpdiAqbmdJZj1cInByb3BzLnN0YXR1cyA9PT0gJ2V4ZWN1dGluZydcIj5cbiAqICAgICA8cD57eyBwcm9wcy5hcmdzLmFjdGlvbiB9fTwvcD5cbiAqICAgICA8YnV0dG9uIChjbGljayk9XCJwcm9wcy5yZXNwb25kKCdhcHByb3ZlZCcpXCI+QXBwcm92ZTwvYnV0dG9uPlxuICogICAgIDxidXR0b24gKGNsaWNrKT1cInByb3BzLnJlc3BvbmQoJ3JlamVjdGVkJylcIj5SZWplY3Q8L2J1dHRvbj5cbiAqICAgPC9kaXY+XG4gKiA8L25nLXRlbXBsYXRlPlxuICogYGBgXG4gKi9cbkBEaXJlY3RpdmUoe1xuICBzZWxlY3RvcjogXCJbY29waWxvdGtpdEh1bWFuSW5UaGVMb29wXVwiLFxuICBzdGFuZGFsb25lOiB0cnVlLFxufSlcbmV4cG9ydCBjbGFzcyBDb3BpbG90S2l0SHVtYW5JblRoZUxvb3BEaXJlY3RpdmU8XG4gICAgVCBleHRlbmRzIFJlY29yZDxzdHJpbmcsIGFueT4gPSBSZWNvcmQ8c3RyaW5nLCBhbnk+LFxuICA+XG4gIGltcGxlbWVudHMgT25Jbml0LCBPbkNoYW5nZXMsIE9uRGVzdHJveVxue1xuICBwcml2YXRlIHRvb2xJZD86IHN0cmluZztcbiAgcHJpdmF0ZSBzdGF0dXNTaWduYWwgPSBzaWduYWw8VG9vbENhbGxTdGF0dXM+KFRvb2xDYWxsU3RhdHVzLkluUHJvZ3Jlc3MpO1xuICBwcml2YXRlIHJlc29sdmVQcm9taXNlOiAoKHJlc3VsdDogdW5rbm93bikgPT4gdm9pZCkgfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBfc3RhdHVzOiBUb29sQ2FsbFN0YXR1cyA9IFRvb2xDYWxsU3RhdHVzLkluUHJvZ3Jlc3M7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgQEluamVjdChDb3BpbG90S2l0U2VydmljZSkgcHJpdmF0ZSByZWFkb25seSBjb3BpbG90a2l0OiBDb3BpbG90S2l0U2VydmljZVxuICApIHt9XG5cbiAgLyoqXG4gICAqIFRoZSBuYW1lIG9mIHRoZSBodW1hbi1pbi10aGUtbG9vcCB0b29sLlxuICAgKi9cbiAgQElucHV0KCkgbmFtZSE6IHN0cmluZztcblxuICAvKipcbiAgICogRGVzY3JpcHRpb24gb2Ygd2hhdCB0aGUgdG9vbCBkb2VzLlxuICAgKi9cbiAgQElucHV0KCkgZGVzY3JpcHRpb24hOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFpvZCBzY2hlbWEgZm9yIHRoZSB0b29sIHBhcmFtZXRlcnMuXG4gICAqL1xuICBASW5wdXQoKSBwYXJhbWV0ZXJzITogei5ab2RTY2hlbWE8VD47XG5cbiAgLyoqXG4gICAqIENvbXBvbmVudCBjbGFzcyBvciB0ZW1wbGF0ZSB0byByZW5kZXIgZm9yIHVzZXIgaW50ZXJhY3Rpb24uXG4gICAqL1xuICBASW5wdXQoKSByZW5kZXIhOiBUeXBlPGFueT4gfCBUZW1wbGF0ZVJlZjxIdW1hbkluVGhlTG9vcFByb3BzPFQ+PjtcblxuICAvKipcbiAgICogV2hldGhlciB0aGUgdG9vbCBzaG91bGQgYmUgcmVnaXN0ZXJlZCAoZGVmYXVsdDogdHJ1ZSkuXG4gICAqL1xuICBASW5wdXQoKSBlbmFibGVkID0gdHJ1ZTtcblxuICAvKipcbiAgICogQWx0ZXJuYXRpdmUgaW5wdXQgdXNpbmcgdGhlIGRpcmVjdGl2ZSBzZWxlY3Rvci5cbiAgICogQWxsb3dzOiBbY29waWxvdGtpdEh1bWFuSW5UaGVMb29wXT1cImNvbmZpZ1wiXG4gICAqL1xuICBASW5wdXQoXCJjb3BpbG90a2l0SHVtYW5JblRoZUxvb3BcIilcbiAgc2V0IGNvbmZpZyh2YWx1ZTogUGFydGlhbDxBbmd1bGFySHVtYW5JblRoZUxvb3A8VD4+IHwgdW5kZWZpbmVkKSB7XG4gICAgaWYgKHZhbHVlKSB7XG4gICAgICBpZiAodmFsdWUubmFtZSkgdGhpcy5uYW1lID0gdmFsdWUubmFtZTtcbiAgICAgIGlmICh2YWx1ZS5kZXNjcmlwdGlvbikgdGhpcy5kZXNjcmlwdGlvbiA9IHZhbHVlLmRlc2NyaXB0aW9uO1xuICAgICAgaWYgKFwicGFyYW1ldGVyc1wiIGluIHZhbHVlICYmIHZhbHVlLnBhcmFtZXRlcnMpXG4gICAgICAgIHRoaXMucGFyYW1ldGVycyA9IHZhbHVlLnBhcmFtZXRlcnMgYXMgei5ab2RTY2hlbWE8VD47XG4gICAgICBpZiAoXCJyZW5kZXJcIiBpbiB2YWx1ZSAmJiB2YWx1ZS5yZW5kZXIpIHRoaXMucmVuZGVyID0gdmFsdWUucmVuZGVyO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBFbWl0cyB3aGVuIHRoZSBzdGF0dXMgY2hhbmdlcy5cbiAgICovXG4gIEBPdXRwdXQoKSBzdGF0dXNDaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPFRvb2xDYWxsU3RhdHVzPigpO1xuXG4gIC8qKlxuICAgKiBUd28td2F5IGJpbmRpbmcgZm9yIHN0YXR1cy5cbiAgICovXG4gIEBJbnB1dCgpXG4gIGdldCBzdGF0dXMoKTogVG9vbENhbGxTdGF0dXMge1xuICAgIHJldHVybiB0aGlzLl9zdGF0dXM7XG4gIH1cbiAgc2V0IHN0YXR1cyh2YWx1ZTogVG9vbENhbGxTdGF0dXMpIHtcbiAgICAvLyBJbnB1dCBzZXR0ZXIgZm9yIHR3by13YXkgYmluZGluZyAodGhvdWdoIHR5cGljYWxseSByZWFkLW9ubHkpXG4gICAgdGhpcy5fc3RhdHVzID0gdmFsdWU7XG4gIH1cblxuICAvKipcbiAgICogRW1pdHMgd2hlbiBhIHJlc3BvbnNlIGlzIHByb3ZpZGVkIGJ5IHRoZSB1c2VyLlxuICAgKi9cbiAgQE91dHB1dCgpIHJlc3BvbnNlUHJvdmlkZWQgPSBuZXcgRXZlbnRFbWl0dGVyPHVua25vd24+KCk7XG5cbiAgLyoqXG4gICAqIEVtaXRzIHdoZW4gdGhlIHRvb2wgZXhlY3V0aW9uIHN0YXJ0cy5cbiAgICovXG4gIEBPdXRwdXQoKSBleGVjdXRpb25TdGFydGVkID0gbmV3IEV2ZW50RW1pdHRlcjxhbnk+KCk7XG5cbiAgLyoqXG4gICAqIEVtaXRzIHdoZW4gdGhlIHRvb2wgZXhlY3V0aW9uIGNvbXBsZXRlcy5cbiAgICovXG4gIEBPdXRwdXQoKSBleGVjdXRpb25Db21wbGV0ZWQgPSBuZXcgRXZlbnRFbWl0dGVyPHVua25vd24+KCk7XG5cbiAgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuZW5hYmxlZCkge1xuICAgICAgdGhpcy5yZWdpc3RlclRvb2woKTtcbiAgICB9XG4gIH1cblxuICBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKTogdm9pZCB7XG4gICAgY29uc3QgcmVsZXZhbnRDaGFuZ2VzID1cbiAgICAgIGNoYW5nZXNbXCJuYW1lXCJdIHx8XG4gICAgICBjaGFuZ2VzW1wiZGVzY3JpcHRpb25cIl0gfHxcbiAgICAgIGNoYW5nZXNbXCJhcmdzXCJdIHx8XG4gICAgICBjaGFuZ2VzW1wicmVuZGVyXCJdIHx8XG4gICAgICBjaGFuZ2VzW1wiZW5hYmxlZFwiXTtcblxuICAgIGlmIChyZWxldmFudENoYW5nZXMgJiYgIXJlbGV2YW50Q2hhbmdlcy5maXJzdENoYW5nZSkge1xuICAgICAgLy8gUmUtcmVnaXN0ZXIgdGhlIHRvb2wgd2l0aCBuZXcgY29uZmlndXJhdGlvblxuICAgICAgdGhpcy51bnJlZ2lzdGVyVG9vbCgpO1xuICAgICAgaWYgKHRoaXMuZW5hYmxlZCkge1xuICAgICAgICB0aGlzLnJlZ2lzdGVyVG9vbCgpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIG5nT25EZXN0cm95KCk6IHZvaWQge1xuICAgIHRoaXMudW5yZWdpc3RlclRvb2woKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBQcm9ncmFtbWF0aWNhbGx5IHRyaWdnZXIgYSByZXNwb25zZS5cbiAgICogVXNlZnVsIHdoZW4gdGhlIGRpcmVjdGl2ZSBpcyB1c2VkIGFzIGEgY29udHJvbGxlci5cbiAgICovXG4gIHJlc3BvbmQocmVzdWx0OiB1bmtub3duKTogdm9pZCB7XG4gICAgdGhpcy5oYW5kbGVSZXNwb25zZShyZXN1bHQpO1xuICB9XG5cbiAgcHJpdmF0ZSByZWdpc3RlclRvb2woKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLm5hbWUgfHwgIXRoaXMuZGVzY3JpcHRpb24gfHwgIXRoaXMucGFyYW1ldGVycyB8fCAhdGhpcy5yZW5kZXIpIHtcbiAgICAgIGlmIChpc0Rldk1vZGUoKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgXCJDb3BpbG90S2l0SHVtYW5JblRoZUxvb3BEaXJlY3RpdmU6IE1pc3NpbmcgcmVxdWlyZWQgaW5wdXRzLiBcIiArXG4gICAgICAgICAgICBcIlJlcXVpcmVkOiBuYW1lLCBkZXNjcmlwdGlvbiwgcGFyYW1ldGVycywgYW5kIHJlbmRlci5cIlxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIENyZWF0ZSBoYW5kbGVyIHRoYXQgcmV0dXJucyBhIFByb21pc2VcbiAgICBjb25zdCBoYW5kbGVyID0gYXN5bmMgKGFyZ3M6IFQpOiBQcm9taXNlPHVua25vd24+ID0+IHtcbiAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4ge1xuICAgICAgICB0aGlzLnVwZGF0ZVN0YXR1cyhUb29sQ2FsbFN0YXR1cy5FeGVjdXRpbmcpO1xuICAgICAgICB0aGlzLnJlc29sdmVQcm9taXNlID0gcmVzb2x2ZTtcbiAgICAgICAgdGhpcy5leGVjdXRpb25TdGFydGVkLmVtaXQoYXJncyk7XG4gICAgICB9KTtcbiAgICB9O1xuXG4gICAgLy8gQ3JlYXRlIHRoZSBmcm9udGVuZCB0b29sIHdpdGggZW5oYW5jZWQgcmVuZGVyXG4gICAgY29uc3QgZnJvbnRlbmRUb29sOiBBbmd1bGFyRnJvbnRlbmRUb29sPFQ+ID0ge1xuICAgICAgbmFtZTogdGhpcy5uYW1lLFxuICAgICAgZGVzY3JpcHRpb246IHRoaXMuZGVzY3JpcHRpb24sXG4gICAgICBwYXJhbWV0ZXJzOiB0aGlzLnBhcmFtZXRlcnMsXG4gICAgICBoYW5kbGVyLFxuICAgICAgcmVuZGVyOiB0aGlzLnJlbmRlciwgLy8gV2lsbCBiZSBlbmhhbmNlZCBieSB0aGUgcmVuZGVyIGNvbXBvbmVudFxuICAgIH07XG5cbiAgICAvLyBBZGQgdGhlIHRvb2wgKHJldHVybnMgdm9pZCwgc28gd2UgdXNlIHRoZSB0b29sIG5hbWUgYXMgSUQpXG4gICAgdGhpcy5jb3BpbG90a2l0LmNvcGlsb3RraXQuYWRkVG9vbChmcm9udGVuZFRvb2wpO1xuICAgIHRoaXMudG9vbElkID0gdGhpcy5uYW1lO1xuXG4gICAgLy8gUmVnaXN0ZXIgdGhlIHJlbmRlciB3aXRoIHJlc3BvbmQgY2FwYWJpbGl0eVxuICAgIHRoaXMuY29waWxvdGtpdC5yZWdpc3RlclRvb2xSZW5kZXIodGhpcy5uYW1lLCB7XG4gICAgICBuYW1lOiB0aGlzLm5hbWUsXG4gICAgICByZW5kZXI6IHRoaXMuY3JlYXRlRW5oYW5jZWRSZW5kZXIoKSxcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgdW5yZWdpc3RlclRvb2woKTogdm9pZCB7XG4gICAgaWYgKHRoaXMudG9vbElkKSB7XG4gICAgICB0aGlzLmNvcGlsb3RraXQuY29waWxvdGtpdC5yZW1vdmVUb29sKHRoaXMudG9vbElkKTtcbiAgICAgIHRoaXMuY29waWxvdGtpdC51bnJlZ2lzdGVyVG9vbFJlbmRlcih0aGlzLm5hbWUpO1xuICAgICAgdGhpcy50b29sSWQgPSB1bmRlZmluZWQ7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBjcmVhdGVFbmhhbmNlZFJlbmRlcigpOiBUeXBlPGFueT4gfCBUZW1wbGF0ZVJlZjxhbnk+IHtcbiAgICAvLyBJZiBpdCdzIGEgdGVtcGxhdGUsIHdlIG5lZWQgdG8gd3JhcCBpdCB3aXRoIG91ciByZXNwb25kIGZ1bmN0aW9uXG4gICAgLy8gVGhpcyBpcyBoYW5kbGVkIGJ5IHJldHVybmluZyBhIHNwZWNpYWwgbWFya2VyIHRoYXQgdGhlIHJlbmRlciBjb21wb25lbnRcbiAgICAvLyB3aWxsIHJlY29nbml6ZSBhbmQgZW5oYW5jZSB3aXRoIHRoZSByZXNwb25kIGZ1bmN0aW9uXG5cbiAgICAvLyBTdG9yZSByZWZlcmVuY2UgdG8gdGhpcyBkaXJlY3RpdmUgaW5zdGFuY2UgZm9yIHRoZSByZW5kZXIgY29tcG9uZW50XG4gICAgKHRoaXMucmVuZGVyIGFzIGFueSkuX19odW1hbkluVGhlTG9vcERpcmVjdGl2ZSA9IHRoaXM7XG4gICAgKHRoaXMucmVuZGVyIGFzIGFueSkuX19odW1hbkluVGhlTG9vcFN0YXR1cyA9IHRoaXMuc3RhdHVzU2lnbmFsO1xuXG4gICAgcmV0dXJuIHRoaXMucmVuZGVyO1xuICB9XG5cbiAgcHJpdmF0ZSBoYW5kbGVSZXNwb25zZShyZXN1bHQ6IHVua25vd24pOiB2b2lkIHtcbiAgICBpZiAodGhpcy5yZXNvbHZlUHJvbWlzZSkge1xuICAgICAgdGhpcy5yZXNvbHZlUHJvbWlzZShyZXN1bHQpO1xuICAgICAgdGhpcy51cGRhdGVTdGF0dXMoVG9vbENhbGxTdGF0dXMuQ29tcGxldGUpO1xuICAgICAgdGhpcy5yZXNvbHZlUHJvbWlzZSA9IG51bGw7XG4gICAgICB0aGlzLnJlc3BvbnNlUHJvdmlkZWQuZW1pdChyZXN1bHQpO1xuICAgICAgdGhpcy5leGVjdXRpb25Db21wbGV0ZWQuZW1pdChyZXN1bHQpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgdXBkYXRlU3RhdHVzKHN0YXR1czogVG9vbENhbGxTdGF0dXMpOiB2b2lkIHtcbiAgICB0aGlzLl9zdGF0dXMgPSBzdGF0dXM7XG4gICAgdGhpcy5zdGF0dXNTaWduYWwuc2V0KHN0YXR1cyk7XG4gICAgdGhpcy5zdGF0dXNDaGFuZ2UuZW1pdChzdGF0dXMpO1xuICB9XG59XG5cbi8qKlxuICogSGVscGVyIGRpcmVjdGl2ZSB0byBwcm92aWRlIHJlc3BvbmQgZnVuY3Rpb24gaW4gdGVtcGxhdGVzLlxuICogVGhpcyB3b3VsZCBiZSB1c2VkIGludGVybmFsbHkgYnkgdGhlIHRvb2wgcmVuZGVyIGNvbXBvbmVudC5cbiAqXG4gKiBAaW50ZXJuYWxcbiAqL1xuQERpcmVjdGl2ZSh7XG4gIHNlbGVjdG9yOiBcIltjb3BpbG90a2l0SHVtYW5JblRoZUxvb3BSZXNwb25kXVwiLFxuICBzdGFuZGFsb25lOiB0cnVlLFxufSlcbmV4cG9ydCBjbGFzcyBDb3BpbG90S2l0SHVtYW5JblRoZUxvb3BSZXNwb25kRGlyZWN0aXZlIHtcbiAgQElucHV0KCkgY29waWxvdGtpdEh1bWFuSW5UaGVMb29wUmVzcG9uZD86IChyZXN1bHQ6IHVua25vd24pID0+IFByb21pc2U8dm9pZD47XG5cbiAgLyoqXG4gICAqIENvbnZlbmllbmNlIG1ldGhvZCBmb3IgdGVtcGxhdGVzIHRvIGNhbGwgcmVzcG9uZC5cbiAgICovXG4gIHJlc3BvbmQocmVzdWx0OiB1bmtub3duKTogdm9pZCB7XG4gICAgdGhpcy5jb3BpbG90a2l0SHVtYW5JblRoZUxvb3BSZXNwb25kPy4ocmVzdWx0KTtcbiAgfVxufVxuIl19