langfun 0.1.2.dev202412110804__py3-none-any.whl → 0.1.2.dev202412140804__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/agentic/action.py +169 -199
- langfun/core/agentic/action_test.py +3 -3
- langfun/core/eval/v2/experiment.py +27 -0
- langfun/core/eval/v2/experiment_test.py +11 -0
- langfun/core/llms/__init__.py +4 -1
- langfun/core/llms/google_genai.py +17 -4
- langfun/core/llms/vertexai.py +28 -2
- langfun/core/structured/prompting.py +48 -13
- langfun/core/structured/prompting_test.py +1 -0
- langfun/core/template.py +23 -37
- langfun/core/template_test.py +6 -26
- {langfun-0.1.2.dev202412110804.dist-info → langfun-0.1.2.dev202412140804.dist-info}/METADATA +1 -1
- {langfun-0.1.2.dev202412110804.dist-info → langfun-0.1.2.dev202412140804.dist-info}/RECORD +16 -16
- {langfun-0.1.2.dev202412110804.dist-info → langfun-0.1.2.dev202412140804.dist-info}/LICENSE +0 -0
- {langfun-0.1.2.dev202412110804.dist-info → langfun-0.1.2.dev202412140804.dist-info}/WHEEL +0 -0
- {langfun-0.1.2.dev202412110804.dist-info → langfun-0.1.2.dev202412140804.dist-info}/top_level.txt +0 -0
langfun/core/agentic/action.py
CHANGED
@@ -32,7 +32,7 @@ class Action(pg.Object):
|
|
32
32
|
super()._on_bound()
|
33
33
|
self._session = None
|
34
34
|
self._result = None
|
35
|
-
self.
|
35
|
+
self._metadata = {}
|
36
36
|
|
37
37
|
@property
|
38
38
|
def session(self) -> Optional['Session']:
|
@@ -45,9 +45,9 @@ class Action(pg.Object):
|
|
45
45
|
return self._result
|
46
46
|
|
47
47
|
@property
|
48
|
-
def
|
48
|
+
def metadata(self) -> dict[str, Any] | None:
|
49
49
|
"""Returns the metadata associated with the result from previous call."""
|
50
|
-
return self.
|
50
|
+
return self._metadata
|
51
51
|
|
52
52
|
def __call__(
|
53
53
|
self,
|
@@ -69,7 +69,7 @@ class Action(pg.Object):
|
|
69
69
|
if new_session:
|
70
70
|
self._session = session
|
71
71
|
self._result = result
|
72
|
-
self.
|
72
|
+
self._metadata = session.current_action.metadata
|
73
73
|
return self._result
|
74
74
|
|
75
75
|
@abc.abstractmethod
|
@@ -139,7 +139,7 @@ class ExecutionTrace(pg.Object, pg.views.html.HtmlTreeView.Extension):
|
|
139
139
|
if self._time_badge is not None:
|
140
140
|
self._time_badge.update(
|
141
141
|
'Starting',
|
142
|
-
add_class=['
|
142
|
+
add_class=['starting'],
|
143
143
|
remove_class=['not-started'],
|
144
144
|
)
|
145
145
|
|
@@ -149,10 +149,14 @@ class ExecutionTrace(pg.Object, pg.views.html.HtmlTreeView.Extension):
|
|
149
149
|
if self._time_badge is not None:
|
150
150
|
self._time_badge.update(
|
151
151
|
f'{int(self.elapse)} seconds',
|
152
|
+
tooltip=pg.format(self.execution_summary(), verbose=False),
|
152
153
|
add_class=['finished'],
|
153
154
|
remove_class=['running'],
|
154
155
|
)
|
155
156
|
|
157
|
+
def __len__(self) -> int:
|
158
|
+
return len(self.items)
|
159
|
+
|
156
160
|
@property
|
157
161
|
def has_started(self) -> bool:
|
158
162
|
return self.start_time is not None
|
@@ -238,17 +242,8 @@ class ExecutionTrace(pg.Object, pg.views.html.HtmlTreeView.Extension):
|
|
238
242
|
and not isinstance(item, lf.logging.LogEntry)):
|
239
243
|
sub_task_label = self._execution_item_label(item)
|
240
244
|
self._time_badge.update(
|
241
|
-
|
242
|
-
|
243
|
-
[
|
244
|
-
'Running',
|
245
|
-
pg.views.html.controls.Badge(
|
246
|
-
sub_task_label.text,
|
247
|
-
tooltip=sub_task_label.tooltip,
|
248
|
-
css_classes=['task-in-progress']
|
249
|
-
)
|
250
|
-
]
|
251
|
-
),
|
245
|
+
text=sub_task_label.text,
|
246
|
+
tooltip=sub_task_label.tooltip.content,
|
252
247
|
add_class=['running'],
|
253
248
|
remove_class=['not-started'],
|
254
249
|
)
|
@@ -263,6 +258,20 @@ class ExecutionTrace(pg.Object, pg.views.html.HtmlTreeView.Extension):
|
|
263
258
|
"""Returns the usage summary of the action."""
|
264
259
|
return self._usage_summary
|
265
260
|
|
261
|
+
def execution_summary(self) -> dict[str, Any]:
|
262
|
+
"""Execution summary string."""
|
263
|
+
return pg.Dict(
|
264
|
+
num_queries=len(self.queries),
|
265
|
+
execution_breakdown=[
|
266
|
+
dict(
|
267
|
+
action=action.action.__class__.__name__,
|
268
|
+
usage=action.usage_summary.total,
|
269
|
+
execution_time=action.execution.elapse,
|
270
|
+
)
|
271
|
+
for action in self.actions
|
272
|
+
]
|
273
|
+
)
|
274
|
+
|
266
275
|
#
|
267
276
|
# HTML views.
|
268
277
|
#
|
@@ -274,57 +283,47 @@ class ExecutionTrace(pg.Object, pg.views.html.HtmlTreeView.Extension):
|
|
274
283
|
extra_flags: dict[str, Any] | None = None,
|
275
284
|
view: pg.views.html.HtmlTreeView, **kwargs
|
276
285
|
):
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
286
|
+
return None
|
287
|
+
|
288
|
+
def _execution_badge(self, interactive: bool = True):
|
289
|
+
if not self.has_started:
|
290
|
+
label = '(Not started)'
|
291
|
+
tooltip = 'Execution not started.'
|
292
|
+
css_class = 'not-started'
|
293
|
+
elif not self.has_stopped:
|
294
|
+
label = 'Starting'
|
295
|
+
tooltip = 'Execution starting.'
|
296
|
+
css_class = 'running'
|
297
|
+
else:
|
298
|
+
label = f'{int(self.elapse)} seconds'
|
299
|
+
tooltip = pg.format(self.execution_summary(), verbose=False)
|
300
|
+
css_class = 'finished'
|
301
|
+
time_badge = pg.views.html.controls.Badge(
|
302
|
+
label,
|
303
|
+
tooltip=tooltip,
|
304
|
+
css_classes=['execution-time', css_class],
|
305
|
+
interactive=interactive,
|
306
|
+
)
|
295
307
|
if interactive:
|
296
308
|
self._time_badge = time_badge
|
297
|
-
|
298
|
-
'div',
|
299
|
-
[
|
300
|
-
'ExecutionTrace',
|
301
|
-
time_badge,
|
302
|
-
],
|
303
|
-
css_classes=['execution-trace-title'],
|
304
|
-
)
|
305
|
-
kwargs.pop('title', None)
|
306
|
-
kwargs['enable_summary_tooltip'] = False
|
307
|
-
kwargs['enable_key_tooltip'] = False
|
308
|
-
return view.summary(
|
309
|
-
self,
|
310
|
-
name=name,
|
311
|
-
title=title,
|
312
|
-
extra_flags=extra_flags,
|
313
|
-
**kwargs
|
314
|
-
)
|
309
|
+
return time_badge
|
315
310
|
|
316
|
-
def _html_tree_view_content(
|
311
|
+
def _html_tree_view_content(
|
312
|
+
self,
|
313
|
+
*,
|
314
|
+
extra_flags: dict[str, Any] | None = None,
|
315
|
+
**kwargs
|
316
|
+
):
|
317
317
|
del kwargs
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
)
|
318
|
+
extra_flags = extra_flags or {}
|
319
|
+
interactive = extra_flags.get('interactive', True)
|
320
|
+
if interactive or self.items:
|
321
|
+
self._tab_control = pg.views.html.controls.TabControl(
|
322
|
+
[self._execution_item_tab(item) for item in self.items],
|
323
|
+
tab_position='left'
|
324
|
+
)
|
325
|
+
return self._tab_control.to_html()
|
326
|
+
return '(no tracked items)'
|
328
327
|
|
329
328
|
def _execution_item_tab(self, item: TracedItem) -> pg.views.html.controls.Tab:
|
330
329
|
if isinstance(item, ActionInvocation):
|
@@ -381,7 +380,8 @@ class ExecutionTrace(pg.Object, pg.views.html.HtmlTreeView.Extension):
|
|
381
380
|
)
|
382
381
|
elif isinstance(item, ExecutionTrace):
|
383
382
|
return pg.views.html.controls.Label(
|
384
|
-
item.name or 'Phase'
|
383
|
+
item.name or 'Phase',
|
384
|
+
tooltip=f'Execution phase {item.name!r}.'
|
385
385
|
)
|
386
386
|
else:
|
387
387
|
raise ValueError(f'Unsupported item type: {type(item)}')
|
@@ -420,21 +420,21 @@ class ExecutionTrace(pg.Object, pg.views.html.HtmlTreeView.Extension):
|
|
420
420
|
display: inline-block;
|
421
421
|
}
|
422
422
|
.badge.execution-time {
|
423
|
-
margin-left:
|
423
|
+
margin-left: 4px;
|
424
|
+
border-radius: 0px;
|
425
|
+
}
|
426
|
+
.execution-time.starting {
|
427
|
+
background-color: ghostwhite;
|
428
|
+
font-weight: normal;
|
424
429
|
}
|
425
430
|
.execution-time.running {
|
426
|
-
background-color:
|
431
|
+
background-color: ghostwhite;
|
427
432
|
font-weight: normal;
|
428
433
|
}
|
429
434
|
.execution-time.finished {
|
430
435
|
background-color: aliceblue;
|
431
436
|
font-weight: bold;
|
432
437
|
}
|
433
|
-
.badge.task-in-progress {
|
434
|
-
margin-left: 5px;
|
435
|
-
background-color: azure;
|
436
|
-
font-weight: bold;
|
437
|
-
}
|
438
438
|
"""
|
439
439
|
]
|
440
440
|
|
@@ -448,7 +448,7 @@ class ActionInvocation(pg.Object, pg.views.html.HtmlTreeView.Extension):
|
|
448
448
|
'The result of the action.'
|
449
449
|
] = None
|
450
450
|
|
451
|
-
|
451
|
+
metadata: Annotated[
|
452
452
|
dict[str, Any],
|
453
453
|
'The metadata returned by the action.'
|
454
454
|
] = {}
|
@@ -464,8 +464,7 @@ class ActionInvocation(pg.Object, pg.views.html.HtmlTreeView.Extension):
|
|
464
464
|
def _on_bound(self):
|
465
465
|
super()._on_bound()
|
466
466
|
self._current_phase = self.execution
|
467
|
-
self.
|
468
|
-
self._result_metadata_badge = None
|
467
|
+
self._tab_control = None
|
469
468
|
|
470
469
|
@property
|
471
470
|
def current_phase(self) -> ExecutionTrace:
|
@@ -520,31 +519,42 @@ class ActionInvocation(pg.Object, pg.views.html.HtmlTreeView.Extension):
|
|
520
519
|
"""Starts the execution of the action."""
|
521
520
|
self.execution.start()
|
522
521
|
|
523
|
-
def end(self, result: Any,
|
522
|
+
def end(self, result: Any, metadata: dict[str, Any]) -> None:
|
524
523
|
"""Ends the execution of the action with result and metadata."""
|
525
|
-
self.execution.stop()
|
526
524
|
self.rebind(
|
527
525
|
result=result,
|
528
|
-
|
526
|
+
metadata=metadata,
|
529
527
|
skip_notification=True,
|
530
528
|
raise_on_no_change=False
|
531
529
|
)
|
532
|
-
|
533
|
-
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
|
540
|
-
|
541
|
-
|
542
|
-
|
543
|
-
|
544
|
-
|
545
|
-
|
546
|
-
|
530
|
+
self.execution.stop()
|
531
|
+
if self._tab_control is not None:
|
532
|
+
if self.metadata:
|
533
|
+
self._tab_control.insert(
|
534
|
+
1,
|
535
|
+
pg.views.html.controls.Tab(
|
536
|
+
'metadata',
|
537
|
+
pg.view(
|
538
|
+
self.metadata,
|
539
|
+
collapse_level=None,
|
540
|
+
enable_summary_tooltip=False
|
541
|
+
),
|
542
|
+
name='metadata',
|
543
|
+
)
|
544
|
+
)
|
545
|
+
self._tab_control.insert(
|
546
|
+
1,
|
547
|
+
pg.views.html.controls.Tab(
|
548
|
+
'result',
|
549
|
+
pg.view(
|
550
|
+
self.result,
|
551
|
+
collapse_level=None,
|
552
|
+
enable_summary_tooltip=False
|
553
|
+
),
|
554
|
+
name='result',
|
555
|
+
),
|
547
556
|
)
|
557
|
+
self._tab_control.select(['metadata', 'result'])
|
548
558
|
|
549
559
|
#
|
550
560
|
# HTML views.
|
@@ -566,128 +576,88 @@ class ActionInvocation(pg.Object, pg.views.html.HtmlTreeView.Extension):
|
|
566
576
|
interactive = extra_flags.get('interactive', True)
|
567
577
|
if (isinstance(self.action, RootAction)
|
568
578
|
and self.execution.has_stopped
|
569
|
-
and len(self.execution
|
579
|
+
and len(self.execution) == 1):
|
570
580
|
return view.content(self.execution.items[0], extra_flags=extra_flags)
|
571
581
|
|
572
|
-
|
573
|
-
|
574
|
-
|
575
|
-
|
576
|
-
|
577
|
-
|
578
|
-
|
579
|
-
|
580
|
-
|
581
|
-
|
582
|
-
|
583
|
-
|
584
|
-
|
585
|
-
interactive=interactive,
|
582
|
+
tabs = []
|
583
|
+
if not isinstance(self.action, RootAction):
|
584
|
+
tabs.append(
|
585
|
+
pg.views.html.controls.Tab(
|
586
|
+
'action',
|
587
|
+
view.render( # pylint: disable=g-long-ternary
|
588
|
+
self.action,
|
589
|
+
collapse_level=None,
|
590
|
+
root_path=self.action.sym_path,
|
591
|
+
enable_summary_tooltip=False,
|
592
|
+
),
|
593
|
+
name='action',
|
594
|
+
)
|
586
595
|
)
|
587
|
-
|
588
|
-
|
589
|
-
|
590
|
-
|
591
|
-
|
592
|
-
|
593
|
-
|
594
|
-
|
595
|
-
|
596
|
-
|
597
|
-
|
598
|
-
label,
|
599
|
-
tooltip=tooltip,
|
600
|
-
css_classes=['invocation-result-metadata', css_class],
|
601
|
-
interactive=interactive,
|
596
|
+
if self.execution.has_stopped:
|
597
|
+
tabs.append(
|
598
|
+
pg.views.html.controls.Tab(
|
599
|
+
'result',
|
600
|
+
view.render(
|
601
|
+
self.result,
|
602
|
+
collapse_level=None,
|
603
|
+
enable_summary_tooltip=False
|
604
|
+
),
|
605
|
+
name='result'
|
606
|
+
)
|
602
607
|
)
|
608
|
+
if self.metadata:
|
609
|
+
tabs.append(
|
610
|
+
pg.views.html.controls.Tab(
|
611
|
+
'metadata',
|
612
|
+
view.render(
|
613
|
+
self.metadata,
|
614
|
+
collapse_level=None,
|
615
|
+
enable_summary_tooltip=False
|
616
|
+
),
|
617
|
+
name='metadata'
|
618
|
+
)
|
619
|
+
)
|
603
620
|
|
604
|
-
|
605
|
-
|
606
|
-
if interactive:
|
607
|
-
self._result_badge = result_badge
|
608
|
-
self._result_metadata_badge = result_metadata_badge
|
609
|
-
|
610
|
-
return pg.Html.element(
|
611
|
-
'div',
|
612
|
-
[
|
621
|
+
tabs.append(
|
622
|
+
pg.views.html.controls.Tab(
|
613
623
|
pg.Html.element(
|
614
|
-
'
|
624
|
+
'span',
|
615
625
|
[
|
616
|
-
|
617
|
-
|
626
|
+
'execution',
|
627
|
+
self.execution._execution_badge(interactive), # pylint: disable=protected-access
|
628
|
+
(
|
629
|
+
self.usage_summary.to_html( # pylint: disable=g-long-ternary
|
630
|
+
extra_flags=dict(as_badge=True)
|
631
|
+
)
|
632
|
+
if (interactive
|
633
|
+
or self.usage_summary.total.num_requests > 0)
|
634
|
+
else None
|
618
635
|
),
|
619
|
-
result_badge,
|
620
|
-
result_metadata_badge,
|
621
636
|
],
|
622
|
-
css_classes=['
|
637
|
+
css_classes=['execution-tab-title']
|
623
638
|
),
|
624
|
-
view.render(
|
625
|
-
|
626
|
-
name='action',
|
627
|
-
collapse_level=None,
|
628
|
-
root_path=self.action.sym_path,
|
629
|
-
css_classes='invocation-title',
|
630
|
-
enable_summary_tooltip=False,
|
631
|
-
) if not isinstance(self.action, RootAction) else None,
|
632
|
-
view.render(self.execution, name='execution'),
|
633
|
-
]
|
634
|
-
)
|
635
|
-
|
636
|
-
def _result_badge_label(self, result: Any) -> str:
|
637
|
-
label = pg.format(
|
638
|
-
result, python_format=True, verbose=False
|
639
|
-
)
|
640
|
-
if len(label) > 40:
|
641
|
-
if isinstance(result, str):
|
642
|
-
label = label[:40] + '...'
|
643
|
-
else:
|
644
|
-
label = f'{result.__class__.__name__}(...)'
|
645
|
-
return label
|
646
|
-
|
647
|
-
def _result_badge_tooltip(self, result: Any) -> pg.Html:
|
648
|
-
return typing.cast(
|
649
|
-
pg.Html,
|
650
|
-
pg.view(
|
651
|
-
result, name='result',
|
652
|
-
collapse_level=None,
|
653
|
-
enable_summary_tooltip=False,
|
654
|
-
enable_key_tooltip=False,
|
655
|
-
)
|
656
|
-
)
|
657
|
-
|
658
|
-
def _result_metadata_badge_tooltip(
|
659
|
-
self, result_metadata: dict[str, Any]
|
660
|
-
) -> pg.Html:
|
661
|
-
return typing.cast(
|
662
|
-
pg.Html,
|
663
|
-
pg.view(
|
664
|
-
result_metadata,
|
665
|
-
name='result_metadata',
|
666
|
-
collapse_level=None,
|
667
|
-
enable_summary_tooltip=False,
|
639
|
+
view.render(self.execution, extra_flags=extra_flags),
|
640
|
+
name='execution',
|
668
641
|
)
|
669
642
|
)
|
643
|
+
tab_control = pg.views.html.controls.TabControl(tabs)
|
644
|
+
# Select the tab following a priority: metadata, result, action, execution.
|
645
|
+
tab_control.select(['metadata', 'result', 'action', 'execution'])
|
646
|
+
if interactive:
|
647
|
+
self._tab_control = tab_control
|
648
|
+
return tab_control
|
670
649
|
|
671
650
|
@classmethod
|
672
651
|
def _html_tree_view_css_styles(cls) -> list[str]:
|
673
652
|
return super()._html_tree_view_css_styles() + [
|
674
653
|
"""
|
675
|
-
.
|
676
|
-
|
677
|
-
padding-bottom: 5px;
|
678
|
-
}
|
679
|
-
.invocation-badge-container > .label-container {
|
680
|
-
margin-right: 3px;
|
681
|
-
}
|
682
|
-
.invocation-result.ready {
|
683
|
-
background-color: lightcyan;
|
654
|
+
.execution-tab-title {
|
655
|
+
text-align: left;
|
684
656
|
}
|
685
|
-
.
|
686
|
-
|
687
|
-
|
688
|
-
|
689
|
-
background-color: aliceblue;
|
690
|
-
border: 0px solid white;
|
657
|
+
.execution-tab-title .usage-summary.label {
|
658
|
+
border-radius: 0px;
|
659
|
+
font-weight: normal;
|
660
|
+
color: #AAA;
|
691
661
|
}
|
692
662
|
"""
|
693
663
|
]
|
@@ -722,7 +692,7 @@ class Session(pg.Object, pg.views.html.HtmlTreeView.Extension):
|
|
722
692
|
def add_metadata(self, **kwargs: Any) -> None:
|
723
693
|
"""Adds metadata to the current invocation."""
|
724
694
|
with pg.notify_on_change(False):
|
725
|
-
self._current_action.
|
695
|
+
self._current_action.metadata.update(kwargs)
|
726
696
|
|
727
697
|
def phase(self, name: str) -> ContextManager[ExecutionTrace]:
|
728
698
|
"""Context manager for starting a new execution phase."""
|
@@ -745,11 +715,11 @@ class Session(pg.Object, pg.views.html.HtmlTreeView.Extension):
|
|
745
715
|
yield invocation
|
746
716
|
finally:
|
747
717
|
# Stop the execution of the current action.
|
748
|
-
self._current_action.end(action.result, action.
|
718
|
+
self._current_action.end(action.result, action.metadata)
|
749
719
|
self._current_action = parent_action
|
750
720
|
if parent_action is self.root:
|
751
721
|
parent_action.end(
|
752
|
-
result=action.result,
|
722
|
+
result=action.result, metadata=action.metadata,
|
753
723
|
)
|
754
724
|
|
755
725
|
@contextlib.contextmanager
|
@@ -73,7 +73,7 @@ class SessionTest(unittest.TestCase):
|
|
73
73
|
self.assertTrue(root.execution.has_stopped)
|
74
74
|
self.assertGreater(root.execution.elapse, 0)
|
75
75
|
self.assertEqual(root.result, 3)
|
76
|
-
self.assertEqual(root.
|
76
|
+
self.assertEqual(root.metadata, dict(note='foo'))
|
77
77
|
|
78
78
|
# The root space should have one action (foo), no queries, and no logs.
|
79
79
|
self.assertEqual(len(list(root.actions)), 1)
|
@@ -109,11 +109,11 @@ class SessionTest(unittest.TestCase):
|
|
109
109
|
self.assertIsInstance(bar_invocation, action_lib.ActionInvocation)
|
110
110
|
self.assertIsInstance(bar_invocation.action, Bar)
|
111
111
|
self.assertEqual(bar_invocation.result, 2)
|
112
|
-
self.assertEqual(bar_invocation.
|
112
|
+
self.assertEqual(bar_invocation.metadata, dict(note='bar'))
|
113
113
|
self.assertEqual(len(bar_invocation.execution.items), 2)
|
114
114
|
|
115
115
|
# Save to HTML
|
116
|
-
self.assertIn('
|
116
|
+
self.assertIn('result', session.to_html().content)
|
117
117
|
|
118
118
|
# Save session to JSON
|
119
119
|
json_str = session.to_json_str(save_ref_value=True)
|
@@ -465,6 +465,33 @@ class Experiment(lf.Component, pg.views.HtmlTreeView.Extension):
|
|
465
465
|
runner.run()
|
466
466
|
return runner.current_run
|
467
467
|
|
468
|
+
def run_preconfigured(
|
469
|
+
self,
|
470
|
+
root_dir: str | None = None,
|
471
|
+
id: str | None = None, # pylint: disable=redefined-builtin
|
472
|
+
**kwargs
|
473
|
+
) -> 'Run':
|
474
|
+
"""Runs the experiment with pre-configured kwargs from `cls.RUN_ARGS`.
|
475
|
+
|
476
|
+
This helper method allows users to config running arguments as a part of
|
477
|
+
the class.
|
478
|
+
|
479
|
+
Args:
|
480
|
+
root_dir: root directory of the experiment.
|
481
|
+
id: ID of the current run.
|
482
|
+
**kwargs: Keyword arguments to override the RUN_CONFIG.
|
483
|
+
|
484
|
+
Returns:
|
485
|
+
The current run.
|
486
|
+
"""
|
487
|
+
run_config = getattr(self, 'RUN_ARGS', {})
|
488
|
+
run_config.update(kwargs)
|
489
|
+
if root_dir is not None:
|
490
|
+
run_config['root_dir'] = root_dir
|
491
|
+
if id is not None:
|
492
|
+
run_config['id'] = id
|
493
|
+
return self.run(**run_config)
|
494
|
+
|
468
495
|
#
|
469
496
|
# HTML views.
|
470
497
|
#
|
@@ -39,6 +39,10 @@ def sample_inputs():
|
|
39
39
|
|
40
40
|
class MyEvaluation(Evaluation):
|
41
41
|
NAME = 'my_eval'
|
42
|
+
RUN_ARGS = dict(
|
43
|
+
runner='test'
|
44
|
+
)
|
45
|
+
|
42
46
|
replica_id: int = 0
|
43
47
|
inputs = sample_inputs()
|
44
48
|
metrics = [metrics_lib.Match()]
|
@@ -288,10 +292,17 @@ class RunnerTest(unittest.TestCase):
|
|
288
292
|
TestRunner
|
289
293
|
)
|
290
294
|
root_dir = os.path.join(tempfile.gettempdir(), 'my_eval')
|
295
|
+
|
296
|
+
# Test standard run.
|
291
297
|
MyEvaluation(replica_id=0).run(
|
292
298
|
root_dir, id='20241101_0', runner='test'
|
293
299
|
)
|
294
300
|
|
301
|
+
# Test run preconfigured.
|
302
|
+
MyEvaluation(replica_id=0).run_preconfigured(
|
303
|
+
root_dir=root_dir, id='20241101_1'
|
304
|
+
)
|
305
|
+
|
295
306
|
with self.assertRaisesRegex(
|
296
307
|
ValueError, 'Runner class must define a NAME constant'
|
297
308
|
):
|
langfun/core/llms/__init__.py
CHANGED
@@ -32,11 +32,12 @@ 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_0Exp
|
35
36
|
from langfun.core.llms.google_genai import GeminiExp_20241114
|
36
37
|
from langfun.core.llms.google_genai import GeminiExp_20241206
|
37
38
|
from langfun.core.llms.google_genai import GeminiFlash1_5
|
38
|
-
from langfun.core.llms.google_genai import GeminiPro
|
39
39
|
from langfun.core.llms.google_genai import GeminiPro1_5
|
40
|
+
from langfun.core.llms.google_genai import GeminiPro
|
40
41
|
from langfun.core.llms.google_genai import GeminiProVision
|
41
42
|
from langfun.core.llms.google_genai import Palm2
|
42
43
|
from langfun.core.llms.google_genai import Palm2_IT
|
@@ -121,6 +122,8 @@ from langfun.core.llms.groq import GroqWhisper_Large_v3
|
|
121
122
|
from langfun.core.llms.groq import GroqWhisper_Large_v3Turbo
|
122
123
|
|
123
124
|
from langfun.core.llms.vertexai import VertexAI
|
125
|
+
from langfun.core.llms.vertexai import VertexAIGemini2_0
|
126
|
+
from langfun.core.llms.vertexai import VertexAIGeminiFlash2_0Exp
|
124
127
|
from langfun.core.llms.vertexai import VertexAIGemini1_5
|
125
128
|
from langfun.core.llms.vertexai import VertexAIGeminiPro1_5
|
126
129
|
from langfun.core.llms.vertexai import VertexAIGeminiPro1_5_001
|
@@ -48,14 +48,15 @@ class GenAI(lf.LanguageModel):
|
|
48
48
|
|
49
49
|
model: Annotated[
|
50
50
|
Literal[
|
51
|
+
'gemini-2.0-flash-exp',
|
52
|
+
'gemini-exp-1206',
|
53
|
+
'gemini-exp-1114',
|
54
|
+
'gemini-1.5-pro-latest',
|
55
|
+
'gemini-1.5-flash-latest',
|
51
56
|
'gemini-pro',
|
52
57
|
'gemini-pro-vision',
|
53
58
|
'text-bison-001',
|
54
59
|
'chat-bison-001',
|
55
|
-
'gemini-1.5-pro-latest',
|
56
|
-
'gemini-1.5-flash-latest',
|
57
|
-
'gemini-exp-1114',
|
58
|
-
'gemini-exp-1206',
|
59
60
|
],
|
60
61
|
'Model name.',
|
61
62
|
]
|
@@ -308,6 +309,18 @@ _GOOGLE_GENAI_MODEL_HUB = _ModelHub()
|
|
308
309
|
#
|
309
310
|
|
310
311
|
|
312
|
+
class GeminiFlash2_0Exp(GenAI): # pylint: disable=invalid-name
|
313
|
+
"""Gemini Experimental model launched on 12/06/2024."""
|
314
|
+
|
315
|
+
model = 'gemini-2.0-flash-exp'
|
316
|
+
supported_modalities = (
|
317
|
+
vertexai.DOCUMENT_TYPES
|
318
|
+
+ vertexai.IMAGE_TYPES
|
319
|
+
+ vertexai.AUDIO_TYPES
|
320
|
+
+ vertexai.VIDEO_TYPES
|
321
|
+
)
|
322
|
+
|
323
|
+
|
311
324
|
class GeminiExp_20241206(GenAI): # pylint: disable=invalid-name
|
312
325
|
"""Gemini Experimental model launched on 12/06/2024."""
|
313
326
|
|
langfun/core/llms/vertexai.py
CHANGED
@@ -40,7 +40,7 @@ except ImportError:
|
|
40
40
|
|
41
41
|
# https://cloud.google.com/vertex-ai/generative-ai/pricing
|
42
42
|
# describes that the average number of characters per token is about 4.
|
43
|
-
|
43
|
+
AVGERAGE_CHARS_PER_TOKEN = 4
|
44
44
|
|
45
45
|
|
46
46
|
# Price in US dollars,
|
@@ -102,6 +102,18 @@ SUPPORTED_MODELS_AND_SETTINGS = {
|
|
102
102
|
cost_per_1k_input_chars=0.000125,
|
103
103
|
cost_per_1k_output_chars=0.000375,
|
104
104
|
),
|
105
|
+
# TODO(sharatsharat): Update costs when published
|
106
|
+
'gemini-exp-1206': pg.Dict(
|
107
|
+
rpm=20,
|
108
|
+
cost_per_1k_input_chars=0.000,
|
109
|
+
cost_per_1k_output_chars=0.000,
|
110
|
+
),
|
111
|
+
# TODO(sharatsharat): Update costs when published
|
112
|
+
'gemini-2.0-flash-exp': pg.Dict(
|
113
|
+
rpm=20,
|
114
|
+
cost_per_1k_input_chars=0.000,
|
115
|
+
cost_per_1k_output_chars=0.000,
|
116
|
+
),
|
105
117
|
# TODO(chengrun): Set a more appropriate rpm for endpoint.
|
106
118
|
'vertexai-endpoint': pg.Dict(
|
107
119
|
rpm=20,
|
@@ -215,7 +227,7 @@ class VertexAI(rest.REST):
|
|
215
227
|
return (
|
216
228
|
cost_per_1k_input_chars * num_input_tokens
|
217
229
|
+ cost_per_1k_output_chars * num_output_tokens
|
218
|
-
) *
|
230
|
+
) * AVGERAGE_CHARS_PER_TOKEN / 1000
|
219
231
|
|
220
232
|
@functools.cached_property
|
221
233
|
def _session(self):
|
@@ -389,6 +401,20 @@ DOCUMENT_TYPES = [
|
|
389
401
|
]
|
390
402
|
|
391
403
|
|
404
|
+
class VertexAIGemini2_0(VertexAI): # pylint: disable=invalid-name
|
405
|
+
"""Vertex AI Gemini 2.0 model."""
|
406
|
+
|
407
|
+
supported_modalities: pg.typing.List(str).freeze( # pytype: disable=invalid-annotation
|
408
|
+
DOCUMENT_TYPES + IMAGE_TYPES + AUDIO_TYPES + VIDEO_TYPES
|
409
|
+
)
|
410
|
+
|
411
|
+
|
412
|
+
class VertexAIGeminiFlash2_0Exp(VertexAI): # pylint: disable=invalid-name
|
413
|
+
"""Vertex AI Gemini 2.0 Flash model."""
|
414
|
+
|
415
|
+
model = 'gemini-2.0-flash-exp'
|
416
|
+
|
417
|
+
|
392
418
|
class VertexAIGemini1_5(VertexAI): # pylint: disable=invalid-name
|
393
419
|
"""Vertex AI Gemini 1.5 model."""
|
394
420
|
|
@@ -15,6 +15,7 @@
|
|
15
15
|
|
16
16
|
import contextlib
|
17
17
|
import functools
|
18
|
+
import time
|
18
19
|
from typing import Annotated, Any, Callable, Iterator, Type, Union
|
19
20
|
|
20
21
|
import langfun.core as lf
|
@@ -221,6 +222,7 @@ def query(
|
|
221
222
|
query_input = schema_lib.mark_missing(prompt)
|
222
223
|
|
223
224
|
with lf.track_usages() as usage_summary:
|
225
|
+
start_time = time.time()
|
224
226
|
if schema in (None, str):
|
225
227
|
# Query with natural language output.
|
226
228
|
output_message = lf.LangFunc.from_value(query_input, **kwargs)(
|
@@ -250,6 +252,7 @@ def query(
|
|
250
252
|
cache_seed=cache_seed,
|
251
253
|
skip_lm=skip_lm,
|
252
254
|
)
|
255
|
+
end_time = time.time()
|
253
256
|
|
254
257
|
def _result(message: lf.Message):
|
255
258
|
return message.text if schema in (None, str) else message.result
|
@@ -268,6 +271,8 @@ def query(
|
|
268
271
|
examples=pg.Ref(examples) if examples else [],
|
269
272
|
lm_response=lf.AIMessage(output_message.text),
|
270
273
|
usage_summary=usage_summary,
|
274
|
+
start_time=start_time,
|
275
|
+
end_time=end_time,
|
271
276
|
)
|
272
277
|
for i, (tracker, include_child_scopes) in enumerate(trackers):
|
273
278
|
if i == 0 or include_child_scopes:
|
@@ -384,6 +389,14 @@ class QueryInvocation(pg.Object, pg.views.HtmlTreeView.Extension):
|
|
384
389
|
lf.UsageSummary,
|
385
390
|
'Usage summary for `lf.query`.'
|
386
391
|
]
|
392
|
+
start_time: Annotated[
|
393
|
+
float,
|
394
|
+
'Start time of query.'
|
395
|
+
]
|
396
|
+
end_time: Annotated[
|
397
|
+
float,
|
398
|
+
'End time of query.'
|
399
|
+
]
|
387
400
|
|
388
401
|
@functools.cached_property
|
389
402
|
def lm_request(self) -> lf.Message:
|
@@ -393,6 +406,11 @@ class QueryInvocation(pg.Object, pg.views.HtmlTreeView.Extension):
|
|
393
406
|
def output(self) -> Any:
|
394
407
|
return query_output(self.lm_response, self.schema)
|
395
408
|
|
409
|
+
@property
|
410
|
+
def elapse(self) -> float:
|
411
|
+
"""Returns query elapse in seconds."""
|
412
|
+
return self.end_time - self.start_time
|
413
|
+
|
396
414
|
def _on_bound(self):
|
397
415
|
super()._on_bound()
|
398
416
|
self.__dict__.pop('lm_request', None)
|
@@ -404,6 +422,8 @@ class QueryInvocation(pg.Object, pg.views.HtmlTreeView.Extension):
|
|
404
422
|
view: pg.views.HtmlTreeView,
|
405
423
|
**kwargs: Any
|
406
424
|
) -> pg.Html | None:
|
425
|
+
kwargs.pop('title', None)
|
426
|
+
kwargs.pop('enable_summary_tooltip', None)
|
407
427
|
return view.summary(
|
408
428
|
value=self,
|
409
429
|
title=pg.Html.element(
|
@@ -423,11 +443,16 @@ class QueryInvocation(pg.Object, pg.views.HtmlTreeView.Extension):
|
|
423
443
|
),
|
424
444
|
css_classes=['query-invocation-lm']
|
425
445
|
),
|
446
|
+
pg.views.html.controls.Badge(
|
447
|
+
f'{int(self.elapse)} seconds',
|
448
|
+
css_classes=['query-invocation-time']
|
449
|
+
),
|
426
450
|
self.usage_summary.to_html(extra_flags=dict(as_badge=True))
|
427
451
|
],
|
428
452
|
css_classes=['query-invocation-title']
|
429
453
|
),
|
430
|
-
enable_summary_tooltip=False
|
454
|
+
enable_summary_tooltip=False,
|
455
|
+
**kwargs
|
431
456
|
)
|
432
457
|
|
433
458
|
def _html_tree_view_content(
|
@@ -441,14 +466,14 @@ class QueryInvocation(pg.Object, pg.views.HtmlTreeView.Extension):
|
|
441
466
|
'input',
|
442
467
|
pg.view(self.input, collapse_level=None),
|
443
468
|
),
|
444
|
-
pg.views.html.controls.Tab(
|
445
|
-
'schema',
|
446
|
-
pg.view(self.schema),
|
447
|
-
),
|
448
469
|
pg.views.html.controls.Tab(
|
449
470
|
'output',
|
450
471
|
pg.view(self.output, collapse_level=None),
|
451
472
|
),
|
473
|
+
pg.views.html.controls.Tab(
|
474
|
+
'schema',
|
475
|
+
pg.view(self.schema),
|
476
|
+
),
|
452
477
|
pg.views.html.controls.Tab(
|
453
478
|
'lm_request',
|
454
479
|
pg.view(
|
@@ -463,24 +488,34 @@ class QueryInvocation(pg.Object, pg.views.HtmlTreeView.Extension):
|
|
463
488
|
extra_flags=dict(include_message_metadata=False)
|
464
489
|
),
|
465
490
|
),
|
466
|
-
], tab_position='top').to_html()
|
491
|
+
], tab_position='top', selected=1).to_html()
|
467
492
|
|
468
493
|
@classmethod
|
469
494
|
def _html_tree_view_css_styles(cls) -> list[str]:
|
470
495
|
return super()._html_tree_view_css_styles() + [
|
471
496
|
"""
|
472
497
|
.query-invocation-title {
|
473
|
-
|
474
|
-
|
498
|
+
display: inline-block;
|
499
|
+
font-weight: normal;
|
475
500
|
}
|
476
501
|
.query-invocation-type-name {
|
477
|
-
|
478
|
-
color: #888;
|
502
|
+
color: #888;
|
479
503
|
}
|
480
504
|
.query-invocation-lm.badge {
|
481
|
-
|
482
|
-
|
483
|
-
|
505
|
+
margin-left: 5px;
|
506
|
+
margin-right: 5px;
|
507
|
+
color: white;
|
508
|
+
background-color: mediumslateblue;
|
509
|
+
}
|
510
|
+
.query-invocation-time.badge {
|
511
|
+
margin-left: 5px;
|
512
|
+
border-radius: 0px;
|
513
|
+
font-weight: bold;
|
514
|
+
background-color: aliceblue;
|
515
|
+
}
|
516
|
+
.query-invocation-title .usage-summary.label {
|
517
|
+
border-radius: 0px;
|
518
|
+
color: #AAA;
|
484
519
|
}
|
485
520
|
"""
|
486
521
|
]
|
@@ -996,6 +996,7 @@ class TrackQueriesTest(unittest.TestCase):
|
|
996
996
|
self.assertEqual(queries[1].schema.spec.cls, Activity)
|
997
997
|
self.assertTrue(pg.eq(queries[1].output, Activity(description='hi')))
|
998
998
|
self.assertIs(queries[1].lm, lm)
|
999
|
+
self.assertGreater(queries[0].elapse, 0)
|
999
1000
|
self.assertGreater(queries[0].usage_summary.total.total_tokens, 0)
|
1000
1001
|
self.assertGreater(queries[1].usage_summary.total.total_tokens, 0)
|
1001
1002
|
|
langfun/core/template.py
CHANGED
@@ -552,38 +552,33 @@ class Template(
|
|
552
552
|
)
|
553
553
|
|
554
554
|
def render_fields():
|
555
|
-
return
|
556
|
-
|
557
|
-
|
558
|
-
|
559
|
-
|
560
|
-
|
561
|
-
|
562
|
-
|
563
|
-
|
564
|
-
|
565
|
-
|
566
|
-
|
567
|
-
|
568
|
-
|
569
|
-
|
570
|
-
**view.get_passthrough_kwargs(
|
571
|
-
remove=['exclude_keys'],
|
572
|
-
**kwargs,
|
573
|
-
)
|
574
|
-
),
|
575
|
-
],
|
576
|
-
css_classes=['template-fields'],
|
555
|
+
return view.complex_value(
|
556
|
+
{k: v for k, v in self.sym_items()},
|
557
|
+
name='fields',
|
558
|
+
root_path=root_path,
|
559
|
+
parent=self,
|
560
|
+
exclude_keys=['template_str', 'clean'],
|
561
|
+
collapse_level=max(
|
562
|
+
collapse_template_vars_level, collapse_level
|
563
|
+
) if collapse_level is not None else None,
|
564
|
+
extra_flags=extra_flags,
|
565
|
+
debug=debug,
|
566
|
+
**view.get_passthrough_kwargs(
|
567
|
+
remove=['exclude_keys'],
|
568
|
+
**kwargs,
|
569
|
+
)
|
577
570
|
)
|
578
571
|
|
579
|
-
return pg.
|
580
|
-
|
581
|
-
|
572
|
+
return pg.views.html.controls.TabControl([
|
573
|
+
pg.views.html.controls.Tab(
|
574
|
+
'template_str',
|
582
575
|
render_template_str(),
|
576
|
+
),
|
577
|
+
pg.views.html.controls.Tab(
|
578
|
+
'variables',
|
583
579
|
render_fields(),
|
584
|
-
|
585
|
-
|
586
|
-
)
|
580
|
+
),
|
581
|
+
], selected=1)
|
587
582
|
|
588
583
|
@classmethod
|
589
584
|
def _html_tree_view_css_styles(cls) -> list[str]:
|
@@ -601,15 +596,6 @@ class Template(
|
|
601
596
|
background-color: #EEE;
|
602
597
|
color: #cc2986;
|
603
598
|
}
|
604
|
-
.template-fields {
|
605
|
-
margin: 0px 0px 5px 0px;
|
606
|
-
border: 1px solid #EEE;
|
607
|
-
padding: 5px;
|
608
|
-
}
|
609
|
-
.template-fields > legend {
|
610
|
-
font-size: 0.8em;
|
611
|
-
margin: 5px 0px 5px 0px;
|
612
|
-
}
|
613
599
|
"""
|
614
600
|
]
|
615
601
|
|
langfun/core/template_test.py
CHANGED
@@ -555,13 +555,6 @@ class TemplateRenderEventTest(unittest.TestCase):
|
|
555
555
|
|
556
556
|
class HtmlTest(unittest.TestCase):
|
557
557
|
|
558
|
-
def assert_html_content(self, html, expected):
|
559
|
-
expected = inspect.cleandoc(expected).strip()
|
560
|
-
actual = html.content.strip()
|
561
|
-
if actual != expected:
|
562
|
-
print(actual)
|
563
|
-
self.assertEqual(actual, expected)
|
564
|
-
|
565
558
|
def test_html(self):
|
566
559
|
|
567
560
|
class Foo(Template):
|
@@ -594,36 +587,23 @@ class HtmlTest(unittest.TestCase):
|
|
594
587
|
background-color: #EEE;
|
595
588
|
color: #cc2986;
|
596
589
|
}
|
597
|
-
.template-fields {
|
598
|
-
margin: 0px 0px 5px 0px;
|
599
|
-
border: 1px solid #EEE;
|
600
|
-
padding: 5px;
|
601
|
-
}
|
602
|
-
.template-fields > legend {
|
603
|
-
font-size: 0.8em;
|
604
|
-
margin: 5px 0px 5px 0px;
|
605
|
-
}
|
606
590
|
"""
|
607
591
|
),
|
608
592
|
Foo(x=1, y=2).to_html().style_section,
|
609
593
|
)
|
610
|
-
self.
|
594
|
+
self.assertIn(
|
595
|
+
'template-str',
|
611
596
|
Foo(x=Bar('{{y}} + {{z}}'), y=1).to_html(
|
612
597
|
enable_summary_tooltip=False,
|
613
|
-
),
|
614
|
-
"""
|
615
|
-
<details open class="pyglove foo lf-template"><summary><div class="summary-title lf-template">Foo(...)</div></summary><div class="complex_value"><div class="template-str"><span>{{x}} + {{y}} = ?</span></div><fieldset class="template-fields"><legend>Template Variables</legend><div class="complex-value foo"><details class="pyglove bar lf-template"><summary><div class="summary-name lf-template">x<span class="tooltip lf-template">x</span></div><div class="summary-title lf-template">Bar(...)</div></summary><div class="complex_value"><div class="template-str"><span>{{y}} + {{z}}</span></div><fieldset class="template-fields"><legend>Template Variables</legend><div class="complex-value bar"><details open class="pyglove contextual-attribute"><summary><div class="summary-name">y<span class="tooltip">x.y</span></div><div class="summary-title">ContextualAttribute(...)</div></summary><span class="simple-value int">1</span></details><details open class="pyglove contextual-attribute"><summary><div class="summary-name">z<span class="tooltip">x.z</span></div><div class="summary-title">ContextualAttribute(...)</div></summary><div class="unavailable-contextual">(not available)</div></details></div></fieldset></div></details><details open class="pyglove int"><summary><div class="summary-name">y<span class="tooltip">y</span></div><div class="summary-title">int</div></summary><span class="simple-value int">1</span></details></div></fieldset></div></details>
|
616
|
-
"""
|
598
|
+
).content,
|
617
599
|
)
|
618
|
-
self.
|
600
|
+
self.assertIn(
|
601
|
+
'template-str',
|
619
602
|
Foo(x=Bar('{{y}} + {{z}}'), y=1).to_html(
|
620
603
|
enable_summary_tooltip=False,
|
621
604
|
collapse_level=0,
|
622
605
|
key_style='label',
|
623
|
-
),
|
624
|
-
"""
|
625
|
-
<details class="pyglove foo lf-template"><summary><div class="summary-title lf-template">Foo(...)</div></summary><div class="complex_value"><div class="template-str"><span>{{x}} + {{y}} = ?</span></div><fieldset class="template-fields"><legend>Template Variables</legend><div class="complex-value foo"><table><tr><td><span class="object-key str">x</span><span class="tooltip">x</span></td><td><details class="pyglove bar lf-template"><summary><div class="summary-title lf-template">Bar(...)</div></summary><div class="complex_value"><div class="template-str"><span>{{y}} + {{z}}</span></div><fieldset class="template-fields"><legend>Template Variables</legend><div class="complex-value bar"><table><tr><td><span class="object-key str">y</span><span class="tooltip">x.y</span></td><td><details open class="pyglove contextual-attribute"><summary><div class="summary-title">ContextualAttribute(...)</div></summary><span class="simple-value int">1</span></details></td></tr><tr><td><span class="object-key str">z</span><span class="tooltip">x.z</span></td><td><details open class="pyglove contextual-attribute"><summary><div class="summary-title">ContextualAttribute(...)</div></summary><div class="unavailable-contextual">(not available)</div></details></td></tr></table></div></fieldset></div></details></td></tr><tr><td><span class="object-key str">y</span><span class="tooltip">y</span></td><td><span class="simple-value int">1</span></td></tr></table></div></fieldset></div></details>
|
626
|
-
"""
|
606
|
+
).content,
|
627
607
|
)
|
628
608
|
|
629
609
|
|
@@ -25,15 +25,15 @@ langfun/core/sampling.py,sha256=SCnS5PFJWNVxSKvSkSCNRUmruvScun8UcNN4gafuXcw,5866
|
|
25
25
|
langfun/core/sampling_test.py,sha256=U7PANpMsl9E_pa4_Y4FzesSjcwg-u-LKHGCWSgv-8FY,3663
|
26
26
|
langfun/core/subscription.py,sha256=euawEuSZP-BHydaT-AQpfYFL0m5pWPGcW0upFhrojqc,10930
|
27
27
|
langfun/core/subscription_test.py,sha256=Y4ZdbZEwm83YNZBxHff0QR4QUa4rdaNXA3_jfIcArBo,8717
|
28
|
-
langfun/core/template.py,sha256=
|
29
|
-
langfun/core/template_test.py,sha256=
|
28
|
+
langfun/core/template.py,sha256=jNhYSrbLIn9kZOa03w5QZbyjgfnzJzE_ZrrMvvWY4t4,24929
|
29
|
+
langfun/core/template_test.py,sha256=g7x4mgNIAXEEj-4W1D5whGfl5YikLEQoylKPzaeDomk,17069
|
30
30
|
langfun/core/text_formatting.py,sha256=d7t9vaY6aCn1dkfkikpNYnBy5E_i93vHbfyDWFclGZU,5284
|
31
31
|
langfun/core/text_formatting_test.py,sha256=ck0Xzdd4YF4CtCUj7VE0GybfbAyKQ8p3xkM1FBGrqIk,2096
|
32
32
|
langfun/core/agentic/__init__.py,sha256=ndoDX0sAYsa3eVdXuu6nB-a-BH5TaK3urW6zAaFiyVs,1110
|
33
|
-
langfun/core/agentic/action.py,sha256=
|
33
|
+
langfun/core/agentic/action.py,sha256=yW5-2NRHIrQmmQEYmL83aIdSwaRfUez9mqCbME_aBWQ,25391
|
34
34
|
langfun/core/agentic/action_eval.py,sha256=ZtjTh34S7XPIUqandQ0YwAtzw-S7ofuZ7rRXnRbUMdQ,4424
|
35
35
|
langfun/core/agentic/action_eval_test.py,sha256=tRUkWmOE9p0rpNOq19xAY2oDEnYsEEykjg6sUpAwJk0,2832
|
36
|
-
langfun/core/agentic/action_test.py,sha256=
|
36
|
+
langfun/core/agentic/action_test.py,sha256=Gu7P5XQvzqbKawn2jjyTpWaARzzhzO04KkC1TuBnUnw,4612
|
37
37
|
langfun/core/coding/__init__.py,sha256=5utju_fwEsImaiftx4oXKl9FAM8p281k8-Esdh_-m1w,835
|
38
38
|
langfun/core/coding/python/__init__.py,sha256=MJ-vubliz-ebrZH3OBRKBwMi0S9-FrhGCp8YQLR6_I4,1776
|
39
39
|
langfun/core/coding/python/correction.py,sha256=WiBdoScL-6C___iA3Tg3vizuYtJWI-_4wy9zcMfVpj8,7020
|
@@ -64,8 +64,8 @@ langfun/core/eval/v2/evaluation.py,sha256=h_AWRUSKhEs-bHLBgqo-GeBYXluD5bPbAqypRW
|
|
64
64
|
langfun/core/eval/v2/evaluation_test.py,sha256=hh6L2HhQPQ6NBv1pXKcNkYraNcV9MLuJ--69t9jbmaI,5846
|
65
65
|
langfun/core/eval/v2/example.py,sha256=fURrvdNmMsVMqoEErcsmLmC6Xq3ny16dYsnLH8HVlcY,9626
|
66
66
|
langfun/core/eval/v2/example_test.py,sha256=WcJmU7IQQXvjFia63mokySC4CqxzVL9Wso1sC5F0YK8,3032
|
67
|
-
langfun/core/eval/v2/experiment.py,sha256=
|
68
|
-
langfun/core/eval/v2/experiment_test.py,sha256=
|
67
|
+
langfun/core/eval/v2/experiment.py,sha256=0JBGckJ93aqSdffpJPDVPy_I5T2BXscghTxiglHzJWo,29556
|
68
|
+
langfun/core/eval/v2/experiment_test.py,sha256=zSMHYqC9cA0k61U71pCSYTAJ6yK2_b6Dml5btc-bKzQ,9133
|
69
69
|
langfun/core/eval/v2/metric_values.py,sha256=_B905bC-jxrYPLSEcP2M8MaHZOVMz_bVrUw8YC4arCE,4660
|
70
70
|
langfun/core/eval/v2/metric_values_test.py,sha256=ab2oF_HsIwrSy459108ggyjgefHSPn8UVILR4dRwx14,2634
|
71
71
|
langfun/core/eval/v2/metrics.py,sha256=bl8i6u-ZHRBz4hAc3LzsZ2Dc7ZRQcuTYeUhhH-GxfF0,10628
|
@@ -79,14 +79,14 @@ langfun/core/eval/v2/reporting_test.py,sha256=JxffbUPWInUyLjo-AQVFrllga884Mdfm05
|
|
79
79
|
langfun/core/eval/v2/runners.py,sha256=kP6ZEg9L8M7fK03tOZYGqIjTKUzoJn8Hz_LXS7btFPQ,14335
|
80
80
|
langfun/core/eval/v2/runners_test.py,sha256=UeiUNygux_U6iGVG18rhp68ZE4hoWeoT6XsXvSjxNQg,11620
|
81
81
|
langfun/core/eval/v2/test_helper.py,sha256=pDpZTBnWRR5xjJv3Uy3NWEzArqlL8FTMOgeR4C53F5M,2348
|
82
|
-
langfun/core/llms/__init__.py,sha256=
|
82
|
+
langfun/core/llms/__init__.py,sha256=lWXKjGHv66ShG7AE_Bc4QM7SDTxJdfoQMn3PF0lr0sU,6461
|
83
83
|
langfun/core/llms/anthropic.py,sha256=afKZmdiLcosS_UEBlB8WKyf1K-zeXgwtPAx6ofg2Gww,13989
|
84
84
|
langfun/core/llms/anthropic_test.py,sha256=-2U4kc_pgBM7wqxu8RuxzyHPGww1EAWqKUvN4PW8Btw,8058
|
85
85
|
langfun/core/llms/compositional.py,sha256=csW_FLlgL-tpeyCOTVvfUQkMa_zCN5Y2I-YbSNuK27U,2872
|
86
86
|
langfun/core/llms/compositional_test.py,sha256=4eTnOer-DncRKGaIJW2ZQQMLnt5r2R0UIx_DYOvGAQo,2027
|
87
87
|
langfun/core/llms/fake.py,sha256=gCHBYBLvBCsC78HI1hpoqXCS-p1FMTgY1P1qh_sGBPk,3070
|
88
88
|
langfun/core/llms/fake_test.py,sha256=2h13qkwEz_JR0mtUDPxdAhQo7MueXaFSwsD2DIRDW9g,7653
|
89
|
-
langfun/core/llms/google_genai.py,sha256=
|
89
|
+
langfun/core/llms/google_genai.py,sha256=AAYOsSyeNIfHduIL9ZBzLhA8_acZUDMzHhS7AwUbOlM,11603
|
90
90
|
langfun/core/llms/google_genai_test.py,sha256=zw14sgWmk0P_irHyb7vpPy1WAuLEE0PmyfiFElu03sA,7686
|
91
91
|
langfun/core/llms/groq.py,sha256=dCnR3eAECEKuKKAAj-PDTs8NRHl6CQPdf57m1f6a79U,10312
|
92
92
|
langfun/core/llms/groq_test.py,sha256=GYF_Qtq5S1H1TrKH38t6_lkdroqT7v-joYLDKnmS9e0,5274
|
@@ -96,7 +96,7 @@ langfun/core/llms/openai.py,sha256=l49v6RubfInvV0iG114AymTKNogTX4u4N-UFCeSgIxw,2
|
|
96
96
|
langfun/core/llms/openai_test.py,sha256=kOWa1nf-nJvtYY10REUw5wojh3ZgfU8tRaCZ8wUgJbA,16623
|
97
97
|
langfun/core/llms/rest.py,sha256=sWbYUV8S3SuOg9giq7xwD-xDRfaF7NP_ig7bI52-Rj4,3442
|
98
98
|
langfun/core/llms/rest_test.py,sha256=NZ3Nf0XQVpT9kLP5cBVo_yBHLI7vWTYhWQxYEJVMGs4,3472
|
99
|
-
langfun/core/llms/vertexai.py,sha256=
|
99
|
+
langfun/core/llms/vertexai.py,sha256=adUTByiuiTHBQ31tM_EXPUWIyUwo3zqyYIe9UILAFDE,14981
|
100
100
|
langfun/core/llms/vertexai_test.py,sha256=ffcA5yPecnQy_rhkuYAw_6o1iLW8AR8FgswmHt6aAys,6725
|
101
101
|
langfun/core/llms/cache/__init__.py,sha256=QAo3InUMDM_YpteNnVCSejI4zOsnjSMWKJKzkb3VY64,993
|
102
102
|
langfun/core/llms/cache/base.py,sha256=rt3zwmyw0y9jsSGW-ZbV1vAfLxQ7_3AVk0l2EySlse4,3918
|
@@ -129,8 +129,8 @@ langfun/core/structured/mapping.py,sha256=vLKH79UT-j0qkQdvqlQBO7SkXXuM-yr2Idm8_H
|
|
129
129
|
langfun/core/structured/mapping_test.py,sha256=bHm2ZCXBITq_G8Lvw_olFHeUUc4s_lGXZm9v9JhoPB4,9630
|
130
130
|
langfun/core/structured/parsing.py,sha256=D58wBWOC6r6DCJNychCDkiHPrsy1XJfBDCDDZtug00k,11765
|
131
131
|
langfun/core/structured/parsing_test.py,sha256=i0i090FVgM8ngGqYjds0hjEm1v7q4gv18k-z1kaNr7E,21467
|
132
|
-
langfun/core/structured/prompting.py,sha256=
|
133
|
-
langfun/core/structured/prompting_test.py,sha256=
|
132
|
+
langfun/core/structured/prompting.py,sha256=ceZQgK00rlnDxFEPKq4O61zJs6u-W_mggT02bODqBSg,17522
|
133
|
+
langfun/core/structured/prompting_test.py,sha256=fHJuBli4dryQIrg_HmU7gMWSIOzHuYM_4xT3m84haGs,29765
|
134
134
|
langfun/core/structured/schema.py,sha256=_T8WIDdpvWXlZVPLVgKYH9TvoM9gK11m3f0b2nImQRM,28190
|
135
135
|
langfun/core/structured/schema_generation.py,sha256=U3nRQsqmMZg_qIVDh2fiY3K4JLfsAL1LcKzIFP1iXFg,5316
|
136
136
|
langfun/core/structured/schema_generation_test.py,sha256=RM9s71kMNg2jTePwInkiW9fK1ACN37eyPeF8OII-0zw,2950
|
@@ -148,8 +148,8 @@ langfun/core/templates/demonstration.py,sha256=vCrgYubdZM5Umqcgp8NUVGXgr4P_c-fik
|
|
148
148
|
langfun/core/templates/demonstration_test.py,sha256=SafcDQ0WgI7pw05EmPI2S4v1t3ABKzup8jReCljHeK4,2162
|
149
149
|
langfun/core/templates/selfplay.py,sha256=yhgrJbiYwq47TgzThmHrDQTF4nDrTI09CWGhuQPNv-s,2273
|
150
150
|
langfun/core/templates/selfplay_test.py,sha256=Ot__1P1M8oJfoTp-M9-PQ6HUXqZKyMwvZ5f7yQ3yfyM,2326
|
151
|
-
langfun-0.1.2.
|
152
|
-
langfun-0.1.2.
|
153
|
-
langfun-0.1.2.
|
154
|
-
langfun-0.1.2.
|
155
|
-
langfun-0.1.2.
|
151
|
+
langfun-0.1.2.dev202412140804.dist-info/LICENSE,sha256=WNHhf_5RCaeuKWyq_K39vmp9F28LxKsB4SpomwSZ2L0,11357
|
152
|
+
langfun-0.1.2.dev202412140804.dist-info/METADATA,sha256=q58cOyfw1yxxacgXgp5nPwnh4cUHuPzJmgD33YE1Ro4,8281
|
153
|
+
langfun-0.1.2.dev202412140804.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
|
154
|
+
langfun-0.1.2.dev202412140804.dist-info/top_level.txt,sha256=RhlEkHxs1qtzmmtWSwYoLVJAc1YrbPtxQ52uh8Z9VvY,8
|
155
|
+
langfun-0.1.2.dev202412140804.dist-info/RECORD,,
|
File without changes
|
File without changes
|
{langfun-0.1.2.dev202412110804.dist-info → langfun-0.1.2.dev202412140804.dist-info}/top_level.txt
RENAMED
File without changes
|