cassandra setup and docu
This commit is contained in:
parent
a7aade03b7
commit
36f06a6d6a
3 changed files with 149 additions and 182 deletions
49
doc/CASSANDRA.md
Normal file
49
doc/CASSANDRA.md
Normal file
|
|
@ -0,0 +1,49 @@
|
||||||
|
# Cassandra RAG Database
|
||||||
|
|
||||||
|
The Cassandra database used by dynamixs.ai is created automatically during startup. This includes the Cassandra keyspace as also the data base schema.
|
||||||
|
Aside from that, the Cassandra cluster can also be managed through the Command Line Console (CLI).
|
||||||
|
|
||||||
|
## Using the Cassandra CLI
|
||||||
|
|
||||||
|
To connect to your cluster you can use the cqlsh tool.
|
||||||
|
To run cqlsh from your started docker environment run:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ docker exec -it cassandra cqlsh
|
||||||
|
Connected to dynamixsAiCluster at 127.0.0.1:9042
|
||||||
|
[cqlsh 6.2.0 | Cassandra 5.0.4 | CQL spec 3.4.7 | Native protocol v5]
|
||||||
|
Use HELP for help.
|
||||||
|
cqlsh>
|
||||||
|
```
|
||||||
|
|
||||||
|
## CQL Examples
|
||||||
|
|
||||||
|
The following section contains some basic cqlsh commands. For full description see the [Cassandra CQL refernce](https://docs.datastax.com/en/dse/6.0/cql/).
|
||||||
|
|
||||||
|
**show key spaces:**
|
||||||
|
|
||||||
|
Show all available keyspaces:
|
||||||
|
|
||||||
|
cqlsh> DESC KEYSPACES;
|
||||||
|
|
||||||
|
**Switch to Keysapce:**
|
||||||
|
|
||||||
|
Select a keyspace be name to interact with this keyspace:
|
||||||
|
|
||||||
|
cqlsh> use embeddings;
|
||||||
|
|
||||||
|
**Show tables in a keyspace:**
|
||||||
|
|
||||||
|
Show tables schemas in current keyspace:
|
||||||
|
|
||||||
|
cqlsh:embeddings> DESC TABLES;
|
||||||
|
|
||||||
|
**Drop Keyspace:**
|
||||||
|
|
||||||
|
Drop the keyspace:
|
||||||
|
|
||||||
|
DROP KEYSPACE IF EXISTS <keyspace_name>;
|
||||||
|
|
||||||
|
### Create a dev keyspace with cqlsh
|
||||||
|
|
||||||
|
cqlsh> CREATE KEYSPACE <keyspace_name> WITH replication = {'class': 'SimpleStrategy', 'replication_factor': 1};
|
||||||
|
|
@ -12,6 +12,7 @@ import org.eclipse.microprofile.config.inject.ConfigProperty;
|
||||||
|
|
||||||
import com.datastax.oss.driver.api.core.CqlSession;
|
import com.datastax.oss.driver.api.core.CqlSession;
|
||||||
import com.datastax.oss.driver.api.core.CqlSessionBuilder;
|
import com.datastax.oss.driver.api.core.CqlSessionBuilder;
|
||||||
|
import com.datastax.oss.driver.api.core.InvalidKeyspaceException;
|
||||||
import com.datastax.oss.driver.api.core.cql.BoundStatement;
|
import com.datastax.oss.driver.api.core.cql.BoundStatement;
|
||||||
import com.datastax.oss.driver.api.core.cql.PreparedStatement;
|
import com.datastax.oss.driver.api.core.cql.PreparedStatement;
|
||||||
import com.datastax.oss.driver.api.core.servererrors.InvalidQueryException;
|
import com.datastax.oss.driver.api.core.servererrors.InvalidQueryException;
|
||||||
|
|
@ -131,12 +132,12 @@ public class ClusterService {
|
||||||
*/
|
*/
|
||||||
private void scheduleClusterCheck() {
|
private void scheduleClusterCheck() {
|
||||||
try {
|
try {
|
||||||
logger.log(Level.INFO, "├── Connecting Cassandra cluster...");
|
logger.log(Level.INFO, "├── connecting Cassandra cluster...");
|
||||||
getSession();
|
getSession();
|
||||||
logger.log(Level.INFO, "├── ✅ Successfully connected to Cassandra!");
|
logger.log(Level.INFO, "├── ✅ successfully connected to cassandra!");
|
||||||
} catch (ClusterException e) {
|
} catch (ClusterException e) {
|
||||||
logger.log(Level.WARNING, "├── " + e.getMessage());
|
logger.log(Level.WARNING, "├── " + e.getMessage());
|
||||||
logger.log(Level.WARNING, "├── ⚠️ Cluster not ready yet. Retrying in 10 seconds...");
|
logger.log(Level.WARNING, "├── ⚠️ cluster not ready yet. retrying in 10 seconds...");
|
||||||
// retry in 10 sec
|
// retry in 10 sec
|
||||||
timerService.createSingleActionTimer(10000, new TimerConfig());
|
timerService.createSingleActionTimer(10000, new TimerConfig());
|
||||||
}
|
}
|
||||||
|
|
@ -174,12 +175,9 @@ public class ClusterService {
|
||||||
public CqlSession getSession() throws ClusterException {
|
public CqlSession getSession() throws ClusterException {
|
||||||
if (session == null) {
|
if (session == null) {
|
||||||
try {
|
try {
|
||||||
logger.info("├── initializing cluster...");
|
logger.info("├── initializing cluster and keyspace...");
|
||||||
session = initSession();
|
session = initSessionWithKeyspace();
|
||||||
if (session != null) {
|
logger.info("│ ├── ✅ schema status = OK");
|
||||||
logger.info("│ ├── keySpace connection status = OK");
|
|
||||||
initKeySpace();
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new ClusterException(ClusterException.CLUSTER_ERROR,
|
throw new ClusterException(ClusterException.CLUSTER_ERROR,
|
||||||
"Failed to init cassandra session: " + e.getMessage(), e);
|
"Failed to init cassandra session: " + e.getMessage(), e);
|
||||||
|
|
@ -189,32 +187,38 @@ public class ClusterService {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a cassandra session for the archive KeySpace. The keyspace is defined
|
* This method opens the configured keyspace. If the keyspace does no yet exist
|
||||||
* by the environmetn variable EMBEDDINGS__CLUSTER_KEYSPACE. If no keyspace with
|
* it creates a new keyspace with the table schema
|
||||||
* this given keyspace name exists, the method creates the keyspace and table
|
|
||||||
* schemas.
|
|
||||||
*
|
*
|
||||||
* @throws ArchiveException
|
* @return
|
||||||
|
* @throws ClusterException
|
||||||
*/
|
*/
|
||||||
private void initKeySpace() throws ClusterException {
|
private CqlSession initSessionWithKeyspace() throws ClusterException {
|
||||||
String keySpacename = keySpace.orElse(null);
|
// validate keyspace name
|
||||||
if (keySpacename == null) {
|
String keySpacename = keySpace.orElseThrow(
|
||||||
throw new ClusterException(ClusterException.INVALID_KEYSPACE, "EMBEDDINGS_CLUSTER_KEYSPACE not set!");
|
() -> new ClusterException(ClusterException.INVALID_KEYSPACE, "EMBEDDINGS_CLUSTER_KEYSPACE not set!"));
|
||||||
}
|
|
||||||
if (!isValidKeyspaceName(keySpacename)) {
|
if (!isValidKeyspaceName(keySpacename)) {
|
||||||
throw new ClusterException(ClusterException.INVALID_KEYSPACE,
|
throw new ClusterException(ClusterException.INVALID_KEYSPACE,
|
||||||
"keyspace '" + keySpacename + "' name invalid.");
|
"keyspace '" + keySpacename + "' name invalid.");
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.info("│ ├── connecting keyspace='" + keySpacename + "'...");
|
|
||||||
// try to open keySpace
|
|
||||||
try {
|
try {
|
||||||
// session = cluster.connect(keySpace.get());
|
// try to connect keyspace ...
|
||||||
} catch (InvalidQueryException e) {
|
session = createSession(keySpacename);
|
||||||
logger.warning("......connecting keySpace '" + keySpacename + "' failed: " + e.getMessage());
|
logger.info("│ ├── ✅ keyspace status = OK");
|
||||||
|
return session;
|
||||||
|
} catch (InvalidQueryException | InvalidKeyspaceException e) {
|
||||||
|
logger.warning("│ ├── ⚠️ Keyspace does not yet exist, creating new keyspace...");
|
||||||
|
// Create a basic session object to create the keyspace....
|
||||||
|
session = createSession(null);
|
||||||
createKeySpace(keySpacename);
|
createKeySpace(keySpacename);
|
||||||
|
// close and reconnect session...
|
||||||
|
session.close();
|
||||||
|
session = createSession(keySpacename);
|
||||||
|
createSchema();
|
||||||
|
return session;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -226,7 +230,9 @@ public class ClusterService {
|
||||||
* @return Cassandra Cluster instacne
|
* @return Cassandra Cluster instacne
|
||||||
* @throws ArchiveException
|
* @throws ArchiveException
|
||||||
*/
|
*/
|
||||||
protected CqlSession initSession() throws ClusterException {
|
|
||||||
|
private CqlSession createSession(String keyspace) throws ClusterException {
|
||||||
|
CqlSessionBuilder builder = CqlSession.builder();
|
||||||
// Boolean used to check if at least one host could be resolved
|
// Boolean used to check if at least one host could be resolved
|
||||||
boolean found = false;
|
boolean found = false;
|
||||||
|
|
||||||
|
|
@ -236,8 +242,6 @@ public class ClusterService {
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.info("│ ├── cluster connecting: " + contactPoint.get());
|
logger.info("│ ├── cluster connecting: " + contactPoint.get());
|
||||||
|
|
||||||
CqlSessionBuilder builder = CqlSession.builder();
|
|
||||||
String[] hosts = contactPoint.get().split(",");
|
String[] hosts = contactPoint.get().split(",");
|
||||||
for (String host : hosts) {
|
for (String host : hosts) {
|
||||||
try {
|
try {
|
||||||
|
|
@ -254,96 +258,18 @@ public class ClusterService {
|
||||||
// No host could be resolved so we throw an exception
|
// No host could be resolved so we throw an exception
|
||||||
throw new IllegalStateException("All provided hosts are unknown - check cluster status and configuration!");
|
throw new IllegalStateException("All provided hosts are unknown - check cluster status and configuration!");
|
||||||
}
|
}
|
||||||
|
|
||||||
// builder.withLoadBalancingPolicy(new RoundRobinPolicy());
|
|
||||||
// builder.withRetryPolicy(DefaultRetryPolicy.INSTANCE);
|
|
||||||
|
|
||||||
// set optional credentials...
|
// set optional credentials...
|
||||||
if (userid.isPresent() && !userid.get().isEmpty()) {
|
if (userid.isPresent() && !userid.get().isEmpty()) {
|
||||||
builder = builder.withAuthCredentials(userid.get(), password.get());
|
builder = builder.withAuthCredentials(userid.get(), password.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
// use SSL ?
|
if (keyspace != null) {
|
||||||
// if (bUseSSL) {
|
builder.withKeyspace(keyspace);
|
||||||
// try {
|
}
|
||||||
// // create ssl options based on environment settings...
|
|
||||||
// SSLOptions options = createSSLOptions();
|
|
||||||
// logger.info("...creating SSL cluster session...");
|
|
||||||
// builder.withSSL(options);
|
|
||||||
// } catch (KeyManagementException | UnrecoverableKeyException |
|
|
||||||
// KeyStoreException | NoSuchAlgorithmException
|
|
||||||
// | CertificateException | IOException e) {
|
|
||||||
// logger.severe("Failed to connect withSSL: " + e.getMessage());
|
|
||||||
// e.printStackTrace();
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
builder.withLocalDatacenter("datacenter1");
|
builder.withLocalDatacenter("datacenter1");
|
||||||
return builder.build();
|
return builder.build();
|
||||||
// cluster = builder.build();
|
|
||||||
// cluster.init();
|
|
||||||
// logger.info("...cluster conection status = OK");
|
|
||||||
|
|
||||||
// return cluster;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper Method to generate sslOpens object for cassandra dataStax driver
|
|
||||||
* withSSL.
|
|
||||||
* <p>
|
|
||||||
* At least the truststorePath is needed to establish a one way SSL connection.
|
|
||||||
* <p>
|
|
||||||
* The keystorePath is only needed in case 'require_client_auth = true' is set
|
|
||||||
* in the cassandra.yaml file
|
|
||||||
*
|
|
||||||
* @return sslOptons
|
|
||||||
* @throws KeyStoreException
|
|
||||||
* @throws FileNotFoundException
|
|
||||||
* @throws IOException
|
|
||||||
* @throws NoSuchAlgorithmException
|
|
||||||
* @throws KeyManagementException
|
|
||||||
* @throws CertificateException
|
|
||||||
* @throws UnrecoverableKeyException
|
|
||||||
*/
|
|
||||||
// private SSLOptions createSSLOptions() throws KeyStoreException,
|
|
||||||
// FileNotFoundException, IOException,
|
|
||||||
// NoSuchAlgorithmException, KeyManagementException, CertificateException,
|
|
||||||
// UnrecoverableKeyException {
|
|
||||||
|
|
||||||
// TrustManagerFactory tmf = null;
|
|
||||||
// if (truststorePath.isPresent() && !truststorePath.get().isEmpty()) {
|
|
||||||
// KeyStore tks = KeyStore.getInstance("JKS");
|
|
||||||
// tks.load((InputStream) new FileInputStream(new File(truststorePath.get())),
|
|
||||||
// truststorePwd.get().toCharArray());
|
|
||||||
// tmf =
|
|
||||||
// TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
|
|
||||||
// tmf.init(tks);
|
|
||||||
// } else {
|
|
||||||
// logger.info("SSLOptions without truststore...");
|
|
||||||
// }
|
|
||||||
|
|
||||||
// KeyManagerFactory kmf = null;
|
|
||||||
// if (keystorePath.isPresent() && !keystorePath.get().isEmpty()) {
|
|
||||||
// KeyStore kks = KeyStore.getInstance("JKS");
|
|
||||||
// kks.load((InputStream) new FileInputStream(new File(keystorePath.get())),
|
|
||||||
// keystorePwd.get().toCharArray());
|
|
||||||
// kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
|
|
||||||
// kmf.init(kks, keystorePwd.get().toCharArray());
|
|
||||||
// } else {
|
|
||||||
// logger.info("SSLOptions without keystore...");
|
|
||||||
// }
|
|
||||||
|
|
||||||
// SSLContext sslContext = SSLContext.getInstance("TLS");
|
|
||||||
// sslContext.init(kmf != null ? kmf.getKeyManagers() : null, tmf != null ?
|
|
||||||
// tmf.getTrustManagers() : null,
|
|
||||||
// new SecureRandom());
|
|
||||||
// RemoteEndpointAwareJdkSSLOptions sslOptions =
|
|
||||||
// RemoteEndpointAwareJdkSSLOptions.builder()
|
|
||||||
// .withSSLContext(sslContext).build();
|
|
||||||
// return sslOptions;
|
|
||||||
// }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test if the keyspace name is valid.
|
* Test if the keyspace name is valid.
|
||||||
*
|
*
|
||||||
|
|
@ -354,46 +280,37 @@ public class ClusterService {
|
||||||
if (keySpace == null || keySpace.isEmpty()) {
|
if (keySpace == null || keySpace.isEmpty()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return keySpace.matches(KEYSPACE_REGEX);
|
return keySpace.matches(KEYSPACE_REGEX);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method creates a cassandra keySpace.
|
* This method creates a cassandra keySpace
|
||||||
* <p>
|
|
||||||
* Depending on the KeyspaceType, the method creates the core table schema to
|
|
||||||
* store configurations, or the extended Archive table schcema which is used to
|
|
||||||
* store imixs documents.
|
|
||||||
*
|
*
|
||||||
* @param cluster
|
* @param cluster
|
||||||
* @throws ArchiveException
|
* @throws ArchiveException
|
||||||
*/
|
*/
|
||||||
protected void createKeySpace(String keySpace) throws ClusterException {
|
private void createKeySpace(String keySpace) throws ClusterException {
|
||||||
logger.info("│ ├── creating new keyspace '" + keySpace + "'...");
|
logger.info("│ ├── creating new keyspace '" + keySpace + "'...");
|
||||||
|
|
||||||
String statement = "CREATE KEYSPACE IF NOT EXISTS " + keySpace + " WITH replication = {'class': '" + repClass
|
String statement = "CREATE KEYSPACE IF NOT EXISTS " + keySpace + " WITH replication = {'class': '" + repClass
|
||||||
+ "', 'replication_factor': " + repFactor + "};";
|
+ "', 'replication_factor': " + repFactor + "};";
|
||||||
|
|
||||||
session.execute(statement);
|
session.execute(statement);
|
||||||
logger.info("│ ├── keyspace created...");
|
logger.info("│ ├── ✅ keyspace '" + keySpace + "' created.");
|
||||||
if (session != null) {
|
|
||||||
logger.info("│ ├── create schema...");
|
|
||||||
// now create table schemas
|
|
||||||
createArchiveTableSchema();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This helper method creates the ImixsArchive document table schema if not yet
|
* This method creates the keySpace schema.
|
||||||
* exists
|
*
|
||||||
|
* @param cluster
|
||||||
|
* @throws ArchiveException
|
||||||
*/
|
*/
|
||||||
protected void createArchiveTableSchema() {
|
private void createSchema() throws ClusterException {
|
||||||
|
|
||||||
logger.info("│ ├── Create Data Table...");
|
logger.info("│ ├── create schema...");
|
||||||
|
// now create table schemas
|
||||||
String query = "CREATE TABLE IF NOT EXISTS embeddings.document_vectors (\n" + //
|
String query = "CREATE TABLE IF NOT EXISTS document_vectors (\n" + //
|
||||||
" record_id timeuuid,\n" + //
|
" record_id timeuuid,\n" + //
|
||||||
" id uuid,\n" + //
|
" id uuid,\n" + //
|
||||||
" content_chunk text,\n" + //
|
" content_chunk text,\n" + //
|
||||||
|
|
@ -404,26 +321,24 @@ public class ClusterService {
|
||||||
"WITH CLUSTERING ORDER BY (created_at DESC);";
|
"WITH CLUSTERING ORDER BY (created_at DESC);";
|
||||||
session.execute(query);
|
session.execute(query);
|
||||||
|
|
||||||
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 embeddings.document_vectors(content_vector) USING 'sai';";
|
" ON document_vectors(content_vector) USING 'sai';";
|
||||||
|
|
||||||
session.execute(query);
|
session.execute(query);
|
||||||
|
logger.info("│ ├── ✅ database schema created.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void insertVector(String content, float[] vector) {
|
public void insertVector(String content, float[] vector) throws ClusterException {
|
||||||
|
String keySpacename = keySpace.orElse(null);
|
||||||
|
try {
|
||||||
// Generiere UUID und aktuelle Zeit
|
// Generiere UUID und aktuelle Zeit
|
||||||
UUID id = UUID.randomUUID();
|
UUID id = UUID.randomUUID();
|
||||||
Instant createdAt = Instant.now();
|
Instant createdAt = Instant.now();
|
||||||
|
|
||||||
// CQL-Query mit Platzhaltern
|
// CQL-Query mit Platzhaltern
|
||||||
String insertQuery = """
|
String insertQuery = "INSERT INTO " + keySpacename + ".document_vectors "
|
||||||
INSERT INTO embeddings.document_vectors
|
+ "(record_id, id, content_chunk, content_vector, created_at) VALUES (now(), ?, ?, ?, ?)";
|
||||||
(record_id, id, content_chunk, content_vector, created_at)
|
|
||||||
VALUES (now(), ?, ?, ?, ?)
|
|
||||||
""";
|
|
||||||
|
|
||||||
// Vorbereiten und Ausführen der Query
|
// Vorbereiten und Ausführen der Query
|
||||||
PreparedStatement preparedStmt = session.prepare(insertQuery);
|
PreparedStatement preparedStmt = session.prepare(insertQuery);
|
||||||
|
|
@ -446,6 +361,11 @@ public class ClusterService {
|
||||||
// content_vector,
|
// content_vector,
|
||||||
// created_at
|
// created_at
|
||||||
// ])
|
// ])
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new ClusterException(ClusterException.CLUSTER_ERROR,
|
||||||
|
"Failed to insert embeddings into keyspace: " + e.getMessage(), e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,6 @@ import java.util.logging.Logger;
|
||||||
|
|
||||||
import org.eclipse.microprofile.config.inject.ConfigProperty;
|
import org.eclipse.microprofile.config.inject.ConfigProperty;
|
||||||
import org.imixs.ai.workflow.ImixsAIPromptEvent;
|
import org.imixs.ai.workflow.ImixsAIPromptEvent;
|
||||||
import org.imixs.ai.workflow.OpenAIAPIAdapter;
|
|
||||||
import org.imixs.ai.workflow.OpenAIAPIService;
|
import org.imixs.ai.workflow.OpenAIAPIService;
|
||||||
import org.imixs.workflow.ItemCollection;
|
import org.imixs.workflow.ItemCollection;
|
||||||
import org.imixs.workflow.SignalAdapter;
|
import org.imixs.workflow.SignalAdapter;
|
||||||
|
|
@ -156,8 +155,6 @@ public class RAGAdapter implements SignalAdapter {
|
||||||
public ItemCollection execute(ItemCollection workitem, ItemCollection event)
|
public ItemCollection execute(ItemCollection workitem, ItemCollection event)
|
||||||
throws AdapterException, PluginException {
|
throws AdapterException, PluginException {
|
||||||
String llmAPIEndpoint = null;
|
String llmAPIEndpoint = null;
|
||||||
String llmAPIResultEvent = null;
|
|
||||||
String llmAPIResultItem = null;
|
|
||||||
boolean llmAPIDebug = false;
|
boolean llmAPIDebug = false;
|
||||||
long processingTime = System.currentTimeMillis();
|
long processingTime = System.currentTimeMillis();
|
||||||
|
|
||||||
|
|
@ -176,17 +173,17 @@ public class RAGAdapter implements SignalAdapter {
|
||||||
llmAPIEndpoint = parseLLMEndpointByBPMN(indexDefinition);
|
llmAPIEndpoint = parseLLMEndpointByBPMN(indexDefinition);
|
||||||
// do we have a valid endpoint?
|
// do we have a valid endpoint?
|
||||||
if (llmAPIEndpoint == null || llmAPIEndpoint.isEmpty()) {
|
if (llmAPIEndpoint == null || llmAPIEndpoint.isEmpty()) {
|
||||||
throw new PluginException(OpenAIAPIAdapter.class.getSimpleName(), API_ERROR,
|
throw new PluginException(RAGAdapter.class.getSimpleName(), API_ERROR,
|
||||||
"imixs-ai configuration error: no llm service endpoint defined!");
|
"imixs-ai configuration error: no llm service endpoint defined!");
|
||||||
}
|
}
|
||||||
if ("true".equalsIgnoreCase(indexDefinition.getItemValueString("debug"))) {
|
if ("true".equalsIgnoreCase(indexDefinition.getItemValueString("debug"))) {
|
||||||
llmAPIDebug = true;
|
llmAPIDebug = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.info("post Llama-cpp request: " + llmAPIEndpoint);
|
logger.info("├── post Llama-cpp request: " + llmAPIEndpoint);
|
||||||
|
|
||||||
String promptTemplate = llmService.loadPromptTemplate(event);
|
String promptTemplate = llmService.loadPromptTemplate(event);
|
||||||
logger.info("===> PromptTemplate: ");
|
logger.info("│ ├── PromptTemplate: ");
|
||||||
logger.info(promptTemplate);
|
logger.info(promptTemplate);
|
||||||
|
|
||||||
String llmPrompt = llmService.buildPrompt(promptTemplate, workitem);
|
String llmPrompt = llmService.buildPrompt(promptTemplate, workitem);
|
||||||
|
|
@ -198,28 +195,29 @@ public class RAGAdapter implements SignalAdapter {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (llmAPIDebug) {
|
if (llmAPIDebug) {
|
||||||
logger.info("===> Total Prompt Length = " + llmPrompt.length());
|
logger.info("│ ├── Total Prompt Length = " + llmPrompt.length());
|
||||||
logger.info("===> Prompt: ");
|
logger.info("│ ├── Prompt: ");
|
||||||
logger.info(llmPrompt);
|
logger.info(llmPrompt);
|
||||||
}
|
}
|
||||||
|
|
||||||
float[] indexResult = llmService.postEmbedding(llmPrompt, llmAPIEndpoint);
|
float[] indexResult = llmService.postEmbedding(llmPrompt, llmAPIEndpoint, llmAPIDebug);
|
||||||
|
|
||||||
// clusterService.insertVector
|
// write to cassandra
|
||||||
logger.info("POST result: " + indexResult);
|
clusterService.insertVector(promptTemplate, indexResult);
|
||||||
logger.info("result size= " + indexResult.length);
|
|
||||||
|
if (llmAPIDebug) {
|
||||||
|
logger.info("├── ✅ " + indexResult.length + " floats stored in RAG db.");
|
||||||
|
logger.info(
|
||||||
|
"├── ✅ Total processing time: " + (System.currentTimeMillis() - processingTime) + "ms");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (PluginException e) {
|
} catch (PluginException e) {
|
||||||
logger.severe("Unable to parse item definitions for 'imixs-ai', verify model - " + e.getMessage());
|
logger.severe("├── ⚠️ Failed to post embeddings: " + e.getMessage());
|
||||||
throw new PluginException(
|
throw e;
|
||||||
RAGAdapter.class.getSimpleName(), e.getErrorCode(),
|
} catch (ClusterException e) {
|
||||||
"Unable to parse item definitions for 'imixs-ai', verify model - " + e.getMessage(), e);
|
throw new PluginException(RAGAdapter.class.getSimpleName(), API_ERROR, e.getMessage(), e);
|
||||||
}
|
|
||||||
|
|
||||||
if (llmAPIDebug) {
|
|
||||||
logger.info("===> Total Processing Time=" + (System.currentTimeMillis() - processingTime) + "ms");
|
|
||||||
}
|
}
|
||||||
return workitem;
|
return workitem;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue