cpee-llm 1.0.6 → 1.1.0

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 (40) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +15 -0
  3. data/cpee-llm.gemspec +1 -1
  4. data/lib/cpee/llm/functions.rb +76 -73
  5. data/lib/cpee/llm/implementation.rb +39 -13
  6. data/lib/cpee/llm/implementation.xml +34 -1
  7. data/lib/cpee/llm/prompts/system/adapt_docxml_description.txt +50 -0
  8. data/lib/cpee/llm/prompts/{adapt_xml_endpoints.txt → system/adapt_xml_endpoints.txt} +1 -76
  9. data/lib/cpee/llm/prompts/system/cpee_xml.txt +99 -0
  10. data/lib/cpee/llm/prompts/system/cpee_xml_documentation_modelling.txt +35 -0
  11. data/lib/cpee/llm/prompts/system/intent.txt +45 -0
  12. data/lib/cpee/llm/prompts/user/cpee_repair.txt +5 -0
  13. data/lib/cpee/llm/prompts/user/dataflow.txt +9 -0
  14. data/lib/cpee/llm/prompts/user/intent.txt +17 -0
  15. data/lib/cpee/llm/prompts/user/process_description.txt +5 -0
  16. data/lib/cpee/llm/prompts/user/process_description_endpoints.txt +9 -0
  17. data/lib/cpee/llm/prompts/user/process_model_adapt.txt +8 -0
  18. data/lib/cpee/llm/prompts/user/process_model_adapt_api.txt +11 -0
  19. data/lib/cpee/llm/prompts/user/process_model_text.txt +4 -0
  20. data/lib/cpee/llm/prompts/user/repair.txt +5 -0
  21. data/lib/cpee/llm/rubyllm_requests.rb +64 -116
  22. data/server/connect_gemini +1 -1
  23. data/server/connect_gpt +1 -1
  24. data/server/connect_morpheus +1 -1
  25. data/server/cpee-llm +1 -1
  26. data/server/plugins.json +51 -0
  27. data/tools/cpee-llm-tool +1 -1
  28. metadata +27 -14
  29. data/lib/cpee/llm/prompts/adapt_docxml_description.txt +0 -131
  30. /data/lib/cpee/llm/prompts/{apply.txt → system/apply.txt} +0 -0
  31. /data/lib/cpee/llm/prompts/{dataflow.txt → system/dataflow.txt} +0 -0
  32. /data/lib/cpee/llm/prompts/{derive.txt → system/derive.txt} +0 -0
  33. /data/lib/cpee/llm/prompts/{describe.txt → system/describe.txt} +0 -0
  34. /data/lib/cpee/llm/prompts/{gemini-request.json → system/gemini-request.json} +0 -0
  35. /data/lib/cpee/llm/prompts/{generate1.txt → system/generate1.txt} +0 -0
  36. /data/lib/cpee/llm/prompts/{generate_enpoints.txt → system/generate_enpoints.txt} +0 -0
  37. /data/lib/cpee/llm/prompts/{generate_enpoints1.txt → system/generate_enpoints1.txt} +0 -0
  38. /data/lib/cpee/llm/prompts/{identify.txt → system/identify.txt} +0 -0
  39. /data/lib/cpee/llm/prompts/{validate_mermaid.xml → system/validate_mermaid.xml} +0 -0
  40. /data/lib/cpee/llm/prompts/{validate_xml.txt → system/validate_xml.txt} +0 -0
@@ -0,0 +1,99 @@
1
+ # CPEE XML Process Model Structure
2
+ The process model itself is contained entirely inside the <description color=""> element. Interpret the XML inside <description> using the following mapping.
3
+ The color attribute controls the color of the whole process model. Individual service task colors can be set (see below). For the color attribute the same color palette as described in the section Service Task applies.
4
+
5
+ ## Sequential Flow
6
+ Sequential execution is represented by sibling XML elements appearing in order inside the same parent element.
7
+
8
+ ## Service Task
9
+ A BPMN Service Task is represented by a `<call id="..." endpoint="...">` element.
10
+ The endpoint of the service is stored in the **endpoint attribute**.
11
+ <call endpoint="measurelightingconditions">
12
+ The following child elements may appear inside `<call>`:
13
+ ├── parameters
14
+ │ ├── label
15
+ │ ├── color
16
+ │ ├── method
17
+ │ └── arguments
18
+ ├── code
19
+ │ ├── signal
20
+ │ ├── prepare
21
+ │ ├── finalize
22
+ │ ├── update
23
+ │ └── rescue
24
+ ├── annotations
25
+ └── documentation
26
+
27
+ The parameters element stores task metadata, such as its label and display color. The <label> is the task name. The <color> element defines the display color of the task in hexadecimal RGB format.
28
+ Use only the following color palette:
29
+ * White — #ffffff
30
+ * Blue — #d4e1f1
31
+ * Green — #d8f0dd
32
+ * Yellow — #ffffcc
33
+ * Purple — #e4c3e4
34
+ * Pink — #f8a8c6
35
+ * Brown — #ded0c5
36
+ * Gray — #deddda
37
+
38
+ The <method> field must strictly follow the Service Registry specification.
39
+ If the service specification defines a method, use exactly that value. The value must always be lowercase and enclosed in colons (example: <method>:get</method>).
40
+ Never invent, infer, or assume a method value that is not explicitly defined in the service specification:
41
+ <method/>
42
+
43
+ Service input parameters are stored inside arguments. Each argument is represented by its own child element.
44
+ <arguments>
45
+ <min>1</min>
46
+ <max>100</max>
47
+ </arguments>
48
+ If an argument depends on a previously computed or returned value, it must be provided using the !data.some_value syntax.
49
+ <arguments>
50
+ <step>!data.current_step</step>
51
+ </arguments>
52
+
53
+ Returned service values are processed inside finalize: <finalize output="result">, where result is the variable containing the service response. Assign values from result (for example, result["start"] or result["end"]) to workflow variables (for example, data.start or data.end) to store them for later use in the process.
54
+ <finalize output="result"> data.temperature = result["temperature"].to_f; data.type = result["celsius"];</finalize>
55
+
56
+ ## Script TaskA BPMN Script Task is represented by <manipulate id="..." label="..." color="...">. The executable Ruby code is stored inside the <code> child element:
57
+ <manipulate><code id="a1">data.counter += 1</code></manipulate>
58
+ The label of the BPMN Script Task is stored in an attribute label in the <manipulate>.
59
+ The color of the BPMN Script Task is stored in an attribute color in the <manipulate>. Use the same color palette as for Service Tasks.
60
+
61
+ ## Exclusive Gateway
62
+ An Exclusive Gateway is represented by <choose eid="..." mode="exclusive">
63
+ Each outgoing branch is represented by <alternative condition="..." eid="e.."> child.
64
+ The branch condition is stored in the **condition attribute**.
65
+ <alternative condition="data.temperature > 30" eid="e1">
66
+ Conditions must be valid Ruby expressions.
67
+ Default branch has no conditions. <otherwise eid="..."/>.
68
+
69
+ ## Inclusive Gateway
70
+ The only differ from Inclusive Gateway by the attribute mode="inclusive".
71
+
72
+ ## Loop
73
+ A BPMN loop is represented by <loop eid="e.." mode="..." condition="...">
74
+ The loop condition is stored in the **condition attribute**. The loop execution mode is stored in the **mode attribute**.
75
+ pre_test is used for head controlled loops.
76
+ post_test is used for tail controlled loops.
77
+ <loop eid="e1" mode="pre_test" condition="data.counter < 10">
78
+ Loop conditions must be valid Ruby expressions.
79
+
80
+ ## Parallel Gateway
81
+ Parallel execution is represented by <parallel eid="e.." wait="-1" cancel="last">
82
+ The attribute wait defines how many branches have to reach the cancel condition before other branches are considered invalid. A normal parallel has always wait="-1".
83
+ The attribute cancel defines the cancel condition, i.e., if the wait rules are evaluated after a branch fully finishes (attribute cancel has the value "last"), or if the wait rules are evaluated after the first task of a branch finishes ((attribute cancel has the value "first").
84
+ An event-based gateway (which is a special case of a parallel) has always wait="1" cancel="last".
85
+ Each concurrent branch is represented by <parallel_branch eid="e..">
86
+
87
+ ##Pause Task
88
+ A pause is represented by a <stop id="a.."> element.
89
+ A <stop> pauses the execution of the process (until it is manually resumed). It does not terminate the process.
90
+ <stop id="a5"/>
91
+ When the user requests to pause, hold, or stop the process, insert a <stop> element.
92
+ The id attribute must be unique within the process model. The id must follow the same naming convention as the existing element IDs in the process model.
93
+ Insert the <stop> element at the location specified or implied by the user's request. Otherwise, insert the <stop> element as the last element of the process.
94
+
95
+ ## Variables
96
+ Variables are referenced as: data.variable_name
97
+ Service outputs are returned as strings unless otherwise specified.
98
+ Whenever a value represents a numeric type (integer or floating-point), convert it to a numeric value before assigning it to a workflow variable by using Ruby's .to_f method:
99
+ data.temperature = result["temperature"].to_f
@@ -0,0 +1,35 @@
1
+ ## Documentation
2
+
3
+ The child documentation may appear inside `<call>` (on the same level as parameters), and can have the following structure:
4
+ ├── ...
5
+ └── documentation
6
+ ├── implementation
7
+ │ └── description
8
+ ├── in
9
+ │ └── description
10
+ └── out
11
+ └── description
12
+
13
+ The documentation element may describe the service implementation as well as its expected inputs and produced outputs.
14
+ The <description> elements contain optional textual information about the task's behavior, including the process variables consumed (<in>), produced (<out>), or implementation-specific details (<implementation>).
15
+ Empty <description> elements indicate that no additional semantic information is provided.
16
+
17
+ If a `<documentation>` element does not exist for a Service Task, append an empty `<documentation>` element. Empty `<documentation>` conmtains only <in> and <implementation>. Include <out> only in tasks, where output is defined.
18
+
19
+ #Outputs:
20
+ Every new output created by the Service Task must be added to the <out><description> element.
21
+ Output variables must use the workflow variable format:
22
+ data.variable_name = "name of document or document content"
23
+ If the output represents a document, specify whether the variable stores the document name or the document content.
24
+ data.invoice_name = "invoice.pdf" or data.invoice_content = "content of the invoice document"
25
+ Each newly created output must introduce a new data. variable.
26
+
27
+ #Inputs:
28
+ Inputs describe the workflow variables consumed by the Service Task.
29
+ An input can either:
30
+ Use an existing output variable from a previous Service Task, or Introduce a new workflow variable.
31
+ If the input is based on an existing output, use the same data. variable name defined in the output:
32
+ data.invoice_content
33
+ If the input is new and has no previous output source, define a new variable:
34
+ data.customer_information = "content of the invoice"
35
+ Do not create a new variable name when an existing output already contains the required data. Reuse the existing data. variable.
@@ -0,0 +1,45 @@
1
+ Normally the input of a user is used to create or edit a process model.
2
+ Typically this entails adding, deleting or moving tasks, setting parameters for
3
+ tasks, or creating a model for a certain domain or topic.
4
+
5
+ Additionally the input, or parts of the input can be passed to a plugin.
6
+ Plugins are defined as json, e.g.:
7
+
8
+ { "id": 1, "priority": 2, "url": "https://cpee.org/llm/plugins/aaa", "description": "Description what the plugin does", ... }
9
+
10
+ If one of the plugins is matchin (according to its description), return its id
11
+ as json { 'id': 12345}. \ If multiple plugins match, choose the one with the
12
+ lowest priority. If one the plugins is only partially suitable, remove that
13
+ part of the text that the plugin requires as input, and replace it with %%%.
14
+ Write the text into a key "input". Replacing the whole input with %%% is fine.
15
+ Replacing a part is also fine, depending on the user input.
16
+
17
+ For example with the plugin:
18
+
19
+ { "id": 1, "url": "https://cpee.org/llm/plugins/aaa", "description": "Extracts a color value from a color name." }
20
+
21
+ And the user input:
22
+
23
+ "Change the process model to occarina blue."
24
+
25
+ Return the following:
26
+
27
+ { "id": 1, "input": "Change the process model to %%%." }
28
+
29
+ If the description tells that it returns multiple names values, and enumerates
30
+ them, output should look like this:
31
+
32
+ { "id": 12345, "input": "create a process model with %%%tasks %%%endpoints" }
33
+
34
+ A plugin's description may refer to a general category of thing (a document, a
35
+ color, a value, ...) rather than one specific named instance. A vague or
36
+ generic reference to that category in the user input (e.g. "the document",
37
+ "that file", "some color") still counts as a match for the plugin - the user
38
+ does not have to name the specific instance.
39
+
40
+ If the input contains several clauses, evaluate each clause against every
41
+ plugin's description separately, don't just judge the input as a whole. One
42
+ clause can match a plugin while the rest of the input is unrelated process
43
+ model editing; use the %%% substitution rule above for that clause and leave
44
+ the rest of the text as is. Only return "{}" once no plugin's description
45
+ matches any clause in the input.
@@ -0,0 +1,5 @@
1
+ Consider following CPEE XML promcess model created by autobpmn.ai:
2
+
3
+ %%%cpee_model
4
+
5
+ Repair the model so that it becomes executable. Return only the repaired XML without any comments or markdown formatting.
@@ -0,0 +1,9 @@
1
+ Given the process model:
2
+
3
+ %%%mermaid_model
4
+
5
+ ... and given a task specification with endpoint data:
6
+
7
+ %%%api_specification
8
+
9
+ Define the execution context and return a JSON specification.
@@ -0,0 +1,17 @@
1
+ Consider the following user input:
2
+
3
+ %%%user_input
4
+
5
+ Consider the follwing list of plugins
6
+
7
+ %%%plugins
8
+
9
+ If appropriate, select a plugin, and return its id as json, e.g., { 'id': 123 }.
10
+ If a plugin is appropriate for a part of the text, replace the text with %%% and return it as part of the json, e.g., { "id": 123, "text": "Some text. %%%. Some more text." }.
11
+ If nothing seems suitable return "null". This includes cases where the user input
12
+ does not convey any intent about creating, adding to, or modifying a process
13
+ model at all, e.g. "what is the weather today", "2+2", or "12".
14
+ If it seems like the text is just for creating or modifying a process model
15
+ return "{}". This includes creating, updating, or modifying a task, event, or
16
+ gateway, changing the documentation of a task, or adding or changing
17
+ information in any field of a task, e.g. "make task a2 pink".
@@ -0,0 +1,5 @@
1
+ Consider following process description:
2
+
3
+ %%%user_input
4
+
5
+ Generate a BPMN model in Mermaid.js format.
@@ -0,0 +1,9 @@
1
+ Consider the following process description:
2
+
3
+ %%%user_input
4
+
5
+ ... and consider the the provided endpoint list:
6
+
7
+ %%%endpoints
8
+
9
+ Interpret the process description as business intent and generate an executable BPMN model in Mermaid.js format using only the available endpoint capabilities.
@@ -0,0 +1,8 @@
1
+ Consider following process model:
2
+
3
+ %%%process_model
4
+
5
+ Update this process model according to provided changes:
6
+
7
+ %%%user_input
8
+
@@ -0,0 +1,11 @@
1
+ Consider following process model:
2
+
3
+ %%%process_model
4
+
5
+ ... and given a task specification with endpoint data:
6
+
7
+ %%%api_specification
8
+
9
+ Update this process model according to provided changes:
10
+
11
+ %%%user_input
@@ -0,0 +1,4 @@
1
+ Consider following process process model:
2
+ %%%user_input
3
+
4
+ Generate a text describing provided process description.
@@ -0,0 +1,5 @@
1
+ Consider following CPEE XML promcess model created by autobpmn.ai:
2
+
3
+ %%%cpee_model
4
+
5
+ Repair the model so that it becomes executable. Return only the repaired XML without any comments or markdown formatting.
@@ -17,13 +17,15 @@
17
17
  require 'ruby_llm'
