llms-py 2.0.13__tar.gz → 2.0.15__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 (58) hide show
  1. llms_py-2.0.15/MANIFEST.in +4 -0
  2. {llms_py-2.0.13/llms_py.egg-info → llms_py-2.0.15}/PKG-INFO +1 -1
  3. llms_py-2.0.15/llms/__init__.py +2 -0
  4. llms_py-2.0.15/llms/__main__.py +9 -0
  5. llms_py-2.0.15/llms/__pycache__/__init__.cpython-312.pyc +0 -0
  6. llms_py-2.0.15/llms/__pycache__/__main__.cpython-312.pyc +0 -0
  7. llms_py-2.0.15/llms/__pycache__/llms.cpython-312.pyc +0 -0
  8. llms_py-2.0.15/llms/__pycache__/main.cpython-312.pyc +0 -0
  9. llms_py-2.0.13/llms.py → llms_py-2.0.15/llms/main.py +65 -19
  10. {llms_py-2.0.13 → llms_py-2.0.15/llms}/ui/ai.mjs +1 -1
  11. {llms_py-2.0.13 → llms_py-2.0.15/llms_py.egg-info}/PKG-INFO +1 -1
  12. llms_py-2.0.15/llms_py.egg-info/SOURCES.txt +53 -0
  13. llms_py-2.0.15/llms_py.egg-info/entry_points.txt +2 -0
  14. {llms_py-2.0.13 → llms_py-2.0.15}/pyproject.toml +4 -4
  15. {llms_py-2.0.13 → llms_py-2.0.15}/setup.py +12 -45
  16. llms_py-2.0.13/MANIFEST.in +0 -7
  17. llms_py-2.0.13/llms_py.egg-info/SOURCES.txt +0 -47
  18. llms_py-2.0.13/llms_py.egg-info/entry_points.txt +0 -2
  19. {llms_py-2.0.13 → llms_py-2.0.15}/LICENSE +0 -0
  20. {llms_py-2.0.13 → llms_py-2.0.15}/README.md +0 -0
  21. {llms_py-2.0.13 → llms_py-2.0.15/llms}/index.html +0 -0
  22. {llms_py-2.0.13 → llms_py-2.0.15/llms}/llms.json +0 -0
  23. {llms_py-2.0.13 → llms_py-2.0.15/llms}/ui/App.mjs +0 -0
  24. {llms_py-2.0.13 → llms_py-2.0.15/llms}/ui/Avatar.mjs +0 -0
  25. {llms_py-2.0.13 → llms_py-2.0.15/llms}/ui/Brand.mjs +0 -0
  26. {llms_py-2.0.13 → llms_py-2.0.15/llms}/ui/ChatPrompt.mjs +0 -0
  27. {llms_py-2.0.13 → llms_py-2.0.15/llms}/ui/Main.mjs +0 -0
  28. {llms_py-2.0.13 → llms_py-2.0.15/llms}/ui/ModelSelector.mjs +0 -0
  29. {llms_py-2.0.13 → llms_py-2.0.15/llms}/ui/ProviderStatus.mjs +0 -0
  30. {llms_py-2.0.13 → llms_py-2.0.15/llms}/ui/Recents.mjs +0 -0
  31. {llms_py-2.0.13 → llms_py-2.0.15/llms}/ui/SettingsDialog.mjs +0 -0
  32. {llms_py-2.0.13 → llms_py-2.0.15/llms}/ui/Sidebar.mjs +0 -0
  33. {llms_py-2.0.13 → llms_py-2.0.15/llms}/ui/SignIn.mjs +0 -0
  34. {llms_py-2.0.13 → llms_py-2.0.15/llms}/ui/SystemPromptEditor.mjs +0 -0
  35. {llms_py-2.0.13 → llms_py-2.0.15/llms}/ui/SystemPromptSelector.mjs +0 -0
  36. {llms_py-2.0.13 → llms_py-2.0.15/llms}/ui/Welcome.mjs +0 -0
  37. {llms_py-2.0.13 → llms_py-2.0.15/llms}/ui/app.css +0 -0
  38. {llms_py-2.0.13 → llms_py-2.0.15/llms}/ui/fav.svg +0 -0
  39. {llms_py-2.0.13 → llms_py-2.0.15/llms}/ui/lib/highlight.min.mjs +0 -0
  40. {llms_py-2.0.13 → llms_py-2.0.15/llms}/ui/lib/idb.min.mjs +0 -0
  41. {llms_py-2.0.13 → llms_py-2.0.15/llms}/ui/lib/marked.min.mjs +0 -0
  42. {llms_py-2.0.13 → llms_py-2.0.15/llms}/ui/lib/servicestack-client.mjs +0 -0
  43. {llms_py-2.0.13 → llms_py-2.0.15/llms}/ui/lib/servicestack-vue.mjs +0 -0
  44. {llms_py-2.0.13 → llms_py-2.0.15/llms}/ui/lib/vue-router.min.mjs +0 -0
  45. {llms_py-2.0.13 → llms_py-2.0.15/llms}/ui/lib/vue.min.mjs +0 -0
  46. {llms_py-2.0.13 → llms_py-2.0.15/llms}/ui/lib/vue.mjs +0 -0
  47. {llms_py-2.0.13 → llms_py-2.0.15/llms}/ui/markdown.mjs +0 -0
  48. {llms_py-2.0.13 → llms_py-2.0.15/llms}/ui/tailwind.input.css +0 -0
  49. {llms_py-2.0.13 → llms_py-2.0.15/llms}/ui/threadStore.mjs +0 -0
  50. {llms_py-2.0.13 → llms_py-2.0.15/llms}/ui/typography.css +0 -0
  51. {llms_py-2.0.13 → llms_py-2.0.15/llms}/ui/utils.mjs +0 -0
  52. {llms_py-2.0.13 → llms_py-2.0.15/llms}/ui.json +0 -0
  53. {llms_py-2.0.13 → llms_py-2.0.15}/llms_py.egg-info/dependency_links.txt +0 -0
  54. {llms_py-2.0.13 → llms_py-2.0.15}/llms_py.egg-info/not-zip-safe +0 -0
  55. {llms_py-2.0.13 → llms_py-2.0.15}/llms_py.egg-info/requires.txt +0 -0
  56. {llms_py-2.0.13 → llms_py-2.0.15}/llms_py.egg-info/top_level.txt +0 -0
  57. {llms_py-2.0.13 → llms_py-2.0.15}/requirements.txt +0 -0
  58. {llms_py-2.0.13 → llms_py-2.0.15}/setup.cfg +0 -0
