langfun 0.1.2.dev202504240804__py3-none-any.whl → 0.1.2.dev202504250804__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.

@@ -20,6 +20,7 @@ import threading
20
20
  import time
21
21
  import typing
22
22
  from typing import Annotated, Any, Callable, Iterable, Iterator, Optional, Type, Union
23
+ import uuid
23
24
  import langfun.core as lf
24
25
  from langfun.core import structured as lf_structured
25
26
  import pyglove as pg
@@ -63,7 +64,11 @@ class Action(pg.Object):
63
64
  lf.console.display(pg.view(session, name='agent_session'))
64
65
 
65
66
  with session.track_action(self):
67
+ pg.logging.info('Example %s starts action %s', session.id, repr(self))
66
68
  result = self.call(session=session, **kwargs)
69
+ pg.logging.info(
70
+ 'Example %s ends action %s', session.id, self.__class__.__name__
71
+ )
67
72
 
68
73
  # For the top-level action, we store the session in the metadata.
69
74
  if new_session:
@@ -792,6 +797,8 @@ class Session(pg.Object, pg.views.html.HtmlTreeView.Extension):
792
797
  self._tls = threading.local()
793
798
  self._current_action = self.root
794
799
  self._current_execution = self.root.execution
800
+ if self.id is None:
801
+ self.rebind(id=uuid.uuid4().hex[-7:], skip_notification=True)
795
802
 
796
803
  #
797
804
  # Context-manager for information tracking.
@@ -68,6 +68,7 @@ class SessionTest(unittest.TestCase):
68
68
  self.assertEqual(foo(lm=lm), 3)
69
69
 
70
70
  session = foo.session
71
+ self.assertEqual(len(session.id), 7)
71
72
  self.assertIsNotNone(session)
72
73
  self.assertIsInstance(session.root.action, action_lib.RootAction)
73
74
  self.assertIs(session.current_action, session.root)
@@ -152,7 +153,8 @@ class SessionTest(unittest.TestCase):
152
153
  session.fatal('hi', x=1, y=2)
153
154
 
154
155
  def test_as_message(self):
155
- session = action_lib.Session()
156
+ session = action_lib.Session(id='abc')
157
+ self.assertEqual(session.id, 'abc')
156
158
  self.assertIsInstance(session.as_message(), lf.AIMessage)
157
159
 
158
160
 
@@ -169,9 +169,23 @@ class Evaluation(experiment_lib.Experiment):
169
169
  checkpointed = self._state.ckpt_example(example.id)
170
170
  with pg.timeit('evaluate') as timeit, lf.track_usages() as usage_summary:
171
171
  if checkpointed is None or checkpointed.has_error:
172
+ if checkpointed is None:
173
+ self.info(
174
+ f'Example {example.id} is being processed for the first time '
175
+ 'as no prior run is found. '
176
+ )
177
+ else:
178
+ self.info(
179
+ f'Example {example.id} is being reprocessed as prior run '
180
+ f'contains error: {checkpointed.error}'
181
+ )
172
182
  example.start_time = time.time()
173
183
  self._process(example, raise_if_has_error=raise_if_has_error)
174
184
  else:
185
+ self.info(
186
+ f'Example {example.id} skipped processing as prior run '
187
+ 'is available and error free.'
188
+ )
175
189
  example.start_time = checkpointed.start_time
176
190
 
177
191
  # Use the output and metadata obtained from the previous processing.
@@ -190,10 +204,12 @@ class Evaluation(experiment_lib.Experiment):
190
204
  # NOTE(daiyip): It's possible that metrics could use LLMs, so we need to
191
205
  # track the usage of the metrics separately.
192
206
  with pg.timeit('metric'):
207
+ self.info(f'Starting metric computation for example {example.id}.')
193
208
  metric_metadata = {}
194
209
  for metric in self.metrics:
195
210
  metric_metadata.update(metric.audit(example))
196
211
  example.metric_metadata = metric_metadata
212
+ self.info(f'Completed metric computation for example {example.id}.')
197
213
 
198
214
  # For previously processed examples, we keep the execution status for the
199
215
  # processing step.
@@ -315,6 +331,26 @@ class Evaluation(experiment_lib.Experiment):
315
331
  with self._log_lock:
