You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Welcome to the ABI (Agent-Based Intelligence) documentation. This repository contains comprehensive documentation about the ABI system, its architecture, components, and usage guidelines.
4
+
5
+
## Table of Contents
6
+
7
+
### Core Documentation
8
+
-[Modules](./modules.md) - Comprehensive guide to ABI's modular architecture
9
+
-[What is a Module?](./modules.md#what-is-a-module)
Copy file name to clipboardexpand all lines: docs/modules.md
+52-19
Original file line number
Diff line number
Diff line change
@@ -2,7 +2,12 @@
2
2
3
3
## What is a Module?
4
4
5
-
A module in the ABI system is a self-contained, standalone component that encapsulates related functionality. Modules are designed to be pluggable, meaning they can be added or removed from the system without modifying other parts of the codebase. Each module resides in its own directory under `src/modules/`.
5
+
A module in the ABI system is a self-contained, standalone component that encapsulates related functionality. Modules are designed to be pluggable, meaning they can be added or removed from the system without modifying other parts of the codebase. Modules are now organized into two categories:
6
+
7
+
1.**Core Modules**: Located in `src/core/modules/` - These are essential modules that provide the core functionality of the ABI system.
8
+
2.**Custom Modules**: Located in `src/custom/modules/` - These are user-created modules that extend the system with additional capabilities.
9
+
10
+
This separation makes the system architecture easier to understand and maintain, with a clear distinction between core functionality and custom extensions.
6
11
7
12
Modules provide a way to organize and structure your code in a modular fashion, making it easier to maintain, extend, and reuse functionality. They can contain various components such as:
8
13
@@ -17,21 +22,35 @@ Modules provide a way to organize and structure your code in a modular fashion,
17
22
18
23
The ABI system automatically discovers and loads modules at runtime. Here's how the process works:
19
24
20
-
1. The system scans the `src/modules/`directory for subdirectories
25
+
1. The system scans both the `src/core/modules/`and `src/custom/modules/` directories for subdirectories
21
26
2. Each subdirectory (except `__pycache__` and those containing "disabled" in their name) is considered a module
22
27
3. The module is imported using Python's import system
23
28
4. An `IModule` instance is created for the module
24
29
5. The module's components (assistants, workflows, pipelines) are loaded
25
30
6. The loaded module is added to the system's registry
26
31
27
-
This automatic loading mechanism means that you can add new functionality to the system simply by creating a new module directory with the appropriate structure.
32
+
This automatic loading mechanism means that you can add new functionality to the system simply by creating a new module directory with the appropriate structure in either the core or custom modules directory.
28
33
29
34
### Module Structure
30
35
31
36
A typical module has the following directory structure:
Triggers are a powerful feature in the ABI system that enable reactive programming based on changes in the ontology store. They allow modules to register callbacks that are automatically executed when specific RDF triples are added to or removed from the ontology.
6
+
7
+
A trigger consists of three main components:
8
+
1. A **triple pattern** to match against (subject, predicate, object)
9
+
2. An **event type** (INSERT or DELETE)
10
+
3. A **callback function** to execute when the event occurs
11
+
12
+
Triggers transform the ontology from a passive data store into a reactive system that can automatically initiate actions when data changes. This creates an "executable ontology" or "reactive ontology" where the knowledge graph itself becomes a mechanism for coordinating system behavior.
13
+
14
+
## Why Use Triggers?
15
+
16
+
Triggers provide several key benefits:
17
+
18
+
1.**Decoupling of Components**: Modules can react to data changes without direct dependencies on each other.
19
+
2.**Event-Driven Architecture**: The system becomes more responsive and can automatically initiate processes when relevant data appears.
20
+
3.**Simplified Workflows**: Complex multi-step processes can be broken down into smaller, more manageable components that activate in sequence.
21
+
4.**Reduced Boilerplate**: No need to manually check for conditions or poll for changes.
22
+
23
+
## How Triggers Work
24
+
25
+
When a triple is added to or removed from the ontology store, the system checks if any registered triggers match the affected triple. If a match is found, the associated callback function is executed.
26
+
27
+
The triple pattern in a trigger can include specific values or `None` wildcards:
28
+
- If a specific value is provided, the trigger only matches triples with exactly that value in the corresponding position.
29
+
- If `None` is provided, the trigger matches any value in that position.
30
+
31
+
For example:
32
+
-`(ex:Person123, ex:hasProfile, None)` matches any triple with subject `ex:Person123` and predicate `ex:hasProfile`, regardless of the object.
33
+
-`(None, rdf:type, ex:LinkedInProfile)` matches any triple with predicate `rdf:type` and object `ex:LinkedInProfile`, regardless of the subject.
34
+
35
+
## Example Use Case
36
+
37
+
Consider a LinkedIn profile ingestion workflow:
38
+
39
+
1. A workflow discovers a person and their LinkedIn profile URL, adding a triple like:
2. Instead of having this workflow also handle the profile ingestion, a separate LinkedIn ingestion pipeline registers a trigger:
45
+
```python
46
+
(None, ex:hasLinkedInProfile, None) # Match any triple with this predicate
47
+
```
48
+
49
+
3. When the triple is added, the trigger automatically activates the LinkedIn ingestion pipeline, which:
50
+
- Retrieves the profile URL
51
+
- Scrapes the LinkedIn profile
52
+
- Processes the data
53
+
- Adds more detailed information to the ontology
54
+
55
+
This approach keeps each component focused on a single responsibility and allows the system to automatically coordinate complex workflows.
56
+
57
+
## How to Register Triggers in a Module
58
+
59
+
Triggers are registered by creating a `triggers.py` file in your module directory. This file should define a `triggers` list variable containing tuples of (triple_pattern, event_type, callback_function).
60
+
61
+
Here's an example of a `triggers.py` file:
62
+
63
+
```python
64
+
from abi.services.ontology_store.OntologyStorePorts import OntologyEvent
65
+
from rdflib import URIRef
66
+
from .pipelines.LinkedInProfileIngestionPipeline import ingest_linkedin_profile
67
+
68
+
# Define the namespace
69
+
ex = URIRef("http://example.org/")
70
+
71
+
# Define the triple pattern to watch for
72
+
# (None, ex:hasLinkedInProfile, None) means "match any subject and object, but the predicate must be ex:hasLinkedInProfile"
1.**Be Specific**: Make your triple patterns as specific as possible to avoid unnecessary callback executions.
107
+
2.**Keep Callbacks Lightweight**: Trigger callbacks should be quick and focused. For complex operations, consider having the callback initiate a separate process.
108
+
3.**Handle Errors Gracefully**: Ensure your callback functions include proper error handling to prevent failures from affecting the ontology store.
109
+
4.**Document Your Triggers**: Clearly document what triggers your module registers and what they do.
110
+
5.**Avoid Circular Triggers**: Be careful not to create circular dependencies where triggers create conditions that activate other triggers indefinitely.
111
+
112
+
## Advanced Usage: Trigger Patterns
113
+
114
+
Here are some common patterns for using triggers effectively:
115
+
116
+
### Wildcard Matching
117
+
118
+
Use `None` as a wildcard to match any value in a triple position:
119
+
120
+
```python
121
+
# Match any triple with rdf:type as predicate and ex:Person as object
122
+
(None, RDF.type, ex.Person)
123
+
```
124
+
125
+
### Chain Reactions
126
+
127
+
Create a chain of triggers where each step in a process triggers the next:
128
+
129
+
```python
130
+
# Step 1: Detect new LinkedIn profile
131
+
(None, ex.hasLinkedInProfile, None)
132
+
133
+
# Step 2: After profile data is ingested, analyze connections
134
+
(None, ex.hasConnection, None)
135
+
136
+
# Step 3: After connections are analyzed, generate recommendations
137
+
(None, ex.hasAnalyzedNetwork, None)
138
+
```
139
+
140
+
### Conditional Processing
141
+
142
+
Use triggers to implement conditional logic based on the ontology state:
143
+
144
+
```python
145
+
# Only process profiles that have both LinkedIn and Twitter
Triggers are a powerful mechanism in the ABI system that enable reactive, event-driven programming based on changes in the ontology. By registering callbacks to respond to specific triple patterns, modules can create sophisticated workflows that automatically react to new information as it becomes available.
159
+
160
+
This approach helps keep the codebase modular, maintainable, and focused on specific responsibilities while allowing complex behaviors to emerge from the interaction of simple components.
0 commit comments