langfun 0.1.2.dev202504270803__py3-none-any.whl → 0.1.2.dev202504290805__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.
Potentially problematic release.
This version of langfun might be problematic. Click here for more details.
- langfun/core/agentic/action.py +253 -105
- langfun/core/agentic/action_eval.py +4 -2
- langfun/core/agentic/action_test.py +173 -47
- langfun/core/structured/schema.py +5 -0
- langfun/core/structured/schema_test.py +13 -0
- {langfun-0.1.2.dev202504270803.dist-info → langfun-0.1.2.dev202504290805.dist-info}/METADATA +29 -6
- {langfun-0.1.2.dev202504270803.dist-info → langfun-0.1.2.dev202504290805.dist-info}/RECORD +10 -10
- {langfun-0.1.2.dev202504270803.dist-info → langfun-0.1.2.dev202504290805.dist-info}/WHEEL +1 -1
- {langfun-0.1.2.dev202504270803.dist-info → langfun-0.1.2.dev202504290805.dist-info}/licenses/LICENSE +0 -0
- {langfun-0.1.2.dev202504270803.dist-info → langfun-0.1.2.dev202504290805.dist-info}/top_level.txt +0 -0
langfun/core/agentic/action.py
CHANGED
@@ -15,6 +15,7 @@
|
|
15
15
|
|
16
16
|
import abc
|
17
17
|
import contextlib
|
18
|
+
import functools
|
18
19
|
import threading
|
19
20
|
import time
|
20
21
|
import typing
|
@@ -31,8 +32,7 @@ class Action(pg.Object):
|
|
31
32
|
def _on_bound(self):
|
32
33
|
super()._on_bound()
|
33
34
|
self._session = None
|
34
|
-
self.
|
35
|
-
self._metadata = {}
|
35
|
+
self._invocation: ActionInvocation | None = None
|
36
36
|
|
37
37
|
@property
|
38
38
|
def session(self) -> Optional['Session']:
|
@@ -42,12 +42,12 @@ class Action(pg.Object):
|
|
42
42
|
@property
|
43
43
|
def result(self) -> Any:
|
44
44
|
"""Returns the result of the action."""
|
45
|
-
return self.
|
45
|
+
return self._invocation.result if self._invocation else None
|
46
46
|
|
47
47
|
@property
|
48
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._invocation.metadata if self._invocation else None
|
51
51
|
|
52
52
|
def __call__(
|
53
53
|
self,
|
@@ -58,31 +58,57 @@ class Action(pg.Object):
|
|
58
58
|
**kwargs
|
59
59
|
) -> Any:
|
60
60
|
"""Executes the action."""
|
61
|
-
|
62
|
-
if new_session:
|
61
|
+
if session is None:
|
63
62
|
session = Session()
|
64
63
|
if show_progress:
|
65
64
|
lf.console.display(pg.view(session, name='agent_session'))
|
66
65
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
result = self.call(session=session, verbose=verbose, **kwargs)
|
66
|
+
# For the top-level action, we store the session in the metadata.
|
67
|
+
self._session = session
|
68
|
+
else:
|
69
|
+
self._session = None
|
72
70
|
|
71
|
+
with session.track_action(self) as invocation:
|
73
72
|
if verbose:
|
74
|
-
session.info(
|
75
|
-
f'Action {self.__class__.__name__} completed successfully.',
|
76
|
-
keep=False,
|
77
|
-
result=result
|
78
|
-
)
|
73
|
+
session.info('Action execution started.', keep=False, action=self)
|
79
74
|
|
80
|
-
|
81
|
-
|
82
|
-
self.
|
83
|
-
|
84
|
-
|
85
|
-
|
75
|
+
try:
|
76
|
+
result = self.call(session=session, verbose=verbose, **kwargs)
|
77
|
+
self._invocation.end(result)
|
78
|
+
if verbose:
|
79
|
+
session.info(
|
80
|
+
(
|
81
|
+
f'Action execution succeeded in '
|
82
|
+
f'{self._invocation.execution.elapse:.2f} seconds.'
|
83
|
+
),
|
84
|
+
keep=False,
|
85
|
+
result=result
|
86
|
+
)
|
87
|
+
except BaseException as e:
|
88
|
+
error = pg.utils.ErrorInfo.from_exception(e)
|
89
|
+
self._invocation.end(result=None, error=error)
|
90
|
+
if invocation.parent_action is session.root:
|
91
|
+
session.error(
|
92
|
+
(
|
93
|
+
f'Top-level action execution failed in '
|
94
|
+
f'{self._invocation.execution.elapse:.2f} seconds.'
|
95
|
+
),
|
96
|
+
keep=True,
|
97
|
+
action=self,
|
98
|
+
error=error
|
99
|
+
)
|
100
|
+
else:
|
101
|
+
session.warning(
|
102
|
+
(
|
103
|
+
f'Action execution failed in '
|
104
|
+
f'{self._invocation.execution.elapse:.2f} seconds.'
|
105
|
+
),
|
106
|
+
keep=False,
|
107
|
+
action=self,
|
108
|
+
error=error
|
109
|
+
)
|
110
|
+
raise
|
111
|
+
return result
|
86
112
|
|
87
113
|
@abc.abstractmethod
|
88
114
|
def call(self, session: 'Session', **kwargs) -> Any:
|
@@ -146,6 +172,38 @@ class ExecutionTrace(pg.Object, pg.views.html.HtmlTreeView.Extension):
|
|
146
172
|
self._tab_control = None
|
147
173
|
self._time_badge = None
|
148
174
|
|
175
|
+
def _on_parent_change(self, *args, **kwargs):
|
176
|
+
super()._on_parent_change(*args, **kwargs)
|
177
|
+
self.__dict__.pop('id', None)
|
178
|
+
|
179
|
+
def indexof(self, item: TracedItem, count_item_cls: Type[Any]) -> int:
|
180
|
+
"""Returns the index of the child items of given type."""
|
181
|
+
pos = 0
|
182
|
+
for x in self._iter_children(count_item_cls):
|
183
|
+
if x is item:
|
184
|
+
return pos
|
185
|
+
pos += 1
|
186
|
+
return -1
|
187
|
+
|
188
|
+
@functools.cached_property
|
189
|
+
def id(self) -> str:
|
190
|
+
parent = self.sym_parent
|
191
|
+
if isinstance(parent, ActionInvocation):
|
192
|
+
# Current execution trace is the body of an action.
|
193
|
+
return parent.id
|
194
|
+
elif isinstance(parent, pg.List):
|
195
|
+
container = parent.sym_parent
|
196
|
+
if isinstance(container, ExecutionTrace):
|
197
|
+
# Current execution trace is a phase.
|
198
|
+
group_id = (
|
199
|
+
self.name or f'g{container.indexof(self, ExecutionTrace) + 1}'
|
200
|
+
)
|
201
|
+
return f'{container.id}/{group_id}'
|
202
|
+
elif isinstance(container, ParallelExecutions):
|
203
|
+
# Current execution trace is a parallel branch.
|
204
|
+
return f'{container.id}/b{self.sym_path.key + 1}'
|
205
|
+
return ''
|
206
|
+
|
149
207
|
def reset(self) -> None:
|
150
208
|
"""Resets the execution trace."""
|
151
209
|
self.rebind(items=[], skip_notification=True, raise_on_no_change=False)
|
@@ -194,58 +252,59 @@ class ExecutionTrace(pg.Object, pg.views.html.HtmlTreeView.Extension):
|
|
194
252
|
@property
|
195
253
|
def queries(self) -> list[lf_structured.QueryInvocation]:
|
196
254
|
"""Returns queries from the sequence."""
|
197
|
-
return self.
|
255
|
+
return list(self._iter_children(lf_structured.QueryInvocation))
|
198
256
|
|
199
257
|
@property
|
200
258
|
def actions(self) -> list['ActionInvocation']:
|
201
259
|
"""Returns action invocations from the sequence."""
|
202
|
-
return self.
|
260
|
+
return list(self._iter_children(ActionInvocation))
|
203
261
|
|
204
262
|
@property
|
205
263
|
def logs(self) -> list[lf.logging.LogEntry]:
|
206
264
|
"""Returns logs from the sequence."""
|
207
|
-
return self.
|
265
|
+
return list(self._iter_children(lf.logging.LogEntry))
|
208
266
|
|
209
267
|
@property
|
210
268
|
def all_queries(self) -> list[lf_structured.QueryInvocation]:
|
211
269
|
"""Returns all queries from current trace and its child execution items."""
|
212
|
-
return self.
|
270
|
+
return list(self._iter_subtree(lf_structured.QueryInvocation))
|
213
271
|
|
214
272
|
@property
|
215
273
|
def all_actions(self) -> list['ActionInvocation']:
|
216
274
|
"""Returns all actions from current trace and its child execution items."""
|
217
|
-
return self.
|
275
|
+
return list(self._iter_subtree(ActionInvocation))
|
218
276
|
|
219
277
|
@property
|
220
278
|
def all_logs(self) -> list[lf.logging.LogEntry]:
|
221
279
|
"""Returns all logs from current trace and its child execution items."""
|
222
|
-
return self.
|
280
|
+
return list(self._iter_subtree(lf.logging.LogEntry))
|
223
281
|
|
224
|
-
def
|
225
|
-
child_items = []
|
282
|
+
def _iter_children(self, item_cls: Type[Any]) -> Iterator[TracedItem]:
|
226
283
|
for item in self.items:
|
227
284
|
if isinstance(item, item_cls):
|
228
|
-
|
285
|
+
yield item
|
229
286
|
elif isinstance(item, ExecutionTrace):
|
230
|
-
|
287
|
+
for x in item._iter_children(item_cls): # pylint: disable=protected-access
|
288
|
+
yield x
|
231
289
|
elif isinstance(item, ParallelExecutions):
|
232
290
|
for branch in item.branches:
|
233
|
-
|
234
|
-
|
291
|
+
for x in branch._iter_children(item_cls): # pylint: disable=protected-access
|
292
|
+
yield x
|
235
293
|
|
236
|
-
def
|
237
|
-
child_items = []
|
294
|
+
def _iter_subtree(self, item_cls: Type[Any]) -> Iterator[TracedItem]:
|
238
295
|
for item in self.items:
|
239
296
|
if isinstance(item, item_cls):
|
240
|
-
|
297
|
+
yield item
|
241
298
|
if isinstance(item, ActionInvocation):
|
242
|
-
|
299
|
+
for x in item.execution._iter_subtree(item_cls): # pylint: disable=protected-access
|
300
|
+
yield x
|
243
301
|
elif isinstance(item, ExecutionTrace):
|
244
|
-
|
302
|
+
for x in item._iter_subtree(item_cls): # pylint: disable=protected-access
|
303
|
+
yield x
|
245
304
|
elif isinstance(item, ParallelExecutions):
|
246
305
|
for branch in item.branches:
|
247
|
-
|
248
|
-
|
306
|
+
for x in branch._iter_subtree(item_cls): # pylint: disable=protected-access
|
307
|
+
yield x
|
249
308
|
|
250
309
|
def append(self, item: TracedItem) -> None:
|
251
310
|
"""Appends an item to the sequence."""
|
@@ -359,7 +418,7 @@ class ExecutionTrace(pg.Object, pg.views.html.HtmlTreeView.Extension):
|
|
359
418
|
elif isinstance(item, lf_structured.QueryInvocation):
|
360
419
|
css_class = 'query'
|
361
420
|
elif isinstance(item, lf.logging.LogEntry):
|
362
|
-
css_class = 'log'
|
421
|
+
css_class = f'log-{item.level}'
|
363
422
|
elif isinstance(item, ExecutionTrace):
|
364
423
|
css_class = 'phase'
|
365
424
|
elif isinstance(item, ParallelExecutions):
|
@@ -379,13 +438,7 @@ class ExecutionTrace(pg.Object, pg.views.html.HtmlTreeView.Extension):
|
|
379
438
|
if isinstance(item, ActionInvocation):
|
380
439
|
return pg.views.html.controls.Label(
|
381
440
|
item.action.__class__.__name__,
|
382
|
-
tooltip=
|
383
|
-
item.action,
|
384
|
-
verbose=False,
|
385
|
-
hide_default_values=True,
|
386
|
-
max_str_len=80,
|
387
|
-
max_bytes_len=20,
|
388
|
-
),
|
441
|
+
tooltip=f'[{item.id}] Action invocation',
|
389
442
|
)
|
390
443
|
elif isinstance(item, lf_structured.QueryInvocation):
|
391
444
|
schema_title = 'str'
|
@@ -393,30 +446,22 @@ class ExecutionTrace(pg.Object, pg.views.html.HtmlTreeView.Extension):
|
|
393
446
|
schema_title = lf_structured.annotation(item.schema.spec)
|
394
447
|
return pg.views.html.controls.Label(
|
395
448
|
schema_title,
|
396
|
-
tooltip=
|
397
|
-
pg.format(
|
398
|
-
item.input,
|
399
|
-
verbose=False,
|
400
|
-
hide_default_values=True,
|
401
|
-
max_str_len=80,
|
402
|
-
max_bytes_len=20,
|
403
|
-
)
|
404
|
-
),
|
449
|
+
tooltip=f'[{item.id}] lf.Query invocation'
|
405
450
|
)
|
406
451
|
elif isinstance(item, lf.logging.LogEntry):
|
407
452
|
return pg.views.html.controls.Label(
|
408
|
-
|
453
|
+
item.level.title(),
|
409
454
|
tooltip=item.message,
|
410
455
|
)
|
411
456
|
elif isinstance(item, ExecutionTrace):
|
412
457
|
return pg.views.html.controls.Label(
|
413
458
|
item.name or 'Phase',
|
414
|
-
tooltip=f'Execution
|
459
|
+
tooltip=f'[{item.id}] Execution group {item.name!r}'
|
415
460
|
)
|
416
461
|
elif isinstance(item, ParallelExecutions):
|
417
462
|
return pg.views.html.controls.Label(
|
418
463
|
item.name or 'Parallel',
|
419
|
-
tooltip='Parallel executions
|
464
|
+
tooltip=f'[{item.id}] Parallel executions'
|
420
465
|
)
|
421
466
|
else:
|
422
467
|
raise ValueError(f'Unsupported item type: {type(item)}')
|
@@ -431,13 +476,13 @@ class ExecutionTrace(pg.Object, pg.views.html.HtmlTreeView.Extension):
|
|
431
476
|
padding: 10px;
|
432
477
|
}
|
433
478
|
.tab-button.phase > ::before {
|
434
|
-
content: "
|
479
|
+
content: "G";
|
435
480
|
font-weight: bold;
|
436
481
|
color: purple;
|
437
482
|
padding: 10px;
|
438
483
|
}
|
439
484
|
.tab-button.parallel > ::before {
|
440
|
-
content: "
|
485
|
+
content: "P";
|
441
486
|
font-weight: bold;
|
442
487
|
color: blue;
|
443
488
|
padding: 10px;
|
@@ -448,11 +493,26 @@ class ExecutionTrace(pg.Object, pg.views.html.HtmlTreeView.Extension):
|
|
448
493
|
color: orange;
|
449
494
|
padding: 10px;
|
450
495
|
}
|
451
|
-
.tab-button.log > ::before {
|
452
|
-
content: "
|
453
|
-
|
454
|
-
|
455
|
-
|
496
|
+
.tab-button.log-debug > ::before {
|
497
|
+
content: "🔍";
|
498
|
+
padding: 7px;
|
499
|
+
}
|
500
|
+
.tab-button.log-info > ::before {
|
501
|
+
content: "ⓘ";
|
502
|
+
color: blue;
|
503
|
+
padding: 7px;
|
504
|
+
}
|
505
|
+
.tab-button.log-warning > ::before {
|
506
|
+
content: "❗";
|
507
|
+
padding: 7px;
|
508
|
+
}
|
509
|
+
.tab-button.log-error > ::before {
|
510
|
+
content: "‼️";
|
511
|
+
padding: 7px;
|
512
|
+
}
|
513
|
+
.tab-button.log-fatal > ::before {
|
514
|
+
content: "❌";
|
515
|
+
padding: 7px;
|
456
516
|
}
|
457
517
|
.details.execution-trace, .details.action-invocation {
|
458
518
|
border: 1px solid #eee;
|
@@ -504,6 +564,22 @@ class ParallelExecutions(pg.Object, pg.views.html.HtmlTreeView.Extension):
|
|
504
564
|
self._tab_control = None
|
505
565
|
self._lock = threading.Lock()
|
506
566
|
|
567
|
+
def _on_parent_change(self, *args, **kwargs):
|
568
|
+
super()._on_parent_change(*args, **kwargs)
|
569
|
+
self.__dict__.pop('id', None)
|
570
|
+
|
571
|
+
@functools.cached_property
|
572
|
+
def id(self) -> str:
|
573
|
+
parent = self.sym_parent
|
574
|
+
if isinstance(parent, pg.List):
|
575
|
+
container = parent.sym_parent
|
576
|
+
if isinstance(container, ExecutionTrace):
|
577
|
+
parallel_id = (
|
578
|
+
self.name or f'p{container.indexof(self, ParallelExecutions) + 1}'
|
579
|
+
)
|
580
|
+
return f'{container.id}/{parallel_id}'
|
581
|
+
return ''
|
582
|
+
|
507
583
|
def add(self) -> ExecutionTrace:
|
508
584
|
"""Appends a branch to the parallel execution."""
|
509
585
|
with self._lock, pg.notify_on_change(False):
|
@@ -547,7 +623,7 @@ class ParallelExecutions(pg.Object, pg.views.html.HtmlTreeView.Extension):
|
|
547
623
|
return pg.views.html.controls.Tab(
|
548
624
|
label=pg.views.html.controls.Label(
|
549
625
|
branch.name,
|
550
|
-
tooltip=f'
|
626
|
+
tooltip=f'[{branch.id}] Branch {branch.name!r}'
|
551
627
|
),
|
552
628
|
content=pg.view(branch),
|
553
629
|
)
|
@@ -567,6 +643,11 @@ class ActionInvocation(pg.Object, pg.views.html.HtmlTreeView.Extension):
|
|
567
643
|
'The metadata returned by the action.'
|
568
644
|
] = {}
|
569
645
|
|
646
|
+
error: Annotated[
|
647
|
+
pg.utils.ErrorInfo | None,
|
648
|
+
'Error from the action if failed.'
|
649
|
+
] = None
|
650
|
+
|
570
651
|
execution: Annotated[
|
571
652
|
ExecutionTrace,
|
572
653
|
'The execution sequence of the action.'
|
@@ -579,6 +660,33 @@ class ActionInvocation(pg.Object, pg.views.html.HtmlTreeView.Extension):
|
|
579
660
|
super()._on_bound()
|
580
661
|
self._tab_control = None
|
581
662
|
|
663
|
+
def _on_parent_change(self, *args, **kwargs):
|
664
|
+
super()._on_parent_change(*args, **kwargs)
|
665
|
+
self.__dict__.pop('id', None)
|
666
|
+
|
667
|
+
@property
|
668
|
+
def parent_action(self) -> Optional['ActionInvocation']:
|
669
|
+
"""Returns the parent action invocation."""
|
670
|
+
return self.sym_ancestor(lambda x: isinstance(x, ActionInvocation))
|
671
|
+
|
672
|
+
@functools.cached_property
|
673
|
+
def id(self) -> str:
|
674
|
+
"""Returns the id of the action invocation."""
|
675
|
+
parent = self.sym_parent
|
676
|
+
if isinstance(parent, Session):
|
677
|
+
return f'{parent.id}:'
|
678
|
+
elif isinstance(parent, pg.List):
|
679
|
+
container = parent.sym_parent
|
680
|
+
if isinstance(container, ExecutionTrace):
|
681
|
+
action_id = f'a{container.indexof(self, ActionInvocation) + 1}'
|
682
|
+
return f'{container.id}/{action_id}'
|
683
|
+
return ''
|
684
|
+
|
685
|
+
@property
|
686
|
+
def has_error(self) -> bool:
|
687
|
+
"""Returns True if the action invocation has an error."""
|
688
|
+
return self.error is not None
|
689
|
+
|
582
690
|
@property
|
583
691
|
def logs(self) -> list[lf.logging.LogEntry]:
|
584
692
|
"""Returns immediate child logs from execution sequence."""
|
@@ -618,14 +726,17 @@ class ActionInvocation(pg.Object, pg.views.html.HtmlTreeView.Extension):
|
|
618
726
|
"""Starts the execution of the action."""
|
619
727
|
self.execution.start()
|
620
728
|
|
621
|
-
def end(
|
729
|
+
def end(
|
730
|
+
self,
|
731
|
+
result: Any,
|
732
|
+
error: pg.utils.ErrorInfo | None = None,
|
733
|
+
metadata: dict[str, Any] | None = None,
|
734
|
+
) -> None:
|
622
735
|
"""Ends the execution of the action with result and metadata."""
|
623
|
-
|
624
|
-
|
625
|
-
|
626
|
-
|
627
|
-
raise_on_no_change=False
|
628
|
-
)
|
736
|
+
rebind_dict = dict(result=result, error=error)
|
737
|
+
if metadata is not None:
|
738
|
+
rebind_dict['metadata'] = metadata
|
739
|
+
self.rebind(**rebind_dict, skip_notification=True, raise_on_no_change=False)
|
629
740
|
self.execution.stop()
|
630
741
|
if self._tab_control is not None:
|
631
742
|
if self.metadata:
|
@@ -641,19 +752,33 @@ class ActionInvocation(pg.Object, pg.views.html.HtmlTreeView.Extension):
|
|
641
752
|
name='metadata',
|
642
753
|
)
|
643
754
|
)
|
644
|
-
self.
|
645
|
-
|
646
|
-
|
647
|
-
|
648
|
-
|
649
|
-
|
650
|
-
|
651
|
-
|
652
|
-
|
653
|
-
|
654
|
-
|
655
|
-
|
656
|
-
|
755
|
+
if self.has_error:
|
756
|
+
self._tab_control.insert(
|
757
|
+
1,
|
758
|
+
pg.views.html.controls.Tab(
|
759
|
+
'error',
|
760
|
+
pg.view(
|
761
|
+
self.error,
|
762
|
+
collapse_level=None,
|
763
|
+
enable_summary_tooltip=False
|
764
|
+
),
|
765
|
+
name='error',
|
766
|
+
)
|
767
|
+
)
|
768
|
+
else:
|
769
|
+
self._tab_control.insert(
|
770
|
+
1,
|
771
|
+
pg.views.html.controls.Tab(
|
772
|
+
'result',
|
773
|
+
pg.view(
|
774
|
+
self.result,
|
775
|
+
collapse_level=None,
|
776
|
+
enable_summary_tooltip=False
|
777
|
+
),
|
778
|
+
name='result',
|
779
|
+
),
|
780
|
+
)
|
781
|
+
self._tab_control.select(['error', 'metadata', 'result'])
|
657
782
|
|
658
783
|
#
|
659
784
|
# HTML views.
|
@@ -806,7 +931,7 @@ class Session(pg.Object, pg.views.html.HtmlTreeView.Extension):
|
|
806
931
|
self._current_execution = self.root.execution
|
807
932
|
if self.id is None:
|
808
933
|
self.rebind(
|
809
|
-
id=f'
|
934
|
+
id=f'agent@{uuid.uuid4().hex[-7:]}',
|
810
935
|
skip_notification=True
|
811
936
|
)
|
812
937
|
|
@@ -821,6 +946,7 @@ class Session(pg.Object, pg.views.html.HtmlTreeView.Extension):
|
|
821
946
|
self._current_execution.start()
|
822
947
|
|
823
948
|
invocation = ActionInvocation(pg.maybe_ref(action))
|
949
|
+
action._invocation = invocation # pylint: disable=protected-access
|
824
950
|
parent_action = self._current_action
|
825
951
|
parent_execution = self._current_execution
|
826
952
|
parent_execution.append(invocation)
|
@@ -832,16 +958,18 @@ class Session(pg.Object, pg.views.html.HtmlTreeView.Extension):
|
|
832
958
|
self._current_action.start()
|
833
959
|
yield invocation
|
834
960
|
finally:
|
835
|
-
# Stop the execution of the current action.
|
836
|
-
invocation.end(action.result, action.metadata)
|
837
961
|
self._current_execution = parent_execution
|
838
962
|
self._current_action = parent_action
|
839
963
|
if parent_action is self.root:
|
840
|
-
parent_action.end(
|
964
|
+
parent_action.end(
|
965
|
+
result=invocation.result,
|
966
|
+
metadata=invocation.metadata,
|
967
|
+
error=invocation.error
|
968
|
+
)
|
841
969
|
|
842
970
|
@contextlib.contextmanager
|
843
971
|
def track_phase(self, name: str | None) -> Iterator[ExecutionTrace]:
|
844
|
-
"""Context manager for starting a new execution phase."""
|
972
|
+
"""Context manager for starting a new execution phase (group)."""
|
845
973
|
parent_execution = self._current_execution
|
846
974
|
if name is None:
|
847
975
|
phase = parent_execution
|
@@ -878,6 +1006,12 @@ class Session(pg.Object, pg.views.html.HtmlTreeView.Extension):
|
|
878
1006
|
try:
|
879
1007
|
yield queries
|
880
1008
|
finally:
|
1009
|
+
for i, query in enumerate(queries):
|
1010
|
+
query.rebind(
|
1011
|
+
id=f'{execution.id}/q{len(execution.queries) + i + 1}',
|
1012
|
+
skip_notification=False,
|
1013
|
+
raise_on_no_change=False
|
1014
|
+
)
|
881
1015
|
execution.extend(queries)
|
882
1016
|
|
883
1017
|
#
|
@@ -897,7 +1031,7 @@ class Session(pg.Object, pg.views.html.HtmlTreeView.Extension):
|
|
897
1031
|
] = None,
|
898
1032
|
default: Any = lf.RAISE_IF_HAS_ERROR,
|
899
1033
|
*,
|
900
|
-
lm: lf.LanguageModel
|
1034
|
+
lm: lf.LanguageModel,
|
901
1035
|
examples: list[lf_structured.MappingExample] | None = None,
|
902
1036
|
**kwargs
|
903
1037
|
) -> Any:
|
@@ -931,14 +1065,24 @@ class Session(pg.Object, pg.views.html.HtmlTreeView.Extension):
|
|
931
1065
|
The result of the query.
|
932
1066
|
"""
|
933
1067
|
with self.track_queries():
|
934
|
-
|
935
|
-
|
936
|
-
|
937
|
-
|
938
|
-
|
939
|
-
|
940
|
-
|
941
|
-
|
1068
|
+
start_time = time.time()
|
1069
|
+
try:
|
1070
|
+
return lf_structured.query(
|
1071
|
+
prompt,
|
1072
|
+
schema=schema,
|
1073
|
+
default=default,
|
1074
|
+
lm=lm,
|
1075
|
+
examples=examples,
|
1076
|
+
**kwargs
|
1077
|
+
)
|
1078
|
+
except BaseException as e:
|
1079
|
+
elapse = time.time() - start_time
|
1080
|
+
self.warning(
|
1081
|
+
f'Failed to query LLM ({lm.model_id}) in {elapse:.2f} seconds.',
|
1082
|
+
error=pg.utils.ErrorInfo.from_exception(e),
|
1083
|
+
keep=False,
|
1084
|
+
)
|
1085
|
+
raise
|
942
1086
|
|
943
1087
|
def concurrent_map(
|
944
1088
|
self,
|
@@ -1069,11 +1213,15 @@ class Session(pg.Object, pg.views.html.HtmlTreeView.Extension):
|
|
1069
1213
|
**kwargs
|
1070
1214
|
) -> None:
|
1071
1215
|
"""Logs a message to the session."""
|
1216
|
+
action_name = self._current_action.action.__class__.__name__
|
1217
|
+
execution = self._current_execution
|
1072
1218
|
log_entry = lf.logging.log(
|
1073
|
-
level,
|
1219
|
+
level,
|
1220
|
+
f'[{execution.id} ({action_name})]: {message}',
|
1221
|
+
**kwargs
|
1074
1222
|
)
|
1075
1223
|
if keep:
|
1076
|
-
|
1224
|
+
execution.append(log_entry)
|
1077
1225
|
|
1078
1226
|
def debug(self, message: str, keep: bool = True, **kwargs):
|
1079
1227
|
"""Logs a debug message to the session."""
|
@@ -34,9 +34,11 @@ class ActionEval(lf.eval.v2.Evaluation):
|
|
34
34
|
def process(self, example: lf.eval.v2.Example) -> tuple[str, dict[str, Any]]:
|
35
35
|
example_input = example.input
|
36
36
|
action = example_input.action
|
37
|
-
session = action_lib.Session(id=
|
37
|
+
session = action_lib.Session(id=f'{self.id}#example-{example.id}')
|
38
38
|
with lf.logging.use_log_level('fatal'):
|
39
|
-
|
39
|
+
kwargs = self.action_args.copy()
|
40
|
+
kwargs.update(verbose=True)
|
41
|
+
action(session=session, **kwargs)
|
40
42
|
return session.final_result, dict(session=session)
|
41
43
|
|
42
44
|
|
@@ -22,54 +22,108 @@ import langfun.core.structured as lf_structured
|
|
22
22
|
import pyglove as pg
|
23
23
|
|
24
24
|
|
25
|
-
class
|
25
|
+
class Bar(action_lib.Action):
|
26
|
+
simulate_action_error: bool = False
|
27
|
+
|
28
|
+
def call(self, session, *, lm, **kwargs):
|
29
|
+
assert session.current_action.action is self
|
30
|
+
session.info('Begin Bar')
|
31
|
+
session.query('bar', lm=lm)
|
32
|
+
session.add_metadata(note='bar')
|
33
|
+
if self.simulate_action_error:
|
34
|
+
raise ValueError('Bar error')
|
35
|
+
return 2
|
36
|
+
|
37
|
+
|
38
|
+
class Foo(action_lib.Action):
|
39
|
+
x: int
|
40
|
+
simulate_action_error: bool = False
|
41
|
+
simulate_query_error: bool = False
|
42
|
+
|
43
|
+
def call(self, session, *, lm, **kwargs):
|
44
|
+
assert session.current_action.action is self
|
45
|
+
with session.track_phase('prepare'):
|
46
|
+
session.info('Begin Foo', x=1)
|
47
|
+
session.query(
|
48
|
+
'foo',
|
49
|
+
schema=int if self.simulate_query_error else None,
|
50
|
+
lm=lm
|
51
|
+
)
|
52
|
+
with session.track_queries():
|
53
|
+
self.make_additional_query(lm)
|
54
|
+
session.add_metadata(note='foo')
|
55
|
+
|
56
|
+
def _sub_task(i):
|
57
|
+
session.add_metadata(**{f'subtask_{i}': i})
|
58
|
+
return lf_structured.query(f'subtask_{i}', lm=lm)
|
59
|
+
|
60
|
+
for i, output, error in session.concurrent_map(
|
61
|
+
_sub_task, range(3), max_workers=2, silence_on_errors=None,
|
62
|
+
):
|
63
|
+
assert isinstance(i, int), i
|
64
|
+
assert isinstance(output, str), output
|
65
|
+
assert error is None, error
|
66
|
+
return self.x + Bar(
|
67
|
+
simulate_action_error=self.simulate_action_error
|
68
|
+
)(session, lm=lm)
|
69
|
+
|
70
|
+
def make_additional_query(self, lm):
|
71
|
+
lf_structured.query('additional query', lm=lm)
|
72
|
+
|
73
|
+
|
74
|
+
class ActionInvocationTest(unittest.TestCase):
|
75
|
+
|
76
|
+
def test_basics(self):
|
77
|
+
action_invocation = action_lib.ActionInvocation(
|
78
|
+
action=Foo(1)
|
79
|
+
)
|
80
|
+
self.assertEqual(action_invocation.id, '')
|
81
|
+
root = action_lib.ActionInvocation(action=action_lib.RootAction())
|
82
|
+
root.execution.append(action_invocation)
|
83
|
+
self.assertIs(action_invocation.parent_action, root)
|
84
|
+
self.assertEqual(action_invocation.id, '/a1')
|
85
|
+
|
86
|
+
|
87
|
+
class ExecutionTraceTest(unittest.TestCase):
|
26
88
|
|
27
89
|
def test_basics(self):
|
28
|
-
|
29
|
-
|
30
|
-
class Bar(action_lib.Action):
|
31
|
-
|
32
|
-
def call(self, session, *, lm, **kwargs):
|
33
|
-
test.assertIs(session.current_action.action, self)
|
34
|
-
session.info('Begin Bar')
|
35
|
-
session.query('bar', lm=lm)
|
36
|
-
session.add_metadata(note='bar')
|
37
|
-
return 2
|
38
|
-
|
39
|
-
class Foo(action_lib.Action):
|
40
|
-
x: int
|
41
|
-
|
42
|
-
def call(self, session, *, lm, **kwargs):
|
43
|
-
test.assertIs(session.current_action.action, self)
|
44
|
-
with session.track_phase('prepare'):
|
45
|
-
session.info('Begin Foo', x=1)
|
46
|
-
session.query('foo', lm=lm)
|
47
|
-
with session.track_queries():
|
48
|
-
self.make_additional_query(lm)
|
49
|
-
session.add_metadata(note='foo')
|
50
|
-
|
51
|
-
def _sub_task(i):
|
52
|
-
session.add_metadata(**{f'subtask_{i}': i})
|
53
|
-
return lf_structured.query(f'subtask_{i}', lm=lm)
|
54
|
-
|
55
|
-
for i, output, error in session.concurrent_map(
|
56
|
-
_sub_task, range(3), max_workers=2, silence_on_errors=None,
|
57
|
-
):
|
58
|
-
assert isinstance(i, int), i
|
59
|
-
assert isinstance(output, str), output
|
60
|
-
assert error is None, error
|
61
|
-
return self.x + Bar()(session, lm=lm)
|
62
|
-
|
63
|
-
def make_additional_query(self, lm):
|
64
|
-
lf_structured.query('additional query', lm=lm)
|
90
|
+
execution = action_lib.ExecutionTrace()
|
91
|
+
self.assertEqual(execution.id, '')
|
65
92
|
|
93
|
+
root = action_lib.ActionInvocation(action=action_lib.RootAction())
|
94
|
+
action_invocation = action_lib.ActionInvocation(
|
95
|
+
action=Foo(1)
|
96
|
+
)
|
97
|
+
root.execution.append(action_invocation)
|
98
|
+
self.assertEqual(action_invocation.execution.id, '/a1')
|
99
|
+
|
100
|
+
root.execution.reset()
|
101
|
+
self.assertEqual(len(root.execution), 0)
|
102
|
+
|
103
|
+
|
104
|
+
class SessionTest(unittest.TestCase):
|
105
|
+
|
106
|
+
def test_succeeded_trajectory(self):
|
66
107
|
lm = fake.StaticResponse('lm response')
|
67
108
|
foo = Foo(1)
|
68
|
-
self.
|
109
|
+
self.assertIsNone(foo.session)
|
110
|
+
self.assertIsNone(foo.result)
|
111
|
+
self.assertIsNone(foo.metadata)
|
112
|
+
|
113
|
+
session = action_lib.Session(id='agent@1')
|
114
|
+
self.assertEqual(session.id, 'agent@1')
|
115
|
+
|
116
|
+
# Render HTML view to trigger dynamic update during execution.
|
117
|
+
_ = session.to_html()
|
118
|
+
|
119
|
+
self.assertEqual(foo(session, lm=lm, verbose=True), 3)
|
120
|
+
|
121
|
+
self.assertIsNone(foo.session)
|
122
|
+
self.assertEqual(foo.result, 3)
|
123
|
+
self.assertEqual(
|
124
|
+
foo.metadata, dict(note='foo', subtask_0=0, subtask_1=1, subtask_2=2)
|
125
|
+
)
|
69
126
|
|
70
|
-
session = foo.session
|
71
|
-
self.assertIn('session@', session.id)
|
72
|
-
self.assertIsNotNone(session)
|
73
127
|
self.assertIsInstance(session.root.action, action_lib.RootAction)
|
74
128
|
self.assertIs(session.current_action, session.root)
|
75
129
|
|
@@ -78,6 +132,9 @@ class SessionTest(unittest.TestCase):
|
|
78
132
|
#
|
79
133
|
|
80
134
|
root = session.root
|
135
|
+
self.assertIsNone(root.parent_action)
|
136
|
+
self.assertEqual(root.id, 'agent@1:')
|
137
|
+
self.assertEqual(root.execution.id, 'agent@1:')
|
81
138
|
self.assertEqual(len(root.execution.items), 1)
|
82
139
|
self.assertIs(root.execution.items[0].action, foo)
|
83
140
|
|
@@ -104,33 +161,57 @@ class SessionTest(unittest.TestCase):
|
|
104
161
|
|
105
162
|
# Inspecting the top-level action (Foo)
|
106
163
|
foo_invocation = root.execution.items[0]
|
164
|
+
self.assertIs(foo_invocation.parent_action, root)
|
165
|
+
self.assertEqual(foo_invocation.id, 'agent@1:/a1')
|
166
|
+
self.assertEqual(foo_invocation.execution.id, 'agent@1:/a1')
|
107
167
|
self.assertEqual(len(foo_invocation.execution.items), 4)
|
108
168
|
|
109
169
|
# Prepare phase.
|
110
170
|
prepare_phase = foo_invocation.execution.items[0]
|
111
|
-
self.assertIsInstance(
|
112
|
-
|
113
|
-
)
|
171
|
+
self.assertIsInstance(prepare_phase, action_lib.ExecutionTrace)
|
172
|
+
self.assertEqual(prepare_phase.id, 'agent@1:/a1/prepare')
|
114
173
|
self.assertEqual(len(prepare_phase.items), 2)
|
115
174
|
self.assertTrue(prepare_phase.has_started)
|
116
175
|
self.assertTrue(prepare_phase.has_stopped)
|
117
176
|
self.assertEqual(prepare_phase.usage_summary.total.num_requests, 1)
|
177
|
+
self.assertIsInstance(prepare_phase.items[0], lf.logging.LogEntry)
|
178
|
+
self.assertIsInstance(prepare_phase.items[1], lf_structured.QueryInvocation)
|
179
|
+
self.assertEqual(prepare_phase.items[1].id, 'agent@1:/a1/prepare/q1')
|
118
180
|
|
119
181
|
# Tracked queries.
|
120
182
|
query_invocation = foo_invocation.execution.items[1]
|
121
183
|
self.assertIsInstance(query_invocation, lf_structured.QueryInvocation)
|
184
|
+
self.assertEqual(query_invocation.id, 'agent@1:/a1/q2')
|
122
185
|
self.assertIs(query_invocation.lm, lm)
|
186
|
+
self.assertEqual(
|
187
|
+
foo_invocation.execution.indexof(
|
188
|
+
query_invocation, lf_structured.QueryInvocation
|
189
|
+
),
|
190
|
+
1
|
191
|
+
)
|
192
|
+
self.assertEqual(
|
193
|
+
root.execution.indexof(
|
194
|
+
query_invocation, lf_structured.QueryInvocation
|
195
|
+
),
|
196
|
+
-1
|
197
|
+
)
|
123
198
|
|
124
199
|
# Tracked parallel executions.
|
125
200
|
parallel_executions = foo_invocation.execution.items[2]
|
201
|
+
self.assertEqual(parallel_executions.id, 'agent@1:/a1/p1')
|
126
202
|
self.assertIsInstance(parallel_executions, action_lib.ParallelExecutions)
|
127
203
|
self.assertEqual(len(parallel_executions), 3)
|
204
|
+
self.assertEqual(parallel_executions[0].id, 'agent@1:/a1/p1/b1')
|
205
|
+
self.assertEqual(parallel_executions[1].id, 'agent@1:/a1/p1/b2')
|
206
|
+
self.assertEqual(parallel_executions[2].id, 'agent@1:/a1/p1/b3')
|
128
207
|
self.assertEqual(len(parallel_executions[0].queries), 1)
|
129
208
|
self.assertEqual(len(parallel_executions[1].queries), 1)
|
130
209
|
self.assertEqual(len(parallel_executions[2].queries), 1)
|
131
210
|
|
132
211
|
# Invocation to Bar.
|
133
212
|
bar_invocation = foo_invocation.execution.items[3]
|
213
|
+
self.assertIs(bar_invocation.parent_action, foo_invocation)
|
214
|
+
self.assertEqual(bar_invocation.id, 'agent@1:/a1/a1')
|
134
215
|
self.assertIsInstance(bar_invocation, action_lib.ActionInvocation)
|
135
216
|
self.assertIsInstance(bar_invocation.action, Bar)
|
136
217
|
self.assertEqual(bar_invocation.result, 2)
|
@@ -144,6 +225,51 @@ class SessionTest(unittest.TestCase):
|
|
144
225
|
json_str = session.to_json_str(save_ref_value=True)
|
145
226
|
self.assertIsInstance(pg.from_json_str(json_str), action_lib.Session)
|
146
227
|
|
228
|
+
def test_failed_action(self):
|
229
|
+
lm = fake.StaticResponse('lm response')
|
230
|
+
foo = Foo(1, simulate_action_error=True)
|
231
|
+
with self.assertRaisesRegex(ValueError, 'Bar error'):
|
232
|
+
foo(lm=lm)
|
233
|
+
|
234
|
+
session = foo.session
|
235
|
+
self.assertIsNotNone(session)
|
236
|
+
self.assertIsInstance(session.root.action, action_lib.RootAction)
|
237
|
+
self.assertIs(session.current_action, session.root)
|
238
|
+
|
239
|
+
# Inspecting the root invocation.
|
240
|
+
root = session.root
|
241
|
+
self.assertRegex(root.id, 'agent@.*:')
|
242
|
+
self.assertTrue(root.has_error)
|
243
|
+
foo_invocation = root.execution.items[0]
|
244
|
+
self.assertIsInstance(foo_invocation, action_lib.ActionInvocation)
|
245
|
+
self.assertTrue(foo_invocation.has_error)
|
246
|
+
bar_invocation = foo_invocation.execution.items[3]
|
247
|
+
self.assertIsInstance(bar_invocation, action_lib.ActionInvocation)
|
248
|
+
self.assertTrue(bar_invocation.has_error)
|
249
|
+
|
250
|
+
# Save to HTML
|
251
|
+
self.assertIn('error', session.to_html().content)
|
252
|
+
|
253
|
+
def test_failed_query(self):
|
254
|
+
lm = fake.StaticResponse('lm response')
|
255
|
+
foo = Foo(1, simulate_query_error=True)
|
256
|
+
with self.assertRaisesRegex(lf_structured.MappingError, 'SyntaxError'):
|
257
|
+
foo(lm=lm)
|
258
|
+
|
259
|
+
session = foo.session
|
260
|
+
self.assertIsNotNone(session)
|
261
|
+
self.assertIsInstance(session.root.action, action_lib.RootAction)
|
262
|
+
self.assertIs(session.current_action, session.root)
|
263
|
+
|
264
|
+
# Inspecting the root invocation.
|
265
|
+
root = session.root
|
266
|
+
self.assertRegex(root.id, 'agent@.*:')
|
267
|
+
self.assertTrue(root.has_error)
|
268
|
+
foo_invocation = root.execution.items[0]
|
269
|
+
self.assertIsInstance(foo_invocation, action_lib.ActionInvocation)
|
270
|
+
self.assertTrue(foo_invocation.has_error)
|
271
|
+
self.assertEqual(len(foo_invocation.execution.items), 2)
|
272
|
+
|
147
273
|
def test_log(self):
|
148
274
|
session = action_lib.Session()
|
149
275
|
session.debug('hi', x=1, y=2)
|
@@ -153,8 +279,8 @@ class SessionTest(unittest.TestCase):
|
|
153
279
|
session.fatal('hi', x=1, y=2)
|
154
280
|
|
155
281
|
def test_as_message(self):
|
156
|
-
session = action_lib.Session(
|
157
|
-
self.
|
282
|
+
session = action_lib.Session()
|
283
|
+
self.assertIn('agent@', session.id)
|
158
284
|
self.assertIsInstance(session.as_message(), lf.AIMessage)
|
159
285
|
|
160
286
|
|
@@ -456,6 +456,11 @@ def class_definition(
|
|
456
456
|
)
|
457
457
|
continue
|
458
458
|
|
459
|
+
# Skip fields that are marked as excluded from the prompt sent to LLM
|
460
|
+
# for OOP.
|
461
|
+
if field.metadata.get('exclude_from_prompt', False):
|
462
|
+
continue
|
463
|
+
|
459
464
|
# Write field doc string as comments before the field definition.
|
460
465
|
if field.description:
|
461
466
|
for line in field.description.split('\n'):
|
@@ -538,6 +538,19 @@ class SchemaPythonReprTest(unittest.TestCase):
|
|
538
538
|
""") + '\n'
|
539
539
|
)
|
540
540
|
|
541
|
+
class E(pg.Object):
|
542
|
+
x: str
|
543
|
+
y: typing.Annotated[int, 'y', dict(exclude_from_prompt=True)]
|
544
|
+
|
545
|
+
self.assertEqual(
|
546
|
+
schema_lib.class_definition(E),
|
547
|
+
inspect.cleandoc(
|
548
|
+
"""
|
549
|
+
class E(Object):
|
550
|
+
x: str
|
551
|
+
""") + '\n'
|
552
|
+
)
|
553
|
+
|
541
554
|
def test_repr(self):
|
542
555
|
class Foo(pg.Object):
|
543
556
|
x: int
|
{langfun-0.1.2.dev202504270803.dist-info → langfun-0.1.2.dev202504290805.dist-info}/METADATA
RENAMED
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: langfun
|
3
|
-
Version: 0.1.2.
|
3
|
+
Version: 0.1.2.dev202504290805
|
4
4
|
Summary: Langfun: Language as Functions.
|
5
5
|
Home-page: https://github.com/google/langfun
|
6
6
|
Author: Langfun Authors
|
@@ -193,7 +193,9 @@ To install a nightly build, include the `--pre` flag, like this:
|
|
193
193
|
pip install langfun[all] --pre
|
194
194
|
```
|
195
195
|
|
196
|
-
If you want to customize your installation, you can select specific features
|
196
|
+
If you want to customize your installation, you can select specific features
|
197
|
+
using package names like `langfun[X1, X2, ..., Xn]`, where `Xi` corresponds to
|
198
|
+
a tag from the list below:
|
197
199
|
|
198
200
|
| Tag | Description |
|
199
201
|
| ------------------- | ---------------------------------------- |
|
@@ -201,15 +203,36 @@ If you want to customize your installation, you can select specific features usi
|
|
201
203
|
| vertexai | VertexAI access. |
|
202
204
|
| mime | All MIME supports. |
|
203
205
|
| mime-auto | Automatic MIME type detection. |
|
204
|
-
| mime-docx | DocX format support. |
|
205
206
|
| mime-pil | Image support for PIL. |
|
206
|
-
| mime-xlsx | XlsX format support. |
|
207
207
|
| ui | UI enhancements |
|
208
208
|
|
209
|
-
|
210
|
-
|
209
|
+
For example, to install a nightly build that includes VertexAI access, full
|
210
|
+
modality support, and UI enhancements, use:
|
211
211
|
```
|
212
212
|
pip install langfun[vertexai,mime,ui] --pre
|
213
213
|
```
|
214
214
|
|
215
|
+
### Solving import issue with `libmagic`
|
216
|
+
|
217
|
+
Langfun utilizes `libmagic` for automatic MIME type detection to support
|
218
|
+
multi-modal functionalities. However, `pip install libmagic` may not work
|
219
|
+
out-of-the-box on all operation systems, sometimes leading to an
|
220
|
+
`'ImportError: failed to find libmagic.'` error after Langfun installation.
|
221
|
+
|
222
|
+
If you encounter this error, you will need to follow the recommendations below
|
223
|
+
to fix the installation of `libmagic` library.
|
224
|
+
|
225
|
+
#### OSX
|
226
|
+
|
227
|
+
```
|
228
|
+
conda install conda-forge::libmagic
|
229
|
+
```
|
230
|
+
|
231
|
+
#### Windows:
|
232
|
+
```
|
233
|
+
pip install python-magic
|
234
|
+
pip uninstall python-magic-bin
|
235
|
+
pip install python-magic-bin
|
236
|
+
```
|
237
|
+
|
215
238
|
*Disclaimer: this is not an officially supported Google product.*
|
@@ -26,10 +26,10 @@ langfun/core/subscription_test.py,sha256=Y4ZdbZEwm83YNZBxHff0QR4QUa4rdaNXA3_jfIc
|
|
26
26
|
langfun/core/template.py,sha256=jNhYSrbLIn9kZOa03w5QZbyjgfnzJzE_ZrrMvvWY4t4,24929
|
27
27
|
langfun/core/template_test.py,sha256=AQv_m9qE93WxhEhSlm1xaBgB4hu0UVtA53dljngkUW0,17090
|
28
28
|
langfun/core/agentic/__init__.py,sha256=qR3jlfUO4rhIoYdRDLz-d22YZf3FvU4FW88vsjiGDQQ,1224
|
29
|
-
langfun/core/agentic/action.py,sha256=
|
30
|
-
langfun/core/agentic/action_eval.py,sha256
|
29
|
+
langfun/core/agentic/action.py,sha256=9P7xDiZVUV9MvJDfuAfLx-xa7qvS5F0EOGWDQnjAZBw,38931
|
30
|
+
langfun/core/agentic/action_eval.py,sha256=8cdH-ubWUL1sscqagrQltPg19vTYNKrI3CKLvluGP24,4615
|
31
31
|
langfun/core/agentic/action_eval_test.py,sha256=tRUkWmOE9p0rpNOq19xAY2oDEnYsEEykjg6sUpAwJk0,2832
|
32
|
-
langfun/core/agentic/action_test.py,sha256=
|
32
|
+
langfun/core/agentic/action_test.py,sha256=9EZKgLaBrqTErSRoxtrSlzmCz_cbnwWu0ZqpwKLst-s,10224
|
33
33
|
langfun/core/coding/__init__.py,sha256=5utju_fwEsImaiftx4oXKl9FAM8p281k8-Esdh_-m1w,835
|
34
34
|
langfun/core/coding/python/__init__.py,sha256=4ByknuoNU-mOIHwHKnTtmo6oD64oMFtlqPlYWmA5Wic,1736
|
35
35
|
langfun/core/coding/python/correction.py,sha256=7zBedlhQKMPA4cfchUMxAOFl6Zl5RqCyllRHGWys40s,7092
|
@@ -139,10 +139,10 @@ langfun/core/structured/parsing.py,sha256=MGvI7ypXlwfzr5XB8_TFU9Ei0_5reYqkWkv64e
|
|
139
139
|
langfun/core/structured/parsing_test.py,sha256=kNPrhpdPY3iWhUld0TFYU-Zgn44wC0d6YuQ9XdVbQ8o,22346
|
140
140
|
langfun/core/structured/querying.py,sha256=GGNtHtJcKh8rzLBNx_Df1ATvsPZzyfZuGkzSQVabdpo,24885
|
141
141
|
langfun/core/structured/querying_test.py,sha256=vUuVUClYBFGEaO9KuD60huPE1dmP6RCRLeRnBv67NmQ,34263
|
142
|
-
langfun/core/structured/schema.py,sha256=
|
142
|
+
langfun/core/structured/schema.py,sha256=pGiAjez-ON2nKLUSeAls27gJsMto5aJnCXLVwH3pUKM,28296
|
143
143
|
langfun/core/structured/schema_generation.py,sha256=3AcuKvv3VOtKY5zMVqODrxfOuDxzoZtGeBxHlOWDOWw,5308
|
144
144
|
langfun/core/structured/schema_generation_test.py,sha256=RM9s71kMNg2jTePwInkiW9fK1ACN37eyPeF8OII-0zw,2950
|
145
|
-
langfun/core/structured/schema_test.py,sha256=
|
145
|
+
langfun/core/structured/schema_test.py,sha256=N8qNVA2hrHlxmHIoKtpzhBASa2RMVoPowF_noAfgPME,26035
|
146
146
|
langfun/core/structured/scoring.py,sha256=Y7Jqs5VVjUQLF_9Z1uIY_dw5zasv2FF52Cz-cxGMsro,5857
|
147
147
|
langfun/core/structured/scoring_test.py,sha256=QvlwDAzwuamKL5tCotm1L3Sx0cs3idoNK4aIEhaO4Yk,2272
|
148
148
|
langfun/core/structured/tokenization.py,sha256=-b4_693quHeYn2AqndwucuXNmhd5NVXVTU3mmDane98,2189
|
@@ -156,8 +156,8 @@ langfun/core/templates/demonstration.py,sha256=vCrgYubdZM5Umqcgp8NUVGXgr4P_c-fik
|
|
156
156
|
langfun/core/templates/demonstration_test.py,sha256=SafcDQ0WgI7pw05EmPI2S4v1t3ABKzup8jReCljHeK4,2162
|
157
157
|
langfun/core/templates/selfplay.py,sha256=yhgrJbiYwq47TgzThmHrDQTF4nDrTI09CWGhuQPNv-s,2273
|
158
158
|
langfun/core/templates/selfplay_test.py,sha256=Ot__1P1M8oJfoTp-M9-PQ6HUXqZKyMwvZ5f7yQ3yfyM,2326
|
159
|
-
langfun-0.1.2.
|
160
|
-
langfun-0.1.2.
|
161
|
-
langfun-0.1.2.
|
162
|
-
langfun-0.1.2.
|
163
|
-
langfun-0.1.2.
|
159
|
+
langfun-0.1.2.dev202504290805.dist-info/licenses/LICENSE,sha256=WNHhf_5RCaeuKWyq_K39vmp9F28LxKsB4SpomwSZ2L0,11357
|
160
|
+
langfun-0.1.2.dev202504290805.dist-info/METADATA,sha256=KWW7NslPxpSS2u0eVRcN022ylI5TeWFdswXMnve9144,8178
|
161
|
+
langfun-0.1.2.dev202504290805.dist-info/WHEEL,sha256=ck4Vq1_RXyvS4Jt6SI0Vz6fyVs4GWg7AINwpsaGEgPE,91
|
162
|
+
langfun-0.1.2.dev202504290805.dist-info/top_level.txt,sha256=RhlEkHxs1qtzmmtWSwYoLVJAc1YrbPtxQ52uh8Z9VvY,8
|
163
|
+
langfun-0.1.2.dev202504290805.dist-info/RECORD,,
|
{langfun-0.1.2.dev202504270803.dist-info → langfun-0.1.2.dev202504290805.dist-info}/licenses/LICENSE
RENAMED
File without changes
|
{langfun-0.1.2.dev202504270803.dist-info → langfun-0.1.2.dev202504290805.dist-info}/top_level.txt
RENAMED
File without changes
|