@@ -0,0 +1,4 @@
1
+ include README.md
2
+ include LICENSE
3
+ include requirements.txt
4
+ recursive-include llms *
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: llms-py
3
- Version: 2.0.13
3
+ Version: 2.0.15
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,2 @@
1
+ # Import the main module content
2
+ from .main import *
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Entry point for running llms as a module: python -m llms
4
+ """
5
+
6
+ from .main import main
7
+
8
+ if __name__ == "__main__":
9
+ main()
@@ -22,7 +22,7 @@ from aiohttp import web
22
22
  from pathlib import Path
23
23
  from importlib import resources # Py≥3.9 (pip install importlib_resources for 3.7/3.8)
24
24
 
25
- VERSION = "2.0.13"
25
+ VERSION = "2.0.15"
26
26
  _ROOT = None
27
27
  g_config_path = None
28
28
  g_ui_path = None
@@ -947,6 +947,36 @@ def resolve_root():
947
947
  # importlib.resources not available (Python < 3.9)
948
948
  pass
949
949
 
950
+ # Method 1b: Look for the installed package and check for UI files
951
+ try:
952
+ import llms
953
+ # If llms is a package, check its directory
954
+ if hasattr(llms, '__path__'):
955
+ # It's a package
956
+ package_path = Path(llms.__path__[0])
957
+
958
+ # Check if UI files are in the package directory
959
+ if (package_path / "index.html").exists() and (package_path / "ui").is_dir():
960
+ _log(f"RESOURCE ROOT (package directory): {package_path}")
961
+ return package_path
962
+ else:
963
+ # It's a module
964
+ module_path = Path(llms.__file__).resolve().parent
965
+
966
+ # Check if UI files are in the same directory as the module
967
+ if (module_path / "index.html").exists() and (module_path / "ui").is_dir():
968
+ _log(f"RESOURCE ROOT (module directory): {module_path}")
969
+ return module_path
970
+
971
+ # Check parent directory (sometimes data files are installed one level up)
972
+ parent_path = module_path.parent
973
+ if (parent_path / "index.html").exists() and (parent_path / "ui").is_dir():
974
+ _log(f"RESOURCE ROOT (module parent): {parent_path}")
975
+ return parent_path
976
+
977
+ except (ImportError, AttributeError):
978
+ pass
979
+
950
980
  # Method 2: Try to find data files in sys.prefix (where data_files are installed)
951
981
  # Get all possible installation directories
952
982
  possible_roots = [
@@ -976,6 +1006,22 @@ def resolve_root():
976
1006
  except AttributeError:
977
1007
  pass
978
1008
 
1009
+ # Method 2b: Look for data files in common macOS Homebrew locations
1010
+ # Homebrew often installs data files in different locations
1011
+ homebrew_roots = []
1012
+ if sys.platform == "darwin": # macOS
1013
+ homebrew_prefixes = ["/opt/homebrew", "/usr/local"] # Apple Silicon and Intel
1014
+ for prefix in homebrew_prefixes:
1015
+ if Path(prefix).exists():
1016
+ homebrew_roots.extend([
1017
+ Path(prefix),
1018
+ Path(prefix) / "share",
1019
+ Path(prefix) / "lib" / "python3.11" / "site-packages",
1020
+ Path(prefix) / "lib" / f"python{sys.version_info.major}.{sys.version_info.minor}" / "site-packages",
1021
+ ])
1022
+
1023
+ possible_roots.extend(homebrew_roots)
1024
+
979
1025
  for root in possible_roots:
980
1026
  try:
981
1027
  if root.exists() and (root / "index.html").exists() and (root / "ui").is_dir():
@@ -1118,12 +1164,12 @@ def main():
1118
1164
  if resource_exists(resource_config_path):
1119
1165
  try:
1120
1166
  # Read config from resource (handle both Path and Traversable objects)
1121
- config_json = read_resource_text(resource_ui_path)
1167
+ config_json = read_resource_text(resource_config_path)
1122
1168
  except (OSError, AttributeError) as e:
1123
1169
  _log(f"Error reading resource config: {e}")
1124
1170
  if not config_json:
1125
1171
  try:
1126
- config_json = asyncio.run(save_text(github_url("llms.json"), home_ui_path))
1172
+ config_json = asyncio.run(save_text(github_url("llms.json"), home_config_path))
1127
1173
  except Exception as e:
1128
1174
  _log(f"Error downloading llms.json: {e}")
1129
1175
  print("Could not create llms.json. Create one with --init or use --config <path>")
@@ -1279,6 +1325,20 @@ def main():
1279
1325
  raise web.HTTPNotFound
1280
1326
 
1281
1327
  app.router.add_get("/ui/{path:.*}", ui_static, name="ui_static")
1328
+
1329
+ async def ui_config_handler(request):
1330
+ with open(g_ui_path, "r") as f:
1331
+ ui = json.load(f)
1332
+ if 'defaults' not in ui:
1333
+ ui['defaults'] = g_config['defaults']
1334
+ enabled, disabled = provider_status()
1335
+ ui['status'] = {
1336
+ "all": list(g_config['providers'].keys()),
1337
+ "enabled": enabled,
1338
+ "disabled": disabled
1339
+ }
1340
+ return web.json_response(ui)
1341
+ app.router.add_get('/config', ui_config_handler)
1282
1342
 
1283
1343
  async def not_found_handler(request):
1284
1344
  return web.Response(text="404: Not Found", status=404)
@@ -1294,23 +1354,9 @@ def main():
1294
1354
 
1295
1355
  # Serve index.html as fallback route (SPA routing)
1296
1356
  app.router.add_route('*', '/{tail:.*}', index_handler)
1297
-
1298
- async def ui_config_handler(request):
1299
- with open(g_ui_path, "r") as f:
1300
- ui = json.load(f)
1301
- if 'defaults' not in ui:
1302
- ui['defaults'] = g_config['defaults']
1303
- enabled, disabled = provider_status()
1304
- ui['status'] = {
1305
- "all": list(g_config['providers'].keys()),
1306
- "enabled": enabled,
1307
- "disabled": disabled
1308
- }
1309
- return web.json_response(ui)
1310
- app.router.add_get('/config', ui_config_handler)
1311
1357
 
1312
1358
  print(f"Starting server on port {port}...")
1313
- web.run_app(app, host='0.0.0.0', port=port)
1359
+ web.run_app(app, host='0.0.0.0', port=port, print=_log)
1314
1360
  exit(0)
1315
1361
 
1316
1362
  if cli_args.enable is not None:
@@ -1436,5 +1482,5 @@ def main():
1436
1482
  parser.print_help()
1437
1483
 
1438
1484
 
1439
- if __name__ == "__main__":
1485
+ if __name__ == "__main__":
1440
1486
  main()
@@ -6,7 +6,7 @@ const headers = { 'Accept': 'application/json' }
6
6
  const prefsKey = 'llms.prefs'
7
7
 
8
8
  export const o = {
9
- version: '2.0.13',
9
+ version: '2.0.15',
10
10
  base,
11
11
  prefsKey,
12
12
  welcome: 'Welcome to llms.py',
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: llms-py
3
- Version: 2.0.13
3
+ Version: 2.0.15
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,53 @@
1
+ LICENSE
2
+ MANIFEST.in
3
+ README.md
4
+ pyproject.toml
5
+ requirements.txt
6
+ setup.py
7
+ llms/__init__.py
8
+ llms/__main__.py
9
+ llms/index.html
10
+ llms/llms.json
11
+ llms/main.py
12
+ llms/ui.json
13
+ llms/__pycache__/__init__.cpython-312.pyc
14
+ llms/__pycache__/__main__.cpython-312.pyc
15
+ llms/__pycache__/llms.cpython-312.pyc
16
+ llms/__pycache__/main.cpython-312.pyc
17
+ llms/ui/App.mjs
18
+ llms/ui/Avatar.mjs
19
+ llms/ui/Brand.mjs
20
+ llms/ui/ChatPrompt.mjs
21
+ llms/ui/Main.mjs
22
+ llms/ui/ModelSelector.mjs
23
+ llms/ui/ProviderStatus.mjs
24
+ llms/ui/Recents.mjs
25
+ llms/ui/SettingsDialog.mjs
26
+ llms/ui/Sidebar.mjs
27
+ llms/ui/SignIn.mjs
28
+ llms/ui/SystemPromptEditor.mjs
29
+ llms/ui/SystemPromptSelector.mjs
30
+ llms/ui/Welcome.mjs
31
+ llms/ui/ai.mjs
32
+ llms/ui/app.css
33
+ llms/ui/fav.svg
34
+ llms/ui/markdown.mjs
35
+ llms/ui/tailwind.input.css
36
+ llms/ui/threadStore.mjs
37
+ llms/ui/typography.css
38
+ llms/ui/utils.mjs
39
+ llms/ui/lib/highlight.min.mjs
40
+ llms/ui/lib/idb.min.mjs
41
+ llms/ui/lib/marked.min.mjs
42
+ llms/ui/lib/servicestack-client.mjs
43
+ llms/ui/lib/servicestack-vue.mjs
44
+ llms/ui/lib/vue-router.min.mjs
45
+ llms/ui/lib/vue.min.mjs
46
+ llms/ui/lib/vue.mjs
47
+ llms_py.egg-info/PKG-INFO
48
+ llms_py.egg-info/SOURCES.txt
49
+ llms_py.egg-info/dependency_links.txt
50
+ llms_py.egg-info/entry_points.txt
51
+ llms_py.egg-info/not-zip-safe
52
+ llms_py.egg-info/requires.txt
53
+ llms_py.egg-info/top_level.txt
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ llms = llms.main:main
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "llms-py"
7
- version = "2.0.13"
7
+ version = "2.0.15"
8
8
  description = "A lightweight CLI tool and OpenAI-compatible server for querying multiple Large Language Model (LLM) providers"
9
9
  readme = "README.md"
10
10
  license = "BSD-3-Clause"
@@ -47,10 +47,10 @@ Repository = "https://github.com/ServiceStack/llms"
47
47
  "Bug Reports" = "https://github.com/ServiceStack/llms/issues"
48
48
 
49
49
  [project.scripts]
50
- llms = "llms:main"
50
+ llms = "llms.main:main"
51
51
 
52
52
  [tool.setuptools]
53
- py-modules = ["llms"]
53
+ packages = ["llms"]
54
54
 
55
55
  [tool.setuptools.package-data]
56
- "*" = ["llms.json", "README.md", "LICENSE", "requirements.txt", "index.html", "ui/**/*"]
56
+ llms = ["index.html", "llms.json", "ui.json", "ui/*", "ui/lib/*"]
@@ -16,7 +16,7 @@ with open(os.path.join(this_directory, "requirements.txt"), encoding="utf-8") as
16
16
 
17
17
  setup(
18
18
  name="llms-py",
19
- version="2.0.13",
19
+ version="2.0.15",
20
20
  author="ServiceStack",
21
21
  author_email="team@servicestack.net",
22
22
  description="A lightweight CLI tool and OpenAI-compatible server for querying multiple Large Language Model (LLM) providers",
@@ -28,12 +28,21 @@ setup(
28
28
  "Source": "https://github.com/ServiceStack/llms",
29
29
  "Documentation": "https://github.com/ServiceStack/llms#readme",
30
30
  },
31
- py_modules=["llms"],
31
+ packages=["llms"],
32
+ package_data={
33
+ "llms": [
34
+ "index.html",
35
+ "llms.json",
36
+ "ui.json",
37
+ "ui/*",
38
+ "ui/lib/*",
39
+ ]
40
+ },
32
41
  install_requires=requirements,
33
42
  python_requires=">=3.7",
34
43
  entry_points={
35
44
  "console_scripts": [
36
- "llms=llms:main",
45
+ "llms=llms.main:main",
37
46
  ],
38
47
  },
39
48
  classifiers=[
@@ -58,47 +67,5 @@ setup(
58
67
  ],
59
68
  keywords="llm ai openai anthropic google gemini groq mistral ollama cli server chat completion",
60
69
  include_package_data=True,
61
- data_files=[
62
- ("", ["index.html", "ui.json", "llms.json", "requirements.txt"]),
63
- (
64
- "ui",
65
- [
66
- "ui/ai.mjs",
67
- "ui/app.css",
68
- "ui/App.mjs",
69
- "ui/Avatar.mjs",
70
- "ui/Brand.mjs",
71
- "ui/ChatPrompt.mjs",
72
- "ui/fav.svg",
73
- "ui/Main.mjs",
74
- "ui/markdown.mjs",
75
- "ui/ModelSelector.mjs",
76
- "ui/ProviderStatus.mjs",
77
- "ui/Recents.mjs",
78
- "ui/SettingsDialog.mjs",
79
- "ui/Sidebar.mjs",
80
- "ui/SignIn.mjs",
81
- "ui/SystemPromptEditor.mjs",
82
- "ui/SystemPromptSelector.mjs",
83
- "ui/tailwind.input.css",
84
- "ui/threadStore.mjs",
85
- "ui/typography.css",
86
- "ui/utils.mjs",
87
- "ui/Welcome.mjs",
88
- ],
89
- ),
90
- (
91
- "ui/lib",
92
- [
93
- "ui/lib/highlight.min.mjs",
94
- "ui/lib/idb.min.mjs",
95
- "ui/lib/marked.min.mjs",
96
- "ui/lib/servicestack-client.mjs",
97
- "ui/lib/servicestack-vue.mjs",
98
- "ui/lib/vue-router.min.mjs",
99
- "ui/lib/vue.min.mjs",
100
- ],
101
- ),
102
- ],
103
70
  zip_safe=False,
104
71
  )
@@ -1,7 +0,0 @@
1
- include README.md
2
- include LICENSE
3
- include requirements.txt
4
- include llms.json
5
- include index.html
6
- include ui.json
7
- recursive-include ui *
@@ -1,47 +0,0 @@
1
- LICENSE
2
- MANIFEST.in
3
- README.md
4
- index.html
5
- llms.json
6
- llms.py
7
- pyproject.toml
8
- requirements.txt
9
- setup.py
10
- ui.json
11
- llms_py.egg-info/PKG-INFO
12
- llms_py.egg-info/SOURCES.txt
13
- llms_py.egg-info/dependency_links.txt
14
- llms_py.egg-info/entry_points.txt
15
- llms_py.egg-info/not-zip-safe
16
- llms_py.egg-info/requires.txt
17
- llms_py.egg-info/top_level.txt
18
- ui/App.mjs
19
- ui/Avatar.mjs
20
- ui/Brand.mjs
21
- ui/ChatPrompt.mjs
22
- ui/Main.mjs
23
- ui/ModelSelector.mjs
24
- ui/ProviderStatus.mjs
25
- ui/Recents.mjs
26
- ui/SettingsDialog.mjs
27
- ui/Sidebar.mjs
28
- ui/SignIn.mjs
29
- ui/SystemPromptEditor.mjs
30
- ui/SystemPromptSelector.mjs
31
- ui/Welcome.mjs
32
- ui/ai.mjs
33
- ui/app.css
34
- ui/fav.svg
35
- ui/markdown.mjs
36
- ui/tailwind.input.css
37
- ui/threadStore.mjs
38
- ui/typography.css
39
- ui/utils.mjs
40
- ui/lib/highlight.min.mjs
41
- ui/lib/idb.min.mjs
42
- ui/lib/marked.min.mjs
43
- ui/lib/servicestack-client.mjs
44
- ui/lib/servicestack-vue.mjs
45
- ui/lib/vue-router.min.mjs
46
- ui/lib/vue.min.mjs
47
- ui/lib/vue.mjs
@@ -1,2 +0,0 @@
1
- [console_scripts]
2
- llms = llms:main
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes