fastapi-fullstack 0.2.15__py3-none-any.whl → 0.2.16__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 (57) hide show
  1. {fastapi_fullstack-0.2.15.dist-info → fastapi_fullstack-0.2.16.dist-info}/METADATA +2 -2
  2. {fastapi_fullstack-0.2.15.dist-info → fastapi_fullstack-0.2.16.dist-info}/RECORD +57 -39
  3. {fastapi_fullstack-0.2.15.dist-info → fastapi_fullstack-0.2.16.dist-info}/WHEEL +1 -1
  4. fastapi_gen/cli.py +17 -0
  5. fastapi_gen/config.py +7 -0
  6. fastapi_gen/prompts.py +7 -0
  7. fastapi_gen/template/VARIABLES.md +1 -0
  8. fastapi_gen/template/cookiecutter.json +1 -0
  9. fastapi_gen/template/hooks/post_gen_project.py +16 -0
  10. fastapi_gen/template/{{cookiecutter.project_slug}}/.gitignore +5 -0
  11. fastapi_gen/template/{{cookiecutter.project_slug}}/CLAUDE.md +19 -114
  12. fastapi_gen/template/{{cookiecutter.project_slug}}/backend/alembic/versions/0025_message_thinking.py +27 -0
  13. fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/db/models/conversation.py +2 -0
  14. fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/repositories/conversation.py +2 -0
  15. fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/schemas/conversation.py +1 -0
  16. fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/services/agent.py +4 -1
  17. fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/services/agent_session.py +43 -8
  18. fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/services/conversation.py +1 -0
  19. fastapi_gen/template/{{cookiecutter.project_slug}}/backend/pyproject.toml +1 -0
  20. fastapi_gen/template/{{cookiecutter.project_slug}}/docker-compose.dev.yml +3 -3
  21. fastapi_gen/template/{{cookiecutter.project_slug}}/docker-compose.prod.yml +3 -3
  22. fastapi_gen/template/{{cookiecutter.project_slug}}/docker-compose.yml +3 -3
  23. fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/demo-export/assets/user-avatar.jpg +0 -0
  24. fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/demo-export/entry.css +7 -0
  25. fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/demo-export/index.html +26 -0
  26. fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/demo-export/main.tsx +74 -0
  27. fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/demo-export/postcss.config.mjs +5 -0
  28. fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/demo-export/shims/next-dynamic.ts +25 -0
  29. fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/demo-export/shims/next-image.tsx +28 -0
  30. fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/demo-export/shims/next-intl.ts +16 -0
  31. fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/demo-export/shims/next-link.tsx +12 -0
  32. fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/demo-export/shims/next-navigation.ts +22 -0
  33. fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/demo-export/vite-env.d.ts +9 -0
  34. fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/demo-export/vite.config.ts +38 -0
  35. fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/package.json +6 -2
  36. fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/chart-message.impl.tsx +1 -1
  37. fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/chat-container.tsx +6 -19
  38. fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/map-message.tsx +1 -1
  39. fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/message-item.tsx +6 -0
  40. fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/research-replay-block.tsx +153 -0
  41. fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/subagent-feed.tsx +8 -3
  42. fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/tool-call-card.tsx +26 -7
  43. fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/tool-results/fetch-url.tsx +46 -0
  44. fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/tool-results/web-search.tsx +24 -3
  45. fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/demo/demo-replay.tsx +1260 -120
  46. fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/hooks/use-conversation-replay.ts +18 -3
  47. fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/hooks/use-step-replay.ts +34 -8
  48. fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/lib/agent-step-captions.ts +21 -0
  49. fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/lib/conversation-to-chat.ts +40 -10
  50. fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/lib/research-from-tools.ts +72 -0
  51. fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/lib/sql-format.ts +28 -0
  52. fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/types/chat.ts +9 -1
  53. fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/types/conversation.ts +1 -0
  54. fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/vitest.setup.ts +35 -0
  55. fastapi_gen/template/{{cookiecutter.project_slug}}/scripts/export_demo_html.py +239 -0
  56. {fastapi_fullstack-0.2.15.dist-info → fastapi_fullstack-0.2.16.dist-info}/entry_points.txt +0 -0
  57. {fastapi_fullstack-0.2.15.dist-info → fastapi_fullstack-0.2.16.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.15
3
+ Version: 0.2.16
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
@@ -21,7 +21,7 @@ Classifier: Topic :: Software Development :: Code Generators
21
21
  Requires-Python: >=3.11
22
22
  Requires-Dist: arq>=0.28.0
23
23
  Requires-Dist: celery>=5.6.3
24
- Requires-Dist: click>=8.3.0
24
+ Requires-Dist: click>=8.3.3
25
25
  Requires-Dist: cookiecutter>=2.7.0
26
26
  Requires-Dist: email-validator>=2.3.0
27
27
  Requires-Dist: httpx>=0.28.1
@@ -1,25 +1,25 @@
1
1
  fastapi_gen/__init__.py,sha256=oK2gEM45SpSYBb-Itgr0GII88-5qfB0kmNkj90FkvQw,257
2
- fastapi_gen/cli.py,sha256=cWf8z-JvirYzoYvpA8Jw5P_ECc7I5UO4aZTRz6ju25g,54824
3
- fastapi_gen/config.py,sha256=XCKYBG9rJSfDqSaB9feg3A3__mk0GrsVDn2OL5oncaU,42662
2
+ fastapi_gen/cli.py,sha256=c6SCn0iO-HJDPRi-J8wpcNdMQucA5GsDrVu9sbVV6Tk,55404
3
+ fastapi_gen/config.py,sha256=GRjFiQOoixvYlU5uzmphYOYQwTEs1f4uYMRDpqDvUdE,43089
4
4
  fastapi_gen/generator.py,sha256=ODY7BBJkdn3VE5ISJL5i0tZj2IFoHsrIDvEvx-WtZJk,8349
5
- fastapi_gen/prompts.py,sha256=l-Etk6ym78CEFRqJrd_p6_lPGHmtiKQoDtzeEe0tez0,65036
6
- fastapi_gen/template/VARIABLES.md,sha256=eVyXLEE3rkfFUICP79gMP1gxmA94tGLLNPNdOi7QLdE,33327
7
- fastapi_gen/template/cookiecutter.json,sha256=tP_Ws5wp_E2cu_bVY0fhEsnXs9tZECuI5fzX-N1zmc8,6276
8
- fastapi_gen/template/hooks/post_gen_project.py,sha256=KcZnKSVDmooTz4uUo2zfyZ3cxlEPh656NSLmJLUkK3o,52479
9
- fastapi_gen/template/{{cookiecutter.project_slug}}/.gitignore,sha256=xOV6ApRFJzURdjEuE6V2IjbsHQP6_EwzUsbXosgwfFI,972
5
+ fastapi_gen/prompts.py,sha256=b_LIh00ZKMejPfFSf8PCHFgEGS85jNK2Jx5ksgFY-zY,65346
6
+ fastapi_gen/template/VARIABLES.md,sha256=8tgY_eyn5dtp355SfaseaM__C46cGvufOE2MZ8dRVOM,33571
7
+ fastapi_gen/template/cookiecutter.json,sha256=hTL-Xp8mQH-BUCc5PxNZVSh--hf5G5CQi0WX0JOuLZI,6307
8
+ fastapi_gen/template/hooks/post_gen_project.py,sha256=MklZrStNKzOSpBvAgTa2vSNbbTMdz5Ek8EroETylGjk,53472
9
+ fastapi_gen/template/{{cookiecutter.project_slug}}/.gitignore,sha256=ALWGkiStRSR61YG0jwfnYf8nZ_qo2p5NEMVjye49Bqw,1132
10
10
  fastapi_gen/template/{{cookiecutter.project_slug}}/.gitlab-ci.yml,sha256=dZh-VSLL5beOtj8_UxBbD86sBdE9ubTpmWvMcrRqr-M,4651
11
11
  fastapi_gen/template/{{cookiecutter.project_slug}}/AGENTS.md,sha256=HqhXNdBq1ZXlFJCC4V3CY8DorTkZkwFJcvv2O77Pwk4,2454
12
- fastapi_gen/template/{{cookiecutter.project_slug}}/CLAUDE.md,sha256=_NQcVjyOvSHkwnaaqXD_-UB9z_m4zYjPHjYzBqoWvO4,7577
12
+ fastapi_gen/template/{{cookiecutter.project_slug}}/CLAUDE.md,sha256=OwM3tVeznjnSr8h0Ors27AIqB7DqC8X1rYLw1fQE0x0,3657
13
13
  fastapi_gen/template/{{cookiecutter.project_slug}}/CONTRIBUTING.md,sha256=pxP7KcIbmZbao1HPnFEykJbCHa7VfW2RQWfBMNSE_kE,3304
14
14
  fastapi_gen/template/{{cookiecutter.project_slug}}/ENV_VARS.md,sha256=t8iwCVu3XV3lAJIvA3nYsbE7Y25JXgkrBMAJt_iiJUc,8234
15
15
  fastapi_gen/template/{{cookiecutter.project_slug}}/MANUAL_STEPS.md,sha256=6HJW2WE6-U4jbyQT7BjH17N6I2xAXbaAKbANiNEFNRA,7775
16
16
  fastapi_gen/template/{{cookiecutter.project_slug}}/Makefile,sha256=QD3Wv03COXT7GsOB_0nSvz6fG8hG0bt3de_uQUgjLJk,17172
17
17
  fastapi_gen/template/{{cookiecutter.project_slug}}/README.md,sha256=faY_FSgHSMc5PhrHFbJGmJpRa0gxUwZLF6JZ4Qn7Ac4,13878
18
18
  fastapi_gen/template/{{cookiecutter.project_slug}}/SECURITY.md,sha256=7X5u7feq2AXxWv2CMMNQZf5QQ5QkwBnzKlrcLz3RJ_Q,4735
19
- fastapi_gen/template/{{cookiecutter.project_slug}}/docker-compose.dev.yml,sha256=kYdJ9uMuN7BDTqymxULxRo71qeIAQ7vue5Gc-0gt3do,12348
19
+ fastapi_gen/template/{{cookiecutter.project_slug}}/docker-compose.dev.yml,sha256=7dmZ1YWeAHk9XtR5WIBZNEvLVwCgKCsthS1XdyFK2oY,12347
20
20
  fastapi_gen/template/{{cookiecutter.project_slug}}/docker-compose.frontend.yml,sha256=nmMjmzmyVudK9vZoFBmHNv4q4-ydq_lW5X4YrxEpP8E,2052
21
- fastapi_gen/template/{{cookiecutter.project_slug}}/docker-compose.prod.yml,sha256=a7o95f5BDXd-hJJtpA-n0AqB2n2mrGbtiGddk00t9OQ,22283
22
- fastapi_gen/template/{{cookiecutter.project_slug}}/docker-compose.yml,sha256=LBlsC40VLrYRzu-kbngvMnQxJXSJgNLKMAVOEI0eNX4,13635
21
+ fastapi_gen/template/{{cookiecutter.project_slug}}/docker-compose.prod.yml,sha256=TDcGq3GTvjzRz2IOVPFWZtFfh5atNTNDhO-cb0Y2-R4,22282
22
+ fastapi_gen/template/{{cookiecutter.project_slug}}/docker-compose.yml,sha256=0vmI_ux4O9WVB1ACcgUUnU54BADFTApI3bc4Z9Iz0MU,13634
23
23
  fastapi_gen/template/{{cookiecutter.project_slug}}/.claude/settings.json,sha256=i6XfBDlx6N1AXg4-MrjmIzPhxRXvQC9PRXJFZyfNs1Y,363
24
24
  fastapi_gen/template/{{cookiecutter.project_slug}}/.claude/commands/add-endpoint.md,sha256=p0EsXDvW23v4uOSPRlwA84nVrB7_VVL_FnKFEE442AQ,1648
25
25
  fastapi_gen/template/{{cookiecutter.project_slug}}/.claude/commands/fix-issue.md,sha256=3bcQwYzf_EXTit9nlkplUd0-G5T9-gGranogIDS_kjU,800
@@ -45,7 +45,7 @@ fastapi_gen/template/{{cookiecutter.project_slug}}/backend/.env.example,sha256=o
45
45
  fastapi_gen/template/{{cookiecutter.project_slug}}/backend/.pre-commit-config.yaml,sha256=22sYeJOrYywl_5PWgPzCyIwhpqmymIDIzx2hlBRQ-yI,681
46
46
  fastapi_gen/template/{{cookiecutter.project_slug}}/backend/Dockerfile,sha256=CKyuUKwt41LHIH9VB28TEzes5_TQkUEo9rIBjE3v8a8,2184
47
47
  fastapi_gen/template/{{cookiecutter.project_slug}}/backend/alembic.ini,sha256=vncO8XHTAW1ospWsdvtXD5PyMhp91CJmdVfv-6TakAY,737
48
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/pyproject.toml,sha256=X_dPJBsitGofJiauOpz2lKZV4gPvFRf_NOfuQUL9QFQ,13785
48
+ fastapi_gen/template/{{cookiecutter.project_slug}}/backend/pyproject.toml,sha256=g8ekuVxzP88UJWe5ad8Pog0J8sTvpgF0P2Vpm6dqWQE,13864
49
49
  fastapi_gen/template/{{cookiecutter.project_slug}}/backend/alembic/env.py,sha256=ifDazpmfYDUI0KGxaGcAgJbz6HNzu9bQYB6li88OMcU,3163
50
50
  fastapi_gen/template/{{cookiecutter.project_slug}}/backend/alembic/script.py.mako,sha256=ZCfgWrEMJRDF_WF_GRGptwAIJI6YnAditBG1axwAP9Q,700
51
51
  fastapi_gen/template/{{cookiecutter.project_slug}}/backend/alembic/versions/.gitkeep,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -74,6 +74,7 @@ fastapi_gen/template/{{cookiecutter.project_slug}}/backend/alembic/versions/0021
74
74
  fastapi_gen/template/{{cookiecutter.project_slug}}/backend/alembic/versions/0022_sync_source_org_scope.py,sha256=p6FtNMfqVQZtG7ollDrl7CaTOuhVwxqqSazvglVbRXU,2079
75
75
  fastapi_gen/template/{{cookiecutter.project_slug}}/backend/alembic/versions/0023_add_is_demo_conversations.py,sha256=VCVhhwyvbuuSiGKwXmw4rIgZ8x811AeCQgsDTaxsVCQ,793
76
76
  fastapi_gen/template/{{cookiecutter.project_slug}}/backend/alembic/versions/0024_create_webhook_tables.py,sha256=HExnIhQAJXNCe1vxhagIhUr0BeBBv2MTBadQEY4GtY8,3233
77
+ fastapi_gen/template/{{cookiecutter.project_slug}}/backend/alembic/versions/0025_message_thinking.py,sha256=8Wi3zcAXADP6WbjuB-Na_Y_OZTx6DDETkrZAVrNEdl8,727
77
78
  fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/__init__.py,sha256=vNnuyVXC5oZ3yq46meWLNhkUYlMgod70TgvWyvgNhBk,68
78
79
  fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/admin.py,sha256=QxVibclQNYtROGtf00Lsb5dlskvs4yLZ7SaEz6vf-IA,12990
79
80
  fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/main.py,sha256=CcUQKjWvANuNCRIS_vEry6ZglCs1wIwD76HkbMa3BHw,18948
@@ -164,7 +165,7 @@ fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/db/models/channel
164
165
  fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/db/models/channel_identity.py,sha256=RL8g8D8srDkvsyIZdKQClazuQXct_oj5VTaiRkaoHNM,3739
165
166
  fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/db/models/channel_session.py,sha256=3JlOn96T8g4o8xAfklxZJNx-OCJ0mJ_Va1aVQhBhLR8,4652
166
167
  fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/db/models/chat_file.py,sha256=yaGlDbt0FWBN3W8C4NKgFyBHJJDjlsfxGXmZrAcMY4U,2992
167
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/db/models/conversation.py,sha256=QeWPp8OHV07UHk4OBfTfiA0oBCEF2h3si5-ujJxuCzo,13147
168
+ fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/db/models/conversation.py,sha256=y0JSITSxhpfydPAwIaNgTpXDgwtU7VbelFhNp-jxzRU,13303
168
169
  fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/db/models/conversation_share.py,sha256=hOY9XL9pf4-VyqhyBZapqs6XP0G9B7uRaaoy1fLBY_k,4305
169
170
  fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/db/models/credit_transaction.py,sha256=BerBTIwkbf-e2OKZQOYFJd-gmrPEP7Zuwn0CJOGXtG4,6475
170
171
  fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/db/models/item.py,sha256=2z8g1K4Q1gFdycP2ZthFpb984Y1zqjWyajCO5Flh2Dw,1532
@@ -187,7 +188,7 @@ fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/repositories/chan
187
188
  fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/repositories/channel_identity.py,sha256=diP-iIg-D1By77eiJg6LDdw2cmKdK6Qi33L7hUtTc9E,2812
188
189
  fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/repositories/channel_session.py,sha256=E-4ThRDfqu41BsFxRMNCWH_4jklSq-Cf6eAPtl45u2A,3675
189
190
  fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/repositories/chat_file.py,sha256=zyBGqHCl2C2jzsz8u-3ra4nHh0Oh-dlyS8kxwSTSlhM,2055
190
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/repositories/conversation.py,sha256=_qozZOLAeNgtzevu6Q4iCo5kO-lghySMI7yiL0VOrQw,17620
191
+ fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/repositories/conversation.py,sha256=ivMNWQauKjVfTAnVo99WpHo5R7L3AVFmckerAPLbPS4,17680
191
192
  fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/repositories/conversation_share.py,sha256=PknNwwbngerOSgifXbbKiYAPvah4xbL9MIFxWgJ3pVc,3954
192
193
  fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/repositories/credit_transaction.py,sha256=CgQi3l9JYI-lTVeLcnK3G_fBsU4FYOxpxy5Hx00p_wc,1708
193
194
  fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/repositories/invitation.py,sha256=ZrHX2UuCtFXndKBVcyT871yPGa4-7OPzrI3mymwn4R0,3332
@@ -214,7 +215,7 @@ fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/schemas/base.py,s
214
215
  fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/schemas/billing.py,sha256=RvPxtX_dbmkF0LKbh-bZGoZcD29uzhmHfV5rH58FaHc,4047
215
216
  fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/schemas/channel_bot.py,sha256=gYlfAkHbsTK3oiYO3LklaO5Dr9VYiuAfzFk861MO8NE,3309
216
217
  fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/schemas/contact.py,sha256=0kN4rtNr80-dl5uhVwfbnQDc4WXNbWSxxqfuLQNW4_4,990
217
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/schemas/conversation.py,sha256=tGHgKQtuAfbDehzlxbz7vLX1AcVR_XuHC3eroV-8Ds8,7382
218
+ fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/schemas/conversation.py,sha256=RFrzIg_O-rU2HxqOapxqkyYKAfg6ZUpgaT2gFBeiis4,7478
218
219
  fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/schemas/conversation_share.py,sha256=PFt1XIipbX7y7YM4j3ZieJx254gQpwSIW90vw-cHSsM,2269
219
220
  fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/schemas/file.py,sha256=UNiB0dAYKtRrlKR-301jRsIEaq4n0MvHhSO5iaDMuoE,421
220
221
  fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/schemas/item.py,sha256=Z3YhlaGPPrSNUMw3IdC4Y86HZoeEJgS-D-S-I16E0cM,1064
@@ -233,13 +234,13 @@ fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/schemas/user_slas
233
234
  fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/schemas/webhook.py,sha256=Dw3HLj_8iXAgn72tx2P6MitBAsfy_LqRDjsLXwjPY3s,1889
234
235
  fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/services/__init__.py,sha256=2eaFa3riNnh9BVf4A6i7ChK1yqCOA8VyTg1zeL2tYy0,523
235
236
  fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/services/admin.py,sha256=FzwzW6FpIx1Ciwj_9lCbWMzi-EWv3v2-J8Sopi9LiZU,5576
236
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/services/agent.py,sha256=cHPy4xDuttdZDPMJhZDdQBB5dUOb4yx2sW5VWEyweVY,11974
237
+ fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/services/agent.py,sha256=nL7gsIBIHNsyePQHUBSWU5sO9jotfOkCXgE2T9t9hPY,12064
237
238
  fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/services/agent_invocation.py,sha256=u3OxIMVO4Q0rbouCKlW38YPjUrRNoydK2euoMT8mSR0,15919
238
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/services/agent_session.py,sha256=K7e_NiGT7rjZc5JNdkj8ViNR00mw9W5NiEQHaUn09tc,109353
239
+ fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/services/agent_session.py,sha256=PRZ0UeRkoqXc8gkjMQOSZvJP5KJqXqyVWwN9NyEb-UA,111483
239
240
  fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/services/anomaly_detection.py,sha256=uKPCzzdeyDSUbgkD7VwFIubEHhoU1LEoOp3R1_F0SlE,3112
240
241
  fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/services/channel_bot.py,sha256=R1tfQQcNxHKZ9C3yOD6Hh4TANY77FL4XNic4Rf40qWo,6383
241
242
  fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/services/contact.py,sha256=AuML8RHIozZkchZlNMjHsZhLWpTMxukfy1xk6mak3Bk,1697
242
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/services/conversation.py,sha256=v6zyIjd6cvPbvuoCWu_6CmdgdQGOq5yBi6J81rOD3Sk,21062
243
+ fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/services/conversation.py,sha256=liTgds5WOCfNpdIQ2mFzFu9F05hxI5IW_ay-hlRvMz0,21098
243
244
  fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/services/conversation_share.py,sha256=JQHy636d7NI058yBlFyQ-17VQzau-Z6G2FIp4E0XOIg,6711
244
245
  fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/services/file_storage.py,sha256=EOl8jrSN5yxMgBb9eN-BElSsRfpEyFC_eF6qR3eRPYc,4618
245
246
  fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/services/file_upload.py,sha256=oFS-voZyGA0OH_yLM8XgvjenOTRV3W9deeg9bJ6sPcE,11022
@@ -415,17 +416,29 @@ fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/README.md,sha256=VWO
415
416
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/eslint.config.mjs,sha256=y48aSi3BZvVi6GvePRqKmfaMJdK6ymN9X5fyeHFlpPU,2663
416
417
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/instrumentation.ts,sha256=KKUhYC1lApvs-Vtw9kkzqYiZBaW5axDvHhxeHznljM4,344
417
418
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/next.config.ts,sha256=5LYPHgUWe0H8oDoQ7aFBT-OlwC0SSvFJMmoroPAYqp0,3497
418
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/package.json,sha256=feSYK-WckSZoB-N8WI85z8432VtKfeZ-ms8dbzXBH7A,3679
419
+ fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/package.json,sha256=LftX3RfeQvzHRrjEfdegH2fG6kbFqat-5edWq6rQ69s,3900
419
420
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/playwright.config.ts,sha256=KVU5cy9ASA9K0ylTbJcDTgS3q_VU5MsqH1-_rH3WiFI,2534
420
421
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/postcss.config.mjs,sha256=36x6wthtMmoOWtsCTnlDwYE5PtF6X8uPAxWyTH2m3d4,94
421
422
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/tsconfig.json,sha256=d8LzqnKr4bNHXByRHfgxcFQwP_5qFpspoaGbQvEpdgc,660
422
423
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/vercel.json,sha256=dZTAUschzf71bsXMxzcTrze9QVhERJNuqbsciWSbE48,128
423
424
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/vitest.config.ts,sha256=bEndp9agQJy9Pbfrjq1ARjLC-SZqJzlEHHi3uT9PUto,924
424
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/vitest.setup.ts,sha256=VkPwN2DE2TjgosXO4vgBFTusROfdmuoi9QqXtDy7pW0,1315
425
+ fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/vitest.setup.ts,sha256=98yWZaevBBKgyrAoWAZFin-pGxjFPoXQvs7LV2XYcoQ,2271
425
426
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/.husky/pre-commit,sha256=p-PuC-dVS7YIN816QU5hqmpR25hzkOMlo3mcvcJU3dg,17
426
427
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/content/blog/rag-defaults-that-age-well.mdx,sha256=Ymg7WB6XD8yo3ouNSFq9MkhKFFHiGuSaR4ZIKkwoXFI,3150
427
428
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/content/blog/shipping-ai-saas-template.mdx,sha256=rP2ggPj6Weauj7Avwj_CGe9HwKoqCxMYqr3czH5hOdI,2768
428
429
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/content/blog/streaming-tool-calls-without-tears.mdx,sha256=V4EZz0BVsn1Dts-9wx5u5cEIuW4sjvV-Yh6KfjiCOro,3665
430
+ fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/demo-export/entry.css,sha256=i0xtoR-s7rUVdt0uDOHXmOzbtVWOhOQ5VoTmhSm20Tg,254
431
+ fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/demo-export/index.html,sha256=ZJxKkNmFPxFvWFw4cHjLjuLAvNQgFEdDXKzyDo2NG54,1062
432
+ fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/demo-export/main.tsx,sha256=XAUNxNSvHOeoINoUz0TAAWqL81pHj2N13muPG9eQCE8,2920
433
+ fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/demo-export/postcss.config.mjs,sha256=WwvEx4vpd82B-Uf7VWOqp8xtRR5vHFOjJgt2VqcUTSA,70
434
+ fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/demo-export/vite-env.d.ts,sha256=-296Fn2cAlXszhonePFhHI7qXbOpQJkEA2G-qLGTzPI,377
435
+ fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/demo-export/vite.config.ts,sha256=bAbyySKnz7UsLrUJYfpUbdrZx017UPr_Srg6g-sriJA,1328
436
+ fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/demo-export/assets/user-avatar.jpg,sha256=3njA64q8WqFkGJKJDDp14akAXIhjuwBW9wnxBWwusMg,2459
437
+ fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/demo-export/shims/next-dynamic.ts,sha256=2v6Mx-Uw8DmaRKYnZJZIII5DILQlTRe3hoeCQBqPbqU,911
438
+ fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/demo-export/shims/next-image.tsx,sha256=SyTVVbiBsHRbED_xsT0x_byVgADpWOMiLutMOqQZKbM,870
439
+ fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/demo-export/shims/next-intl.ts,sha256=98MBubpR6SX7IQIqjzLOUaCznK54S6opUXJiAYUAKXU,428
440
+ fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/demo-export/shims/next-link.tsx,sha256=hm-u1TLyIo72VdgDNsaK2nNKByzl1j6KlZ8Owg86Yfw,456
441
+ fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/demo-export/shims/next-navigation.ts,sha256=a3XS3n74xnnTkXE78z2F3RWANva_ku4LkVd9qExvRcs,517
429
442
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/e2e/auth.setup.ts,sha256=OyeeeylUxBClyZk-n8X6rd5_43yt3Tf0m8g9Og75rYk,1496
430
443
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/e2e/auth.spec.ts,sha256=WgBZMrrJRDurowJ0GFAFmV1Ro1zLX5xZ2nNDGzrTuBs,4697
431
444
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/e2e/chat.spec.ts,sha256=7Uof2VBRfw6Hsg7UMEMjb0cvPV5j5x0EqktOI-youkk,6470
@@ -618,9 +631,9 @@ fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/billi
618
631
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/billing/subscription-panel.tsx,sha256=_bX5U5WtZJcHcG5CN70IOOkgKPpuKowaXsABEgcfYws,8395
619
632
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/billing/usage-gauge.tsx,sha256=ZPqrAje74mN05C_OLa_RsjMa4NltVob2YUP0sJTUel8,3345
620
633
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/blog/mdx-components.tsx,sha256=0P0-9MrhgNr_dJJzC6PKxexzI5TcdiJajWF1QXDskuM,1546
621
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/chart-message.impl.tsx,sha256=sEcx2PaCohCH-xOXEgJrxpwtsjhGdktj5KsCgk7hxvI,12254
634
+ fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/chart-message.impl.tsx,sha256=uFKDkl9bIL4TZ2xwbUrZXWKzLVeJJEKPTX99e2uN-xw,12267
622
635
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/chart-message.tsx,sha256=ZpsuzDVcyyqa931jJ4NF8Be_hLy6VnH_xYECpCkbRew,1584
623
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/chat-container.tsx,sha256=v93gZIcM8A0WsN8StcJ3yNaH084WFkK_cCmGkZw8SO0,16202
636
+ fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/chat-container.tsx,sha256=7pBOadMRnKKglZdIGdhjW1rHPCJ8-Tfe0OSEeN72y4A,15926
624
637
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/chat-controls.tsx,sha256=3AlRkCKfn3tgZ7BNyJG0gRtd1_w599TFIR8wUiKhaak,22010
625
638
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/chat-empty-state.tsx,sha256=MDliSs2OeBqAdgsDB8n2F6hAnph171ToMKyWKNhGNZM,3450
626
639
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/chat-input.tsx,sha256=93lH1N65c1unaYZsAdfCY7BJy6uaY_-nX0XXfunexvk,14101
@@ -630,29 +643,31 @@ fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/
630
643
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/file-preview-panel.tsx,sha256=k7Zc3GErzDqG9AWYjC-FHashgGe5np3PFp3jDcz3V20,5346
631
644
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/index.ts,sha256=QQyEzBBusvWeWsRJxG8vWJOLByKB6RPRupGshGCr4Pg,661
632
645
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/map-leaflet.tsx,sha256=kw6smOBFHQabKtkPE7RF-SrDBvtc8RNG0yEzP3zwRrQ,2166
633
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/map-message.tsx,sha256=qXVGLU5E8YLnQ9VCi3W2731ONHNswY6dyWt4MkA6r8s,1195
646
+ fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/map-message.tsx,sha256=-MvkM0ewxpYEk8S2lVKzFLsqLuhySX1X1M7o4rxnh6c,1208
634
647
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/markdown-content.impl.tsx,sha256=Ib-0S-O2lPR2YWb1Npgzgy_wNX1e0wSlH9ng4r-MgZg,7898
635
648
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/markdown-content.tsx,sha256=CshGuy6cuMpUbxwNc3ediV-bP33dmzs26XjqV32uoYc,1241
636
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/message-item.tsx,sha256=L6iInDwUf1VwHaCRNzzP9QneOUhSo_eUvUIyr945efg,17283
649
+ fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/message-item.tsx,sha256=3YZcLIU1okozTOf-EuNpsgxmN6Pxz50HeANcuKbeORM,17581
637
650
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/message-list.tsx,sha256=eSf8wtI7_aOsLWYmhkDrOcdHEoI5Br-RPgtz26rLgM0,1544
638
651
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/pending-messages.tsx,sha256=7gx3EDbgrT-xygRdhCeLapl6VIVWZHUIneCEbzq3Gh8,2464
639
652
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/rating-buttons.tsx,sha256=lmtyqe1rUvq99BNZumM_uV1B1-040dko4EYqJBlbzQA,8625
640
653
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/research-panel.tsx,sha256=3DZ7qKdzb6TwQx6qGWXfGefkyBf4Q_QOAWwB3whQKkA,6888
654
+ fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/research-replay-block.tsx,sha256=dxHESiwxgt1mAOi36QegNJ7Nsox1TXabE47xzfpSkkk,5630
641
655
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/share-dialog.tsx,sha256=prBfZ04-DuFzYaN1a-yC2vVQE1oeGP9iICa7BgFfaDc,6993
642
656
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/slash-command-palette.tsx,sha256=CJppPM_hGl7_gLTWUpvpR9Ka2YZ-_ZDKkKit_La0PmM,2733
643
657
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/slash-commands.ts,sha256=ddcIKQm4vqXh17nqIFPWdnGkuzOQlDCsigIx2W_oSI4,4920
644
658
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/sources-panel.tsx,sha256=u3W67H46o1b_KWTeT7CZMAE_oWKlDqFOcnzqsAwkHBU,6143
645
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/subagent-feed.tsx,sha256=HeOmoSxjvIazSGCHyFvULEQrRA8NaIeXPj5x7oKLlHY,3519
659
+ fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/subagent-feed.tsx,sha256=0pDGWnBc1GNCOgl9fhc9YUlBavqTQtSxXbKxRFXE9Eo,3655
646
660
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/subagent-panel.tsx,sha256=ObR1ACPfOLUllCZmrwCcYV0vFhyms7yOtYYNkZ2Duk8,6268
647
661
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/tool-approval-dialog.tsx,sha256=TIwATvTCIB-NQMEay0KvKrsk1bfjnvX-8IdhOBK0L9I,3814
648
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/tool-call-card.tsx,sha256=QBKbPuCEuHg_X-4Ii5bXKHeI5LfDTsXHMmQRQ0mv5i8,11496
662
+ fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/tool-call-card.tsx,sha256=BjQgDx5OXieqVfVVOKNwMi0YfDaRdkbzkBU63Uikh5w,12396
649
663
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/tool-results/ask-user.tsx,sha256=0WDPIa2VfVCCZAD9ErSDm8k_obQ-6Jzk8NUEju-U3P4,1850
650
664
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/tool-results/datetime.tsx,sha256=8QD9Goqr0LQSUJZ8YBxX03tFfXBpSr_0UxDLbgAuK_s,1124
665
+ fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/tool-results/fetch-url.tsx,sha256=SuOfe4LCJR52mRU2Bd4tr_UbHViYBym06KlInrCiaMM,1919
651
666
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/tool-results/generic.tsx,sha256=NeZhU7C30jrXdsaabpU3wl0140zmrsbSGBi5vya0Blw,4648
652
667
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/tool-results/rag.tsx,sha256=0dvNBaKqemY1UZc9ng0rMgonVbhRFuq8i0d66SEwFG4,6768
653
668
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/tool-results/run-python.tsx,sha256=YHTMHyzCDKChmUE--vpr9Uvc238ZGv4-VOJcPJOFHkg,2982
654
669
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/tool-results/skills.tsx,sha256=m8vGsbrBxT6mVQadhLE2O6-qCykDZ7MicaBfHHL0-Tk,1220
655
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/tool-results/web-search.tsx,sha256=FLuPPITEMbBZ7eAq3T7KSnCzaJyq-f2Hwryd0m2JTKw,2814
670
+ fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/tool-results/web-search.tsx,sha256=QAYSZQrZy7CDuBy80oSTTFT_a_INMFsxCAwCRoilGjo,3549
656
671
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/dashboard/active-sessions.tsx,sha256=N23ngldlMR4qwQBFxT5gBPEtw2zy1ndnM7-pPjKirwo,3699
657
672
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/dashboard/onboarding-banner.tsx,sha256=8HjxqlXjaVh9WF1PVG6LuVfmKJpGdtzTme8FCdbWF_s,2095
658
673
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/dashboard/page-header.tsx,sha256=GkcV7Fw2UF-r8FHfwA9Tr_ZtxgDWUlxZO3agKYUcWEk,2892
@@ -669,7 +684,7 @@ fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/dashb
669
684
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/dashboard/top-models.tsx,sha256=SCF6Km4k-6vZ1PJ34_-I1HI_kOtWG6LPRUZZP7mbiG0,5378
670
685
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/dashboard/usage-timeline-chart.tsx,sha256=5qOWHGrRL1RowATqM6dnL4Fpp17QZemQQHy40WOHr3Y,2996
671
686
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/dashboard/usage-timeline.tsx,sha256=9UTnbjkAJxpoJddtJ-LC8znxNTatrUb9RxZvy4aLqak,4878
672
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/demo/demo-replay.tsx,sha256=EYHtPsNwWHmu9BMETquVuwQc_GiP239uDm_hVflIWWw,7903
687
+ fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/demo/demo-replay.tsx,sha256=NOe7uRFArkjqpXLHU_6M842hz6xgqTRYaRjLd_6vMfQ,54265
673
688
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/icons/google-icon.tsx,sha256=c_mbeTuAWdBIqIIi4eQkhdBIu3EwxjjCf8oQCsPYwwA,45
674
689
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/icons/index.ts,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
675
690
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/kb/create-kb-dialog.tsx,sha256=FmM1SgExL8FopJ08tL49dXc06Bm3iooQtE8EQvhRgQU,3396
@@ -791,7 +806,7 @@ fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/hooks/use-admin-
791
806
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/hooks/use-auth.ts,sha256=t_ty2PTLpxhY4UDMop9-Qm21n6Ne8swEPwDhlPzUPOA,4936
792
807
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/hooks/use-billing.ts,sha256=XosrZfGWIg5u7Nkg4oP4iSIwPf2B-jM9hntryppQ8rU,5193
793
808
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/hooks/use-chat.ts,sha256=1ySt4t1O_DaLw9vQ-3Y1EfyXTrFSo6nKaS1IhDhWTmQ,21791
794
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/hooks/use-conversation-replay.ts,sha256=WtHU_lMxPt33E55luBV6_I8X811KRFxsJKcpcWRaXWM,4111
809
+ fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/hooks/use-conversation-replay.ts,sha256=RihruqoeHxoHm9lz1vfa4vlCC265N6Qb7QMVP0scKzA,4587
795
810
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/hooks/use-conversation-shares.ts,sha256=zBDtX_8Y7y7prGgvluG9snsd76THpwpAz6Svc4BY2qY,4828
796
811
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/hooks/use-conversations.ts,sha256=GaIjfll-yJDVlP0-5-7dbkiuPsy8mW6sKCzYC5q_vvs,10826
797
812
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/hooks/use-copy-to-clipboard.ts,sha256=PKdzoWMTTthOqzC9Fj_paf42EkaFpFjl1LO-8Pj8tE0,437
@@ -802,25 +817,27 @@ fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/hooks/use-org-in
802
817
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/hooks/use-organizations.ts,sha256=YxxH4Kv4RrMeAXhcddZHXYxUSJkZis_aHD4fMh50SMM,3814
803
818
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/hooks/use-projects.ts,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
804
819
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/hooks/use-slash-commands.ts,sha256=Ld7DgSNXY7NoJBvYq86SNBJPkbv-oR1KfLk-UZAX60E,4352
805
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/hooks/use-step-replay.ts,sha256=i5OyeW3reN0B8Gj55qaP_cZCwJb9OYl--o6zh5a8V3A,6265
820
+ fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/hooks/use-step-replay.ts,sha256=-ulQgOYrlD9FBWLfRXHaRaYs6JqOk9RGj_6XqIiGgz0,7459
806
821
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/hooks/use-websocket.ts,sha256=UtuIGl4sl6ykDkRrosdBXg2EwiQmNYxdaUWF6Bt1t2o,6967
807
822
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/lib/active-route.ts,sha256=WuHpNgE_Vc4CaAX__rD-cQLASL-O0_x7SB0TDRoRiyI,1305
808
823
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/lib/admin-auth.ts,sha256=2K09o5o8Q24yn1dn1uAfqIIlrCgQQDz4tTFFdJVSCTU,904
809
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/lib/agent-step-captions.ts,sha256=G7axXhQ0ju341KwYqqOU-pPEGcu-S6X2lcN3Lvxdznk,1755
824
+ fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/lib/agent-step-captions.ts,sha256=JjD-uhglLL3D9aUoNElMkjbdD-r4P9AayGUC2YmVO44,2388
810
825
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/lib/api-client.ts,sha256=v9qO6pac2VH5j-o0oMhawpOUXDKqGQNrPo4KPUlLFX4,4107
811
826
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/lib/blog.ts,sha256=xaVKtXjwO53zzvVSPEfaifwfVXQzHnpNvpM8zDfElns,4304
812
827
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/lib/changelog.ts,sha256=1z3pSuUEks_KmO-E9u5VUt1yXqQFDOrsXeJ-RvUHB0s,4340
813
828
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/lib/chat-sources.ts,sha256=P7P2-8OvQQTvAzSaRiqRvOb3IkFF6CDgBnRdEAsL9rU,2035
814
829
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/lib/constants.ts,sha256=eesSDW2Oubtjtpzhw4SQhQun5U1UpHSR_hzS4m2XFzE,2286
815
830
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/lib/contact-info.ts,sha256=oTIbswuq-RlSXv-z08jlZTOp2pyPazwcOoRN9PjfjtE,1168
816
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/lib/conversation-to-chat.ts,sha256=_dBgZCouqzplmw9i40qn5aMhEvZcn1xG0yfHzJheNhw,2424
831
+ fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/lib/conversation-to-chat.ts,sha256=Xcaa0gI6loIKkOJnjP73V0BFH4NMbcRXONiCrpdkJpk,3512
817
832
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/lib/file-api.ts,sha256=t7uOB7xdIh4K1Jt5kcyWro_oEfnrh2hxi52xsPEZRw8,787
818
833
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/lib/query-keys.ts,sha256=UK1jzUwj6y7bxSIetYY1oP_CeDN2p1n6P30KNKhhdNI,2405
819
834
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/lib/rag-api.ts,sha256=fSr_Zeus_FULCZvtkWrPHIKHbX4A45yL0w1NzDv21zc,9702
835
+ fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/lib/research-from-tools.ts,sha256=jwgjUuOgwgRKkz7EN9lxM2weuu3NNBk2sl4FKeB6hRw,2459
820
836
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/lib/schema-org.ts,sha256=CmKYvUS5wXQfKF9RtmChvLN18aWinPiFIwohTPmyAOc,2108
821
837
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/lib/seo.ts,sha256=B2_BjfwxTqQteTjqc-YfffaFbTP9l9X14ZUeb7V9K-I,4159
822
838
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/lib/server-api.ts,sha256=l2EqqLbGOqpciksb6LCrb3sI605mPbZfn5rF2n8dwPU,2248
823
839
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/lib/slash-commands-api.ts,sha256=-o7aMs7VN54nMpQhF1f8bSM6fn_OzLXXEFjxl5tvqUs,1640
840
+ fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/lib/sql-format.ts,sha256=17eV_mh8lYt9gJ_zUMqMeycewW2ipodYvjg6FQAXLj4,1345
824
841
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/lib/teaser-plans.ts,sha256=EAA5FC-ZnTJr-dJsHApDUOtc6pwnygs924-hVywLMFI,3312
825
842
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/lib/utils.test.ts,sha256=7f9craA0Jb-q8Xlm_UklKgirdlUXdBH-k089pgabJrE,1183
826
843
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/lib/utils.ts,sha256=wnyTmnuMv_87gwoRl9Fa_A3l-R_rp7uJX24w5JTnl-c,3569
@@ -842,8 +859,8 @@ fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/stores/theme-sto
842
859
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/types/api.ts,sha256=s71GyMC2O6w5mtqY8uB9aBYMVRFKeB_QGDfvGldweuo,364
843
860
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/types/auth.ts,sha256=2sMcucSTN-8d4zk1Lql30DElfizApr_fHtOsQ3DvTmE,1369
844
861
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/types/billing.ts,sha256=71NnQ9xs6G3LC_H-eA7mCSbDfUbWD3leyntmid_AWpI,2517
845
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/types/chat.ts,sha256=m3HlMSF7ji9-zuiB9UL3Gezq2ij2SF2n4RMce2Zdgko,6597
846
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/types/conversation.ts,sha256=laFw5_5gG5_tEsprAXyrhXVGGLLxdFHkSgV1lcZX3vU,2910
862
+ fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/types/chat.ts,sha256=o_xP6YGkbWcDJzF0KG_G6IVjPTAWB8QJWH7SdCXmyFE,6839
863
+ fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/types/conversation.ts,sha256=j36sf9CRIimGgEWGhI76Gl8V9HaTf80-B76LD-JisQU,2938
847
864
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/types/index.ts,sha256=ujKK1JNdTCrKisVTeaUCgq23Dxv6nVBVgYM3L9aEFyY,373
848
865
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/types/knowledge-base.ts,sha256=xkCES2rU51ei-pdqwxMNsZuoTfmaT7fWteoJrOMQGzw,1053
849
866
  fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/types/organization.ts,sha256=-Dsw9FGzZAqbclJwnc7l3PqVJYqEehw8Kj7z7kmFYsc,1204
@@ -858,8 +875,9 @@ fastapi_gen/template/{{cookiecutter.project_slug}}/kubernetes/secret.yaml,sha256
858
875
  fastapi_gen/template/{{cookiecutter.project_slug}}/kubernetes/service.yaml,sha256=o3bCXguj8E5aQ0H1o3cBD3z_iZ_RA_Pmx1bc0sVzK28,682
859
876
  fastapi_gen/template/{{cookiecutter.project_slug}}/nginx/nginx.conf,sha256=gJWUMMqNvr9TwNZOcc_WPPGZvdAlRUH3jLhbllOb_YY,7359
860
877
  fastapi_gen/template/{{cookiecutter.project_slug}}/nginx/ssl/.gitkeep,sha256=o_WQQOgVGOLttT48x0EXSC4BbbDFemApFpmwhybcVUU,617
861
- fastapi_fullstack-0.2.15.dist-info/METADATA,sha256=cUV7-TJgE9zjN2dWk8eTSypHf2UHnZR1lRK6Izkr5DY,59043
862
- fastapi_fullstack-0.2.15.dist-info/WHEEL,sha256=mffPy8wBnZQn2VnJUU5jE99KsxaSfiyMHV9Yt0aLVxs,87
863
- fastapi_fullstack-0.2.15.dist-info/entry_points.txt,sha256=s9JXrISZp8LMYJGeVofOAd1wPTzpq-jwjSgSf4hWzjs,59
864
- fastapi_fullstack-0.2.15.dist-info/licenses/LICENSE,sha256=bL4JuK_rcA8y__Gg7PEuTs3g2Qf6VvSz2w2Jajd6nVU,1063
865
- fastapi_fullstack-0.2.15.dist-info/RECORD,,
878
+ fastapi_gen/template/{{cookiecutter.project_slug}}/scripts/export_demo_html.py,sha256=H1tbIfr1xrh2pRuoy5NwvAOYEu0S2vgnw_XsKNMKXeM,10414
879
+ fastapi_fullstack-0.2.16.dist-info/METADATA,sha256=2E5Ak0s1WW_t5jvxaF_oyIa2b1PamD9oUCG03diGvj4,59043
880
+ fastapi_fullstack-0.2.16.dist-info/WHEEL,sha256=lCkmxWfQsSc9CfIClYeavTdQeEX2toPqufh9gI35EQA,87
881
+ fastapi_fullstack-0.2.16.dist-info/entry_points.txt,sha256=s9JXrISZp8LMYJGeVofOAd1wPTzpq-jwjSgSf4hWzjs,59
882
+ fastapi_fullstack-0.2.16.dist-info/licenses/LICENSE,sha256=bL4JuK_rcA8y__Gg7PEuTs3g2Qf6VvSz2w2Jajd6nVU,1063
883
+ fastapi_fullstack-0.2.16.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: hatchling 1.30.1
2
+ Generator: hatchling 1.31.0
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
fastapi_gen/cli.py CHANGED
@@ -50,6 +50,7 @@ def _preflight_check( # noqa: C901
50
50
  frontend: str,
51
51
  admin_panel: bool,
52
52
  marketing_site: bool,
53
+ demo_export: bool,
53
54
  oauth_google: bool,
54
55
  gdrive_rag: bool,
55
56
  s3_rag: bool,
@@ -152,6 +153,13 @@ def _preflight_check( # noqa: C901
152
153
  "Add --frontend nextjs or drop --marketing-site",
153
154
  )
154
155
  )
156
+ if demo_export and frontend == "none":
157
+ issues.append(
158
+ (
159
+ "--demo-export requires --frontend nextjs (it bundles the real replay UI into the HTML)",
160
+ "Add --frontend nextjs or drop --demo-export",
161
+ )
162
+ )
155
163
  if admin_panel and frontend == "none":
156
164
  click.echo(
157
165
  click.style(
@@ -631,6 +639,12 @@ def new(output: Path | None, no_input: bool, name: str | None, minimal: bool) ->
631
639
  default=False,
632
640
  help="Generate marketing/landing pages",
633
641
  )
642
+ @click.option(
643
+ "--demo-export",
644
+ is_flag=True,
645
+ default=False,
646
+ help="Self-contained HTML demo export (Vite bundle + exporter script; requires --frontend)",
647
+ )
634
648
  @click.option(
635
649
  "--i18n/--no-i18n",
636
650
  "i18n",
@@ -793,6 +807,7 @@ def create(
793
807
  email_provider: str,
794
808
  newsletter: bool,
795
809
  marketing_site: bool,
810
+ demo_export: bool,
796
811
  i18n: bool,
797
812
  example_resource: bool,
798
813
  changelog: bool,
@@ -1117,6 +1132,7 @@ def create(
1117
1132
  frontend=frontend,
1118
1133
  admin_panel=admin_panel,
1119
1134
  marketing_site=marketing_site,
1135
+ demo_export=demo_export,
1120
1136
  oauth_google=oauth_google,
1121
1137
  gdrive_rag=gdrive_rag,
1122
1138
  s3_rag=s3_rag,
@@ -1213,6 +1229,7 @@ def create(
1213
1229
  email_provider=EmailProviderType(email_provider),
1214
1230
  enable_newsletter_signup=newsletter,
1215
1231
  enable_marketing_site=marketing_site,
1232
+ enable_demo_export=demo_export,
1216
1233
  enable_i18n=i18n,
1217
1234
  include_example_crud=example_resource,
1218
1235
  enable_changelog=changelog,
fastapi_gen/config.py CHANGED
@@ -395,6 +395,7 @@ class ProjectConfig(BaseModel):
395
395
 
396
396
  # Marketing / Frontend pages
397
397
  enable_marketing_site: bool = False
398
+ enable_demo_export: bool = False
398
399
  enable_i18n: bool = True
399
400
  include_example_crud: bool = False
400
401
  enable_changelog: bool = False
@@ -618,6 +619,11 @@ class ProjectConfig(BaseModel):
618
619
  "Marketing site requires a frontend (landing/blog/legal pages need a UI). "
619
620
  "Quick fix: add --frontend nextjs, or drop --marketing-site."
620
621
  )
622
+ if self.enable_demo_export and self.frontend == FrontendType.NONE:
623
+ raise ValueError(
624
+ "Demo export requires a frontend (it bundles the real replay UI into the HTML). "
625
+ "Quick fix: add --frontend nextjs, or drop --demo-export."
626
+ )
621
627
  if self.oauth_provider != OAuthProvider.NONE and self.frontend == FrontendType.NONE:
622
628
  raise ValueError(
623
629
  "OAuth requires a frontend for the callback page. "
@@ -969,6 +975,7 @@ class ProjectConfig(BaseModel):
969
975
  "enable_admin_features_system_health": self.enable_admin_features_system_health,
970
976
  # Marketing / Frontend pages
971
977
  "enable_marketing_site": self.enable_marketing_site,
978
+ "enable_demo_export": self.enable_demo_export and self.frontend != FrontendType.NONE,
972
979
  "enable_changelog": self.enable_changelog,
973
980
  "enable_testimonials": self.enable_testimonials,
974
981
  "enable_comparison_pages": self.enable_comparison_pages,
fastapi_gen/prompts.py CHANGED
@@ -1450,6 +1450,11 @@ def prompt_marketing_features() -> dict[str, bool]:
1450
1450
  value="status_badge",
1451
1451
  checked=True,
1452
1452
  ),
1453
+ questionary.Choice(
1454
+ "Demo export (offline HTML replay of a saved conversation)",
1455
+ value="demo_export",
1456
+ checked=False,
1457
+ ),
1453
1458
  ],
1454
1459
  ).ask()
1455
1460
  )
@@ -1461,6 +1466,7 @@ def prompt_marketing_features() -> dict[str, bool]:
1461
1466
  "enable_comparison_pages": "comparison_pages" in features,
1462
1467
  "enable_affiliate_program": "affiliate_program" in features,
1463
1468
  "enable_status_badge": "status_badge" in features,
1469
+ "enable_demo_export": "demo_export" in features,
1464
1470
  }
1465
1471
 
1466
1472
 
@@ -1801,6 +1807,7 @@ def run_interactive_prompts() -> ProjectConfig:
1801
1807
  "enable_comparison_pages": True,
1802
1808
  "enable_affiliate_program": True,
1803
1809
  "enable_status_badge": True,
1810
+ "enable_demo_export": False,
1804
1811
  }
