Skip to content

Commit a612803

Browse files
committed
Merge remote-tracking branch 'origin' into cyber-security
2 parents d2b0b31 + 286fa4c commit a612803

File tree

7 files changed

+112
-13
lines changed

7 files changed

+112
-13
lines changed

Makefile

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ git-deps: .git/hooks/pre-commit
209209
# Create symbolic link to allow importing lib.abi from the virtual environment
210210
python_version=$(shell cat .python-version)
211211
.venv/lib/python$(python_version)/site-packages/abi: deps
212-
@[ -L .venv/lib/python$(python_version)/site-packages/abi ] || ln -s `pwd`/lib/abi .venv/lib/python$(python_version)/site-packages/abi
212+
@[ -L .venv/lib/python$(python_version)/site-packages/abi ] || ln -s `pwd`/lib/abi .venv/lib/python$(python_version)/site-packages/abi
213213

214214
# Install dependencies (alternative to .venv)
215215
install: dep
@@ -242,7 +242,7 @@ chat-chatgpt-agent: deps
242242
chat-claude-agent: deps
243243
@ LOG_LEVEL=$(log_level) uv run python -m src.cli ClaudeAgent
244244

245-
chat-deepseek-agent: deps
245+
chat-deepseek-agent: deps
246246
@ LOG_LEVEL=DEBUG uv run python -m src.cli DeepSeekAgent
247247

248248
chat-gemini-agent: deps
@@ -292,7 +292,7 @@ create-pipeline: deps
292292

293293
# Create a new ontology from template
294294
create-ontology: deps
295-
@ LOG_LEVEL=ERROR uv run python -m src.core.abi.cli create-ontology
295+
@ LOG_LEVEL=ERROR uv run python -m src.core.abi.cli create-ontology
296296

297297
# =============================================================================
298298
# CHAT WITH MARKETPLACE AGENTS
@@ -306,6 +306,10 @@ pull-request-description: deps
306306
chat-naas-agent: deps
307307
@ LOG_LEVEL=$(log_level) uv run python -m src.cli NaasAgent
308308

309+
# Bodo data analysis agent
310+
chat-bodo-agent: deps
311+
@ LOG_LEVEL=$(log_level) uv run python -m src.cli BodoAgent
312+
309313
# Customer support specialized agent
310314
chat-support-agent: deps
311315
@ LOG_LEVEL=$(log_level) uv run python -m src.cli SupportAgent
@@ -345,7 +349,7 @@ mcp-test: deps
345349

346350
# Interactive SPARQL terminal for querying the knowledge graph
347351
sparql-terminal: deps
348-
@ uv run python -m src.core.abi.apps.sparql_terminal.main
352+
@ uv run python -m src.core.abi.apps.sparql_terminal.main
349353

350354
# Oxigraph administrative interface for database management
351355
oxigraph-admin: deps
@@ -376,7 +380,7 @@ test-coverage: deps
376380
@ uv run coverage-badge -f -o coverage.svg
377381
@ echo "📊 Coverage report generated:"
378382
@ echo " - HTML: htmlcov/index.html"
379-
@ echo " - XML: coverage.xml"
383+
@ echo " - XML: coverage.xml"
380384
@ echo " - Badge: coverage.svg"
381385

382386
# Run basic tests for CI (no external dependencies)
@@ -550,7 +554,7 @@ build: build.linux.x86_64
550554
# Build Docker image for Linux x86_64 architecture with size reporting
551555
build.linux.x86_64: deps
552556
DOCKER_BUILDKIT=1 docker build . -t abi -f docker/images/Dockerfile.linux.x86_64 --platform linux/amd64
553-
557+
554558
@# Show container size
555559
@docker image ls abi
556560

config.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,3 +53,5 @@ modules:
5353
enabled: true
5454
- path: src/marketplace/applications/pubmed
5555
enabled: false
56+
- path: src/marketplace/applications/bodo
57+
enabled: false

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ dependencies = [
7373
"dagster-aws[s3]>=0.27.12",
7474
"ratelimit>=2.2.1",
7575
"yahooquery>=2.4.1",
76+
"bodo>=2025.10",
7677
"pandas-stubs>=2.3.2.250926",
7778
]
7879

src/core/abi/cli.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
import re
1010
from rich.console import Console
1111
from rich.prompt import Prompt
12+
import yaml
13+
import dotenv
1214

1315
console = Console(style="")
1416

@@ -80,8 +82,6 @@ def get_component_selection():
8082

8183
def enable_module_in_config(module_path: str):
8284
"""Enable the module in config files if they exist."""
83-
import yaml
84-
import dotenv
8585
dotenv.load_dotenv()
8686

8787
env = os.getenv("ENV")
@@ -229,8 +229,9 @@ def create_new_module():
229229
content = f.read()
230230

231231
# Replace template references
232-
content = content.replace('__templates__', module_name)
233232
content = content.replace('Template', module_name.replace('_', '').title())
233+
content = content.replace(template_path.replace('\\', '/').replace('/', '.'), target_path.replace('\\', '/').replace('/', '.'))
234+
content = content.replace('__templates__', module_name)
234235
content = content.replace('template', module_name.replace('_', '').lower())
235236

