cpee 2.1.135 → 2.1.136

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 (205) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/cockpit/compliance-view.html +12 -13
  4. data/cockpit/compliance.html +12 -13
  5. data/cockpit/css/llm.css +3 -3
  6. data/cockpit/css/llmmodel.css +140 -0
  7. data/cockpit/css/model.css +0 -1
  8. data/cockpit/css/ui.css +13 -7
  9. data/cockpit/css/wfadaptor.css +15 -10
  10. data/cockpit/edit.html +12 -13
  11. data/cockpit/graph.html +8 -8
  12. data/cockpit/index.html +12 -13
  13. data/cockpit/js/build-bpmn2.js +302 -0
  14. data/cockpit/js/details.js +27 -10
  15. data/cockpit/js/instance.js +193 -203
  16. data/cockpit/js/llm-ui-bubble.js +36 -0
  17. data/cockpit/js/llm-ui-status.js +34 -0
  18. data/cockpit/js/llm-ui.js +87 -0
  19. data/cockpit/js/llm.js +463 -118
  20. data/cockpit/js/parameters.js +45 -14
  21. data/cockpit/js/wfadaptor.js +394 -75
  22. data/cockpit/llm.html +17 -15
  23. data/cockpit/llmmodel.html +18 -17
  24. data/cockpit/model.html +9 -9
  25. data/cockpit/only_llm.html +15 -13
  26. data/cockpit/themes/base.js +1 -1
  27. data/cockpit/themes/packed/theme.js +3 -0
  28. data/cockpit/themes/presetlr/rngs/alternative.rng +28 -0
  29. data/cockpit/themes/presetlr/rngs/call.rng +249 -0
  30. data/cockpit/themes/presetlr/rngs/callmanipulate.rng +281 -0
  31. data/cockpit/themes/presetlr/rngs/choose.rng +27 -0
  32. data/cockpit/themes/presetlr/rngs/closed_loop.rng +62 -0
  33. data/cockpit/themes/presetlr/rngs/closed_loop_cancel.rng +5 -0
  34. data/cockpit/themes/presetlr/rngs/closed_loop_control.rng +31 -0
  35. data/cockpit/themes/presetlr/rngs/closed_loop_measuring.rng +12 -0
  36. data/cockpit/themes/presetlr/rngs/critical.rng +8 -0
  37. data/cockpit/themes/presetlr/rngs/escape.rng +5 -0
  38. data/cockpit/themes/presetlr/rngs/group.rng +3 -0
  39. data/cockpit/themes/presetlr/rngs/loop.rng +40 -0
  40. data/cockpit/themes/presetlr/rngs/manipulate.rng +76 -0
  41. data/cockpit/themes/presetlr/rngs/otherwise.rng +25 -0
  42. data/cockpit/themes/presetlr/rngs/parallel.rng +24 -0
  43. data/cockpit/themes/presetlr/rngs/parallel_branch.rng +5 -0
  44. data/cockpit/themes/presetlr/rngs/scripts.rng +23 -0
  45. data/cockpit/themes/presetlr/rngs/start.rng +143 -0
  46. data/cockpit/themes/presetlr/rngs/stop.rng +5 -0
  47. data/cockpit/themes/presetlr/rngs/terminate.rng +8 -0
  48. data/cockpit/themes/presetlr/rngs/wait_for_signal.rng +8 -0
  49. data/cockpit/themes/presetlr/symbols/alternative.svg +19 -0
  50. data/cockpit/themes/presetlr/symbols/arrow.svg +1 -0
  51. data/cockpit/themes/presetlr/symbols/call.svg +1 -0
  52. data/cockpit/themes/presetlr/symbols/call_sensor.svg +1 -0
  53. data/cockpit/themes/presetlr/symbols/callmanipulate.svg +1 -0
  54. data/cockpit/themes/presetlr/symbols/callmanipulate_sensor.svg +1 -0
  55. data/cockpit/themes/presetlr/symbols/callmanipulate_sensor_signal.svg +1 -0
  56. data/cockpit/themes/presetlr/symbols/callmanipulate_signal.svg +1 -0
  57. data/cockpit/themes/presetlr/symbols/choose.svg +15 -0
  58. data/cockpit/themes/presetlr/symbols/choose_exclusive.svg +15 -0
  59. data/cockpit/themes/presetlr/symbols/choose_exclusive_finish.svg +1 -0
  60. data/cockpit/themes/presetlr/symbols/choose_inclusive.svg +13 -0
  61. data/cockpit/themes/presetlr/symbols/choose_inclusive_finish.svg +1 -0
  62. data/cockpit/themes/presetlr/symbols/closed_loop.svg +1 -0
  63. data/cockpit/themes/presetlr/symbols/closed_loop_cancel.svg +1 -0
  64. data/cockpit/themes/presetlr/symbols/closed_loop_control.svg +1 -0
  65. data/cockpit/themes/presetlr/symbols/closed_loop_measuring.svg +1 -0
  66. data/cockpit/themes/presetlr/symbols/complex.svg +1 -0
  67. data/cockpit/themes/presetlr/symbols/critical.svg +1 -0
  68. data/cockpit/themes/presetlr/symbols/delete.svg +1 -0
  69. data/cockpit/themes/presetlr/symbols/end.svg +1 -0
  70. data/cockpit/themes/presetlr/symbols/escape.svg +1 -0
  71. data/cockpit/themes/presetlr/symbols/event_end.svg +1 -0
  72. data/cockpit/themes/presetlr/symbols/event_start.svg +1 -0
  73. data/cockpit/themes/presetlr/symbols/loop.svg +15 -0
  74. data/cockpit/themes/presetlr/symbols/loop_end.svg +15 -0
  75. data/cockpit/themes/presetlr/symbols/loop_end_pre.svg +15 -0
  76. data/cockpit/themes/presetlr/symbols/manipulate.svg +1 -0
  77. data/cockpit/themes/presetlr/symbols/mark.svg +1 -0
  78. data/cockpit/themes/presetlr/symbols/otherwise.svg +7 -0
  79. data/cockpit/themes/presetlr/symbols/parallel.svg +1 -0
  80. data/cockpit/themes/presetlr/symbols/parallel_branch.svg +7 -0
  81. data/cockpit/themes/presetlr/symbols/parallel_branch_event.svg +14 -0
  82. data/cockpit/themes/presetlr/symbols/parallel_branch_event_rev.svg +11 -0
  83. data/cockpit/themes/presetlr/symbols/parallel_branch_normal.svg +7 -0
  84. data/cockpit/themes/presetlr/symbols/parallel_eventbased_exclusive.svg +1 -0
  85. data/cockpit/themes/presetlr/symbols/parallel_eventbased_parallel.svg +1 -0
  86. data/cockpit/themes/presetlr/symbols/scripts.svg +1 -0
  87. data/cockpit/themes/presetlr/symbols/start.svg +1 -0
  88. data/cockpit/themes/presetlr/symbols/start_event.svg +1 -0
  89. data/cockpit/themes/presetlr/symbols/stop.svg +1 -0
  90. data/cockpit/themes/presetlr/symbols/terminate.svg +1 -0
  91. data/cockpit/themes/presetlr/symbols/wait_for_signal.svg +1 -0
  92. data/cockpit/themes/presetlr/theme.js +54 -0
  93. data/cockpit/themes/wellformed/rngs/alternative.rng +28 -0
  94. data/cockpit/themes/wellformed/rngs/call.rng +249 -0
  95. data/cockpit/themes/wellformed/rngs/callmanipulate.rng +281 -0
  96. data/cockpit/themes/wellformed/rngs/choose.rng +27 -0
  97. data/cockpit/themes/wellformed/rngs/closed_loop.rng +62 -0
  98. data/cockpit/themes/wellformed/rngs/closed_loop_cancel.rng +5 -0
  99. data/cockpit/themes/wellformed/rngs/closed_loop_control.rng +31 -0
  100. data/cockpit/themes/wellformed/rngs/closed_loop_measuring.rng +12 -0
  101. data/cockpit/themes/wellformed/rngs/critical.rng +8 -0
  102. data/cockpit/themes/wellformed/rngs/escape.rng +5 -0
  103. data/cockpit/themes/wellformed/rngs/group.rng +3 -0
  104. data/cockpit/themes/wellformed/rngs/loop.rng +40 -0
  105. data/cockpit/themes/wellformed/rngs/manipulate.rng +76 -0
  106. data/cockpit/themes/wellformed/rngs/otherwise.rng +25 -0
  107. data/cockpit/themes/wellformed/rngs/parallel.rng +24 -0
  108. data/cockpit/themes/wellformed/rngs/parallel_branch.rng +5 -0
  109. data/cockpit/themes/wellformed/rngs/scripts.rng +23 -0
  110. data/cockpit/themes/wellformed/rngs/start.rng +143 -0
  111. data/cockpit/themes/wellformed/rngs/stop.rng +5 -0
  112. data/cockpit/themes/wellformed/rngs/terminate.rng +8 -0
  113. data/cockpit/themes/wellformed/rngs/wait_for_signal.rng +8 -0
  114. data/cockpit/themes/wellformed/symbols/alternative.svg +1 -0
  115. data/cockpit/themes/wellformed/symbols/arrow.svg +1 -0
  116. data/cockpit/themes/wellformed/symbols/call.svg +1 -0
  117. data/cockpit/themes/wellformed/symbols/call_sensor.svg +1 -0
  118. data/cockpit/themes/wellformed/symbols/callmanipulate.svg +1 -0
  119. data/cockpit/themes/wellformed/symbols/callmanipulate_sensor.svg +1 -0
  120. data/cockpit/themes/wellformed/symbols/callmanipulate_sensor_signal.svg +1 -0
  121. data/cockpit/themes/wellformed/symbols/callmanipulate_signal.svg +1 -0
  122. data/cockpit/themes/wellformed/symbols/choose.svg +1 -0
  123. data/cockpit/themes/wellformed/symbols/choose_exclusive.svg +1 -0
  124. data/cockpit/themes/wellformed/symbols/choose_exclusive_finish.svg +1 -0
  125. data/cockpit/themes/wellformed/symbols/choose_inclusive.svg +1 -0
  126. data/cockpit/themes/wellformed/symbols/choose_inclusive_finish.svg +1 -0
  127. data/cockpit/themes/wellformed/symbols/closed_loop.svg +1 -0
  128. data/cockpit/themes/wellformed/symbols/closed_loop_cancel.svg +1 -0
  129. data/cockpit/themes/wellformed/symbols/closed_loop_control.svg +1 -0
  130. data/cockpit/themes/wellformed/symbols/closed_loop_measuring.svg +1 -0
  131. data/cockpit/themes/wellformed/symbols/complex.svg +1 -0
  132. data/cockpit/themes/wellformed/symbols/critical.svg +1 -0
  133. data/cockpit/themes/wellformed/symbols/delete.svg +1 -0
  134. data/cockpit/themes/wellformed/symbols/end.svg +1 -0
  135. data/cockpit/themes/wellformed/symbols/escape.svg +1 -0
  136. data/cockpit/themes/wellformed/symbols/event_end.svg +1 -0
  137. data/cockpit/themes/wellformed/symbols/event_start.svg +6 -0
  138. data/cockpit/themes/wellformed/symbols/loop.svg +1 -0
  139. data/cockpit/themes/wellformed/symbols/loop_end.svg +1 -0
  140. data/cockpit/themes/wellformed/symbols/manipulate.svg +1 -0
  141. data/cockpit/themes/wellformed/symbols/mark.svg +1 -0
  142. data/cockpit/themes/wellformed/symbols/otherwise.svg +1 -0
  143. data/cockpit/themes/wellformed/symbols/parallel.svg +1 -0
  144. data/cockpit/themes/wellformed/symbols/parallel_branch.svg +1 -0
  145. data/cockpit/themes/wellformed/symbols/parallel_branch_event.svg +1 -0
  146. data/cockpit/themes/wellformed/symbols/parallel_branch_event_rev.svg +11 -0
  147. data/cockpit/themes/wellformed/symbols/parallel_branch_normal.svg +1 -0
  148. data/cockpit/themes/wellformed/symbols/parallel_eventbased_exclusive.svg +1 -0
  149. data/cockpit/themes/wellformed/symbols/parallel_eventbased_parallel.svg +1 -0
  150. data/cockpit/themes/wellformed/symbols/scripts.svg +1 -0
  151. data/cockpit/themes/wellformed/symbols/start.svg +1 -0
  152. data/cockpit/themes/wellformed/symbols/start_event.svg +1 -0
  153. data/cockpit/themes/wellformed/symbols/stop.svg +1 -0
  154. data/cockpit/themes/wellformed/symbols/terminate.svg +1 -0
  155. data/cockpit/themes/wellformed/symbols/wait_for_signal.svg +1 -0
  156. data/cockpit/themes/wellformed/theme.js +32 -0
  157. data/cockpit/track.html +8 -8
  158. data/cpee.gemspec +2 -2
  159. data/lib/callbacks/callbacks.rng +4 -4
  160. data/lib/callbacks.xml +4 -4
  161. data/lib/cpee/constants.rb +4 -4
  162. data/lib/cpee/fail.rb +4 -4
  163. data/lib/cpee/implementation.rb +5 -4
  164. data/lib/cpee/implementation_callbacks.rb +4 -4
  165. data/lib/cpee/implementation_notifications.rb +4 -4
  166. data/lib/cpee/implementation_properties.rb +108 -12
  167. data/lib/cpee/message.rb +4 -4
  168. data/lib/cpee/persistence.rb +6 -4
  169. data/lib/cpee/redis.rb +4 -4
  170. data/lib/cpee/statemachine.rb +4 -4
  171. data/lib/cpee/value_helper.rb +4 -4
  172. data/lib/cpee.xml +4 -4
  173. data/lib/engine/executionhandler-list.rng +4 -4
  174. data/lib/engine/instance-info.rng +4 -4
  175. data/lib/engine/instances.rng +4 -4
  176. data/lib/engine.xml +4 -4
  177. data/lib/properties/t_dslx.rng +346 -0
  178. data/lib/properties/transformation.rng +14 -0
  179. data/lib/properties.xml +5 -4
  180. data/server/executionhandlers/eval/backend/opts.yaml +1 -1
  181. data/server/executionhandlers/eval/connection.rb +4 -4
  182. data/server/executionhandlers/eval/execution.rb +4 -4
  183. data/server/executionhandlers/ruby/backend/opts.yaml +1 -1
  184. data/server/executionhandlers/ruby/connection.rb +5 -6
  185. data/server/executionhandlers/ruby/controller.rb +4 -4
  186. data/server/executionhandlers/ruby/dsl_to_dslx.xsl +6 -2
  187. data/server/executionhandlers/ruby/execution.rb +4 -4
  188. data/server/resources/properties.empty +5 -4
  189. data/server/resources/properties.init +5 -4
  190. data/server/resources/topics.xml +4 -4
  191. data/server/routing/end.pid +1 -1
  192. data/server/routing/end.rb +4 -4
  193. data/server/routing/forward-events-00.pid +1 -1
  194. data/server/routing/forward-events.rb +4 -4
  195. data/server/routing/forward-votes.pid +1 -1
  196. data/server/routing/forward-votes.rb +4 -4
  197. data/server/routing/persist.pid +1 -1
  198. data/server/routing/persist.rb +6 -4
  199. data/tools/server/cpee +1 -1
  200. data/tools/server/resources/properties.init +4 -4
  201. metadata +136 -5
  202. data/cockpit/CPEE.xml +0 -8
  203. data/cockpit/Signavio.xml +0 -8
  204. data/cockpit/transformations.xml +0 -4
  205. /data/{COPYING → LICENSE} +0 -0