1805
1812
  if frontend != FrontendType.NONE
1806
1813
  else {}
@@ -196,6 +196,7 @@ These variables are set automatically by the generator.
196
196
  | `enable_cors` | bool | `true` | Enable CORS middleware | - |
197
197
  | `enable_webhooks` | bool | `false` | Enable webhook support | - |
198
198
  | `enable_conversation_persistence` | bool | `true` | Enable conversation persistence (derived from `use_ai`) | Computed from `use_ai` |
199
+ | `enable_demo_export` | bool | `false` | Self-contained HTML demo export: a `frontend/demo-export/` Vite single-file bundle + `scripts/export_demo_html.py` that render a saved conversation to one offline `.html` replay | Requires a frontend |
199
200
  | `include_example_crud` | bool | `false` | Include example CRUD endpoints (always disabled) | Always false |
200
201
  | `enable_i18n` | bool | `true` | Enable internationalization in frontend (always enabled) | Always true |
201
202
  | `seed_admin_email` | string | `""` | Email of a user to auto-promote to app-admin on first startup (via `FIRST_ADMIN_EMAIL` env var) | - |
@@ -84,6 +84,7 @@
84
84
  "use_all_providers": false,
85
85
  "use_ai": true,
86
86
  "enable_conversation_persistence": true,