18
18
  require 'typhoeus'
19
19
  require 'json'
20
+ require 'mime/types'
21
+ require 'securerandom'
20
22
 
21
23
  module CPEE
22
24
 
23
25
  module LLM
24
26
 
25
- # own llm error class
26
- class LLMError < StandardError #{{{
27
+ # custom llm error class #{{{
28
+ class LLMError < StandardError
27
29
  attr_reader :http_response
28
30
  def initialize(message = "Something went wrong", http_response = 500)
29
31
  @http_response = http_response
@@ -35,141 +37,87 @@ module CPEE
35
37
 
36
38
  def connect_llm(myllm,llms) #{{{
37
39
  chat = nil
38
- RubyLLM.configure do |config|
39
- config.request_timeout = llms[:request_timeout]
40
- config.max_retries = llms[:max_retries]
40
+ context = RubyLLM.context
41
+ config = context.config
42
+ config.request_timeout = llms[:request_timeout]
43
+ config.max_retries = llms[:max_retries]
44
+
45
+ llms[:connectors].each do |k,v|
46
+ if myllm =~ /#{k}/ && chat.nil?
47
+ chat = eval(v)
48
+ end
49
+ end
50
+
51
+ if chat.nil?
52
+ raise LLMError.new("Selected LLM model does not exist or is not supported. Please, select another LLM model.", 400)
53
+ end
54
+ return chat
55
+ end #}}}
41
56
 