data/cockpit/js/llm.js CHANGED
@@ -1,19 +1,14 @@
1
- var last_generated_model = undefined;
2
- var last_model_before_generation =undefined;
3
- var default_llm = "gemini-2.5-flash-lite";
4
-
5
- function clean_llm_ui(status) { //{{{
6
- status.empty();
7
- status.removeClass('error').removeClass('success');
8
- status.removeClass('error').removeClass('error');
9
- status.removeClass('error').removeClass('loading');
10
- } //}}}
1
+ var last_model_before_generation = undefined;
2
+ var default_llm = "gemini-3.1-flash-lite";
11
3
 
12
- function querying_llm_ui(status,llm,what) { //{{{
13
- let myllm = llm.find(":selected").val();
14
- if (myllm === undefined){ myllm = default_llm; }
15
- status.addClass('loading');
16
- status.text('Agent ' + what + ' (' + myllm + ')');
4
+ function xhr_error(xhr) { //{{{
5
+ if (xhr.responseJSON && xhr.responseJSON.error) {
6
+ return xhr.responseJSON.error;
7
+ }
8
+ if (xhr.responseText) {
9
+ return 'LLM Service not reachable (request status ' + xhr.status + ')!'
10
+ }
11
+ return xhr.statusText;
17
12
  } //}}}
18
13
 
19
14
  function add_prompt(input,content) { //{{{
@@ -25,6 +20,104 @@ function add_prompt(input,content) { //{{{
25
20
  document.execCommand('insertText', false, content);
26
21
  } //}}}
27
22
 
23
+ function call_llm_service_intent(input, llm, llms, dslx, messages, documents, depth=0) { //{{{
24
+ let def = new $.Deferred();
25
+
26
+ (async () => {
27
+ try {
28
+ const intent_form = new FormData();
29
+ intent_form.append("user_input", new Blob([input], { type: "text/plain" }));
30
+ intent_form.append("llm", new Blob([llm], { type: "text/plain" }));
31
+
32
+ let intent = await $.ajax({
33
+ url: $('body').attr('current-llm-service') + '/intent/',
34
+ data: intent_form,
35
+ contentType: false,
36
+ processData: false,
37
+ cache: false,
38
+ method: 'POST'
39
+ });
40
+
41
+ if (intent === null) {
42
+ // no intent matched at all
43
+ ui.success(llms,"Your request seems to be not about process modelling (or anything covered by the installed plugins).");
44
+ def.resolve(null);
45
+ return;
46
+ }
47
+
48
+ if (typeof intent === 'object' && Object.keys(intent).length === 0) {
49
+ // no specific plugin matched: proceed normally with the original input
50
+ def.resolve(input);
51
+ return;
52
+ }
53
+
54
+ const call_form = new FormData();
55
+ call_form.append("user_input", new Blob([input], { type: "text/plain" }));
56
+ call_form.append("llm", new Blob([llm], { type: "text/plain" }));
57
+ (intent.required_input || []).forEach(function(name){
58
+ if (name === 'model') {
59
+ call_form.append("dslx", new Blob([dslx], { type: "text/xml" }));
60
+ } else if (name === 'documents') {
61
+ call_form.append("documents", new Blob([JSON.stringify(documents)], { type: "application/json" }));
62
+ } else if (name === 'messages') {
63
+ call_form.append("messages", new Blob([messages], { type: "text/plain" }));
64
+ }
65
+ });
66
+
67
+ let response;
68
+ console.log(intent.url);
69
+ try {
70
+ response = await $.ajax({
71
+ url: intent.url,
72
+ data: call_form,
73
+ cache: false,
74
+ contentType: false,
75
+ processData: false,
76
+ method: 'PUT'
77
+ });
78
+ } catch (xhr) {
79
+ let trimmed_url = intent.url.replace(/\/+$/, '');
80
+ ui.error(llms,"The intent plugin \'" + trimmed_url.substr(trimmed_url.lastIndexOf('/') + 1) + "\' is not working properly.");
81
+ def.resolve(null);
82
+ return;
83
+ }
84
+
85
+ let filled_output;
86
+ if (intent.output_template) {
87
+ filled_output = intent.output_template;
88
+ if (response !== null && typeof response === 'object') {
89
+ Object.keys(response).forEach(function(key){
90
+ filled_output = filled_output.split('%%%' + key).join(response[key]);
91
+ });
92
+ } else {
93
+ filled_output = filled_output.replace('%%%', response);
94
+ }
95
+ } else {
96
+ filled_output = response;
97
+ }
98
+
99
+ if (intent.output == 'chat') {
100
+ ui.success(llms,filled_output);
101
+ def.resolve(null);
102
+ } else if (intent.output == 'reintent' && filled_output !== input && depth < 3) {
103
+ // repeat the process of looking for a plugin/intent, using the filled output as the new input
104
+ // (at most 3 times, to avoid endless plugin loops)
105
+ call_llm_service_intent(filled_output,llm,llms,dslx,messages,documents,depth + 1).done((result) => {
106
+ def.resolve(result);
107
+ }).fail((xhr) => {
108
+ def.reject(xhr);
109
+ });
110
+ } else {
111
+ def.resolve(filled_output);
112
+ }
113
+ } catch (xhr) {
114
+ def.reject(xhr);
115
+ }
116
+ })();
117
+
118
+ return def.promise();
119
+ } //}}}
120
+
28
121
  function call_llm_service_model(dslx,input,llm,prompt_type) { //{{{
29
122
  const formData = new FormData();
30
123
  const blob1 = new Blob([dslx], { type: "text/xml" });
@@ -112,7 +205,7 @@ function call_llm_service_validation(model,llm) { //{{{
112
205
  return def.promise();
113
206
  } //}}}
114
207
 
115
- function call_llm_text_service(status,prompt,llms,action) { //{{{
208
+ function call_llm_text_service(prompt,llms,action) { //{{{
116
209
  let myllm = llms.find(":selected").val();
117
210
  if (myllm === undefined){ myllm = default_llm; }
118
211
  const info = save.attributes_raw.info;
@@ -140,16 +233,256 @@ function call_llm_text_service(status,prompt,llms,action) { //{{{
140
233
  link.href = dataUri;
141
234
  link.click();
142
235
  };
143
- last_model_before_generation = save['dslx'];
144
- set_success(status,data.status);
236
+ ui.success(llms,data.status);
145
237
  },
146
238
  error: function(xhr, stat, data) {
147
- set_error(status,xhr.responseJSON.error);
239
+ ui.error(llms,xhr_error(xhr));
148
240
  }
149
241
  });
150
242
  } //}}}
151
243
 
244
+ function diff_summary_rec(el, nodes) { //{{{
245
+ function hash_str(str) {
246
+ let h = 0x811c9dc5;
247
+ for (let i = 0; i < str.length; i++) {
248
+ h ^= str.charCodeAt(i);
249
+ h = Math.imul(h, 0x01000193);
250
+ }
251
+ return (h >>> 0).toString(36);
252
+ }
253
+
254
+ function serialize_clean(node) {
255
+ let clone = node.cloneNode(true);
256
+ (function strip(n){
257
+ for (let i = n.childNodes.length - 1; i >= 0; i--) {
258
+ let c = n.childNodes[i];
259
+ if (c.nodeType === 3 && /^\s*$/.test(c.nodeValue)) { n.removeChild(c); }
260
+ else if (c.nodeType === 1) { strip(c); }
261
+ }
262
+ })(clone);
263
+ return new XMLSerializer().serializeToString(clone);
264
+ }
265
+
266
+ $(el).children().each(function(){
267
+ let child = this;
268
+ let id = child.getAttribute('id');
269
+ let eid = child.getAttribute('eid');
270
+ if (id !== null) {
271
+ let fields = {};
272
+ for (let i = 0; i < child.attributes.length; i++) {
273
+ fields[child.attributes[i].name] = child.attributes[i].value;
274
+ }
275
+ $(child).children().each(function(){
276
+ let name = this.localName || this.nodeName;
277
+ if (name === 'parameters') {
278
+ $(this).children().each(function(){
279
+ let pname = this.localName || this.nodeName;
280
+ fields[pname] = serialize_clean(this);
281
+ });
282
+ } else {
283
+ fields[name] = serialize_clean(this);
284
+ }
285
+ });
286
+ nodes.push({ id: id, type: 'task', fingerprint: hash_str(serialize_clean(child)), fields: fields });
287
+ } else if (eid !== null) {
288
+ let fields = {};
289
+ for (let i = 0; i < child.attributes.length; i++) {
290
+ fields[child.attributes[i].name] = child.attributes[i].value;
291
+ }
292
+ let attr_parts = Object.keys(fields).sort().map(function(k){ return k + '=' + fields[k]; });
293
+ let child_parts = [];
294
+ $(child).children().each(function(){
295
+ let name = this.localName || this.nodeName;
296
+ if (name.charAt(0) === '_') {
297
+ let serialized = serialize_clean(this);
298
+ fields[name] = serialized;
299
+ child_parts.push(serialized);
300
+ }
301
+ });
302
+ let branch_names = ['parallel_branch','alternative','otherwise'];
303
+ let tag_name = child.localName || child.nodeName;
304
+ let type = branch_names.indexOf(tag_name) !== -1 ? 'branch' : 'gateway';
305
+ nodes.push({ id: eid, type: type, fingerprint: hash_str(attr_parts.concat(child_parts).join('|')), fields: fields });
306
+ }
307
+ diff_summary_rec(child, nodes);
308
+ });
309
+ } //}}}
310
+ function diff_summary(model_old, model_new) { //{{{
311
+ // depth_first traverse both model_old and model_new:
312
+ // all elements with an attribute @id are tasks
313
+ // all elements with an attribute @eid are a gateway, except parallel_branch, alternative and otherwise elements, which are a branch
314
+ // these are the ones included in the list that results from traversal
315
+ // while traversing:
316
+ // for any element that has an @id calculate a fingerprint that contains the whole content
317
+ // for any element that has an @eid calculate a fingerprint for all its attributes and direct children elements whos name starts with a _
318
+
319
+ // after traversal: compare the old_nodes with the new_nodes list by their ids and types (task, gateway)
320
+ // if nodes are in the old_nodes but not in the new_nodes they have been deleted
321
+ // if nodes are in the new_nodes but not in the old_nodes they have been added
322
+ // if nodes of the old_nodes are in a new position in the new_nodes they have been moved
323
+ // if the fingerprint of nodes is not identical, their parameters have been changed
324
+ // if the fingerprint of nodes is not identical, investigate which children or attributes of the nodes have differnt text content
325
+
326
+ // collect all the changes
327
+
328
+ // if more that 3 nodes are affected by any change summarize, combining types that share the same operation: "7 tasks, 3 gateways, and 2 branches have been added, 1 task has been changed"
329
+ // if 3 or less nodes are affected name them "Tasks a3, a2 and a1 have been moved. Parameters of node a1 have been changed."
330
+ // More examples: Task a1 had the attribute "color" changed.
331
+ // More examples: Task a1 had its "color" changed.
332
+ // More examples: Task a1 had its "parameters" changed.
333
+
334
+ // the function returns the textual summary of the differences.
335
+
336
+ function to_root(model) {
337
+ if (typeof model === 'string') { return $X(model).get(0); }
338
+ if (model && model.jquery) { return model.get(0); }
339
+ return model;
340
+ }
341
+
342
+ let old_nodes = [];
343
+ let new_nodes = [];
344
+ diff_summary_rec(to_root(model_old), old_nodes);
345
+ diff_summary_rec(to_root(model_new), new_nodes);
346
+
347
+ let old_index = {};
348
+ old_nodes.forEach(function(n,i){ old_index[n.type + ':' + n.id] = { pos: i, node: n }; });
349
+ let new_index = {};
350
+ new_nodes.forEach(function(n,i){ new_index[n.type + ':' + n.id] = { pos: i, node: n }; });
351
+
352
+ let added = [];
353
+ let deleted = [];
354
+ let moved = [];
355
+ let changed = [];
356
+
357
+ old_nodes.forEach(function(n){
358
+ if (!(n.type + ':' + n.id in new_index)) { deleted.push({ id: n.id, type: n.type }); }
359
+ });
360
+ new_nodes.forEach(function(n){
361
+ if (!(n.type + ':' + n.id in old_index)) { added.push({ id: n.id, type: n.type }); }
362
+ });
363
+
364
+ let common_old_order = old_nodes.filter(function(n){ return (n.type + ':' + n.id) in new_index; }).map(function(n){ return n.type + ':' + n.id; });
365
+ let common_new_order = new_nodes.filter(function(n){ return (n.type + ':' + n.id) in old_index; }).map(function(n){ return n.type + ':' + n.id; });
366
+ let new_pos_of = {};
367
+ common_new_order.forEach(function(key,i){ new_pos_of[key] = i; });
368
+
369
+ // longest increasing subsequence of new-positions (in old order): the nodes that
370
+ // stay in relative order across both versions, i.e. did NOT move. Everything else
371
+ // did move. This avoids flagging every node between an actually-moved node's old
372
+ // and new position as "moved" too.
373
+ let seq = common_old_order.map(function(key){ return new_pos_of[key]; });
374
+ let dp = new Array(seq.length).fill(1);
375
+ let prev = new Array(seq.length).fill(-1);
376
+ let best = -1;
377
+ for (let i = 0; i < seq.length; i++) {
378
+ for (let j = 0; j < i; j++) {
379
+ if (seq[j] < seq[i] && dp[j] + 1 > dp[i]) {
380
+ dp[i] = dp[j] + 1;
381
+ prev[i] = j;
382
+ }
383
+ }
384
+ if (best === -1 || dp[i] > dp[best]) { best = i; }
385
+ }
386
+ let in_lis = new Array(seq.length).fill(false);
387
+ for (let k = best; k !== -1; k = prev[k]) { in_lis[k] = true; }
388
+
389
+ common_old_order.forEach(function(key,i){
390
+ let old_entry = old_index[key];
391
+ let new_entry = new_index[key];
392
+ let id = old_entry.node.id;
393
+ let type = old_entry.node.type;
394
+ if (!in_lis[i]) { moved.push({ id: id, type: type }); }
395
+ if (old_entry.node.fingerprint !== new_entry.node.fingerprint) {
396
+ let old_fields = old_entry.node.fields;
397
+ let new_fields = new_entry.node.fields;
398
+ let field_names = Array.from(new Set(Object.keys(old_fields).concat(Object.keys(new_fields))));
399
+ let diff_fields = field_names.filter(function(f){ return old_fields[f] !== new_fields[f]; });
400
+ changed.push({ id: id, type: type, fields: diff_fields });
401
+ }
402
+ });
403
+
404
+ // when the llm fucks up the ids or eids, this result is fucked as well. And
405
+ // by fucking up i mean, omitting the ids, or changing them all. Oh well.
406
+ // Better than nothing.
407
+
408
+ let affected = new Set(added.concat(deleted,moved,changed).map(function(e){ return e.type + ':' + e.id; }));
409
+ if (affected.size === 0) {
410
+ return "No changes to the model have been made.";
411
+ }
412
+
413
+ // constructing the output
414
+ function join_names(names) {
415
+ if (names.length <= 1) { return names.join(''); }
416
+ if (names.length === 2) { return names[0] + ' and ' + names[1]; }
417
+ return names.slice(0,-1).join(', ') + ' and ' + names[names.length-1];
418
+ }
419
+
420
+ function type_word(type, count) {
421
+ if (type === 'task') { return count === 1 ? 'task' : 'tasks'; }
422
+ if (type === 'branch') { return count === 1 ? 'branch' : 'branches'; }
423
+ return count === 1 ? 'gateway' : 'gateways';
424
+ }
425
+
426
+ const categories = ['added','deleted','moved','changed'];
427
+ const lists = { added: added, deleted: deleted, moved: moved, changed: changed };
428
+
429
+ if (affected.size > 3) {
430
+ const action = { added: 'been added', deleted: 'been deleted', moved: 'been moved', changed: 'been changed' };
431
+ function join_oxford(items) {
432
+ if (items.length <= 1) { return items.join(''); }
433
+ if (items.length === 2) { return items[0] + ' and ' + items[1]; }
434
+ return items.slice(0,-1).join(', ') + ', and ' + items[items.length-1];
435
+ }
436
+ let parts = [];
437
+ categories.forEach(function(c){
438
+ let type_counts = ['task','gateway','branch'].map(function(t){
439
+ return { type: t, count: lists[c].filter(function(e){ return e.type === t; }).length };
440
+ }).filter(function(tc){ return tc.count > 0; });
441
+ if (type_counts.length === 0) { return; }
442
+ let pieces = type_counts.map(function(tc){ return tc.count + ' ' + type_word(tc.type, tc.count); });
443
+ let total = type_counts.reduce(function(sum,tc){ return sum + tc.count; }, 0);
444
+ let verb = total === 1 ? 'has' : 'have';
445
+ parts.push(join_oxford(pieces) + ' ' + verb + ' ' + action[c]);
446
+ });
447
+ let text = parts.join(', ') + '.';
448
+ return text.charAt(0).toUpperCase() + text.slice(1);
449
+ } else {
450
+ let sentences = [];
451
+ const action = { added: 'added', deleted: 'deleted', moved: 'moved', changed: 'changed' };
452
+ categories.forEach(function(c){
453
+ ['task','gateway','branch'].forEach(function(t){
454
+ let entries = lists[c].filter(function(e){ return e.type === t; });
455
+ if (entries.length === 0) { return; }
456
+ if (c === 'changed' && entries.length === 1) {
457
+ let e = entries[0];
458
+ let subj = e.type === 'task' ? 'Task ' : (e.type === 'branch' ? 'Branch ' : 'Gateway ');
459
+ let field_text;
460
+ if (e.fields.length === 0) {
461
+ field_text = '"parameters"';
462
+ } else {
463
+ field_text = join_names(e.fields.map(function(f){ return '"' + f + '"'; }));
464
+ }
465
+ sentences.push(subj + e.id + ' had its ' + field_text + ' changed.');
466
+ return;
467
+ }
468
+ let names = join_names(entries.map(function(e){ return e.id; }));
469
+ let subj = type_word(t, entries.length);
470
+ subj = subj.charAt(0).toUpperCase() + subj.slice(1) + ' ';
471
+ let verb = entries.length === 1 ? ' has been ' : ' have been ';
472
+ sentences.push(subj + names + verb + action[c] + '.');
473
+ });
474
+ });
475
+ return sentences.join(' ');
476
+ }
477
+ } //}}}
478
+
152
479
  function set_cpee_model(cpee_xml,expositions=[]) { //{{{
480
+ let root = $X(cpee_xml).get(0);
481
+ if (root.childElementCount === 0) {
482
+ root.textContent = '';
483
+ cpee_xml = new XMLSerializer().serializeToString(root);
484
+ }
485
+
153
486
  const form_data = new FormData();
154
487
  const blob = new Blob([cpee_xml], { type: "text/xml" });
155
488
  form_data.append("dslx", blob);
@@ -159,42 +492,24 @@ function set_cpee_model(cpee_xml,expositions=[]) { //{{{
159
492
  form_data.append("exposition", blobi);
160
493
  }
161
494
 
162
- $.ajax({
495
+ return $.ajax({
163
496
  type: "PUT",
164
497
  url: url + "/properties/dslx/",
165
498
  contentType: false,
166
499
  processData: false,
167
- data: form_data
500
+ data: form_data,
501
+ error: report_model_failure
168
502
  });
169
503
  } //}}}
170
504
 
171
- function set_success(status,success_text) { //{{{
172
- status.text(success_text);
173
- status.addClass('success');
174
- status.removeClass('loading');
175
- status.removeClass('error');
176
- } //}}}
177
-
178
- function set_error(status,error_text) { //{{{
179
- status.text(error_text);
180
- status.addClass('error');
181
- status.removeClass('success');
182
- status.removeClass('loading');
183
- } //}}}
184
-
185
505
  function empty_model(){ //{{{
506
+ details_leave(false);
186
507
  set_cpee_model('<description xmlns="http://cpee.org/ns/description/1.0" xmlns:a="http://cpee.org/ns/annotation/1.0"/>',["Reset Context!"]);
187
508
  $('#dat_details').empty();
188
509
  } //}}}
189
- function load_last_generated_model() { //{{{
190
- set_cpee_model(last_generated_model === undefined ? save['dslx'] : last_generated_model);
191
- } //}}}
192
- function load_last_generated_model() { //{{{
193
- set_cpee_model(last_generated_model === undefined ? save['dslx'] : last_generated_model);
194
- } //}}}
195
510
 
196
511
  function load_last_model_before_generation() { //{{{
197
- set_cpee_model(last_model_before_generation === undefined ? save['dslx'] : last_model_before_generation);
512
+ return set_cpee_model(last_model_before_generation === undefined ? save['dslx'] : last_model_before_generation);
198
513
  } //}}}
199
514
 
200
515
  function load_file_content(files) { //{{{
@@ -204,23 +519,26 @@ function load_file_content(files) { //{{{
204
519
  }
205
520
  var reader = new FileReader();
206
521
  reader.onload = function(){
207
- clean_llm_ui($('#status'));
208
- add_prompt('prompt',reader.result);
522
+ ui.clean();
523
+ add_prompt($('#prompt'),reader.result);
209
524
  }
210
525
  reader.onerror = function(){ console.log("reader error"); }
211
526
  reader.onabort = function(){ console.log("reader abort"); }
212
527
  reader.readAsText(files[0]);
213
528
  } //}}}
214
529
 
215
- function create(status,prompt,llms,generation,mode) {
216
- clean_llm_ui(status);
530
+ function create(prompt,llms,generation,mode) {
531
+ ui.clean();
217
532
 
218
533
  // Imagine I want to implement a smart home system to control the lights in
219
534
  // the dining room. Depending on the current lighting conditions, the
220
535
  // system would automatically adjust the brightness—either increasing or
221
536
  // reducing it as needed—and turn the lights off completely at night.
222
537
 
223
- let input = prompt.text(); prompt.empty();
538
+ let input = prompt.text();
539
+ if (input.trim() === '') { return; }
540
+ prompt.empty();
541
+ ui.input(llms,input);
224
542
  let myllm = llms.find(":selected").val();
225
543
  let prompt_type = mode.find(":selected").val();
226
544
  let gen = generation.find(":selected").val();
@@ -234,70 +552,88 @@ function create(status,prompt,llms,generation,mode) {
234
552
  if (gen == 'dataflow') { prompt_type = 'adapt_endpoints'; }
235
553
  }
236
554
 
237
- querying_llm_ui(status,llms,'creates model');
238
- call_llm_service_model(save['dslx'],input,myllm,prompt_type).done((data) => {
239
- let expositions = ["<!-- Input CPEE-Tree -->\n"+data.input_cpee,"# User Input:\n"+data.user_input,"# Used LLM:\n"+data.used_llm,"%% Input Intermediate\n"+data.input_intermediate,"%% Output Intermediate\n"+data.output_intermediate,"<!-- Output CPEE-Tree -->\n"+data.output_cpee];
240
- if (prompt_type == 'adapt_endpoints') {
241
- let testset = $X(data.output_cpee);
242
- let model = $('> dslx > description',testset);
243
- let endpoints = $('> endpoints',testset);
244
- $.ajax({
245
- type: "PATCH",
246
- url: url + "/properties/endpoints/",
247
- contentType: 'text/xml',
248
- headers: {
249
- 'Content-ID': 'endpoints',
250
- 'CPEE-Event-Source': myid
251
- },
252
- data: endpoints.serializePrettyXML()
253
- });
254
-
255
- last_model_before_generation = save['dslx'];
256
- last_generated_model = model.serializePrettyXML();
257
- set_cpee_model(model.serializePrettyXML(),expositions);
258
- set_success(status,data.status);
259
- } else {
260
- if (gen == "dataflow") {
261
- querying_llm_ui(status,llms,'selects endpoints and calculates dataflow');
262
- call_llm_service_dataflow($X(data.output_cpee).serializePrettyXML(),myllm).done((data) => {
263
- let url = $('body').attr('current-instance');
264
- $.ajax({
265
- type: "PATCH",
266
- url: url + "/properties/endpoints/",
267
- contentType: 'text/xml',
268
- headers: {
269
- 'Content-ID': 'endpoints',
270
- 'CPEE-Event-Source': myid
271
- },
272
- data: data.endpoints
273
- });
555
+ ui.querying(llms,'analyses user intent');
556
+
557
+ let documents = save['documents'] ? save['documents'].save_object() : {};
558
+ let history_promise = (typeof($('body').attr('current-document-store')) != "undefined" && documents && ('chat_history' in documents))
559
+ ? do_parameters_get_document_exec('chat_history',10)
560
+ : $.Deferred().resolve([]).promise();
561
+
562
+ history_promise.then(function(history){
563
+ let messages = JSON.stringify(history);
564
+ call_llm_service_intent(input,myllm,llms,save['dslx'],messages,documents).done((piped) => {
565
+ console.log(piped);
566
+ if (piped !== null) {
567
+ ui.querying(llms,'creates model');
568
+ call_llm_service_model(save['dslx'],piped,myllm,prompt_type).done((data) => {
569
+ let expositions = ["<!-- Input CPEE-Tree -->\n"+data.input_cpee,"# User Input:\n"+data.user_input,"# Used LLM:\n"+data.used_llm,"%% Input Intermediate\n"+data.input_intermediate,"%% Output Intermediate\n"+data.output_intermediate,"<!-- Output CPEE-Tree -->\n"+data.output_cpee];
570
+ if (prompt_type == 'adapt_endpoints') {
571
+ let testset = $X(data.output_cpee); //{{{
572
+ let model = $('> dslx > description',testset);
573
+ let endpoints = $('> endpoints',testset);
574
+ $.ajax({
575
+ type: "PATCH",
576
+ url: url + "/properties/endpoints/",
577
+ contentType: 'text/xml',
578
+ headers: {
579
+ 'Content-ID': 'endpoints',
580
+ 'CPEE-Event-Source': myid
581
+ },
582
+ data: endpoints.serializePrettyXML()
583
+ });
274
584
 
275
- querying_llm_ui(status,llms,'validates dataflow');
276
- expositions.push("# Dataflow:\n"+data.dataflow);
277
- call_llm_service_validation($X(data.output_cpee).serializePrettyXML(),myllm).done((data) => {
278
- // for undo button
279
585
  last_model_before_generation = save['dslx'];
280
- last_generated_model = data.output_cpee;
281
- set_cpee_model($X(data.output_cpee).serializePrettyXML(),expositions);
282
- set_success(status,data.status);
283
- });
284
-
586
+ set_cpee_model(model.serializePrettyXML(),expositions);
587
+
588
+ ui.success(llms,diff_summary(last_model_before_generation,model)); //}}}
589
+ } else {
590
+ if (gen == "dataflow") {
591
+ ui.querying(llms,'selects endpoints and calculates dataflow'); //{{{
592
+ call_llm_service_dataflow($X(data.output_cpee).serializePrettyXML(),myllm).done((data) => {
593
+ let url = $('body').attr('current-instance');
594
+ $.ajax({
595
+ type: "PATCH",
596
+ url: url + "/properties/endpoints/",
597
+ contentType: 'text/xml',
598
+ headers: {
599
+ 'Content-ID': 'endpoints',
600
+ 'CPEE-Event-Source': myid
601
+ },
602
+ data: data.endpoints
603
+ });
604
+
605
+ ui.querying(llms,'validates dataflow');
606
+ expositions.push("# Dataflow:\n"+data.dataflow);
607
+ call_llm_service_validation($X(data.output_cpee).serializePrettyXML(),myllm).done((data) => {
608
+ // for undo button
609
+ last_model_before_generation = save['dslx'];
610
+ set_cpee_model($X(data.output_cpee).serializePrettyXML(),expositions);
611
+ ui.success(llms,diff_summary(last_model_before_generation,data.output_cpee));
612
+ })
613
+ .fail((xhr) => {
614
+ ui.error(llms,xhr_error(xhr));
615
+ });
616
+
617
+ })
618
+ .fail((xhr) => {
619
+ ui.error(llms,xhr_error(xhr));
620
+ }); //}}}
621
+ } else if (gen == "model") {
622
+ last_model_before_generation = save['dslx']; //{{{
623
+ set_cpee_model(data.output_cpee,expositions);
624
+ ui.success(llms,diff_summary(last_model_before_generation,data.output_cpee)); //}}}
625
+ } else {
626
+ ui.success(llms,"Successfully done nothing");
627
+ }
628
+ }
285
629
  })
286
630
  .fail((xhr) => {
287
- set_error(status,xhr.responseJSON.error);
631
+ ui.error(llms,xhr_error(xhr));
288
632
  });
289
- } else if (gen == "model") {
290
- last_model_before_generation = save['dslx'];
291
- last_generated_model = data.output_cpee;
292
- set_cpee_model(data.output_cpee,expositions);
293
- set_success(status,data.status);
294
- } else {
295
- set_success(status,"Successfully done nothing");
296
633
  }
297
- }
298
- })
299
- .fail((xhr) => {
300
- set_error(status,xhr.responseJSON.error);
634
+ }).fail((xhr) => {
635
+ ui.error(llms,xhr_error(xhr));
636
+ });
301
637
  });
302
638
  }
303
639
 
@@ -309,32 +645,37 @@ $(document).ready(async function() { //{{{
309
645
  let mode_active = await $.get('css/mode_active.svg', 'xml').then(function(data) { return $(data.documentElement); });
310
646
 
311
647
  $(document).on('keydown','#prompt',function(e){
312
- clean_llm_ui($('#status'));
648
+ ui.clean();
313
649
  if (e.key === "Enter" && (e.metaKey || e.ctrlKey)) {
314
- create($('#status'),$('#prompt'),$('#llms'),$('#generation'),$('#mode'));
650
+ create($('#prompt'),$('#llms'),$('#generation'),$('#mode'));
315
651
  }
316
652
  });
317
653
  $(document).on('click','#prompt_submit_button',function(e){
318
- create($('#status'),$('#prompt'),$('#llms'),$('#generation'),$('#mode'));
654
+ create($('#prompt'),$('#llms'),$('#generation'),$('#mode'));
319
655
  });
320
656
  $(document).on('click','#prompt_reset_button',function(e){
321
- clean_llm_ui($('#status'));
657
+ ui.clean();
322
658
  empty_model();
323
659
  });
324
660
  $(document).on('click','#generate_itext_button',function(e){
325
- clean_llm_ui($('#status'));
326
- querying_llm_ui($('#status'),$('#llms'),'thinks');
327
- call_llm_text_service($('#status'),'prompt','#llms','file');
661
+ ui.clean();
662
+ ui.querying($('#llms'),'thinks');
663
+ call_llm_text_service($('#prompt'),$('#llms'),'file');
328
664
  });
329
665
  $(document).on('click','#generate_text_button',function(e){
330
- clean_llm_ui($('#status'));
331
- querying_llm_ui($('#status'),$('#llms'),'thinks');
332
- call_llm_text_service($('#status'),$('#prompt'),$('#llms'),'show');
666
+ ui.clean();
667
+ ui.querying($('#llms'),'thinks');
668
+ call_llm_text_service($('#prompt'),$('#llms'),'show');
333
669
  });
334
670
  $(document).on('click','#prompt_undo_button',function(e){
335
- clean_llm_ui($('#status'));
336
- querying_llm_ui($('#status'),$('#llms'),'thinks');
337
- load_last_model_before_generation();
671
+ ui.clean();
672
+ ui.input($('#llms'),'Undo');
673
+ ui.querying($('#llms'),'thinks');
674
+ load_last_model_before_generation().done(() => {
675
+ ui.success($('#llms'),'Previous model restored.');
676
+ }).fail((xhr) => {
677
+ ui.error($('#llms'),xhr_error(xhr));
678
+ });
338
679
  });
339
680
  $(document).on('click','#prompt_attach_button',function(e){
340
681
  document.getElementById('loadtxt').click();
@@ -389,4 +730,8 @@ $(document).ready(async function() { //{{{
389
730
  e.stopPropagation();
390
731
  load_file_content(e.originalEvent.dataTransfer.files);
391
732
  });
733
+
734
+ document.addEventListener('documents:loaded', function (e) {
735
+ ui.init();
736
+ }, { capture: false, once: true } );
392
737
  }); //}}}