|
|
|
|
|
|
|
|
|
from langchain.callbacks.tracers import LangChainTracer |
|
from langchain.callbacks.tracers.langchain import wait_for_all_tracers |
|
from langchain_core.messages import HumanMessage |
|
from langchain_core.runnables import RunnableConfig |
|
|
|
from ea4all.src.shared.configuration import BaseConfiguration, APM_MOCK_QNA, PMO_MOCK_QNA |
|
from ea4all.src.ea4all_gra.configuration import AgentConfiguration as gra |
|
from ea4all.src.ea4all_apm.graph import apm_graph |
|
from ea4all.src.ea4all_vqa.graph import diagram_graph |
|
from ea4all.src.ea4all_gra.graph import togaf_graph |
|
from ea4all.src.ea4all_indexer.graph import indexer_graph |
|
from ea4all.src.shared.utils import ( |
|
get_relevant_questions, |
|
get_vqa_examples, |
|
_join_paths, |
|
EA4ALL_ARCHITECTURE, |
|
EA4ALL_PODCAST, |
|
) |
|
|
|
|
|
|
|
from typing import AsyncGenerator |
|
import gradio as gr |
|
from gradio import ChatMessage |
|
import os |
|
import uuid |
|
import time |
|
from PIL import Image |
|
|
|
from ea4all.utils.utils import ( |
|
UIUtils, |
|
ea4all_agent_init, get_image, |
|
get_question_diagram_from_example, |
|
on_image_update |
|
) |
|
|
|
TITLE = """ |
|
# Title |
|
|
|
**Explore, Share, Together:** harness the value of `Enterprise Architecture in the era of Generative AI` with ready-to-use MCP Tools.\n |
|
|
|
## Overview |
|
""" |
|
|
|
|
|
tracer = LangChainTracer(project_name=os.getenv('LANGCHAIN_PROJECT')) |
|
|
|
config = RunnableConfig( |
|
run_name = os.getenv('LANGCHAIN_RUNNAME', "ea4all-gradio-agent-mcp-hackathon-run"), |
|
tags = [os.getenv('EA4ALL_ENV', "MCP")], |
|
callbacks = [tracer], |
|
recursion_limit = 25, |
|
configurable = {"thread_id": uuid.uuid4()}, |
|
|
|
) |
|
|
|
async def call_indexer_apm(config: RunnableConfig): |
|
response = await indexer_graph.ainvoke(input={"docs":[]}, config=config) |
|
return response |
|
|
|
|
|
async def run_qna_agentic_system(question: str) -> AsyncGenerator[list, None]: |
|
""" |
|
description: |
|
Handles conversational Q&A for the Application Landscape using an agentic system. |
|
Args: |
|
question (str): The user's question or message. |
|
request (gr.Request): The Gradio request object for user identification. |
|
Returns: |
|
reponse: Response to user's architectural question. |
|
""" |
|
|
|
format_response = "" |
|
chat_memory = [] |
|
if not question: |
|
format_response = "Hi, how are you today? To start using the EA4ALL MCP Tool, provide the required Inputs!" |
|
chat_memory.append(ChatMessage(role="assistant", content=format_response)) |
|
else: |
|
index = await call_indexer_apm(config) |
|
response = await apm_graph.ainvoke({"question": question}, config=config) |
|
chat_memory.append(ChatMessage(role="assistant", content=response['generation'])) |
|
|
|
yield chat_memory |
|
|
|
|
|
async def run_vqa_agentic_system(question: str, diagram: str, request: gr.Request) -> AsyncGenerator[list, None]: |
|
""" |
|
description: |
|
Handles Visual Question Answering (VQA) for uploaded architecture diagrams. |
|
Args: |
|
question (str): User's question about the Architecture Diagram. |
|
diagram (str): Path to the diagram file. |
|
Returns: |
|
response: Response to user's question. |
|
""" |
|
|
|
|
|
|
|
|
|
"""Handle file uploads and validate their types.""" |
|
allowed_file_types = ('JPEG', 'PNG') |
|
|
|
message = { |
|
'text': question, |
|
'files': [diagram] if isinstance(diagram, str) else diagram |
|
} |
|
|
|
print("---CALLING VISUAL QUESTION ANSWERING AGENTIC SYSTEM---") |
|
print(f"Prompt: {message}") |
|
|
|
chat_memory = [] |
|
if message['files'] in ([], None): |
|
chat_memory.append(ChatMessage(role="assistant", content="Please upload an Architecture PNG, JPEG diagram to start!")) |
|
yield chat_memory |
|
else: |
|
diagram = message['files'][-1] |
|
msg = message['text'] |
|
print(f"---DIAGRAM: {diagram}---") |
|
try: |
|
if msg == "": |
|
msg = "Please describe this diagram." |
|
|
|
with Image.open(diagram) as diagram_: |
|
if diagram_.format not in allowed_file_types: |
|
|
|
print(f"---DIAGRAM: {diagram.format} is not a valid file type. Allowed file types are JPEG and PNG.---") |
|
|
|
|
|
|
|
vqa_image = diagram |
|
response = await diagram_graph.ainvoke({"question":msg, "image": vqa_image}, config) |
|
chat_memory.append(ChatMessage(role="assistant", content=response['messages'][-1].content if len(response['messages']) else response['safety_status']['description'])) |
|
|
|
yield chat_memory |
|
|
|
except Exception as e: |
|
yield (e.args[-1]) |
|
|
|
|
|
async def run_reference_architecture_agentic_system(business_query: str) -> AsyncGenerator[list, str]: |
|
""" |
|
description: |
|
Generates a reference architecture blueprint based on a business requirement using the TOGAF agentic system. |
|
Args: |
|
business_query (str): Description of a business problem / requirement. |
|
Returns: |
|
response: High-level architecture blueprint and target diagram. |
|
""" |
|
|
|
if len(business_query) < 20: |
|
agent_response = "Please provide a valid Business Requirement content to start!" |
|
yield([agent_response, None]) |
|
else: |
|
inputs = {"business_query": [{"role": "user", "content": business_query}]} |
|
index = await call_indexer_apm(config) |
|
response = await togaf_graph.ainvoke( |
|
input=inputs, |
|
config=config |
|
) |
|
vision_target = response['vision_target'] |
|
if isinstance(response['architecture_runway'], str): |
|
architecture_runway = response['architecture_runway'] |
|
else: |
|
architecture_runway = None |
|
|
|
yield [vision_target, architecture_runway] |
|
|
|
async def run_pmo_agentic_system(question:str) -> AsyncGenerator[list, None]: |
|
""" |
|
description: |
|
Answers questions about Project Portfolio Management and Architect Demand Management. |
|
Args: |
|
question (str): The user's question about project portfolio or resource management. |
|
chat_memory: The conversation history. |
|
Returns: |
|
response: Architect Demand Allocation Report |
|
""" |
|
|
|
format_response = "" |
|
chat_memory = [] |
|
if not question: |
|
format_response = "Hi, how are you today? To start our conversation, please chat your message!" |
|
chat_memory.append(ChatMessage(role="assistant", content=format_response)) |
|
yield chat_memory |
|
|
|
if not chat_memory: |
|
chat_memory.append(ChatMessage(role="user", content=question)) |
|
yield chat_memory |
|
|
|
inputs = { |
|
"question": question, |
|
"verbose": True, |
|
} |
|
|
|
|
|
|
|
|
|
with gr.Blocks(title="Your ArchitectGPT",fill_height=True, fill_width=True) as ea4all_mcp: |
|
|
|
agentic_pmo_desc=""" |
|
Hi, |
|
Provide project resource estimation for architecture work based on business requirements, skillset, |
|
architects allocation, and any other relevant information to enable successful project solution delivery.""" |
|
|
|
agentic_qna_desc=""" |
|
Hi, |
|
Improve Architect's ability to share knowledge, and provide valuable insights from IT landscape using natural language answering questions related to Enterprise Architecture, Technology, plus the following IT Landscape sample dataset: """ |
|
|
|
agentic_vqa_desc=""" |
|
Hi, |
|
Gain rapid knowledge and insights translating image to meaningful description. |
|
""" |
|
|
|
agentic_togaf_desc=""" |
|
Hi, |
|
in a click of button create a reference architecture that serves as a blueprint for designing and implementing IT solutions. |
|
Standardise, increase efficiency and productivity to architecture solution development. |
|
Generate context-specific reference and minimal viable architectures to support business and IT strategy and digital transformation. |
|
Streamline the architecture operating model, taking the best of agentic workflows and architects working together. |
|
""" |
|
|
|
|
|
wrapper = gr.Button(visible=False) |
|
wrapper1 = gr.Button(visible=False) |
|
|
|
|
|
with gr.Tabs(selected="how_to") as tabs: |
|
with gr.Tab(label="Architect Demand Management", visible=False): |
|
with gr.Tab(label="Architect Project Planning", id="pmo_qna_1"): |
|
ea4all_pmo_description = gr.Markdown(value=agentic_pmo_desc) |
|
pmo_chatbot = gr.Chatbot( |
|
label="EA4ALL your AI Demand Management Architect Companion", type="messages", |
|
max_height=160, |
|
layout="bubble", |
|
) |
|
pmo_prompt = gr.Textbox(lines=1, show_label=False, max_lines=1, submit_btn=True, stop_btn=True,autofocus=True, placeholder="Type your message here or select an example...") |
|
with gr.Accordion("Open for question examples", open=False): |
|
pmo_examples = gr.Dropdown(get_relevant_questions(PMO_MOCK_QNA), value=None,label="Questions", interactive=True) |
|
gr.ClearButton([pmo_chatbot,pmo_prompt], value="Clear", size="sm", visible=False) |
|
with gr.Tab(label="Project Portfolio Sample Dataset", id="id_pmo_ds"): |
|
pmo_df = gr.Dataframe() |
|
with gr.Tab(label="Application Landscape QnA"): |
|
with gr.Tabs() as tabs_apm_qna: |
|
with gr.Tab(label="Connect, Explore, Together", id="app_qna_1"): |
|
ea4all_agent_metadata = gr.Markdown(value=agentic_qna_desc) |
|
ea4all_chatbot = gr.Chatbot( |
|
label="EA4ALL your AI Landscape Architect Companion", type="messages", |
|
max_height=160, |
|
layout="bubble", |
|
) |
|
qna_prompt = gr.Textbox(lines=1, show_label=False, max_lines=1, submit_btn=True, autofocus=True, placeholder="Type your message here or select an example...") |
|
with gr.Accordion("Open for question examples", open=False): |
|
qna_examples = gr.Dropdown(get_relevant_questions(APM_MOCK_QNA),label="Questions", interactive=True) |
|
gr.ClearButton([ea4all_chatbot,qna_prompt, qna_examples], value="Clear", size="sm", visible=True) |
|
with gr.Tab(label="Sample Dataset", id="id_apm_ds"): |
|
apm_df = gr.Dataframe() |
|
with gr.Tab(label="Diagram Question and Answering"): |
|
gr.Markdown(value=agentic_vqa_desc) |
|
ea4all_vqa = gr.Chatbot( |
|
label="EA4ALL your AI Multimodal Architect Companion", type="messages", |
|
max_height=160, |
|
layout="bubble", |
|
) |
|
vqa_prompt = gr.Textbox(lines=1, show_label=False, max_lines=1, submit_btn=True, stop_btn=True,autofocus=True, placeholder="Type your message here and upload your diagram...") |
|
vqa_image = gr.Image( |
|
label="Architecture Diagram", |
|
type="filepath", |
|
format="jpeg, png", |
|
interactive=True, |
|
show_download_button=False, |
|
show_share_button=False, |
|
visible=True, |
|
) |
|
|
|
with gr.Accordion("Open for question examples", open=False): |
|
vqa_examples = gr.Dropdown(get_vqa_examples(), value=0,label="Diagram and Questions", interactive=True) |
|
gr.ClearButton([ea4all_vqa,vqa_prompt,vqa_image, vqa_examples], value="Clear", size="sm", visible=True) |
|
with gr.Tab(label="Reference Architecture", id="id_refarch"): |
|
dbr_text=gr.TextArea(label="Business Problem Sample", value="Provide a Business Problem / Requirement Specification or select an example provided.", lines=14, interactive=True) |
|
togaf_vision=gr.Markdown(value='### Reference Architecture: Vision and Target') |
|
architecture_runway=gr.Image(label="Target Architecture Runway",interactive=False,visible=False) |
|
with gr.Row(): |
|
dbr_file=gr.File( |
|
value=_join_paths(BaseConfiguration.ea4all_store, gra.dbr_mock), |
|
label="Business Requirement", |
|
height=35, |
|
show_label=False, |
|
file_count="single", |
|
file_types=['text'], |
|
interactive=True, |
|
type='binary', |
|
visible=False |
|
) |
|
dbr_run=gr.Button(scale=None,value="Run Reference Architecture") |
|
dbr_cls=gr.ClearButton([togaf_vision, architecture_runway]) |
|
with gr.Tab(label="Overview", id="how_to"): |
|
gr.Markdown(value=TITLE) |
|
gr.Image( |
|
get_image(EA4ALL_ARCHITECTURE), |
|
show_download_button=False, |
|
container=False, |
|
show_share_button=False, |
|
) |
|
gr.Markdown( |
|
""" |
|
- `Empower individuals with Knowledge`: understand and talk about Business and Technology strategy, IT landscape, Architectue Artefacts in a single click of button. |
|
- `Increase efficiency and productivity`: generate a documented architecture with diagram, model and descriptions. Accelerate Business Requirement identification and translation to Target Reference Architecture. Automated steps and reduced times for task execution. |
|
- `Improve agility`: plan, execute, review and iterate over EA inputs and outputs. Increase the ability to adapt, transform and execute at pace and scale in response to changes in strategy, threats and opportunities. |
|
- `Increase collaboration`: democratise architecture work and knowledge with anyone using natural language. |
|
|
|
### Knowledge Context |
|
|
|
Synthetic datasets are used to exemplify the Agentic System capabilities. |
|
|
|
### IT Landscape Question and Answering |
|
|
|
- Application name |
|
- Business fit: appropriate, inadequate, perfect |
|
- Technical fit: adequate, insufficient, perfect |
|
- Business_criticality: operational, medium, high, critical |
|
- Roadmap: maintain, invest, divers |
|
- Architect responsible |
|
- Hosting: user device, on-premise, IaaS, SaaS |
|
- Business capability |
|
- Business domain |
|
- Description |
|
|
|
|
|
### Architecture Diagram Visual Question and Answering |
|
|
|
- Architecture Visual Artefacts |
|
- jpeg, png |
|
|
|
**Disclaimer** |
|
- Your data & image are not accessible or shared with anyone else nor used for training purpose. |
|
- EA4ALL-VQA Agent should be used ONLY FOR Architecture Diagram images. |
|
- This feature should NOT BE USED to process inappropriate content. |
|
|
|
### Reference Architecture Generation |
|
|
|
- Clock in/out Use-case |
|
""" |
|
) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
dbr_file.change(UIUtils.load_dbr,inputs=dbr_file, outputs=dbr_text, show_api=False) |
|
|
|
|
|
|
|
qna_prompt.submit(run_qna_agentic_system,[qna_prompt],ea4all_chatbot, api_name="landscape_answering_agent") |
|
|
|
|
|
qna_examples.input(lambda value: value, qna_examples, qna_prompt, show_api=False) |
|
|
|
|
|
dbr_run.click(run_reference_architecture_agentic_system,show_progress='full',inputs=[dbr_text],outputs=[togaf_vision, architecture_runway], api_name="togaf_blueprint_generation") |
|
architecture_runway.change(on_image_update, inputs=architecture_runway, outputs=architecture_runway, show_api=False) |
|
|
|
|
|
|
|
vqa_prompt.submit(run_vqa_agentic_system,[vqa_prompt, vqa_image], ea4all_vqa, api_name="diagram_answering_agent") |
|
|
|
|
|
vqa_examples.input(get_question_diagram_from_example, vqa_examples, outputs=[vqa_prompt, vqa_image], show_api=False) |
|
|
|
|
|
pmo_prompt.submit(run_pmo_agentic_system,[pmo_prompt],pmo_chatbot, api_name="architect_demand_agent", show_api=False) |
|
pmo_prompt.submit(lambda: "", None, [pmo_prompt], show_api=False) |
|
|
|
|
|
|
|
ea4all_mcp.load(ea4all_agent_init, outputs=[ |
|
ea4all_agent_metadata, |
|
ea4all_chatbot, |
|
ea4all_vqa, |
|
pmo_chatbot, |
|
apm_df, |
|
pmo_df, |
|
dbr_text |
|
], |
|
show_api=False) |
|
|