42
- llms[:connectors].each do |k,v|
43
- if myllm =~ /#{k}/ && chat.nil?
44
- chat = eval(v)
45
- end
57
+ def build_system_prompt(name) #{{{
58
+ sp = File.read(File.join(__dir__,"prompts","system",name))
59
+ sp.gsub!(/(^|\n)[\t ]*%%%([^\n]+)(\n|$)/) do |e|
60
+ b = $1
61
+ m = $2
62
+ a = $3
63
+ if File.exist? File.join(__dir__,"prompts","system",m)
64
+ "#{a}#{File.read(File.join(__dir__,"prompts","system",m))}#{b}"
65
+ else
66
+ "#{a}#{b}"
46
67
  end
68
+ end
69
+ sp
70
+ end #}}}
47
71
 
48
- if chat.nil?
49
- raise LLMError.new("Selected LLM model does not exist or is not supported. Please, select another LLM model.", 400)
72
+ def build_user_prompt(name,opts) #{{{
73
+ sp = File.read(File.join(__dir__,"prompts","user",name))
74
+ sp.gsub!(/(^|\n)[\t ]*%%%([^\n]+)(\n|$)/) do |e|
75
+ b = $1
76
+ m = $2.to_sym
77
+ a = $3
78
+ if opts[m]
79
+ "#{a}#{opts[m]}#{b}"
80
+ else
81
+ "#{a}#{b}"
50
82
  end
