Skip to content

Commit c19f78f

Browse files
authored
Merge pull request #550 from jupyter-naas/546-enhance-linkedin-module-with-mutual-connections-search-and-invitation-feature
feat: enhance linkedin module with mutual connections search
2 parents 9e635ef + 6be8c48 commit c19f78f

20 files changed

Lines changed: 628 additions & 227 deletions

File tree

config.yaml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,16 +36,18 @@ modules:
3636
enabled: true
3737
- path: src/core/modules/qwen
3838
enabled: true
39+
- path: src/core/modules/templatablesparqlquery
40+
enabled: true
3941
- path: src/marketplace/modules/applications/algolia
4042
enabled: false
4143
- path: src/marketplace/modules/applications/arxiv
4244
enabled: false
4345
- path: src/marketplace/modules/applications/git
44-
enabled: false
46+
enabled: true
4547
- path: src/marketplace/modules/applications/github
4648
enabled: true
4749
- path: src/marketplace/modules/applications/google_search
48-
enabled: false
50+
enabled: true
4951
- path: src/marketplace/modules/applications/linkedin
5052
enabled: true
5153
- path: src/marketplace/modules/applications/naas

lib/abi/utils/Module.py

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ def __init__(self, module_path: str, module_import_path: str, imported_module: A
3535
self.triggers = []
3636
self.ontologies = []
3737
self.agents = []
38-
self.loaded = False
3938

4039
def check_requirements(self):
4140
if hasattr(self.imported_module, "requirements"):
@@ -44,16 +43,14 @@ def check_requirements(self):
4443
raise SystemExit(f"Application crashed due to module loading failure: {self.module_import_path}")
4544

4645
def load(self):
47-
if self.loaded is False:
48-
try:
49-
self.check_requirements()
50-
self.__load_agents()
51-
self.__load_triggers()
52-
self.__load_ontologies()
53-
self.loaded = True
54-
except Exception as e:
55-
logger.error(f"❌ Critical error loading module {self.module_import_path}: {e}")
56-
raise SystemExit(f"Application crashed due to module loading failure: {self.module_import_path}")
46+
try:
47+
self.check_requirements()
48+
# self.__load_agents()
49+
self.__load_triggers()
50+
self.__load_ontologies()
51+
except Exception as e:
52+
logger.error(f"❌ Critical error loading module {self.module_import_path}: {e}")
53+
raise SystemExit(f"Application crashed due to module loading failure: {self.module_import_path}")
5754

5855
def load_agents(self):
5956
try:

src/__init__.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,10 +196,15 @@ def load_modules():
196196
topic, event_type, callback, background
197197
)
198198

199-
199+
logger.debug("Loading on_initialized")
200200
for module in _modules:
201201
module.on_initialized()
202202

203+
logger.debug("Loading agents")
204+
for module in _modules:
205+
logger.debug(f"Loading agents for module {module.module_import_path}")
206+
module.load_agents()
207+
203208
return _modules
204209

205210
services = LazyLoader(lambda: init_services(config, secret))

src/api.py

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
import subprocess
1111
import os
1212
from abi import logger
13-
from src.__modules__ import get_modules
13+
from src import modules
1414

1515
# Authentication
1616
from fastapi.security import OAuth2PasswordRequestForm
@@ -20,8 +20,6 @@
2020
from src.openapi_doc import TAGS_METADATA, API_LANDING_HTML
2121
from src import config
2222

23-
# Automatic loading of agents from modules
24-
2523
# Init API
2624
TITLE = config.api_title
2725
DESCRIPTION = config.api_description
@@ -190,9 +188,6 @@ def root():
190188
return API_LANDING_HTML.replace("[TITLE]", TITLE).replace("[LOGO_NAME]", logo_name)
191189

192190
# Add agents to the API
193-
modules = get_modules(config)
194-
195-
# Collect all agents first
196191
all_agents: list = []
197192
for module in modules:
198193
for agent in module.agents:

