llms-py 3.0.0b9__tar.gz → 3.0.1__tar.gz

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 (220) hide show
  1. {llms_py-3.0.0b9/llms_py.egg-info → llms_py-3.0.1}/PKG-INFO +1 -1
  2. llms_py-3.0.1/llms/extensions/app/README.md +20 -0
  3. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/app/__init__.py +16 -15
  4. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/app/db.py +7 -6
  5. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/app/ui/index.mjs +1 -1
  6. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/app/ui/threadStore.mjs +21 -17
  7. llms_py-3.0.1/llms/extensions/core_tools/CALCULATOR.md +32 -0
  8. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/core_tools/__init__.py +1 -1
  9. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/core_tools/ui/index.mjs +4 -4
  10. llms_py-3.0.1/llms/extensions/gallery/README.md +61 -0
  11. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/gallery/ui/index.mjs +1 -0
  12. llms_py-3.0.1/llms/extensions/katex/README.md +39 -0
  13. llms_py-3.0.1/llms/extensions/system_prompts/README.md +22 -0
  14. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/system_prompts/ui/index.mjs +21 -26
  15. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/system_prompts/ui/prompts.json +5 -5
  16. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/llms.json +9 -12
  17. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/main.py +25 -5
  18. llms_py-3.0.1/llms/providers.json +1 -0
  19. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/ui/ai.mjs +20 -5
  20. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/ui/ctx.mjs +25 -1
  21. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/ui/modules/chat/ChatBody.mjs +43 -27
  22. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/ui/modules/chat/index.mjs +17 -29
  23. {llms_py-3.0.0b9 → llms_py-3.0.1/llms_py.egg-info}/PKG-INFO +1 -1
  24. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms_py.egg-info/SOURCES.txt +5 -31
  25. {llms_py-3.0.0b9 → llms_py-3.0.1}/pyproject.toml +1 -1
  26. {llms_py-3.0.0b9 → llms_py-3.0.1}/setup.py +1 -1
  27. llms_py-3.0.0b9/llms/__pycache__/__init__.cpython-312.pyc +0 -0
  28. llms_py-3.0.0b9/llms/__pycache__/__init__.cpython-313.pyc +0 -0
  29. llms_py-3.0.0b9/llms/__pycache__/__init__.cpython-314.pyc +0 -0
  30. llms_py-3.0.0b9/llms/__pycache__/__main__.cpython-312.pyc +0 -0
  31. llms_py-3.0.0b9/llms/__pycache__/__main__.cpython-314.pyc +0 -0
  32. llms_py-3.0.0b9/llms/__pycache__/llms.cpython-312.pyc +0 -0
  33. llms_py-3.0.0b9/llms/__pycache__/main.cpython-312.pyc +0 -0
  34. llms_py-3.0.0b9/llms/__pycache__/main.cpython-313.pyc +0 -0
  35. llms_py-3.0.0b9/llms/__pycache__/main.cpython-314.pyc +0 -0
  36. llms_py-3.0.0b9/llms/__pycache__/plugins.cpython-314.pyc +0 -0
  37. llms_py-3.0.0b9/llms/extensions/app/__pycache__/__init__.cpython-314.pyc +0 -0
  38. llms_py-3.0.0b9/llms/extensions/app/__pycache__/db.cpython-314.pyc +0 -0
  39. llms_py-3.0.0b9/llms/extensions/app/__pycache__/db_manager.cpython-314.pyc +0 -0
  40. llms_py-3.0.0b9/llms/extensions/app/requests.json +0 -9073
  41. llms_py-3.0.0b9/llms/extensions/app/threads.json +0 -15290
  42. llms_py-3.0.0b9/llms/extensions/core_tools/__pycache__/__init__.cpython-314.pyc +0 -0
  43. llms_py-3.0.0b9/llms/extensions/core_tools/ui/codemirror/lib/codemirror.css +0 -344
  44. llms_py-3.0.0b9/llms/extensions/core_tools/ui/codemirror/lib/codemirror.js +0 -9884
  45. llms_py-3.0.0b9/llms/extensions/gallery/__pycache__/__init__.cpython-314.pyc +0 -0
  46. llms_py-3.0.0b9/llms/extensions/gallery/__pycache__/db.cpython-314.pyc +0 -0
  47. llms_py-3.0.0b9/llms/extensions/katex/__pycache__/__init__.cpython-314.pyc +0 -0
  48. llms_py-3.0.0b9/llms/extensions/providers/__pycache__/__init__.cpython-314.pyc +0 -0
  49. llms_py-3.0.0b9/llms/extensions/providers/__pycache__/anthropic.cpython-314.pyc +0 -0
  50. llms_py-3.0.0b9/llms/extensions/providers/__pycache__/chutes.cpython-314.pyc +0 -0
  51. llms_py-3.0.0b9/llms/extensions/providers/__pycache__/google.cpython-314.pyc +0 -0
  52. llms_py-3.0.0b9/llms/extensions/providers/__pycache__/nvidia.cpython-314.pyc +0 -0
  53. llms_py-3.0.0b9/llms/extensions/providers/__pycache__/openai.cpython-314.pyc +0 -0
  54. llms_py-3.0.0b9/llms/extensions/providers/__pycache__/openrouter.cpython-314.pyc +0 -0
  55. llms_py-3.0.0b9/llms/extensions/system_prompts/__pycache__/__init__.cpython-314.pyc +0 -0
  56. llms_py-3.0.0b9/llms/extensions/tools/__pycache__/__init__.cpython-314.pyc +0 -0
  57. llms_py-3.0.0b9/llms/providers.json +0 -1
  58. llms_py-3.0.0b9/llms/ui/modules/chat/HomeTools.mjs +0 -12
  59. {llms_py-3.0.0b9 → llms_py-3.0.1}/LICENSE +0 -0
  60. {llms_py-3.0.0b9 → llms_py-3.0.1}/MANIFEST.in +0 -0
  61. {llms_py-3.0.0b9 → llms_py-3.0.1}/README.md +0 -0
  62. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/__init__.py +0 -0
  63. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/__main__.py +0 -0
  64. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/analytics/ui/index.mjs +0 -0
  65. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/app/db_manager.py +0 -0
  66. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/app/ui/Recents.mjs +0 -0
  67. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/core_tools/ui/codemirror/addon/edit/closebrackets.js +0 -0
  68. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/core_tools/ui/codemirror/addon/edit/closetag.js +0 -0
  69. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/core_tools/ui/codemirror/addon/edit/continuelist.js +0 -0
  70. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/core_tools/ui/codemirror/addon/edit/matchbrackets.js +0 -0
  71. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/core_tools/ui/codemirror/addon/edit/matchtags.js +0 -0
  72. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/core_tools/ui/codemirror/addon/edit/trailingspace.js +0 -0
  73. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/core_tools/ui/codemirror/addon/selection/active-line.js +0 -0
  74. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/core_tools/ui/codemirror/addon/selection/mark-selection.js +0 -0
  75. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/core_tools/ui/codemirror/addon/selection/selection-pointer.js +0 -0
  76. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/core_tools/ui/codemirror/doc/docs.css +0 -0
  77. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/core_tools/ui/codemirror/doc/source_sans.woff +0 -0
  78. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/core_tools/ui/codemirror/mode/clike/clike.js +0 -0
  79. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/core_tools/ui/codemirror/mode/javascript/index.html +0 -0
  80. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/core_tools/ui/codemirror/mode/javascript/javascript.js +0 -0
  81. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/core_tools/ui/codemirror/mode/javascript/typescript.html +0 -0
  82. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/core_tools/ui/codemirror/mode/python/python.js +0 -0
  83. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/core_tools/ui/codemirror/theme/dracula.css +0 -0
  84. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/core_tools/ui/codemirror/theme/mocha.css +0 -0
  85. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/gallery/__init__.py +0 -0
  86. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/gallery/db.py +0 -0
  87. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/katex/__init__.py +0 -0
  88. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/katex/ui/README.md +0 -0
  89. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/katex/ui/contrib/auto-render.js +0 -0
  90. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/katex/ui/contrib/auto-render.min.js +0 -0
  91. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/katex/ui/contrib/auto-render.mjs +0 -0
  92. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/katex/ui/contrib/copy-tex.js +0 -0
  93. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/katex/ui/contrib/copy-tex.min.js +0 -0
  94. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/katex/ui/contrib/copy-tex.mjs +0 -0
  95. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/katex/ui/contrib/mathtex-script-type.js +0 -0
  96. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/katex/ui/contrib/mathtex-script-type.min.js +0 -0
  97. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/katex/ui/contrib/mathtex-script-type.mjs +0 -0
  98. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/katex/ui/contrib/mhchem.js +0 -0
  99. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/katex/ui/contrib/mhchem.min.js +0 -0
  100. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/katex/ui/contrib/mhchem.mjs +0 -0
  101. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/katex/ui/contrib/render-a11y-string.js +0 -0
  102. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/katex/ui/contrib/render-a11y-string.min.js +0 -0
  103. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/katex/ui/contrib/render-a11y-string.mjs +0 -0
  104. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/katex/ui/fonts/KaTeX_AMS-Regular.ttf +0 -0
  105. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/katex/ui/fonts/KaTeX_AMS-Regular.woff +0 -0
  106. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/katex/ui/fonts/KaTeX_AMS-Regular.woff2 +0 -0
  107. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/katex/ui/fonts/KaTeX_Caligraphic-Bold.ttf +0 -0
  108. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/katex/ui/fonts/KaTeX_Caligraphic-Bold.woff +0 -0
  109. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/katex/ui/fonts/KaTeX_Caligraphic-Bold.woff2 +0 -0
  110. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/katex/ui/fonts/KaTeX_Caligraphic-Regular.ttf +0 -0
  111. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/katex/ui/fonts/KaTeX_Caligraphic-Regular.woff +0 -0
  112. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/katex/ui/fonts/KaTeX_Caligraphic-Regular.woff2 +0 -0
  113. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/katex/ui/fonts/KaTeX_Fraktur-Bold.ttf +0 -0
  114. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/katex/ui/fonts/KaTeX_Fraktur-Bold.woff +0 -0
  115. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/katex/ui/fonts/KaTeX_Fraktur-Bold.woff2 +0 -0
  116. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/katex/ui/fonts/KaTeX_Fraktur-Regular.ttf +0 -0
  117. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/katex/ui/fonts/KaTeX_Fraktur-Regular.woff +0 -0
  118. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/katex/ui/fonts/KaTeX_Fraktur-Regular.woff2 +0 -0
  119. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/katex/ui/fonts/KaTeX_Main-Bold.ttf +0 -0
  120. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/katex/ui/fonts/KaTeX_Main-Bold.woff +0 -0
  121. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/katex/ui/fonts/KaTeX_Main-Bold.woff2 +0 -0
  122. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/katex/ui/fonts/KaTeX_Main-BoldItalic.ttf +0 -0
  123. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/katex/ui/fonts/KaTeX_Main-BoldItalic.woff +0 -0
  124. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/katex/ui/fonts/KaTeX_Main-BoldItalic.woff2 +0 -0
  125. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/katex/ui/fonts/KaTeX_Main-Italic.ttf +0 -0
  126. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/katex/ui/fonts/KaTeX_Main-Italic.woff +0 -0
  127. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/katex/ui/fonts/KaTeX_Main-Italic.woff2 +0 -0
  128. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/katex/ui/fonts/KaTeX_Main-Regular.ttf +0 -0
  129. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/katex/ui/fonts/KaTeX_Main-Regular.woff +0 -0
  130. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/katex/ui/fonts/KaTeX_Main-Regular.woff2 +0 -0
  131. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/katex/ui/fonts/KaTeX_Math-BoldItalic.ttf +0 -0
  132. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/katex/ui/fonts/KaTeX_Math-BoldItalic.woff +0 -0
  133. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/katex/ui/fonts/KaTeX_Math-BoldItalic.woff2 +0 -0
  134. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/katex/ui/fonts/KaTeX_Math-Italic.ttf +0 -0
  135. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/katex/ui/fonts/KaTeX_Math-Italic.woff +0 -0
  136. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/katex/ui/fonts/KaTeX_Math-Italic.woff2 +0 -0
  137. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/katex/ui/fonts/KaTeX_SansSerif-Bold.ttf +0 -0
  138. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/katex/ui/fonts/KaTeX_SansSerif-Bold.woff +0 -0
  139. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/katex/ui/fonts/KaTeX_SansSerif-Bold.woff2 +0 -0
  140. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/katex/ui/fonts/KaTeX_SansSerif-Italic.ttf +0 -0
  141. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/katex/ui/fonts/KaTeX_SansSerif-Italic.woff +0 -0
  142. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/katex/ui/fonts/KaTeX_SansSerif-Italic.woff2 +0 -0
  143. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/katex/ui/fonts/KaTeX_SansSerif-Regular.ttf +0 -0
  144. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/katex/ui/fonts/KaTeX_SansSerif-Regular.woff +0 -0
  145. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/katex/ui/fonts/KaTeX_SansSerif-Regular.woff2 +0 -0
  146. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/katex/ui/fonts/KaTeX_Script-Regular.ttf +0 -0
  147. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/katex/ui/fonts/KaTeX_Script-Regular.woff +0 -0
  148. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/katex/ui/fonts/KaTeX_Script-Regular.woff2 +0 -0
  149. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/katex/ui/fonts/KaTeX_Size1-Regular.ttf +0 -0
  150. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/katex/ui/fonts/KaTeX_Size1-Regular.woff +0 -0
  151. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/katex/ui/fonts/KaTeX_Size1-Regular.woff2 +0 -0
  152. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/katex/ui/fonts/KaTeX_Size2-Regular.ttf +0 -0
  153. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/katex/ui/fonts/KaTeX_Size2-Regular.woff +0 -0
  154. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/katex/ui/fonts/KaTeX_Size2-Regular.woff2 +0 -0
  155. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/katex/ui/fonts/KaTeX_Size3-Regular.ttf +0 -0
  156. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/katex/ui/fonts/KaTeX_Size3-Regular.woff +0 -0
  157. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/katex/ui/fonts/KaTeX_Size3-Regular.woff2 +0 -0
  158. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/katex/ui/fonts/KaTeX_Size4-Regular.ttf +0 -0
  159. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/katex/ui/fonts/KaTeX_Size4-Regular.woff +0 -0
  160. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/katex/ui/fonts/KaTeX_Size4-Regular.woff2 +0 -0
  161. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/katex/ui/fonts/KaTeX_Typewriter-Regular.ttf +0 -0
  162. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/katex/ui/fonts/KaTeX_Typewriter-Regular.woff +0 -0
  163. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/katex/ui/fonts/KaTeX_Typewriter-Regular.woff2 +0 -0
  164. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/katex/ui/index.mjs +0 -0
  165. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/katex/ui/katex-swap.css +0 -0
  166. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/katex/ui/katex-swap.min.css +0 -0
  167. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/katex/ui/katex.css +0 -0
  168. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/katex/ui/katex.js +0 -0
  169. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/katex/ui/katex.min.css +0 -0
  170. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/katex/ui/katex.min.js +0 -0
  171. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/katex/ui/katex.min.mjs +0 -0
  172. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/katex/ui/katex.mjs +0 -0
  173. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/providers/__init__.py +0 -0
  174. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/providers/anthropic.py +0 -0
  175. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/providers/chutes.py +0 -0
  176. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/providers/google.py +0 -0
  177. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/providers/nvidia.py +0 -0
  178. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/providers/openai.py +0 -0
  179. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/providers/openrouter.py +0 -0
  180. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/system_prompts/__init__.py +0 -0
  181. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/tools/__init__.py +0 -0
  182. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/extensions/tools/ui/index.mjs +0 -0
  183. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/index.html +0 -0
  184. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/providers-extra.json +0 -0
  185. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/ui/App.mjs +0 -0
  186. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/ui/app.css +0 -0
  187. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/ui/fav.svg +0 -0
  188. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/ui/index.mjs +0 -0
  189. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/ui/lib/chart.js +0 -0
  190. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/ui/lib/charts.mjs +0 -0
  191. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/ui/lib/color.js +0 -0
  192. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/ui/lib/highlight.min.mjs +0 -0
  193. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/ui/lib/idb.min.mjs +0 -0
  194. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/ui/lib/marked.min.mjs +0 -0
  195. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/ui/lib/servicestack-client.mjs +0 -0
  196. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/ui/lib/servicestack-vue.mjs +0 -0
  197. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/ui/lib/vue-router.min.mjs +0 -0
  198. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/ui/lib/vue.min.mjs +0 -0
  199. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/ui/lib/vue.mjs +0 -0
  200. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/ui/markdown.mjs +0 -0
  201. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/ui/modules/chat/SettingsDialog.mjs +0 -0
  202. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/ui/modules/layout.mjs +0 -0
  203. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/ui/modules/model-selector.mjs +0 -0
  204. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/ui/tailwind.input.css +0 -0
  205. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/ui/typography.css +0 -0
  206. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms/ui/utils.mjs +0 -0
  207. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms_py.egg-info/dependency_links.txt +0 -0
  208. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms_py.egg-info/entry_points.txt +0 -0
  209. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms_py.egg-info/not-zip-safe +0 -0
  210. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms_py.egg-info/requires.txt +0 -0
  211. {llms_py-3.0.0b9 → llms_py-3.0.1}/llms_py.egg-info/top_level.txt +0 -0
  212. {llms_py-3.0.0b9 → llms_py-3.0.1}/requirements.txt +0 -0
  213. {llms_py-3.0.0b9 → llms_py-3.0.1}/setup.cfg +0 -0
  214. {llms_py-3.0.0b9 → llms_py-3.0.1}/tests/test_async.py +0 -0
  215. {llms_py-3.0.0b9 → llms_py-3.0.1}/tests/test_config.py +0 -0
  216. {llms_py-3.0.0b9 → llms_py-3.0.1}/tests/test_extensions.py +0 -0
  217. {llms_py-3.0.0b9 → llms_py-3.0.1}/tests/test_integration.py +0 -0
  218. {llms_py-3.0.0b9 → llms_py-3.0.1}/tests/test_provider_checks.py +0 -0
  219. {llms_py-3.0.0b9 → llms_py-3.0.1}/tests/test_provider_config.py +0 -0
  220. {llms_py-3.0.0b9 → llms_py-3.0.1}/tests/test_utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: llms-py
3
- Version: 3.0.0b9
3
+ Version: 3.0.1
4
4
  Summary: A lightweight CLI tool and OpenAI-compatible server for querying multiple Large Language Model (LLM) providers
5
5
  Home-page: https://github.com/ServiceStack/llms
6
6
  Author: ServiceStack
@@ -0,0 +1,20 @@
1
+ # App Extension
2
+
3
+ This extension provides the core application logic and data persistence for the LLMs platform.
4
+
5
+ ## Data Storage & Architecture
6
+
7
+ ### Server-Side SQLite Migration
8
+ The application has migrated from client-side IndexedDB storage to a robust server-side SQLite solution. This architectural shift ensures better data consistency, improved performance, and enables multi-device access to your chat history.
9
+
10
+ ### Asset Management
11
+ To keep the database efficient and portable, binary assets (images, audio, etc.) are not stored directly in the SQLite database. Instead:
12
+ - All generated assets are stored in the local file system cache at `~/.llms/cache`.
13
+ - The database stores only **relative URLs** pointing to these assets.
14
+ - This approach allows for efficient caching and serving of static media.
15
+
16
+ ### Concurrency Model
17
+ To ensure data integrity and high performance without complex locking mechanisms, the system utilizes a **single background thread** for managing all write operations to the database. This design improves concurrency handling and eliminates database locking issues during high-load scenarios.
18
+
19
+ ### Multi-Tenancy & Security
20
+ When authentication is enabled, data isolation is automatically enforced. All core tables, including `threads` and `requests`, are scoped to the authenticated user, ensuring that users can only access their own data.
@@ -25,16 +25,6 @@ def install(ctx):
25
25
  g_db = AppDB(ctx, db_path)
26
26
  ctx.register_shutdown_handler(g_db.close)
27
27
 
28
- threads_json = "/home/mythz/src/ServiceStack/llms/llms/extensions/app/threads.json"
29
- requests_json = "/home/mythz/src/ServiceStack/llms/llms/extensions/app/requests.json"
30
- with open(threads_json) as f:
31
- threads = json.load(f)["threads"]
32
- threads.reverse()
33
- with open(requests_json) as f:
34
- requests = json.load(f)["requests"]
35
- requests.reverse()
36
- # g_db.import_db(threads, requests)
37
-
38
28
  except Exception as e:
39
29
  ctx.err("Failed to init AppDB", e)
40
30
  return g_db
@@ -60,7 +50,7 @@ def install(ctx):
60
50
  return to
61
51
 
62
52
  def thread_dto(row):
63
- return row and to_dto(row, ["messages", "modalities", "args", "modelInfo", "stats"])
53
+ return row and to_dto(row, ["messages", "modalities", "args", "modelInfo", "stats", "metadata"])
64
54
 
65
55
  def request_dto(row):
66
56
  return row and to_dto(row, ["usage"])
@@ -174,12 +164,13 @@ def install(ctx):
174
164
  if not thread:
175
165
  raise Exception("Thread not found")
176
166
 
167
+ metadata = thread.get("metadata", {})
177
168
  chat = {
178
169
  "model": thread.get("model"),
179
170
  "messages": thread.get("messages"),
180
171
  "modalities": thread.get("modalities"),
181
172
  "systemPrompt": thread.get("systemPrompt"),
182
- "metadata": thread.get("metadata", {}),
173
+ "metadata": metadata,
183
174
  }
184
175
  for k, v in thread.get("args", {}).items():
185
176
  if k in ctx.request_args:
@@ -189,7 +180,8 @@ def install(ctx):
189
180
  "chat": chat,
190
181
  "user": user,
191
182
  "threadId": id,
192
- "tools": chat.get("metadata").get("tools", "all"),
183
+ "metadata": metadata,
184
+ "tools": metadata.get("tools", "all"),
193
185
  }
194
186
 
195
187
  # execute chat in background thread
@@ -341,13 +333,22 @@ def install(ctx):
341
333
 
342
334
  ctx.register_chat_request_filter(chat_request)
343
335
 
344
- async def tool_request(tool_chat, context):
345
- ctx.dbg("tool_request")
336
+ async def tool_request(chat_request, context):
337
+ messages = chat_request.get("messages", [])
338
+ ctx.dbg(f"tool_request: messages {len(messages)}")
346
339
  thread_id = context.get("threadId", None)
347
340
  if not thread_id:
348
341
  ctx.dbg("Missing threadId")
349
342
  return
350
343
  user = context.get("user", None)
344
+ await g_db.update_thread_async(
345
+ thread_id,
346
+ {
347
+ "messages": messages,
348
+ },
349
+ user=user,
350
+ )
351
+
351
352
  completed_at = g_db.get_thread_column(thread_id, "completedAt", user=user)
352
353
  if completed_at:
353
354
  context["completed"] = True
@@ -91,6 +91,7 @@ class AppDB:
91
91
  "publishedAt": "TIMESTAMP",
92
92
  "startedAt": "TIMESTAMP",
93
93
  "completedAt": "TIMESTAMP",
94
+ "metadata": "JSON",
94
95
  "error": "TEXT",
95
96
  "ref": "TEXT",
96
97
  },
@@ -444,7 +445,7 @@ class AppDB:
444
445
  event.wait()
445
446
  return ret[0]
446
447
 
447
- def prepare_thread(self, thread, id=None):
448
+ def prepare_thread(self, thread, id=None, user=None):
448
449
  now = datetime.now()
449
450
  if id:
450
451
  thread["id"] = id
@@ -454,19 +455,19 @@ class AppDB:
454
455
  if "messages" in thread:
455
456
  for m in thread["messages"]:
456
457
  self.ctx.cache_message_inline_data(m)
457
- return thread
458
+ return with_user(thread, user=user)
458
459
 
459
460
  def create_thread(self, thread: Dict[str, Any], user=None):
460
- return self.insert("thread", with_user(self.prepare_thread(thread), user=user))
461
+ return self.insert("thread", self.prepare_thread(thread, user=user))
461
462
 
462
463
  async def create_thread_async(self, thread: Dict[str, Any], user=None):
463
- return await self.insert_async("thread", with_user(self.prepare_thread(thread), user=user))
464
+ return await self.insert_async("thread", self.prepare_thread(thread, user=user))
464
465
 
465
466
  def update_thread(self, id, thread: Dict[str, Any], user=None):
466
- return self.update("thread", with_user(self.prepare_thread(thread, id), user=user))
467
+ return self.update("thread", self.prepare_thread(thread, id, user=user))
467
468
 
468
469
  async def update_thread_async(self, id, thread: Dict[str, Any], user=None):
469
- return await self.update_async("thread", with_user(self.prepare_thread(thread, id), user=user))
470
+ return await self.update_async("thread", self.prepare_thread(thread, id, user=user))
470
471
 
471
472
  def delete_thread(self, id, user=None, callback=None):
472
473
  sql_where, params = self.get_user_filter(user, {"id": id})
@@ -219,7 +219,7 @@ const ThreadsSidebar = {
219
219
  }
220
220
 
221
221
  const createNewThread = async () => {
222
- ctx.threads.startNewThread({ title: 'New Chat', model: ctx.chat.getSelectedModel() })
222
+ ctx.threads.startNewThread({ title: 'New Chat', model: ctx.chat.getSelectedModel(), redirect: true })
223
223
  }
224
224
 
