fastapi-fullstack 0.2.8__py3-none-any.whl → 0.2.9__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. {fastapi_fullstack-0.2.8.dist-info → fastapi_fullstack-0.2.9.dist-info}/METADATA +11 -5
  2. {fastapi_fullstack-0.2.8.dist-info → fastapi_fullstack-0.2.9.dist-info}/RECORD +51 -45
  3. fastapi_gen/cli.py +11 -3
  4. fastapi_gen/config.py +13 -0
  5. fastapi_gen/prompts.py +73 -22
  6. fastapi_gen/template/VARIABLES.md +5 -2
  7. fastapi_gen/template/cookiecutter.json +3 -0
  8. fastapi_gen/template/hooks/post_gen_project.py +17 -1
  9. fastapi_gen/template/{{cookiecutter.project_slug}}/.gitignore +0 -1
  10. fastapi_gen/template/{{cookiecutter.project_slug}}/ENV_VARS.md +1 -1
  11. fastapi_gen/template/{{cookiecutter.project_slug}}/Makefile +8 -8
  12. fastapi_gen/template/{{cookiecutter.project_slug}}/README.md +3 -3
  13. fastapi_gen/template/{{cookiecutter.project_slug}}/backend/.env.example +4 -4
  14. fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/agents/assistant.py +38 -0
  15. fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/agents/crewai_assistant.py +60 -1
  16. fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/agents/deepagents_assistant.py +65 -1
  17. fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/agents/langchain_assistant.py +65 -0
  18. fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/agents/langgraph_assistant.py +65 -0
  19. fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/agents/prompts.py +56 -52
  20. fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/agents/pydantic_deep_assistant.py +53 -7
  21. fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/agents/tools/__init__.py +18 -9
  22. fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/agents/tools/chart_render.py +125 -0
  23. fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/agents/tools/chart_tool.py +166 -0
  24. fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/agents/tools/fetch_url.py +106 -0
  25. fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/agents/tools/web_search.py +70 -28
  26. fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/core/config.py +25 -24
  27. fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/services/agent_session.py +283 -192
  28. fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/services/billing/pricing.py +14 -6
  29. fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/services/channels/base.py +14 -2
  30. fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/services/channels/router.py +36 -0
  31. fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/services/channels/slack.py +12 -0
  32. fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/services/channels/telegram.py +12 -0
  33. fastapi_gen/template/{{cookiecutter.project_slug}}/backend/pyproject.toml +6 -0
  34. fastapi_gen/template/{{cookiecutter.project_slug}}/backend/tests/test_agents.py +38 -12
  35. fastapi_gen/template/{{cookiecutter.project_slug}}/backend/tests/test_chart_tool.py +137 -0
  36. fastapi_gen/template/{{cookiecutter.project_slug}}/backend/tests/test_fetch_url.py +101 -0
  37. fastapi_gen/template/{{cookiecutter.project_slug}}/backend/tests/test_web_search.py +97 -0
  38. fastapi_gen/template/{{cookiecutter.project_slug}}/docker-compose.prod.yml +8 -14
  39. fastapi_gen/template/{{cookiecutter.project_slug}}/docs/configuration.md +4 -4
  40. fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/README.md +2 -2
  41. fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/chart-message.tsx +321 -0
  42. fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/chat-container.tsx +35 -7
  43. fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/kb-selector.tsx +9 -5
  44. fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/message-item.tsx +166 -103
  45. fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/tool-call-card.tsx +338 -163
  46. fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/hooks/use-chat.ts +55 -36
  47. fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/stores/chat-store.ts +86 -1
  48. fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/types/chat.ts +48 -0
  49. fastapi_gen/template/{{cookiecutter.project_slug}}/.env.prod.example +0 -112
  50. {fastapi_fullstack-0.2.8.dist-info → fastapi_fullstack-0.2.9.dist-info}/WHEEL +0 -0
  51. {fastapi_fullstack-0.2.8.dist-info → fastapi_fullstack-0.2.9.dist-info}/entry_points.txt +0 -0
  52. {fastapi_fullstack-0.2.8.dist-info → fastapi_fullstack-0.2.9.dist-info}/licenses/LICENSE +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fastapi-fullstack
3
- Version: 0.2.8
3
+ Version: 0.2.9
4
4
  Summary: Full-stack FastAPI + Next.js template generator with PydanticAI/LangChain agents, WebSocket streaming, 20+ enterprise integrations, and Logfire/LangSmith observability. Ship AI apps fast. CLI tool to generate production-ready FastAPI + Next.js projects with AI agents, auth, and observability.
5
5
  Project-URL: Homepage, https://github.com/vstorm-co/full-stack-ai-agent-template
6
6
  Project-URL: Documentation, https://github.com/vstorm-co/full-stack-ai-agent-template#readme
@@ -221,7 +221,7 @@ make dev-frontend # start the Next.js container
221
221
  |---|---|---|
222
222
  | `make dev` | `docker-compose.dev.yml` | Local development with hot-reload + bind-mounted source. |
223
223
  | `make stage` | `docker-compose.yml` | Production-like build (no bind mounts) running on localhost. Sanity-check before deploy. |
224
- | `make prod` | `docker-compose.prod.yml` | Production. Requires `.env.prod` (copy from `.env.prod.example`) + external Nginx using `nginx/nginx.conf`. |
224
+ | `make prod` | `docker-compose.prod.yml` | Production. Requires `backend/.env` (copy from `backend/.env.example`, fill real secrets) + external Nginx using `nginx/nginx.conf`. |
225
225
 
226
226
  Each env has matching `-down`, `-logs`, `-rebuild` siblings.
227
227
 
@@ -255,7 +255,7 @@ make run # uvicorn --reload
255
255
  git clone <your-repo>
256
256
  cd my_ai_app
257
257
 
258
- cp .env.prod.example .env.prod # fill in real secrets
258
+ cp backend/.env.example backend/.env # fill in real secrets
259
259
  # Configure your nginx host using nginx/nginx.conf as reference
260
260
 
261
261
  make prod # builds + starts + migrates
@@ -298,10 +298,16 @@ Use `make help` to see all available Makefile shortcuts.
298
298
  <img src="https://raw.githubusercontent.com/vstorm-co/full-stack-ai-agent-template/main/assets/app_start.gif" alt="FastAPI Fullstack Generator Demo">
299
299
  </p>
300
300
 
301
- **Live chat:**
301
+ **Live chat — web search:**
302
302
 
303
303
  <p align="center">
304
- <img src="https://raw.githubusercontent.com/vstorm-co/full-stack-ai-agent-template/main/assets/new/chat_demo_light.gif" alt="Chat Demo">
304
+ <img src="https://raw.githubusercontent.com/vstorm-co/full-stack-ai-agent-template/main/assets/chat/websearchdemo.gif" alt="Agent answering with live web search">
305
+ </p>
306
+
307
+ **Live chat — chart generation:**
308
+
309
+ <p align="center">
310
+ <img src="https://raw.githubusercontent.com/vstorm-co/full-stack-ai-agent-template/main/assets/chat/chartdemo.gif" alt="Agent generating an interactive chart">
305
311
  </p>
306
312
 
307
313
  **File upload & RAG ingestion:**
@@ -1,25 +1,24 @@
1
1
  fastapi_gen/__init__.py,sha256=oK2gEM45SpSYBb-Itgr0GII88-5qfB0kmNkj90FkvQw,257
2
- fastapi_gen/cli.py,sha256=Qek_8WQclx0CFti6KiaeoEerxH3njNFmnfmKSucPzhI,55037
3
- fastapi_gen/config.py,sha256=UrXJ1XM4HVAl31at8GjePtNal_BT7pRu37y7EEQS3f4,42364
2
+ fastapi_gen/cli.py,sha256=EEF6Oj6qlWlEbH0Qx5yK-qVpt2O459anN2P4vdDWRR0,55244
3
+ fastapi_gen/config.py,sha256=ubQPbHaqdDN3gaxkHeG8WNgVb0m9p24Gnt_TtYOWp4k,42989
4
4
  fastapi_gen/generator.py,sha256=aEYbD6eC_3B1Y7sY54AJkEWrXx58zVaTQrXqCy5r_Ac,8995
