langfun 0.1.2.dev202505040804__py3-none-any.whl → 0.1.2.dev202505060804__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.

@@ -194,6 +194,11 @@ class Action(pg.Object):
194
194
  """Returns the metadata associated with the result from previous call."""
195
195
  return self._invocation.metadata if self._invocation else None
196
196
 
197
+ @property
198
+ def invocation(self) -> Optional['ActionInvocation']:
199
+ """Returns last invocation. None if the action is not executed."""
200
+ return self._invocation
201
+
197
202
  def __call__(
198
203
  self,
199
204
  session: Optional['Session'] = None,
@@ -825,6 +830,7 @@ class ActionInvocation(pg.Object, pg.views.html.HtmlTreeView.Extension):
825
830
  def _on_bound(self):
826
831
  super()._on_bound()
827
832
  self._tab_control = None
833
+ self.action._invocation = self # pylint: disable=protected-access
828
834
 
829
835
  def _on_parent_change(self, *args, **kwargs):
830
836
  super()._on_parent_change(*args, **kwargs)
@@ -1154,7 +1160,6 @@ class Session(pg.Object, pg.views.html.HtmlTreeView.Extension):
1154
1160
  )
1155
1161
 
1156
1162
  invocation = ActionInvocation(pg.maybe_ref(action))
1157
- action._invocation = invocation # pylint: disable=protected-access
1158
1163
  parent_action = self._current_action
1159
1164
  parent_execution = self._current_execution
1160
1165
  parent_execution.append(invocation)
@@ -1412,38 +1417,103 @@ class Session(pg.Object, pg.views.html.HtmlTreeView.Extension):
1412
1417
  level: lf.logging.LogLevel,
1413
1418
  message: str,
1414
1419
  keep: bool,
1420
+ *,
1421
+ for_action: Action | ActionInvocation | None = None,
1415
1422
  **kwargs
1416
1423
  ) -> None:
1417
- """Logs a message to the session."""
1418
- action_name = self._current_action.action.__class__.__name__
1424
+ """Logs a message to the session.
1425
+
1426
+ Args:
1427
+ level: The logging level.
1428
+ message: The message to log.
1429
+ keep: Whether to keep the log entry in the execution trace.
1430
+ for_action: The action to log the message for. If not provided, the
1431
+ current action will be used.
1432
+ **kwargs: Additional keyword arguments to pass to `lf.logging.log` as
1433
+ metadata to show.
1434
+ """
1419
1435
  execution = self._current_execution
1436
+ if for_action is None:
1437
+ for_action = self._current_action
1438
+ elif isinstance(for_action, Action):
1439
+ for_action = for_action.invocation
1440
+ assert for_action is not None
1441
+
1420
1442
  log_entry = lf.logging.log(
1421
1443
  level,
1422
- f'[{execution.id} ({action_name})]: {message}',
1444
+ (
1445
+ f'[{for_action.id} ({for_action.action.__class__.__name__})]: '
1446
+ f'{message}'
1447
+ ),
1423
1448
  **kwargs
1424
1449
  )
1425
1450
  if keep:
1426
1451
  execution.append(log_entry)
1427
1452
 
1428
- def debug(self, message: str, keep: bool = True, **kwargs):
1453
+ def debug(
1454
+ self,
1455
+ message: str,
1456
+ keep: bool = True,
1457
+ *,
1458
+ for_action: Action | ActionInvocation | None = None,
1459
+ **kwargs
1460
+ ) -> None:
1429
1461
  """Logs a debug message to the session."""
1430
- self._log('debug', message, keep=keep, **kwargs)
1462
+ self._log(
1463
+ 'debug', message, keep=keep, for_action=for_action, **kwargs
1464
+ )
1431
1465
 
1432
- def info(self, message: str, keep: bool = True, **kwargs):
1466
+ def info(
1467
+ self,
1468
+ message: str,
1469
+ keep: bool = True,
1470
+ *,
1471
+ for_action: Action | ActionInvocation | None = None,
1472
+ **kwargs
1473
+ ) -> None:
1433
1474
  """Logs an info message to the session."""
1434
- self._log('info', message, keep=keep, **kwargs)
1475
+ self._log(
1476
+ 'info', message, keep=keep, for_action=for_action, **kwargs
1477
+ )
1435
1478
 
1436
- def warning(self, message: str, keep: bool = True, **kwargs):
1479
+ def warning(
1480
+ self,
1481
+ message: str,
1482
+ keep: bool = True,
1483
+ *,
1484
+ for_action: Action | ActionInvocation | None = None,
1485
+ **kwargs
1486
+ ) -> None:
1437
1487
  """Logs a warning message to the session."""
1438
- self._log('warning', message, keep=keep, **kwargs)
1488
+ self._log(
1489
+ 'warning', message, keep=keep, for_action=for_action, **kwargs
1490
+ )
1439
1491
 
1440
- def error(self, message: str, keep: bool = True, **kwargs):
1492
+ def error(
1493
+ self,
1494
+ message: str,
1495
+ keep: bool = True,
1496
+ *,
1497
+ for_action: Action | ActionInvocation | None = None,
1498
+ **kwargs
1499
+ ):
1441
1500
  """Logs an error message to the session."""
1442
- self._log('error', message, keep=keep, **kwargs)
1501
+ self._log(
1502
+ 'error', message, keep=keep, for_action=for_action, **kwargs
1503
+ )
1443
1504
 
1444
- def fatal(self, message: str, **kwargs):
1505
+ def fatal(
1506
+ self,
1507
+ message: str,
1508
+ keep: bool = True,
1509
+ *,
1510
+ for_action: Action | ActionInvocation | None = None,
1511
+ **kwargs
1512
+ ):
1445
1513
  """Logs a fatal message to the session."""
1446
- self._log('fatal', message, keep=True, **kwargs)
1514
+ self._log(
1515
+ 'fatal', message, keep=keep, for_action=for_action, **kwargs
1516
+ )
1447
1517
 
1448
1518
  def as_message(self) -> lf.AIMessage:
1449
1519
  """Returns the session as a message."""
@@ -107,6 +107,7 @@ class SessionTest(unittest.TestCase):
107
107
  lm = fake.StaticResponse('lm response')
108
108
  foo = Foo(1)
109
109
  self.assertIsNone(foo.session)
110
+ self.assertIsNone(foo.invocation)
110
111
  self.assertIsNone(foo.result)
111
112
  self.assertIsNone(foo.metadata)
112
113
 
@@ -167,6 +168,7 @@ class SessionTest(unittest.TestCase):
167
168
 
168
169
  # Inspecting the top-level action (Foo)
169
170
  foo_invocation = root.execution[0]
171
+ self.assertIs(foo.invocation, foo_invocation)
170
172
  self.assertIs(foo_invocation.parent_action, root)
171
173
  self.assertEqual(foo_invocation.id, 'agent@1:/a1')
172
174
  self.assertEqual(foo_invocation.execution.id, 'agent@1:/a1')
@@ -414,8 +416,8 @@ class SessionTest(unittest.TestCase):
414
416
  def test_log(self):
415
417
  session = action_lib.Session()
416
418
  session.debug('hi', x=1, y=2)
417
- session.info('hi', x=1, y=2)
418
- session.warning('hi', x=1, y=2)
419
+ session.info('hi', x=1, y=2, for_action=session.root)
420
+ session.warning('hi', x=1, y=2, for_action=session.root.action)
419
421
  session.error('hi', x=1, y=2)
420
422
  session.fatal('hi', x=1, y=2)
421
423
 
@@ -213,7 +213,8 @@ class ModelInfo(pg.Object):
213
213
  return None
214
214
  return (
215
215
  self.cost_per_1m_input_tokens * usage.prompt_tokens
216
- + self.cost_per_1m_output_tokens * usage.completion_tokens
216
+ + self.cost_per_1m_output_tokens
217
+ * (usage.total_tokens - usage.prompt_tokens)
217
218
  ) / 1000_000
218
219
 
219
220
  pricing: Annotated[
@@ -87,6 +87,7 @@ VertexAIGeminiFlash1_5 = VertexAIGemini15Flash
87
87
  # OpenAI models.
88
88
  from langfun.core.llms.openai import OpenAI
89
89
 
90
+ from langfun.core.llms.openai import Gpt41
90
91
  from langfun.core.llms.openai import GptO3
91
92
  from langfun.core.llms.openai import GptO4Mini
92
93
  from langfun.core.llms.openai import Gpt45Preview_20250227
@@ -133,7 +133,7 @@ class GeminiModelInfo(lf.ModelInfo):
133
133
  self.cost_per_1m_input_tokens_with_prompt_longer_than_128k
134
134
  * usage.prompt_tokens
135
135
  + self.cost_per_1m_output_tokens_with_prompt_longer_than_128k
136
- * usage.completion_tokens
136
+ * (usage.total_tokens - usage.prompt_tokens)
137
137
  ) / 1000_000
138
138
 
139
139
  experimental: Annotated[
@@ -657,7 +657,7 @@ class Gemini(rest.REST):
657
657
  def result(self, json: dict[str, Any]) -> lf.LMSamplingResult:
658
658
  messages = [
659
659
  lf.Message.from_value(candidate['content'], format='gemini')
660
- for candidate in json['candidates']
660
+ for candidate in json.get('candidates', [])
661
661
  ]
662
662
  usage = json['usageMetadata']
663
663
  input_tokens = usage['promptTokenCount']
@@ -49,6 +49,30 @@ class OpenAIModelInfo(lf.ModelInfo):
49
49
  #
50
50
 
51
51
  SUPPORTED_MODELS = [
52
+ # GPT-4.1 models
53
+ OpenAIModelInfo(
54
+ model_id='gpt-4.1',
55
+ alias_for='gpt-4.1-2025-04-14',
56
+ in_service=True,
57
+ model_type='instruction-tuned',
58
+ description='GPT 4.1 model (latest stable).',
59
+ url='https://platform.openai.com/docs/models/gpt-4.1',
60
+ input_modalities=OpenAIModelInfo.INPUT_IMAGE_TYPES,
61
+ context_length=lf.ModelInfo.ContextLength(
62
+ max_input_tokens=1_047_576,
63
+ max_output_tokens=32_768,
64
+ ),
65
+ pricing=lf.ModelInfo.Pricing(
66
+ cost_per_1m_cached_input_tokens=0.50,
67
+ cost_per_1m_input_tokens=2.0,
68
+ cost_per_1m_output_tokens=8.0,
69
+ ),
70
+ # Tier 5 rate limits.
71
+ rate_limits=lf.ModelInfo.RateLimits(
72
+ max_requests_per_minute=10_000,
73
+ max_tokens_per_minute=30_000_000,
74
+ ),
75
+ ),
52
76
  # o3 models.
53
77
  OpenAIModelInfo(
54
78
  model_id='o3',
@@ -1045,6 +1069,11 @@ class OpenAI(openai_compatible.OpenAICompatible):
1045
1069
  return super()._request_args(options)
1046
1070
 
1047
1071
 
1072
+ class Gpt41(OpenAI):
1073
+ """GPT-4.1."""
1074
+ model = 'gpt-4.1'
1075
+
1076
+
1048
1077
  class GptO4Mini(OpenAI):
1049
1078
  """GPT O4 mini."""
1050
1079
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: langfun
3
- Version: 0.1.2.dev202505040804
3
+ Version: 0.1.2.dev202505060804
4
4
  Summary: Langfun: Language as Functions.
5
5
  Home-page: https://github.com/google/langfun
6
6
  Author: Langfun Authors
@@ -8,7 +8,7 @@ langfun/core/console.py,sha256=V_mOiFi9oGh8gLsUeR56pdFDkuvYOpvQt7DY1KUTWTA,2535
8
8
  langfun/core/console_test.py,sha256=pBOcuNMJdVELywvroptfcRtJMsegMm3wSlHAL2TdxVk,1679
9
9
  langfun/core/langfunc.py,sha256=G50YgoVZ0y1GFw2ev41MlOqr6qa8YakbvNC0h_E0PiA,11140
10
10
  langfun/core/langfunc_test.py,sha256=CDn-gJCa5EnjN7cotAVCfSCbuzddq2o-HzEt7kV8HbY,8882
11
- langfun/core/language_model.py,sha256=_hT8dGHw7CWQgMTQ-Ons5VTOwpF_j8k_gn2P0hoG-lE,46307
11
+ langfun/core/language_model.py,sha256=c6Vds9qXuC0BiHeZstxCTTsoU8ZL9K4w4co_hXA3-RI,46336
12
12
  langfun/core/language_model_test.py,sha256=iA5uo7rIj2jAtCYzMzhyNg1fWqE2Onn60bOO58q72C0,36454
13
13
  langfun/core/logging.py,sha256=ypjSwGzQpIhadewEKkIH5VWS55rfU4e6mlni41PMHlw,9116
14
14
  langfun/core/logging_test.py,sha256=vbVGOQxwMmVSiFfbt2897gUt-8nqDpV64jCAeUG_q5U,6924
@@ -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=3m2-k07Zz8qrzOdOa7xPl7fRH3I0c3VsMLR86_JBCcU,45359
29
+ langfun/core/agentic/action.py,sha256=jxjW4vkJs3p-AYb83P0AVnmE93Vx7z0QoFsm40NQ65k,46853
30
30
  langfun/core/agentic/action_eval.py,sha256=JXhS5qEjWu9EZ0chDsjWxCqPAV26PUCBijtUYxiDeO4,4975
31
31
  langfun/core/agentic/action_eval_test.py,sha256=7AkOwNbUX-ZgR1R0a7bvUZ5abNTUV7blf_8Mnrwb-II,2811
32
- langfun/core/agentic/action_test.py,sha256=ezqg3tKlVwgLMnHKUmOdtxpnntuL8YIvhcTCSSdb8oc,15468
32
+ langfun/core/agentic/action_test.py,sha256=wrx7_JUyL6EXhJeUqmPkPyIwOAh_KwTOWhSRgv2wYWo,15613
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
@@ -81,7 +81,7 @@ langfun/core/eval/v2/reporting.py,sha256=yUIPCAMnp7InIzpv1DDWrcLO-75iiOUTpscj7sm
81
81
  langfun/core/eval/v2/reporting_test.py,sha256=hcPJJaMtPulqERvHYTpId83WXdqDKnnexmULtK7WKwk,5686
82
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
- langfun/core/llms/__init__.py,sha256=0XyDya5doAIK_8Fjw_a78El-eBf63ggJMY8vICtQMtw,8495
84
+ langfun/core/llms/__init__.py,sha256=Fr4ScBDvWnfZQvdoUIlmdEG02zkWAvj8DxsFGsiV4mo,8538
85
85
  langfun/core/llms/anthropic.py,sha256=qaclpfX3qeHoZMDxU3Gn-638Vi4IyCbxdow3zgGUHK4,22195
86
86
  langfun/core/llms/anthropic_test.py,sha256=dFnNvrgwCYUseDuiuWCBoQ5jloYX9RIlZQf7cCLPNU4,8282
87
87
  langfun/core/llms/azure_openai.py,sha256=-KkSLaR54MlsIqz_XIwv0TnsBnvNTAxnjA2Q2O2u5KM,2733
@@ -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=ZtUo2lQMSByYlzSALWae3KxFiKNtOOwGbkFwZTI1dO0,24472
95
+ langfun/core/llms/gemini.py,sha256=S9TT_p-UWTdYnyUzQa1pnrvAu9SnFu2E2V2suxJ_3SU,24499
96
96
  langfun/core/llms/gemini_test.py,sha256=Ve9X2Wvwu9wVFHpKZDP-qoM1_hzB4kgt6_HR9wxtNkg,7592
97
97
  langfun/core/llms/google_genai.py,sha256=j8W22WFvkT80Fw-r7Rg-e7MKhcSwljZkmtuufwSEn5s,5051
98
98
  langfun/core/llms/google_genai_test.py,sha256=NKNtpebArQ9ZR7Qsnhd2prFIpMjleojy6o6VMXkJ1zY,1502
@@ -100,7 +100,7 @@ langfun/core/llms/groq.py,sha256=S9V10kFo3cgX89qPgt_umq-SpRnxEDLTt_hJmpERfbo,120
100
100
  langfun/core/llms/groq_test.py,sha256=P4EgexCqsh4K2x11w0UL_vz-YYNaPdQU0WsDAdnTRQ8,2045
101
101
  langfun/core/llms/llama_cpp.py,sha256=Z7P3gc4xeIjc2bX0Ey1y5EUYJVMnMa2Q67PZ9iye9sE,1409
102
102
  langfun/core/llms/llama_cpp_test.py,sha256=wfTO7nmUwL65U2kK9P9fcMt92JjNDuVia4G1E7znf_4,1086
103
- langfun/core/llms/openai.py,sha256=F3vQkLVKeKhm34e2akqryuhjl7uOefAANUN3_i4SVhM,41414
103
+ langfun/core/llms/openai.py,sha256=LxENwsuGh-h1LXMu2Ub8Rjp1g1WNpm1NHBrwhkD-M4Q,42333
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
@@ -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.dev202505040804.dist-info/licenses/LICENSE,sha256=WNHhf_5RCaeuKWyq_K39vmp9F28LxKsB4SpomwSZ2L0,11357
160
- langfun-0.1.2.dev202505040804.dist-info/METADATA,sha256=5IYkqanozH8dVb3Nr0bH2jmybe-FPKrvx7-nAEPNCeM,8178
161
- langfun-0.1.2.dev202505040804.dist-info/WHEEL,sha256=GHB6lJx2juba1wDgXDNlMTyM13ckjBMKf-OnwgKOCtA,91
162
- langfun-0.1.2.dev202505040804.dist-info/top_level.txt,sha256=RhlEkHxs1qtzmmtWSwYoLVJAc1YrbPtxQ52uh8Z9VvY,8
163
- langfun-0.1.2.dev202505040804.dist-info/RECORD,,
159
+ langfun-0.1.2.dev202505060804.dist-info/licenses/LICENSE,sha256=WNHhf_5RCaeuKWyq_K39vmp9F28LxKsB4SpomwSZ2L0,11357
160
+ langfun-0.1.2.dev202505060804.dist-info/METADATA,sha256=nWF0YcXH9lFbXYgzHPjf7Dr_qqw223Kt230LtPpsGEA,8178
161
+ langfun-0.1.2.dev202505060804.dist-info/WHEEL,sha256=0CuiUZ_p9E4cD6NyLD6UG80LBXYyiSYZOKDm5lp32xk,91
162
+ langfun-0.1.2.dev202505060804.dist-info/top_level.txt,sha256=RhlEkHxs1qtzmmtWSwYoLVJAc1YrbPtxQ52uh8Z9VvY,8
163
+ langfun-0.1.2.dev202505060804.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.3.0)
2
+ Generator: setuptools (80.3.1)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5