225
225
  const goToInitialState = () => {
@@ -1,5 +1,5 @@
1
1
  import { ref, computed } from 'vue'
2
- import { appendQueryString, createErrorStatus } from '@servicestack/client'
2
+ import { appendQueryString } from '@servicestack/client'
3
3
 
4
4
  /**
5
5
  * Returns an ever-increasing unique integer id.
@@ -21,11 +21,6 @@ const isLoading = ref(false)
21
21
  let ctx = null
22
22
  let ext = null
23
23
 
24
- // Generate unique thread ID
25
- function generateThreadId() {
26
- return Date.now().toString()
27
- }
28
-
29
24
  function setError(error, msg = null) {
30
25
  ctx?.setError(error, msg)
31
26
  }
@@ -170,7 +165,7 @@ async function redoMessageFromThread(threadId, timestamp) {
170
165
  // Find the index of the message to redo
171
166
  const messageIndex = thread.messages.findIndex(m => m.timestamp === timestamp)
172
167
  if (messageIndex === -1) {
173
- setError(createErrorStatus(`Message not found for timestamp ${timestamp}`))
168
+ setError({ message: `Message not found for timestamp ${timestamp}` })
174
169
  return
175
170
  }
176
171
 
@@ -188,7 +183,8 @@ async function redoMessageFromThread(threadId, timestamp) {
188
183
  const updatedMessages = thread.messages.slice(0, messageIndex + 1)
189
184
 
190
185
  // Update the thread with the new messages
191
- const api = await queueChat(threadId, { messages: updatedMessages })
186
+ const request = { messages: updatedMessages }
187
+ const api = await queueChat({ request, thread })
192
188
  if (api.response) {
193
189
  replaceThread(api.response)
194
190
  } else {
@@ -311,7 +307,7 @@ function getLatestCachedThread() {
311
307
  return threads.value[0]
312
308
  }
313
309
 
314
- async function startNewThread({ title, model }) {
310
+ async function startNewThread({ title, model, redirect }) {
315
311
  if (!model) {
316
312
  console.error('No model selected')
317
313
  return
@@ -337,8 +333,10 @@ async function startNewThread({ title, model }) {
337
333
  })
338
334
 
339
335
  console.log('newThread', newThread, model)
340
- // Navigate to the new thread URL
341
- ctx.to(`/c/${newThread.id}`)
336
+ if (redirect) {
337
+ // Navigate to the new thread URL
338
+ ctx.to(`/c/${newThread.id}`)
339
+ }
342
340
 
343
341
  // Get the thread to check for duplicates
344
342
  let thread = await getThread(newThread.id)
@@ -346,12 +344,19 @@ async function startNewThread({ title, model }) {
346
344
  return thread
347
345
  }
348
346
 
349
- async function queueChat(threadId, body, options = {}) {
350
- const api = await ctx.postJson(`/ext/app/threads/${threadId}/chat`, {
347
+ async function queueChat(ctxRequest, options = {}) {
348
+ if (!ctxRequest.request) return ctx.createErrorResult({ message: 'No request provided' })
349
+ if (!ctxRequest.thread) return ctx.createErrorResult({ message: 'No thread provided' })
350
+ if (!ctxRequest.request.metadata) {
351
+ ctxRequest.request.metadata = {}
352
+ }
353
+ ctx.chatRequestFilters.forEach(f => f(ctxRequest))
354
+ const { thread, request } = ctxRequest
355
+ const api = await ctx.postJson(`/ext/app/threads/${thread.id}/chat`, {
351
356
  ...options,
352
- body: typeof body == 'string'
353
- ? body
354
- : JSON.stringify(body),
357
+ body: typeof request == 'string'
358
+ ? request
359
+ : JSON.stringify(request),
355
360
  })
356
361
  return api
357
362
  }
@@ -380,7 +385,6 @@ export function useThreadStore() {
380
385
  clearCurrentThread,
381
386
  getGroupedThreads,
382
387
  getLatestCachedThread,
383
- generateThreadId,
384
388
  startNewThread,
385
389
  replaceThread,
386
390
  queueChat,
@@ -0,0 +1,32 @@
1
+ # Calculator
2
+
3
+ A powerful and safe mathematical expression evaluator with a rich web interface.
4
+
5
+ ## Features
6
+
7
+ ### 🖥️ UX Friendly Interface
8
+ Experience a clean, modern interface designed for efficiency. The UI is fully responsive and supports dark mode, seamlessly integrating with the rest of the application.
9
+
10
+ ### 💾 Persistent History
11
+ Never lose track of your calculations. The Calculator automatically saves your history to `localStorage`, ensuring your previous expressions and results are preserved between sessions.
12
+
13
+ ### ⚡ 1-Click Interaction
14
+ Streamline your workflow with interactive history items:
15
+ - **Load & Copy**: Click on any past expression or answer to instantly load it into the input field and copy it to your clipboard.
16
+ - **Visual Feedback**: Temporary checkmarks confirm successful copy actions.
17
+
18
+ ### ⌨️ Keyboard-Free Access
19
+ While full keyboard support is available, you can perform complex calculations entirely via the UI:
20
+ - **Numbers & Constants**: Quick access to digits and mathematical constants like `pi`, `e`, `inf`.
21
+ - **Operators**: Comprehensive set of buttons for arithmetic (`+`, `-`, `*`, `/`, `%`, `^`) and boolean logic (`and`, `or`, `not`).
22
+ - **Functions**: One-click insertion or wrapping of selection for all supported math functions.
23
+
24
+ ### 🐍 Python Math Support
25
+ Unlock the power of Python's math library directly in the browser.
26
+ - **Math Functions**: Support for `sin`, `cos`, `tan`, `sqrt`, `log`, `factorial`, and many more.
27
+ - **Statistics**: Built-in functions for `mean`, `median`, `stdev`, and `variance`.
28
+
29
+ ### 🛡️ Safe Evaluation
30
+ Security is a priority. Instead of using Python's unsafe `eval()`, the Calculator uses a robust **AST (Abstract Syntax Tree) evaluator**.
31
+ - **Restricted Environment**: Only allowed mathematical operations and functions are executed.
32
+ - **No Side Effects**: Prevents arbitrary code execution, making it safe to evaluate expressions from untrusted sources.
@@ -523,7 +523,7 @@ def install(ctx):
523
523
  # Examples of registering tools using automatic definition generation
524
524
  ctx.register_tool(memory_read)
525
525
  ctx.register_tool(memory_write)
526
- ctx.register_tool(semantic_search)
526
+ # ctx.register_tool(semantic_search) # TODO: implement
527
527
  ctx.register_tool(read_file)
528
528
  ctx.register_tool(write_file)
529
529
  ctx.register_tool(list_directory)
@@ -381,7 +381,7 @@ const CalcPage = {
381
381
  type="button"
382
382
  @click="insert(num)"
383
383
  class="px-3 py-1 bg-gray-100 dark:bg-gray-800 hover:bg-blue-100 dark:hover:bg-blue-900/30 text-gray-700 dark:text-gray-300 hover:text-blue-700 dark:hover:text-blue-300 border border-gray-200 dark:border-gray-700 rounded text-sm font-mono transition-colors"
384
- title="Click to insert"
384
+ :title="'insert number ' + num"
385
385
  >
386
386
  {{ num }}
387
387
  </button>
@@ -392,7 +392,7 @@ const CalcPage = {
392
392
  type="button"
393
393
  @click="insert(c)"
394
394
  class="px-3 py-1 bg-gray-100 dark:bg-gray-800 hover:bg-blue-100 dark:hover:bg-blue-900/30 text-gray-700 dark:text-gray-300 hover:text-blue-700 dark:hover:text-blue-300 border border-gray-200 dark:border-gray-700 rounded text-sm font-mono transition-colors"
395
- title="Click to insert"
395
+ :title="'insert constant ' + c"
396
396
  >
397
397
  {{ c }}
398
398
  </button>
@@ -408,7 +408,7 @@ const CalcPage = {
408
408
  type="button"
409
409
  @click="insert(op)"
410
410
  class="px-3 py-1 bg-gray-100 dark:bg-gray-800 hover:bg-blue-100 dark:hover:bg-blue-900/30 text-gray-700 dark:text-gray-300 hover:text-blue-700 dark:hover:text-blue-300 border border-gray-200 dark:border-gray-700 rounded text-sm font-mono transition-colors"
411
- title="Click to insert"
411
+ :title="'insert operator ' + op"
412
412
  >
413
413
  {{ op }}
414
414
  </button>
@@ -425,7 +425,7 @@ const CalcPage = {
425
425
  type="button"
426
426
  @click="wrapWithFunction(func)"
427
427
  class="px-3 py-1 bg-gray-100 dark:bg-gray-800 hover:bg-purple-100 dark:hover:bg-purple-900/30 text-gray-700 dark:text-gray-300 hover:text-purple-700 dark:hover:text-purple-300 border border-gray-200 dark:border-gray-700 rounded text-sm font-mono transition-colors"
428
- title="Click to insert"
428
+ :title="'use function ' + func"
429
429
  >
430
430
  {{ func }}
431
431
  </button>
@@ -0,0 +1,61 @@
1
+ # Gallery Extension
2
+
3
+ The Gallery extension intercepts all generated image, audio & file assets and uploaded files in `~/.llms/cache` file storage whose metadata is maintained in a SQLite database.
4
+
5
+ Dedicated UIs are available for quickly browsing and navigating or generated images / audio files with optimized UIs for viewing portrait, square and landscape images.
6
+
7
+ ## Generated Asset Interception
8
+
9
+ The Gallery extension automatically monitors the creation of new cache entries. Whenever a file is saved to the LLMs cache (located at `~/.llms/cache`), the extension captures its metadata and stores it in the gallery database.
10
+
11
+ This includes:
12
+ - **Generated Images**: Images created by AI models (e.g., DALL-E, Stable Diffusion).
13
+ - **Generated Audio**: Audio files generated by text-to-speech or audio models.
14
+ - **Uploaded Files**: Any files uploaded through the UI.
15
+
16
+ All metadata is stored in a dedicated SQLite database located at `~/.llms/user/default/gallery/gallery.sqlite`, in the `media` table.
17
+
18
+ ## User Interface
19
+
20
+ The Gallery UI provides a rich, interactive way to explore your generated assets. You can access it via the **Gallery** tab in the sidebar or by navigating to `/gallery`.
21
+
22
+ ### Image Gallery
23
+
24
+ The image view offers a responsive grid layout optimized for different aspect ratios.
25
+
26
+ - **Filtering**:
27
+ - **By Format**: Easily switch between **Portrait**, **Square**, and **Landscape** views to see images in their best light.
28
+ - **Search**: Real-time search by prompt, model name, or other metadata.
29
+ - **Interactions**:
30
+ - **Lightbox**: Click any image to view it in full screen.
31
+ - **Details**: View comprehensive metadata including the prompt used, generation model, dimensions, file size, creation date, and generation cost.
32
+ - **Download**: extensive download options.
33
+ - **Remix**: Quickly re-use the prompt and settings of an existing image to generate a new one.
34
+ - **Delete**: Remove unwanted images from the gallery.
35
+
36
+ ### Audio Gallery
37
+
38
+ The audio view presents a list layout designed for easy listening and management.
39
+
40
+ - **Playback**: Integrated audio player to preview generated sounds directly in the list.
41
+ - **Metadata**: Displays the caption/prompt, model, and creation time.
42
+ - **Actions**:
43
+ - **Remix**: Regenerate audio using the same prompt.
44
+ - **Delete**: Remove audio files.
45
+
46
+ ## Storage Data model
47
+
48
+ The `media` table tracks extensive information about each asset to support the search and filtering capabilities:
49
+
50
+ | Column | Description |
51
+ |---|---|
52
+ | `url` | Relative path to the file in `~/.llms/cache` |
53
+ | `type` | Asset type (image, audio, video) |
54
+ | `prompt` | The prompt used to generate the asset |
55
+ | `model` | The AI model used |
56
+ | `aspect_ratio` | Aspect ratio (e.g., "1:1", "16:9") |
57
+ | `cost` | Generation cost |
58
+ | `metadata` | Additional JSON metadata |
59
+ | `created` | Timestamp of creation |
60
+
61
+ This local database ensures your gallery remains fast and responsive, even with a large collection of generated assets.
@@ -390,6 +390,7 @@ const GalleryPage = {
390
390
  ctx.threads.startNewThread({
391
391
  title: selected.prompt,
392
392
  model: ctx.chat.getSelectedModel(),
393
+ redirect: true,
393
394
  })
394
395
  }
395
396
 
@@ -0,0 +1,39 @@
1
+ # KaTeX Extension
2
+
3
+ This extension enables beautiful rendering of LaTeX math expressions in AI responses using [KaTeX](https://katex.org/). It integrates automatically with the markdown parser to render math equations in both inline and block formats.
4
+
5
+ ## Features
6
+
7
+ - **Fast Rendering**: Uses KaTeX for high-performance rendering of math expressions.
8
+ - **Inline Math**: Renders math within text using `$` or `$$` delimiters.
9
+ - **Block Math**: Renders complex equations in their own block using `$` or `$$` delimiters across multiple lines.
10
+ - **Auto-Integration**: Automatically extends the `marked` parser used in the application.
11
+
12
+ ## Usage
13
+
14
+ The extension supports standard LaTeX math syntax.
15
+
16
+ ### Inline Math
17
+
18
+ Surround your LaTeX expression with single `$` (for inline style) or double `$$` (for display style) delimiters.
19
+
20
+ **Example:**
21
+ `The quadratic formula is $x = \frac{-b \pm \sqrt{b^2 - 4ac}}{2a}$.`
22
+
23
+ ### Block Math
24
+
25
+ For larger equations or when you want the math to be displayed on its own line, use block syntax by placing the delimiters on separate lines. Standard usage is to use double `$$` delimiters.
26
+
27
+ **Example:**
28
+ ```latex
29
+ $$
30
+ \int_{-\infty}^{\infty} e^{-x^2} dx = \sqrt{\pi}
31
+ $$
32
+ ```
33
+
34
+ ## Configuration
35
+
36
+ The extension automatically registers:
37
+ - **Import Maps**: Loads `katex.min.mjs` for the frontend.
38
+ - **CSS**: Injects `katex.min.css` for styling.
39
+ - **Markdown Extension**: Adds a custom tokenizer and renderer to `marked` to detect and render LaTeX patterns.
@@ -0,0 +1,22 @@
1
+ # System Prompts Extension
2
+
3
+ This extension configures AI requests with a library of **over 200+** awesome curated system prompts that can be selected from the UI.
4
+
5
+ ## Custom System Prompts
6
+
7
+ You can also maintain your own library of system prompts which can be maintained for all anonymous users at:
8
+ `~/.llms/user/default/system-prompts.json`
9
+
10
+ Or for signed in users at:
11
+ `~/.llms/user/<github-user>/system-prompts.json`
12
+
13
+ The JSON file should contain an array of Prompt objects, e.g:
14
+
15
+ ```json
16
+ [
17
+ {
18
+ "name": "Helpful Assistant",
19
+ "prompt": "You are a helpful assistant."
20
+ }
21
+ ]
22
+ ```
@@ -142,7 +142,7 @@ const SystemPromptEditor = {
142
142
  System Prompt
143
143
  </label>
144
144
  <div v-if="hasMessages" class="text-sm text-gray-500 dark:text-gray-400">
145
- {{ !threadSystemPrompt ? '' : prompts.find(x => x.value === threadSystemPrompt)?.name || 'Custom' }}
145
+ {{ !ext.prefs.systemPrompt ? '' : prompts.find(x => x.value === ext.prefs.systemPrompt)?.name || 'Custom' }}
146
146
  </div>
147
147
  <div v-else class="mb-2 relative" ref="containerRef">
148
148
  <div class="flex items-center gap-2">
@@ -154,16 +154,16 @@ const SystemPromptEditor = {
154
154
  <svg class="size-4 text-gray-500 dark:text-gray-400" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="currentColor" d="M19 6.41L17.59 5L12 10.59L6.41 5L5 6.41L10.59 12L5 17.59L6.41 19L12 13.41L17.59 19L19 17.59L13.41 12z"/></svg>
155
155
  </button>
156
156
  <button type="button"
157
- @click="showFinder = !showFinder"
157
+ @click="ext.setPrefs({ showFinder: !ext.prefs.showFinder })"
158
158
  class="inline-flex items-center gap-x-1.5 rounded-md bg-white dark:bg-gray-900 px-2.5 py-1.5 text-sm font-medium text-gray-700 dark:text-gray-300 shadow-sm border border-gray-300 dark:border-gray-600 hover:bg-gray-50 dark:hover:bg-gray-800">
159
159
  Explore Prompts
160
160
  </button>
161
161
  </div>
162
- <PromptFinder v-model="showFinder" :prompts="prompts" @select="onSelect" />
162
+ <PromptFinder v-model="ext.prefs.showFinder" :prompts="prompts" @select="onSelect" />
163
163
  </div>
164
164
  </div>
165
165
  <div v-if="hasMessages" class="w-full rounded-md border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-900 text-gray-900 dark:text-gray-100 px-3 py-2 text-sm">
166
- {{threadSystemPrompt || 'No System Prompt was used' }}
166
+ {{$threads.currentThread.value?.systemPrompt || 'No System Prompt was used' }}
167
167
  </div>
168
168
  <div v-else>
169
169
  <textarea
@@ -186,32 +186,29 @@ const SystemPromptEditor = {
186
186
  /**@type {AppContext} */
187
187
  const ctx = inject('ctx')
188
188
  const containerRef = ref()
189
- const showFinder = ref(false)
190
- const prefs = ext.getPrefs()
191
189
  const hasMessages = computed(() => ctx.threads.currentThread.value?.messages?.length > 0)
192
- const threadSystemPrompt = computed(() => ctx.threads.currentThread.value?.systemPrompt || '')
193
190
  const selected = computed(() =>
194
191
  props.prompts.find(x => x.value === props.modelValue) ?? { name: "Custom", value: props.modelValue })
195
192
 
196
193
  function onSelect(prompt) {
194
+ ext.setPrefs({ prompt: prompt }) // {"id","name","value"}
197
195
  emit('update:modelValue', prompt.value)
198
196
  }
199
197
 
200
198
  function closeFinder(e) {
201
- if (showFinder.value && containerRef.value && !containerRef.value.contains(e.target)) {
202
- showFinder.value = false
199
+ if (ext.prefs.showFinder && containerRef.value && !containerRef.value.contains(e.target)) {
200
+ ext.setPrefs({ showFinder: false })
203
201
  }
204
202
  }
205
203
 
206
- watch(() => props.modelValue, promptValue => {
207
- prefs.prompt = selected.value
208
- ext.setPrefs(prefs)
204
+ watch(() => props.modelValue, systemPrompt => {
205
+ ext.setPrefs({ systemPrompt })
209
206
  })
210
207
 
211
208
  onMounted(() => {
212
209
  document.addEventListener('click', closeFinder)
213
- if (prefs.prompt) {
214
- emit('update:modelValue', prefs.prompt.value)
210
+ if (ext.prefs.prompt) {
211
+ emit('update:modelValue', ext.prefs.prompt)
215
212
  }
216
213
  })
217
214
  onUnmounted(() => {
@@ -219,11 +216,10 @@ const SystemPromptEditor = {
219
216
  })
220
217
 
221
218
  return {
222
- threadSystemPrompt,
219
+ ext,
223
220
  hasMessages,
224
221
  selected,
225
222
  containerRef,
226
- showFinder,
227
223
  onSelect,
228
224
  }
229
225
  }
@@ -238,9 +234,13 @@ export default {
238
234
  PromptFinder,
239
235
  SystemPromptEditor,
240
236
  SystemPromptsPanel: {
241
- template: `<SystemPromptEditor :prompts="$state.prompts" v-model="$state.selectedPrompt" />`,
237
+ template: `<SystemPromptEditor :prompts="ext.state.prompts" v-model="ext.prefs.prompt" />`,
238
+ setup() {
239
+ return { ext }
240
+ }
242
241
  }
243
242
  })
243
+ ext.setPrefs({ systemPrompt: '' })
244
244
 
245
245
  ctx.setTopIcons({
246
246
  system_prompts: {
@@ -251,12 +251,6 @@ export default {
251
251
  }
252
252
  })
253
253
 
254
- ctx.createThreadFilters.push(thread => {
255
- const prefs = ext.getPrefs()
256
- thread.systemPrompt = prefs?.prompt?.value || ""
257
- console.log('createThreadFilters', prefs, thread)
258
- })
259
-
260
254
  ctx.chatRequestFilters.push(({ request, thread }) => {
261
255
 
262
256
  const hasSystemPrompt = request.messages.find(x => x.role === 'system')
@@ -265,11 +259,12 @@ export default {
265
259
  return
266
260
  }
267
261
 
268
- if (thread.systemPrompt) {
262
+ // Only add the selected system prompt for new requests
263
+ if (ext.prefs.systemPrompt && request.messages.length <= 1) {
269
264
  // add message to start
270
265
  request.messages.unshift({
271
266
  role: 'system',
272
- content: thread.systemPrompt
267
+ content: ext.prefs.systemPrompt
273
268
  })
274
269
  }
275
270
  })
@@ -280,6 +275,6 @@ export default {
280
275
  async load(ctx) {
281
276
  const api = await ext.getJson(`/prompts.json`)
282
277
  const prompts = api.response || []
283
- ctx.setState({ prompts })
278
+ ext.setState({ prompts })
284
279
  }
285
280
  }
@@ -645,7 +645,7 @@
645
645
  "value": "I want you to act as an biblical translator. I will speak to you in english and you will translate it and answer in the corrected and improved version of my text, in a biblical dialect. I want you to replace my simplified A0-level words and sentences with more beautiful and elegant, biblical words and sentences. Keep the meaning same. I want you to only reply the correction, the improvements and nothing else, do not write explanations. My first sentence is \"Hello, World!\""
646
646
  },
647
647
  {
648
- "id": "chess-player",
648
+ "id": "chess-player2",
649
649
  "name": "Act as an Chess Player",
650
650
  "value": "I want you to act as a rival chess player. I We will say our moves in reciprocal order. In the beginning I will be white. Also please don't explain your moves to me because we are rivals. After my first message i will just write my move. Don't forget to update the state of the board in your mind as we make moves. My first move is e4."
651
651
  },
@@ -740,7 +740,7 @@
740
740
  "value": "I want you to act as a Graphviz DOT generator, an expert to create meaningful diagrams. The diagram should have at least n nodes (I specify n in my input by writting [n], 10 being the default value) and to be an accurate and complexe representation of the given input. Each node is indexed by a number to reduce the size of the output, should not include any styling, and with layout=neato, overlap=false, node [shape=rectangle] as parameters. The code should be valid, bugless and returned on a single line, without any explanation. Provide a clear and organized diagram, the relationships between the nodes have to make sense for an expert of that input. My first diagram is: \"The water cycle [8]\"."
741
741
  },
742
742
  {
743
- "id": "life-coach",
743
+ "id": "life-coach2",
744
744
  "name": "Act as a Life Coach",
745
745
  "value": "I want you to act as a Life Coach. Please summarize this non-fiction book, [title] by [author]. Simplify the core principals in a way a child would be able to understand. Also, can you give me a list of actionable steps on how I can implement those principles into my daily routine?"
746
746
  },
@@ -840,7 +840,7 @@
840
840
  "value": "I want you to act as a Japanese Kanji quiz machine. Each time I ask you for the next question, you are to provide one random Japanese kanji from JLPT N5 kanji list and ask for its meaning. You will generate four options, one correct, three wrong. The options will be labeled from A to D. I will reply to you with one letter, corresponding to one of these labels. You will evaluate my each answer based on your last question and tell me if I chose the right option. If I chose the right label, you will congratulate me. Otherwise you will tell me the right answer. Then you will ask me the next question."
841
841
  },
842
842
  {
843
- "id": "note-taking-assistant",
843
+ "id": "note-taking-assistant2",
844
844
  "name": "Act as a note-taking assistant",
845
845
  "value": "I want you to act as a note-taking assistant for a lecture. Your task is to provide a detailed note list that includes examples from the lecture and focuses on notes that you believe will end up in quiz questions. Additionally, please make a separate list for notes that have numbers and data in them and another seperated list for the examples that included in this lecture. The notes should be concise and easy to read."
846
846
  },
@@ -975,7 +975,7 @@
975
975
  "value": "You are the \"Architect Guide,\" specialized in assisting programmers who are experienced in individual module development but are looking to enhance their skills in understanding and managing entire project architectures. Your primary roles and methods of guidance include:\n\n- **Basics of Project Architecture**: Start with foundational knowledge, focusing on principles and practices of inter-module communication and standardization in modular coding. - **Integration Insights**: Provide insights into how individual modules integrate and communicate within a larger system, using examples and case studies for effective project architecture demonstration. - **Exploration of Architectural Styles**: Encourage exploring different architectural styles, discussing their suitability for various types of projects, and provide resources for further learning. - **Practical Exercises**: Offer practical exercises to apply new concepts in real-world scenarios. - **Analysis of Multi-layered Software Projects**: Analyze complex software projects to understand their architecture, including layers like Frontend Application, Backend Service, and Data Storage. - **Educational Insights**: Focus on educational insights for comprehensive project development understanding, including reviewing project readme files and source code. - **Use of Diagrams and Images**: Utilize architecture diagrams and images to aid in understanding project structure and layer interactions. - **Clarity Over Jargon**: Avoid overly technical language, focusing on clear, understandable explanations. - **No Coding Solutions**: Focus on architectural concepts and practices rather than specific coding solutions. - **Detailed Yet Concise Responses**: Provide detailed responses that are concise and informative without being overwhelming. - **Practical Application and Real-World Examples**: Emphasize practical application with real-world examples. - **Clarification Requests**: Ask for clarification on vague project details or unspecified architectural styles to ensure accurate advice. - **Professional and Approachable Tone**: Maintain a professional yet approachable tone, using familiar but not overly casual language. - **Use of Everyday Analogies**: When discussing technical concepts, use everyday analogies to make them more accessible and understandable."
976
976
  },
977
977
  {
978
- "id": "chatgpt-prompt-generator",
978
+ "id": "chatgpt-prompt-generator2",
979
979
  "name": "Act as ChatGPT Prompt Generator",
980
980
  "value": "Let's refine the process of creating high-quality prompts together. Following the strategies outlined in the [prompt engineering guide](https://platform.openai.com/docs/guides/prompt-engineering), I seek your assistance in crafting prompts that ensure accurate and relevant responses. Here's how we can proceed:\n\n1. **Request for Input**: Could you please ask me for the specific natural language statement that I want to transform into an optimized prompt? 2. **Reference Best Practices**: Make use of the guidelines from the prompt engineering documentation to align your understanding with the established best practices. 3. **Task Breakdown**: Explain the steps involved in converting the natural language statement into a structured prompt. 4. **Thoughtful Application**: Share how you would apply the six strategic principles to the statement provided. 5. **Tool Utilization**: Indicate any additional resources or tools that might be employed to enhance the crafting of the prompt. 6. **Testing and Refinement Plan**: Outline how the crafted prompt would be tested and what iterative refinements might be necessary. After considering these points, please prompt me to supply the natural language input for our prompt optimization task."
981
981
  },
@@ -1060,7 +1060,7 @@
1060
1060
  "value": "Using WebPilot, create an outline for an article that will be 2,000 words on the keyword “Best SEO Prompts” based on the top 10 results from Google. Include every relevant heading possible. Keep the keyword density of the headings high.<br/> For each section of the outline, include the word count.<br/> Include FAQs section in the outline too, based on people also ask section from Google for the keyword.<br/> This outline must be very detailed and comprehensive, so that I can create a 2,000 word article from it. Generate a long list of LSI and NLP keywords related to my keyword. Also include any other words related to the keyword.<br/> Give me a list of 3 relevant external links to include and the recommended anchor text. Make sure they’re not competing articles.<br/> Split the outline into part 1 and part 2."
1061
1061
  },
1062
1062
  {
1063
- "id": "linkedin-ghostwriter",
1063
+ "id": "linkedin-ghostwriter2",
1064
1064
  "name": "Act as Linkedin Ghostwriter",
1065
1065
  "value": "Act as an Expert Technical Architecture in Mobile, having more then 20 years of expertise in mobile technologies and development of various domain with cloud and native architecting design. Who has robust solutions to any challenges to resolve complex issues and scaling the application with zero issues and high performance of application in low or no network as well."
1066
1066
  }