Developer Guide
For developers building or packaging the connector, or reasoning about its runtime behavior. For day-to-day modeling, see Configuring the Agent.
Module layout & dependency footprint
The connector is the Maven module org.cibseven.connect:cibseven-connect-ai-agent (under the
cibseven-connect-root parent), compiled for Java 17 (required by LangChain4j). Source layout:
connect/ai-agent/
src/main/java/org/cibseven/connect/ai/agent/ # public API: AgentConnector, AgentRequest/Response,
# KnowledgeIngestor*, AgentConnectorConstants
.../impl/ # AgentConnectorImpl, AgentChatListener,
# AgentChatMemoryStore, ProcessStarterTool, …
src/main/resources/element-templates/*.json # the two element templates
src/main/resources/org/cibseven/connect/ai/agent/default-instruction.txt
src/main/resources/META-INF/services/…ConnectorProvider
Key dependencies (the “weight” behind the removable overlay):
| Dependency | Role |
|---|---|
langchain4j (1.14) |
Agent loop, tools, RAG plumbing |
langchain4j-open-ai |
OpenAI-compatible chat + embedding + Responses API |
langchain4j-agentic-mcp |
MCP client / transport |
langchain4j-embeddings-all-minilm-l6-v2 |
Local 384-dim embedding model (bundled ONNX) |
langchain4j-pgvector |
pgvector embedding store |
langchain4j-document-parser-apache-pdfbox |
PDF parsing for the ingestor CLI |
cibseven-connect-core |
The Connect SPI it implements |
cibseven-engine (provided) |
Engine APIs for ProcessStarterTool / audit context |
Connect SPI & registration
Both connectors are plain CIB seven connectors registered through the ConnectorProvider SPI via
META-INF/services/org.cibseven.connect.spi.ConnectorProvider:
org.cibseven.connect.ai.agent.impl.AgentConnectorProviderImpl
org.cibseven.connect.ai.agent.impl.KnowledgeIngestorProviderImpl
The implementations extend AbstractConnector and are discovered by the engine’s connect plugin the
same way the HTTP/SOAP connectors are — which is why putting the overlay on the engine classpath
(see Installation) is all that’s needed to register them. There is no Spring
auto-configuration and no @ComponentScan requirement.
Note on shipped vs. planned registration
This is the actual, shipped registration mechanism. Early designs also sketched a richer
“process-as-tool / ad-hoc subprocess” engine plugin with spring.factories auto-config; that did
not ship — see Known Limitations.
Threading and transaction semantics
Engine executor
When the agent calls ProcessStarterTool, the engine work runs on a dedicated cached
daemon thread pool (ENGINE_EXECUTOR), not the JVM common pool — so each engine call gets its
own CommandContext/transaction and blocking polls don’t starve unrelated parallel work. The caller
authentication and the active audit listener are bridged onto that thread and cleared in finally.
Executor shutdown
The executor is a static pool that is never explicitly shut down. On hot redeploy of the engine this can retain a classloader reference. See Known Limitations.
Transaction semantics
A process started by ProcessStarterTool runs in its own transaction and commits independently.
There is no rollback symmetry: if the agent service task (or a later step in the parent process)
fails and rolls back after the tool already started/completed a subprocess, that subprocess is
not undone. Design tool-driven process starts to be idempotent or compensable, and prefer
camunda:asyncBefore on the agent task so retries are bounded by the job executor. See
Known Limitations.
Replacing the chat-memory store (persistent / shared)
The default chat-memory backing store is in-memory and JVM-local (see Chat Memory). To make conversations survive restarts or work across a cluster, replace it — but note the connector does not ship a persistent store or a configuration switch for one; you provide both:
- Implement
dev.langchain4j.store.memory.chat.ChatMemoryStore(LangChain4j) backed by your durable store (database table, Redis, …). - Install it once at startup, before the first agent invocation, via the static seam:
AgentChatMemoryStore.setStore(new MyDurableChatMemoryStore(...));
Where to call it depends on the distribution (there is no main() on Tomcat/WildFly):
- run / Spring Boot: an
@Configurationbean orApplicationRunner. - Tomcat / WildFly: a
ServletContextListener, or a customProcessEnginePlugin(postProcessEngineBuild) packaged on the engine classpath — anything that runs once at boot.
Keep the implementation thread-safe; it is a JVM-wide singleton shared by all agent activities.
AgentChatMemoryStore.clear(memoryId) deletes one conversation.
Building & testing
Build just this module from the repo root:
mvn -q -pl connect/ai-agent -am install
Run its tests (unit + coverage of the connector, listener, memory, RAG, MCP, and ProcessStarterTool):
mvn -q -pl connect/ai-agent test
Run the Knowledge Ingestor CLI via the configured exec plugin (see RAG):
mvn -pl connect/ai-agent exec:java -Dexec.args="--file doc.pdf --pgHost localhost --pgUser postgres --pgPassword secret"
Test factory seams worth knowing when writing tests:
AgentConnectorImpl.createChatModel(...)/createEmbeddingModel(...)andKnowledgeIngestorConnectorImpl.createEmbeddingModel(...)areprotectedso tests can inject stubbed models without network calls.AgentChatMemoryStore.setStore(...)isolates memory state between tests.AgentConnectorConstants.ENV_READER/AgentChatListener.ENV_READERare swappable env-lookup seams (restore toSystem::getenvafter each test).