extended rag table schemata

This commit is contained in:
Ralph Soika 2025-06-14 17:39:33 +02:00
parent 41181227c6
commit 5f0a528b90
6 changed files with 484 additions and 182 deletions

View file

@ -1,20 +0,0 @@
# Dynamixs AI - Retrieval-Augmented-Generation (RAG)
Retrieval Augmented Generation (RAG) is a term from the field of artificial intelligence and machine learning.
- **Retrieval** - refers to the ability to quickly and efficiently access stored information or retrieve it from a database or other storage system.
- **Augmented** - refers to the idea of improving or expanding an existing function or capability by adding something new.
- **Generation** - refers to the creation of new content or results based on available information.
In summary, Retrieval Augmented Generation (RAG) describes a method that uses artificial intelligence or machine learning to quickly and efficiently access stored information and use it to generate new content or results. This method can help improve the accuracy and relevance of generated content by drawing on a broader range of information.
The following section give a general overview how the Retrieval-augmented generation (RAG) is realized in Dynamixs AI.
## The Model
The retrieval data in Dynamixs.AI is generated by the LLM [nomic-embed-text-v2-moe](https://huggingface.co/nomic-ai/nomic-embed-text-v2-moe-GGUF) which is
a [sentence-transformers model](https://www.sbert.net/) supporting more then 100 languages and trained on over 1.6B pairs.
The model is used in Q4 quantitation and a size of 328MiB which provides a good quality for most use cases.
The model maps sentences & paragraphs to a 768 dimensional dense vector space. It can be run on a CPU with adequate performance.
## BPMN

74
doc/RAG_SERVICE.md Normal file
View file

@ -0,0 +1,74 @@
# The RAG ClusterService EJB
With the EJB `ClusterService` clients can index and retrieve embeddings.
## Index
A text chunk can be index by:
```java
clusterService.insertVector(workitem.getUniqueID(),
workitem.getModelVersion(),
workitem.getTaskID(),
chunk,
indexResult);
```
## Retrieval
The retrieval can be based on text embedding only or refined by workflow metadata like the modelVersion or the TaskId
```java
List<RetrievalResult> retrievalResultList = clusterService.searchEmbeddings(embeddings, 5);
```
You can refine the retrieval by providing additional workflow context
1. Task ID Range: Suche alle Tasks zwischen 1000-1999
```java
List<RetrievalResult> rangeResults = clusterService.searchEmbeddingsWithTaskRange(
queryEmbedding,
5,
null, // all Model Versions
1000,
1999
);
```
2. Wildcard Model Version: all products by wildcard search
```java
List<RetrievalResult> productResults = clusterService.searchEmbeddingsWithModelWildcard(
queryEmbedding,
5,
"product-de*", // product-de-1.0.0, product-de-2.0.0, etc.
null
);
```
3. Combination products and Task Range 1000-1999
```java
List<RetrievalResult> combinedResults = clusterService.searchEmbeddings(
queryEmbedding,
5,
Arrays.asList("product-de*"),
null, // no specific Task IDs
1000, // Task Range Start
1999 // Task Range End
);
```
4. Multiple Wildcards: all german models
```java
List<RetrievalResult> germanResults = clusterService.searchEmbeddings(
queryEmbedding,
5,
Arrays.asList("product-de*", "offer-de*", "invoice-de*"),
null, null, null
);
```

View file

@ -39,16 +39,16 @@ ID;Name; Description;stock;price;category;Lieferzeit;EAN
1170;Wandkonsole für Plattentauscher B3-12-xx;Wandhalterung für eine schnelle Montage mit praktischem Klettverschlußband.;1;18,9;Wandhalterung;;2837107354495 1170;Wandkonsole für Plattentauscher B3-12-xx;Wandhalterung für eine schnelle Montage mit praktischem Klettverschlußband.;1;18,9;Wandhalterung;;2837107354495
1181;LP-375VA 115kW mit Wärmedämmung;Hochwertiger Schwimmbad-Wärmetauscher aus Edelstahl für Schwimmbadbeheizung mit Wärmedämmung.;0;459;Pool Wärmetauscher > Rohrförmig aus Edelstahl;;8247903213713 1181;LP-375VA 115kW mit Wärmedämmung;Hochwertiger Schwimmbad-Wärmetauscher aus Edelstahl für Schwimmbadbeheizung mit Wärmedämmung.;0;459;Pool Wärmetauscher > Rohrförmig aus Edelstahl;;8247903213713
1188;Wandkonsole für isolierte Pooltauscher LP-xx;Wandhalterung für eine schnelle Montage mit praktischem Klettverschlußband.;1;19,9;Wandhalterung;;5234087663802 1188;Wandkonsole für isolierte Pooltauscher LP-xx;Wandhalterung für eine schnelle Montage mit praktischem Klettverschlußband.;1;19,9;Wandhalterung;;5234087663802
1191;LP-65VA 20kW mit Wärmedämmung;Hochwertiger Schwimmbad-Wärmetauscher aus Edelstahl für Schwimmbadbeheizung mit Wärmedämmung.;1;219,9;Pool Wärmetauscher > Rohrförmig aus Edelstahl;;938364240247 1191;LP-65VA 20kW mit Wärmedämmung;Hochwertiger Schwimmbad-Wärmetauscher aus Edelstahl für Schwimmbadbeheizung mit Wärmedämmung.;1;219,9;Pool Wärmetauscher > Rohrförmig aus Edelstahl;;938364240247
1194;LP-100VA 30kW mit Wärmedämmung;Hochwertiger Schwimmbad-Wärmetauscher aus Edelstahl für Schwimmbadbeheizung mit Wärmedämmung.;1;239,9;Pool Wärmetauscher > Rohrförmig aus Edelstahl;;450118214736 1194;LP-100VA 30kW mit Wärmedämmung;Hochwertiger Schwimmbad-Wärmetauscher aus Edelstahl für Schwimmbadbeheizung mit Wärmedämmung.;1;239,9;Pool Wärmetauscher > Rohrförmig aus Edelstahl;;450118214736
1196;LP-175VA 50kW mit Wärmedämmung;Hochwertiger Schwimmbad-Wärmetauscher aus Edelstahl für Schwimmbadbeheizung mit Wärmedämmung.;1;259,9;Pool Wärmetauscher > Rohrförmig aus Edelstahl;;655296358115 1196;LP-175VA 50kW mit Wärmedämmung;Hochwertiger Schwimmbad-Wärmetauscher aus Edelstahl für Schwimmbadbeheizung mit Wärmedämmung.;1;259,9;Pool Wärmetauscher > Rohrförmig aus Edelstahl;;655296358115
1198;LP-230VA 70kW mit Wärmedämmung;Hochwertiger Schwimmbad-Wärmetauscher aus Edelstahl für Schwimmbadbeheizung mit Wärmedämmung.;1;329,9;Pool Wärmetauscher > Rohrförmig aus Edelstahl;;8611986118980 1198;LP-230VA 70kW mit Wärmedämmung;Hochwertiger Schwimmbad-Wärmetauscher aus Edelstahl für Schwimmbadbeheizung mit Wärmedämmung.;1;329,9;Pool Wärmetauscher > Rohrförmig aus Edelstahl;;8611986118980
1200;LP-325VA 95kW mit Wärmedämmung;Hochwertiger Schwimmbad-Wärmetauscher aus Edelstahl für Schwimmbadbeheizung mit Wärmedämmung.;0;389,9;Pool Wärmetauscher > Rohrförmig aus Edelstahl;;9005775281402 1200;LP-325VA 95kW mit Wärmedämmung;Hochwertiger Schwimmbad-Wärmetauscher aus Edelstahl für Schwimmbadbeheizung mit Wärmedämmung.;0;389,9;Pool Wärmetauscher > Rohrförmig aus Edelstahl;;9005775281402
1204;Dämmschale für Plattentauscher M3-M;Hochwertige Dämmschale für Plattentauscher in verschiedenen Größen;1;89,9;Isolierung für Wärmetauscher;;5367012957872 1204;Dämmschale für Plattentauscher M3-M;Hochwertige Dämmschale für Plattentauscher in verschiedenen Größen;1;89,9;Isolierung für Wärmetauscher;;5367012957872
1205;Dämmschale für Plattentauscher M3-L;Hochwertige Dämmschale für Plattentauscher in verschiedenen Größen;1;99,9;Isolierung für Wärmetauscher;;6854117854742 1205;Dämmschale für Plattentauscher M3-L;Hochwertige Dämmschale für Plattentauscher in verschiedenen Größen;1;99,9;Isolierung für Wärmetauscher;;6854117854742
1206;Dämmschale für Plattentauscher SP-S;Hochwertige Dämmschale für Plattentauscher in verschiedenen Größen;1;79,9;Isolierung für Wärmetauscher;;1382809012286 1206;Dämmschale für Plattentauscher SP-S;Hochwertige Dämmschale für Plattentauscher in verschiedenen Größen;1;79,9;Isolierung für Wärmetauscher;;1382809012286
1207;Dämmschale für Plattentauscher SP-M;Hochwertige Dämmschale für Plattentauscher in verschiedenen Größen;1;89,9;Isolierung für Wärmetauscher;;5461960384619 1207;Dämmschale für Plattentauscher SP-M;Hochwertige Dämmschale für Plattentauscher in verschiedenen Größen;1;89,9;Isolierung für Wärmetauscher;;5461960384619
1252;Dämmschale für Plattentauscher M1-S;Hochwertige Dämmschale für Plattentauscher in verschiedenen Größen;1;79,9;Isolierung für Wärmetauscher;;3625664059934 1252;Dämmschale für Plattentauscher M1-S;Hochwertige Dämmschale für Plattentauscher in verschiedenen Größen;1;79,9;Isolierung für Wärmetauscher;;3625664059934
1253;Dämmschale für Plattentauscher M1-M;Hochwertige Dämmschale für Plattentauscher in verschiedenen Größen;1;89,9;Isolierung für Wärmetauscher;;4894233116968 1253;Dämmschale für Plattentauscher M1-M;Hochwertige Dämmschale für Plattentauscher in verschiedenen Größen;1;89,9;Isolierung für Wärmetauscher;;4894233116968
1254;Dämmschale für Plattentauscher M1-L;Hochwertige Dämmschale für Plattentauscher in verschiedenen Größen;1;99,9;Isolierung für Wärmetauscher;;8183922928019 1254;Dämmschale für Plattentauscher M1-L;Hochwertige Dämmschale für Plattentauscher in verschiedenen Größen;1;99,9;Isolierung für Wärmetauscher;;8183922928019
1257;Wandbefestigung für Plattentauscher M1-53;Hochwertige Dämmschale für Plattentauscher in verschiedenen Größen;1;34,9;Wandhalterung;;8183313115592 1257;Wandbefestigung für Plattentauscher M1-53;Hochwertige Dämmschale für Plattentauscher in verschiedenen Größen;1;34,9;Wandhalterung;;8183313115592
@ -62,7 +62,7 @@ ID;Name; Description;stock;price;category;Lieferzeit;EAN
1268;Edelstahl Plattenwärmetauscher Typ M4-56-45;Edelstahl Plattenwärmetauscher geeignet für Anwendungen mit geschlossenen Kreisläufen wie z.B. Heizungsanwendungen;1;499,9;Plattenwärmetauscher > M4-56 Baureihe / zerlegbar;;4811928042234 1268;Edelstahl Plattenwärmetauscher Typ M4-56-45;Edelstahl Plattenwärmetauscher geeignet für Anwendungen mit geschlossenen Kreisläufen wie z.B. Heizungsanwendungen;1;499,9;Plattenwärmetauscher > M4-56 Baureihe / zerlegbar;;4811928042234
1269;Edelstahl Plattenwärmetauscher Typ M4-56-50;Edelstahl Plattenwärmetauscher geeignet für Anwendungen mit geschlossenen Kreisläufen wie z.B. Heizungsanwendungen;1;535,9;Plattenwärmetauscher > M4-56 Baureihe / zerlegbar;;3388615003133 1269;Edelstahl Plattenwärmetauscher Typ M4-56-50;Edelstahl Plattenwärmetauscher geeignet für Anwendungen mit geschlossenen Kreisläufen wie z.B. Heizungsanwendungen;1;535,9;Plattenwärmetauscher > M4-56 Baureihe / zerlegbar;;3388615003133
1270;Edelstahl Plattenwärmetauscher Typ M4-56-60;Edelstahl Plattenwärmetauscher geeignet für Anwendungen mit geschlossenen Kreisläufen wie z.B. Heizungsanwendungen;1;599,9;Plattenwärmetauscher > M4-56 Baureihe / zerlegbar;;6261793125392 1270;Edelstahl Plattenwärmetauscher Typ M4-56-60;Edelstahl Plattenwärmetauscher geeignet für Anwendungen mit geschlossenen Kreisläufen wie z.B. Heizungsanwendungen;1;599,9;Plattenwärmetauscher > M4-56 Baureihe / zerlegbar;;6261793125392
1326;Abgaswärmetauscher AWT-7/160VA;Abgaswärmetauscher mit Edelstahl Tauscherspirale.Dieser Tauscher wurde speziell für Kamin und Kachelöfen entwickelt.;1;284,9;Abgaswärmetauscher;;6474143371206 1326;Abgaswärmetauscher AWT-7/160VA a;Abgaswärmetauscher mit Edelstahl Tauscherspirale.Dieser Tauscher wurde speziell für Kamin und Kachelöfen entwickelt.;1;284,9;Abgaswärmetauscher;;6474143371206
1327;Abgaswärmetauscher AWT-7/160-Titan;Abgaswärmetauscher mit titanlegierter Edelstahl Tauscherspirale entwickelt für höchste Temperatur- und Feuchtebelastungen. Dieser Tauscher ist für extreme Langlebigkeit und Beständigkeit ausgelegt.;1;289,9;Abgaswärmetauscher;;4089415274929 1327;Abgaswärmetauscher AWT-7/160-Titan;Abgaswärmetauscher mit titanlegierter Edelstahl Tauscherspirale entwickelt für höchste Temperatur- und Feuchtebelastungen. Dieser Tauscher ist für extreme Langlebigkeit und Beständigkeit ausgelegt.;1;289,9;Abgaswärmetauscher;;4089415274929
1328;Abgaswärmetauscher AWT-7/180-Titan;Abgaswärmetauscher mit titanlegierter Edelstahl Tauscherspirale entwickelt für höchste Temperatur- und Feuchtebelastungen. Dieser Tauscher ist für extreme Langlebigkeit und Beständigkeit ausgelegt.;1;319,9;Abgaswärmetauscher;;4598541150958 1328;Abgaswärmetauscher AWT-7/180-Titan;Abgaswärmetauscher mit titanlegierter Edelstahl Tauscherspirale entwickelt für höchste Temperatur- und Feuchtebelastungen. Dieser Tauscher ist für extreme Langlebigkeit und Beständigkeit ausgelegt.;1;319,9;Abgaswärmetauscher;;4598541150958
1329;Abgaswärmetauscher AWT-7/180VA;Abgaswärmetauscher mit Edelstahl Tauscherspirale.Dieser Tauscher wurde speziell für Kamin und Kachelöfen entwickelt.;1;314,9;Abgaswärmetauscher;;9282813513019 1329;Abgaswärmetauscher AWT-7/180VA;Abgaswärmetauscher mit Edelstahl Tauscherspirale.Dieser Tauscher wurde speziell für Kamin und Kachelöfen entwickelt.;1;314,9;Abgaswärmetauscher;;9282813513019

1 ID Name Description stock price category Lieferzeit EAN
39 1170 Wandkonsole für Plattentauscher B3-12-xx Wandhalterung für eine schnelle Montage mit praktischem Klettverschlußband. 1 18,9 Wandhalterung 2837107354495
40 1181 LP-375VA 115kW mit Wärmedämmung Hochwertiger Schwimmbad-Wärmetauscher aus Edelstahl für Schwimmbadbeheizung mit Wärmedämmung. 0 459 Pool Wärmetauscher > Rohrförmig aus Edelstahl 8247903213713
41 1188 Wandkonsole für isolierte Pooltauscher LP-xx Wandhalterung für eine schnelle Montage mit praktischem Klettverschlußband. 1 19,9 Wandhalterung 5234087663802
42 1191 LP-65VA 20kW mit Wärmedämmung Hochwertiger Schwimmbad-Wärmetauscher aus Edelstahl für Schwimmbadbeheizung mit Wärmedämmung. Hochwertiger Schwimmbad-Wärmetauscher aus Edelstahl für Schwimmbadbeheizung mit Wärmedämmung. 1 219,9 Pool Wärmetauscher > Rohrförmig aus Edelstahl 938364240247
43 1194 LP-100VA 30kW mit Wärmedämmung Hochwertiger Schwimmbad-Wärmetauscher aus Edelstahl für Schwimmbadbeheizung mit Wärmedämmung. 1 239,9 Pool Wärmetauscher > Rohrförmig aus Edelstahl 450118214736
44 1196 LP-175VA 50kW mit Wärmedämmung Hochwertiger Schwimmbad-Wärmetauscher aus Edelstahl für Schwimmbadbeheizung mit Wärmedämmung. 1 259,9 Pool Wärmetauscher > Rohrförmig aus Edelstahl 655296358115
45 1198 LP-230VA 70kW mit Wärmedämmung Hochwertiger Schwimmbad-Wärmetauscher aus Edelstahl für Schwimmbadbeheizung mit Wärmedämmung. 1 329,9 Pool Wärmetauscher > Rohrförmig aus Edelstahl 8611986118980
46 1200 LP-325VA 95kW mit Wärmedämmung Hochwertiger Schwimmbad-Wärmetauscher aus Edelstahl für Schwimmbadbeheizung mit Wärmedämmung. 0 389,9 Pool Wärmetauscher > Rohrförmig aus Edelstahl 9005775281402
47 1204 Dämmschale für Plattentauscher M3-M Hochwertige Dämmschale für Plattentauscher in verschiedenen Größen 1 89,9 Isolierung für Wärmetauscher 5367012957872
48 1205 Dämmschale für Plattentauscher M3-L Hochwertige Dämmschale für Plattentauscher in verschiedenen Größen Hochwertige Dämmschale für Plattentauscher in verschiedenen Größen 1 99,9 Isolierung für Wärmetauscher 6854117854742
49 1206 Dämmschale für Plattentauscher SP-S Hochwertige Dämmschale für Plattentauscher in verschiedenen Größen 1 79,9 Isolierung für Wärmetauscher 1382809012286
50 1207 Dämmschale für Plattentauscher SP-M Hochwertige Dämmschale für Plattentauscher in verschiedenen Größen 1 89,9 Isolierung für Wärmetauscher 5461960384619
51 1252 Dämmschale für Plattentauscher M1-S Hochwertige Dämmschale für Plattentauscher in verschiedenen Größen Hochwertige Dämmschale für Plattentauscher in verschiedenen Größen 1 79,9 Isolierung für Wärmetauscher 3625664059934
52 1253 Dämmschale für Plattentauscher M1-M Hochwertige Dämmschale für Plattentauscher in verschiedenen Größen 1 89,9 Isolierung für Wärmetauscher 4894233116968
53 1254 Dämmschale für Plattentauscher M1-L Hochwertige Dämmschale für Plattentauscher in verschiedenen Größen 1 99,9 Isolierung für Wärmetauscher 8183922928019
54 1257 Wandbefestigung für Plattentauscher M1-53 Hochwertige Dämmschale für Plattentauscher in verschiedenen Größen 1 34,9 Wandhalterung 8183313115592
62 1268 Edelstahl Plattenwärmetauscher Typ M4-56-45 Edelstahl Plattenwärmetauscher geeignet für Anwendungen mit geschlossenen Kreisläufen wie z.B. Heizungsanwendungen 1 499,9 Plattenwärmetauscher > M4-56 Baureihe / zerlegbar 4811928042234
63 1269 Edelstahl Plattenwärmetauscher Typ M4-56-50 Edelstahl Plattenwärmetauscher geeignet für Anwendungen mit geschlossenen Kreisläufen wie z.B. Heizungsanwendungen 1 535,9 Plattenwärmetauscher > M4-56 Baureihe / zerlegbar 3388615003133
64 1270 Edelstahl Plattenwärmetauscher Typ M4-56-60 Edelstahl Plattenwärmetauscher geeignet für Anwendungen mit geschlossenen Kreisläufen wie z.B. Heizungsanwendungen 1 599,9 Plattenwärmetauscher > M4-56 Baureihe / zerlegbar 6261793125392
65 1326 Abgaswärmetauscher AWT-7/160VA Abgaswärmetauscher AWT-7/160VA a Abgaswärmetauscher mit Edelstahl Tauscherspirale.Dieser Tauscher wurde speziell für Kamin und Kachelöfen entwickelt. 1 284,9 Abgaswärmetauscher 6474143371206
66 1327 Abgaswärmetauscher AWT-7/160-Titan Abgaswärmetauscher mit titanlegierter Edelstahl Tauscherspirale entwickelt für höchste Temperatur- und Feuchtebelastungen. Dieser Tauscher ist für extreme Langlebigkeit und Beständigkeit ausgelegt. 1 289,9 Abgaswärmetauscher 4089415274929
67 1328 Abgaswärmetauscher AWT-7/180-Titan Abgaswärmetauscher mit titanlegierter Edelstahl Tauscherspirale entwickelt für höchste Temperatur- und Feuchtebelastungen. Dieser Tauscher ist für extreme Langlebigkeit und Beständigkeit ausgelegt. 1 319,9 Abgaswärmetauscher 4598541150958
68 1329 Abgaswärmetauscher AWT-7/180VA Abgaswärmetauscher mit Edelstahl Tauscherspirale.Dieser Tauscher wurde speziell für Kamin und Kachelöfen entwickelt. 1 314,9 Abgaswärmetauscher 9282813513019

View file

@ -1,6 +1,9 @@
package ai.dynamixs.rag; package ai.dynamixs.rag;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -334,6 +337,8 @@ public class ClusterService {
String query = "CREATE TABLE IF NOT EXISTS document_vectors (\n" + // String query = "CREATE TABLE IF NOT EXISTS document_vectors (\n" + //
" id text,\n" + // " id text,\n" + //
" chunk_id uuid,\n" + // " chunk_id uuid,\n" + //
" model_version text,\n" + //
" task_id int,\n" + //
" content_chunk text,\n" + // " content_chunk text,\n" + //
" content_vector VECTOR <FLOAT, " + DIMENSIONS + ">,\n" + // " content_vector VECTOR <FLOAT, " + DIMENSIONS + ">,\n" + //
" PRIMARY KEY (id, chunk_id)\n" + // " PRIMARY KEY (id, chunk_id)\n" + //
@ -343,8 +348,16 @@ public class ClusterService {
logger.info("│ ├── create index..."); logger.info("│ ├── create index...");
query = "CREATE INDEX IF NOT EXISTS edv_ann_index\n" + // query = "CREATE INDEX IF NOT EXISTS edv_ann_index\n" + //
" ON document_vectors(content_vector) USING 'sai';"; " ON document_vectors(content_vector) USING 'sai';";
session.execute(query); session.execute(query);
// Additional indexes for metadata filtering
query = "CREATE INDEX IF NOT EXISTS idx_model_version " + //
" ON document_vectors(model_version) USING 'sai';";
session.execute(query);
query = "CREATE INDEX IF NOT EXISTS idx_task_id " + //
" ON document_vectors(task_id) USING 'sai';";
session.execute(query);
logger.info("│ ├── ✅ database schema created."); logger.info("│ ├── ✅ database schema created.");
} }
@ -354,27 +367,30 @@ public class ClusterService {
* data. * data.
* *
* @param uniqueID * @param uniqueID
* @param modelVersion
* @param taskId
* @param content * @param content
* @param vector * @param vector
* @throws ClusterException * @throws ClusterException
*/ */
public void insertVector(String uniqueID, String content, List<Float> vector) throws ClusterException { public void insertVector(String uniqueID, String modelVersion, int taskId, String content, List<Float> vector)
throws ClusterException {
// Prepare statement? // Prepare statement?
if (insertVectorStmt == null) { if (insertVectorStmt == null) {
String insertQuery = "INSERT INTO document_vectors " String insertQuery = "INSERT INTO document_vectors "
+ "(id, chunk_id, content_chunk, content_vector) VALUES (?, ?, ?, ?)"; + "(id, chunk_id, model_version, task_id, content_chunk, content_vector) VALUES (?, ?, ?, ?, ?, ?)";
insertVectorStmt = session.prepare(insertQuery); insertVectorStmt = session.prepare(insertQuery);
} }
try { try {
// Generiere UUID // Generiere UUID
UUID chunk_id = UUID.randomUUID(); UUID chunk_id = UUID.randomUUID();
// CqlVector
// CqlVector verwenden
CqlVector<Float> cqlVector = CqlVector.newInstance(vector); CqlVector<Float> cqlVector = CqlVector.newInstance(vector);
BoundStatement boundStmt = insertVectorStmt.bind(uniqueID, chunk_id, content, cqlVector); BoundStatement boundStmt = insertVectorStmt.bind(uniqueID, chunk_id, modelVersion, taskId, content,
cqlVector);
session.execute(boundStmt); session.execute(boundStmt);
} catch (Exception e) { } catch (Exception e) {
@ -440,6 +456,9 @@ public class ClusterService {
* provided query embedding. If multiple chunks exist for the same document ID, * provided query embedding. If multiple chunks exist for the same document ID,
* only the chunk with the highest similarity score is returned. The results are * only the chunk with the highest similarity score is returned. The results are
* sorted by relevance score in descending order. * sorted by relevance score in descending order.
* <p>
* The params 'modelVrsions' and 'taskIds' are optional and can be used to
* refine the search result to specific process instances only.
* *
* @param queryEmbedding The embedding vector of the search query as a list of * @param queryEmbedding The embedding vector of the search query as a list of
* float values. The dimensionality must match the * float values. The dimensionality must match the
@ -455,41 +474,109 @@ public class ClusterService {
* @see RetrievalResult * @see RetrievalResult
* @since 1.0 * @since 1.0
*/ */
public List<RetrievalResult> searchEmbeddings(List<Float> embedding, int maxResults) throws ClusterException { public List<RetrievalResult> searchEmbeddings(List<Float> embedding,
int maxResults,
List<String> modelVersions,
List<Integer> taskIds,
Integer taskIdRangeStart,
Integer taskIdRangeEnd) throws ClusterException {
if (maxResults <= 0) { if (maxResults <= 0) {
throw new ClusterException(ClusterException.CLUSTER_ERROR, throw new ClusterException(ClusterException.CLUSTER_ERROR,
"maxResults must be greater than 0, but was: " + maxResults); "maxResults must be greater than 0, but was: " + maxResults);
} }
// Calculate a reasonable DB limit based on maxResults // Calculate a reasonable DB limit based on maxResults
// Factor 3-4 times to have enough chunks for deduplication. // Factor 3-4 times to have enough chunks for deduplication.
int dbLimit = Math.min(maxResults * 4, SEARCH_LIMIT_MAX); // Max 100 int searchLimit = Math.min(maxResults * 4, SEARCH_LIMIT_MAX); // Max 100
// Prepare statement if not already done (dynamisches Limit erfordert neue StringBuilder queryBuilder = new StringBuilder();
// Statements) queryBuilder.append("SELECT id, model_version, task_id, content_chunk, ")
String statementKey = "search_" + dbLimit; .append("similarity_cosine(content_vector, ?) ")
PreparedStatement searchVectorStmt = searchVectorStatements.get(statementKey); .append("FROM document_vectors ");
// Prepare statement if not already done List<String> whereConditions = new ArrayList<>();
if (searchVectorStmt == null) { // Model version filtering (with wildcard support)
String searchQuery = "SELECT id,content_chunk,similarity_cosine(content_vector, ?) " + // if (modelVersions != null && !modelVersions.isEmpty()) {
" FROM document_vectors " + // List<String> modelConditions = new ArrayList<>();
" ORDER BY content_vector ANN OF ? " + // for (String modelVersion : modelVersions) {
" LIMIT " + dbLimit; if (modelVersion.endsWith("*")) {
searchVectorStmt = session.prepare(searchQuery); // Wildcard search using LIKE
modelConditions.add("model_version LIKE ?");
} else {
// Exact match
modelConditions.add("model_version = ?");
}
}
whereConditions.add("(" + String.join(" OR ", modelConditions) + ")");
} }
// Task ID filtering - either list or range
if (taskIds != null && !taskIds.isEmpty()) {
whereConditions.add("task_id IN " + formatInClause(taskIds.size()));
} else if (taskIdRangeStart != null && taskIdRangeEnd != null) {
whereConditions.add("task_id >= ? AND task_id <= ?");
} else if (taskIdRangeStart != null) {
whereConditions.add("task_id >= ?");
} else if (taskIdRangeEnd != null) {
whereConditions.add("task_id <= ?");
}
if (!whereConditions.isEmpty()) {
queryBuilder.append("WHERE ").append(String.join(" AND ", whereConditions)).append(" ");
}
queryBuilder.append("ORDER BY content_vector ANN OF ? LIMIT ").append(searchLimit);
// Prepare statement (with caching)
String statementKey = buildStatementKey(searchLimit, modelVersions, taskIds,
taskIdRangeStart, taskIdRangeEnd);
PreparedStatement searchStmt = searchVectorStatements.get(statementKey);
if (searchStmt == null) {
searchStmt = session.prepare(queryBuilder.toString());
searchVectorStatements.put(statementKey, searchStmt);
}
try { try {
// use CqlVector // use CqlVector
CqlVector<Float> cqlVector = CqlVector.newInstance(embedding); CqlVector<Float> cqlVector = CqlVector.newInstance(embedding);
ResultSet resultRows = session.execute(searchVectorStmt.bind( // Build parameters list
cqlVector, List<Object> params = new ArrayList<>();
cqlVector)); params.add(cqlVector); // First parameter for similarity calculation
// Add model version parameters
if (modelVersions != null && !modelVersions.isEmpty()) {
for (String modelVersion : modelVersions) {
if (modelVersion.endsWith("*")) {
// Convert wildcard to LIKE pattern
params.add(modelVersion.substring(0, modelVersion.length() - 1) + "%");
} else {
params.add(modelVersion);
}
}
}
// Add task ID parameters
if (taskIds != null && !taskIds.isEmpty()) {
params.addAll(taskIds);
} else if (taskIdRangeStart != null && taskIdRangeEnd != null) {
params.add(taskIdRangeStart);
params.add(taskIdRangeEnd);
} else if (taskIdRangeStart != null) {
params.add(taskIdRangeStart);
} else if (taskIdRangeEnd != null) {
params.add(taskIdRangeEnd);
}
params.add(cqlVector);
ResultSet resultRows = session.execute(searchStmt.bind(params.toArray()));
// track best Similarity per uniqueID // track best Similarity per uniqueID
Map<String, RetrievalResult> bestMatches = new HashMap<>(); Map<String, RetrievalResult> bestMatches = new HashMap<>();
for (Row row : resultRows) { for (Row row : resultRows) {
String id = row.getString(0); String id = row.getString(0);
String contentChunk = row.getString(1); String contentChunk = row.getString(3);
Float similarity = row.getFloat(2); Float similarity = row.getFloat(4);
// test if we already have a match // test if we already have a match
RetrievalResult existingMatch = bestMatches.get(id); RetrievalResult existingMatch = bestMatches.get(id);
@ -523,4 +610,70 @@ public class ClusterService {
} }
} }
public List<RetrievalResult> searchEmbeddings(List<Float> embedding,
int maxResults) throws ClusterException {
return searchEmbeddings(embedding, maxResults, null, null, null, null);
}
// Range-based search
public List<RetrievalResult> searchEmbeddingsWithTaskRange(List<Float> embedding, int maxResults,
List<String> modelVersions,
int taskIdStart, int taskIdEnd)
throws ClusterException {
return searchEmbeddings(embedding, maxResults, modelVersions, null, taskIdStart, taskIdEnd);
}
// Wildcard model search
public List<RetrievalResult> searchEmbeddingsWithModelWildcard(List<Float> embedding, int maxResults,
String modelPattern,
List<Integer> taskIds)
throws ClusterException {
return searchEmbeddings(embedding, maxResults, Arrays.asList(modelPattern), taskIds, null, null);
}
/**
* Helper method to prepare a IN clause
*
* @param size
* @return
*/
private String formatInClause(int size) {
return "(" + String.join(",", Collections.nCopies(size, "?")) + ")";
}
/**
* Helper method to build a key for specific select statement with parameters.
* This key is used to cache prepared statements
*
* @param dbLimit
* @param modelVersions
* @param taskIds
* @param taskIdRangeStart
* @param taskIdRangeEnd
* @return
*/
private String buildStatementKey(int dbLimit, List<String> modelVersions, List<Integer> taskIds,
Integer taskIdRangeStart, Integer taskIdRangeEnd) {
StringBuilder keyBuilder = new StringBuilder("search_").append(dbLimit);
if (modelVersions != null) {
keyBuilder.append("_mv").append(modelVersions.size());
// Add wildcard indicator
long wildcardCount = modelVersions.stream().mapToLong(mv -> mv.endsWith("*") ? 1 : 0).sum();
keyBuilder.append("w").append(wildcardCount);
}
if (taskIds != null && !taskIds.isEmpty()) {
keyBuilder.append("_ti").append(taskIds.size());
} else if (taskIdRangeStart != null || taskIdRangeEnd != null) {
keyBuilder.append("_tr");
if (taskIdRangeStart != null)
keyBuilder.append("s");
if (taskIdRangeEnd != null)
keyBuilder.append("e");
}
return keyBuilder.toString();
}
} }

View file

@ -96,13 +96,10 @@ public class RAGAdapter implements SignalAdapter {
public static final String ML_ENTITY = "entity"; public static final String ML_ENTITY = "entity";
public static final String API_ERROR = "API_ERROR"; public static final String API_ERROR = "API_ERROR";
public static final String LLM_PROMPT = "PROMPT";
public static final String LLM_SUGGEST = "SUGGEST";
public static final String LLM_INDEX = "INDEX";
public static final String LLM_RETRIEVAL = "RETRIEVAL";
public static final int API_EVENT_SUCCESS = 110; public static final String RAG_INDEX = "INDEX";
public static final int API_EVENT_FAILURE = 90; public static final String RAG_DELETE = "DELETE";
public static final String RAG_RETRIEVAL = "RETRIEVAL";
private static Logger logger = Logger.getLogger(RAGAdapter.class.getName()); private static Logger logger = Logger.getLogger(RAGAdapter.class.getName());
@ -156,9 +153,21 @@ public class RAGAdapter implements SignalAdapter {
// read optional configuration form the model or imixs.properties.... // read optional configuration form the model or imixs.properties....
List<ItemCollection> llmIndexDefinitions = workflowService.evalWorkflowResultXML(event, "imixs-ai", List<ItemCollection> llmIndexDefinitions = workflowService.evalWorkflowResultXML(event, "imixs-ai",
LLM_INDEX, workitem, false); RAG_INDEX, workitem, false);
List<ItemCollection> llmRetrievalDefinitions = workflowService.evalWorkflowResultXML(event, "imixs-ai", List<ItemCollection> llmRetrievalDefinitions = workflowService.evalWorkflowResultXML(event, "imixs-ai",
LLM_RETRIEVAL, workitem, false); RAG_RETRIEVAL, workitem, false);
List<ItemCollection> llmDeleteDefinitions = workflowService.evalWorkflowResultXML(event, "imixs-ai",
RAG_DELETE, workitem, false);
// verify if we have an DELETE configuration
if (llmDeleteDefinitions != null && llmDeleteDefinitions.size() > 0) {
try {
clusterService.removeAllEmbeddings(workitem.getUniqueID());
} catch (ClusterException e) {
throw new PluginException(RAGAdapter.class.getSimpleName(), API_ERROR, e.getMessage(), e);
}
}
// verify if we have an INDEX configuration // verify if we have an INDEX configuration
if (llmIndexDefinitions != null && llmIndexDefinitions.size() > 0) { if (llmIndexDefinitions != null && llmIndexDefinitions.size() > 0) {
@ -227,7 +236,11 @@ public class RAGAdapter implements SignalAdapter {
} }
List<Float> indexResult = llmService.postEmbedding(chunk, llmAPIEndpoint, llmAPIDebug); List<Float> indexResult = llmService.postEmbedding(chunk, llmAPIEndpoint, llmAPIDebug);
// write to cassandra // write to cassandra
clusterService.insertVector(workitem.getUniqueID(), chunk, indexResult); clusterService.insertVector(workitem.getUniqueID(),
workitem.getModelVersion(),
workitem.getTaskID(),
chunk,
indexResult);
if (llmAPIDebug) { if (llmAPIDebug) {
logger.info("│ ├── ⇨ " + indexResult.size() + " floats stored in RAG db."); logger.info("│ ├── ⇨ " + indexResult.size() + " floats stored in RAG db.");
} }
@ -289,12 +302,12 @@ public class RAGAdapter implements SignalAdapter {
} }
// retrieve prompt.... // retrieve prompt....
List<Float> indexResult = llmService.postEmbedding(llmPrompt, llmAPIEndpoint, llmAPIDebug); List<Float> embeddings = llmService.postEmbedding(llmPrompt, llmAPIEndpoint, llmAPIDebug);
if (llmAPIDebug) { if (llmAPIDebug) {
logger.info("├── ⇨ " + indexResult.size() + " floats stored in RAG db."); logger.info("├── ⇨ " + embeddings.size() + " floats stored in RAG db.");
} }
// search cassandra // search cassandra
List<RetrievalResult> retrievalResultList = clusterService.searchEmbeddings(indexResult, 5); List<RetrievalResult> retrievalResultList = clusterService.searchEmbeddings(embeddings, 5);
List<String> listOfIds = retrievalResultList.stream() List<String> listOfIds = retrievalResultList.stream()
.map(RetrievalResult::getUniqueId) .map(RetrievalResult::getUniqueId)
.collect(Collectors.toList()); .collect(Collectors.toList());

View file

@ -50,7 +50,6 @@
<bpmn2:flowNodeRef>Task_3</bpmn2:flowNodeRef> <bpmn2:flowNodeRef>Task_3</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>StartEvent_1</bpmn2:flowNodeRef> <bpmn2:flowNodeRef>StartEvent_1</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>IntermediateCatchEvent_17</bpmn2:flowNodeRef> <bpmn2:flowNodeRef>IntermediateCatchEvent_17</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>ExclusiveGateway_2</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>IntermediateCatchEvent_9</bpmn2:flowNodeRef> <bpmn2:flowNodeRef>IntermediateCatchEvent_9</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>Task_4</bpmn2:flowNodeRef> <bpmn2:flowNodeRef>Task_4</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>IntermediateCatchEvent_8</bpmn2:flowNodeRef> <bpmn2:flowNodeRef>IntermediateCatchEvent_8</bpmn2:flowNodeRef>
@ -73,6 +72,8 @@
<bpmn2:flowNodeRef>event_y0smQw</bpmn2:flowNodeRef> <bpmn2:flowNodeRef>event_y0smQw</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>event_qb0xXA</bpmn2:flowNodeRef> <bpmn2:flowNodeRef>event_qb0xXA</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>event_jBz77w</bpmn2:flowNodeRef> <bpmn2:flowNodeRef>event_jBz77w</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>gateway_cDqotg</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>event_k2i6EQ</bpmn2:flowNodeRef>
</bpmn2:lane> </bpmn2:lane>
</bpmn2:laneSet> </bpmn2:laneSet>
<bpmn2:startEvent id="StartEvent_1" name="Start"> <bpmn2:startEvent id="StartEvent_1" name="Start">
@ -138,6 +139,7 @@ Color: <itemvalue>_color</itemvalue>
<bpmn2:incoming>sequenceFlow_OiqVHg</bpmn2:incoming> <bpmn2:incoming>sequenceFlow_OiqVHg</bpmn2:incoming>
<bpmn2:incoming>sequenceFlow_4DUFiA</bpmn2:incoming> <bpmn2:incoming>sequenceFlow_4DUFiA</bpmn2:incoming>
<bpmn2:outgoing>sequenceFlow_crpgGw</bpmn2:outgoing> <bpmn2:outgoing>sequenceFlow_crpgGw</bpmn2:outgoing>
<bpmn2:incoming>SequenceFlow_21</bpmn2:incoming>
</bpmn2:task> </bpmn2:task>
<bpmn2:dataObject id="DataObject_2" imixs:datatype="form-data" name="Order Form"> <bpmn2:dataObject id="DataObject_2" imixs:datatype="form-data" name="Order Form">
<bpmn2:documentation id="Documentation_8"><![CDATA[<?xml version="1.0"?> <bpmn2:documentation id="Documentation_8"><![CDATA[<?xml version="1.0"?>
@ -253,9 +255,9 @@ Color: <itemvalue>_color</itemvalue><br />
</bpmn2:extensionElements> </bpmn2:extensionElements>
<bpmn2:documentation id="Documentation_30"><![CDATA[<textblock><itemvalue>$workflowgroup</itemvalue> - <itemvalue>$workflowstatus</itemvalue></textblock>]]></bpmn2:documentation> <bpmn2:documentation id="Documentation_30"><![CDATA[<textblock><itemvalue>$workflowgroup</itemvalue> - <itemvalue>$workflowstatus</itemvalue></textblock>]]></bpmn2:documentation>
<bpmn2:incoming>SequenceFlow_17</bpmn2:incoming> <bpmn2:incoming>SequenceFlow_17</bpmn2:incoming>
<bpmn2:incoming>SequenceFlow_40</bpmn2:incoming>
<bpmn2:outgoing>SequenceFlow_19</bpmn2:outgoing> <bpmn2:outgoing>SequenceFlow_19</bpmn2:outgoing>
<bpmn2:outgoing>SequenceFlow_25</bpmn2:outgoing> <bpmn2:incoming>sequenceFlow_8XT0hw</bpmn2:incoming>
<bpmn2:incoming>SequenceFlow_26</bpmn2:incoming>
</bpmn2:task> </bpmn2:task>
<bpmn2:task id="Task_5" imixs:processid="1900" name="Eingestellt"> <bpmn2:task id="Task_5" imixs:processid="1900" name="Eingestellt">
<bpmn2:extensionElements> <bpmn2:extensionElements>
@ -299,7 +301,6 @@ Color: <itemvalue>_color</itemvalue><br />
</imixs:item> </imixs:item>
</bpmn2:extensionElements> </bpmn2:extensionElements>
<bpmn2:documentation id="Documentation_31"><![CDATA[<textblock><itemvalue>$workflowgroup</itemvalue> - <itemvalue>$workflowstatus</itemvalue></textblock>]]></bpmn2:documentation> <bpmn2:documentation id="Documentation_31"><![CDATA[<textblock><itemvalue>$workflowgroup</itemvalue> - <itemvalue>$workflowstatus</itemvalue></textblock>]]></bpmn2:documentation>
<bpmn2:incoming>SequenceFlow_21</bpmn2:incoming>
<bpmn2:outgoing>SequenceFlow_47</bpmn2:outgoing> <bpmn2:outgoing>SequenceFlow_47</bpmn2:outgoing>
</bpmn2:task> </bpmn2:task>
<bpmn2:endEvent id="EndEvent_2" name="Ende"> <bpmn2:endEvent id="EndEvent_2" name="Ende">
@ -310,7 +311,7 @@ Color: <itemvalue>_color</itemvalue><br />
<bpmn2:sequenceFlow id="SequenceFlow_47" sourceRef="Task_5" targetRef="EndEvent_2"> <bpmn2:sequenceFlow id="SequenceFlow_47" sourceRef="Task_5" targetRef="EndEvent_2">
<bpmn2:documentation id="documentation_ad1jJw"/> <bpmn2:documentation id="documentation_ad1jJw"/>
</bpmn2:sequenceFlow> </bpmn2:sequenceFlow>
<bpmn2:intermediateCatchEvent id="IntermediateCatchEvent_17" imixs:activityid="40" name="Bestellt"> <bpmn2:intermediateCatchEvent id="IntermediateCatchEvent_17" imixs:activityid="20" name="Bestellt">
<bpmn2:extensionElements> <bpmn2:extensionElements>
<imixs:item name="keylogtimeformat" type="xs:string"> <imixs:item name="keylogtimeformat" type="xs:string">
<imixs:value><![CDATA[2]]></imixs:value> <imixs:value><![CDATA[2]]></imixs:value>
@ -378,13 +379,10 @@ Betrag: <itemvalue>_amount</itemvalue> (Brutto € <itemvalue>_amount_brutto</it
</imixs:item> </imixs:item>
</bpmn2:extensionElements> </bpmn2:extensionElements>
<bpmn2:documentation id="Documentation_32"><![CDATA[Bestellung ausgeführt]]></bpmn2:documentation> <bpmn2:documentation id="Documentation_32"><![CDATA[Bestellung ausgeführt]]></bpmn2:documentation>
<bpmn2:outgoing>SequenceFlow_56</bpmn2:outgoing> <bpmn2:incoming>sequenceFlow_Hq0Ccg</bpmn2:incoming>
<bpmn2:incoming>sequenceFlow_HCxYvw</bpmn2:incoming> <bpmn2:outgoing>sequenceFlow_8XT0hw</bpmn2:outgoing>
</bpmn2:intermediateCatchEvent> </bpmn2:intermediateCatchEvent>
<bpmn2:sequenceFlow id="SequenceFlow_56" sourceRef="IntermediateCatchEvent_17" targetRef="ExclusiveGateway_2"> <bpmn2:intermediateCatchEvent id="IntermediateCatchEvent_4" imixs:activityid="20" name="Geliefert">
<bpmn2:documentation id="documentation_T3n4KQ"/>
</bpmn2:sequenceFlow>
<bpmn2:intermediateCatchEvent id="IntermediateCatchEvent_4" imixs:activityid="20" name="Erledigt">
<bpmn2:extensionElements> <bpmn2:extensionElements>
<imixs:item name="keylogtimeformat" type="xs:string"> <imixs:item name="keylogtimeformat" type="xs:string">
<imixs:value><![CDATA[2]]></imixs:value> <imixs:value><![CDATA[2]]></imixs:value>
@ -436,7 +434,8 @@ Betrag: <itemvalue>_amount</itemvalue> (Brutto € <itemvalue>_amount_brutto</it
<imixs:value/> <imixs:value/>
</imixs:item> </imixs:item>
<imixs:item name="txtactivityresult" type="xs:string"> <imixs:item name="txtactivityresult" type="xs:string">
<imixs:value><![CDATA[<item name="action">home</item>]]></imixs:value> <imixs:value><![CDATA[<item name="action">home</item>
]]></imixs:value>
</imixs:item> </imixs:item>
<imixs:item name="txtname" type="xs:string"> <imixs:item name="txtname" type="xs:string">
<imixs:value><![CDATA[Freigabe einholen]]></imixs:value> <imixs:value><![CDATA[Freigabe einholen]]></imixs:value>
@ -459,7 +458,7 @@ Betrag: <itemvalue>_amount</itemvalue> (Brutto € <itemvalue>_amount_brutto</it
<bpmn2:sequenceFlow id="SequenceFlow_19" sourceRef="Task_4" targetRef="IntermediateCatchEvent_4"> <bpmn2:sequenceFlow id="SequenceFlow_19" sourceRef="Task_4" targetRef="IntermediateCatchEvent_4">
<bpmn2:documentation id="documentation_8nOd8A"/> <bpmn2:documentation id="documentation_8nOd8A"/>
</bpmn2:sequenceFlow> </bpmn2:sequenceFlow>
<bpmn2:sequenceFlow id="SequenceFlow_21" sourceRef="IntermediateCatchEvent_4" targetRef="Task_5"> <bpmn2:sequenceFlow id="SequenceFlow_21" sourceRef="IntermediateCatchEvent_4" targetRef="Task_2">
<bpmn2:documentation id="documentation_0MbT1A"/> <bpmn2:documentation id="documentation_0MbT1A"/>
</bpmn2:sequenceFlow> </bpmn2:sequenceFlow>
<bpmn2:task id="Task_1" imixs:processid="1500" name="Nicht lagerned"> <bpmn2:task id="Task_1" imixs:processid="1500" name="Nicht lagerned">
@ -506,9 +505,9 @@ Color: <itemvalue>_color</itemvalue><br />
</imixs:item> </imixs:item>
</bpmn2:extensionElements> </bpmn2:extensionElements>
<bpmn2:documentation id="Documentation_73"><![CDATA[<textblock><itemvalue>$workflowgroup</itemvalue> - <itemvalue>$workflowstatus</itemvalue></textblock>]]></bpmn2:documentation> <bpmn2:documentation id="Documentation_73"><![CDATA[<textblock><itemvalue>$workflowgroup</itemvalue> - <itemvalue>$workflowstatus</itemvalue></textblock>]]></bpmn2:documentation>
<bpmn2:incoming>SequenceFlow_26</bpmn2:incoming>
<bpmn2:outgoing>SequenceFlow_23</bpmn2:outgoing> <bpmn2:outgoing>SequenceFlow_23</bpmn2:outgoing>
<bpmn2:outgoing>SequenceFlow_36</bpmn2:outgoing> <bpmn2:incoming>sequenceFlow_2pAPvA</bpmn2:incoming>
<bpmn2:incoming>sequenceFlow_RgOnDQ</bpmn2:incoming>
</bpmn2:task> </bpmn2:task>
<bpmn2:intermediateCatchEvent id="IntermediateCatchEvent_6" imixs:activityid="99" name="[Wiedervorlage]"> <bpmn2:intermediateCatchEvent id="IntermediateCatchEvent_6" imixs:activityid="99" name="[Wiedervorlage]">
<bpmn2:extensionElements> <bpmn2:extensionElements>
@ -589,15 +588,11 @@ Betrag: <itemvalue>_amount</itemvalue> (Brutto € <itemvalue>_amount_brutto</it
<imixs:value><![CDATA[4]]></imixs:value> <imixs:value><![CDATA[4]]></imixs:value>
</imixs:item> </imixs:item>
</bpmn2:extensionElements> </bpmn2:extensionElements>
<bpmn2:incoming>SequenceFlow_25</bpmn2:incoming>
<bpmn2:outgoing>SequenceFlow_26</bpmn2:outgoing> <bpmn2:outgoing>SequenceFlow_26</bpmn2:outgoing>
<bpmn2:timerEventDefinition id="TimerEventDefinition_1"/> <bpmn2:timerEventDefinition id="TimerEventDefinition_1"/>
<bpmn2:documentation id="documentation_md5giQ"/> <bpmn2:documentation id="documentation_md5giQ"/>
</bpmn2:intermediateCatchEvent> </bpmn2:intermediateCatchEvent>
<bpmn2:sequenceFlow id="SequenceFlow_25" sourceRef="Task_4" targetRef="IntermediateCatchEvent_6"> <bpmn2:sequenceFlow id="SequenceFlow_26" sourceRef="IntermediateCatchEvent_6" targetRef="Task_4">
<bpmn2:documentation id="documentation_Bz09Rw"/>
</bpmn2:sequenceFlow>
<bpmn2:sequenceFlow id="SequenceFlow_26" sourceRef="IntermediateCatchEvent_6" targetRef="Task_1">
<bpmn2:documentation id="documentation_xUioTg"/> <bpmn2:documentation id="documentation_xUioTg"/>
</bpmn2:sequenceFlow> </bpmn2:sequenceFlow>
<bpmn2:sequenceFlow id="SequenceFlow_27" sourceRef="EventBasedGateway_1" targetRef="IntermediateCatchEvent_4"> <bpmn2:sequenceFlow id="SequenceFlow_27" sourceRef="EventBasedGateway_1" targetRef="IntermediateCatchEvent_4">
@ -671,8 +666,7 @@ Betrag: <itemvalue>_amount</itemvalue> (Brutto € <itemvalue>_amount_brutto</it
</imixs:item> </imixs:item>
</bpmn2:extensionElements> </bpmn2:extensionElements>
<bpmn2:documentation id="Documentation_16"><![CDATA[Zwischenspeichern]]></bpmn2:documentation> <bpmn2:documentation id="Documentation_16"><![CDATA[Zwischenspeichern]]></bpmn2:documentation>
<bpmn2:incoming>SequenceFlow_36</bpmn2:incoming> <bpmn2:outgoing>sequenceFlow_2pAPvA</bpmn2:outgoing>
<bpmn2:outgoing>SequenceFlow_39</bpmn2:outgoing>
</bpmn2:intermediateCatchEvent> </bpmn2:intermediateCatchEvent>
<bpmn2:intermediateCatchEvent id="IntermediateCatchEvent_8" imixs:activityid="10" name="Speichern"> <bpmn2:intermediateCatchEvent id="IntermediateCatchEvent_8" imixs:activityid="10" name="Speichern">
<bpmn2:extensionElements> <bpmn2:extensionElements>
@ -885,21 +879,6 @@ result.isValid=true;
<bpmn2:sequenceFlow id="SequenceFlow_34" sourceRef="EventBasedGateway_1" targetRef="IntermediateCatchEvent_9"> <bpmn2:sequenceFlow id="SequenceFlow_34" sourceRef="EventBasedGateway_1" targetRef="IntermediateCatchEvent_9">
<bpmn2:documentation id="documentation_J2bE6A"/> <bpmn2:documentation id="documentation_J2bE6A"/>
</bpmn2:sequenceFlow> </bpmn2:sequenceFlow>
<bpmn2:exclusiveGateway gatewayDirection="Converging" id="ExclusiveGateway_2">
<bpmn2:incoming>SequenceFlow_56</bpmn2:incoming>
<bpmn2:incoming>SequenceFlow_39</bpmn2:incoming>
<bpmn2:outgoing>SequenceFlow_40</bpmn2:outgoing>
<bpmn2:documentation id="documentation_k8LvXA"/>
</bpmn2:exclusiveGateway>
<bpmn2:sequenceFlow id="SequenceFlow_36" sourceRef="Task_1" targetRef="IntermediateCatchEvent_7">
<bpmn2:documentation id="documentation_MrgTLA"/>
</bpmn2:sequenceFlow>
<bpmn2:sequenceFlow id="SequenceFlow_39" sourceRef="IntermediateCatchEvent_7" targetRef="ExclusiveGateway_2">
<bpmn2:documentation id="documentation_TncqqQ"/>
</bpmn2:sequenceFlow>
<bpmn2:sequenceFlow id="SequenceFlow_40" sourceRef="ExclusiveGateway_2" targetRef="Task_4">
<bpmn2:documentation id="documentation_pBSG0g"/>
</bpmn2:sequenceFlow>
<bpmn2:sequenceFlow id="SequenceFlow_41" sourceRef="IntermediateCatchEvent_9" targetRef="Task_6"> <bpmn2:sequenceFlow id="SequenceFlow_41" sourceRef="IntermediateCatchEvent_9" targetRef="Task_6">
<bpmn2:documentation id="documentation_TCjUeA"/> <bpmn2:documentation id="documentation_TCjUeA"/>
</bpmn2:sequenceFlow> </bpmn2:sequenceFlow>
@ -1194,7 +1173,7 @@ result.isValid=true;
<bpmn2:sequenceFlow id="sequenceFlow_N5KIRQ" sourceRef="event_qTIbqA" targetRef="Task_3"> <bpmn2:sequenceFlow id="sequenceFlow_N5KIRQ" sourceRef="event_qTIbqA" targetRef="Task_3">
<bpmn2:documentation id="documentation_r0YZaQ"/> <bpmn2:documentation id="documentation_r0YZaQ"/>
</bpmn2:sequenceFlow> </bpmn2:sequenceFlow>
<bpmn2:sequenceFlow id="sequenceFlow_HCxYvw" sourceRef="Task_3" targetRef="IntermediateCatchEvent_17"> <bpmn2:sequenceFlow id="sequenceFlow_HCxYvw" sourceRef="Task_3" targetRef="gateway_cDqotg">
<bpmn2:documentation id="documentation_Vl0LOg"/> <bpmn2:documentation id="documentation_Vl0LOg"/>
</bpmn2:sequenceFlow> </bpmn2:sequenceFlow>
<bpmn2:association id="association_haKP7Q" sourceRef="textAnnotation_JTmRrA" targetRef="event_oeP3WQ"> <bpmn2:association id="association_haKP7Q" sourceRef="textAnnotation_JTmRrA" targetRef="event_oeP3WQ">
@ -1203,7 +1182,7 @@ result.isValid=true;
<bpmn2:association id="association_BseA8A" sourceRef="DataObject_2" targetRef="Task_3"> <bpmn2:association id="association_BseA8A" sourceRef="DataObject_2" targetRef="Task_3">
<bpmn2:documentation id="documentation_waNoXQ"/> <bpmn2:documentation id="documentation_waNoXQ"/>
</bpmn2:association> </bpmn2:association>
<bpmn2:intermediateCatchEvent id="event_jBz77w" imixs:activityid="50" name="(RAG)"> <bpmn2:intermediateCatchEvent id="event_jBz77w" imixs:activityid="100" name="(RAG)">
<bpmn2:extensionElements> <bpmn2:extensionElements>
<imixs:item name="keylogtimeformat" type="xs:string"> <imixs:item name="keylogtimeformat" type="xs:string">
<imixs:value><![CDATA[2]]></imixs:value> <imixs:value><![CDATA[2]]></imixs:value>
@ -1285,6 +1264,104 @@ result.isValid=true;
<bpmn2:association id="association_SjKymg" sourceRef="dataObject_axJA7Q" targetRef="event_jBz77w"> <bpmn2:association id="association_SjKymg" sourceRef="dataObject_axJA7Q" targetRef="event_jBz77w">
<bpmn2:documentation id="documentation_EaPADA"/> <bpmn2:documentation id="documentation_EaPADA"/>
</bpmn2:association> </bpmn2:association>
<bpmn2:sequenceFlow id="sequenceFlow_2pAPvA" sourceRef="IntermediateCatchEvent_7" targetRef="Task_1">
<bpmn2:documentation id="documentation_OACYUA"/>
</bpmn2:sequenceFlow>
<bpmn2:eventBasedGateway gatewayDirection="Diverging" id="gateway_cDqotg" name="">
<bpmn2:documentation id="documentation_GbhsFQ"/>
<bpmn2:incoming>sequenceFlow_HCxYvw</bpmn2:incoming>
<bpmn2:outgoing>sequenceFlow_Hq0Ccg</bpmn2:outgoing>
<bpmn2:outgoing>sequenceFlow_Jkgs0A</bpmn2:outgoing>
</bpmn2:eventBasedGateway>
<bpmn2:sequenceFlow id="sequenceFlow_Hq0Ccg" sourceRef="gateway_cDqotg" targetRef="IntermediateCatchEvent_17">
<bpmn2:documentation id="documentation_ZV9ayA"/>
</bpmn2:sequenceFlow>
<bpmn2:sequenceFlow id="sequenceFlow_8XT0hw" sourceRef="IntermediateCatchEvent_17" targetRef="Task_4">
<bpmn2:documentation id="documentation_KYSJuA"/>
</bpmn2:sequenceFlow>
<bpmn2:intermediateCatchEvent id="event_k2i6EQ" imixs:activityid="30" name="Nicht mehr auf Lager">
<bpmn2:extensionElements>
<imixs:item name="keylogtimeformat" type="xs:string">
<imixs:value><![CDATA[2]]></imixs:value>
</imixs:item>
<imixs:item name="keyarchive" type="xs:string">
<imixs:value><![CDATA[0]]></imixs:value>
</imixs:item>
<imixs:item name="txtmailsubject" type="xs:string">
<imixs:value><![CDATA[Eingangsrechnung erhalten: <itemvalue>_subject</itemvalue>]]></imixs:value>
</imixs:item>
<imixs:item name="keyaccessmode" type="xs:string">
<imixs:value><![CDATA[0]]></imixs:value>
</imixs:item>
<imixs:item name="keyscheduledactivity" type="xs:string">
<imixs:value><![CDATA[0]]></imixs:value>
</imixs:item>
<imixs:item name="rtfmailbody" type="xs:string">
<imixs:value><![CDATA[Wir haben folgende Rechnung erhalten: bitte freigeben.
Betrag: <itemvalue>_amount</itemvalue> (Brutto € <itemvalue>_amount_brutto</itemvalue>)
<itemvalue>_description</itemvalue>]]></imixs:value>
</imixs:item>
<imixs:item name="keymailreceiverfields" type="xs:string"/>
<imixs:item name="keyversion" type="xs:string">
<imixs:value><![CDATA[0]]></imixs:value>
</imixs:item>
<imixs:item name="keyaddwritefields" type="xs:string">
<imixs:value><![CDATA[namprocessmanager]]></imixs:value>
</imixs:item>
<imixs:item name="numnextactivityid" type="xs:int">
<imixs:value><![CDATA[0]]></imixs:value>
</imixs:item>
<imixs:item name="keyfollowup" type="xs:string">
<imixs:value><![CDATA[2]]></imixs:value>
</imixs:item>
<imixs:item name="keypublicresult" type="xs:string">
<imixs:value><![CDATA[1]]></imixs:value>
</imixs:item>
<imixs:item name="keylogdateformat" type="xs:string">
<imixs:value><![CDATA[2]]></imixs:value>
</imixs:item>
<imixs:item name="keyownershipfields" type="xs:string">
<imixs:value><![CDATA[namprocessmanager]]></imixs:value>
</imixs:item>
<imixs:item name="numnextid" type="xs:int">
<imixs:value><![CDATA[5005]]></imixs:value>
</imixs:item>
<imixs:item name="txtnextprocesstree" type="xs:string">
<imixs:value/>
</imixs:item>
<imixs:item name="txtactivityresult" type="xs:string">
<imixs:value><![CDATA[<item name="action">home</item>
<imixs-ai name="DELETE">
<endpoint>https://llama.cpp2.imixs.com/</endpoint>
<debug>true</debug>
</imixs-ai>
]]></imixs:value>
</imixs:item>
<imixs:item name="txtname" type="xs:string">
<imixs:value><![CDATA[Freigabe einholen]]></imixs:value>
</imixs:item>
<imixs:item name="keyownershipmode" type="xs:string">
<imixs:value><![CDATA[0]]></imixs:value>
</imixs:item>
<imixs:item name="rtfresultlog" type="xs:string">
<imixs:value><![CDATA[Artikel nicht mehr auf Lager]]></imixs:value>
</imixs:item>
<imixs:item name="keyupdateacl" type="xs:boolean">
<imixs:value>false</imixs:value>
</imixs:item>
</bpmn2:extensionElements>
<bpmn2:documentation id="documentation_DVm0Lg"><![CDATA[Bestellung ausgeführt]]></bpmn2:documentation>
<bpmn2:incoming>sequenceFlow_Jkgs0A</bpmn2:incoming>
<bpmn2:outgoing>sequenceFlow_RgOnDQ</bpmn2:outgoing>
<bpmn2:signalEventDefinition id="signalEventDefinition_auduLQ" signalRef="signal_4"/>
</bpmn2:intermediateCatchEvent>
<bpmn2:sequenceFlow id="sequenceFlow_Jkgs0A" sourceRef="gateway_cDqotg" targetRef="event_k2i6EQ">
<bpmn2:documentation id="documentation_JgAfHA"/>
</bpmn2:sequenceFlow>
<bpmn2:sequenceFlow id="sequenceFlow_RgOnDQ" sourceRef="event_k2i6EQ" targetRef="Task_1">
<bpmn2:documentation id="documentation_4kf6UQ"/>
</bpmn2:sequenceFlow>
</bpmn2:process> </bpmn2:process>
<bpmn2:process id="process_2" name="Default Process" processType="Public"> <bpmn2:process id="process_2" name="Default Process" processType="Public">
<bpmn2:documentation id="documentation_imRbaw"/> <bpmn2:documentation id="documentation_imRbaw"/>
@ -1297,10 +1374,10 @@ result.isValid=true;
<bpmndi:BPMNDiagram id="BPMNDiagram_1"> <bpmndi:BPMNDiagram id="BPMNDiagram_1">
<bpmndi:BPMNPlane bpmnElement="Collaboration_1" id="BPMNPlane_Process_1"> <bpmndi:BPMNPlane bpmnElement="Collaboration_1" id="BPMNPlane_Process_1">
<bpmndi:BPMNShape bpmnElement="Participant_1" id="BPMNShape_Participant_1" isHorizontal="true"> <bpmndi:BPMNShape bpmnElement="Participant_1" id="BPMNShape_Participant_1" isHorizontal="true">
<dc:Bounds height="530.0" width="1880.0" x="100.0" y="70.0"/> <dc:Bounds height="810.0" width="1900.0" x="100.0" y="70.0"/>
</bpmndi:BPMNShape> </bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="Lane_1" id="BPMNShape_Lane_1" isHorizontal="true"> <bpmndi:BPMNShape bpmnElement="Lane_1" id="BPMNShape_Lane_1" isHorizontal="true">
<dc:Bounds height="530.0" width="1850.0" x="130.0" y="70.0"/> <dc:Bounds height="810.0" width="1870.0" x="130.0" y="70.0"/>
</bpmndi:BPMNShape> </bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="StartEvent_1" id="BPMNShape_StartEvent_1"> <bpmndi:BPMNShape bpmnElement="StartEvent_1" id="BPMNShape_StartEvent_1">
<dc:Bounds height="36.0" width="36.0" x="177.0" y="317.0"/> <dc:Bounds height="36.0" width="36.0" x="177.0" y="317.0"/>
@ -1339,9 +1416,9 @@ result.isValid=true;
</bpmndi:BPMNLabel> </bpmndi:BPMNLabel>
</bpmndi:BPMNShape> </bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="IntermediateCatchEvent_17" id="BPMNShape_IntermediateCatchEvent_27"> <bpmndi:BPMNShape bpmnElement="IntermediateCatchEvent_17" id="BPMNShape_IntermediateCatchEvent_27">
<dc:Bounds height="36.0" width="36.0" x="857.0" y="317.0"/> <dc:Bounds height="36.0" width="36.0" x="997.0" y="317.0"/>
<bpmndi:BPMNLabel id="BPMNLabel_116" labelStyle="BPMNLabelStyle_1"> <bpmndi:BPMNLabel id="BPMNLabel_116" labelStyle="BPMNLabelStyle_1">
<dc:Bounds height="20.0" width="100.0" x="834.0128173828125" y="357.1767883300781"/> <dc:Bounds height="20.0" width="100.0" x="974.0128173828125" y="357.1767883300781"/>
</bpmndi:BPMNLabel> </bpmndi:BPMNLabel>
</bpmndi:BPMNShape> </bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="IntermediateCatchEvent_4" id="BPMNShape_IntermediateCatchEvent_9"> <bpmndi:BPMNShape bpmnElement="IntermediateCatchEvent_4" id="BPMNShape_IntermediateCatchEvent_9">
@ -1351,48 +1428,42 @@ result.isValid=true;
</bpmndi:BPMNLabel> </bpmndi:BPMNLabel>
</bpmndi:BPMNShape> </bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="Task_1" id="BPMNShape_Task_3"> <bpmndi:BPMNShape bpmnElement="Task_1" id="BPMNShape_Task_3">
<dc:Bounds height="50.0" width="110.0" x="1150.0" y="160.0"/> <dc:Bounds height="50.0" width="110.0" x="1150.0" y="560.0"/>
</bpmndi:BPMNShape> </bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="IntermediateCatchEvent_6" id="BPMNShape_IntermediateCatchEvent_11"> <bpmndi:BPMNShape bpmnElement="IntermediateCatchEvent_6" id="BPMNShape_IntermediateCatchEvent_11">
<dc:Bounds height="36.0" width="36.0" x="1187.0" y="237.0"/> <dc:Bounds height="36.0" width="36.0" x="1187.0" y="227.0"/>
<bpmndi:BPMNLabel id="BPMNLabel_56" labelStyle="BPMNLabelStyle_1"> <bpmndi:BPMNLabel id="BPMNLabel_56" labelStyle="BPMNLabelStyle_1">
<dc:Bounds height="20.0" width="100.0" x="1155.2283935546875" y="278.10797119140625"/> <dc:Bounds height="20.0" width="100.0" x="1155.2283935546875" y="268.10797119140625"/>
</bpmndi:BPMNLabel> </bpmndi:BPMNLabel>
</bpmndi:BPMNShape> </bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="TextAnnotation_4" id="BPMNShape_TextAnnotation_4"> <bpmndi:BPMNShape bpmnElement="TextAnnotation_4" id="BPMNShape_TextAnnotation_4">
<dc:Bounds height="60.0" width="239.0" x="1240.0" y="90.0"/> <dc:Bounds height="60.0" width="239.0" x="980.0" y="740.0"/>
</bpmndi:BPMNShape> </bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="IntermediateCatchEvent_7" id="BPMNShape_IntermediateCatchEvent_12"> <bpmndi:BPMNShape bpmnElement="IntermediateCatchEvent_7" id="BPMNShape_IntermediateCatchEvent_12">
<dc:Bounds height="36.0" width="36.0" x="1077.0" y="167.0"/> <dc:Bounds height="36.0" width="36.0" x="1237.0" y="657.0"/>
<bpmndi:BPMNLabel id="BPMNLabel_31" labelStyle="BPMNLabelStyle_1"> <bpmndi:BPMNLabel id="BPMNLabel_31" labelStyle="BPMNLabelStyle_1">
<dc:Bounds height="20.0" width="100.0" x="1048.638671875" y="203.10794067382812"/> <dc:Bounds height="20.0" width="100.0" x="1208.638671875" y="693.10791015625"/>
</bpmndi:BPMNLabel> </bpmndi:BPMNLabel>
</bpmndi:BPMNShape> </bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="IntermediateCatchEvent_8" id="BPMNShape_IntermediateCatchEvent_14"> <bpmndi:BPMNShape bpmnElement="IntermediateCatchEvent_8" id="BPMNShape_IntermediateCatchEvent_14">
<dc:Bounds height="36.0" width="36.0" x="1187.0" y="427.0"/> <dc:Bounds height="36.0" width="36.0" x="1187.0" y="417.0"/>
<bpmndi:BPMNLabel id="BPMNLabel_70" labelStyle="BPMNLabelStyle_1"> <bpmndi:BPMNLabel id="BPMNLabel_70" labelStyle="BPMNLabelStyle_1">
<dc:Bounds height="20.0" width="100.0" x="1154.7283935546875" y="464.10797119140625"/> <dc:Bounds height="20.0" width="100.0" x="1154.7283935546875" y="454.10797119140625"/>
</bpmndi:BPMNLabel> </bpmndi:BPMNLabel>
</bpmndi:BPMNShape> </bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="Task_6" id="BPMNShape_Task_4"> <bpmndi:BPMNShape bpmnElement="Task_6" id="BPMNShape_Task_4">
<dc:Bounds height="50.0" width="110.0" x="1630.0" y="160.0"/> <dc:Bounds height="50.0" width="110.0" x="1630.0" y="560.0"/>
</bpmndi:BPMNShape> </bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="EventBasedGateway_1" id="BPMNShape_EventBasedGateway_1" isMarkerVisible="true"> <bpmndi:BPMNShape bpmnElement="EventBasedGateway_1" id="BPMNShape_EventBasedGateway_1" isMarkerVisible="true">
<dc:Bounds height="50.0" width="50.0" x="1340.0" y="160.0"/> <dc:Bounds height="50.0" width="50.0" x="1340.0" y="560.0"/>
<bpmndi:BPMNLabel id="BPMNLabel_74" labelStyle="BPMNLabelStyle_1"> <bpmndi:BPMNLabel id="BPMNLabel_74" labelStyle="BPMNLabelStyle_1">
<dc:Bounds height="20.0" width="100.0" x="1315.0" y="213.0"/> <dc:Bounds height="20.0" width="100.0" x="1315.0" y="613.0"/>
</bpmndi:BPMNLabel> </bpmndi:BPMNLabel>
</bpmndi:BPMNShape> </bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="IntermediateCatchEvent_9" id="BPMNShape_IntermediateCatchEvent_15"> <bpmndi:BPMNShape bpmnElement="IntermediateCatchEvent_9" id="BPMNShape_IntermediateCatchEvent_15">
<dc:Bounds height="36.0" width="36.0" x="1497.0" y="167.0"/> <dc:Bounds height="36.0" width="36.0" x="1497.0" y="567.0"/>
<bpmndi:BPMNLabel id="BPMNLabel_76" labelStyle="BPMNLabelStyle_1"> <bpmndi:BPMNLabel id="BPMNLabel_76" labelStyle="BPMNLabelStyle_1">
<dc:Bounds height="20.0" width="100.0" x="1467.138671875" y="203.10794067382812"/> <dc:Bounds height="20.0" width="100.0" x="1467.138671875" y="603.10791015625"/>
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="ExclusiveGateway_2" id="BPMNShape_ExclusiveGateway_2" isMarkerVisible="true">
<dc:Bounds height="50.0" width="50.0" x="980.0" y="310.0"/>
<bpmndi:BPMNLabel id="BPMNLabel_82" labelStyle="BPMNLabelStyle_1">
<dc:Bounds height="20.0" width="100.0" x="955.0" y="363.0"/>
</bpmndi:BPMNLabel> </bpmndi:BPMNLabel>
</bpmndi:BPMNShape> </bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="IntermediateCatchEvent_10" id="BPMNShape_IntermediateCatchEvent_16"> <bpmndi:BPMNShape bpmnElement="IntermediateCatchEvent_10" id="BPMNShape_IntermediateCatchEvent_16">
@ -1418,89 +1489,65 @@ result.isValid=true;
<di:waypoint x="1805.0" y="323.0"/> <di:waypoint x="1805.0" y="323.0"/>
<di:waypoint x="1805.0" y="283.0"/> <di:waypoint x="1805.0" y="283.0"/>
</bpmndi:BPMNEdge> </bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="SequenceFlow_56" id="BPMNEdge_SequenceFlow_57" sourceElement="BPMNShape_IntermediateCatchEvent_27" targetElement="BPMNShape_ExclusiveGateway_2">
<bpmndi:BPMNLabel id="BPMNLabel_118"/>
<di:waypoint x="893.0" y="335.0"/>
<di:waypoint x="980.0" y="335.0"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="SequenceFlow_19" id="BPMNEdge_SequenceFlow_20" sourceElement="BPMNShape_Task_10" targetElement="BPMNShape_IntermediateCatchEvent_9"> <bpmndi:BPMNEdge bpmnElement="SequenceFlow_19" id="BPMNEdge_SequenceFlow_20" sourceElement="BPMNShape_Task_10" targetElement="BPMNShape_IntermediateCatchEvent_9">
<bpmndi:BPMNLabel id="BPMNLabel_48"/> <bpmndi:BPMNLabel id="BPMNLabel_48"/>
<di:waypoint x="1260.0" y="335.0"/> <di:waypoint x="1260.0" y="335.0"/>
<di:waypoint x="1347.0" y="335.0"/> <di:waypoint x="1347.0" y="335.0"/>
</bpmndi:BPMNEdge> </bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="SequenceFlow_21" id="BPMNEdge_SequenceFlow_21" sourceElement="BPMNShape_IntermediateCatchEvent_9" targetElement="BPMNShape_Task_11"> <bpmndi:BPMNEdge bpmnElement="SequenceFlow_21" id="BPMNEdge_SequenceFlow_21" sourceElement="BPMNShape_IntermediateCatchEvent_9" targetElement="BPMNShape_Task_5">
<bpmndi:BPMNLabel id="BPMNLabel_49"/> <bpmndi:BPMNLabel id="BPMNLabel_49"/>
<di:waypoint x="1383.0" y="335.0"/> <di:waypoint x="1365.0" y="317.0"/>
<di:waypoint x="1630.0" y="335.0"/> <di:waypoint x="1365.0" y="137.0"/>
<di:waypoint x="385.0" y="137.0"/>
<di:waypoint x="385.0" y="310.0"/>
</bpmndi:BPMNEdge> </bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="SequenceFlow_25" id="BPMNEdge_SequenceFlow_26" sourceElement="BPMNShape_Task_10" targetElement="BPMNShape_IntermediateCatchEvent_11"> <bpmndi:BPMNEdge bpmnElement="SequenceFlow_26" id="BPMNEdge_SequenceFlow_27" sourceElement="BPMNShape_IntermediateCatchEvent_11" targetElement="BPMNShape_Task_10">
<bpmndi:BPMNLabel id="BPMNLabel_57"/>
<di:waypoint x="1205.0" y="310.0"/>
<di:waypoint x="1205.0" y="273.0"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="SequenceFlow_26" id="BPMNEdge_SequenceFlow_27" sourceElement="BPMNShape_IntermediateCatchEvent_11" targetElement="BPMNShape_Task_3">
<bpmndi:BPMNLabel id="BPMNLabel_59"/> <bpmndi:BPMNLabel id="BPMNLabel_59"/>
<di:waypoint x="1205.0" y="237.0"/> <di:waypoint x="1205.0" y="263.0"/>
<di:waypoint x="1205.0" y="210.0"/> <di:waypoint x="1205.0" y="310.0"/>
</bpmndi:BPMNEdge> </bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="SequenceFlow_27" id="BPMNEdge_SequenceFlow_28" sourceElement="BPMNShape_EventBasedGateway_1" targetElement="BPMNShape_IntermediateCatchEvent_9"> <bpmndi:BPMNEdge bpmnElement="SequenceFlow_27" id="BPMNEdge_SequenceFlow_28" sourceElement="BPMNShape_EventBasedGateway_1" targetElement="BPMNShape_IntermediateCatchEvent_9">
<bpmndi:BPMNLabel id="BPMNLabel_62"/> <bpmndi:BPMNLabel id="BPMNLabel_62"/>
<di:waypoint x="1365.0" y="210.0"/> <di:waypoint x="1365.0" y="560.0"/>
<di:waypoint x="1365.0" y="263.0"/> <di:waypoint x="1365.0" y="459.0"/>
<di:waypoint x="1365.0" y="317.0"/> <di:waypoint x="1365.0" y="353.0"/>
</bpmndi:BPMNEdge> </bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="Association_5" id="BPMNEdge_Association_5" sourceElement="BPMNShape_TextAnnotation_4" targetElement="BPMNShape_Task_3"> <bpmndi:BPMNEdge bpmnElement="Association_5" id="BPMNEdge_Association_5" sourceElement="BPMNShape_TextAnnotation_4" targetElement="BPMNShape_Task_3">
<bpmndi:BPMNLabel id="BPMNLabel_12"/> <bpmndi:BPMNLabel id="BPMNLabel_12"/>
<di:waypoint x="1240.0" y="112.0"/> <di:waypoint x="1100.0" y="740.0"/>
<di:waypoint x="1209.0" y="112.0"/> <di:waypoint x="1100.0" y="675.0"/>
<di:waypoint x="1209.0" y="160.0"/> <di:waypoint x="1205.0" y="675.0"/>
<di:waypoint x="1205.0" y="610.0"/>
</bpmndi:BPMNEdge> </bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="SequenceFlow_17" id="BPMNEdge_SequenceFlow_18" sourceElement="BPMNShape_IntermediateCatchEvent_14" targetElement="BPMNShape_Task_10"> <bpmndi:BPMNEdge bpmnElement="SequenceFlow_17" id="BPMNEdge_SequenceFlow_18" sourceElement="BPMNShape_IntermediateCatchEvent_14" targetElement="BPMNShape_Task_10">
<bpmndi:BPMNLabel id="BPMNLabel_71"/> <bpmndi:BPMNLabel id="BPMNLabel_71"/>
<di:waypoint x="1205.0" y="427.0"/> <di:waypoint x="1205.0" y="417.0"/>
<di:waypoint x="1205.0" y="360.0"/> <di:waypoint x="1205.0" y="360.0"/>
</bpmndi:BPMNEdge> </bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="SequenceFlow_22" id="BPMNEdge_SequenceFlow_22" sourceElement="BPMNShape_Task_4" targetElement="BPMNShape_EndEvent_2"> <bpmndi:BPMNEdge bpmnElement="SequenceFlow_22" id="BPMNEdge_SequenceFlow_22" sourceElement="BPMNShape_Task_4" targetElement="BPMNShape_EndEvent_2">
<bpmndi:BPMNLabel id="BPMNLabel_73"/> <bpmndi:BPMNLabel id="BPMNLabel_73"/>
<di:waypoint x="1740.0" y="185.0"/> <di:waypoint x="1740.0" y="584.0"/>
<di:waypoint x="1805.0" y="185.0"/> <di:waypoint x="1805.0" y="584.0"/>
<di:waypoint x="1805.0" y="247.0"/> <di:waypoint x="1805.0" y="283.0"/>
</bpmndi:BPMNEdge> </bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="SequenceFlow_23" id="BPMNEdge_SequenceFlow_23" sourceElement="BPMNShape_Task_3" targetElement="BPMNShape_EventBasedGateway_1"> <bpmndi:BPMNEdge bpmnElement="SequenceFlow_23" id="BPMNEdge_SequenceFlow_23" sourceElement="BPMNShape_Task_3" targetElement="BPMNShape_EventBasedGateway_1">
<bpmndi:BPMNLabel id="BPMNLabel_75"/> <bpmndi:BPMNLabel id="BPMNLabel_75"/>
<di:waypoint x="1260.0" y="185.0"/> <di:waypoint x="1260.0" y="585.0"/>
<di:waypoint x="1340.0" y="185.0"/> <di:waypoint x="1340.0" y="585.0"/>
</bpmndi:BPMNEdge> </bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="SequenceFlow_34" id="BPMNEdge_SequenceFlow_35" sourceElement="BPMNShape_EventBasedGateway_1" targetElement="BPMNShape_IntermediateCatchEvent_15"> <bpmndi:BPMNEdge bpmnElement="SequenceFlow_34" id="BPMNEdge_SequenceFlow_35" sourceElement="BPMNShape_EventBasedGateway_1" targetElement="BPMNShape_IntermediateCatchEvent_15">
<bpmndi:BPMNLabel id="BPMNLabel_78"/> <bpmndi:BPMNLabel id="BPMNLabel_78"/>
<di:waypoint x="1390.0" y="185.0"/> <di:waypoint x="1390.0" y="585.0"/>
<di:waypoint x="1497.0" y="185.0"/> <di:waypoint x="1497.0" y="585.0"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="SequenceFlow_36" id="BPMNEdge_SequenceFlow_37" sourceElement="BPMNShape_Task_3" targetElement="BPMNShape_IntermediateCatchEvent_12">
<bpmndi:BPMNLabel id="BPMNLabel_83"/>
<di:waypoint x="1150.0" y="185.0"/>
<di:waypoint x="1113.0" y="185.0"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="SequenceFlow_39" id="BPMNEdge_SequenceFlow_40" sourceElement="BPMNShape_IntermediateCatchEvent_12" targetElement="BPMNShape_ExclusiveGateway_2">
<bpmndi:BPMNLabel id="BPMNLabel_84"/>
<di:waypoint x="1077.0" y="185.0"/>
<di:waypoint x="1006.0" y="185.0"/>
<di:waypoint x="1006.0" y="311.0"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="SequenceFlow_40" id="BPMNEdge_SequenceFlow_41" sourceElement="BPMNShape_ExclusiveGateway_2" targetElement="BPMNShape_Task_10">
<bpmndi:BPMNLabel id="BPMNLabel_87"/>
<di:waypoint x="1030.0" y="335.0"/>
<di:waypoint x="1150.0" y="335.0"/>
</bpmndi:BPMNEdge> </bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="SequenceFlow_41" id="BPMNEdge_SequenceFlow_42" sourceElement="BPMNShape_IntermediateCatchEvent_15" targetElement="BPMNShape_Task_4"> <bpmndi:BPMNEdge bpmnElement="SequenceFlow_41" id="BPMNEdge_SequenceFlow_42" sourceElement="BPMNShape_IntermediateCatchEvent_15" targetElement="BPMNShape_Task_4">
<bpmndi:BPMNLabel id="BPMNLabel_88"/> <bpmndi:BPMNLabel id="BPMNLabel_88"/>
<di:waypoint x="1533.0" y="185.0"/> <di:waypoint x="1533.0" y="585.0"/>
<di:waypoint x="1630.0" y="185.0"/> <di:waypoint x="1630.0" y="585.0"/>
</bpmndi:BPMNEdge> </bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="SequenceFlow_42" id="BPMNEdge_SequenceFlow_43" sourceElement="BPMNShape_IntermediateCatchEvent_16" targetElement="BPMNShape_Task_9"> <bpmndi:BPMNEdge bpmnElement="SequenceFlow_42" id="BPMNEdge_SequenceFlow_43" sourceElement="BPMNShape_IntermediateCatchEvent_16" targetElement="BPMNShape_Task_9">
<bpmndi:BPMNLabel id="BPMNLabel_94"/> <bpmndi:BPMNLabel id="BPMNLabel_94"/>
<di:waypoint x="725.0" y="427.0"/> <di:waypoint x="725.0" y="427.0"/>
<di:waypoint x="725.0" y="395.0"/>
<di:waypoint x="725.0" y="360.0"/> <di:waypoint x="725.0" y="360.0"/>
</bpmndi:BPMNEdge> </bpmndi:BPMNEdge>
<bpmndi:BPMNShape bpmnElement="message_1" id="BPMNShape_5X9D7w"> <bpmndi:BPMNShape bpmnElement="message_1" id="BPMNShape_5X9D7w">
@ -1510,7 +1557,7 @@ result.isValid=true;
</bpmndi:BPMNLabel> </bpmndi:BPMNLabel>
</bpmndi:BPMNShape> </bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="textAnnotation_JTmRrA" id="BPMNShape_RE0Y6A"> <bpmndi:BPMNShape bpmnElement="textAnnotation_JTmRrA" id="BPMNShape_RE0Y6A">
<dc:Bounds height="72.0" width="203.0" x="190.0" y="130.0"/> <dc:Bounds height="72.0" width="203.0" x="180.0" y="440.0"/>
</bpmndi:BPMNShape> </bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="event_oeP3WQ" id="BPMNShape_5wLVcQ"> <bpmndi:BPMNShape bpmnElement="event_oeP3WQ" id="BPMNShape_5wLVcQ">
<dc:Bounds height="36.0" width="36.0" x="277.0" y="317.0"/> <dc:Bounds height="36.0" width="36.0" x="277.0" y="317.0"/>
@ -1570,20 +1617,20 @@ result.isValid=true;
<di:waypoint x="563.0" y="335.0"/> <di:waypoint x="563.0" y="335.0"/>
<di:waypoint x="670.0" y="335.0"/> <di:waypoint x="670.0" y="335.0"/>
</bpmndi:BPMNEdge> </bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="sequenceFlow_HCxYvw" id="BPMNEdge_HrTn1A" sourceElement="BPMNShape_Task_9" targetElement="BPMNShape_IntermediateCatchEvent_27"> <bpmndi:BPMNEdge bpmnElement="sequenceFlow_HCxYvw" id="BPMNEdge_HrTn1A" sourceElement="BPMNShape_Task_9" targetElement="BPMNShape_Pgpsrw">
<di:waypoint x="780.0" y="335.0"/> <di:waypoint x="780.0" y="335.0"/>
<di:waypoint x="857.0" y="335.0"/> <di:waypoint x="880.0" y="335.0"/>
</bpmndi:BPMNEdge> </bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="association_haKP7Q" id="BPMNEdge_KUecbw" sourceElement="BPMNShape_RE0Y6A" targetElement="BPMNShape_5wLVcQ"> <bpmndi:BPMNEdge bpmnElement="association_haKP7Q" id="BPMNEdge_KUecbw" sourceElement="BPMNShape_RE0Y6A" targetElement="BPMNShape_5wLVcQ">
<di:waypoint x="292.0" y="202.0"/> <di:waypoint x="282.0" y="440.0"/>
<di:waypoint x="292.0" y="260.0"/> <di:waypoint x="282.0" y="398.0"/>
<di:waypoint x="295.0" y="260.0"/> <di:waypoint x="295.0" y="398.0"/>
<di:waypoint x="295.0" y="317.0"/> <di:waypoint x="295.0" y="353.0"/>
</bpmndi:BPMNEdge> </bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="association_BseA8A" id="BPMNEdge_E3SzCA" sourceElement="BPMNShape_DataObject_1" targetElement="BPMNShape_Task_9"> <bpmndi:BPMNEdge bpmnElement="association_BseA8A" id="BPMNEdge_E3SzCA" sourceElement="BPMNShape_DataObject_1" targetElement="BPMNShape_Task_9">
<di:waypoint x="605.0" y="205.0"/> <di:waypoint x="605.0" y="205.0"/>
<di:waypoint x="728.0" y="205.0"/> <di:waypoint x="695.0" y="205.0"/>
<di:waypoint x="728.0" y="310.0"/> <di:waypoint x="695.0" y="310.0"/>
</bpmndi:BPMNEdge> </bpmndi:BPMNEdge>
<bpmndi:BPMNShape bpmnElement="event_jBz77w" id="BPMNShape_MQkY4w"> <bpmndi:BPMNShape bpmnElement="event_jBz77w" id="BPMNShape_MQkY4w">
<dc:Bounds height="36.0" width="36.0" x="797.0" y="427.0"/> <dc:Bounds height="36.0" width="36.0" x="797.0" y="427.0"/>
@ -1594,8 +1641,8 @@ result.isValid=true;
<bpmndi:BPMNEdge bpmnElement="sequenceFlow_kvvOjA" id="BPMNEdge_St0T1w" sourceElement="BPMNShape_MQkY4w" targetElement="BPMNShape_Task_9"> <bpmndi:BPMNEdge bpmnElement="sequenceFlow_kvvOjA" id="BPMNEdge_St0T1w" sourceElement="BPMNShape_MQkY4w" targetElement="BPMNShape_Task_9">
<di:waypoint x="815.0" y="427.0"/> <di:waypoint x="815.0" y="427.0"/>
<di:waypoint x="815.0" y="394.0"/> <di:waypoint x="815.0" y="394.0"/>
<di:waypoint x="761.0" y="394.0"/> <di:waypoint x="762.0" y="394.0"/>
<di:waypoint x="761.0" y="360.0"/> <di:waypoint x="762.0" y="360.0"/>
</bpmndi:BPMNEdge> </bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="association_SjKymg" id="BPMNEdge_mSixYw" sourceElement="BPMNShape_3PbNFQ" targetElement="BPMNShape_MQkY4w"> <bpmndi:BPMNEdge bpmnElement="association_SjKymg" id="BPMNEdge_mSixYw" sourceElement="BPMNShape_3PbNFQ" targetElement="BPMNShape_MQkY4w">
<di:waypoint x="548.0" y="470.0"/> <di:waypoint x="548.0" y="470.0"/>
@ -1603,6 +1650,41 @@ result.isValid=true;
<di:waypoint x="815.0" y="533.0"/> <di:waypoint x="815.0" y="533.0"/>
<di:waypoint x="815.0" y="463.0"/> <di:waypoint x="815.0" y="463.0"/>
</bpmndi:BPMNEdge> </bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="sequenceFlow_2pAPvA" id="BPMNEdge_o1hQ3A" sourceElement="BPMNShape_IntermediateCatchEvent_12" targetElement="BPMNShape_Task_3">
<di:waypoint x="1255.0" y="657.0"/>
<di:waypoint x="1255.0" y="634.0"/>
<di:waypoint x="1205.0" y="634.0"/>
<di:waypoint x="1205.0" y="610.0"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape bpmnElement="gateway_cDqotg" id="BPMNShape_Pgpsrw">
<dc:Bounds height="50.0" width="50.0" x="880.0" y="310.0"/>
<bpmndi:BPMNLabel id="BPMNLabel_UYr0pg">
<dc:Bounds height="20.0" width="100.0" x="855.0" y="363.0"/>
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge bpmnElement="sequenceFlow_Hq0Ccg" id="BPMNEdge_eyV1jw" sourceElement="BPMNShape_Pgpsrw" targetElement="BPMNShape_IntermediateCatchEvent_27">
<di:waypoint x="930.0" y="335.0"/>
<di:waypoint x="997.0" y="335.0"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="sequenceFlow_8XT0hw" id="BPMNEdge_e4lMzA" sourceElement="BPMNShape_IntermediateCatchEvent_27" targetElement="BPMNShape_Task_10">
<di:waypoint x="1033.0" y="335.0"/>
<di:waypoint x="1150.0" y="335.0"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape bpmnElement="event_k2i6EQ" id="BPMNShape_mXI8kQ">
<dc:Bounds height="36.0" width="36.0" x="997.0" y="567.0"/>
<bpmndi:BPMNLabel id="BPMNLabel_eW520g">
<dc:Bounds height="20.0" width="100.0" x="965.0" y="606.0"/>
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge bpmnElement="sequenceFlow_Jkgs0A" id="BPMNEdge_ur6coA" sourceElement="BPMNShape_Pgpsrw" targetElement="BPMNShape_mXI8kQ">
<di:waypoint x="903.0" y="358.0"/>
<di:waypoint x="903.0" y="585.0"/>
<di:waypoint x="997.0" y="585.0"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="sequenceFlow_RgOnDQ" id="BPMNEdge_Qxfu4Q" sourceElement="BPMNShape_mXI8kQ" targetElement="BPMNShape_Task_3">
<di:waypoint x="1033.0" y="585.0"/>
<di:waypoint x="1150.0" y="585.0"/>
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane> </bpmndi:BPMNPlane>
<bpmndi:BPMNLabelStyle id="BPMNLabelStyle_1"> <bpmndi:BPMNLabelStyle id="BPMNLabelStyle_1">
<dc:Font name="arial" size="9.0"/> <dc:Font name="arial" size="9.0"/>