51
83
  end
52
- return chat
84
+ sp
53
85
  end #}}}
54
86
 
55
- def generate_content(myllm, system_prompt, user_prompt, max_tokens, temperature, llms) #{{{
87
+ def generate_content(myllm, system_prompt, user_prompt, max_tokens, temperature, llms, opts={}, documents=[]) #{{{
88
+ temperature = temperature.nil? ? 0.1 : temperature.to_f
56
89
  chat = connect_llm(myllm,llms)
57
90
  chat.with_instructions system_prompt
58
91
  chat.with_temperature(temperature)
59
92
  if max_tokens != 0
60
93
  if myllm.include?("gemini")
61
- chat.with_params(generationConfig:{maxOutputTokens: max_tokens})
94
+ opts[:generationConfig] = { maxOutputTokens: max_tokens }
95
+ opts[:generationConfig].merge!(response_mime_type: 'application/json') if opts[:json]
62
96
  elsif myllm.include?("gpt")
63
- chat.with_params(max_completion_tokens: max_tokens)
97
+ opts[:max_completion_tokens] = max_tokens
98
+ opts[:response_format] = { type: "json_object" } if opts[:json]
64
99
  else
65
- chat.with_params(max_tokens: max_tokens)
100
+ opts[:max_tokens] = max_tokens
66
101
  end
67
102
  end
68
- response = chat.ask user_prompt
69
- return response.content
70
- rescue Faraday::TimeoutError => e
71
- raise LLMError.new(e.message, 504)
72
- rescue Exception => e
73
- raise LLMError.new(e.message, 500)
74
- end #}}}
75
-
76
- def generate_json_content(myllm,system_prompt,user_prompt,max_tokens,temperature,llms) #{{{
77
- chat = connect_llm(myllm,llms)
78
-
79
- #set parameters
80
- chat.with_params(max_tokens: max_tokens,response_format:{type:'json_object'})
81
- chat.with_instructions system_prompt
82
- chat.with_temperature(temperature)
83
- response = chat.ask user_prompt
84
- #puts JSON.parse(response.content)
103
+ opts.delete(:json)
104
+ chat.with_params **opts
105
+ message = RubyLLM::Content.new(user_prompt)
106
+ documents.each do |doc|
107
+ filename = doc.filename
108
+ if (filename.nil? || filename.empty?) && !doc.mimetype.to_s.empty?
109
+ extension = MIME::Types[doc.mimetype].first&.extensions&.first
110
+ filename = SecureRandom.hex(8)
111
+ filename += ".#{extension}" if extension
112
+ end
113
+ message.add_attachment(doc.value, filename:)
114
+ end
115
+ response = chat.ask message
85
116
  return response.content
86
117
  rescue Faraday::TimeoutError => e
87
118
  raise LLMError.new(e.message, 504)
88
119
  rescue Exception => e
89
120
  raise LLMError.new(e.message, 500)
90
- end #}}}
91
-
92
- def generate_mermaid_model(llm, user_input, temperature, llms={}) #{{{
93
- max_tokens = 4000
94
- temperature = temperature.nil? ? 0.1 : temperature.to_f
95
- system_prompt = File.read(File.join(__dir__,"prompts/generate1.txt"))
96
- user_prompt = "Consider following process description: #{user_input}. Generate a BPMN model in Mermaid.js format."
97
- new_mermaid = generate_content(llm,system_prompt,user_prompt,max_tokens,temperature,llms)
98
- return new_mermaid
99
- end #}}}
100
-
101
- def adapt_mermaid_model(llm, user_input, process_model, llms={}) #{{{
102
- max_tokens = 4000
103
- temperature = 0
104
- system_prompt = File.read(File.join(__dir__,"prompts/apply.txt"))
105
- user_prompt = "Consider following process model: #{process_model}. Update this process model according to provided changes #{user_input}."
106
- new_mermaid = generate_content(llm,system_prompt,user_prompt,max_tokens,temperature,llms)
107
- return new_mermaid
108
- end #}}}
109
-
110
- def adapt_docxml_description(llm, user_input, process_model, llms={}) #{{{
111
- max_tokens = 20000
112
- temperature = 0
113
- system_prompt = File.read(File.join(__dir__,"prompts/adapt_docxml_description.txt"))
114
- user_prompt = "Consider following process model: #{process_model}. Update this process model according to provided changes #{user_input}."
115
- new_cpee = generate_content(llm,system_prompt,user_prompt,max_tokens,temperature,llms)
116
- return new_cpee
117
- end #}}}
118
-
119
- def adapt_xml_model(llm, user_input, process_model, api_specification, llms={}) #{{{
120
- max_tokens = 20000
121
- temperature = 0
122
- system_prompt = File.read(File.join(__dir__,"prompts/adapt_xml_endpoints.txt"))
123
- user_prompt = "Consider following process model: #{process_model.to_s} and task specification #{api_specification} with endpoint data. Update this process model according to provided changes #{user_input}."
124
- new_cpee = generate_content(llm,system_prompt,user_prompt,max_tokens,temperature,llms)
125
- return new_cpee
126
- end #}}}
127
-
128
- def generate_plain_text(llm, user_input, llms={}) #{{{
129
- max_tokens = 4000
130
- temperature = 0
131
- system_prompt = File.read(File.join(__dir__,"prompts/describe.txt"))
132
- user_prompt = "Consider following process process model: #{user_input}. Generate a text describing provided process description."
133
- process_description = generate_content(llm,system_prompt,user_prompt,max_tokens,temperature,llms)
134
- return process_description
135
- end #}}}
136
-
137
- def generate_generic_content(llm, user_input, system_prompt, json, temperature, llms={}) #{{{
138
- max_tokens = 20000
139
- temperature = temperature.nil? ? 0 : temperature.to_f
140
- if json == 'true'
141
- process_description = generate_json_content(llm,system_prompt,user_input,max_tokens,temperature,llms)
142
- else
143
- process_description = generate_content(llm,system_prompt,user_input,max_tokens,temperature,llms)
144
- end
145
- return process_description
146
- end #}}}
147
-
148
- def generate_dataflow_content(llm, mermaid_model, api_specification, llms={}) #{{{
149
- max_tokens = 10000
150
- temperature = 0.1
151
- system_prompt = File.read(File.join(__dir__,"prompts/dataflow.txt"))
152
- user_prompt = "Given process mode #{mermaid_model} and task specification #{api_specification} with endpoint data, define the execution context and return a JSON specification."
153
- dataflow = generate_content(llm,system_prompt,user_prompt,max_tokens,temperature,llms)
154
- return dataflow
155
- end #}}}
156
-
157
- def generate_endpoint_mermaid_model(llm, user_input, endpoints, llms={}) #{{{
158
- max_tokens = 4000
159
- temperature = 0.1
160
- system_prompt = File.read(File.join(__dir__,"prompts/generate_enpoints.txt"))
161
- user_prompt = "Consider the following process description: #{user_input} and the provided endpoint list: #{endpoints}. Interpret the process description as business intent and generate an executable BPMN model in Mermaid.js format using only the available endpoint capabilities."
162
- new_mermaid = generate_content(llm,system_prompt,user_prompt,max_tokens,temperature,llms)
163
- return new_mermaid
164
- end #}}}
165
-
166
- def validate_xml_model(llm, cpee_model, llms={}) #{{{
167
- max_tokens = 0
168
- temperature = 0.1
169
- system_prompt = File.read(File.join(__dir__,"prompts/validate_xml.txt"))
170
- user_prompt = "Consider following CPEE XML promcess model created by autobpmn.ai: #{cpee_model}. Repair the model so that it becomes executable. Return only the repaired XML without any comments or markdown formatting."
171
- repaired_cpee = generate_content(llm,system_prompt,user_prompt,max_tokens,temperature,llms)
172
- return repaired_cpee
173
121
  end #}}}
174
122
 
175
123
  end
@@ -1,3 +1,3 @@
1
1
  config.gemini_api_key = 'insert your key here'
2
2
 
3
- RubyLLM.chat(model: myllm)
3
+ context.chat(model: myllm)
data/server/connect_gpt CHANGED
@@ -1,4 +1,4 @@
1
1
  config.openai_api_key = 'insert your key here'