5
- fastapi_gen/prompts.py,sha256=gJSN5yAHk1hnu7f5iXNaVsK02bsGI99IdVDzBJlvNvU,59540
6
- fastapi_gen/template/VARIABLES.md,sha256=fcRE5oBddA8eezUJmZsV1-POd9Wdao6oKhujHTx-TjY,30413
7
- fastapi_gen/template/cookiecutter.json,sha256=uxXITUCwX2bCnDrRSnYQdm69r2tC8h_M-Kust2rcKRs,6066
8
- fastapi_gen/template/hooks/post_gen_project.py,sha256=8ywkryNHfytwNod3FfobKSn7n2LOUfNn6CvUc9WUSO4,49423
9
- fastapi_gen/template/{{cookiecutter.project_slug}}/.env.prod.example,sha256=oKXAPRzBKJI1Lj5TQpglCBS0KQ0Rn0XJOXXySljay1Q,2786
10
- fastapi_gen/template/{{cookiecutter.project_slug}}/.gitignore,sha256=-wgZ6PX_xKjy_wU37jkCD_husmzyVbpdC7hQsZlpNJI,1035
5
+ fastapi_gen/prompts.py,sha256=zBggPl0doVu5ntuDbDEfb3jg6khXJxmcDqS0qhX28QU,61146
6
+ fastapi_gen/template/VARIABLES.md,sha256=YcUtGlrbiic3LMyJZuD4_qAK2JW_NjWdfK9OjDo8sI4,31140
7
+ fastapi_gen/template/cookiecutter.json,sha256=Ujn5L4v0ro1zAe_TXSo1tk3ZrYxA3P3NrLAtITw11GQ,6150
8
+ fastapi_gen/template/hooks/post_gen_project.py,sha256=tLqoaXn2y3HJcKXQOOVPInlYR3v0whFmKoKExgWNS7E,50492
9
+ fastapi_gen/template/{{cookiecutter.project_slug}}/.gitignore,sha256=5j7L5gA20xU_04lptzSu2jNWjhAy___Nqm6JBONSifE,1025
11
10
  fastapi_gen/template/{{cookiecutter.project_slug}}/.gitlab-ci.yml,sha256=3ajZ4hIeWMcagAFOK7c54Ef66M6rqPBZP69BCfDWzQo,4833
12
11
  fastapi_gen/template/{{cookiecutter.project_slug}}/AGENTS.md,sha256=hShNTKVXEvBDRMcRfIqjbJnf2kQ-qMSAGR6b24B5lQs,2592
13
12
  fastapi_gen/template/{{cookiecutter.project_slug}}/CLAUDE.md,sha256=HNwSHcIHb6NuIf68tUFsbc87sAmKVWGbgVd_LixvA4w,7909
14
13
  fastapi_gen/template/{{cookiecutter.project_slug}}/CONTRIBUTING.md,sha256=1GDflj4HotHOvF0bX3SaB4G2Yoo8wtla5IOM0B3FiKk,3456
15
- fastapi_gen/template/{{cookiecutter.project_slug}}/ENV_VARS.md,sha256=bDIPfYg83Dv3bm6aFQrDB0XbHywZi3w3W1hhNNg03vw,8728
14
+ fastapi_gen/template/{{cookiecutter.project_slug}}/ENV_VARS.md,sha256=8BaGvi65JHWG70kOg3b-7FlFDn5CSkKxh0kbazYq1BU,8744
16
15
  fastapi_gen/template/{{cookiecutter.project_slug}}/MANUAL_STEPS.md,sha256=gWrC38KoUxhI25KGYwbDqHuUEtq_8AX68KMBxNSDH5s,8278
17
- fastapi_gen/template/{{cookiecutter.project_slug}}/Makefile,sha256=qbXExrxxWvbVw00ShmffhixDuaPNN80Tim-WSc6HByk,17614
18
- fastapi_gen/template/{{cookiecutter.project_slug}}/README.md,sha256=B1x6jNcvBXqi_yPd5PiW75_tyHVwSoKYTp_X0mnlNjE,13329
16
+ fastapi_gen/template/{{cookiecutter.project_slug}}/Makefile,sha256=H0HLu8twzixNPRRBr4qUvVbwNaXokIeJGt72yYEHI0E,17739
17
+ fastapi_gen/template/{{cookiecutter.project_slug}}/README.md,sha256=lPXbuNViW6c2E0gfwa_jPRIr-oxLZBi10aZeeFuYCfw,13474
19
18
  fastapi_gen/template/{{cookiecutter.project_slug}}/SECURITY.md,sha256=7X5u7feq2AXxWv2CMMNQZf5QQ5QkwBnzKlrcLz3RJ_Q,4735
20
19
  fastapi_gen/template/{{cookiecutter.project_slug}}/docker-compose.dev.yml,sha256=eR6PdvKzVB7hbnDsNqqtQe9C7rDbIftaJ1P3o646uEs,11470
21
20
  fastapi_gen/template/{{cookiecutter.project_slug}}/docker-compose.frontend.yml,sha256=KvYVb7P1vlimx2_klOy-qnsh93tn40RfpUXV2qeH6Sw,1262
22
- fastapi_gen/template/{{cookiecutter.project_slug}}/docker-compose.prod.yml,sha256=kbrKJYqB3UBwa780ZjJRSG-K0NDZlgb5JmbAJ4aDC1M,23346
21
+ fastapi_gen/template/{{cookiecutter.project_slug}}/docker-compose.prod.yml,sha256=Jbb2PykbuLE7jVZ6KHd9d6L-dRwSxrqbv0j_d9dbtOs,23380
23
22
  fastapi_gen/template/{{cookiecutter.project_slug}}/docker-compose.yml,sha256=z_LwfzZt17KSWvcMrGMun7IFbYJNTlXxPEUfqo-TPrs,12671
24
23
  fastapi_gen/template/{{cookiecutter.project_slug}}/.claude/settings.json,sha256=i6XfBDlx6N1AXg4-MrjmIzPhxRXvQC9PRXJFZyfNs1Y,363
25
24
  fastapi_gen/template/{{cookiecutter.project_slug}}/.claude/commands/add-endpoint.md,sha256=p0EsXDvW23v4uOSPRlwA84nVrB7_VVL_FnKFEE442AQ,1648
@@ -34,11 +33,11 @@ fastapi_gen/template/{{cookiecutter.project_slug}}/.claude/rules/schemas-models.
34
33
  fastapi_gen/template/{{cookiecutter.project_slug}}/.claude/rules/testing.md,sha256=w-zM54qfLNSB3tCMxBuOp7jABHS6dG1s62SGvSSXlxU,2267
35
34
  fastapi_gen/template/{{cookiecutter.project_slug}}/.github/workflows/ci.yml,sha256=qR2eyiMNEhPo3cZ4HCS1dskVLK5O6xIaqP_zBtd6FDo,4926
36
35
  fastapi_gen/template/{{cookiecutter.project_slug}}/backend/.dockerignore,sha256=_iRaYQqTvt8_2yhJZUp60PPaL5XLiUFg0OSa-J_9XIQ,523
37
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/.env.example,sha256=zWPLmIWt-ddHOWQdzH-xOs78jVgvBozh7aykjSb7FOU,10995
36
+ fastapi_gen/template/{{cookiecutter.project_slug}}/backend/.env.example,sha256=15C7OJ0fLktoyo5zrUyCB4T1pGnY1zgs_YPAyyaYcLs,10981
38
37
  fastapi_gen/template/{{cookiecutter.project_slug}}/backend/.pre-commit-config.yaml,sha256=22sYeJOrYywl_5PWgPzCyIwhpqmymIDIzx2hlBRQ-yI,681
39
38
  fastapi_gen/template/{{cookiecutter.project_slug}}/backend/Dockerfile,sha256=CKyuUKwt41LHIH9VB28TEzes5_TQkUEo9rIBjE3v8a8,2184
40
39
  fastapi_gen/template/{{cookiecutter.project_slug}}/backend/alembic.ini,sha256=Ol5tRsSTj20-C-9YOyQV17oEPFhPRi0aY859ZNc3cUs,872