316
332
  self._log_entries.append(log_entry)
317
333
 
334
+ # Also add system log.
335
+ match level:
336
+ case 'debug':
337
+ sys_log_func = pg.logging.debug
338
+ case 'info':
339
+ sys_log_func = pg.logging.info
340
+ case 'warning':
341
+ sys_log_func = pg.logging.warning
342
+ case 'error':
343
+ sys_log_func = pg.logging.error
344
+ case 'fatal':
345
+ sys_log_func = pg.logging.error
346
+ case _:
347
+ raise ValueError(f'Unsupported log level: {level}')
348
+
349
+ sys_log_func(
350
+ '%s: %s\nMetadata: %s',
351
+ self.id, message, pg.format(kwargs)
352
+ )
353
+
318
354
  def debug(self, message: str, **kwargs):
319
355
  """Logs a debug message to the session."""
320
356
  self._log(pg.logging.debug, 'debug', message, **kwargs)
@@ -249,22 +249,23 @@ class RunnerBase(Runner):
249
249
  if example.error is None:
250
250
  experiment.progress.increment_processed()
251
251
  experiment.info(
252
- f'Example {example.id} is successfully evaluated in '
253
- f'{example.elapse:.2f} seconds.' # pylint: disable=bad-whitespace
252
+ f'Example {example.id} is successfully evaluated (with process) in '
253
+ f'{example.elapse:.2f} seconds.'
254
254
  )
255
255
  else:
256
256
  experiment.progress.increment_failed()
257
257
  experiment.error(
258
258
  (
259
259
  f'Failed to evaluate example {example.id} in'
260
- f'{example.elapse:.2f} seconds.' # pylint: disable=bad-whitespace
260
+ f'{example.elapse:.2f} seconds.'
261
261
  ),
262
262
  error=example.error
263
263
  )
264
264
  else:
265
265
  experiment.progress.increment_skipped()
266
266
  experiment.info(
267
- f'Skipped example {example.id} as it is loaded from checkpoint.'
267
+ f'Example {example.id} is successfully evaluated (without reprocess) '
268
+ f'in {example.elapse:.2f} seconds.'
268
269
  )
269
270
 
270
271
  experiment.usage_summary.merge(example.usage_summary)
langfun/core/llms/rest.py CHANGED
@@ -103,6 +103,8 @@ class REST(lf.LanguageModel):
103
103
  error_message = str(e)
104
104
  if 'REJECTED_CLIENT_THROTTLED' in error_message:
105
105
  raise lf.TemporaryLMError(error_message) from e
106
+ if 'UNREACHABLE_ERROR' in error_message:
107
+ raise lf.TemporaryLMError(error_message) from e
106
108
  raise lf.LMError(error_message) from e
107
109
 
108
110
  def _error(self, status_code: int, content: str) -> lf.LMError:
@@ -113,6 +115,7 @@ class REST(lf.LanguageModel):
113
115
  502, # Bad gateway (upstream issue, might retry).
114
116
  503, # Servers currently under load, retry after a brief wait.
115
117
  529, # Overloaded, retry after a brief wait.
118
+ 499, # Client Closed Request
116
119
  ):
117
120
  error_cls = lf.TemporaryLMError
118
121
  else:
langfun/core/message.py CHANGED
@@ -443,11 +443,14 @@ class Message(
443
443
  metadata = dict()
444
444
  last_char = None
445
445
  for i, chunk in enumerate(chunks):
446
- if i > 0 and last_char not in ('\t', ' ', '\n'):
446
+ if i > 0 and last_char not in ('\t', ' ', '\n', None):
447
447
  fused_text.write(separator)
448
448
  if isinstance(chunk, str):
449
449
  fused_text.write(chunk)
450
- last_char = chunk[-1]
450
+ if chunk:
451
+ last_char = chunk[-1]
452
+ else:
453
+ last_char = None
451
454
  else:
452
455
  assert isinstance(chunk, modality.Modality), chunk
453
456
  var_name = f'obj{ref_index}'
@@ -476,6 +476,15 @@ class MessageTest(unittest.TestCase):
476
476
  """
477
477
  )
478
478
 
479
+ def test_from_chunks_with_empty_str(self):
480
+ chunks = ['Hello', '', 'World']
481
+ msg = message.AIMessage.from_chunks(chunks)
482
+ self.assertEqual(msg.text, 'Hello World')
483
+
484
+ chunks = ['', 'hello']
485
+ msg = message.AIMessage.from_chunks(chunks)
486
+ self.assertEqual(msg.text, 'hello')
487
+
479
488
 
480
489
  class MessageConverterTest(unittest.TestCase):
481
490
 
@@ -71,7 +71,6 @@ class SchemaTest(unittest.TestCase):
71
71
  self.assert_schema(float, pg.typing.Float())
72
72
  self.assert_schema(str, pg.typing.Str())
73
73
  self.assert_schema(bool, pg.typing.Bool())
74
- self.assert_schema(bool | None, pg.typing.Bool().noneable())
75
74
 
76
75
  # Top-level dictionary with 'result' as the only key is flattened.
77
76
  self.assert_schema(dict(result=int), pg.typing.Int())
@@ -80,10 +80,10 @@ class BasicTest(unittest.TestCase):
80
80
 
81
81
  def test_custom_typing(self):
82
82
  class Foo(component.Component):
83
- x: str | None
84
- y: int | None
83
+ x: str | None = None
84
+ y: int | None = None
85
85
  z: str
86
- p: component.Component | None
86
+ p: component.Component | None = None
87
87
 
88
88
  d = Foo(z='bar')
89
89
  # String template can be assigned to str.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: langfun
3
- Version: 0.1.2.dev202504240804
3
+ Version: 0.1.2.dev202504250804
4
4
  Summary: Langfun: Language as Functions.
5
5
  Home-page: https://github.com/google/langfun
6
6
  Author: Langfun Authors
@@ -13,8 +13,8 @@ langfun/core/language_model_test.py,sha256=iA5uo7rIj2jAtCYzMzhyNg1fWqE2Onn60bOO5
13
13
  langfun/core/logging.py,sha256=W3mLEMXdo210Q5OX3a1ZTc4nU-xMy73-IfNKnsA-RFo,8051
14
14
  langfun/core/logging_test.py,sha256=N7-YvSXC8zvnr2SNwWHOykn1CFmqvIuTLDgn41Ku9JU,6642
15
15
  langfun/core/memory.py,sha256=f-asN1F7Vehgdn_fK84v73GrEUOxRtaW934keutTKjk,2416
16
- langfun/core/message.py,sha256=1QOs_jIbehBKumQxVQigOXgN03kcGCBt5K706xHkbqg,32750
17
- langfun/core/message_test.py,sha256=RluzSk40hWNKale3SPD26oMcr-sw70KyP-4taBlHmg0,40501
16
+ langfun/core/message.py,sha256=qUJZ9NfrlYG3aU_K2ud236gdTnvZ7Qw2T4pv4hI9ivg,32817
17
+ langfun/core/message_test.py,sha256=XE7SaYJUK8TCJBdih4XtnpnB6NhcU-vLxJoaP67WbSU,40793
18
18
  langfun/core/modality.py,sha256=K8pUGuMpfWcOtVcXC_OqVjro1-RhHF6ddQni61DuYzM,4166
19
19
  langfun/core/modality_test.py,sha256=0WL_yd3B4K-FviWdSpDnOwj0f9TQI0v9t6X0vWvvJbo,2415
20
20
  langfun/core/natural_language.py,sha256=3ynSnaYQnjE60LIPK5fyMgdIjubnPYZwzGq4rWPeloE,1177
@@ -24,12 +24,12 @@ langfun/core/sampling_test.py,sha256=U7PANpMsl9E_pa4_Y4FzesSjcwg-u-LKHGCWSgv-8FY
24
24
  langfun/core/subscription.py,sha256=euawEuSZP-BHydaT-AQpfYFL0m5pWPGcW0upFhrojqc,10930
25
25
  langfun/core/subscription_test.py,sha256=Y4ZdbZEwm83YNZBxHff0QR4QUa4rdaNXA3_jfIcArBo,8717
26
26
  langfun/core/template.py,sha256=jNhYSrbLIn9kZOa03w5QZbyjgfnzJzE_ZrrMvvWY4t4,24929
27
- langfun/core/template_test.py,sha256=g7x4mgNIAXEEj-4W1D5whGfl5YikLEQoylKPzaeDomk,17069
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=AVc2aSZEvyblG_PRsri4kg5fnPrrnqjHU_sYB9EdR-o,33123
29
+ langfun/core/agentic/action.py,sha256=zm4R1D7NFi2YCMpUpc4gIR5_3Q1UgVfgYSGxhfxlvu0,33410
30
30
  langfun/core/agentic/action_eval.py,sha256=-ZcWt_eYqnTyOe9HFGyrLJkQRd4iG3hfN4IZ-NYAWwA,4534
31
31
  langfun/core/agentic/action_eval_test.py,sha256=tRUkWmOE9p0rpNOq19xAY2oDEnYsEEykjg6sUpAwJk0,2832
32
- langfun/core/agentic/action_test.py,sha256=-QDP_U8hIZA2IYmaSDIWEvVjtyXMTq3S49onjLrsqJ8,5604
32
+ langfun/core/agentic/action_test.py,sha256=HvNE175bjd5sH-Oz2rRenW9-7aw4DFTHPBn9zT6z4PA,5693
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
@@ -63,7 +63,7 @@ langfun/core/eval/v2/__init__.py,sha256=9lNKJwbvl0lcFblAXYT_OHI8fOubJsTOdSkxEqsP
63
63
  langfun/core/eval/v2/checkpointing.py,sha256=t47rBfzGZYgIqWW1N1Ak9yQnNtHd-IRbEO0cZjG2VRo,11755
64
64
  langfun/core/eval/v2/checkpointing_test.py,sha256=NggOSJ_6XSa4cNP6nGIu9wLsK59dUwe8SPWDiXtGGDE,9197
65
65
  langfun/core/eval/v2/eval_test_helper.py,sha256=sKFi_wPYCNmr96WyTduuXY0KnxjFxcJyEhXey-_nGX8,3962
66
- langfun/core/eval/v2/evaluation.py,sha256=JF4ztdkOURShiDIu3p9e8dSCGD6HUK3Y5491I7ldvV8,23929
66
+ langfun/core/eval/v2/evaluation.py,sha256=kdhou304i74LSjvCPuY4jeF7HpkQGZsKVFEhZCn1FUU,25105
67
67
  langfun/core/eval/v2/evaluation_test.py,sha256=TKbeyeenoaUDH23E3TXXJ4otuq3VZBuWkWdV7c5vMk4,6804
68
68
  langfun/core/eval/v2/example.py,sha256=Jegt-viQSNYzPVkOZE_M19GON2TYGTct4Cp9HnJ7DGo,10861
69
69
  langfun/core/eval/v2/example_test.py,sha256=1DNm6EuyZOq827DKvf3oTRVFkMNM_qTnLUpvOjpgz5I,3419
@@ -79,7 +79,7 @@ langfun/core/eval/v2/progress_tracking.py,sha256=zNhNPGlnJnHELEfFpbTMCSXFn8d1IJ5
79
79
  langfun/core/eval/v2/progress_tracking_test.py,sha256=fouMVJkFJqHjbhQJngGLGCmA9x3n0dU4USI2dY163mg,2291
80
80
  langfun/core/eval/v2/reporting.py,sha256=yUIPCAMnp7InIzpv1DDWrcLO-75iiOUTpscj7smkfrA,8335
81
81
  langfun/core/eval/v2/reporting_test.py,sha256=hcPJJaMtPulqERvHYTpId83WXdqDKnnexmULtK7WKwk,5686
82
- langfun/core/eval/v2/runners.py,sha256=Af9iCnzzyhAexcl266eYFN1s36J5B5DuFde98yNifuU,16655
82
+ langfun/core/eval/v2/runners.py,sha256=8PGNlpqSGCW4O-z0E9SHcLklZNceAzwbS7letstljPE,16652
83
83
  langfun/core/eval/v2/runners_test.py,sha256=A37fKK2MvAVTiShsg_laluJzJ9AuAQn52k7HPbfD0Ks,11666
84
84
  langfun/core/llms/__init__.py,sha256=0XyDya5doAIK_8Fjw_a78El-eBf63ggJMY8vICtQMtw,8495
85
85
  langfun/core/llms/anthropic.py,sha256=qaclpfX3qeHoZMDxU3Gn-638Vi4IyCbxdow3zgGUHK4,22195
@@ -104,7 +104,7 @@ langfun/core/llms/openai.py,sha256=F3vQkLVKeKhm34e2akqryuhjl7uOefAANUN3_i4SVhM,4
104
104
  langfun/core/llms/openai_compatible.py,sha256=JlFUTiK4e3ox2DGeGBcAD-cXkxmBdx5g6LrYkyMIaps,5777
105
105
  langfun/core/llms/openai_compatible_test.py,sha256=KwOMA7tsmOxFBjezltkBDSU77AvOQkI23dO2nHLAlB4,17689
106
106
  langfun/core/llms/openai_test.py,sha256=gwuO6aoa296iM2welWV9ua4KF8gEVGsEPakgbtkWkFQ,2687
107
- langfun/core/llms/rest.py,sha256=ucMKHXlmg6pYSIMhQSktLmTSGMSIiqO8fp1r_GiEhaU,4333
107
+ langfun/core/llms/rest.py,sha256=MCybcHApJcf49lubLnDzScN9Oc2IWY_JnMHIGdbDOuU,4474
108
108
  langfun/core/llms/rest_test.py,sha256=_zM7nV8DEVyoXNiQOnuwJ917mWjki0614H88rNmDboE,5020
109
109
  langfun/core/llms/vertexai.py,sha256=jCO1AjB3kBdBDNznygFpeXMZy-a7Lcap0NTe5Y7Wzx4,18205
110
110
  langfun/core/llms/vertexai_test.py,sha256=dOprP_uLNmXHYxMoX_hMPMsjKR-e_B5nKHjhlMCQoOQ,4252
@@ -142,7 +142,7 @@ langfun/core/structured/querying_test.py,sha256=5gNYus8Vf6lxMM7rxQGIUR_lzQw4MY7e
142
142
  langfun/core/structured/schema.py,sha256=_iqhHEGDQsHk0AsybWnK44sOspTWkKJjci781PWD7x0,27988
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=RjYhwTgktQgyqAjzLvo967nTiIK9KWgP-aNGg4e7ihE,25258
145
+ langfun/core/structured/schema_test.py,sha256=ntgPzhoVhTRzT_QKn7ipXDIc6CZmz_zCpCzZnGKc_WQ,25193
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.dev202504240804.dist-info/licenses/LICENSE,sha256=WNHhf_5RCaeuKWyq_K39vmp9F28LxKsB4SpomwSZ2L0,11357
160
- langfun-0.1.2.dev202504240804.dist-info/METADATA,sha256=dqsGhPPS45Do678sHQhqGVWijGZy4FmcgOvQCrBcN78,7692
161
- langfun-0.1.2.dev202504240804.dist-info/WHEEL,sha256=SmOxYU7pzNKBqASvQJ7DjX3XGUF92lrGhMb3R6_iiqI,91
162
- langfun-0.1.2.dev202504240804.dist-info/top_level.txt,sha256=RhlEkHxs1qtzmmtWSwYoLVJAc1YrbPtxQ52uh8Z9VvY,8
163
- langfun-0.1.2.dev202504240804.dist-info/RECORD,,
159
+ langfun-0.1.2.dev202504250804.dist-info/licenses/LICENSE,sha256=WNHhf_5RCaeuKWyq_K39vmp9F28LxKsB4SpomwSZ2L0,11357
160
+ langfun-0.1.2.dev202504250804.dist-info/METADATA,sha256=pb3hyM9a6nqaEvlFDUKBWKkZUWJue66LME5Zz26qVs0,7692
161
+ langfun-0.1.2.dev202504250804.dist-info/WHEEL,sha256=SmOxYU7pzNKBqASvQJ7DjX3XGUF92lrGhMb3R6_iiqI,91
162
+ langfun-0.1.2.dev202504250804.dist-info/top_level.txt,sha256=RhlEkHxs1qtzmmtWSwYoLVJAc1YrbPtxQ52uh8Z9VvY,8
163
+ langfun-0.1.2.dev202504250804.dist-info/RECORD,,