src/core/modules/__templates__/agents/TemplateAgent.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ def create_agent(
7171
tools: list = []
7272

7373
# Get tools from intentmapping
74-
from src.core.modules.abi import get_tools
74+
from src.core.modules.templatablesparqlquery import get_tools
7575
templates_tools = [
7676
"search_class"
7777
]

src/core/modules/abi/README.md

Lines changed: 75 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,62 @@
11
# Abi Agent Module
22

3-
> **Multi-Agent Orchestrator and Strategic Advisory System**
3+
> **Multi-Agent Orchestrator and Knowledge Graph Management System**
44
5-
The Abi agent is the **central coordinator** for the ABI ecosystem, managing specialized AI agents and knowledge graph operations while providing strategic advisory capabilities.
5+
The Abi module is the **central coordination hub** for the ABI ecosystem, featuring a sophisticated multi-agent orchestrator, specialized knowledge graph agents, and comprehensive ontology management capabilities.
66

77
## 🎯 Purpose & Role
88

9-
**Abi** (*Agentic Brain Infrastructure*) orchestrates multi-agent workflows by:
9+
**Abi** (*Agentic Brain Infrastructure*) provides comprehensive AI orchestration and knowledge management through:
1010

11-
- **Coordinating** specialized AI agents (ChatGPT, Claude, Mistral, Gemini, Grok, Llama, Perplexity)
12-
- **Managing** conversation context and agent transitions
13-
- **Routing** requests based on weighted decision hierarchy
14-
- **Providing** strategic advisory through direct consultation
15-
- **Supporting** multilingual interactions (English/French)
16-
- **Integrating** knowledge graph exploration and SPARQL querying
11+
- **Multi-Agent Orchestration**: Central coordinator managing specialized AI agents (ChatGPT, Claude, Mistral, Gemini, Grok, Llama, Perplexity, Qwen, DeepSeek, Gemma)
12+
- **Knowledge Graph Operations**: Complete CRUD operations for semantic data management
13+
- **Ontology Engineering**: BFO-compliant entity extraction and SPARQL generation
14+
- **Intelligent Routing**: Weighted decision hierarchy with context preservation
15+
- **Multilingual Support**: Native French/English interactions with cultural awareness
16+
- **Production Integration**: Event-driven triggers and YAML ontology publishing
1717

1818
## 🏗️ Architecture
1919

2020
### Directory Structure
2121
```
2222
src/core/modules/abi/
2323
├── agents/ # Agent implementations
24-
│ ├── AbiAgent.py # Main orchestrator
25-
│ ├── AbiAgent_test.py # Test suite
26-
│ ├── EntitytoSPARQLAgent.py
27-
│ ├── KnowledgeGraphBuilderAgent.py
28-
│ └── OntologyEngineerAgent.py
24+
│ ├── AbiAgent.py # Main multi-agent orchestrator
25+
│ ├── AbiAgent_test.py # Comprehensive test suite
26+
│ ├── EntitytoSPARQLAgent.py # BFO entity extraction & SPARQL generation
27+
│ ├── EntitytoSPARQLAgent_test.py # Entity extraction tests
28+
│ ├── KnowledgeGraphBuilderAgent.py # Triple store CRUD operations
29+
│ ├── KnowledgeGraphBuilderAgent_test.py # KG builder tests
30+
│ ├── OntologyEngineerAgent.py # BFO ontology engineering
31+
│ └── OntologyEngineerAgent_test.py # Ontology engineering tests
2932
├── models/ # Model configurations
30-
│ ├── o3_mini.py # OpenAI o3-mini (cloud)
31-
│ └── qwen3_8b.py # Qwen3 8B (local/Ollama)
32-
├── workflows/ # Business logic workflows
33-
├── pipelines/ # Data processing pipelines
34-
├── ontologies/ # Ontology definitions
35-
├── sandbox/ # Experimental scripts
36-
├── triggers.py # Event-driven triggers
37-
├── mappings.py # Visualization mappings
33+
│ ├── o3_mini.py # OpenAI o3-mini (cloud, temp=1.0)
34+
│ └── qwen3_8b.py # Qwen3 8B (local/Ollama, temp=0.7)
35+
├── workflows/ # Business logic workflows (15 implementations)
36+
│ ├── AgentRecommendationWorkflow.py # AI agent recommendation engine
37+
│ ├── ConvertOntologyGraphToYamlWorkflow.py # Graph to YAML conversion
38+
│ ├── CreateClassOntologyYamlWorkflow.py # Class ontology publishing
39+
│ ├── CreateIndividualOntologyYamlWorkflow.py # Individual ontology publishing
40+
│ ├── ExportGraphInstancesToExcelWorkflow.py # Data export capabilities
41+
│ ├── GetObjectPropertiesFromClassWorkflow.py # Property retrieval
42+
│ ├── GetSubjectGraphWorkflow.py # Entity graph exploration
43+
│ ├── SearchIndividualWorkflow.py # Semantic search
44+
│ └── TemplatableSparqlQuery.py # SPARQL query templating
45+
├── pipelines/ # Data processing pipelines (18 implementations)
46+
│ ├── AddIndividualPipeline.py # Entity creation
47+
│ ├── InsertDataSPARQLPipeline.py # SPARQL data insertion
48+
│ ├── MergeIndividualsPipeline.py # Entity merging
49+
│ ├── RemoveIndividualPipeline.py # Entity deletion
50+
│ ├── UpdateDataPropertyPipeline.py # Property updates
51+
│ └── Update*Pipeline.py # Specialized update pipelines
52+
├── ontologies/ # Ontology definitions (4-level hierarchy)
53+
│ ├── top-level/ # BFO foundational ontologies
54+
│ ├── mid-level/ # Common Core Ontologies
55+
│ ├── domain-level/ # Domain-specific ontologies
56+
│ └── application-level/ # Use-case specific ontologies
57+
├── sandbox/ # Experimental scripts (8 utilities)
58+
├── triggers.py # Production event-driven triggers
59+
├── mappings.py # Knowledge graph visualization colors
3860
└── __init__.py # Module initialization
3961
```
4062

@@ -65,23 +87,31 @@ graph TD
6587
| Variable | Values | Default | Description |
6688
|----------|--------|---------|-------------|
6789
| `AI_MODE` | `cloud` \| `local` | `cloud` | Model deployment mode |
68-
| `OPENAI_API_KEY` | API key | Required | For cloud model (o3-mini) |
69-
| `NAAS_API_KEY` | API key | Optional | For production ontology triggers |
90+
| `OPENAI_API_KEY` | API key | Required | For cloud models (o3-mini, gpt-4o) |
91+
| `NAAS_API_KEY` | API key | Optional | For production ontology triggers & YAML publishing |
92+
| `ENV` | `dev` \| `prod` | `dev` | Environment mode (affects trigger activation) |
7093

7194
### Model Selection
7295

7396
The agent automatically selects models based on `AI_MODE`:
7497

7598
```python
76-
# Cloud Mode (default)
99+
# Cloud Mode (default) - Creative orchestration
77100
AI_MODE=cloud # Uses OpenAI o3-mini with temperature=1.0
78101

79-
# Local Mode
102+
# Local Mode - Privacy-focused with stable performance
80103
AI_MODE=local # Uses Ollama qwen3:8b with temperature=0.7
81104

82-
# Error handling
105+
# Model Selection Logic:
106+
# - AbiAgent: Uses AI_MODE selection (o3-mini vs qwen3:8b)
107+
# - EntitytoSPARQLAgent: Uses o3-mini (cloud only)
108+
# - KnowledgeGraphBuilderAgent: Uses gpt-4o (cloud only)
109+
# - OntologyEngineerAgent: Uses o3-mini (cloud only)
110+
111+
# Error Handling:
83112
# Missing OPENAI_API_KEY in cloud mode → Agent creation fails
84-
# Missing Ollama in local mode → Agent creation fails
113+
# Missing Ollama in local mode → AbiAgent creation fails
114+
# Specialized agents require cloud mode and OpenAI API key
85115
```
86116

87117
## 🚀 Usage
@@ -92,32 +122,32 @@ AI_MODE=local # Uses Ollama qwen3:8b with temperature=0.7
92122
# Start Abi agent (default target)
93123
make chat-abi-agent
94124

95-
# Explicit cloud mode
96-
AI_MODE=cloud make chat-abi-agent
97-
98-
# Local privacy mode (requires Ollama)
99-
AI_MODE=local make chat-abi-agent
100-
101-
# Alternative generic agent runner
102-
make chat agent=AbiAgent
125+
# Alternative agent runners
126+
make chat agent=AbiAgent # Multi-agent orchestrator
127+
make chat agent=EntitytoSPARQLAgent # Entity extraction & SPARQL
128+
make chat agent=KnowledgeGraphBuilderAgent # Knowledge graph operations
129+
make chat agent=OntologyEngineerAgent # BFO ontology engineering
103130
```
104131

105132
### Programmatic Integration
106133

107134
```python
108135
from src.core.modules.abi.agents.AbiAgent import create_agent
136+
from src.core.modules.abi.agents.EntitytoSPARQLAgent import create_agent as create_entity_agent
137+
from src.core.modules.abi.agents.KnowledgeGraphBuilderAgent import create_agent as create_kg_agent
109138

110-
# Create agent with automatic model selection
111-
agent = create_agent()
139+
# Create orchestrator with automatic model selection
140+
abi_agent = create_agent()
141+
response = abi_agent.invoke("Route this to the best AI for code generation")
142+
# Workflow: Context preservation → Classification → Weighted routing to Mistral
112143

113-
# Direct interaction
114-
response = agent.invoke("Route this to the best AI for code generation")
144+
# Knowledge graph operations
145+
kg_agent = create_kg_agent()
146+
kg_agent.invoke("Add a new organization called 'NaasAI' to the knowledge graph")
115147

116-
# Workflow:
117-
# 1. Context preservation check
118-
# 2. Request classification (code generation)
119-
# 3. Weighted routing to Mistral
120-
# 4. Response synthesis with "Abi:" prefix
148+
# Entity extraction and SPARQL generation
149+
entity_agent = create_entity_agent()
150+
entity_agent.invoke("Extract entities from: 'John works at Microsoft as a software engineer'")
121151
```
122152

123153
### Interaction Patterns

src/core/modules/abi/__init__.py

Lines changed: 1 addition & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,2 @@
1-
from src.core.modules.abi.workflows.TemplatableSparqlQuery import load_workflows
2-
# from abi import logger
3-
4-
workflows: list = []
5-
tools: list = []
6-
loaded = False
7-
81
def requirements():
9-
return True
10-
11-
12-
def get_workflows():
13-
return workflows
14-
15-
16-
def get_tools(tool_names: list[str] = []):
17-
global loaded
18-
if not loaded:
19-
load_tools()
20-
loaded = True
21-
22-
if len(tool_names) == 0:
23-
return tools
24-
else:
25-
return [tool for tool in tools if tool.name in tool_names]
26-
27-
28-
def load_tools():
29-
# logger.debug("Loading Intent Mapping workflows")
30-
w = load_workflows()
31-
workflows.extend(w)
32-
[tools.extend(workflow.as_tools()) for workflow in w]
33-
# logger.debug(f"Tools from intentmapping loaded: {len(tools)}")
34-
# tool_names = sorted([tool.name for tool in tools])
35-
# logger.debug(tool_names)
2+
return True

src/core/modules/abi/agents/AbiAgent.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ class EmptySchema(BaseModel):
217217
tools.append(knowledge_graph_tool)
218218

219219
# Get tools
220-
from src.core.modules.abi import get_tools
220+
from src.core.modules.templatablesparqlquery import get_tools
221221
agent_recommendation_tools = [
222222
"find_business_proposal_agents",
223223
"find_coding_agents",
@@ -384,7 +384,7 @@ class EmptySchema(BaseModel):
384384
intent_target=agent.name
385385
))
386386

387-
if hasattr(agent, 'intents'):
387+
if hasattr(agent, 'intents') and agent.name not in agent_intents_map:
388388
for intent in agent.intents:
389389
# Create new intent with target set to agent name
390390
new_intent = Intent(

src/core/modules/abi/agents/KnowledgeGraphBuilderAgent.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,7 @@ def create_agent(
282282

283283

284284
# Add search organizations tools
285-
from src.core.modules.abi import get_tools
285+
from src.core.modules.templatablesparqlquery import get_tools
286286
ontology_tools: list = [
287287
"search_class",
288288
"count_instances_by_class",

0 commit comments

Comments
 (0)