langfun 0.1.2.dev202501030804__py3-none-any.whl → 0.1.2.dev202501040804__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.
- langfun/core/eval/v2/experiment.py +23 -18
- langfun/core/eval/v2/experiment_test.py +21 -4
- langfun/core/eval/v2/reporting.py +17 -7
- langfun/core/eval/v2/reporting_test.py +1 -1
- langfun/core/llms/__init__.py +2 -0
- langfun/core/llms/google_genai.py +11 -0
- langfun/core/llms/vertexai.py +13 -1
- {langfun-0.1.2.dev202501030804.dist-info → langfun-0.1.2.dev202501040804.dist-info}/METADATA +1 -1
- {langfun-0.1.2.dev202501030804.dist-info → langfun-0.1.2.dev202501040804.dist-info}/RECORD +12 -12
- {langfun-0.1.2.dev202501030804.dist-info → langfun-0.1.2.dev202501040804.dist-info}/LICENSE +0 -0
- {langfun-0.1.2.dev202501030804.dist-info → langfun-0.1.2.dev202501040804.dist-info}/WHEEL +0 -0
- {langfun-0.1.2.dev202501030804.dist-info → langfun-0.1.2.dev202501040804.dist-info}/top_level.txt +0 -0
@@ -381,7 +381,7 @@ class Experiment(lf.Component, pg.views.HtmlTreeView.Extension):
|
|
381
381
|
example_ids: list[int] | None = None,
|
382
382
|
raise_if_has_error: bool = False,
|
383
383
|
reprocess: bool | list[int] = False,
|
384
|
-
|
384
|
+
generate_example_html: Literal['new', 'all', 'no'] | list[int] = 'new',
|
385
385
|
process_timeout: int | None = None,
|
386
386
|
use_cache: Literal['global', 'per_dataset', 'no'] = 'per_dataset',
|
387
387
|
note: str | None = None,
|
@@ -435,11 +435,13 @@ class Experiment(lf.Component, pg.views.HtmlTreeView.Extension):
|
|
435
435
|
meaning that existing checkpoints will be ignored. If a list of
|
436
436
|
example IDs, it indicates that only the specified examples will be
|
437
437
|
reprocessed.
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
438
|
+
generate_example_html: Among 'new', 'all', 'no' or a list of example IDs.
|
439
|
+
If 'new', generate HTML files for all newly processed examples, and
|
440
|
+
keep/copy existing HTML files for unchanged examples.
|
441
|
+
If 'all', generate HTML files for all examples.
|
442
|
+
If 'no', do not generate HTML files for any examples.
|
443
|
+
If a list of example IDs, generate HTML files for the specified
|
444
|
+
examples.
|
443
445
|
process_timeout: The timeout in seconds for each process. If None, it
|
444
446
|
will use the default timeout for the runner.
|
445
447
|
use_cache: Whether to use LLM cache for the experiment.
|
@@ -467,7 +469,7 @@ class Experiment(lf.Component, pg.views.HtmlTreeView.Extension):
|
|
467
469
|
example_ids=example_ids,
|
468
470
|
raise_if_has_error=raise_if_has_error,
|
469
471
|
reprocess=reprocess,
|
470
|
-
|
472
|
+
generate_example_html=generate_example_html,
|
471
473
|
use_cache=use_cache,
|
472
474
|
process_timeout=process_timeout,
|
473
475
|
note=note,
|
@@ -837,14 +839,17 @@ class Run(pg.Object, pg.views.html.HtmlTreeView.Extension):
|
|
837
839
|
)
|
838
840
|
] = False
|
839
841
|
|
840
|
-
|
841
|
-
|
842
|
+
generate_example_html: Annotated[
|
843
|
+
Literal['new', 'all', 'no'] | list[int],
|
842
844
|
(
|
843
|
-
'If
|
844
|
-
'
|
845
|
-
'
|
845
|
+
'If "new", generate HTML files for all newly processed examples, '
|
846
|
+
'and keep/copy existing HTML files for unchanged examples. '
|
847
|
+
'If "all", generate HTML files for all examples. '
|
848
|
+
'If "no", do not generate HTML files for any examples. '
|
849
|
+
'If a list of example IDs, generate HTML files for the specified '
|
850
|
+
'examples.'
|
846
851
|
)
|
847
|
-
] =
|
852
|
+
] = 'new'
|
848
853
|
|
849
854
|
filter: Annotated[
|
850
855
|
Callable[[Experiment], bool] | None,
|
@@ -917,17 +922,17 @@ class Run(pg.Object, pg.views.html.HtmlTreeView.Extension):
|
|
917
922
|
def examples_to_load(self, experiment: Experiment) -> set[int]:
|
918
923
|
"""Returns the example IDs to load from checkpoint files.."""
|
919
924
|
load_ids = self.examples_to_evaluate(experiment)
|
920
|
-
if isinstance(self.
|
921
|
-
load_ids |= set(self.
|
925
|
+
if isinstance(self.generate_example_html, list):
|
926
|
+
load_ids |= set(self.generate_example_html)
|
922
927
|
load_ids -= self.examples_to_reprocess(experiment)
|
923
928
|
return load_ids
|
924
929
|
|
925
930
|
def examples_to_load_metadata(self, experiment: Experiment) -> set[int]:
|
926
931
|
"""Returns the example IDs to load the metadata."""
|
927
932
|
load_metadata_ids = set()
|
928
|
-
if isinstance(self.
|
929
|
-
load_metadata_ids = set(self.
|
930
|
-
elif self.
|
933
|
+
if isinstance(self.generate_example_html, list):
|
934
|
+
load_metadata_ids = set(self.generate_example_html)
|
935
|
+
elif self.generate_example_html == 'all':
|
931
936
|
load_metadata_ids = self.examples_to_evaluate(experiment)
|
932
937
|
load_metadata_ids -= self.examples_to_reprocess(experiment)
|
933
938
|
return load_metadata_ids
|
@@ -337,7 +337,7 @@ class RunTest(unittest.TestCase):
|
|
337
337
|
self.assertEqual(run.examples_to_load(exp), set([3, 5]))
|
338
338
|
self.assertEqual(run.examples_to_load_metadata(exp), set())
|
339
339
|
|
340
|
-
def
|
340
|
+
def test_examples_with_generate_example_html_all(self):
|
341
341
|
run = Run(
|
342
342
|
'/root',
|
343
343
|
RunId.from_id('20241102_0'),
|
@@ -346,7 +346,7 @@ class RunTest(unittest.TestCase):
|
|
346
346
|
])),
|
347
347
|
example_ids=[1, 3, 5],
|
348
348
|
reprocess=[1],
|
349
|
-
|
349
|
+
generate_example_html='all',
|
350
350
|
)
|
351
351
|
exp = run.experiment.leaf_nodes[0]
|
352
352
|
self.assertEqual(run.examples_to_evaluate(exp), set([1, 3, 5]))
|
@@ -354,7 +354,7 @@ class RunTest(unittest.TestCase):
|
|
354
354
|
self.assertEqual(run.examples_to_load(exp), set([3, 5]))
|
355
355
|
self.assertEqual(run.examples_to_load_metadata(exp), set([3, 5]))
|
356
356
|
|
357
|
-
def
|
357
|
+
def test_examples_with_generate_example_html_new(self):
|
358
358
|
run = Run(
|
359
359
|
'/root',
|
360
360
|
RunId.from_id('20241102_0'),
|
@@ -363,7 +363,24 @@ class RunTest(unittest.TestCase):
|
|
363
363
|
])),
|
364
364
|
example_ids=[1, 3, 5],
|
365
365
|
reprocess=[1],
|
366
|
-
|
366
|
+
generate_example_html='new',
|
367
|
+
)
|
368
|
+
exp = run.experiment.leaf_nodes[0]
|
369
|
+
self.assertEqual(run.examples_to_evaluate(exp), set([1, 3, 5]))
|
370
|
+
self.assertEqual(run.examples_to_reprocess(exp), set([1]))
|
371
|
+
self.assertEqual(run.examples_to_load(exp), set([3, 5]))
|
372
|
+
self.assertEqual(run.examples_to_load_metadata(exp), set())
|
373
|
+
|
374
|
+
def test_examples_with_generate_example_html_some(self):
|
375
|
+
run = Run(
|
376
|
+
'/root',
|
377
|
+
RunId.from_id('20241102_0'),
|
378
|
+
pg.Ref(Suite([
|
379
|
+
MyEvaluation(replica_id=0, inputs=sample_inputs(10)),
|
380
|
+
])),
|
381
|
+
example_ids=[1, 3, 5],
|
382
|
+
reprocess=[1],
|
383
|
+
generate_example_html=[1, 2, 3],
|
367
384
|
)
|
368
385
|
exp = run.experiment.leaf_nodes[0]
|
369
386
|
self.assertEqual(run.examples_to_evaluate(exp), set([1, 3, 5]))
|
@@ -195,6 +195,7 @@ class HtmlReporter(experiment_lib.Plugin):
|
|
195
195
|
self, runner: Runner, experiment: Experiment, example: Example
|
196
196
|
) -> None:
|
197
197
|
"""Saves the example in HTML format."""
|
198
|
+
current_run = runner.current_run
|
198
199
|
def _generate():
|
199
200
|
try:
|
200
201
|
with pg.timeit() as t:
|
@@ -222,14 +223,19 @@ class HtmlReporter(experiment_lib.Plugin):
|
|
222
223
|
raise e
|
223
224
|
|
224
225
|
def _copy():
|
225
|
-
src_file =
|
226
|
-
|
227
|
-
|
228
|
-
dest_file = runner.current_run.output_path_for(
|
229
|
-
experiment, f'{example.id}.html'
|
230
|
-
)
|
226
|
+
src_file = current_run.input_path_for(experiment, f'{example.id}.html')
|
227
|
+
dest_file = current_run.output_path_for(experiment, f'{example.id}.html')
|
228
|
+
|
231
229
|
if src_file == dest_file:
|
232
230
|
return
|
231
|
+
|
232
|
+
if not pg.io.path_exists(src_file):
|
233
|
+
experiment.warning(
|
234
|
+
f'Skip copying \'{example.id}.html\' as '
|
235
|
+
f'{src_file!r} does not exist.'
|
236
|
+
)
|
237
|
+
return
|
238
|
+
|
233
239
|
try:
|
234
240
|
with pg.timeit() as t, pg.io.open(src_file, 'r') as src:
|
235
241
|
content = src.read()
|
@@ -244,7 +250,11 @@ class HtmlReporter(experiment_lib.Plugin):
|
|
244
250
|
)
|
245
251
|
raise e
|
246
252
|
|
247
|
-
|
253
|
+
generate_example_html = current_run.generate_example_html
|
254
|
+
if (generate_example_html == 'all'
|
255
|
+
or (generate_example_html == 'new' and example.newly_processed)
|
256
|
+
or (isinstance(generate_example_html, list)
|
257
|
+
and example.id in generate_example_html)):
|
248
258
|
op = _generate
|
249
259
|
else:
|
250
260
|
op = _copy
|
@@ -148,7 +148,7 @@ class ReportingTest(unittest.TestCase):
|
|
148
148
|
)
|
149
149
|
found_error_log = False
|
150
150
|
for log_entry in experiment._log_entries:
|
151
|
-
if log_entry.message.startswith('
|
151
|
+
if log_entry.message.startswith('Skip copying'):
|
152
152
|
found_error_log = True
|
153
153
|
break
|
154
154
|
self.assertTrue(found_error_log)
|
langfun/core/llms/__init__.py
CHANGED
@@ -32,6 +32,7 @@ from langfun.core.llms.rest import REST
|
|
32
32
|
|
33
33
|
# Gemini models.
|
34
34
|
from langfun.core.llms.google_genai import GenAI
|
35
|
+
from langfun.core.llms.google_genai import GeminiFlash2_0ThinkingExp
|
35
36
|
from langfun.core.llms.google_genai import GeminiFlash2_0Exp
|
36
37
|
from langfun.core.llms.google_genai import GeminiExp_20241114
|
37
38
|
from langfun.core.llms.google_genai import GeminiExp_20241206
|
@@ -126,6 +127,7 @@ from langfun.core.llms.groq import GroqWhisper_Large_v3Turbo
|
|
126
127
|
from langfun.core.llms.vertexai import VertexAI
|
127
128
|
from langfun.core.llms.vertexai import VertexAIGemini2_0
|
128
129
|
from langfun.core.llms.vertexai import VertexAIGeminiFlash2_0Exp
|
130
|
+
from langfun.core.llms.vertexai import VertexAIGeminiFlash2_0ThinkingExp
|
129
131
|
from langfun.core.llms.vertexai import VertexAIGemini1_5
|
130
132
|
from langfun.core.llms.vertexai import VertexAIGeminiPro1_5
|
131
133
|
from langfun.core.llms.vertexai import VertexAIGeminiPro1_5_001
|
@@ -48,6 +48,7 @@ class GenAI(lf.LanguageModel):
|
|
48
48
|
|
49
49
|
model: Annotated[
|
50
50
|
Literal[
|
51
|
+
'gemini-2.0-flash-thinking-exp-1219',
|
51
52
|
'gemini-2.0-flash-exp',
|
52
53
|
'gemini-exp-1206',
|
53
54
|
'gemini-exp-1114',
|
@@ -307,6 +308,16 @@ _GOOGLE_GENAI_MODEL_HUB = _ModelHub()
|
|
307
308
|
#
|
308
309
|
# Public Gemini models.
|
309
310
|
#
|
311
|
+
class GeminiFlash2_0ThinkingExp(GenAI): # pylint: disable=invalid-name
|
312
|
+
"""Gemini 2.0 Flash Thinking Experimental model."""
|
313
|
+
|
314
|
+
model = 'gemini-2.0-flash-thinking-exp-1219'
|
315
|
+
supported_modalities = (
|
316
|
+
vertexai.DOCUMENT_TYPES
|
317
|
+
+ vertexai.IMAGE_TYPES
|
318
|
+
+ vertexai.AUDIO_TYPES
|
319
|
+
+ vertexai.VIDEO_TYPES
|
320
|
+
)
|
310
321
|
|
311
322
|
|
312
323
|
class GeminiFlash2_0Exp(GenAI): # pylint: disable=invalid-name
|
langfun/core/llms/vertexai.py
CHANGED
@@ -110,7 +110,13 @@ SUPPORTED_MODELS_AND_SETTINGS = {
|
|
110
110
|
),
|
111
111
|
# TODO(sharatsharat): Update costs when published
|
112
112
|
'gemini-2.0-flash-exp': pg.Dict(
|
113
|
-
rpm=
|
113
|
+
rpm=10,
|
114
|
+
cost_per_1k_input_chars=0.000,
|
115
|
+
cost_per_1k_output_chars=0.000,
|
116
|
+
),
|
117
|
+
# TODO(yifenglu): Update costs when published
|
118
|
+
'gemini-2.0-flash-thinking-exp-1219': pg.Dict(
|
119
|
+
rpm=10,
|
114
120
|
cost_per_1k_input_chars=0.000,
|
115
121
|
cost_per_1k_output_chars=0.000,
|
116
122
|
),
|
@@ -415,6 +421,12 @@ class VertexAIGeminiFlash2_0Exp(VertexAIGemini2_0): # pylint: disable=invalid-n
|
|
415
421
|
model = 'gemini-2.0-flash-exp'
|
416
422
|
|
417
423
|
|
424
|
+
class VertexAIGeminiFlash2_0ThinkingExp(VertexAIGemini2_0): # pylint: disable=invalid-name
|
425
|
+
"""Vertex AI Gemini 2.0 Flash model."""
|
426
|
+
|
427
|
+
model = 'gemini-2.0-flash-thinking-exp-1219'
|
428
|
+
|
429
|
+
|
418
430
|
class VertexAIGemini1_5(VertexAI): # pylint: disable=invalid-name
|
419
431
|
"""Vertex AI Gemini 1.5 model."""
|
420
432
|
|
@@ -63,8 +63,8 @@ langfun/core/eval/v2/evaluation.py,sha256=kARf0pG6SrpN__IMeFsw8DV_5mT_tl52pJrr6w
|
|
63
63
|
langfun/core/eval/v2/evaluation_test.py,sha256=0l0DqJTF8PZGA2Q1OlaF4YIax4ZhSk0ewOCvuVW1XAk,6658
|
64
64
|
langfun/core/eval/v2/example.py,sha256=4-LNr8Ke-fhaF6gyeXX4JMyw0s8YkVTC63pXZ-CXKrE,10144
|
65
65
|
langfun/core/eval/v2/example_test.py,sha256=1DNm6EuyZOq827DKvf3oTRVFkMNM_qTnLUpvOjpgz5I,3419
|
66
|
-
langfun/core/eval/v2/experiment.py,sha256=
|
67
|
-
langfun/core/eval/v2/experiment_test.py,sha256=
|
66
|
+
langfun/core/eval/v2/experiment.py,sha256=qYWx22KMfoUa4ieSq1bt7NE8L9dgoiJpuNOQGT1IBQw,32723
|
67
|
+
langfun/core/eval/v2/experiment_test.py,sha256=CqpDsDai2DiIU-SzpVmqFzM_ZxxkVYKd0Gr1Uvcvkuw,13546
|
68
68
|
langfun/core/eval/v2/metric_values.py,sha256=_B905bC-jxrYPLSEcP2M8MaHZOVMz_bVrUw8YC4arCE,4660
|
69
69
|
langfun/core/eval/v2/metric_values_test.py,sha256=ab2oF_HsIwrSy459108ggyjgefHSPn8UVILR4dRwx14,2634
|
70
70
|
langfun/core/eval/v2/metrics.py,sha256=bl8i6u-ZHRBz4hAc3LzsZ2Dc7ZRQcuTYeUhhH-GxfF0,10628
|
@@ -73,18 +73,18 @@ langfun/core/eval/v2/progress.py,sha256=azZgssQgNdv3IgjKEaQBuGI5ucFDNbdi02P4z_nQ
|
|
73
73
|
langfun/core/eval/v2/progress_test.py,sha256=YU7VHzmy5knPZwj9vpBN3rQQH2tukj9eKHkuBCI62h8,2540
|
74
74
|
langfun/core/eval/v2/progress_tracking.py,sha256=l9fEkz4oP5McpZzf72Ua7PYm3lAWtRru7gRWNf8H0ms,6083
|
75
75
|
langfun/core/eval/v2/progress_tracking_test.py,sha256=fouMVJkFJqHjbhQJngGLGCmA9x3n0dU4USI2dY163mg,2291
|
76
|
-
langfun/core/eval/v2/reporting.py,sha256=
|
77
|
-
langfun/core/eval/v2/reporting_test.py,sha256=
|
76
|
+
langfun/core/eval/v2/reporting.py,sha256=KF4pE2H1qj3mJcgkv_c5YYFjrU-uJCk_-fuu891Olzs,8061
|
77
|
+
langfun/core/eval/v2/reporting_test.py,sha256=UmYSAQvD3AIXsSyWQ-WD2uLtEISYpmBeoKY5u5Qwc8E,5696
|
78
78
|
langfun/core/eval/v2/runners.py,sha256=DKEmSlGXjOXKWFdBhTpLy7tMsBHZHd1Brl3hWIngsSQ,15931
|
79
79
|
langfun/core/eval/v2/runners_test.py,sha256=A37fKK2MvAVTiShsg_laluJzJ9AuAQn52k7HPbfD0Ks,11666
|
80
|
-
langfun/core/llms/__init__.py,sha256=
|
80
|
+
langfun/core/llms/__init__.py,sha256=6mi0IKTNfq6kymZPlPGA2V7YF1xDLrBCPytojeFMMeA,6716
|
81
81
|
langfun/core/llms/anthropic.py,sha256=a5MmnFsBA0CbfvwzXT1v_0fqLRMrhUNdh1tx6469PQ4,14357
|
82
82
|
langfun/core/llms/anthropic_test.py,sha256=-2U4kc_pgBM7wqxu8RuxzyHPGww1EAWqKUvN4PW8Btw,8058
|
83
83
|
langfun/core/llms/compositional.py,sha256=csW_FLlgL-tpeyCOTVvfUQkMa_zCN5Y2I-YbSNuK27U,2872
|
84
84
|
langfun/core/llms/compositional_test.py,sha256=4eTnOer-DncRKGaIJW2ZQQMLnt5r2R0UIx_DYOvGAQo,2027
|
85
85
|
langfun/core/llms/fake.py,sha256=gCHBYBLvBCsC78HI1hpoqXCS-p1FMTgY1P1qh_sGBPk,3070
|
86
86
|
langfun/core/llms/fake_test.py,sha256=2h13qkwEz_JR0mtUDPxdAhQo7MueXaFSwsD2DIRDW9g,7653
|
87
|
-
langfun/core/llms/google_genai.py,sha256=
|
87
|
+
langfun/core/llms/google_genai.py,sha256=3iAmLMcBXxkfiiI8BN0S6trKCfyfuajCIHIGpnCrtTg,11973
|
88
88
|
langfun/core/llms/google_genai_test.py,sha256=zw14sgWmk0P_irHyb7vpPy1WAuLEE0PmyfiFElu03sA,7686
|
89
89
|
langfun/core/llms/groq.py,sha256=dCnR3eAECEKuKKAAj-PDTs8NRHl6CQPdf57m1f6a79U,10312
|
90
90
|
langfun/core/llms/groq_test.py,sha256=GYF_Qtq5S1H1TrKH38t6_lkdroqT7v-joYLDKnmS9e0,5274
|
@@ -94,7 +94,7 @@ langfun/core/llms/openai.py,sha256=dLDVBB47nJ30XCwjJpAZMc55ZlZXB__PcfcICCRNuXQ,2
|
|
94
94
|
langfun/core/llms/openai_test.py,sha256=kOWa1nf-nJvtYY10REUw5wojh3ZgfU8tRaCZ8wUgJbA,16623
|
95
95
|
langfun/core/llms/rest.py,sha256=sWbYUV8S3SuOg9giq7xwD-xDRfaF7NP_ig7bI52-Rj4,3442
|
96
96
|
langfun/core/llms/rest_test.py,sha256=NZ3Nf0XQVpT9kLP5cBVo_yBHLI7vWTYhWQxYEJVMGs4,3472
|
97
|
-
langfun/core/llms/vertexai.py,sha256=
|
97
|
+
langfun/core/llms/vertexai.py,sha256=EPPswgaTfPZQ_GGa_dWsqWPV9uRjCmIH2Iwgm1YXOqM,15377
|
98
98
|
langfun/core/llms/vertexai_test.py,sha256=ffcA5yPecnQy_rhkuYAw_6o1iLW8AR8FgswmHt6aAys,6725
|
99
99
|
langfun/core/llms/cache/__init__.py,sha256=QAo3InUMDM_YpteNnVCSejI4zOsnjSMWKJKzkb3VY64,993
|
100
100
|
langfun/core/llms/cache/base.py,sha256=rt3zwmyw0y9jsSGW-ZbV1vAfLxQ7_3AVk0l2EySlse4,3918
|
@@ -146,8 +146,8 @@ langfun/core/templates/demonstration.py,sha256=vCrgYubdZM5Umqcgp8NUVGXgr4P_c-fik
|
|
146
146
|
langfun/core/templates/demonstration_test.py,sha256=SafcDQ0WgI7pw05EmPI2S4v1t3ABKzup8jReCljHeK4,2162
|
147
147
|
langfun/core/templates/selfplay.py,sha256=yhgrJbiYwq47TgzThmHrDQTF4nDrTI09CWGhuQPNv-s,2273
|
148
148
|
langfun/core/templates/selfplay_test.py,sha256=Ot__1P1M8oJfoTp-M9-PQ6HUXqZKyMwvZ5f7yQ3yfyM,2326
|
149
|
-
langfun-0.1.2.
|
150
|
-
langfun-0.1.2.
|
151
|
-
langfun-0.1.2.
|
152
|
-
langfun-0.1.2.
|
153
|
-
langfun-0.1.2.
|
149
|
+
langfun-0.1.2.dev202501040804.dist-info/LICENSE,sha256=WNHhf_5RCaeuKWyq_K39vmp9F28LxKsB4SpomwSZ2L0,11357
|
150
|
+
langfun-0.1.2.dev202501040804.dist-info/METADATA,sha256=NwyfthRhAHybN6adGkLwsSDi_A-Tj2i6oP7ys-Kln-0,8281
|
151
|
+
langfun-0.1.2.dev202501040804.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
|
152
|
+
langfun-0.1.2.dev202501040804.dist-info/top_level.txt,sha256=RhlEkHxs1qtzmmtWSwYoLVJAc1YrbPtxQ52uh8Z9VvY,8
|
153
|
+
langfun-0.1.2.dev202501040804.dist-info/RECORD,,
|
File without changes
|
File without changes
|
{langfun-0.1.2.dev202501030804.dist-info → langfun-0.1.2.dev202501040804.dist-info}/top_level.txt
RENAMED
File without changes
|