mirror of
https://github.com/fsecada01/Pygentic-AI.git
synced 2025-07-08 20:24:04 +00:00
initial building of routers and Agent management of SWOT analysis
This commit is contained in:
@ -12,6 +12,7 @@ httpx[socks]
|
|||||||
httpx-html
|
httpx-html
|
||||||
html5lib
|
html5lib
|
||||||
hypercorn; platform_system == 'Windows'
|
hypercorn; platform_system == 'Windows'
|
||||||
|
jinjax
|
||||||
loguru
|
loguru
|
||||||
lxml
|
lxml
|
||||||
lxml[html_clean]
|
lxml[html_clean]
|
||||||
@ -19,6 +20,7 @@ python-dateutil
|
|||||||
python-decouple
|
python-decouple
|
||||||
python-slugify
|
python-slugify
|
||||||
psycopg
|
psycopg
|
||||||
|
pydantic-ai[examples]
|
||||||
pytz
|
pytz
|
||||||
redis
|
redis
|
||||||
simplejson
|
simplejson
|
||||||
|
@ -10,16 +10,29 @@ annotated-types==0.7.0
|
|||||||
# via
|
# via
|
||||||
# pydantic
|
# pydantic
|
||||||
# sqlmodel-crud-utilities
|
# sqlmodel-crud-utilities
|
||||||
|
anthropic==0.43.0
|
||||||
|
# via pydantic-ai-slim
|
||||||
anyio==4.8.0
|
anyio==4.8.0
|
||||||
# via
|
# via
|
||||||
|
# anthropic
|
||||||
|
# groq
|
||||||
# httpx
|
# httpx
|
||||||
|
# openai
|
||||||
# starlette
|
# starlette
|
||||||
appdirs==1.4.4
|
appdirs==1.4.4
|
||||||
# via pyppeteer
|
# via pyppeteer
|
||||||
|
asgiref==3.8.1
|
||||||
|
# via opentelemetry-instrumentation-asgi
|
||||||
|
asttokens==2.4.1
|
||||||
|
# via devtools
|
||||||
|
asyncpg==0.30.0
|
||||||
|
# via pydantic-ai-examples
|
||||||
beautifulsoup4==4.12.3
|
beautifulsoup4==4.12.3
|
||||||
# via httpx-html
|
# via httpx-html
|
||||||
billiard==4.2.1
|
billiard==4.2.1
|
||||||
# via celery
|
# via celery
|
||||||
|
cachetools==5.5.0
|
||||||
|
# via google-auth
|
||||||
celery==5.4.0
|
celery==5.4.0
|
||||||
# via
|
# via
|
||||||
# -r core_requirements.in
|
# -r core_requirements.in
|
||||||
@ -29,6 +42,9 @@ certifi==2024.12.14
|
|||||||
# httpcore
|
# httpcore
|
||||||
# httpx
|
# httpx
|
||||||
# pyppeteer
|
# pyppeteer
|
||||||
|
# requests
|
||||||
|
charset-normalizer==3.4.1
|
||||||
|
# via requests
|
||||||
click==8.1.8
|
click==8.1.8
|
||||||
# via
|
# via
|
||||||
# celery
|
# celery
|
||||||
@ -45,11 +61,32 @@ click-repl==0.3.0
|
|||||||
colorama==0.4.6
|
colorama==0.4.6
|
||||||
# via
|
# via
|
||||||
# click
|
# click
|
||||||
|
# griffe
|
||||||
# loguru
|
# loguru
|
||||||
# sqlmodel-crud-utilities
|
# sqlmodel-crud-utilities
|
||||||
# tqdm
|
# tqdm
|
||||||
cssselect==1.2.0
|
cssselect==1.2.0
|
||||||
# via pyquery
|
# via pyquery
|
||||||
|
deprecated==1.2.15
|
||||||
|
# via
|
||||||
|
# opentelemetry-api
|
||||||
|
# opentelemetry-exporter-otlp-proto-http
|
||||||
|
# opentelemetry-semantic-conventions
|
||||||
|
devtools==0.12.2
|
||||||
|
# via pydantic-ai-examples
|
||||||
|
distro==1.9.0
|
||||||
|
# via
|
||||||
|
# anthropic
|
||||||
|
# groq
|
||||||
|
# openai
|
||||||
|
eval-type-backport==0.2.2
|
||||||
|
# via
|
||||||
|
# mistralai
|
||||||
|
# pydantic-ai-slim
|
||||||
|
executing==2.1.0
|
||||||
|
# via
|
||||||
|
# devtools
|
||||||
|
# logfire
|
||||||
fake-useragent==2.0.3
|
fake-useragent==2.0.3
|
||||||
# via httpx-html
|
# via httpx-html
|
||||||
fastapi==0.115.6
|
fastapi==0.115.6
|
||||||
@ -57,17 +94,26 @@ fastapi==0.115.6
|
|||||||
# -r core_requirements.in
|
# -r core_requirements.in
|
||||||
# fastapi-restful
|
# fastapi-restful
|
||||||
# fastcrud
|
# fastcrud
|
||||||
|
# pydantic-ai-examples
|
||||||
fastapi-restful==0.6.0
|
fastapi-restful==0.6.0
|
||||||
# via -r core_requirements.in
|
# via -r core_requirements.in
|
||||||
fastcrud==0.15.5
|
fastcrud==0.15.5
|
||||||
# via -r core_requirements.in
|
# via -r core_requirements.in
|
||||||
flower==2.0.1
|
flower==2.0.1
|
||||||
# via -r core_requirements.in
|
# via -r core_requirements.in
|
||||||
|
google-auth==2.37.0
|
||||||
|
# via pydantic-ai-slim
|
||||||
|
googleapis-common-protos==1.66.0
|
||||||
|
# via opentelemetry-exporter-otlp-proto-http
|
||||||
greenlet==3.1.1
|
greenlet==3.1.1
|
||||||
# via
|
# via
|
||||||
# -r core_requirements.in
|
# -r core_requirements.in
|
||||||
# sqlalchemy
|
# sqlalchemy
|
||||||
# sqlmodel-crud-utilities
|
# sqlmodel-crud-utilities
|
||||||
|
griffe==1.5.5
|
||||||
|
# via pydantic-ai-slim
|
||||||
|
groq==0.15.0
|
||||||
|
# via pydantic-ai-slim
|
||||||
h11==0.14.0
|
h11==0.14.0
|
||||||
# via
|
# via
|
||||||
# httpcore
|
# httpcore
|
||||||
@ -85,7 +131,12 @@ httpcore==1.0.7
|
|||||||
httpx==0.28.1
|
httpx==0.28.1
|
||||||
# via
|
# via
|
||||||
# -r core_requirements.in
|
# -r core_requirements.in
|
||||||
|
# anthropic
|
||||||
|
# groq
|
||||||
# httpx-html
|
# httpx-html
|
||||||
|
# mistralai
|
||||||
|
# openai
|
||||||
|
# pydantic-ai-slim
|
||||||
httpx-html==0.11.0.dev0
|
httpx-html==0.11.0.dev0
|
||||||
# via -r core_requirements.in
|
# via -r core_requirements.in
|
||||||
humanize==4.11.0
|
humanize==4.11.0
|
||||||
@ -98,10 +149,27 @@ idna==3.10
|
|||||||
# via
|
# via
|
||||||
# anyio
|
# anyio
|
||||||
# httpx
|
# httpx
|
||||||
|
# requests
|
||||||
importlib-metadata==8.5.0
|
importlib-metadata==8.5.0
|
||||||
# via pyppeteer
|
# via
|
||||||
|
# opentelemetry-api
|
||||||
|
# pyppeteer
|
||||||
|
jinja2==3.1.5
|
||||||
|
# via jinjax
|
||||||
|
jinjax==0.48
|
||||||
|
# via -r core_requirements.in
|
||||||
|
jiter==0.8.2
|
||||||
|
# via
|
||||||
|
# anthropic
|
||||||
|
# openai
|
||||||
|
jsonpath-python==1.0.6
|
||||||
|
# via mistralai
|
||||||
kombu==5.4.2
|
kombu==5.4.2
|
||||||
# via celery
|
# via celery
|
||||||
|
logfire==3.1.1
|
||||||
|
# via pydantic-ai-examples
|
||||||
|
logfire-api==3.1.1
|
||||||
|
# via pydantic-ai-slim
|
||||||
loguru==0.7.3
|
loguru==0.7.3
|
||||||
# via
|
# via
|
||||||
# -r core_requirements.in
|
# -r core_requirements.in
|
||||||
@ -113,8 +181,75 @@ lxml==5.3.0
|
|||||||
# pyquery
|
# pyquery
|
||||||
lxml-html-clean==0.4.1
|
lxml-html-clean==0.4.1
|
||||||
# via lxml
|
# via lxml
|
||||||
|
markdown-it-py==3.0.0
|
||||||
|
# via rich
|
||||||
|
markupsafe==3.0.2
|
||||||
|
# via
|
||||||
|
# jinja2
|
||||||
|
# jinjax
|
||||||
|
mdurl==0.1.2
|
||||||
|
# via markdown-it-py
|
||||||
|
mistralai==1.3.1
|
||||||
|
# via pydantic-ai-slim
|
||||||
mypy-extensions==1.0.0
|
mypy-extensions==1.0.0
|
||||||
# via typing-inspect
|
# via typing-inspect
|
||||||
|
openai==1.59.7
|
||||||
|
# via pydantic-ai-slim
|
||||||
|
opentelemetry-api==1.29.0
|
||||||
|
# via
|
||||||
|
# opentelemetry-exporter-otlp-proto-http
|
||||||
|
# opentelemetry-instrumentation
|
||||||
|
# opentelemetry-instrumentation-asgi
|
||||||
|
# opentelemetry-instrumentation-asyncpg
|
||||||
|
# opentelemetry-instrumentation-dbapi
|
||||||
|
# opentelemetry-instrumentation-fastapi
|
||||||
|
# opentelemetry-instrumentation-sqlite3
|
||||||
|
# opentelemetry-sdk
|
||||||
|
# opentelemetry-semantic-conventions
|
||||||
|
opentelemetry-exporter-otlp-proto-common==1.29.0
|
||||||
|
# via opentelemetry-exporter-otlp-proto-http
|
||||||
|
opentelemetry-exporter-otlp-proto-http==1.29.0
|
||||||
|
# via logfire
|
||||||
|
opentelemetry-instrumentation==0.50b0
|
||||||
|
# via
|
||||||
|
# logfire
|
||||||
|
# opentelemetry-instrumentation-asgi
|
||||||
|
# opentelemetry-instrumentation-asyncpg
|
||||||
|
# opentelemetry-instrumentation-dbapi
|
||||||
|
# opentelemetry-instrumentation-fastapi
|
||||||
|
# opentelemetry-instrumentation-sqlite3
|
||||||
|
opentelemetry-instrumentation-asgi==0.50b0
|
||||||
|
# via opentelemetry-instrumentation-fastapi
|
||||||
|
opentelemetry-instrumentation-asyncpg==0.50b0
|
||||||
|
# via logfire
|
||||||
|
opentelemetry-instrumentation-dbapi==0.50b0
|
||||||
|
# via opentelemetry-instrumentation-sqlite3
|
||||||
|
opentelemetry-instrumentation-fastapi==0.50b0
|
||||||
|
# via logfire
|
||||||
|
opentelemetry-instrumentation-sqlite3==0.50b0
|
||||||
|
# via logfire
|
||||||
|
opentelemetry-proto==1.29.0
|
||||||
|
# via
|
||||||
|
# opentelemetry-exporter-otlp-proto-common
|
||||||
|
# opentelemetry-exporter-otlp-proto-http
|
||||||
|
opentelemetry-sdk==1.29.0
|
||||||
|
# via
|
||||||
|
# logfire
|
||||||
|
# opentelemetry-exporter-otlp-proto-http
|
||||||
|
opentelemetry-semantic-conventions==0.50b0
|
||||||
|
# via
|
||||||
|
# opentelemetry-instrumentation
|
||||||
|
# opentelemetry-instrumentation-asgi
|
||||||
|
# opentelemetry-instrumentation-asyncpg
|
||||||
|
# opentelemetry-instrumentation-dbapi
|
||||||
|
# opentelemetry-instrumentation-fastapi
|
||||||
|
# opentelemetry-sdk
|
||||||
|
opentelemetry-util-http==0.50b0
|
||||||
|
# via
|
||||||
|
# opentelemetry-instrumentation-asgi
|
||||||
|
# opentelemetry-instrumentation-fastapi
|
||||||
|
packaging==24.2
|
||||||
|
# via opentelemetry-instrumentation
|
||||||
parse==1.20.2
|
parse==1.20.2
|
||||||
# via httpx-html
|
# via httpx-html
|
||||||
priority==2.0.0
|
priority==2.0.0
|
||||||
@ -123,23 +258,51 @@ prometheus-client==0.21.1
|
|||||||
# via flower
|
# via flower
|
||||||
prompt-toolkit==3.0.48
|
prompt-toolkit==3.0.48
|
||||||
# via click-repl
|
# via click-repl
|
||||||
|
protobuf==5.29.3
|
||||||
|
# via
|
||||||
|
# googleapis-common-protos
|
||||||
|
# logfire
|
||||||
|
# opentelemetry-proto
|
||||||
psutil==5.9.8
|
psutil==5.9.8
|
||||||
# via fastapi-restful
|
# via fastapi-restful
|
||||||
psycopg==3.2.4
|
psycopg==3.2.4
|
||||||
# via -r core_requirements.in
|
# via -r core_requirements.in
|
||||||
|
pyasn1==0.6.1
|
||||||
|
# via
|
||||||
|
# pyasn1-modules
|
||||||
|
# rsa
|
||||||
|
pyasn1-modules==0.4.1
|
||||||
|
# via google-auth
|
||||||
pydantic==2.10.5
|
pydantic==2.10.5
|
||||||
# via
|
# via
|
||||||
|
# anthropic
|
||||||
# fastapi
|
# fastapi
|
||||||
# fastapi-restful
|
# fastapi-restful
|
||||||
# fastcrud
|
# fastcrud
|
||||||
|
# groq
|
||||||
|
# mistralai
|
||||||
|
# openai
|
||||||
|
# pydantic-ai-slim
|
||||||
# sqlmodel
|
# sqlmodel
|
||||||
# sqlmodel-crud-utilities
|
# sqlmodel-crud-utilities
|
||||||
|
pydantic-ai==0.0.18
|
||||||
|
# via -r core_requirements.in
|
||||||
|
pydantic-ai-examples==0.0.18
|
||||||
|
# via pydantic-ai
|
||||||
|
pydantic-ai-slim==0.0.18
|
||||||
|
# via
|
||||||
|
# pydantic-ai
|
||||||
|
# pydantic-ai-examples
|
||||||
pydantic-core==2.27.2
|
pydantic-core==2.27.2
|
||||||
# via
|
# via
|
||||||
# pydantic
|
# pydantic
|
||||||
# sqlmodel-crud-utilities
|
# sqlmodel-crud-utilities
|
||||||
pyee==11.1.1
|
pyee==11.1.1
|
||||||
# via pyppeteer
|
# via pyppeteer
|
||||||
|
pygments==2.19.1
|
||||||
|
# via
|
||||||
|
# devtools
|
||||||
|
# rich
|
||||||
pymysql==1.1.1
|
pymysql==1.1.1
|
||||||
# via aiomysql
|
# via aiomysql
|
||||||
pyppeteer==2.0.0
|
pyppeteer==2.0.0
|
||||||
@ -150,11 +313,14 @@ python-dateutil==2.9.0.post0
|
|||||||
# via
|
# via
|
||||||
# -r core_requirements.in
|
# -r core_requirements.in
|
||||||
# celery
|
# celery
|
||||||
|
# mistralai
|
||||||
# sqlmodel-crud-utilities
|
# sqlmodel-crud-utilities
|
||||||
python-decouple==3.8
|
python-decouple==3.8
|
||||||
# via -r core_requirements.in
|
# via -r core_requirements.in
|
||||||
python-dotenv==1.0.1
|
python-dotenv==1.0.1
|
||||||
# via sqlmodel-crud-utilities
|
# via sqlmodel-crud-utilities
|
||||||
|
python-multipart==0.0.20
|
||||||
|
# via pydantic-ai-examples
|
||||||
python-slugify==8.0.4
|
python-slugify==8.0.4
|
||||||
# via -r core_requirements.in
|
# via -r core_requirements.in
|
||||||
pytz==2024.2
|
pytz==2024.2
|
||||||
@ -163,16 +329,31 @@ pytz==2024.2
|
|||||||
# flower
|
# flower
|
||||||
redis==5.2.1
|
redis==5.2.1
|
||||||
# via -r core_requirements.in
|
# via -r core_requirements.in
|
||||||
|
requests==2.32.3
|
||||||
|
# via
|
||||||
|
# opentelemetry-exporter-otlp-proto-http
|
||||||
|
# pydantic-ai-slim
|
||||||
|
rich==13.9.4
|
||||||
|
# via
|
||||||
|
# logfire
|
||||||
|
# pydantic-ai-examples
|
||||||
|
rsa==4.9
|
||||||
|
# via google-auth
|
||||||
simplejson==3.19.3
|
simplejson==3.19.3
|
||||||
# via -r core_requirements.in
|
# via -r core_requirements.in
|
||||||
six==1.17.0
|
six==1.17.0
|
||||||
# via
|
# via
|
||||||
|
# asttokens
|
||||||
# html5lib
|
# html5lib
|
||||||
# python-dateutil
|
# python-dateutil
|
||||||
# sqlalchemy-mixins
|
# sqlalchemy-mixins
|
||||||
# sqlmodel-crud-utilities
|
# sqlmodel-crud-utilities
|
||||||
sniffio==1.3.1
|
sniffio==1.3.1
|
||||||
# via anyio
|
# via
|
||||||
|
# anthropic
|
||||||
|
# anyio
|
||||||
|
# groq
|
||||||
|
# openai
|
||||||
socksio==1.0.0
|
socksio==1.0.0
|
||||||
# via httpx
|
# via httpx
|
||||||
soupsieve==2.6
|
soupsieve==2.6
|
||||||
@ -201,12 +382,17 @@ text-unidecode==1.3
|
|||||||
tornado==6.4.2
|
tornado==6.4.2
|
||||||
# via flower
|
# via flower
|
||||||
tqdm==4.67.1
|
tqdm==4.67.1
|
||||||
# via pyppeteer
|
# via
|
||||||
|
# openai
|
||||||
|
# pyppeteer
|
||||||
typing-extensions==4.12.2
|
typing-extensions==4.12.2
|
||||||
# via
|
# via
|
||||||
# anyio
|
# anthropic
|
||||||
# fastapi
|
# fastapi
|
||||||
# psycopg
|
# groq
|
||||||
|
# logfire
|
||||||
|
# openai
|
||||||
|
# opentelemetry-sdk
|
||||||
# pydantic
|
# pydantic
|
||||||
# pydantic-core
|
# pydantic-core
|
||||||
# pyee
|
# pyee
|
||||||
@ -214,16 +400,22 @@ typing-extensions==4.12.2
|
|||||||
# sqlmodel-crud-utilities
|
# sqlmodel-crud-utilities
|
||||||
# typing-inspect
|
# typing-inspect
|
||||||
typing-inspect==0.9.0
|
typing-inspect==0.9.0
|
||||||
# via -r core_requirements.in
|
# via
|
||||||
|
# -r core_requirements.in
|
||||||
|
# mistralai
|
||||||
tzdata==2024.2
|
tzdata==2024.2
|
||||||
# via
|
# via
|
||||||
# celery
|
# celery
|
||||||
# kombu
|
# kombu
|
||||||
# psycopg
|
# psycopg
|
||||||
urllib3==1.26.20
|
urllib3==1.26.20
|
||||||
# via pyppeteer
|
# via
|
||||||
|
# pyppeteer
|
||||||
|
# requests
|
||||||
uvicorn==0.34.0
|
uvicorn==0.34.0
|
||||||
# via -r core_requirements.in
|
# via
|
||||||
|
# -r core_requirements.in
|
||||||
|
# pydantic-ai-examples
|
||||||
vine==5.1.0
|
vine==5.1.0
|
||||||
# via
|
# via
|
||||||
# amqp
|
# amqp
|
||||||
@ -241,6 +433,11 @@ win32-setctime==1.2.0
|
|||||||
# via
|
# via
|
||||||
# loguru
|
# loguru
|
||||||
# sqlmodel-crud-utilities
|
# sqlmodel-crud-utilities
|
||||||
|
wrapt==1.17.2
|
||||||
|
# via
|
||||||
|
# deprecated
|
||||||
|
# opentelemetry-instrumentation
|
||||||
|
# opentelemetry-instrumentation-dbapi
|
||||||
wsproto==1.2.0
|
wsproto==1.2.0
|
||||||
# via hypercorn
|
# via hypercorn
|
||||||
xmljson==0.2.1
|
xmljson==0.2.1
|
||||||
|
@ -19,8 +19,10 @@ argon2-cffi-bindings==21.2.0
|
|||||||
# via argon2-cffi
|
# via argon2-cffi
|
||||||
arrow==1.3.0
|
arrow==1.3.0
|
||||||
# via isoduration
|
# via isoduration
|
||||||
asttokens==3.0.0
|
asttokens==2.4.1
|
||||||
# via stack-data
|
# via
|
||||||
|
# -c core_requirements.txt
|
||||||
|
# stack-data
|
||||||
async-lru==2.0.4
|
async-lru==2.0.4
|
||||||
# via jupyterlab
|
# via jupyterlab
|
||||||
attrs==24.3.0
|
attrs==24.3.0
|
||||||
@ -48,7 +50,9 @@ cffi==1.17.1
|
|||||||
cfgv==3.4.0
|
cfgv==3.4.0
|
||||||
# via pre-commit
|
# via pre-commit
|
||||||
charset-normalizer==3.4.1
|
charset-normalizer==3.4.1
|
||||||
# via requests
|
# via
|
||||||
|
# -c core_requirements.txt
|
||||||
|
# requests
|
||||||
click==8.1.8
|
click==8.1.8
|
||||||
# via
|
# via
|
||||||
# -c core_requirements.txt
|
# -c core_requirements.txt
|
||||||
@ -60,7 +64,7 @@ colorama==0.4.6
|
|||||||
# ipython
|
# ipython
|
||||||
comm==0.2.2
|
comm==0.2.2
|
||||||
# via ipykernel
|
# via ipykernel
|
||||||
debugpy==1.8.11
|
debugpy==1.8.12
|
||||||
# via ipykernel
|
# via ipykernel
|
||||||
decorator==5.1.1
|
decorator==5.1.1
|
||||||
# via ipython
|
# via ipython
|
||||||
@ -69,7 +73,9 @@ defusedxml==0.7.1
|
|||||||
distlib==0.3.9
|
distlib==0.3.9
|
||||||
# via virtualenv
|
# via virtualenv
|
||||||
executing==2.1.0
|
executing==2.1.0
|
||||||
# via stack-data
|
# via
|
||||||
|
# -c core_requirements.txt
|
||||||
|
# stack-data
|
||||||
fastapi==0.115.6
|
fastapi==0.115.6
|
||||||
# via
|
# via
|
||||||
# -c core_requirements.txt
|
# -c core_requirements.txt
|
||||||
@ -119,6 +125,7 @@ jedi==0.19.2
|
|||||||
# via ipython
|
# via ipython
|
||||||
jinja2==3.1.5
|
jinja2==3.1.5
|
||||||
# via
|
# via
|
||||||
|
# -c core_requirements.txt
|
||||||
# fastapi-debug-toolbar
|
# fastapi-debug-toolbar
|
||||||
# jupyter-server
|
# jupyter-server
|
||||||
# jupyterlab
|
# jupyterlab
|
||||||
@ -174,6 +181,7 @@ mako==1.3.8
|
|||||||
# via alembic
|
# via alembic
|
||||||
markupsafe==3.0.2
|
markupsafe==3.0.2
|
||||||
# via
|
# via
|
||||||
|
# -c core_requirements.txt
|
||||||
# jinja2
|
# jinja2
|
||||||
# mako
|
# mako
|
||||||
# nbconvert
|
# nbconvert
|
||||||
@ -206,6 +214,7 @@ overrides==7.7.0
|
|||||||
# via jupyter-server
|
# via jupyter-server
|
||||||
packaging==24.2
|
packaging==24.2
|
||||||
# via
|
# via
|
||||||
|
# -c core_requirements.txt
|
||||||
# black
|
# black
|
||||||
# ipykernel
|
# ipykernel
|
||||||
# jupyter-server
|
# jupyter-server
|
||||||
@ -259,6 +268,7 @@ pydantic-settings==2.7.1
|
|||||||
# via fastapi-debug-toolbar
|
# via fastapi-debug-toolbar
|
||||||
pygments==2.19.1
|
pygments==2.19.1
|
||||||
# via
|
# via
|
||||||
|
# -c core_requirements.txt
|
||||||
# ipython
|
# ipython
|
||||||
# nbconvert
|
# nbconvert
|
||||||
pyinstrument==5.0.0
|
pyinstrument==5.0.0
|
||||||
@ -290,13 +300,15 @@ pyzmq==26.2.0
|
|||||||
# ipykernel
|
# ipykernel
|
||||||
# jupyter-client
|
# jupyter-client
|
||||||
# jupyter-server
|
# jupyter-server
|
||||||
referencing==0.35.1
|
referencing==0.36.0
|
||||||
# via
|
# via
|
||||||
# jsonschema
|
# jsonschema
|
||||||
# jsonschema-specifications
|
# jsonschema-specifications
|
||||||
# jupyter-events
|
# jupyter-events
|
||||||
requests==2.32.3
|
requests==2.32.3
|
||||||
# via jupyterlab-server
|
# via
|
||||||
|
# -c core_requirements.txt
|
||||||
|
# jupyterlab-server
|
||||||
rfc3339-validator==0.1.4
|
rfc3339-validator==0.1.4
|
||||||
# via
|
# via
|
||||||
# jsonschema
|
# jsonschema
|
||||||
@ -318,6 +330,7 @@ setuptools==75.8.0
|
|||||||
six==1.17.0
|
six==1.17.0
|
||||||
# via
|
# via
|
||||||
# -c core_requirements.txt
|
# -c core_requirements.txt
|
||||||
|
# asttokens
|
||||||
# python-dateutil
|
# python-dateutil
|
||||||
# rfc3339-validator
|
# rfc3339-validator
|
||||||
sniffio==1.3.1
|
sniffio==1.3.1
|
||||||
@ -374,7 +387,6 @@ typing-extensions==4.12.2
|
|||||||
# via
|
# via
|
||||||
# -c core_requirements.txt
|
# -c core_requirements.txt
|
||||||
# alembic
|
# alembic
|
||||||
# anyio
|
|
||||||
# fastapi
|
# fastapi
|
||||||
# pydantic
|
# pydantic
|
||||||
# pydantic-core
|
# pydantic-core
|
||||||
|
@ -79,24 +79,39 @@ dependencies = [
|
|||||||
"aiomysql==0.2.0",
|
"aiomysql==0.2.0",
|
||||||
"amqp==5.3.1",
|
"amqp==5.3.1",
|
||||||
"annotated-types==0.7.0",
|
"annotated-types==0.7.0",
|
||||||
|
"anthropic==0.43.0",
|
||||||
"anyio==4.8.0",
|
"anyio==4.8.0",
|
||||||
"appdirs==1.4.4",
|
"appdirs==1.4.4",
|
||||||
|
"asgiref==3.8.1",
|
||||||
|
"asttokens==2.4.1",
|
||||||
|
"asyncpg==0.30.0",
|
||||||
"beautifulsoup4==4.12.3",
|
"beautifulsoup4==4.12.3",
|
||||||
"billiard==4.2.1",
|
"billiard==4.2.1",
|
||||||
|
"cachetools==5.5.0",
|
||||||
"celery==5.4.0",
|
"celery==5.4.0",
|
||||||
"certifi==2024.12.14",
|
"certifi==2024.12.14",
|
||||||
|
"charset-normalizer==3.4.1",
|
||||||
"click-didyoumean==0.3.1",
|
"click-didyoumean==0.3.1",
|
||||||
"click-plugins==1.1.1",
|
"click-plugins==1.1.1",
|
||||||
"click-repl==0.3.0",
|
"click-repl==0.3.0",
|
||||||
"click==8.1.8",
|
"click==8.1.8",
|
||||||
"colorama==0.4.6",
|
"colorama==0.4.6",
|
||||||
"cssselect==1.2.0",
|
"cssselect==1.2.0",
|
||||||
|
"deprecated==1.2.15",
|
||||||
|
"devtools==0.12.2",
|
||||||
|
"distro==1.9.0",
|
||||||
|
"eval-type-backport==0.2.2",
|
||||||
|
"executing==2.1.0",
|
||||||
"fake-useragent==2.0.3",
|
"fake-useragent==2.0.3",
|
||||||
"fastapi-restful==0.6.0",
|
"fastapi-restful==0.6.0",
|
||||||
"fastapi==0.115.6",
|
"fastapi==0.115.6",
|
||||||
"fastcrud==0.15.5",
|
"fastcrud==0.15.5",
|
||||||
"flower==2.0.1",
|
"flower==2.0.1",
|
||||||
|
"google-auth==2.37.0",
|
||||||
|
"googleapis-common-protos==1.66.0",
|
||||||
"greenlet==3.1.1",
|
"greenlet==3.1.1",
|
||||||
|
"griffe==1.5.5",
|
||||||
|
"groq==0.15.0",
|
||||||
"h11==0.14.0",
|
"h11==0.14.0",
|
||||||
"h2==4.1.0",
|
"h2==4.1.0",
|
||||||
"hpack==4.0.0",
|
"hpack==4.0.0",
|
||||||
@ -109,29 +124,65 @@ dependencies = [
|
|||||||
"hyperframe==6.0.1",
|
"hyperframe==6.0.1",
|
||||||
"idna==3.10",
|
"idna==3.10",
|
||||||
"importlib-metadata==8.5.0",
|
"importlib-metadata==8.5.0",
|
||||||
|
"jinja2==3.1.5",
|
||||||
|
"jinjax==0.48",
|
||||||
|
"jiter==0.8.2",
|
||||||
|
"jsonpath-python==1.0.6",
|
||||||
"kombu==5.4.2",
|
"kombu==5.4.2",
|
||||||
|
"logfire-api==3.1.1",
|
||||||
|
"logfire==3.1.1",
|
||||||
"loguru==0.7.3",
|
"loguru==0.7.3",
|
||||||
"lxml-html-clean==0.4.1",
|
"lxml-html-clean==0.4.1",
|
||||||
"lxml==5.3.0",
|
"lxml==5.3.0",
|
||||||
|
"markdown-it-py==3.0.0",
|
||||||
|
"markupsafe==3.0.2",
|
||||||
|
"mdurl==0.1.2",
|
||||||
|
"mistralai==1.3.1",
|
||||||
"mypy-extensions==1.0.0",
|
"mypy-extensions==1.0.0",
|
||||||
|
"openai==1.59.7",
|
||||||
|
"opentelemetry-api==1.29.0",
|
||||||
|
"opentelemetry-exporter-otlp-proto-common==1.29.0",
|
||||||
|
"opentelemetry-exporter-otlp-proto-http==1.29.0",
|
||||||
|
"opentelemetry-instrumentation-asgi==0.50b0",
|
||||||
|
"opentelemetry-instrumentation-asyncpg==0.50b0",
|
||||||
|
"opentelemetry-instrumentation-dbapi==0.50b0",
|
||||||
|
"opentelemetry-instrumentation-fastapi==0.50b0",
|
||||||
|
"opentelemetry-instrumentation-sqlite3==0.50b0",
|
||||||
|
"opentelemetry-instrumentation==0.50b0",
|
||||||
|
"opentelemetry-proto==1.29.0",
|
||||||
|
"opentelemetry-sdk==1.29.0",
|
||||||
|
"opentelemetry-semantic-conventions==0.50b0",
|
||||||
|
"opentelemetry-util-http==0.50b0",
|
||||||
|
"packaging==24.2",
|
||||||
"parse==1.20.2",
|
"parse==1.20.2",
|
||||||
"priority==2.0.0",
|
"priority==2.0.0",
|
||||||
"prometheus-client==0.21.1",
|
"prometheus-client==0.21.1",
|
||||||
"prompt-toolkit==3.0.48",
|
"prompt-toolkit==3.0.48",
|
||||||
|
"protobuf==5.29.3",
|
||||||
"psutil==5.9.8",
|
"psutil==5.9.8",
|
||||||
"psycopg==3.2.4",
|
"psycopg==3.2.4",
|
||||||
|
"pyasn1-modules==0.4.1",
|
||||||
|
"pyasn1==0.6.1",
|
||||||
|
"pydantic-ai-examples==0.0.18",
|
||||||
|
"pydantic-ai-slim==0.0.18",
|
||||||
|
"pydantic-ai==0.0.18",
|
||||||
"pydantic-core==2.27.2",
|
"pydantic-core==2.27.2",
|
||||||
"pydantic==2.10.5",
|
"pydantic==2.10.5",
|
||||||
"pyee==11.1.1",
|
"pyee==11.1.1",
|
||||||
|
"pygments==2.19.1",
|
||||||
"pymysql==1.1.1",
|
"pymysql==1.1.1",
|
||||||
"pyppeteer==2.0.0",
|
"pyppeteer==2.0.0",
|
||||||
"pyquery==2.0.1",
|
"pyquery==2.0.1",
|
||||||
"python-dateutil==2.9.0.post0",
|
"python-dateutil==2.9.0.post0",
|
||||||
"python-decouple==3.8",
|
"python-decouple==3.8",
|
||||||
"python-dotenv==1.0.1",
|
"python-dotenv==1.0.1",
|
||||||
|
"python-multipart==0.0.20",
|
||||||
"python-slugify==8.0.4",
|
"python-slugify==8.0.4",
|
||||||
"pytz==2024.2",
|
"pytz==2024.2",
|
||||||
"redis==5.2.1",
|
"redis==5.2.1",
|
||||||
|
"requests==2.32.3",
|
||||||
|
"rich==13.9.4",
|
||||||
|
"rsa==4.9",
|
||||||
"simplejson==3.19.3",
|
"simplejson==3.19.3",
|
||||||
"six==1.17.0",
|
"six==1.17.0",
|
||||||
"sniffio==1.3.1",
|
"sniffio==1.3.1",
|
||||||
@ -157,6 +208,7 @@ dependencies = [
|
|||||||
"webencodings==0.5.1",
|
"webencodings==0.5.1",
|
||||||
"websockets==10.4",
|
"websockets==10.4",
|
||||||
"win32-setctime==1.2.0",
|
"win32-setctime==1.2.0",
|
||||||
|
"wrapt==1.17.2",
|
||||||
"wsproto==1.2.0",
|
"wsproto==1.2.0",
|
||||||
"xmljson==0.2.1",
|
"xmljson==0.2.1",
|
||||||
"xmltodict==0.14.2",
|
"xmltodict==0.14.2",
|
||||||
@ -171,7 +223,7 @@ dev = [
|
|||||||
"argon2-cffi-bindings==21.2.0",
|
"argon2-cffi-bindings==21.2.0",
|
||||||
"argon2-cffi==23.1.0",
|
"argon2-cffi==23.1.0",
|
||||||
"arrow==1.3.0",
|
"arrow==1.3.0",
|
||||||
"asttokens==3.0.0",
|
"asttokens==2.4.1",
|
||||||
"async-lru==2.0.4",
|
"async-lru==2.0.4",
|
||||||
"attrs==24.3.0",
|
"attrs==24.3.0",
|
||||||
"babel==2.16.0",
|
"babel==2.16.0",
|
||||||
@ -185,7 +237,7 @@ dev = [
|
|||||||
"click==8.1.8",
|
"click==8.1.8",
|
||||||
"colorama==0.4.6",
|
"colorama==0.4.6",
|
||||||
"comm==0.2.2",
|
"comm==0.2.2",
|
||||||
"debugpy==1.8.11",
|
"debugpy==1.8.12",
|
||||||
"decorator==5.1.1",
|
"decorator==5.1.1",
|
||||||
"defusedxml==0.7.1",
|
"defusedxml==0.7.1",
|
||||||
"distlib==0.3.9",
|
"distlib==0.3.9",
|
||||||
@ -257,7 +309,7 @@ dev = [
|
|||||||
"pywinpty==2.0.14",
|
"pywinpty==2.0.14",
|
||||||
"pyyaml==6.0.2",
|
"pyyaml==6.0.2",
|
||||||
"pyzmq==26.2.0",
|
"pyzmq==26.2.0",
|
||||||
"referencing==0.35.1",
|
"referencing==0.36.0",
|
||||||
"requests==2.32.3",
|
"requests==2.32.3",
|
||||||
"rfc3339-validator==0.1.4",
|
"rfc3339-validator==0.1.4",
|
||||||
"rfc3986-validator==0.1.1",
|
"rfc3986-validator==0.1.1",
|
||||||
|
@ -0,0 +1,21 @@
|
|||||||
|
AI_MODEL = "gpt-4o"
|
||||||
|
default_system_prompt = """
|
||||||
|
You are an advanced and intelligent AI assistant specializing in generating
|
||||||
|
comprehensive and detailed SWOT analyses for a variety of scenarios, topics,
|
||||||
|
or businesses.
|
||||||
|
|
||||||
|
Your task is to analyze given entities, situations, or contexts and organize
|
||||||
|
the information systematically into (typically provided as an URL value):
|
||||||
|
1. **Strengths**: Internal factors that give a competitive advantage or are beneficial.
|
||||||
|
2. **Weaknesses**: Internal factors that hinder performance or present challenges.
|
||||||
|
3. **Opportunities**: External factors that can be leveraged for growth or improvement.
|
||||||
|
4. **Threats**: External factors that pose risks or challenges.
|
||||||
|
|
||||||
|
Guidelines for your approach:
|
||||||
|
- Be concise yet descriptive in your explanation for each category.
|
||||||
|
- Consider internal factors for Strengths and Weaknesses (e.g., resources,
|
||||||
|
skills, limitations).
|
||||||
|
- Focus on external or environmental factors for Opportunities and Threats (
|
||||||
|
e.g., market trends, competition, external risks).
|
||||||
|
- Provide additional context or examples to support your points when relevant.
|
||||||
|
"""
|
||||||
|
@ -0,0 +1,36 @@
|
|||||||
|
from collections.abc import Callable
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
from pydantic_ai import Agent
|
||||||
|
from pydantic_ai.models.openai import OpenAIModel
|
||||||
|
|
||||||
|
from backend.core.consts import AI_MODEL, default_system_prompt
|
||||||
|
from backend.db.base import Base
|
||||||
|
from backend.utils import get_val
|
||||||
|
|
||||||
|
|
||||||
|
class SwotAnalysis(Base):
|
||||||
|
"""SQLModel for SWOT Analysis Response Object"""
|
||||||
|
|
||||||
|
strengths: list[str]
|
||||||
|
weaknesses: list[str]
|
||||||
|
opportunities: list[str]
|
||||||
|
threats: list[str]
|
||||||
|
analysis: str
|
||||||
|
|
||||||
|
|
||||||
|
class SwotAgentDeps(Base):
|
||||||
|
"""Agent Dependencies for SWOT Analysis"""
|
||||||
|
|
||||||
|
request: Any | None = None
|
||||||
|
update_status_func: Callable | None = None
|
||||||
|
tool_history: list[str]
|
||||||
|
|
||||||
|
|
||||||
|
swot_agent = Agent(
|
||||||
|
OpenAIModel(model_name=AI_MODEL, api_key=get_val("OPENAI_API_KEY")),
|
||||||
|
deps_type=SwotAgentDeps,
|
||||||
|
result_type=SwotAnalysis,
|
||||||
|
system_prompt=default_system_prompt,
|
||||||
|
retries=5,
|
||||||
|
)
|
||||||
|
95
src/backend/core/tools.py
Normal file
95
src/backend/core/tools.py
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
import httpx
|
||||||
|
from bs4 import BeautifulSoup as soup
|
||||||
|
from pydantic_ai import RunContext
|
||||||
|
|
||||||
|
from backend.core.consts import AI_MODEL
|
||||||
|
from backend.core.core import SwotAgentDeps, swot_agent
|
||||||
|
from backend.core.utils import report_tool_usage
|
||||||
|
from backend.logger import logger
|
||||||
|
|
||||||
|
|
||||||
|
@swot_agent.tool(prepare=report_tool_usage)
|
||||||
|
async def fetch_website_content(
|
||||||
|
_ctx: RunContext[SwotAgentDeps], url: str
|
||||||
|
) -> str:
|
||||||
|
"""
|
||||||
|
Fetches the HTML content of the given URL via httpx and beautifulsoup
|
||||||
|
|
||||||
|
:param _ctx: RunContext[SwotAgentDeps]
|
||||||
|
:param url: str
|
||||||
|
:return: str
|
||||||
|
"""
|
||||||
|
logger.info(f"Fetching website content for: {url}")
|
||||||
|
async with httpx.AsyncClient(follow_redirects=True) as http_client:
|
||||||
|
try:
|
||||||
|
response = await http_client.get(url)
|
||||||
|
response.raise_for_status()
|
||||||
|
html_content = response.text
|
||||||
|
content = soup(html_content, "html.parser")
|
||||||
|
text_content = content.get_text(separator=" ", strip=True)
|
||||||
|
return text_content
|
||||||
|
except httpx.HTTPError as e:
|
||||||
|
logger.info(f"Request failed: {e}")
|
||||||
|
raise
|
||||||
|
|
||||||
|
|
||||||
|
@swot_agent.tool(prepare=report_tool_usage)
|
||||||
|
async def analyze_competition(
|
||||||
|
ctx: RunContext[SwotAgentDeps],
|
||||||
|
product_name: str,
|
||||||
|
product_description: str,
|
||||||
|
) -> str:
|
||||||
|
"""Analyzes the competition for the given product using the Gemini model."""
|
||||||
|
logger.info(f"Analyzing competition for: {product_name}")
|
||||||
|
|
||||||
|
prompt = f"""
|
||||||
|
You are a competitive analysis expert. Analyze the competition for the following product:
|
||||||
|
Product Name: {product_name}
|
||||||
|
Product Description: {product_description}
|
||||||
|
|
||||||
|
Provide a detailed analysis of:
|
||||||
|
1. Key competitors and their market position
|
||||||
|
2. Competitive advantages and disadvantages
|
||||||
|
3. Market trends and potential disruptions
|
||||||
|
4. Entry barriers and competitive pressures
|
||||||
|
"""
|
||||||
|
|
||||||
|
if not ctx.deps.client:
|
||||||
|
logger.info("Error: OpenAI client not initialized.")
|
||||||
|
return ""
|
||||||
|
try:
|
||||||
|
response = await ctx.deps.client.aio.models.generate_content(
|
||||||
|
model=AI_MODEL,
|
||||||
|
contents=prompt,
|
||||||
|
)
|
||||||
|
return response.text
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Error analyzing competition: {e}")
|
||||||
|
return f"Error analyzing competition: {e}"
|
||||||
|
|
||||||
|
|
||||||
|
@swot_agent.tool(prepare=report_tool_usage)
|
||||||
|
async def get_reddit_insights(
|
||||||
|
ctx: RunContext[SwotAgentDeps], query: str, subreddit_name: str = "python"
|
||||||
|
):
|
||||||
|
"""
|
||||||
|
A tool to gain insights from a subreddit. Data is returned as string
|
||||||
|
with newlines
|
||||||
|
|
||||||
|
:param ctx: RunContext[SwotAgentDeps]
|
||||||
|
:param query: str
|
||||||
|
:param subreddit_name: str
|
||||||
|
:return: str
|
||||||
|
"""
|
||||||
|
subreddit = ctx.deps.reddit.subreddit(subreddit_name)
|
||||||
|
search_results = subreddit.search(query)
|
||||||
|
|
||||||
|
insights = []
|
||||||
|
for post in search_results:
|
||||||
|
insights.append(
|
||||||
|
f"Title: {post.title}\n"
|
||||||
|
f"URL: {post.url}\n"
|
||||||
|
f"Content: {post.selftext}\n"
|
||||||
|
)
|
||||||
|
|
||||||
|
return "\n".join(insights)
|
@ -0,0 +1,25 @@
|
|||||||
|
from pydantic_ai import RunContext
|
||||||
|
from pydantic_ai.tools import ToolDefinition
|
||||||
|
|
||||||
|
from backend.core.core import SwotAgentDeps
|
||||||
|
|
||||||
|
|
||||||
|
async def report_tool_usage(
|
||||||
|
ctx: RunContext[SwotAgentDeps], tool_def: ToolDefinition
|
||||||
|
) -> ToolDefinition:
|
||||||
|
"""
|
||||||
|
Reports tool usage + results to an update function
|
||||||
|
:param ctx: RunContext[SwotAgentDeps]
|
||||||
|
:param tool_def: ToolDefinition
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
if tool_def.name in ctx.deps.tool_history:
|
||||||
|
return tool_def
|
||||||
|
|
||||||
|
if ctx.deps.update_status_func:
|
||||||
|
await ctx.deps.update_status_func(
|
||||||
|
ctx.deps.request, f"Using tool: {tool_def.name}..."
|
||||||
|
)
|
||||||
|
ctx.deps.tool_history.append(tool_def.name)
|
||||||
|
|
||||||
|
return tool_def
|
||||||
|
0
src/backend/server/router.py
Normal file
0
src/backend/server/router.py
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
from collections import defaultdict
|
||||||
|
from typing import Any, Final
|
||||||
|
|
||||||
|
ANALYZING_MESSAGE: Final = "Analyzing..."
|
||||||
|
ANALYSIS_COMPLETE_MESSAGE = "Analysis complete!"
|
||||||
|
|
||||||
|
running_tasks = set()
|
||||||
|
status_store: dict[str, list] = defaultdict(list)
|
||||||
|
result_store: dict[str, Any] = {}
|
||||||
|
157
src/backend/site/router.py
Normal file
157
src/backend/site/router.py
Normal file
@ -0,0 +1,157 @@
|
|||||||
|
import asyncio
|
||||||
|
import os
|
||||||
|
import random
|
||||||
|
import time
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
from fastapi import APIRouter, Form, Request
|
||||||
|
from jinjax import Catalog, JinjaX
|
||||||
|
from starlette.responses import HTMLResponse
|
||||||
|
from starlette.staticfiles import StaticFiles
|
||||||
|
from starlette.templating import Jinja2Templates
|
||||||
|
|
||||||
|
from backend.core.core import SwotAnalysis
|
||||||
|
from backend.logger import logger
|
||||||
|
from backend.settings import app_settings
|
||||||
|
from backend.site.consts import (
|
||||||
|
ANALYSIS_COMPLETE_MESSAGE,
|
||||||
|
ANALYZING_MESSAGE,
|
||||||
|
result_store,
|
||||||
|
status_store,
|
||||||
|
)
|
||||||
|
|
||||||
|
user_frontend = APIRouter(prefix="", tags=["frontend"])
|
||||||
|
frontend = app_settings.frontend_dir
|
||||||
|
|
||||||
|
templates = Jinja2Templates(directory=os.path.join(frontend, "templates"))
|
||||||
|
templates.env.add_extension(JinjaX)
|
||||||
|
catalog = Catalog(jinja_env=templates.env)
|
||||||
|
list(
|
||||||
|
map(
|
||||||
|
lambda folder: catalog.add_folder(
|
||||||
|
os.path.join(frontend, "components", folder) # noqa
|
||||||
|
),
|
||||||
|
("main", "forms", "snippets"),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
user_frontend.mount(
|
||||||
|
"/static",
|
||||||
|
StaticFiles(directory=os.path.join(frontend, "static")),
|
||||||
|
name="static",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def run_agent_with_progress(session_id, url):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@user_frontend.post("analyze", response_class=HTMLResponse)
|
||||||
|
async def analyze_url(request: Request, url: str = Form(...)) -> HTMLResponse:
|
||||||
|
"""
|
||||||
|
Analyze a given URL using SWOT analysis agent
|
||||||
|
:param request:
|
||||||
|
: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] = []
|
||||||
|
|
||||||
|
status_store[session_id].append(ANALYZING_MESSAGE)
|
||||||
|
|
||||||
|
logger.info(f"Starting new analysis with session ID: {session_id}")
|
||||||
|
|
||||||
|
task = asyncio.create_task(run_agent_with_progress(session_id, url))
|
||||||
|
running_tasks.add(task)
|
||||||
|
task.add_done_callback(running_tasks.discard)
|
||||||
|
|
||||||
|
return templates.TemplateResponse(
|
||||||
|
"status.html",
|
||||||
|
context={
|
||||||
|
"request": request,
|
||||||
|
"messages": [ANALYZING_MESSAGE],
|
||||||
|
"result": False,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@user_frontend.get("/status", response_class=HTMLResponse)
|
||||||
|
async def get_status(request: Request):
|
||||||
|
"""
|
||||||
|
Returns the current status messages
|
||||||
|
:param request:
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
context = {"request": request, "messages": [], "result": False}
|
||||||
|
session_id = request.session.get("analysis_id")
|
||||||
|
if 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"{messages}"
|
||||||
|
)
|
||||||
|
|
||||||
|
context.update({"messages": messages, "result": result})
|
||||||
|
|
||||||
|
return templates.TemplateResponse("status.html", context=context)
|
||||||
|
|
||||||
|
|
||||||
|
@user_frontend.get("/result", response_class=HTMLResponse)
|
||||||
|
async def get_result(request: Request) -> HTMLResponse:
|
||||||
|
"""
|
||||||
|
Returns the SWOT analysis result from the existing session ID.
|
||||||
|
|
||||||
|
:param request: Request
|
||||||
|
:return: HTMLResponse
|
||||||
|
"""
|
||||||
|
session_id = request.session.get("analysis_id")
|
||||||
|
|
||||||
|
if session_id and session_id in result_store:
|
||||||
|
result = result_store[session_id]
|
||||||
|
else:
|
||||||
|
result = None
|
||||||
|
|
||||||
|
return templates.TemplateResponse(
|
||||||
|
"result.html",
|
||||||
|
{"request": request, "result": result},
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def emulate_tool_completion(session_id: str, message: str) -> None:
|
||||||
|
"""Pydantic AI doesn't provide a post-processing hook, so we need to emulate one."""
|
||||||
|
|
||||||
|
# Sleep a random amount of time between 0 and 5 seconds
|
||||||
|
time.sleep(random.randint(0, 5))
|
||||||
|
status_store[session_id].append(message)
|
||||||
|
|
||||||
|
|
||||||
|
async def update_status(session_id: str, message: Any) -> None:
|
||||||
|
"""Updates status messages and handles SWOT analysis results."""
|
||||||
|
logger.info(f"Updating status for session {session_id}: {message}")
|
||||||
|
|
||||||
|
# Handle SWOT analysis result
|
||||||
|
if isinstance(message, SwotAnalysis):
|
||||||
|
result_store[session_id] = message.model_dump()
|
||||||
|
status_store[session_id].append(ANALYSIS_COMPLETE_MESSAGE)
|
||||||
|
return
|
||||||
|
|
||||||
|
# Handle string messages
|
||||||
|
if isinstance(message, str):
|
||||||
|
# Instantly store first status message, emulate tool completion for others
|
||||||
|
if message == ANALYSIS_COMPLETE_MESSAGE:
|
||||||
|
status_store[session_id].append(message)
|
||||||
|
else:
|
||||||
|
loop = asyncio.get_running_loop()
|
||||||
|
await loop.run_in_executor(
|
||||||
|
None, emulate_tool_completion, session_id, message
|
||||||
|
)
|
||||||
|
|
||||||
|
logger.info(
|
||||||
|
f"Status messages for session {session_id}: {status_store[session_id]}"
|
||||||
|
)
|
Reference in New Issue
Block a user