2
2
  config.openai_use_system_role = true
3
3
 
4
- RubyLLM.chat(model: myllm,provider: :openai,assume_model_exists: true)
4
+ context.chat(model: myllm,provider: :openai,assume_model_exists: true)
@@ -2,4 +2,4 @@ config.openai_api_key = 'insert your key here'
2
2
  config.openai_api_base = "https://morpheus.cit.tum.de/api/v1"
3
3
  config.openai_use_system_role = true
4
4
 
5
- RubyLLM.chat(model: myllm,provider: :openai,assume_model_exists: true)
5
+ context.chat(model: myllm,provider: :openai,assume_model_exists: true)
data/server/cpee-llm CHANGED
@@ -26,7 +26,7 @@ end
26
26
 
27
27
  options = {
28
28
  :host => 'localhost',
29
- :port => 9297,
29
+ :port => 9305,
30
30
  :secure => false,
31
31
  :llms => {}
32
32
  }
@@ -0,0 +1,51 @@
1
+ [
2
+ {
3
+ "id": 1,
4
+ "priority": 1,
5
+ "url": "https://echo.bpm.in.tum.de/services/llm/dnames/",
6
+ "description": "Use ONLY when the user wants to know whether a document exists or where it is, and plans no further operation on it (e.g. 'does the spec document exist', 'where is the process document'). A vague or generic reference (e.g. 'the process document', 'that file') still counts as a document reference, it does not need to be a specific file name. Looks up the document, extracts its url, and outputs the result directly to chat. If the input hints at any further operation on the document (analyse, extract, look at, summarize, use it to build or modify a process model, ...), do NOT use this plugin - use plugin id 2 instead.",
7
+ "required_input": [
8
+ "documents"
9
+ ],
10
+ "output": "chat"
11
+ },
12
+ {
13
+ "id": 2,
14
+ "priority": 1,
15
+ "url": "https://echo.bpm.in.tum.de/services/llm/dnames/",
16
+ "description": "Use when the user wants to look up a document AND then do something further with it (analyse it, extract from it, use it to create or modify a process model, ...), e.g. 'analyse the process document and create a process from it'. A vague or generic reference (e.g. 'the process document', 'that file') still counts as a document reference, it does not need to be a specific file name. Looks up the document, extracts its url, and inserts the result back into the text so a subsequent plugin selection pass can pick up from there. If the input hints at NO further operation on the document, do NOT use this plugin - use plugin id 1 instead.",
17
+ "required_input": [
18
+ "documents"
19
+ ],
20
+ "output": "reintent"
21
+ },
22
+ {
23
+ "id": 3,
24
+ "priority": 2,
25
+ "url": "https://echo.bpm.in.tum.de/services/llm/documents/",
26
+ "description": "Use ONLY when a document url is already given in the input (not a symbolic/vague document name - if only a name is given, use plugin id 2 to resolve it to a url first) AND the user just wants the document's content described or extracted, with no explicit intention to use the result to build or change the process model. Analyses, extracts from, or otherwise works on the document at the given url and outputs the textual result to chat. If the input explicitly signifies that the result should feed into creating or modifying the process model (e.g. 'and create a process from it', 'and modify the model with the result', 'add it to the model'), do NOT use this plugin - use plugin id 4 instead.",
27
+ "required_input": [],
28
+ "output_template": "%%%",
29
+ "output": "chat"
30
+ },
31
+ {
32
+ "id": 4,
33
+ "priority": 2,
34
+ "url": "https://echo.bpm.in.tum.de/services/llm/documents/",
35
+ "description": "Use when a document url is already given in the input (not a symbolic/vague document name - if only a name is given, use plugin id 2 to resolve it to a url first) AND the input explicitly signifies that the result should feed into creating or modifying the process model, e.g. 'and create a process from it', 'and build a model from it', 'and modify the models with the result', or 'add it to the model'. Analyses, extracts from, or otherwise works on the document at the given url and feeds the textual result back into the pipeline so it is used to create or modify the process model. If the input has no such explicit intention to affect the model, do NOT use this plugin - use plugin id 3 instead.",
36
+ "required_input": [],
37
+ "output_template": "%%%",
38
+ "output": "pipe"
39
+ },
40
+ {
41
+ "id": 5,
42
+ "priority": 2,
43
+ "url": "https://echo.bpm.in.tum.de/services/llm/stats/",
44
+ "description": "Answer a questions about the process model. This should relate to tasks, gateways or events, or any information contained in them. It can also relate to quantitative properties of the process, e.g. 'how many tasks'.",
45
+ "required_input": [
46
+ "model"
47
+ ],
48
+ "output_template": "%%%",
49
+ "output": "chat"
50
+ }
51
+ ]
data/tools/cpee-llm-tool CHANGED
@@ -27,7 +27,7 @@ require 'typhoeus'
27
27
  # ./cpee-llm-tool.rb adapt 'Add task A after dismissal review.' 'geminin-2.0-flash' 1501
28
28
 
29
29
 
30
- srv = Riddl::Client.new('http://localhost:9297/')
30
+ srv = Riddl::Client.new('http://localhost:9305/')
31
31
  status, res = srv.post [
32
32
  Riddl::Parameter::Complex.new("rpst_xml","text/xml",ARGV[0] == 'adapt' ? Typhoeus.get("https://cpee.org/flow/engine/#{ARGV[2]}/properties/dslx/").response_body() : File.read('cpee_empty_example')),
33
33
  Riddl::Parameter::Complex.new("user_input","text/plain",ARGV[1]),
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cpee-llm
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.6
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nataliia Klievtsova
@@ -126,25 +126,38 @@ files:
126
126
  - lib/cpee/llm/functions.rb
127
127
  - lib/cpee/llm/implementation.rb
128
128
  - lib/cpee/llm/implementation.xml
129
- - lib/cpee/llm/prompts/adapt_docxml_description.txt
130
- - lib/cpee/llm/prompts/adapt_xml_endpoints.txt
131
- - lib/cpee/llm/prompts/apply.txt
132
- - lib/cpee/llm/prompts/dataflow.txt
133
- - lib/cpee/llm/prompts/derive.txt
134
- - lib/cpee/llm/prompts/describe.txt
135
- - lib/cpee/llm/prompts/gemini-request.json
136
- - lib/cpee/llm/prompts/generate1.txt
137
- - lib/cpee/llm/prompts/generate_enpoints.txt
138
- - lib/cpee/llm/prompts/generate_enpoints1.txt
139
- - lib/cpee/llm/prompts/identify.txt
140
- - lib/cpee/llm/prompts/validate_mermaid.xml
141
- - lib/cpee/llm/prompts/validate_xml.txt
129
+ - lib/cpee/llm/prompts/system/adapt_docxml_description.txt
130
+ - lib/cpee/llm/prompts/system/adapt_xml_endpoints.txt
131
+ - lib/cpee/llm/prompts/system/apply.txt
132
+ - lib/cpee/llm/prompts/system/cpee_xml.txt
133
+ - lib/cpee/llm/prompts/system/cpee_xml_documentation_modelling.txt
134
+ - lib/cpee/llm/prompts/system/dataflow.txt
135
+ - lib/cpee/llm/prompts/system/derive.txt
136
+ - lib/cpee/llm/prompts/system/describe.txt
137
+ - lib/cpee/llm/prompts/system/gemini-request.json
138
+ - lib/cpee/llm/prompts/system/generate1.txt
139
+ - lib/cpee/llm/prompts/system/generate_enpoints.txt
140
+ - lib/cpee/llm/prompts/system/generate_enpoints1.txt
141
+ - lib/cpee/llm/prompts/system/identify.txt
142
+ - lib/cpee/llm/prompts/system/intent.txt
143
+ - lib/cpee/llm/prompts/system/validate_mermaid.xml
144
+ - lib/cpee/llm/prompts/system/validate_xml.txt
145
+ - lib/cpee/llm/prompts/user/cpee_repair.txt
146
+ - lib/cpee/llm/prompts/user/dataflow.txt
147
+ - lib/cpee/llm/prompts/user/intent.txt
148
+ - lib/cpee/llm/prompts/user/process_description.txt
149
+ - lib/cpee/llm/prompts/user/process_description_endpoints.txt
150
+ - lib/cpee/llm/prompts/user/process_model_adapt.txt
151
+ - lib/cpee/llm/prompts/user/process_model_adapt_api.txt
152
+ - lib/cpee/llm/prompts/user/process_model_text.txt
153
+ - lib/cpee/llm/prompts/user/repair.txt
142
154
  - lib/cpee/llm/rubyllm_requests.rb
143
155
  - server/connect_gemini
144
156
  - server/connect_gpt
145
157
  - server/connect_morpheus
146
158
  - server/cpee-llm
147
159
  - server/cpee-llm.conf
160
+ - server/plugins.json
148
161
  - tools/cpee-llm
149
162
  - tools/cpee-llm-tool
150
163
  homepage: http://github.com/etm/cpee-llm/