236237
# Update path references
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
from langchain_openai import ChatOpenAI
2+
from abi.services.agent.Agent import Agent, AgentConfiguration, AgentSharedState
3+
from src import secret
4+
from fastapi import APIRouter
5+
from src.marketplace.__demo__.workflows.ExecutePythonCodeWorkflow import ExecutePythonCodeWorkflow, ExecutePythonCodeWorkflowConfiguration
6+
from enum import Enum
7+
from typing import Optional
8+
from pydantic import SecretStr
9+
from langchain_core.tools import Tool, BaseTool
10+
11+
NAME = "BodoAgent"
12+
MODEL = "gpt-4o"
13+
TEMPERATURE = 0
14+
DESCRIPTION = "An agent that can analyze large data with Bodo DataFrames"
15+
# TODO: Add avatar
16+
AVATAR_URL = "https://raw.githubusercontent.com/jupyter-naas/awesome-notebooks/refs/heads/master/.github/assets/logos/Naas.png"
17+
SYSTEM_PROMPT = f"""
18+
You are {NAME}, a data analysis assistant that uses Bodo DataFrames to efficiently explore and analyze datasets.
19+
You can execute Python code through the ExecutePythonWorkflow tool to perform your analyses.
20+
21+
When a user asks a question involving data (e.g., describing a dataset, computing aggregates, or exploring patterns), you should:
22+
23+
* Write a complete Python script to perform the analysis.
24+
25+
* Always import bodo.pandas as pd at the top of the script (never use regular pandas).
26+
27+
* Read data using pandas-style APIs (for example: `pd.read_parquet("/path/to/file"))`.
28+
29+
* Perform any operations or computations using standard pandas syntax (groupby, describe, value_counts, etc.).
30+
31+
* Print concise, readable outputs — summary statistics, shapes, missing value counts, or aggregates.
32+
33+
* Avoid unsafe or network operations; only read data and compute results.
34+
35+
* After running the workflow, summarize the findings in plain English.
36+
37+
Your responses should be short, factual, and focused on analytical insights rather than speculation.
38+
"""
39+
SUGGESTIONS = ["Summarize this CSV file: /path/to/file.csv"]
40+
41+
def create_agent(
42+
agent_shared_state: Optional[AgentSharedState] = None,
43+
agent_configuration: Optional[AgentConfiguration] = None
44+
) -> Agent:
45+
# Init
46+
tools: list[Tool | BaseTool | Agent] = []
47+
48+
# Set model
49+
model = ChatOpenAI(
50+
model=MODEL,
51+
temperature=TEMPERATURE,
52+
api_key=SecretStr(secret.get('OPENAI_API_KEY'))
53+
)
54+
55+
# Set configuration
56+
if agent_configuration is None:
57+
agent_configuration = AgentConfiguration(system_prompt=SYSTEM_PROMPT)
58+
if agent_shared_state is None:
59+
agent_shared_state = AgentSharedState(thread_id="0")
60+
61+
# Add tools
62+
config = ExecutePythonCodeWorkflowConfiguration(timeout=600, allow_imports=True)
63+
tools += ExecutePythonCodeWorkflow(config).as_tools()
64+
65+
return BodoAgent(
66+
name=NAME,
67+
description=DESCRIPTION,
68+
chat_model=model,
69+
tools=tools,
70+
agents=[],
71+
state=agent_shared_state,
72+
configuration=agent_configuration,
73+
# memory is automatically configured based on POSTGRES_URL environment variable
74+
)
75+
76+
class BodoAgent(Agent):
77+
def as_api(
78+
self,
79+
router: APIRouter,
80+
route_name: str = NAME,
81+
name: str = NAME,
82+
description: str = "API endpoints to call the Bodo agent completion.",
83+
description_stream: str = "API endpoints to call the Bodo agent stream completion.",
84+
tags: Optional[list[str | Enum]] = None,
85+
):
86+
return super().as_api(router, route_name, name, description, description_stream, tags)

src/marketplace/domains/cyber-security-analyst/agents/CyberSecurityAgent.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,12 @@ def create_agent(
5959
) -> Optional[IntentAgent]:
6060
"""Create Cyber Security Agent with all 22 competency question tools."""
6161

62+
if agent_shared_state is None:
63+
agent_shared_state = AgentSharedState()
64+
65+
if agent_configuration is None:
66+
agent_configuration = AgentConfiguration(system_prompt=SYSTEM_PROMPT)
67+
6268
# Load model based on AI_MODE
6369
from src import secret
6470
from langchain_openai import ChatOpenAI
@@ -149,6 +155,5 @@ def create_agent(
149155
intents=intents,
150156
state=agent_shared_state,
151157
configuration=agent_configuration,
152-
memory=None,
153-
system_prompt=SYSTEM_PROMPT,
158+
memory=None
154159
)

src/mcp_server.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ async def wait_for_api():
136136
for attempt in range(max_retries):
137137
try:
138138
async with httpx.AsyncClient(timeout=5.0) as client:
139-
response = await client.get(f"{ABI_API_BASE}/health")
139+
response = await client.get(f"{ABI_API_BASE}")
140140
if response.status_code == 200:
141141
print("✅ API is ready!")
142142
return True
@@ -222,4 +222,4 @@ def run():
222222
mcp.run(transport='stdio')
223223

224224
if __name__ == "__main__":
225-
run()
225+
run()

0 commit comments

Comments
 (0)