mirror of
https://github.com/fsecada01/Pygentic-AI.git
synced 2025-06-15 19:46:03 +00:00
WIP: status component working; result
page still being patched
This commit is contained in:
parent
05d8baffb1
commit
f2363ff81d
@ -10,7 +10,7 @@ annotated-types==0.7.0
|
||||
# via
|
||||
# pydantic
|
||||
# sqlmodel-crud-utilities
|
||||
anthropic==0.43.1
|
||||
anthropic==0.44.0
|
||||
# via pydantic-ai-slim
|
||||
anyio==4.8.0
|
||||
# via
|
||||
@ -31,7 +31,7 @@ beautifulsoup4==4.12.3
|
||||
# via httpx-html
|
||||
billiard==4.2.1
|
||||
# via celery
|
||||
cachetools==5.5.0
|
||||
cachetools==5.5.1
|
||||
# via google-auth
|
||||
celery==5.4.0
|
||||
# via
|
||||
@ -195,7 +195,7 @@ mistralai==1.4.0
|
||||
# via pydantic-ai-slim
|
||||
mypy-extensions==1.0.0
|
||||
# via typing-inspect
|
||||
openai==1.59.9
|
||||
openai==1.60.0
|
||||
# via
|
||||
# -r core_requirements.in
|
||||
# pydantic-ai-slim
|
||||
@ -413,7 +413,7 @@ typing-inspect==0.9.0
|
||||
# via
|
||||
# -r core_requirements.in
|
||||
# mistralai
|
||||
tzdata==2024.2
|
||||
tzdata==2025.1
|
||||
# via
|
||||
# celery
|
||||
# kombu
|
||||
|
@ -84,7 +84,7 @@ fastapi-debug-toolbar @ git+https://github.com/fsecada01/fastapi-debug-toolbar.g
|
||||
# via -r dev_requirements.in
|
||||
fastjsonschema==2.21.1
|
||||
# via nbformat
|
||||
filelock==3.16.1
|
||||
filelock==3.17.0
|
||||
# via virtualenv
|
||||
fqdn==1.5.1
|
||||
# via jsonschema
|
||||
|
@ -80,7 +80,7 @@ dependencies = [
|
||||
"aiomysql==0.2.0",
|
||||
"amqp==5.3.1",
|
||||
"annotated-types==0.7.0",
|
||||
"anthropic==0.43.1",
|
||||
"anthropic==0.44.0",
|
||||
"anyio==4.8.0",
|
||||
"appdirs==1.4.4",
|
||||
"asgiref==3.8.1",
|
||||
@ -88,7 +88,7 @@ dependencies = [
|
||||
"asyncpg==0.30.0",
|
||||
"beautifulsoup4==4.12.3",
|
||||
"billiard==4.2.1",
|
||||
"cachetools==5.5.0",
|
||||
"cachetools==5.5.1",
|
||||
"celery==5.4.0",
|
||||
"certifi==2024.12.14",
|
||||
"charset-normalizer==3.4.1",
|
||||
@ -141,7 +141,7 @@ dependencies = [
|
||||
"mdurl==0.1.2",
|
||||
"mistralai==1.4.0",
|
||||
"mypy-extensions==1.0.0",
|
||||
"openai==1.59.9",
|
||||
"openai==1.60.0",
|
||||
"opentelemetry-api==1.29.0",
|
||||
"opentelemetry-exporter-otlp-proto-common==1.29.0",
|
||||
"opentelemetry-exporter-otlp-proto-http==1.29.0",
|
||||
@ -203,7 +203,7 @@ dependencies = [
|
||||
"tqdm==4.67.1",
|
||||
"typing-extensions==4.12.2",
|
||||
"typing-inspect==0.9.0",
|
||||
"tzdata==2024.2",
|
||||
"tzdata==2025.1",
|
||||
"update-checker==0.18.0",
|
||||
"urllib3==1.26.20",
|
||||
"uvicorn==0.34.0",
|
||||
@ -252,7 +252,7 @@ dev = [
|
||||
"fastapi-debug-toolbar==0.6.3",
|
||||
"fastapi==0.115.6",
|
||||
"fastjsonschema==2.21.1",
|
||||
"filelock==3.16.1",
|
||||
"filelock==3.17.0",
|
||||
"fqdn==1.5.1",
|
||||
"greenlet==3.1.1",
|
||||
"h11==0.14.0",
|
||||
|
@ -119,7 +119,7 @@ async def run_agent(
|
||||
f"Perform a comprehensive SWOT analysis for this product: {url}",
|
||||
deps=deps,
|
||||
)
|
||||
logger.info(f"Agent Result: {pformat(result.data)}")
|
||||
logger.info(f"Agent Result: {pformat(result.data.model_dump())}")
|
||||
|
||||
if deps.update_status_func:
|
||||
await deps.update_status_func(deps.request, "Analysis Complete")
|
||||
|
@ -13,6 +13,7 @@ from backend.site.consts import (
|
||||
ANALYSIS_COMPLETE_MESSAGE,
|
||||
ANALYZING_MESSAGE,
|
||||
result_store,
|
||||
running_tasks,
|
||||
status_store,
|
||||
)
|
||||
from backend.site.utils import run_agent_with_progress
|
||||
@ -47,13 +48,13 @@ async def analyze_url(request: Request, url: str = Form(...)) -> HTMLResponse:
|
||||
:param url:
|
||||
:return:
|
||||
"""
|
||||
running_tasks = set()
|
||||
session_id = str(id(request))
|
||||
request.session["analysis_id"] = session_id
|
||||
request.session["start_time"] = asyncio.get_event_loop().time()
|
||||
|
||||
# Clearing out the status store for the analysis ID session
|
||||
status_store[session_id] = []
|
||||
result_store[session_id] = None
|
||||
|
||||
status_store[session_id].append(ANALYZING_MESSAGE)
|
||||
|
||||
@ -83,15 +84,18 @@ async def get_status(request: Request):
|
||||
context = {"request": request, "messages": [], "result": False}
|
||||
session_id = request.session.get("analysis_id")
|
||||
if session_id:
|
||||
logger.info(f"Found session id! {session_id}")
|
||||
messages = status_store.get(session_id, [])
|
||||
result = ANALYSIS_COMPLETE_MESSAGE in messages
|
||||
logger.info(
|
||||
f"Status check - Session ID: {'session_id'}, Messages: "
|
||||
f"Status check - Session ID: {session_id}, Messages: "
|
||||
f"{messages}",
|
||||
)
|
||||
|
||||
context.update({"messages": messages, "result": result})
|
||||
|
||||
logger.info(context)
|
||||
|
||||
return templates.TemplateResponse("status.html", context=context)
|
||||
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
{% extends "components/main/base.html" %}
|
||||
{% block content %}
|
||||
<section class="hero is-large is-info">
|
||||
<section class="hero is-medium is-info">
|
||||
<div class="hero-body">
|
||||
<p class="title">SWOT ANALYZER</p>
|
||||
<p class="subtitle">Strengths, Weaknesses, Opportunities and Threats
|
||||
@ -31,29 +31,28 @@
|
||||
</Search>
|
||||
</div>
|
||||
</section>
|
||||
<section class="section">
|
||||
<div class="container"
|
||||
id="status">
|
||||
<div class="box"
|
||||
id="status"
|
||||
hx-get={{ url_for('get_status') }}
|
||||
hx-trigger='load, every 1s'
|
||||
hx-swap='innerHTML'
|
||||
style="display: none">
|
||||
</div>
|
||||
<div class="box"
|
||||
id="result"
|
||||
hx-get={{ url_for('get_result') }}
|
||||
hx-trigger="load, every 1s[!this.querySelector('#result-container') || this.style.display === 'none']"
|
||||
hx-swap='innerHTML'
|
||||
hx-on:after-request="
|
||||
if(this.innerHTML.trim().length > 0) {
|
||||
const statusDiv = document.querySelector(#status);
|
||||
if (statusDiv) statusDiv.style.display = 'none';
|
||||
this.style.display = 'block'
|
||||
}
|
||||
">
|
||||
</div>
|
||||
<section class="section"
|
||||
id="analysis-content">
|
||||
<div class="box"
|
||||
id="status"
|
||||
hx-get={{ url_for('get_status') }}
|
||||
hx-trigger="load, every 1s"
|
||||
hx-swap="innerHTML"
|
||||
style="display: none">
|
||||
</div>
|
||||
<div class="box"
|
||||
id="result"
|
||||
hx-get={{ url_for('get_result') }}
|
||||
hx-trigger="load, every 1s[!this.querySelector('#result-container') || this.style.display === 'none']"
|
||||
hx-swap="innerHTML"
|
||||
hx-on:after-request="
|
||||
if(this.innerHTML.trim().length > 0) {
|
||||
console.log('Going to turn off the status element and load the result element.')
|
||||
const statusDiv = document.querySelector('#status');
|
||||
if (statusDiv) statusDiv.style.display = 'none';
|
||||
this.style.display = 'block'
|
||||
}
|
||||
">
|
||||
</div>
|
||||
</section>
|
||||
{% endblock content %}
|
@ -1,17 +1,19 @@
|
||||
{% if result %}
|
||||
<section class="section"
|
||||
id="result-container">
|
||||
<div class="container"
|
||||
id="result-container">
|
||||
<h2 class="title is-2">
|
||||
{{ result }}
|
||||
</h2>
|
||||
<div class="container">
|
||||
<h2 class="subtitle is-2">Analysis Complete</h2>
|
||||
<div class="fixed-grid">
|
||||
<div class="grid">
|
||||
{% for cat in result %}
|
||||
{% for cat, val in result.items() %}
|
||||
<div class="cell">
|
||||
<div class="content">
|
||||
<ul>
|
||||
{% for result in cat %}
|
||||
<ResultEntry result=result>
|
||||
{% for value in val %}
|
||||
<ResultEntry result=value>
|
||||
{% if cat == 'strengths' %}
|
||||
<i class="fas fa-solid fa-arrow-up"></i>
|
||||
{% elif cat == 'weaknesses' %}
|
||||
@ -23,7 +25,6 @@
|
||||
class="fas fa-solid fa-triangle-exclamation"></i>
|
||||
{% endif %}
|
||||
</ResultEntry>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -7,18 +7,20 @@
|
||||
{% set is_loading = loop.last and not result %}
|
||||
{% set is_tool_message = message.startswith('Using tool') %}
|
||||
<div class="box">
|
||||
{% set bg_color = 'danger' if is_error else ('dark' if is_loading else
|
||||
"info") %}
|
||||
{% if is_error %}
|
||||
{% set bg_color = 'danger' %}
|
||||
{% set header_content, content = message.split('body:', 1) %}
|
||||
{% elif is_tool_message %}
|
||||
{% set header_content, content = message.split(' ', 2)[2].split('...', 1) %}
|
||||
{% elif is_loading %}
|
||||
{% set content = message %}
|
||||
{% set header_content = 'In Progress' %}
|
||||
{% else %}
|
||||
{% set bg_color = 'success' %}
|
||||
{% set content = message %}
|
||||
{% set header_content = 'Complete' %}
|
||||
{% elif is_tool_message %}
|
||||
{% set bg_color = 'dark'%}
|
||||
{% set header_content, content = message.split(' ', 2)[2].split('...', 1) %}
|
||||
{% else %}
|
||||
{% set bg_color = 'info' %}
|
||||
{% set content = message %}
|
||||
{% set header_content = 'In Progress' %}
|
||||
{% endif %}
|
||||
<StatusResult div_class={{ bg_color }}
|
||||
header_content={{ header_content }}>{{ message }}
|
||||
|
40
uv.lock
generated
40
uv.lock
generated
@ -282,7 +282,7 @@ requires-dist = [
|
||||
{ name = "aiomysql", specifier = "==0.2.0" },
|
||||
{ name = "amqp", specifier = "==5.3.1" },
|
||||
{ name = "annotated-types", specifier = "==0.7.0" },
|
||||
{ name = "anthropic", specifier = "==0.43.1" },
|
||||
{ name = "anthropic", specifier = "==0.44.0" },
|
||||
{ name = "anyio", specifier = "==4.8.0" },
|
||||
{ name = "appdirs", specifier = "==1.4.4" },
|
||||
{ name = "asgiref", specifier = "==3.8.1" },
|
||||
@ -290,7 +290,7 @@ requires-dist = [
|
||||
{ name = "asyncpg", specifier = "==0.30.0" },
|
||||
{ name = "beautifulsoup4", specifier = "==4.12.3" },
|
||||
{ name = "billiard", specifier = "==4.2.1" },
|
||||
{ name = "cachetools", specifier = "==5.5.0" },
|
||||
{ name = "cachetools", specifier = "==5.5.1" },
|
||||
{ name = "celery", specifier = "==5.4.0" },
|
||||
{ name = "certifi", specifier = "==2024.12.14" },
|
||||
{ name = "charset-normalizer", specifier = "==3.4.1" },
|
||||
@ -343,7 +343,7 @@ requires-dist = [
|
||||
{ name = "mdurl", specifier = "==0.1.2" },
|
||||
{ name = "mistralai", specifier = "==1.4.0" },
|
||||
{ name = "mypy-extensions", specifier = "==1.0.0" },
|
||||
{ name = "openai", specifier = "==1.59.9" },
|
||||
{ name = "openai", specifier = "==1.60.0" },
|
||||
{ name = "opentelemetry-api", specifier = "==1.29.0" },
|
||||
{ name = "opentelemetry-exporter-otlp-proto-common", specifier = "==1.29.0" },
|
||||
{ name = "opentelemetry-exporter-otlp-proto-http", specifier = "==1.29.0" },
|
||||
@ -405,7 +405,7 @@ requires-dist = [
|
||||
{ name = "tqdm", specifier = "==4.67.1" },
|
||||
{ name = "typing-extensions", specifier = "==4.12.2" },
|
||||
{ name = "typing-inspect", specifier = "==0.9.0" },
|
||||
{ name = "tzdata", specifier = "==2024.2" },
|
||||
{ name = "tzdata", specifier = "==2025.1" },
|
||||
{ name = "update-checker", specifier = "==0.18.0" },
|
||||
{ name = "urllib3", specifier = "==1.26.20" },
|
||||
{ name = "uvicorn", specifier = "==0.34.0" },
|
||||
@ -454,7 +454,7 @@ dev = [
|
||||
{ name = "fastapi", specifier = "==0.115.6" },
|
||||
{ name = "fastapi-debug-toolbar", git = "https://github.com/fsecada01/fastapi-debug-toolbar.git?rev=2da9f1e724d1d7ca56990ba7a8e72598fa3e1cf4" },
|
||||
{ name = "fastjsonschema", specifier = "==2.21.1" },
|
||||
{ name = "filelock", specifier = "==3.16.1" },
|
||||
{ name = "filelock", specifier = "==3.17.0" },
|
||||
{ name = "fqdn", specifier = "==1.5.1" },
|
||||
{ name = "greenlet", specifier = "==3.1.1" },
|
||||
{ name = "h11", specifier = "==0.14.0" },
|
||||
@ -606,7 +606,7 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "anthropic"
|
||||
version = "0.43.1"
|
||||
version = "0.44.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "anyio" },
|
||||
@ -617,9 +617,9 @@ dependencies = [
|
||||
{ name = "sniffio" },
|
||||
{ name = "typing-extensions" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/ca/d8/238c2bc59e41a787e7b62460adfc7b2edd88f28b0a14e292801a72725369/anthropic-0.43.1.tar.gz", hash = "sha256:c7f13e4b7b515ac4a3111142310b214527c0fc561485e5bc9b582e49fe3adba2", size = 195298 }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/eb/34/ed394012684f7d6e36bb36c8b7c82b438f0ef189d2afd3d0090b85801211/anthropic-0.44.0.tar.gz", hash = "sha256:dc5c91c8b0463f97513d2e79350511ef295a56910bac4fbbe9491016c71f2ef0", size = 196065 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/89/2b/63b167d76401f759c8c4ff0266042e60aac6fd3cc0685b27437ceaaf95eb/anthropic-0.43.1-py3-none-any.whl", hash = "sha256:20759c25cd0f4072eb966b0180a41c061c156473bbb674da6a3f1e92e1ad78f8", size = 208170 },
|
||||
{ url = "https://files.pythonhosted.org/packages/d3/ad/c3c7d199eedc0b6d4621deed8dc1ed252ce399400cd76f1da098f1f50e56/anthropic-0.44.0-py3-none-any.whl", hash = "sha256:7087ccfc8ed7b164f971e094495cd3aeabac1e435fa393480cc146c87946c21c", size = 208634 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -823,11 +823,11 @@ css = [
|
||||
|
||||
[[package]]
|
||||
name = "cachetools"
|
||||
version = "5.5.0"
|
||||
version = "5.5.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/c3/38/a0f315319737ecf45b4319a8cd1f3a908e29d9277b46942263292115eee7/cachetools-5.5.0.tar.gz", hash = "sha256:2cc24fb4cbe39633fb7badd9db9ca6295d766d9c2995f245725a46715d050f2a", size = 27661 }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/d9/74/57df1ab0ce6bc5f6fa868e08de20df8ac58f9c44330c7671ad922d2bbeae/cachetools-5.5.1.tar.gz", hash = "sha256:70f238fbba50383ef62e55c6aff6d9673175fe59f7c6782c7a0b9e38f4a9df95", size = 28044 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/a4/07/14f8ad37f2d12a5ce41206c21820d8cb6561b728e51fad4530dff0552a67/cachetools-5.5.0-py3-none-any.whl", hash = "sha256:02134e8439cdc2ffb62023ce1debca2944c3f289d66bb17ead3ab3dede74b292", size = 9524 },
|
||||
{ url = "https://files.pythonhosted.org/packages/ec/4e/de4ff18bcf55857ba18d3a4bd48c8a9fde6bb0980c9d20b263f05387fd88/cachetools-5.5.1-py3-none-any.whl", hash = "sha256:b76651fdc3b24ead3c648bbdeeb940c1b04d365b38b4af66788f9ec4a81d42bb", size = 9530 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1162,11 +1162,11 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "filelock"
|
||||
version = "3.16.1"
|
||||
version = "3.17.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/9d/db/3ef5bb276dae18d6ec2124224403d1d67bccdbefc17af4cc8f553e341ab1/filelock-3.16.1.tar.gz", hash = "sha256:c249fbfcd5db47e5e2d6d62198e565475ee65e4831e2561c8e313fa7eb961435", size = 18037 }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/dc/9c/0b15fb47b464e1b663b1acd1253a062aa5feecb07d4e597daea542ebd2b5/filelock-3.17.0.tar.gz", hash = "sha256:ee4e77401ef576ebb38cd7f13b9b28893194acc20a8e68e18730ba9c0e54660e", size = 18027 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/b9/f8/feced7779d755758a52d1f6635d990b8d98dc0a29fa568bbe0625f18fdf3/filelock-3.16.1-py3-none-any.whl", hash = "sha256:2082e5703d51fbf98ea75855d9d5527e33d8ff23099bec374a134febee6946b0", size = 16163 },
|
||||
{ url = "https://files.pythonhosted.org/packages/89/ec/00d68c4ddfedfe64159999e5f8a98fb8442729a63e2077eb9dcd89623d27/filelock-3.17.0-py3-none-any.whl", hash = "sha256:533dc2f7ba78dc2f0f531fc6c4940addf7b70a481e269a5a3b93be94ffbe8338", size = 16164 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2091,7 +2091,7 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "openai"
|
||||
version = "1.59.9"
|
||||
version = "1.60.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "anyio" },
|
||||
@ -2103,9 +2103,9 @@ dependencies = [
|
||||
{ name = "tqdm" },
|
||||
{ name = "typing-extensions" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/ec/2d/04faa92bac0341649223398503db4415d2f658a757d9d32bb68f3378ddd0/openai-1.59.9.tar.gz", hash = "sha256:ec1a20b0351b4c3e65c6292db71d8233515437c6065efd4fd50edeb55df5f5d2", size = 347134 }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/d4/2d/9bdf4435d7669b4d027d6d69b4ac82f6be76153d9e90d3155d4224626a29/openai-1.60.0.tar.gz", hash = "sha256:7fa536cd4b644718645b874d2706e36dbbef38b327e42ca0623275da347ee1a9", size = 347844 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/07/b4/57f1954a4560092ad8c45f07ad183eab9c8e093e0a1db829f9b506b2d5d1/openai-1.59.9-py3-none-any.whl", hash = "sha256:61a0608a1313c08ddf92fe793b6dbd1630675a1fe3866b2f96447ce30050c448", size = 455527 },
|
||||
{ url = "https://files.pythonhosted.org/packages/c0/53/782008d94f5f3141795e65bd7f87afaebb97e7516342299c1b1a08d5aaf8/openai-1.60.0-py3-none-any.whl", hash = "sha256:df06c43be8018274980ac363da07d4b417bd835ead1c66e14396f6f15a0d5dda", size = 456109 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3309,11 +3309,11 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "tzdata"
|
||||
version = "2024.2"
|
||||
version = "2025.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/e1/34/943888654477a574a86a98e9896bae89c7aa15078ec29f490fef2f1e5384/tzdata-2024.2.tar.gz", hash = "sha256:7d85cc416e9382e69095b7bdf4afd9e3880418a2413feec7069d533d6b4e31cc", size = 193282 }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/43/0f/fa4723f22942480be4ca9527bbde8d43f6c3f2fe8412f00e7f5f6746bc8b/tzdata-2025.1.tar.gz", hash = "sha256:24894909e88cdb28bd1636c6887801df64cb485bd593f2fd83ef29075a81d694", size = 194950 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/a6/ab/7e5f53c3b9d14972843a647d8d7a853969a58aecc7559cb3267302c94774/tzdata-2024.2-py2.py3-none-any.whl", hash = "sha256:a48093786cdcde33cad18c2555e8532f34422074448fbc874186f0abd79565cd", size = 346586 },
|
||||
{ url = "https://files.pythonhosted.org/packages/0f/dd/84f10e23edd882c6f968c21c2434fe67bd4a528967067515feca9e611e5e/tzdata-2025.1-py2.py3-none-any.whl", hash = "sha256:7e127113816800496f027041c570f50bcd464a020098a3b6b199517772303639", size = 346762 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
Loading…
x
Reference in New Issue
Block a user