langfun 0.1.2.dev202505140804__py3-none-any.whl → 0.1.2.dev202505150805__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.

@@ -898,6 +898,11 @@ class ActionInvocation(pg.Object, pg.views.html.HtmlTreeView.Extension):
898
898
  """Returns the usage summary of the action."""
899
899
  return self.execution.usage_summary
900
900
 
901
+ @property
902
+ def elapse(self) -> float:
903
+ """Returns the elapsed time of the action."""
904
+ return self.execution.elapse
905
+
901
906
  def start(self) -> None:
902
907
  """Starts the execution of the action."""
903
908
  self.execution.start()
@@ -1088,6 +1093,60 @@ class Session(pg.Object, pg.views.html.HtmlTreeView.Extension):
1088
1093
  )
1089
1094
  ] = False
1090
1095
 
1096
+ #
1097
+ # Shortcut methods for accessing the root action invocation.
1098
+ #
1099
+
1100
+ @property
1101
+ def all_queries(self) -> list[lf_structured.QueryInvocation]:
1102
+ """Returns all queries made by the session."""
1103
+ return self.root.all_queries
1104
+
1105
+ @property
1106
+ def all_actions(self) -> list[ActionInvocation]:
1107
+ """Returns all actions made by the session."""
1108
+ return self.root.all_actions
1109
+
1110
+ @property
1111
+ def all_logs(self) -> list[lf.logging.LogEntry]:
1112
+ """Returns all logs made by the session."""
1113
+ return self.root.all_logs
1114
+
1115
+ @property
1116
+ def usage_summary(self) -> lf.UsageSummary:
1117
+ """Returns the usage summary of the session."""
1118
+ return self.root.usage_summary
1119
+
1120
+ @property
1121
+ def has_started(self) -> bool:
1122
+ """Returns True if the session has started."""
1123
+ return self.root.execution.has_started
1124
+
1125
+ @property
1126
+ def has_stopped(self) -> bool:
1127
+ """Returns True if the session has stopped."""
1128
+ return self.root.execution.has_stopped
1129
+
1130
+ @property
1131
+ def has_error(self) -> bool:
1132
+ """Returns True if the session has an error."""
1133
+ return self.root.has_error
1134
+
1135
+ @property
1136
+ def final_result(self) -> Any:
1137
+ """Returns the final result of the session."""
1138
+ return self.root.result
1139
+
1140
+ @property
1141
+ def final_error(self) -> pg.utils.ErrorInfo | None:
1142
+ """Returns the error of the session."""
1143
+ return self.root.error
1144
+
1145
+ @property
1146
+ def elapse(self) -> float:
1147
+ """Returns the elapsed time of the session."""
1148
+ return self.root.elapse
1149
+
1091
1150
  # NOTE(daiyip): Action execution may involve multi-threading, hence current
1092
1151
  # action and execution are thread-local.
1093
1152
 
@@ -1131,6 +1190,20 @@ class Session(pg.Object, pg.views.html.HtmlTreeView.Extension):
1131
1190
  metadata: dict[str, Any] | None = None,
1132
1191
  ) -> None:
1133
1192
  """Ends the session."""
1193
+ if error is not None:
1194
+ self.error(
1195
+ f'Trajectory failed in {self.elapse:.2f} seconds.',
1196
+ error=error,
1197
+ metadata=metadata,
1198
+ keep=True,
1199
+ )
1200
+ elif self.verbose:
1201
+ self.info(
1202
+ f'Trajectory succeeded in {self.elapse:.2f} seconds.',
1203
+ result=result,
1204
+ metadata=metadata,
1205
+ keep=False,
1206
+ )
1134
1207
  self.root.end(result, error, metadata)
1135
1208
 
1136
1209
  def __enter__(self):
@@ -1191,26 +1264,15 @@ class Session(pg.Object, pg.views.html.HtmlTreeView.Extension):
1191
1264
  yield invocation
1192
1265
  finally:
1193
1266
  if invocation.has_error:
1194
- if invocation.parent_action is self.root:
1195
- self.error(
1196
- (
1197
- f'Top-level action execution failed in '
1198
- f'{invocation.execution.elapse:.2f} seconds.'
1199
- ),
1200
- action=invocation.action,
1201
- error=invocation.error,
1202
- keep=True,
1203
- )
1204
- else:
1205
- self.warning(
1206
- (
1207
- f'Action execution failed in '
1208
- f'{invocation.execution.elapse:.2f} seconds.'
1209
- ),
1210
- action=invocation.action,
1211
- error=invocation.error,
1212
- keep=True,
1213
- )
1267
+ self.warning(
1268
+ (
1269
+ f'Action execution failed in '
1270
+ f'{invocation.execution.elapse:.2f} seconds.'
1271
+ ),
1272
+ action=invocation.action,
1273
+ error=invocation.error,
1274
+ keep=True,
1275
+ )
1214
1276
  elif self.verbose:
1215
1277
  self.info(
1216
1278
  (
@@ -1522,7 +1584,9 @@ class Session(pg.Object, pg.views.html.HtmlTreeView.Extension):
1522
1584
  for_action = self._current_action
1523
1585
  elif isinstance(for_action, Action):
1524
1586
  for_action = for_action.invocation
1525
- assert for_action is not None
1587
+ assert for_action is not None, (
1588
+ f'Action must be called before it can be logged: {for_action}'
1589
+ )
1526
1590
 
1527
1591
  log_entry = lf.logging.log(
1528
1592
  level,
@@ -1607,26 +1671,6 @@ class Session(pg.Object, pg.views.html.HtmlTreeView.Extension):
1607
1671
  result=self.root
1608
1672
  )
1609
1673
 
1610
- @property
1611
- def final_result(self) -> Any:
1612
- """Returns the final result of the session."""
1613
- return self.root.result
1614
-
1615
- @property
1616
- def has_started(self) -> bool:
1617
- """Returns whether the session has started."""
1618
- return self.root.execution.has_started
1619
-
1620
- @property
1621
- def has_stopped(self) -> bool:
1622
- """Returns whether the session has stopped."""
1623
- return self.root.execution.has_stopped
1624
-
1625
- @property
1626
- def has_error(self) -> bool:
1627
- """Returns whether the session has an error."""
1628
- return self.root.has_error
1629
-
1630
1674
  @property
1631
1675
  def current_action(self) -> ActionInvocation:
1632
1676
  """Returns the current invocation."""
@@ -155,15 +155,19 @@ class SessionTest(unittest.TestCase):
155
155
  )
156
156
 
157
157
  # The root space should have one action (foo), no queries, and no logs.
158
- self.assertEqual(len(list(root.actions)), 1)
159
- self.assertEqual(len(list(root.queries)), 0)
160
- self.assertEqual(len(list(root.logs)), 0)
158
+ self.assertEqual(len(root.actions), 1)
159
+ self.assertEqual(len(root.queries), 0)
160
+ self.assertEqual(len(root.logs), 0)
161
161
  # 1 query from Bar, 2 from Foo and 3 from parallel executions.
162
- self.assertEqual(len(list(root.all_queries)), 6)
162
+ self.assertEqual(len(session.all_queries), 6)
163
+ self.assertEqual(len(root.all_queries), 6)
163
164
  # 2 actions: Foo and Bar.
164
- self.assertEqual(len(list(root.all_actions)), 2)
165
+ self.assertEqual(len(session.all_actions), 2)
166
+ self.assertEqual(len(root.all_actions), 2)
165
167
  # 1 log from Bar and 1 from Foo.
166
- self.assertEqual(len(list(root.all_logs)), 2)
168
+ self.assertEqual(len(session.all_logs), 2)
169
+ self.assertEqual(len(root.all_logs), 2)
170
+ self.assertIs(session.usage_summary, root.usage_summary)
167
171
  self.assertEqual(root.usage_summary.total.num_requests, 6)
168
172
 
169
173
  # Inspecting the top-level action (Foo)
@@ -276,7 +280,7 @@ class SessionTest(unittest.TestCase):
276
280
  foo_invocation = root.execution[0]
277
281
  self.assertIsInstance(foo_invocation, action_lib.ActionInvocation)
278
282
  self.assertTrue(foo_invocation.has_error)
279
- self.assertEqual(len(foo_invocation.execution.items), 2)
283
+ self.assertEqual(len(foo_invocation.execution.items), 3)
280
284
 
281
285
  def test_succeeded_with_implicit_session(self):
282
286
  lm = fake.StaticResponse('lm response')
@@ -304,7 +308,7 @@ class SessionTest(unittest.TestCase):
304
308
  self.assertTrue(session.has_started)
305
309
  self.assertTrue(session.has_stopped)
306
310
  self.assertTrue(session.has_error)
307
- self.assertIsInstance(session.root.error, pg.utils.ErrorInfo)
311
+ self.assertIsInstance(session.final_error, pg.utils.ErrorInfo)
308
312
  self.assertIn('Bar error', str(session.root.error))
309
313
 
310
314
  def test_succeeded_with_explicit_session(self):
@@ -409,7 +413,9 @@ class SessionTest(unittest.TestCase):
409
413
  self.assertTrue(session.has_stopped)
410
414
  self.assertTrue(session.has_error)
411
415
  self.assertIsInstance(session.root.error, pg.utils.ErrorInfo)
412
- self.assertEqual(len(session.root.execution), 2)
416
+ self.assertEqual(len(session.root.execution), 3)
417
+ self.assertEqual(len(session.root.actions), 2)
418
+ self.assertEqual(len(session.root.logs), 1)
413
419
  self.assertFalse(session.root.execution[0].has_error)
414
420
  self.assertTrue(session.root.execution[1].has_error)
415
421
 
@@ -509,17 +509,13 @@ class Anthropic(rest.REST):
509
509
  raise ValueError(f'Unsupported modality: {chunk!r}.')
510
510
  return chunk
511
511
 
512
- messages = []
513
512
  if system_message := prompt.get('system_message'):
514
513
  assert isinstance(system_message, lf.SystemMessage), type(system_message)
515
- messages.append(
516
- system_message.as_format(
517
- 'anthropic', chunk_preprocessor=modality_check
518
- )
519
- )
520
- messages.append(
514
+ request['system'] = system_message.text
515
+
516
+ messages = [
521
517
  prompt.as_format('anthropic', chunk_preprocessor=modality_check)
522
- )
518
+ ]
523
519
  request.update(messages=messages)
524
520
  return request
525
521
 
@@ -31,21 +31,46 @@ def mock_requests_post(url: str, json: dict[str, Any], **kwargs):
31
31
 
32
32
  response = requests.Response()
33
33
  response.status_code = 200
34
+
35
+ # Construct base text from user/assistant messages payload
36
+ messages_payload_text = '\n'.join(
37
+ c['content'][0]['text']
38
+ for c in json.get('messages', [])
39
+ if c.get('content')
40
+ and isinstance(c['content'], list)
41
+ and c['content']
42
+ and c['content'][0].get('type') == 'text'
43
+ and 'text' in c['content'][0]
44
+ )
45
+
46
+ # Check for a system prompt in the request payload
47
+ system_prompt_text = json.get('system')
48
+
49
+ processed_text_parts = []
50
+ if system_prompt_text:
51
+ processed_text_parts.append(system_prompt_text)
52
+ if messages_payload_text:
53
+ processed_text_parts.append(messages_payload_text)
54
+
55
+ processed_text = '\n'.join(processed_text_parts)
56
+
57
+ response_content_text = (
58
+ f'{processed_text} with temperature={json.get("temperature")}, '
59
+ f'top_k={json.get("top_k")}, '
60
+ f'top_p={json.get("top_p")}, '
61
+ f'max_tokens={json.get("max_tokens")}, '
62
+ f'stop={json.get("stop_sequences")}.'
63
+ )
64
+
34
65
  response._content = pg.to_json_str({
35
- 'content': [{
36
- 'type': 'text',
37
- 'text': (
38
- '\n'.join(c['content'][0]['text'] for c in json['messages']) +
39
- f' with temperature={json.get("temperature")}, '
40
- f'top_k={json.get("top_k")}, '
41
- f'top_p={json.get("top_p")}, '
42
- f'max_tokens={json.get("max_tokens")}, '
43
- f'stop={json.get("stop_sequences")}.'
44
- ),
45
- }],
66
+ 'content': [{'type': 'text', 'text': response_content_text}],
46
67
  'usage': {
47
- 'input_tokens': 2,
48
- 'output_tokens': 1,
68
+ 'input_tokens': (
69
+ 2
70
+ ), # Placeholder: adjust if tests need accurate token counts
71
+ 'output_tokens': (
72
+ 1
73
+ ), # Placeholder: adjust if tests need accurate token counts
49
74
  },
50
75
  }).encode()
51
76
  return response
@@ -155,7 +155,7 @@ SUPPORTED_MODELS = [
155
155
  GeminiModelInfo(
156
156
  model_id='gemini-2.5-pro-preview-05-06',
157
157
  in_service=True,
158
- provider=pg.oneof(['Google GenAI', ' VertexAI']),
158
+ provider=pg.oneof(['Google GenAI', 'VertexAI']),
159
159
  model_type='instruction-tuned',
160
160
  description='Gemini 2.5 Pro.',
161
161
  release_date=datetime.datetime(2025, 5, 6),
@@ -178,7 +178,7 @@ SUPPORTED_MODELS = [
178
178
  GeminiModelInfo(
179
179
  model_id='gemini-2.5-flash-preview-04-17',
180
180
  in_service=True,
181
- provider=pg.oneof(['Google GenAI', ' VertexAI']),
181
+ provider=pg.oneof(['Google GenAI', 'VertexAI']),
182
182
  model_type='instruction-tuned',
183
183
  description='Gemini 2.5 Flash.',
184
184
  release_date=datetime.datetime(2025, 4, 17),
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: langfun
3
- Version: 0.1.2.dev202505140804
3
+ Version: 0.1.2.dev202505150805
4
4
  Summary: Langfun: Language as Functions.
5
5
  Home-page: https://github.com/google/langfun
6
6
  Author: Langfun Authors
@@ -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=G2HwLr8SZe0fpqGBu5obuzMz3EDMl-xFJab5myQOBv4,49571
29
+ langfun/core/agentic/action.py,sha256=WEKCaqtGVYKHARvY0Nqichc_hMKkJUYarrUky-DsfHk,50709
30
30
  langfun/core/agentic/action_eval.py,sha256=YTilyUEkJl_8FVMgdfO17PurWWaEJ6oA15CuefJJRLk,4887
31
31
  langfun/core/agentic/action_eval_test.py,sha256=7AkOwNbUX-ZgR1R0a7bvUZ5abNTUV7blf_8Mnrwb-II,2811
32
- langfun/core/agentic/action_test.py,sha256=wrx7_JUyL6EXhJeUqmPkPyIwOAh_KwTOWhSRgv2wYWo,15613
32
+ langfun/core/agentic/action_test.py,sha256=FO42Ab_riHHJxD6iJensskDCMx1-j7blzPr3fFaIfwc,15885
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=4PD76Xfv36Xrm8Ji3-GgGDNImtcDqWfMw3z6ircJMlM,7285
@@ -82,8 +82,8 @@ langfun/core/eval/v2/reporting_test.py,sha256=hcPJJaMtPulqERvHYTpId83WXdqDKnnexm
82
82
  langfun/core/eval/v2/runners.py,sha256=iqbH4jMtnNMhfuv1eHaxJmk1Vvsrz-sAJJFP8U44-tA,16758
83
83
  langfun/core/eval/v2/runners_test.py,sha256=DO3xV0sBNB6n65j41xx2i7gqUCJcPF37DFZLEjrmISg,11987
84
84
  langfun/core/llms/__init__.py,sha256=QWxRhzVn_vgJvdmW_xs5PcPuDbHsUxTU94YyV4Ofl34,8684
85
- langfun/core/llms/anthropic.py,sha256=qaclpfX3qeHoZMDxU3Gn-638Vi4IyCbxdow3zgGUHK4,22195
86
- langfun/core/llms/anthropic_test.py,sha256=dFnNvrgwCYUseDuiuWCBoQ5jloYX9RIlZQf7cCLPNU4,8282
85
+ langfun/core/llms/anthropic.py,sha256=dCkTYvwb_wWWeKQNzMtRfA6kno1E_bO9PBHSNqL0wiw,22080
86
+ langfun/core/llms/anthropic_test.py,sha256=qA9vByp_cwwXNlXzcwHpPWFnO9lfFo8NKfDi5nBNqgI,9052
87
87
  langfun/core/llms/azure_openai.py,sha256=-KkSLaR54MlsIqz_XIwv0TnsBnvNTAxnjA2Q2O2u5KM,2733
88
88
  langfun/core/llms/azure_openai_test.py,sha256=lkMZkQdJBV97fTM4C4z8qNfvr6spgiN5G4hvVUIVr0M,1735
89
89
  langfun/core/llms/compositional.py,sha256=csW_FLlgL-tpeyCOTVvfUQkMa_zCN5Y2I-YbSNuK27U,2872
@@ -92,7 +92,7 @@ langfun/core/llms/deepseek.py,sha256=jvTxdXPr-vH6HNakn_Ootx1heDg8Fen2FUkUW36bpCs
92
92
  langfun/core/llms/deepseek_test.py,sha256=DvROWPlDuow5E1lfoSkhyGt_ELA19JoQoDsTnRgDtTg,1847
93
93
  langfun/core/llms/fake.py,sha256=xmgCkk9y0I4x0IT32SZ9_OT27aLadXH8PRiYNo5VTd4,3265
94
94
  langfun/core/llms/fake_test.py,sha256=2h13qkwEz_JR0mtUDPxdAhQo7MueXaFSwsD2DIRDW9g,7653
95
- langfun/core/llms/gemini.py,sha256=ij3NJHhAcs8-H4H2P4ny78q5L9iAmjQC4cu8nUyoPDA,25591
95
+ langfun/core/llms/gemini.py,sha256=JCxwTDdOBBhtME_s-wxV3-fOREIkQ-uMOVYFg09RmfQ,25589
96
96
  langfun/core/llms/gemini_test.py,sha256=Ve9X2Wvwu9wVFHpKZDP-qoM1_hzB4kgt6_HR9wxtNkg,7592
97
97
  langfun/core/llms/google_genai.py,sha256=YjvyasibmXYPFr_sxdrIdHDPHfaNzMCiJjWJs0iQyms,5188
98
98
  langfun/core/llms/google_genai_test.py,sha256=NKNtpebArQ9ZR7Qsnhd2prFIpMjleojy6o6VMXkJ1zY,1502
@@ -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.dev202505140804.dist-info/licenses/LICENSE,sha256=WNHhf_5RCaeuKWyq_K39vmp9F28LxKsB4SpomwSZ2L0,11357
160
- langfun-0.1.2.dev202505140804.dist-info/METADATA,sha256=sg9BNWj3ZTxdvhCni6lzMwhy9PJwBSa4tSv_saN6RQ0,8178
161
- langfun-0.1.2.dev202505140804.dist-info/WHEEL,sha256=DnLRTWE75wApRYVsjgc6wsVswC54sMSJhAEd4xhDpBk,91
162
- langfun-0.1.2.dev202505140804.dist-info/top_level.txt,sha256=RhlEkHxs1qtzmmtWSwYoLVJAc1YrbPtxQ52uh8Z9VvY,8
163
- langfun-0.1.2.dev202505140804.dist-info/RECORD,,
159
+ langfun-0.1.2.dev202505150805.dist-info/licenses/LICENSE,sha256=WNHhf_5RCaeuKWyq_K39vmp9F28LxKsB4SpomwSZ2L0,11357
160
+ langfun-0.1.2.dev202505150805.dist-info/METADATA,sha256=O9L1gbEi6xg41c0yHT45Pla-2HS9u_5f4f04flDUcIw,8178
161
+ langfun-0.1.2.dev202505150805.dist-info/WHEEL,sha256=Nw36Djuh_5VDukK0H78QzOX-_FQEo6V37m3nkm96gtU,91
162
+ langfun-0.1.2.dev202505150805.dist-info/top_level.txt,sha256=RhlEkHxs1qtzmmtWSwYoLVJAc1YrbPtxQ52uh8Z9VvY,8
163
+ langfun-0.1.2.dev202505150805.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.4.0)
2
+ Generator: setuptools (80.7.1)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5