87
+ "enable_demo_export": false,
87
88
  "enable_langsmith": false,
88
89
  "enable_web_search": false,
89
90
  "enable_web_fetch": false,
@@ -41,7 +41,9 @@ enable_rag_image_description = "{{ cookiecutter.enable_rag_image_description }}"
41
41
  enable_google_drive_ingestion = "{{ cookiecutter.enable_google_drive_ingestion }}" == "True"
42
42
  enable_s3_ingestion = "{{ cookiecutter.enable_s3_ingestion }}" == "True"
43
43
  enable_web_search = "{{ cookiecutter.enable_web_search }}" == "True"
44
+ enable_web_fetch = "{{ cookiecutter.enable_web_fetch }}" == "True"
44
45
  web_fetch_tool = "{{ cookiecutter.web_fetch_tool }}" == "True"
46
+ enable_demo_export = "{{ cookiecutter.enable_demo_export }}" == "True"
45
47
  enable_charts = "{{ cookiecutter.enable_charts }}" == "True"
46
48
  charts_channel_png = "{{ cookiecutter.charts_channel_png }}" == "True"
47
49
  enable_code_execution = "{{ cookiecutter.enable_code_execution }}" == "True"
@@ -154,6 +156,20 @@ if not enable_deep_research and use_frontend:
154
156
  frontend_src = os.path.join(os.getcwd(), "frontend", "src")