41
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/pyproject.toml,sha256=-pu4UKnnMSdoIJ-VJs_IX_mKXgKkW3SR2j1B31wrK4M,12471
40
+ fastapi_gen/template/{{cookiecutter.project_slug}}/backend/pyproject.toml,sha256=WER_TKLPf2wS2pRxk0w4gpg3v8FphbotdkOHKHtYya4,12632
42
41
  fastapi_gen/template/{{cookiecutter.project_slug}}/backend/alembic/env.py,sha256=zVW8oenoX9RgNDCftpmx7KUj_g2-okGJyi2ic7isn0I,3609
43
42
  fastapi_gen/template/{{cookiecutter.project_slug}}/backend/alembic/script.py.mako,sha256=hSTffz_8YXK8N5IfhFpyXXXWIho_zWEzMgdzZzTQPGo,817
44
43
  fastapi_gen/template/{{cookiecutter.project_slug}}/backend/alembic/versions/.gitkeep,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -68,17 +67,20 @@ fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/__init__.py,sha25
68
67
  fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/admin.py,sha256=V-XGDX3cQpC-xPdYgqQbjMfh0ehCHC2liKlSimUdjPA,13987
69
68
  fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/main.py,sha256=j74_Yzqt3J-0QWwHkVDZD8xoYzqx53yBWQ3bFeMRpPU,22549
70
69
  fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/agents/__init__.py,sha256=GqXJ__IgcB24zVUnWiDDzZaDJrfIUEnGA8nv0NIHG5Q,2225
71
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/agents/assistant.py,sha256=BlbFbLXB8P7LXcNpu8swMMx8hj8i9RUSEXzthh7tojE,13152
72
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/agents/crewai_assistant.py,sha256=4VmMqIYJ5sVg9wfirUkiTY3z3FKW9HXpEeuTy1O_jXs,24423
73
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/agents/deepagents_assistant.py,sha256=nbRpB1aeIFs0G7IZv-q7_vh7xvGnuyj-NpeyByuweOI,29652
74
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/agents/langchain_assistant.py,sha256=vVnNH6URjXNq2gudkaP_3Fgt_XVWl4C5h9fArATBYHM,14825
75
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/agents/langgraph_assistant.py,sha256=vBQsdv9ttbuifSXCZ65nEdsviJhIB6Gm1U8GN2eUs6k,18507
76
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/agents/prompts.py,sha256=iKBQdAVx-CixduPrSbu-51hFQq7DNm1kHNglY9TG9Co,2627
77
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/agents/pydantic_deep_assistant.py,sha256=r1tS2FLz2J_Yt0WQ7wPwQOXcAMeVTLRlWK3YRq5TgZo,16203
78
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/agents/tools/__init__.py,sha256=JzGrYSImLJ-O30Q81B5ShgRwFogd1vdqqhXyJ9wMYO0,987
70
+ fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/agents/assistant.py,sha256=T9Rg2mR4LiARIjZo9Z39pIZXVGV2x3G4ZpjZ1n4Qkho,14751
71
+ fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/agents/crewai_assistant.py,sha256=XfnvT8J2mz65R9uNqm81pQ2vMbo1rTFm9VjQifqimqg,26780
72
+ fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/agents/deepagents_assistant.py,sha256=r9dfs4KYIEqWpsVBxLOJPtjD64qAl7FyCid_jC1vNtM,31747
73
+ fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/agents/langchain_assistant.py,sha256=LQWqs3ACC_iSAXFcDwfaiTnNi6_XxMcux6EltuLf8N4,16930
74
+ fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/agents/langgraph_assistant.py,sha256=VGdbdmJaqttBuQu8XjumIf_BAq-StA5nKwVARyR77_k,20592
75
+ fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/agents/prompts.py,sha256=Z0ZPG24N3oJeIoZ5C5SMqxH1P6kOKWmhHcGK70TJS7g,5439
76
+ fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/agents/pydantic_deep_assistant.py,sha256=UUPDr9ThxhAAuOMEDZUKzyKDlSnDu5dtSEGcXApQFtQ,17746
77
+ fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/agents/tools/__init__.py,sha256=PuvtVxl_NO2tlSRUBFOgM15GLYEi64G2hw-zcc92-lA,1212
78
+ fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/agents/tools/chart_render.py,sha256=XFV1UdalA1UItx71qKIBSCCM9i6v2uEHEVg5mpW-JfA,4332
79
+ fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/agents/tools/chart_tool.py,sha256=IbUdCTzLHQGTkT8jUZroE27XpTAewZRJxMthGrsueiI,6373
79
80
  fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/agents/tools/datetime_tool.py,sha256=tXJNg2y_3In2mva0QZzsngVK-0-xYSLzZQew8vSqMO8,359
81
+ fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/agents/tools/fetch_url.py,sha256=Bd5uNh19F6ntAYKHApcyzmgaU4CcIPKPJnNuGOR-5IM,4348
80
82
  fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/agents/tools/rag_tool.py,sha256=L_r_ACiJSlDROka4PKr0sFYCK56MQ3uAPn4CRGgAjQQ,10989
81
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/agents/tools/web_search.py,sha256=Kz-NiA1TYKukrCIzh_bC6028DujiyTrdpo5Mpw2Uszg,2077
83
+ fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/agents/tools/web_search.py,sha256=FiZKe8RmS2UcLfDFi0mlr1pgQvMzY5Ouj2nqLUlD7kE,3534
82
84
  fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/api/__init__.py,sha256=NeESK8RjcyjY9KL1c9H2jIw34RpWmtlHgd8rhPBuolo,18
83
85
  fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/api/deps.py,sha256=SKaO_mIM9HilC4sDX2TNkb0u-XmiO01BCll9LfR1BtI,38779
84
86
  fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/api/exception_handlers.py,sha256=OfUHejfR3zXUQzIN2w8YH9yMf0Cln6GP6e6tLBdotjI,3299
@@ -127,7 +129,7 @@ fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/core/__init__.py,
127
129
  fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/core/audit.py,sha256=ZIftatS3M2ak_O39nqmvkVj2y4lrdnWD54F6VGv5zCo,3383
128
130
  fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/core/cache.py,sha256=VYZfvIdLdtb1Y8h09IoxqPkDyG8pZtY96hR15Hff8YM,626
129
131
  fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/core/channel_crypto.py,sha256=VG98BxIMoXL_6U6B40gCX_p8xHSoOTBPre3zCclVyQs,1608
130
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/core/config.py,sha256=fUr3Gaa60OdfKXswzzo76Y4Y7IDPjboISsfwgj_-L1A,28050
132
+ fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/core/config.py,sha256=Ao_olmb_DeUBokffG6GkToogdbEmRWoNRz5n2haeobg,28144
131
133
  fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/core/csrf.py,sha256=jOOXs5M0vJlLOvlGtz6bU05AO3B9gWCg6FnzFGljnZY,4990
132
134
  fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/core/exceptions.py,sha256=CTI-5c-WzGy7F0fITqhOkqNpvcPIsGgYl7jbmvvbssg,3038
133
135
  fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/core/logfire_setup.py,sha256=EGLqO2cegA0h_IbEneNLgwwoYwMuB4u3kRW8BsOMlwI,2264
@@ -217,7 +219,7 @@ fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/services/__init__
217
219
  fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/services/admin.py,sha256=yCUE1Ytbh3yvrfaB7tOPoBqJKFupzJWkBzZtb8t00iY,6315
218
220
  fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/services/agent.py,sha256=ZInHnzj3k5mp67NdFItS2_nDAT7FVQOQp3iZEG1qLGM,17676
219
221
  fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/services/agent_invocation.py,sha256=O0YwsRK8Ulbtgp8apOy4vbK4zVtn_OvdWSv1dvhIV0s,25367
220
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/services/agent_session.py,sha256=aizCbcvBQxjjjj7gztfWGLDIPDCXhkl__23JwXZaz3A,97541
222
+ fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/services/agent_session.py,sha256=g381_0vCcAt--h7_-eg7LGnN4fghwXL--XfDgUQijU4,101391
221
223
  fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/services/anomaly_detection.py,sha256=Fc59bfur-OsX9Dm4FB-QVbWDoEerL-C_ztQXWEmiGtE,8132
222
224
  fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/services/channel_bot.py,sha256=iR_PwnuoZmXSnrGQgOTkjivKU4a1acYPiFT7vBKKbcA,18281
223
225
  fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/services/contact.py,sha256=AuML8RHIozZkchZlNMjHsZhLWpTMxukfy1xk6mak3Bk,1697
@@ -248,7 +250,7 @@ fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/services/billing/
248
250
  fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/services/billing/credit_service.py,sha256=EfW2oSYFCwnYWaFq_58vCCpYSNfOcXY5_xNDIT7QvXk,12404
249
251
  fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/services/billing/exceptions.py,sha256=MSjxrmISnQ_fBDxqGUoWmvegaTicB2F4Q9vR5ZqYP68,869
250
252
  fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/services/billing/facade.py,sha256=JvMDso1BFzLVEm-RI9dFvPg9Dkj_Oahk6fL46T44Z44,13674
251
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/services/billing/pricing.py,sha256=K0bos0mzNWmeF84VkwcE_47JukqIAc2ijMjsTEEzrMU,2269
253
+ fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/services/billing/pricing.py,sha256=mQXdrmYU2N1iVTa97ddB0WaUQmMz-1Sd_LgpdFWiMUA,2870
252
254
  fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/services/billing/stripe_client.py,sha256=_ol2DQr2xgmMEdyoT87pA3YQdvDirbwyexboTit5iDg,7324
253
255
  fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/services/billing/subscription_service.py,sha256=FVB7DQr_xQDWTmuIlGYxN5d2ZMKAiB2r6AMKs1zxLKk,7541
254
256
  fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/services/billing/webhook_handler.py,sha256=oU0XQ2ueLewHepIPHbjZ1CeC1WmkrjtoCbiEGzRdOno,7047
@@ -258,10 +260,10 @@ fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/services/billing/
258
260
  fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/services/billing/handlers/payment_events.py,sha256=FjbTgGjGmVRZ500dpAurmLnYiXo6ZzEBEtiavhN2q_8,3571
259
261
  fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/services/billing/handlers/subscription_events.py,sha256=DnaZlwk1opT_q7n2vsmDyDlAU0lN5-t1J20OWTpAcpU,21584
260
262
  fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/services/channels/__init__.py,sha256=Q0huVERW4DQ3RI3Np4A2_punujeHNncz6rHfp7O8Tuw,900
261
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/services/channels/base.py,sha256=b9PHI7NB0k3fQWrKxTrJMmcn5GHVEdvNv2RNLYtrLPE,3265
262
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/services/channels/router.py,sha256=GlUiFg39RRIEmNX-lcYgpwF94P_E3esfSQHT-8_-iP0,27923
263
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/services/channels/slack.py,sha256=qrIQT1iUisecfUp-LRsJxlPBR0787h-_J2s2xV1XxPw,9258
264
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/services/channels/telegram.py,sha256=OCgpq9cHN1lTMWd2eWtRVqI5hPCEVqqa5LAB6Fph84U,9134
263
+ fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/services/channels/base.py,sha256=WIhtJUGvtCNf_iZ_scLWhdnclqoQRs3zbzWw4cVo7ho,3748
264
+ fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/services/channels/router.py,sha256=1Z3r7z07nTJ06oZFlg4Msj1ddiaHngXobaoKl9qv8jY,29424
265
+ fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/services/channels/slack.py,sha256=WEzghhLdJN0IHUjZv09yEa0rrY4E4oUYY_rahOScTSg,9634
266
+ fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/services/channels/telegram.py,sha256=yDp43vWcOfLY_gNdZme8iKI3QKyOOzTuoBf_a5biFmg,9598
265
267
  fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/services/email/__init__.py,sha256=xWJWS497C6dWVQvkcUTqgI8yivUb_KpEwAiUKAtjIAU,1150
266
268
  fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/services/email/exceptions.py,sha256=mr_qYBVqpqB2j5j9iVvixJPVlY2q95sj7x5BlsMoVQg,646
267
269
  fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/services/email/service.py,sha256=5MLytHbz77-nGwuGICTnR_ytm83PnrWGVjdfQvTnXrE,8007
@@ -311,11 +313,13 @@ fastapi_gen/template/{{cookiecutter.project_slug}}/backend/scripts/.gitkeep,sha2
311
313
  fastapi_gen/template/{{cookiecutter.project_slug}}/backend/tests/__init__.py,sha256=xqsJPT1QR2TH_5GYK8tiHp-Lb29chxGsr147MWoLAZw,21
312
314
  fastapi_gen/template/{{cookiecutter.project_slug}}/backend/tests/conftest.py,sha256=PCNGRKHULXDT_m1TwvA444HbUQ3nvNdxOveQ05eQXwg,4256
313
315
  fastapi_gen/template/{{cookiecutter.project_slug}}/backend/tests/test_admin.py,sha256=GdsLGZUuNMM45j7-haiNEQqlUgFYeG8Q7Zz6EB-Dk4U,29744
314
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/tests/test_agents.py,sha256=To0Ztc-3BICcvfwVfMSkZV6SBpJunImAtQBUynJwQ9o,9547
316
+ fastapi_gen/template/{{cookiecutter.project_slug}}/backend/tests/test_agents.py,sha256=jVTBnUrkqZfhi7YjcHrryfwRLpK5oOSvO2YCJZyLtRo,10650
317
+ fastapi_gen/template/{{cookiecutter.project_slug}}/backend/tests/test_chart_tool.py,sha256=jgj61I54OlTheIAZk2nqWo4cdIJi3Uuo9ECwKZikTbY,4632
315
318
  fastapi_gen/template/{{cookiecutter.project_slug}}/backend/tests/test_clients.py,sha256=qKU2z4YVQMWdnNE9aH5lnACsdzQ1G4fcE9_sK8x7K2U,6282
316
319
  fastapi_gen/template/{{cookiecutter.project_slug}}/backend/tests/test_commands.py,sha256=45TvE15OGGd3p2HS4bpnUnVToW24L5rjMOQXaJpkWyk,5014
317
320
  fastapi_gen/template/{{cookiecutter.project_slug}}/backend/tests/test_conversation_kb_toggle.py,sha256=WgKpvgtZmYkLXyHEZ9TGgKip9nrCLujoNk6SlSFY1Ds,6738
318
321
  fastapi_gen/template/{{cookiecutter.project_slug}}/backend/tests/test_core.py,sha256=qs9Y1qsxFXxewN7WtfnU5pBuVPEJWD4gOjd-eS9jmEg,4109
322
+ fastapi_gen/template/{{cookiecutter.project_slug}}/backend/tests/test_fetch_url.py,sha256=flnPRdoDcSwxuVgdYewtQl3RahyQ073i_H-_-ptiDPc,3874
319
323
  fastapi_gen/template/{{cookiecutter.project_slug}}/backend/tests/test_kb_scoping.py,sha256=qzXvcAEqQNqouRh2b6cEIdg-z-MIlxxteFGrIsPsNco,12287
320
324
  fastapi_gen/template/{{cookiecutter.project_slug}}/backend/tests/test_migrations.py,sha256=R5gVVmXuwlKMRrOOmt8rOHPT9DGa68F0uBkViUT8SK0,3449
321
325
  fastapi_gen/template/{{cookiecutter.project_slug}}/backend/tests/test_rbac_teams.py,sha256=OmS5gzo2R1tc98bl2V-kC0jE7BYe5MwPvzKeKt6MeIU,10773
@@ -329,6 +333,7 @@ fastapi_gen/template/{{cookiecutter.project_slug}}/backend/tests/test_services_o
329
333
  fastapi_gen/template/{{cookiecutter.project_slug}}/backend/tests/test_ssrf.py,sha256=3EQP8FbmoLgbe_mGlCFtkmX1P8ItVvVYlD_6jUbkeYg,5896
330
334
  fastapi_gen/template/{{cookiecutter.project_slug}}/backend/tests/test_stripe_seats.py,sha256=RgtuOoVVM3kr097rP9D8ZpeNOgyYNXGiz22iCNZdqkc,8892
331
335
  fastapi_gen/template/{{cookiecutter.project_slug}}/backend/tests/test_tenant_isolation.py,sha256=64a_SCR4pvEARQUsv1N6g_sQegGrWSDogBb_8U9Gafc,8304
336
+ fastapi_gen/template/{{cookiecutter.project_slug}}/backend/tests/test_web_search.py,sha256=TNp8p9KRVchQ6JjaSLLw9LHKVMpD278admQ-oEiKbQU,3372
332
337
  fastapi_gen/template/{{cookiecutter.project_slug}}/backend/tests/api/__init__.py,sha256=WV9U5TSWbUYHVA2F3CD7gfod4RdX8EM1s4ewEnwszr0,25
333
338
  fastapi_gen/template/{{cookiecutter.project_slug}}/backend/tests/api/test_auth.py,sha256=mGHb0f1Qq4Es7mbo8fc-2CyQOmFI8XHJobuQHl3GWck,7473
334
339
  fastapi_gen/template/{{cookiecutter.project_slug}}/backend/tests/api/test_exceptions.py,sha256=dWLK2zCvX-S5wGeC7uZKhpjP0kp6MUmAggmRL8wTPIE,4710
@@ -339,7 +344,7 @@ fastapi_gen/template/{{cookiecutter.project_slug}}/backend/tests/api/test_users.
339
344
  fastapi_gen/template/{{cookiecutter.project_slug}}/docs/adding_features.md,sha256=EbNBxbLkswwMwa-Z4IAd8TxF_GHTmkgwZSeyEqth_h0,6929
340
345
  fastapi_gen/template/{{cookiecutter.project_slug}}/docs/architecture.md,sha256=nt4M2coQs83TQiSChvW-aXnTvLxBopo_fK3_r2Ibgd4,11821
341
346
  fastapi_gen/template/{{cookiecutter.project_slug}}/docs/commands.md,sha256=mFW8XvDrO14jW6kboCHjxYN0bZRt6c4h4UWp7_VPqho,11091
342
- fastapi_gen/template/{{cookiecutter.project_slug}}/docs/configuration.md,sha256=KLUL2kT_GpT2uptKFjN9BoPaK5OYIr3nVsn1KT45md0,18369
347
+ fastapi_gen/template/{{cookiecutter.project_slug}}/docs/configuration.md,sha256=hDmlyAT0f4OMFZdZQFt2quyf7x4nDYgRf2JhWI7FBM8,18353
343
348
  fastapi_gen/template/{{cookiecutter.project_slug}}/docs/deploy.md,sha256=tuGpCWc6OjZ3sduyktbuNKwCzg9zfVH42c9iaEVFzYg,5937
344
349
  fastapi_gen/template/{{cookiecutter.project_slug}}/docs/file-processing.md,sha256=3BGOT7hUAsdQFDYMmkI9CRVgc1kmC8V2jVFw8oSP0gk,11081
345
350
  fastapi_gen/template/{{cookiecutter.project_slug}}/docs/patterns.md,sha256=FiEkdtRMkhPcU32spCnnEQFts0gh-3kGchKZoA1QK9A,5976
@@ -386,7 +391,7 @@ fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/.gitignore,sha256=fZ
386
391
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/.prettierignore,sha256=wYnkkZcvXw2mtuFVzYAjH-eFldFkK5Xn26fsZZ19BK0,161
387
392
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/.prettierrc,sha256=1byVwTV0G71t2x5Ko6ryNm2oZ8753NfLLqhrCcon4v0,227
388
393
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/Dockerfile,sha256=XLuo3WNbnfjune-9bN9hVGnlU_y3tbSJwGeuRqAp8P8,1023
389
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/README.md,sha256=UCylLnUAOP0e8ziIZBLUB8OOosXWMftePBdSVmgSLhc,20365
394
+ fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/README.md,sha256=Kn2RbGbWP9fwJVg3iWJHGSAiX9DAmAv5bfFbTwjQKLY,20357
390
395
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/eslint.config.mjs,sha256=GD9tAQLZByfoulEkEq6JvWyPzoIPbmoNn5vr7jApFpA,449
391
396
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/instrumentation.ts,sha256=KKUhYC1lApvs-Vtw9kkzqYiZBaW5axDvHhxeHznljM4,344
392
397
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/next.config.ts,sha256=Ts876RkCrTY6jw-PA8mEjfYYBudaMMmXAgerfXay5mM,3244
@@ -577,7 +582,8 @@ fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/billi
577
582
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/billing/subscription-panel.tsx,sha256=fDbR_WU94nBrlDC9yc-uThKHHjDwmOj9RzJV4l6C8dA,8471
578
583
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/billing/usage-gauge.tsx,sha256=UXsErClKdHDHtTgcaGzUYq9mjbHnJcOBR_BlTOw_wrs,3433
579
584
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/blog/mdx-components.tsx,sha256=Am3qOdvSPQ9xxLQzJKCD0EcE5iWr_E23h4j1w96b01A,1313
580
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/chat-container.tsx,sha256=GaLMFsol8VhdSVAI-6T4-XPrlwE_mku6dxr97dyx_RI,15604
585
+ fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/chart-message.tsx,sha256=vgZH2Bd2lrxxWBc0Vlu8nL8kQ1ypr8izyygeqEBh3Us,8895
586
+ fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/chat-container.tsx,sha256=Z_AT6nTWWJjXDKLcdQ8Gk7Xp0Yq6GsLK12zD19Vzf4Y,16539
581
587
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/chat-empty-state.tsx,sha256=siFZOe7L4Ff4bzjt0dFb6Yqwx7MGX_3bIzJuV1qaQCo,2756
582
588
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/chat-input.tsx,sha256=J6s9NvkyOXaBrkbbDDYRPTyJeS_mRGBFWSdS4PXmH9M,11870
583
589
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/chat-settings.tsx,sha256=TYN--cRVyJTXT__8lav4aOQSRILSAVW8doMH2aiodPI,5402
@@ -585,9 +591,9 @@ fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/
585
591
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/copy-button.tsx,sha256=pIfxMOISSDGTguykzmYIuoJIvjuuXsqcbHsG5V0X1ks,1165
586
592
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/file-preview-panel.tsx,sha256=Ml5lnl8enpc-jI28HSsoeqrn7UVR5_vbrIVjQxVWzcI,20057
587
593
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/index.ts,sha256=1qhvYhUg_eZWtPfdbUXTiXRKR-ZaMW9ClAQkEDHgM3g,686
588
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/kb-selector.tsx,sha256=y7iYQFeHECO_NgVr-JW1QLfD_HR5QFxxX9EVn_JL7sQ,6720
594
+ fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/kb-selector.tsx,sha256=xqfKGICIC6Wgj5WOBoZ_e_TjnE7xDk3xi_EQUKMbfgU,6861
589
595
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/markdown-content.tsx,sha256=6aHyakloM7r5Cf4bEjf4RyBsgLownQ_y4VXTbRsNlO0,6729
590
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/message-item.tsx,sha256=oACFxKy8k2egEN_BVQ5xmE83F0yD3O8KWHPlb0RIHxw,11378
596
+ fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/message-item.tsx,sha256=U78XvgsLBVSq2IZp8DtfAkL2XoIc55LtkiJTaazl-s0,14001
591
597
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/message-list.tsx,sha256=GLJChplCSD-zNjpgtVWfMF3gzZcKULX8wr-fE1Ll9QA,1622
592
598
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/pending-messages.tsx,sha256=z7c7czW6CedjVic-J-q6FQkAldfUCe4JbUlTnrPDC_U,2491
593
599
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/rating-buttons.tsx,sha256=F18IqOrVMBHkPlpZFEEQdlVH93S0zYb0Ga5DoQ0-m9k,8729
@@ -595,7 +601,7 @@ fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/
595
601
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/slash-command-palette.tsx,sha256=CJppPM_hGl7_gLTWUpvpR9Ka2YZ-_ZDKkKit_La0PmM,2733
596
602
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/slash-commands.ts,sha256=s5e4_sld01RGvQ9LSPSniTVcGCthOZJNRfycEakh04M,4925
597
603
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/tool-approval-dialog.tsx,sha256=XoylQa_7X2cajkHF-asehDAw66nep00ueKo-yAmyqGk,3925
598
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/tool-call-card.tsx,sha256=nti5SwtwTfQnW9VY486i7z6Z_gaWk8XW4CGK6QAGqFU,16834
604
+ fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/tool-call-card.tsx,sha256=2jjFNMvrvB27EIycoj2-hqNGL3R0KpZ7xHIQs_BuiVs,21625
599
605
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/dashboard/active-sessions.tsx,sha256=tDDBLEHyG-kAG894K3OeENG73Zw-T3rQFFJziX86V-g,3987
600
606
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/dashboard/onboarding-banner.tsx,sha256=pfLtIZKIBKpYc03ItahyoiOYz2z6-isQU96KWgkWSKU,2091
601
607
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/dashboard/quick-actions.tsx,sha256=i8L6Q_F2prPqfzCMPawPEW1I_VWBkAbAvTc_LA5r2xo,2224
@@ -711,7 +717,7 @@ fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/hooks/use-admin-
711
717
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/hooks/use-admin-users.ts,sha256=knLtbDn4EkfaV7IfuXbw-gM0eaaw3uMg-kvIaoO__ZM,2705
712
718
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/hooks/use-auth.ts,sha256=-GRSDTJQtWt3pTixIPwx4KSNZuiEymsky-Dcx-4Q77Q,3021
713
719
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/hooks/use-billing.ts,sha256=pW7tSepHPjnwX0OIEK2YQkyER3ctOvpazRvgdqZfG1E,5576
714
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/hooks/use-chat.ts,sha256=G3dZyZ3LISDGkXVTM2EFzaEsVBg_-Di_4flJA_hVWaw,20817
720
+ fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/hooks/use-chat.ts,sha256=NaOgl6Yb6NFDV7JTksAtAZMWBKfMD1F7wGLJ2toY-yY,21804
715
721
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/hooks/use-conversation-shares.ts,sha256=F7JIXyrFiYYFLs9nLpXNZGM2yGzB97N_HQP2euP2WKM,3256
716
722
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/hooks/use-conversations.ts,sha256=PQJvUyHgK45AJYD_2lypuVS9kE4_rLBtFJlI9biVXVI,8566
717
723
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/hooks/use-invitations.ts,sha256=0EHKt6wTxQc5WzNC3R8EYU5ruDvpDYVEhFrA_JsjN8w,1891
@@ -739,7 +745,7 @@ fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/lib/utils.ts,sha
739
745
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/stores/auth-store.test.ts,sha256=T_1k_oYdXOGIvLlKP_Z_1QxuZ05-TJ9B1XsSpzrE7Bo,1594
740
746
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/stores/auth-store.ts,sha256=u-Z9osePagP_nGqWVJgE8YLS3AP-srUH1DNbnqDzr10,1796
741
747
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/stores/chat-sidebar-store.ts,sha256=GBkD_ryKf2dlO6YIj-K85S9t9KuoGfs4tiUqZ0Uom4k,395
742
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/stores/chat-store.ts,sha256=9n2xYuvhEaoNpk4t9fMbSota7d00BgFRCd9miEKSUUc,1897
748
+ fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/stores/chat-store.ts,sha256=WcwKjK9bru9ikJNQwTM-ncp2WuWIIz9L3cSZkaV6WMA,5023
743
749
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/stores/conversation-store.ts,sha256=XsYFZmH2fh5ZZasnBLebdRjKRajv5mVFpkPTen8Te6k,2142
744
750
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/stores/file-preview-store.ts,sha256=6zbbAkTJzP61x6DjFcMNrpJnvyPmEtLHA-eNPVpRt4s,446
745
751
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/stores/index.ts,sha256=fdKJRzOD6FptF04S8xQFjBhjj6Pa1fuw6WwSxB114KQ,568
@@ -751,7 +757,7 @@ fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/stores/theme-sto
751
757
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/types/api.ts,sha256=h_WXzUWJ67lDJ2hKi5It2hlTWhGnm_YMa0nTYJn3TDM,396
752
758
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/types/auth.ts,sha256=NAmjkWIit2gLUffIQ6lRni8NRGmUOKxIJw3Qjvd8r_o,1403
753
759
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/types/billing.ts,sha256=71NnQ9xs6G3LC_H-eA7mCSbDfUbWD3leyntmid_AWpI,2517
754
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/types/chat.ts,sha256=DHybASgV3s4kL_iN3ffCslyNrLTusCmSc2cyLwNgQyU,3794
760
+ fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/types/chat.ts,sha256=CQ0qjgC18CNOm-5CH500xWzEkr0N75QhJfoFk2AkLQ8,5149
755
761
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/types/conversation.ts,sha256=HXdApDZPATMgpGlVnlHBbog4rh_4enoJyvaWXNuDMwM,2908
756
762
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/types/index.ts,sha256=AYWPqhi-14u5bjsuYpojHbSeUmHARXy4DUiJhgcaEt4,487
757
763
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/types/knowledge-base.ts,sha256=xkCES2rU51ei-pdqwxMNsZuoTfmaT7fWteoJrOMQGzw,1053
@@ -767,8 +773,8 @@ fastapi_gen/template/{{cookiecutter.project_slug}}/kubernetes/secret.yaml,sha256
767
773
  fastapi_gen/template/{{cookiecutter.project_slug}}/kubernetes/service.yaml,sha256=o3bCXguj8E5aQ0H1o3cBD3z_iZ_RA_Pmx1bc0sVzK28,682
768
774
  fastapi_gen/template/{{cookiecutter.project_slug}}/nginx/nginx.conf,sha256=gJWUMMqNvr9TwNZOcc_WPPGZvdAlRUH3jLhbllOb_YY,7359
769
775
  fastapi_gen/template/{{cookiecutter.project_slug}}/nginx/ssl/.gitkeep,sha256=o_WQQOgVGOLttT48x0EXSC4BbbDFemApFpmwhybcVUU,617
770
- fastapi_fullstack-0.2.8.dist-info/METADATA,sha256=9cAm3bi3JZ1XConjv3P4Ofwk9yKPjwzgTT-6Qj6Da8E,56658
771
- fastapi_fullstack-0.2.8.dist-info/WHEEL,sha256=QccIxa26bgl1E6uMy58deGWi-0aeIkkangHcxk2kWfw,87
772
- fastapi_fullstack-0.2.8.dist-info/entry_points.txt,sha256=s9JXrISZp8LMYJGeVofOAd1wPTzpq-jwjSgSf4hWzjs,59
773
- fastapi_fullstack-0.2.8.dist-info/licenses/LICENSE,sha256=bL4JuK_rcA8y__Gg7PEuTs3g2Qf6VvSz2w2Jajd6nVU,1063
774
- fastapi_fullstack-0.2.8.dist-info/RECORD,,
776
+ fastapi_fullstack-0.2.9.dist-info/METADATA,sha256=SUgo8EZ0lN13esY2a7Pq71QYWePaont06HFWjhGeR20,56948
777
+ fastapi_fullstack-0.2.9.dist-info/WHEEL,sha256=QccIxa26bgl1E6uMy58deGWi-0aeIkkangHcxk2kWfw,87
778
+ fastapi_fullstack-0.2.9.dist-info/entry_points.txt,sha256=s9JXrISZp8LMYJGeVofOAd1wPTzpq-jwjSgSf4hWzjs,59
779
+ fastapi_fullstack-0.2.9.dist-info/licenses/LICENSE,sha256=bL4JuK_rcA8y__Gg7PEuTs3g2Qf6VvSz2w2Jajd6nVU,1063
780
+ fastapi_fullstack-0.2.9.dist-info/RECORD,,
fastapi_gen/cli.py CHANGED
@@ -465,6 +465,12 @@ def new(output: Path | None, no_input: bool, name: str | None, minimal: bool) ->
465
465
  @click.option(
466
466
  "--web-fetch", is_flag=True, default=False, help="Enable web fetch/scraping tool for AI agents"
467
467
  )
468
+ @click.option(
469
+ "--charts",
470
+ is_flag=True,
471
+ default=False,
472
+ help="Enable the chart-generation tool for AI agents (line/bar/pie/area/scatter)",
473
+ )
468
474
  @click.option("--session-management", is_flag=True, help="Enable session management")
