llms-py 3.0.26__py3-none-any.whl → 3.0.27__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.
- llms/extensions/computer/filesystem.py +16 -1
- llms/extensions/core_tools/__init__.py +1 -169
- llms/extensions/skills/ui/index.mjs +12 -3
- llms/main.py +1 -1
- llms/ui/ai.mjs +1 -1
- {llms_py-3.0.26.dist-info → llms_py-3.0.27.dist-info}/METADATA +1 -1
- {llms_py-3.0.26.dist-info → llms_py-3.0.27.dist-info}/RECORD +11 -11
- {llms_py-3.0.26.dist-info → llms_py-3.0.27.dist-info}/WHEEL +0 -0
- {llms_py-3.0.26.dist-info → llms_py-3.0.27.dist-info}/entry_points.txt +0 -0
- {llms_py-3.0.26.dist-info → llms_py-3.0.27.dist-info}/licenses/LICENSE +0 -0
- {llms_py-3.0.26.dist-info → llms_py-3.0.27.dist-info}/top_level.txt +0 -0
|
@@ -496,15 +496,20 @@ def move_file(source: Annotated[str, "Source path"], destination: Annotated[str,
|
|
|
496
496
|
|
|
497
497
|
|
|
498
498
|
def search_files(
|
|
499
|
-
path: Annotated[str, "Path to search in"],
|
|
500
499
|
pattern: Annotated[str, "Glob pattern to match"],
|
|
500
|
+
path: Annotated[str, "Path to search in"] = None,
|
|
501
501
|
exclude_patterns: Annotated[List[str], "Glob patterns to exclude"] = None,
|
|
502
|
+
sort_by: Annotated[Literal["path", "modified", "size"], "Sort by path, modified or size"] = "path",
|
|
503
|
+
max_results: int = 200,
|
|
502
504
|
) -> str:
|
|
503
505
|
"""
|
|
504
506
|
Recursively search for files and directories matching a pattern. The patterns should be glob-style patterns that match paths relative to the working directory.
|
|
505
507
|
Use pattern like '.ext' to match files in current directory, and '**/.ext' to match files in all subdirectories.
|
|
506
508
|
Returns full paths to all matching items. Great for finding files when you don't know their exact location. Only searches within allowed directories.
|
|
509
|
+
If no path is provided, searches in the first allowed directory.
|
|
507
510
|
"""
|
|
511
|
+
if not path:
|
|
512
|
+
path = get_allowed_directories()[0]
|
|
508
513
|
valid_path = _validate_path(path)
|
|
509
514
|
results = []
|
|
510
515
|
if exclude_patterns is None:
|
|
@@ -533,6 +538,16 @@ def search_files(
|
|
|
533
538
|
except Exception as e:
|
|
534
539
|
raise RuntimeError(f"Error searching files in {valid_path}: {e}") from e
|
|
535
540
|
|
|
541
|
+
if sort_by == "size":
|
|
542
|
+
results.sort(key=lambda p: os.path.getsize(p) if os.path.exists(p) else 0, reverse=True)
|
|
543
|
+
elif sort_by == "modified":
|
|
544
|
+
results.sort(key=lambda p: os.path.getmtime(p) if os.path.exists(p) else 0, reverse=True)
|
|
545
|
+
else: # path
|
|
546
|
+
results.sort()
|
|
547
|
+
|
|
548
|
+
if max_results > 0:
|
|
549
|
+
results = results[:max_results]
|
|
550
|
+
|
|
536
551
|
if not results:
|
|
537
552
|
return "No matches found"
|
|
538
553
|
|
|
@@ -4,8 +4,6 @@ Core System Tools providing essential file operations, memory persistence, math
|
|
|
4
4
|
|
|
5
5
|
import ast
|
|
6
6
|
import contextlib
|
|
7
|
-
import glob
|
|
8
|
-
import json
|
|
9
7
|
import math
|
|
10
8
|
import operator
|
|
11
9
|
import os
|
|
@@ -21,165 +19,6 @@ from aiohttp import web
|
|
|
21
19
|
|
|
22
20
|
g_ctx = None
|
|
23
21
|
|
|
24
|
-
# -----------------------------
|
|
25
|
-
# In-memory storage (replace later)
|
|
26
|
-
# -----------------------------
|
|
27
|
-
|
|
28
|
-
_MEMORY_STORE: Dict[str, Any] = {}
|
|
29
|
-
_SEMANTIC_STORE: List[Dict[str, Any]] = [] # {id, text, metadata}
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
# -----------------------------
|
|
33
|
-
# Memory tools
|
|
34
|
-
# -----------------------------
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
def memory_read(key: str) -> Any:
|
|
38
|
-
"""Read a value from persistent memory."""
|
|
39
|
-
return _MEMORY_STORE.get(key)
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
def memory_write(key: str, value: Any) -> bool:
|
|
43
|
-
"""Write a value to persistent memory."""
|
|
44
|
-
_MEMORY_STORE[key] = value
|
|
45
|
-
return True
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
# -----------------------------
|
|
49
|
-
# Path safety helpers
|
|
50
|
-
# -----------------------------
|
|
51
|
-
|
|
52
|
-
# Limit tools to only access files and folders within LLMS_BASE_DIR if specified, otherwise the current working directory
|
|
53
|
-
_BASE_DIR = os.environ.get("LLMS_BASE_DIR") or os.path.realpath(os.getcwd())
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
def _resolve_safe_path(path: str) -> str:
|
|
57
|
-
"""
|
|
58
|
-
Resolve a path and ensure it stays within the current working directory.
|
|
59
|
-
Raises ValueError if the path escapes the base directory.
|
|
60
|
-
"""
|
|
61
|
-
resolved = os.path.realpath(os.path.join(_BASE_DIR, path))
|
|
62
|
-
if not resolved.startswith(_BASE_DIR + os.sep) and resolved != _BASE_DIR:
|
|
63
|
-
raise ValueError("Access denied: path is outside the working directory")
|
|
64
|
-
return resolved
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
# -----------------------------
|
|
68
|
-
# Semantic search (placeholder)
|
|
69
|
-
# -----------------------------
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
def semantic_search(query: str, top_k: int = 5) -> List[Dict[str, Any]]:
|
|
73
|
-
"""
|
|
74
|
-
Naive semantic search placeholder.
|
|
75
|
-
Replace with embeddings + vector DB.
|
|
76
|
-
"""
|
|
77
|
-
results = []
|
|
78
|
-
for item in _SEMANTIC_STORE:
|
|
79
|
-
if query.lower() in item["text"].lower():
|
|
80
|
-
results.append(item)
|
|
81
|
-
return results[:top_k]
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
# -----------------------------
|
|
85
|
-
# File system tools (restricted to CWD)
|
|
86
|
-
# -----------------------------
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
def read_file(path: str) -> str:
|
|
90
|
-
"""Read a text file from disk within the current working directory."""
|
|
91
|
-
safe_path = _resolve_safe_path(path)
|
|
92
|
-
with open(safe_path, encoding="utf-8") as f:
|
|
93
|
-
return f.read()
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
def write_file(path: str, content: str) -> bool:
|
|
97
|
-
"""Write text to a file within the current working directory (overwrites)."""
|
|
98
|
-
safe_path = _resolve_safe_path(path)
|
|
99
|
-
os.makedirs(os.path.dirname(safe_path) or _BASE_DIR, exist_ok=True)
|
|
100
|
-
with open(safe_path, "w", encoding="utf-8") as f:
|
|
101
|
-
f.write(content)
|
|
102
|
-
return True
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
def list_directory(path: str) -> str:
|
|
106
|
-
"""List directory contents"""
|
|
107
|
-
safe_path = _resolve_safe_path(path)
|
|
108
|
-
if not os.path.exists(safe_path):
|
|
109
|
-
return f"Error: Path not found: {path}"
|
|
110
|
-
|
|
111
|
-
entries = []
|
|
112
|
-
try:
|
|
113
|
-
for entry in os.scandir(safe_path):
|
|
114
|
-
stat = entry.stat()
|
|
115
|
-
entries.append(
|
|
116
|
-
{
|
|
117
|
-
"name": "/" + entry.name if entry.is_dir() else entry.name,
|
|
118
|
-
"size": stat.st_size,
|
|
119
|
-
"mtime": datetime.fromtimestamp(stat.st_mtime).isoformat(),
|
|
120
|
-
}
|
|
121
|
-
)
|
|
122
|
-
return json.dumps({"path": os.path.relpath(safe_path, _BASE_DIR), "entries": entries}, indent=2)
|
|
123
|
-
except Exception as e:
|
|
124
|
-
return f"Error listing directory: {e}"
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
def glob_paths(
|
|
128
|
-
pattern: str,
|
|
129
|
-
extensions: Optional[List[str]] = None,
|
|
130
|
-
sort_by: str = "path", # "path" | "modified" | "size"
|
|
131
|
-
max_results: int = 100,
|
|
132
|
-
) -> Dict[str, List[Dict[str, str]]]:
|
|
133
|
-
"""
|
|
134
|
-
Find files and directories matching a glob pattern
|
|
135
|
-
"""
|
|
136
|
-
if sort_by not in {"path", "modified", "size"}:
|
|
137
|
-
raise ValueError("sort_by must be one of: path, modified, size")
|
|
138
|
-
|
|
139
|
-
safe_pattern = _resolve_safe_path(pattern)
|
|
140
|
-
|
|
141
|
-
results = []
|
|
142
|
-
|
|
143
|
-
for path in glob.glob(safe_pattern, recursive=True):
|
|
144
|
-
resolved = os.path.realpath(path)
|
|
145
|
-
|
|
146
|
-
# Enforce CWD restriction (important for symlinks)
|
|
147
|
-
if not resolved.startswith(_BASE_DIR):
|
|
148
|
-
continue
|
|
149
|
-
|
|
150
|
-
is_dir = os.path.isdir(resolved)
|
|
151
|
-
|
|
152
|
-
# Extension filtering (files only)
|
|
153
|
-
if extensions and not is_dir:
|
|
154
|
-
ext = os.path.splitext(resolved)[1].lower().lstrip(".")
|
|
155
|
-
if ext not in {e.lower().lstrip(".") for e in extensions}:
|
|
156
|
-
continue
|
|
157
|
-
|
|
158
|
-
stat = os.stat(resolved)
|
|
159
|
-
|
|
160
|
-
results.append(
|
|
161
|
-
{
|
|
162
|
-
"path": os.path.relpath(resolved, _BASE_DIR),
|
|
163
|
-
"type": "directory" if is_dir else "file",
|
|
164
|
-
"size_bytes": stat.st_size,
|
|
165
|
-
"modified_time": stat.st_mtime,
|
|
166
|
-
}
|
|
167
|
-
)
|
|
168
|
-
|
|
169
|
-
if len(results) >= max_results:
|
|
170
|
-
break
|
|
171
|
-
|
|
172
|
-
# Sorting
|
|
173
|
-
if sort_by == "path":
|
|
174
|
-
results.sort(key=lambda x: x["path"])
|
|
175
|
-
elif sort_by == "modified":
|
|
176
|
-
results.sort(key=lambda x: x["modified_time"], reverse=True)
|
|
177
|
-
elif sort_by == "size":
|
|
178
|
-
results.sort(key=lambda x: x["size_bytes"], reverse=True)
|
|
179
|
-
|
|
180
|
-
return {"pattern": pattern, "count": len(results), "results": results}
|
|
181
|
-
|
|
182
|
-
|
|
183
22
|
# -----------------------------
|
|
184
23
|
# Expression evaluation tools
|
|
185
24
|
# -----------------------------
|
|
@@ -522,19 +361,12 @@ def install(ctx):
|
|
|
522
361
|
g_ctx = ctx
|
|
523
362
|
group = "core_tools"
|
|
524
363
|
# Examples of registering tools using automatic definition generation
|
|
525
|
-
ctx.register_tool(
|
|
526
|
-
ctx.register_tool(memory_write, group=group)
|
|
527
|
-
# ctx.register_tool(semantic_search) # TODO: implement
|
|
528
|
-
ctx.register_tool(read_file, group=group)
|
|
529
|
-
ctx.register_tool(write_file, group=group)
|
|
530
|
-
ctx.register_tool(list_directory, group=group)
|
|
531
|
-
ctx.register_tool(glob_paths, group=group)
|
|
364
|
+
ctx.register_tool(get_current_time, group=group)
|
|
532
365
|
ctx.register_tool(calc, group=group)
|
|
533
366
|
ctx.register_tool(run_python, group=group)
|
|
534
367
|
ctx.register_tool(run_typescript, group=group)
|
|
535
368
|
ctx.register_tool(run_javascript, group=group)
|
|
536
369
|
ctx.register_tool(run_csharp, group=group)
|
|
537
|
-
ctx.register_tool(get_current_time, group=group)
|
|
538
370
|
|
|
539
371
|
def exec_language(language: str, code: str) -> Dict[str, Any]:
|
|
540
372
|
if language == "python":
|
|
@@ -921,14 +921,23 @@ export default {
|
|
|
921
921
|
},
|
|
922
922
|
show({ thread }) {
|
|
923
923
|
if (thread.messages.length < 2) return false
|
|
924
|
-
|
|
925
|
-
|
|
924
|
+
|
|
925
|
+
const lastMessage = thread.messages[thread.messages.length - 1]
|
|
926
|
+
// only show if the last message is from the assistant
|
|
927
|
+
if (lastMessage.role != "assistant") return false
|
|
928
|
+
|
|
929
|
+
// and it has a skill tool call
|
|
926
930
|
const hasSkillToolCall = thread.messages.some(m =>
|
|
927
931
|
m.tool_calls?.some(tc => tc.type == "function" && tc.function.name == "skill"))
|
|
932
|
+
// or a plan system prompt
|
|
928
933
|
const systemPrompt = thread.messages.find(m => m.role == "system")?.content.toLowerCase() || ''
|
|
929
934
|
const line1 = leftPart(systemPrompt.trim(), "\n")
|
|
930
935
|
const hasPlanSystemPrompt = line1.includes("plan") || systemPrompt.includes("# plan")
|
|
931
|
-
|
|
936
|
+
|
|
937
|
+
// or the last message has no content but has reasoning
|
|
938
|
+
const hasOnlyThinking = !lastMessage.content?.trim() && lastMessage.reasoning?.trim()
|
|
939
|
+
|
|
940
|
+
return hasSkillToolCall || hasPlanSystemPrompt || hasOnlyThinking
|
|
932
941
|
}
|
|
933
942
|
}
|
|
934
943
|
})
|
llms/main.py
CHANGED
llms/ui/ai.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: llms-py
|
|
3
|
-
Version: 3.0.
|
|
3
|
+
Version: 3.0.27
|
|
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
|
|
@@ -3,7 +3,7 @@ llms/__main__.py,sha256=hrBulHIt3lmPm1BCyAEVtB6DQ0Hvc3gnIddhHCmJasg,151
|
|
|
3
3
|
llms/db.py,sha256=oozp5I5lECVO8oZEFwcZl3ES5mARqWeR1BkoqG5kSqM,11687
|
|
4
4
|
llms/index.html,sha256=nGk1Djtn9p7l6LuKp4Kg0JIB9fCzxtTWXFfmDb4ggpc,1658
|
|
5
5
|
llms/llms.json,sha256=ar7f5uti80RrYhbsYLtCuqdHSFWWlwyVeV0nPCgUzeA,11564
|
|
6
|
-
llms/main.py,sha256=
|
|
6
|
+
llms/main.py,sha256=JETnTf2TkJd14WTM6nkfiaqH6VZ72JnaXY_ySWb2uZY,176657
|
|
7
7
|
llms/providers-extra.json,sha256=_6DmGBiQY9LM6_Y0zOiObYn7ba4g3akSNQfmHcYlENc,11101
|
|
8
8
|
llms/providers.json,sha256=yls3OUqPIBLSf2rk0xgwUHKkvd-8drGq4JW7w49rEws,299324
|
|
9
9
|
llms/extensions/analytics/ui/index.mjs,sha256=m1XwaqYCLwK267JAUCAltkN_nOXep0GxfpvGNS5i4_w,69547
|
|
@@ -19,11 +19,11 @@ llms/extensions/computer/base.py,sha256=Igio5R6kPQOxIbmpaA7X6j6eC4cpF3jwTTR8rURf
|
|
|
19
19
|
llms/extensions/computer/bash.py,sha256=-xo67wVAdrqxtXgR7MK-iAkJ4Wne7Dm1JmnuHC2xW8o,5953
|
|
20
20
|
llms/extensions/computer/computer.py,sha256=wehwcrYwi9usCRcziE_loMhWDbVgfjLk_T4_4TZa4W4,19642
|
|
21
21
|
llms/extensions/computer/edit.py,sha256=QluhvRhYSSQJfbih4QyfC4M8W8aVqiOApfYXZgZTI5M,12725
|
|
22
|
-
llms/extensions/computer/filesystem.py,sha256=
|
|
22
|
+
llms/extensions/computer/filesystem.py,sha256=V6UI2rtGxreQyPvYnXfeQQuLocTDloAQU1k_jCTybnY,21825
|
|
23
23
|
llms/extensions/computer/platform.py,sha256=w5ECar8lM4Lag7rTYUQmU7wEWaqCeejNXwwM3CB8ulQ,14866
|
|
24
24
|
llms/extensions/computer/run.py,sha256=ZIcoYyy2cc3IKR_T4yJgx6IUHu2m7UusIJi9Dx1s7dA,1566
|
|
25
25
|
llms/extensions/core_tools/CALCULATOR.md,sha256=pJRtCVF01BgxFrSNh2Ys_lrRi3SFwLgJzAX93AGh93Q,1944
|
|
26
|
-
llms/extensions/core_tools/__init__.py,sha256=
|
|
26
|
+
llms/extensions/core_tools/__init__.py,sha256=YazB9yM5mLEtZWmCb_Dguz9XU2aPw4O6QU2Jk0vWI44,16422
|
|
27
27
|
llms/extensions/core_tools/ui/index.mjs,sha256=KycJ2FcQ6BieBY7fjWGxVBGHN6WuFx712OFrO6flXww,31770
|
|
28
28
|
llms/extensions/core_tools/ui/codemirror/codemirror.css,sha256=60lOqXLSZh74b39qxlbdZ4bXIeScnBtG4euWfktvm_M,8720
|
|
29
29
|
llms/extensions/core_tools/ui/codemirror/codemirror.js,sha256=7cA89SlK249o7tVfiEWIiqDEA6ZEWxX4CoZmofVA14s,402008
|
|
@@ -156,7 +156,7 @@ llms/extensions/skills/installer.py,sha256=GfNYRK6LbYSZtIOesQ_fQvjtBsiZC9sTXLVuU
|
|
|
156
156
|
llms/extensions/skills/models.py,sha256=xmRfz8BMeOdzZXhW6MYFjkOVHOKD6bMDynId8aysans,1461
|
|
157
157
|
llms/extensions/skills/parser.py,sha256=Mb4NOtoY3Ip4Nng8ixb26oE8U_Sp5CI3n3l_qxbg1UM,5500
|
|
158
158
|
llms/extensions/skills/validator.py,sha256=te49hTfIPJWcMcLLCApSJ2Ru3lrqVF8ayDXtPEZF9sU,5154
|
|
159
|
-
llms/extensions/skills/ui/index.mjs,sha256=
|
|
159
|
+
llms/extensions/skills/ui/index.mjs,sha256=YYVaa4qWiLrcj9USnQWHz6NVblXzahV7R9SVJ-irUPc,63587
|
|
160
160
|
llms/extensions/skills/ui/data/skills-top-5000.json,sha256=e8fUF_NQSUZRK0rGRUqBFecW5JEX6QO6H_P3WqTBBQ4,540056
|
|
161
161
|
llms/extensions/skills/ui/skills/create-plan/SKILL.md,sha256=ZAtiM2qPHcc8Z3Ongl1NgX5ythITPwyvcIqisgqWrGA,2493
|
|
162
162
|
llms/extensions/skills/ui/skills/skill-creator/LICENSE.txt,sha256=WNHhf_5RCaeuKWyq_K39vmp9F28LxKsB4SpomwSZ2L0,11357
|
|
@@ -173,7 +173,7 @@ llms/extensions/system_prompts/ui/prompts.json,sha256=t5DD3bird-87wFa4OlW-bC2wdo
|
|
|
173
173
|
llms/extensions/tools/__init__.py,sha256=PRZe0QMfsOymJ3jTqO0VFppNEWI4f2bYSOImK_YrGQM,2036
|
|
174
174
|
llms/extensions/tools/ui/index.mjs,sha256=1TgCn74oX_rUAhxO8w54HlIgNkHnI5ma-GCqXp-qYVY,39434
|
|
175
175
|
llms/ui/App.mjs,sha256=8yljf7M7LUp4q7XPEHTCUKpJB3X2d8ePnatRamwTM00,7622
|
|
176
|
-
llms/ui/ai.mjs,sha256=
|
|
176
|
+
llms/ui/ai.mjs,sha256=s3DYVkugdmqbkjePM4-koPoy7kPIFyAqGU8M__K2sI8,6540
|
|
177
177
|
llms/ui/app.css,sha256=SVVzmFhTd0chuGq5yhv3FjgNudgo6WXlM2fnb-csK4c,190220
|
|
178
178
|
llms/ui/ctx.mjs,sha256=4x-LTmofhf6OvLThSlDSTQOsLkzyBFOEMRGIOLHszqs,14974
|
|
179
179
|
llms/ui/fav.svg,sha256=_R6MFeXl6wBFT0lqcUxYQIDWgm246YH_3hSTW0oO8qw,734
|
|
@@ -199,9 +199,9 @@ llms/ui/modules/model-selector.mjs,sha256=6U4rAZ7vmQELFRQGWk4YEtq02v3lyHdMq6yUOp
|
|
|
199
199
|
llms/ui/modules/chat/ChatBody.mjs,sha256=OyjAQPHNIbdqEhQq01ysbx7Cbt1CezUERbgFpcbnrNI,58081
|
|
200
200
|
llms/ui/modules/chat/SettingsDialog.mjs,sha256=HMBJTwrapKrRIAstIIqp0QlJL5O-ho4hzgvfagPfsX8,19930
|
|
201
201
|
llms/ui/modules/chat/index.mjs,sha256=nS_L6G1RSuCybgnA6n-q8Sn3OeSbQWL2iW3-zCIFqJk,39548
|
|
202
|
-
llms_py-3.0.
|
|
203
|
-
llms_py-3.0.
|
|
204
|
-
llms_py-3.0.
|
|
205
|
-
llms_py-3.0.
|
|
206
|
-
llms_py-3.0.
|
|
207
|
-
llms_py-3.0.
|
|
202
|
+
llms_py-3.0.27.dist-info/licenses/LICENSE,sha256=bus9cuAOWeYqBk2OuhSABVV1P4z7hgrEFISpyda_H5w,1532
|
|
203
|
+
llms_py-3.0.27.dist-info/METADATA,sha256=Ojx7FD0AjI3enkul3b9wiEqEVnDf0Yo_QN-3uynyN4c,2195
|
|
204
|
+
llms_py-3.0.27.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
205
|
+
llms_py-3.0.27.dist-info/entry_points.txt,sha256=WswyE7PfnkZMIxboC-MS6flBD6wm-CYU7JSUnMhqMfM,40
|
|
206
|
+
llms_py-3.0.27.dist-info/top_level.txt,sha256=gC7hk9BKSeog8gyg-EM_g2gxm1mKHwFRfK-10BxOsa4,5
|
|
207
|
+
llms_py-3.0.27.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|