155
157
  remove_file(os.path.join(frontend_src, "stores", "research-store.ts"))
156
158
  remove_file(os.path.join(frontend_src, "stores", "chat-mode-store.ts"))
159
+ remove_file(os.path.join(frontend_src, "lib", "research-from-tools.ts"))
160
+ remove_file(os.path.join(frontend_src, "components", "chat", "research-replay-block.tsx"))
161
+
162
+ # The fetched-page tool-result renderer is only referenced when web fetch is on.
163
+ if not enable_web_fetch and use_frontend:
164
+ frontend_src = os.path.join(os.getcwd(), "frontend", "src")
165
+ remove_file(os.path.join(frontend_src, "components", "chat", "tool-results", "fetch-url.tsx"))
166
+
167
+ # Self-contained HTML demo export (Vite single-file bundle + exporter script).
168
+ # Only meaningful with a frontend to bundle; drop everything otherwise. The
169
+ # scripts/ dir exists solely for this exporter, so remove it wholesale.
170
+ if not (enable_demo_export and use_frontend):
171
+ remove_dir(os.path.join(os.getcwd(), "frontend", "demo-export"))
172
+ remove_dir(os.path.join(os.getcwd(), "scripts"))
157
173
 
158
174
  if not enable_subagents and use_frontend:
159
175
  frontend_src = os.path.join(os.getcwd(), "frontend", "src")
@@ -99,5 +99,10 @@ logs/
99
99
  # OS
100
100
  .DS_Store
101
101
  Thumbs.db
102
+ {%- if cookiecutter.enable_demo_export %}
103
+
104
+ # Demo-export Vite build output (regenerated by `bun run build:demo-export`)
105
+ frontend/demo-export/dist/
106
+ {%- endif %}
102
107
 
103
108
  # Project specific