469
475
  @click.option(
470
476
  "--reverse-proxy",
@@ -739,6 +745,7 @@ def create(
739
745
  websockets: bool,
740
746
  web_search: bool,
741
747
  web_fetch: bool,
748
+ charts: bool,
742
749
  session_management: bool,
743
750
  reverse_proxy: str,
744
751
  kubernetes: bool,
@@ -1166,6 +1173,7 @@ def create(
1166
1173
  enable_websockets=websockets,
1167
1174
  enable_web_search=web_search,
1168
1175
  enable_web_fetch=web_fetch,
1176
+ enable_charts=charts,
1169
1177
  enable_session_management=session_management,
1170
1178
  reverse_proxy=_rp_map[reverse_proxy],
1171
1179
  enable_kubernetes=kubernetes,
@@ -1321,9 +1329,9 @@ def templates() -> None:
1321
1329
  console.print(
1322
1330
  " --ai-framework pydantic_deep PydanticDeep (deep agentic coding, Docker sandbox)"
1323
1331
  )
1324
- console.print(" --llm-provider openai OpenAI (gpt-4o-mini)")
1325
- console.print(" --llm-provider anthropic Anthropic (claude-sonnet-4-5)")
1326
- console.print(" --llm-provider google Google Gemini (gemini-2.0-flash)")
1332
+ console.print(" --llm-provider openai OpenAI (gpt-5.5)")
1333
+ console.print(" --llm-provider anthropic Anthropic (claude-opus-4-7)")
1334
+ console.print(" --llm-provider google Google Gemini (gemini-2.5-flash)")
1327
1335
  console.print(" --llm-provider openrouter OpenRouter (pydantic_ai only)")
1328
1336
  console.print(
1329
1337
  " --websockets Enable WebSocket support (real-time chat streaming)"
fastapi_gen/config.py CHANGED
@@ -324,6 +324,7 @@ class ProjectConfig(BaseModel):
324
324
  enable_langsmith: bool = False
325
325
  enable_web_search: bool = False
326
326
  enable_web_fetch: bool = False
327
+ enable_charts: bool = False
327
328
  use_telegram: bool = False
328
329
  use_slack: bool = False
329
330
  enable_cors: bool = True
@@ -791,6 +792,18 @@ class ProjectConfig(BaseModel):
791
792
  "enable_langsmith": self.enable_langsmith,
792
793
  "enable_web_search": self.enable_web_search,
793
794
  "enable_web_fetch": self.enable_web_fetch,
795
+ # PydanticAI/PydanticDeep have a model-native WebFetch capability;
796
+ # the other frameworks don't, so they get a portable fetch_url tool.
797
+ "web_fetch_tool": self.enable_web_fetch
798
+ and self.ai_framework
799
+ in (
800
+ AIFrameworkType.LANGCHAIN,
801
+ AIFrameworkType.LANGGRAPH,
802
+ AIFrameworkType.CREWAI,
803
+ AIFrameworkType.DEEPAGENTS,
804
+ ),
805
+ "enable_charts": self.enable_charts,
806
+ "charts_channel_png": self.enable_charts and (self.use_slack or self.use_telegram),
794
807
  "enable_webhooks": self.enable_webhooks,
795
808
  # Legacy fixed values (WebSocket always uses JWT)
796
809
  "websocket_auth": "jwt",
fastapi_gen/prompts.py CHANGED
@@ -800,9 +800,9 @@ def prompt_llm_provider(ai_framework: AIFrameworkType) -> LLMProviderType:
800
800
  console.print()
801
801
 
802
802
  choices = [
803
- questionary.Choice("OpenAI (gpt-4o-mini)", value=LLMProviderType.OPENAI),
804
- questionary.Choice("Anthropic (claude-sonnet-4-5)", value=LLMProviderType.ANTHROPIC),
805
- questionary.Choice("Google Gemini (gemini-2.0-flash)", value=LLMProviderType.GOOGLE),
803
+ questionary.Choice("OpenAI (gpt-5.5)", value=LLMProviderType.OPENAI),
804
+ questionary.Choice("Anthropic (claude-opus-4-7)", value=LLMProviderType.ANTHROPIC),
805
+ questionary.Choice("Google Gemini (gemini-2.5-flash)", value=LLMProviderType.GOOGLE),
806
806
  ]
807
807
 
808
808
  # OpenRouter available for PydanticAI and PydanticDeep (both use pydantic-ai)
@@ -823,36 +823,77 @@ def prompt_llm_provider(ai_framework: AIFrameworkType) -> LLMProviderType:
823
823
  )
824
824
 
825
825
 
826
- def prompt_pydantic_capabilities() -> tuple[bool, bool]:
827
- """Prompt for PydanticAI built-in capabilities (WebSearch, WebFetch).
826
+ def prompt_web_capabilities(ai_framework: AIFrameworkType) -> tuple[bool, bool]:
827
+ """Prompt for web search / web fetch.
828
+
829
+ PydanticAI and PydanticDeep use the model-native WebSearch/WebFetch
830
+ capabilities. LangChain, LangGraph, CrewAI and DeepAgents use a
831
+ Tavily-backed web search tool plus a portable fetch_url tool.
828
832
 
829
833
  Returns:
830
834
  Tuple of (enable_web_search, enable_web_fetch).
831
835
  """
836
+ native = ai_framework in (
837
+ AIFrameworkType.PYDANTIC_AI,
838
+ AIFrameworkType.PYDANTIC_DEEP,
839
+ )
840
+
832
841
  console.print()
833
- console.print("[bold cyan]PydanticAI Capabilities[/]")
834
- console.print("Built-in model capabilities (model must support them).")
842
+ console.print("[bold cyan]Web Search & Fetch[/]")
843
+ if native:
844
+ console.print("Built-in model capabilities (the model must support them).")
845
+ else:
846
+ console.print(
847
+ "Web search uses Tavily (needs TAVILY_API_KEY); "
848
+ "fetch reads a given URL's readable content."
849
+ )
835
850
  console.print()
836
851
 
852
+ search_q = (
853
+ "Enable WebSearch capability (model-native web search)?"
854
+ if native
855
+ else "Enable the web search tool (Tavily — needs TAVILY_API_KEY)?"
856
+ )
857
+ fetch_q = (
858
+ "Enable WebFetch capability (model-native URL fetching)?"
859
+ if native
860
+ else "Enable the fetch-URL tool (read a web page's content)?"
861
+ )
862
+
837
863
  enable_web_search = cast(
838
864
  bool,
839
- _check_cancelled(
840
- questionary.confirm(
841
- "Enable WebSearch capability (model-native web search)?",
842
- default=False,
843
- ).ask()
844
- ),
865
+ _check_cancelled(questionary.confirm(search_q, default=False).ask()),
845
866
  )
846
867
  enable_web_fetch = cast(
868
+ bool,
869
+ _check_cancelled(questionary.confirm(fetch_q, default=False).ask()),
870
+ )
871
+ return enable_web_search, enable_web_fetch
872
+
873
+
874
+ def prompt_charts() -> bool:
875
+ """Prompt for the agent chart-generation tool.
876
+
877
+ Returns:
878
+ Whether the chart tool is enabled.
879
+ """
880
+ console.print()
881
+ console.print("[bold cyan]Chart Generation Tool[/]")
882
+ console.print(
883
+ "Lets the agent produce line/bar/pie/area/scatter charts. Rendered "
884
+ "interactively in the web chat; sent as PNG images on Slack/Telegram."
885
+ )
886
+ console.print()
887
+
888
+ return cast(
847
889
  bool,
848
890
  _check_cancelled(
849
891
  questionary.confirm(
850
- "Enable WebFetch capability (model-native URL fetching)?",
892
+ "Enable the chart-generation tool for the agent?",
851
893
  default=False,
852
894
  ).ask()
853
895
  ),
854
896
  )
855
- return enable_web_search, enable_web_fetch
856
897
 
857
898
 
858
899
  def prompt_langsmith() -> bool:
@@ -1363,6 +1404,7 @@ def run_interactive_prompts() -> ProjectConfig:
1363
1404
  "enable_langsmith": False,
1364
1405
  "enable_web_search": False,
1365
1406
  "enable_web_fetch": False,
1407
+ "enable_charts": False,
1366
1408
  "rag_features": RAGFeatures(),
1367
1409
  "orm_type": OrmType.SQLALCHEMY,
1368
1410
  "sandbox_backend": "state",
@@ -1486,15 +1528,15 @@ def run_interactive_prompts() -> ProjectConfig:
1486
1528
  else:
1487
1529
  state["llm_provider"] = prompt_llm_provider(state["ai_framework"])
1488
1530
 
1489
- def step_pydantic_capabilities() -> None:
1490
- if state["ai_framework"] == AIFrameworkType.PYDANTIC_AI:
1531
+ def step_web_capabilities() -> None:
1532
+ if state["ai_framework"] == AIFrameworkType.NONE:
1533
+ state["enable_web_search"] = False
1534
+ state["enable_web_fetch"] = False
1535
+ else:
1491
1536
  (
1492
1537
  state["enable_web_search"],
1493
1538
  state["enable_web_fetch"],
1494
- ) = prompt_pydantic_capabilities()
1495
- else:
1496
- state["enable_web_search"] = False
1497
- state["enable_web_fetch"] = False
1539
+ ) = prompt_web_capabilities(state["ai_framework"])
1498
1540
 
1499
1541
  def step_rag_config() -> None:
1500
1542
  if state["ai_framework"] == AIFrameworkType.NONE:
@@ -1515,6 +1557,12 @@ def run_interactive_prompts() -> ProjectConfig:
1515
1557
  )
1516
1558
  state["dev_tools"]["enable_docker"] = True
1517
1559
 
1560
+ def step_charts() -> None:
1561
+ if state["ai_framework"] == AIFrameworkType.NONE:
1562
+ state["enable_charts"] = False
1563
+ else:
1564
+ state["enable_charts"] = prompt_charts()
1565
+
1518
1566
  def step_langsmith() -> None:
1519
1567
  if state["ai_framework"] in (
1520
1568
  AIFrameworkType.LANGCHAIN,
@@ -1582,8 +1630,9 @@ def run_interactive_prompts() -> ProjectConfig:
1582
1630
  ("Observability (Logfire)", step_logfire),
1583
1631
  ("Agent Sandbox", step_sandbox_backend),
1584
1632
  ("LLM Provider", step_llm_provider),
1585
- ("PydanticAI Capabilities", step_pydantic_capabilities),
1633
+ ("Web Search & Fetch", step_web_capabilities),
1586
1634
  ("RAG", step_rag_config),
1635
+ ("Chart Tool", step_charts),
1587
1636
  ("LangSmith", step_langsmith),
1588
1637
  ("Messaging Channels", step_channels),
1589
1638
  ("Teams & Billing", step_teams_billing),
@@ -1629,6 +1678,7 @@ def run_interactive_prompts() -> ProjectConfig:
1629
1678
  llm_provider = state["llm_provider"]
1630
1679
  enable_web_search = state["enable_web_search"]
1631
1680
  enable_web_fetch = state["enable_web_fetch"]
1681
+ enable_charts = state["enable_charts"]
1632
1682
  rag_features = state["rag_features"]
1633
1683
  enable_langsmith = state["enable_langsmith"]
1634
1684
  use_telegram = state["use_telegram"]
@@ -1670,6 +1720,7 @@ def run_interactive_prompts() -> ProjectConfig:
1670
1720
  enable_langsmith=enable_langsmith,
1671
1721
  enable_web_search=enable_web_search,
1672
1722
  enable_web_fetch=enable_web_fetch,
1723
+ enable_charts=enable_charts,
1673
1724
  use_telegram=use_telegram,
1674
1725
  use_slack=use_slack,
1675
1726
  rate_limit_requests=rate_limit_requests,
@@ -281,8 +281,11 @@ These variables are set automatically by the generator.
281
281
  | `use_google` | bool | `false` | Google Gemini is selected | Computed from `llm_provider` |
282
282
  | `use_openrouter` | bool | `false` | OpenRouter is selected | Computed from `llm_provider` |
283
283
  | `enable_langsmith` | bool | `false` | Enable LangSmith observability (tracing, prompt management) | Requires LangChain, LangGraph, or DeepAgents |
284
- | `enable_web_search` | bool | `false` | Enable WebSearch capability for PydanticAI agents | PydanticAI only |
285
- | `enable_web_fetch` | bool | `false` | Enable WebFetch capability for PydanticAI agents | PydanticAI only |
284
+ | `enable_web_search` | bool | `false` | Web search. PydanticAI/PydanticDeep use the model-native WebSearch capability; LangChain/LangGraph/CrewAI/DeepAgents use a Tavily-backed tool (needs `TAVILY_API_KEY`) | Requires an AI framework |
285
+ | `enable_web_fetch` | bool | `false` | Web fetch. PydanticAI/PydanticDeep use the model-native WebFetch capability; LangChain/LangGraph/CrewAI/DeepAgents use the portable `fetch_url` tool | Requires an AI framework |
286
+ | `web_fetch_tool` | bool | `false` | Computed: portable `fetch_url` tool is generated | `enable_web_fetch` and framework is LangChain/LangGraph/CrewAI/DeepAgents |
287
+ | `enable_charts` | bool | `false` | Enable the chart-generation tool (line/bar/pie/area/scatter); interactive in web chat, PNG on Slack/Telegram | Requires an AI framework |
288
+ | `charts_channel_png` | bool | `false` | Computed: render charts to PNG for messaging channels | `enable_charts` and (`use_slack` or `use_telegram`) |
286
289
 
287
290
  **Notes:**
288
291
 
@@ -88,6 +88,9 @@
88
88
  "enable_langsmith": false,
89
89
  "enable_web_search": false,
90
90
  "enable_web_fetch": false,
91
+ "web_fetch_tool": false,
92
+ "enable_charts": false,
93
+ "charts_channel_png": false,
91
94
  "enable_webhooks": false,
92
95
  "websocket_auth": "jwt",
93
96
  "websocket_auth_jwt": true,
@@ -45,6 +45,9 @@ enable_rag_image_description = "{{ cookiecutter.enable_rag_image_description }}"
45
45
  enable_google_drive_ingestion = "{{ cookiecutter.enable_google_drive_ingestion }}" == "True"
46
46
  enable_s3_ingestion = "{{ cookiecutter.enable_s3_ingestion }}" == "True"
47
47
  enable_web_search = "{{ cookiecutter.enable_web_search }}" == "True"
48
+ web_fetch_tool = "{{ cookiecutter.web_fetch_tool }}" == "True"
49
+ enable_charts = "{{ cookiecutter.enable_charts }}" == "True"
50
+ charts_channel_png = "{{ cookiecutter.charts_channel_png }}" == "True"
48
51
  use_pydantic_deep = "{{ cookiecutter.use_pydantic_deep }}" == "True"
49
52
  use_telegram = "{{ cookiecutter.use_telegram }}" == "True"
50
53
  use_slack = "{{ cookiecutter.use_slack }}" == "True"
@@ -126,6 +129,20 @@ if not use_pydantic_deep:
126
129
  remove_file(os.path.join(backend_app, "agents", "pydantic_deep_assistant.py"))
127
130
  if not enable_web_search:
128
131
  remove_file(os.path.join(backend_app, "agents", "tools", "web_search.py"))
132
+ remove_file(os.path.join(os.getcwd(), "backend", "tests", "test_web_search.py"))
133
+ if not web_fetch_tool:
134
+ remove_file(os.path.join(backend_app, "agents", "tools", "fetch_url.py"))
135
+ remove_file(os.path.join(os.getcwd(), "backend", "tests", "test_fetch_url.py"))
136
+ if not enable_charts:
137
+ remove_file(os.path.join(backend_app, "agents", "tools", "chart_tool.py"))
138
+ remove_file(os.path.join(backend_app, "agents", "tools", "chart_render.py"))
139
+ remove_file(os.path.join(os.getcwd(), "backend", "tests", "test_chart_tool.py"))
140
+ if use_frontend:
141
+ frontend_src = os.path.join(os.getcwd(), "frontend", "src")
142
+ remove_file(os.path.join(frontend_src, "components", "chat", "chart-message.tsx"))
143
+ elif not charts_channel_png:
144
+ # Chart tool enabled but no Slack/Telegram — PNG renderer not needed.
145
+ remove_file(os.path.join(backend_app, "agents", "tools", "chart_render.py"))
129
146
 
130
147
  # --- No-AI mode: remove all AI/chat/conversation files ---
131
148
  if not use_ai:
@@ -326,7 +343,6 @@ if not enable_docker:
326
343
  "docker-compose.dev.yml",
327
344
  "docker-compose.prod.yml",
328
345
  "docker-compose.frontend.yml",
329
- ".env.prod.example",
330
346
  ):
331
347
  remove_file(os.path.join(project_root, compose_file))
332
348
 
@@ -55,7 +55,6 @@ coverage.xml
55
55
  .env
56
56
  .env.local
57
57
  .env.*.local
58
- .env.prod
59
58
  .venv
60
59
  env/
61
60
  venv/