langfun 0.1.2.dev202411060804__py3-none-any.whl → 0.1.2.dev202411090804__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.
@@ -85,12 +85,12 @@ class Scoring(base.Evaluation):
85
85
  del progress
86
86
  return {
87
87
  'Average Score': {self.avg_score},
88
- 'Scored': '%.2f%% (%d/%d)' % (
88
+ 'Scored': '%.3f%% (%d/%d)' % (
89
89
  self.score_rate * 100,
90
90
  self.num_scored,
91
91
  self.num_completed,
92
92
  ),
93
- 'Failed': '%.2f%% (%d/%d)' % (
93
+ 'Failed': '%.3f%% (%d/%d)' % (
94
94
  self.failure_rate * 100,
95
95
  self.num_failures,
96
96
  self.num_completed,
@@ -101,8 +101,8 @@ class Scoring(base.Evaluation):
101
101
  assert self.result is not None
102
102
  m = self.result.metrics
103
103
  return (
104
- 'COMPLETED(%s): AvgScore=%f Scored=%.2f%% (%d/%d) '
105
- 'Failures=%.2f%% (%d/%d)'
104
+ 'COMPLETED(%s): AvgScore=%f Scored=%.3f%% (%d/%d) '
105
+ 'Failures=%.3f%% (%d/%d)'
106
106
  ) % (
107
107
  run_status,
108
108
  m.avg_score,
@@ -155,12 +155,12 @@ class Scoring(base.Evaluation):
155
155
  def _render_result_row(self, s: io.StringIO):
156
156
  super()._render_result_row(s)
157
157
  s.write(
158
- '<td><span style="color:blue">%.2f</span></td>' % self.avg_score
158
+ '<td><span style="color:blue">%.3f</span></td>' % self.avg_score
159
159
  )
160
160
  s.write(
161
161
  '<td><span style="color:red">%s</span>%s</td>'
162
162
  % (
163
- '%.2f%% ' % (self.score_rate * 100),
163
+ '%.3f%% ' % (self.score_rate * 100),
164
164
  '<a href="%s">(%d/%d)</a>'
165
165
  % (self.scored_link, self.num_scored, self.num_completed),
166
166
  )
@@ -173,7 +173,7 @@ class Scoring(base.Evaluation):
173
173
  self._render_link(
174
174
  s,
175
175
  'Average score (%d/%d)' % (m.num_scored, m.total),
176
- '%.2f (%.2f%%)' % (m.avg_score, m.score_rate * 100),
176
+ '%.3f (%.3f%%)' % (m.avg_score, m.score_rate * 100),
177
177
  'color:green',
178
178
  lambda: self.scored_link,
179
179
  )
@@ -95,6 +95,9 @@ from langfun.core.llms.anthropic import Claude35Sonnet20240620
95
95
  from langfun.core.llms.anthropic import Claude3Opus
96
96
  from langfun.core.llms.anthropic import Claude3Sonnet
97
97
  from langfun.core.llms.anthropic import Claude3Haiku
98
+ from langfun.core.llms.anthropic import VertexAIAnthropic
99
+ from langfun.core.llms.anthropic import VertexAIClaude3_5_Sonnet_20241022
100
+ from langfun.core.llms.anthropic import VertexAIClaude3_5_Haiku_20241022
98
101
 
99
102
  from langfun.core.llms.groq import Groq
100
103
  from langfun.core.llms.groq import GroqLlama3_2_3B
@@ -14,8 +14,9 @@
14
14
  """Language models from Anthropic."""
15
15
 
16
16
  import base64
17
+ import functools
17
18
  import os
18
- from typing import Annotated, Any
19
+ from typing import Annotated, Any, Literal
19
20
 
20
21
  import langfun.core as lf
21
22
  from langfun.core import modalities as lf_modalities
@@ -23,6 +24,20 @@ from langfun.core.llms import rest
23
24
  import pyglove as pg
24
25
 
25
26
 
27
+ try:
28
+ # pylint: disable=g-import-not-at-top
29
+ from google import auth as google_auth
30
+ from google.auth import credentials as credentials_lib
31
+ from google.auth.transport import requests as auth_requests
32
+ Credentials = credentials_lib.Credentials
33
+ # pylint: enable=g-import-not-at-top
34
+ except ImportError:
35
+ google_auth = None
36
+ auth_requests = None
37
+ credentials_lib = None
38
+ Credentials = None # pylint: disable=invalid-name
39
+
40
+
26
41
  SUPPORTED_MODELS_AND_SETTINGS = {
27
42
  # See https://docs.anthropic.com/claude/docs/models-overview
28
43
  # Rate limits from https://docs.anthropic.com/claude/reference/rate-limits
@@ -30,20 +45,43 @@ SUPPORTED_MODELS_AND_SETTINGS = {
30
45
  # as RPM/TPM of the largest-available model (Claude-3-Opus).
31
46
  # Price in US dollars at https://www.anthropic.com/pricing
32
47
  # as of 2024-10-10.
48
+ # Anthropic models hosted on VertexAI.
49
+ 'claude-3-5-sonnet-v2@20241022': pg.Dict(
50
+ max_tokens=8192,
51
+ rpm=1000,
52
+ tpm=100000,
53
+ cost_per_1k_input_tokens=0.003,
54
+ cost_per_1k_output_tokens=0.015,
55
+ ),
56
+ 'claude-3-5-haiku@20241022': pg.Dict(
57
+ max_tokens=8192,
58
+ rpm=1000,
59
+ tpm=100000,
60
+ cost_per_1k_input_tokens=0.001,
61
+ cost_per_1k_output_tokens=0.005,
62
+ ),
63
+ # Anthropic hosted models.
33
64
  'claude-3-5-sonnet-20241022': pg.Dict(
34
- max_tokens=4096,
65
+ max_tokens=8192,
35
66
  rpm=4000,
36
67
  tpm=400000,
37
68
  cost_per_1k_input_tokens=0.003,
38
69
  cost_per_1k_output_tokens=0.015,
39
70
  ),
40
71
  'claude-3-5-sonnet-20240620': pg.Dict(
41
- max_tokens=4096,
72
+ max_tokens=8192,
42
73
  rpm=4000,
43
74
  tpm=400000,
44
75
  cost_per_1k_input_tokens=0.003,
45
76
  cost_per_1k_output_tokens=0.015,
46
77
  ),
78
+ 'claude-3-5-haiku-20241022': pg.Dict(
79
+ max_tokens=8192,
80
+ rpm=4000,
81
+ tpm=400000,
82
+ cost_per_1k_input_tokens=0.001,
83
+ cost_per_1k_output_tokens=0.005,
84
+ ),
47
85
  'claude-3-opus-20240229': pg.Dict(
48
86
  max_tokens=4096,
49
87
  rpm=4000,
@@ -327,3 +365,100 @@ class Claude21(Anthropic):
327
365
  class ClaudeInstant(Anthropic):
328
366
  """Cheapest small and fast model, 100K context window."""
329
367
  model = 'claude-instant-1.2'
368
+
369
+
370
+ #
371
+ # Authropic models on VertexAI.
372
+ #
373
+
374
+
375
+ class VertexAIAnthropic(Anthropic):
376
+ """Anthropic models on VertexAI."""
377
+
378
+ project: Annotated[
379
+ str | None,
380
+ 'Google Cloud project ID.',
381
+ ] = None
382
+
383
+ location: Annotated[
384
+ Literal['us-east5', 'europe-west1'],
385
+ 'GCP location with Anthropic models hosted.'
386
+ ] = 'us-east5'
387
+
388
+ credentials: Annotated[
389
+ Credentials | None, # pytype: disable=invalid-annotation
390
+ (
391
+ 'Credentials to use. If None, the default credentials '
392
+ 'to the environment will be used.'
393
+ ),
394
+ ] = None
395
+
396
+ api_version = 'vertex-2023-10-16'
397
+
398
+ def _on_bound(self):
399
+ super()._on_bound()
400
+ if google_auth is None:
401
+ raise ValueError(
402
+ 'Please install "langfun[llm-google-vertex]" to use Vertex AI models.'
403
+ )
404
+ self._project = None
405
+ self._credentials = None
406
+
407
+ def _initialize(self):
408
+ project = self.project or os.environ.get('VERTEXAI_PROJECT', None)
409
+ if not project:
410
+ raise ValueError(
411
+ 'Please specify `project` during `__init__` or set environment '
412
+ 'variable `VERTEXAI_PROJECT` with your Vertex AI project ID.'
413
+ )
414
+ self._project = project
415
+ credentials = self.credentials
416
+ if credentials is None:
417
+ # Use default credentials.
418
+ credentials = google_auth.default(
419
+ scopes=['https://www.googleapis.com/auth/cloud-platform']
420
+ )
421
+ self._credentials = credentials
422
+
423
+ @functools.cached_property
424
+ def _session(self):
425
+ assert self._api_initialized
426
+ assert self._credentials is not None
427
+ assert auth_requests is not None
428
+ s = auth_requests.AuthorizedSession(self._credentials)
429
+ s.headers.update(self.headers or {})
430
+ return s
431
+
432
+ @property
433
+ def headers(self):
434
+ return {
435
+ 'Content-Type': 'application/json; charset=utf-8',
436
+ }
437
+
438
+ @property
439
+ def api_endpoint(self) -> str:
440
+ return (
441
+ f'https://{self.location}-aiplatform.googleapis.com/v1/projects/'
442
+ f'{self._project}/locations/{self.location}/publishers/anthropic/'
443
+ f'models/{self.model}:streamRawPredict'
444
+ )
445
+
446
+ def request(
447
+ self,
448
+ prompt: lf.Message,
449
+ sampling_options: lf.LMSamplingOptions
450
+ ):
451
+ request = super().request(prompt, sampling_options)
452
+ request['anthropic_version'] = self.api_version
453
+ del request['model']
454
+ return request
455
+
456
+
457
+ class VertexAIClaude3_5_Sonnet_20241022(VertexAIAnthropic): # pylint: disable=invalid-name
458
+ """Anthropic's Claude 3.5 Sonnet model on VertexAI."""
459
+ model = 'claude-3-5-sonnet-v2@20241022'
460
+
461
+
462
+ class VertexAIClaude3_5_Haiku_20241022(VertexAIAnthropic): # pylint: disable=invalid-name
463
+ """Anthropic's Claude 3.5 Haiku model on VertexAI."""
464
+ model = 'claude-3-5-haiku@20241022'
@@ -18,6 +18,10 @@ import os
18
18
  from typing import Any
19
19
  import unittest
20
20
  from unittest import mock
21
+
22
+ from google.auth import exceptions
23
+ from langfun.core import language_model
24
+ from langfun.core import message as lf_message
21
25
  from langfun.core import modalities as lf_modalities
22
26
  from langfun.core.llms import anthropic
23
27
  import pyglove as pg
@@ -182,5 +186,50 @@ class AnthropicTest(unittest.TestCase):
182
186
  lm('hello', max_attempts=1)
183
187
 
184
188
 
189
+ class VertexAIAnthropicTest(unittest.TestCase):
190
+ """Tests for VertexAI Anthropic models."""
191
+
192
+ def test_basics(self):
193
+ with self.assertRaisesRegex(ValueError, 'Please specify `project`'):
194
+ lm = anthropic.VertexAIClaude3_5_Sonnet_20241022()
195
+ lm('hi')
196
+
197
+ model = anthropic.VertexAIClaude3_5_Sonnet_20241022(project='langfun')
198
+
199
+ # NOTE(daiyip): For OSS users, default credentials are not available unless
200
+ # users have already set up their GCP project. Therefore we ignore the
201
+ # exception here.
202
+ try:
203
+ model._initialize()
204
+ except exceptions.DefaultCredentialsError:
205
+ pass
206
+
207
+ self.assertEqual(
208
+ model.api_endpoint,
209
+ (
210
+ 'https://us-east5-aiplatform.googleapis.com/v1/projects/'
211
+ 'langfun/locations/us-east5/publishers/anthropic/'
212
+ 'models/claude-3-5-sonnet-v2@20241022:streamRawPredict'
213
+ )
214
+ )
215
+ request = model.request(
216
+ lf_message.UserMessage('hi'),
217
+ language_model.LMSamplingOptions(temperature=0.0),
218
+ )
219
+ self.assertEqual(
220
+ request,
221
+ {
222
+ 'anthropic_version': 'vertex-2023-10-16',
223
+ 'max_tokens': 8192,
224
+ 'messages': [
225
+ {'content': [{'text': 'hi', 'type': 'text'}], 'role': 'user'}
226
+ ],
227
+ 'stream': False,
228
+ 'temperature': 0.0,
229
+ 'top_k': 40,
230
+ },
231
+ )
232
+
233
+
185
234
  if __name__ == '__main__':
186
235
  unittest.main()
langfun/core/llms/rest.py CHANGED
@@ -98,6 +98,7 @@ class REST(lf.LanguageModel):
98
98
  500, # Server side issue (might be bug).
99
99
  502, # Bad gateway (upstream issue, might retry).
100
100
  503, # Servers currently under load, retry after a brief wait.
101
+ 529, # Overloaded, retry after a brief wait.
101
102
  ):
102
103
  error_cls = lf.TemporaryLMError
103
104
  else:
@@ -38,6 +38,11 @@ class Conversation(Completion):
38
38
  '(Optional) Preamble before beginning the conversation.',
39
39
  ] = None
40
40
 
41
+ role: Annotated[
42
+ str | None,
43
+ '(Optional) User defined role for the AI response in the conversation.',
44
+ ] = None
45
+
41
46
  conversation_context: Annotated[
42
47
  lf.LangFunc | None,
43
48
  (
@@ -71,6 +76,10 @@ class Conversation(Completion):
71
76
  with lf.context(**kwargs):
72
77
  # Call LM based on the prompt generated from `input_message`.
73
78
  lm_response = super().__call__()
79
+ if self.role is not None:
80
+ lm_response.rebind(
81
+ sender=self.role, skip_notification=True, raise_on_no_change=False
82
+ )
74
83
 
75
84
  # Add current turn to memory.
76
85
  self.add(self.input_message, lm_response)
@@ -83,6 +83,7 @@ class ConversationTest(unittest.TestCase):
83
83
  def test_call(self):
84
84
  c = Conversation(
85
85
  lm=QuestionCounter(),
86
+ role='Agent',
86
87
  preamble="You are a helpful and joyful AI bot. Now let's chat.",
87
88
  )
88
89
  # First round.
@@ -102,7 +103,7 @@ class ConversationTest(unittest.TestCase):
102
103
  inspect.cleandoc("""
103
104
  You are a helpful and joyful AI bot. Now let's chat.
104
105
  User: Hello
105
- AI: Response 1.
106
+ Agent: Response 1.
106
107
  User: How are you?
107
108
  """),
108
109
  )
@@ -114,9 +115,9 @@ class ConversationTest(unittest.TestCase):
114
115
  inspect.cleandoc("""
115
116
  You are a helpful and joyful AI bot. Now let's chat.
116
117
  User: Hello
117
- AI: Response 1.
118
+ Agent: Response 1.
118
119
  User: How are you?
119
- AI: Response 2.
120
+ Agent: Response 2.
120
121
  User: Okay, bye.
121
122
  """),
122
123
  )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: langfun
3
- Version: 0.1.2.dev202411060804
3
+ Version: 0.1.2.dev202411090804
4
4
  Summary: Langfun: Language as Functions.
5
5
  Home-page: https://github.com/google/langfun
6
6
  Author: Langfun Authors
@@ -50,11 +50,11 @@ langfun/core/eval/matching.py,sha256=UnjdM_ebPqXKJamY4lvL3AYxrMIz3LqkjRTnHJ5xsYc
50
50
  langfun/core/eval/matching_test.py,sha256=QCoYEuf4b_1bkHqUCuRzKMbXHrV3AB2FCOBivo1stC4,5249
51
51
  langfun/core/eval/patching.py,sha256=R0s2eAd1m97exQt06dmUL0V_MBG0W2Hxg7fhNB7cXW0,3866
52
52
  langfun/core/eval/patching_test.py,sha256=8kCd54Egjju22FMgtJuxEsrXkW8ifs-UUBHtrCG1L6w,4775
53
- langfun/core/eval/scoring.py,sha256=SUdMzOkP0n2qGaSuUA4VwFiTw36jgMvgCJHPJS4yYDw,6254
53
+ langfun/core/eval/scoring.py,sha256=B69IsIxiPs1xZcOBFIhZF70YmDue2Siik-CPL2bh33s,6254
54
54
  langfun/core/eval/scoring_test.py,sha256=O8olHbrUEg60gMxwOkWzKBJZpZoUlmVnBANX5Se2SXM,4546
55
- langfun/core/llms/__init__.py,sha256=SFa3qKHSq_P_bV_SkIEVasm58J6wvwLVeoh0rhhDy9o,5985
56
- langfun/core/llms/anthropic.py,sha256=Wwpe7WZT6NhHELVuQxowVYWCwfZJCE-igR10cyJUCLc,9785
57
- langfun/core/llms/anthropic_test.py,sha256=9l0WuM0As7X78lbbnpuvguMBMVSHX2QiAZuwjbj0HbA,6555
55
+ langfun/core/llms/__init__.py,sha256=ATayGMO5rQzkPBAf7zl3vfgRQ8fth33TFVXv_tvraCQ,6190
56
+ langfun/core/llms/anthropic.py,sha256=XPQxjfe9O4b-CygCgqvQU0MPSfe1rU7uErNbo8zth7Q,13606
57
+ langfun/core/llms/anthropic_test.py,sha256=-2U4kc_pgBM7wqxu8RuxzyHPGww1EAWqKUvN4PW8Btw,8058
58
58
  langfun/core/llms/fake.py,sha256=gCHBYBLvBCsC78HI1hpoqXCS-p1FMTgY1P1qh_sGBPk,3070
59
59
  langfun/core/llms/fake_test.py,sha256=2h13qkwEz_JR0mtUDPxdAhQo7MueXaFSwsD2DIRDW9g,7653
60
60
  langfun/core/llms/google_genai.py,sha256=btUIfWteBoj8Jl0j8d3e8hyI6p3Biq4rldlQYctVQfg,10936
@@ -65,7 +65,7 @@ langfun/core/llms/llama_cpp.py,sha256=9tXQntSCDtjTF3bnyJrAPCr4N6wycy5nXYvp9uduyg
65
65
  langfun/core/llms/llama_cpp_test.py,sha256=MWO_qaOeKjRniGjcaWPDScd7HPaIJemqUZoslrt4FPs,1806
66
66
  langfun/core/llms/openai.py,sha256=qrAiJxE0tS7ZqjaVzRgVJKtMtoo1Z5TYpvi5ikTwPpw,22716
67
67
  langfun/core/llms/openai_test.py,sha256=_8cd3VRNEUfE0-Ko1RiM6MlC5hjalRj7nYTJNhG1p3E,18907
68
- langfun/core/llms/rest.py,sha256=laopuq-zD8V-3Y6eFDngftHEbE66VlUkCD2-rvvRaLU,3388
68
+ langfun/core/llms/rest.py,sha256=sWbYUV8S3SuOg9giq7xwD-xDRfaF7NP_ig7bI52-Rj4,3442
69
69
  langfun/core/llms/rest_test.py,sha256=NZ3Nf0XQVpT9kLP5cBVo_yBHLI7vWTYhWQxYEJVMGs4,3472
70
70
  langfun/core/llms/vertexai.py,sha256=eUFU0JjgpTVCAvQVEWiGqZrlE3Dye-EkzZCF1P8nwc4,18866
71
71
  langfun/core/llms/vertexai_test.py,sha256=7uBVOF5VF86xQ9HFAbSTh4J-0NjYLnuotBS1YRm-vgw,10529
@@ -113,14 +113,14 @@ langfun/core/structured/tokenization_test.py,sha256=dVW30kGYkX2HNtiRZe1oTmXFP7iI
113
113
  langfun/core/templates/__init__.py,sha256=bO0eMsVJbi7sxEB2YlInKRQ2EVP-RyyKUwcD-8msuN4,927
114
114
  langfun/core/templates/completion.py,sha256=mUqZHOEV3ag6-A08XghpeEltcrBvCDxXP004eDDfeag,1931
115
115
  langfun/core/templates/completion_test.py,sha256=vGnjnM38UHyVDUyaUYtmp20s9KBGOdbPVsX-H-ET11E,1636
116
- langfun/core/templates/conversation.py,sha256=HVih0atzCFpYbE-2bmO1VewhKGyKYAoCty-IZYCjf00,2589
117
- langfun/core/templates/conversation_test.py,sha256=RryYyIhfc34dLWOs6GfPQ8HU8mXpKGL87UgVkysfIMo,3911
116
+ langfun/core/templates/conversation.py,sha256=dTy_fs3g92d3vP09bACGJ_zJ3b8-OzA8vsKgUDoB76o,2866
117
+ langfun/core/templates/conversation_test.py,sha256=HCD5f1sgmSGqL3OGe7hEctjRdcFjcmkz3NV1ArexNYI,3942
118
118
  langfun/core/templates/demonstration.py,sha256=vCrgYubdZM5Umqcgp8NUVGXgr4P_c-fikKhwhzwhpKI,1460
119
119
  langfun/core/templates/demonstration_test.py,sha256=SafcDQ0WgI7pw05EmPI2S4v1t3ABKzup8jReCljHeK4,2162
120
120
  langfun/core/templates/selfplay.py,sha256=yhgrJbiYwq47TgzThmHrDQTF4nDrTI09CWGhuQPNv-s,2273
121
121
  langfun/core/templates/selfplay_test.py,sha256=Ot__1P1M8oJfoTp-M9-PQ6HUXqZKyMwvZ5f7yQ3yfyM,2326
122
- langfun-0.1.2.dev202411060804.dist-info/LICENSE,sha256=WNHhf_5RCaeuKWyq_K39vmp9F28LxKsB4SpomwSZ2L0,11357
123
- langfun-0.1.2.dev202411060804.dist-info/METADATA,sha256=7pmVZg70qMsD08wH-RC6Fi7ljIKiMOtVEHyUBslyo3o,8890
124
- langfun-0.1.2.dev202411060804.dist-info/WHEEL,sha256=P9jw-gEje8ByB7_hXoICnHtVCrEwMQh-630tKvQWehc,91
125
- langfun-0.1.2.dev202411060804.dist-info/top_level.txt,sha256=RhlEkHxs1qtzmmtWSwYoLVJAc1YrbPtxQ52uh8Z9VvY,8
126
- langfun-0.1.2.dev202411060804.dist-info/RECORD,,
122
+ langfun-0.1.2.dev202411090804.dist-info/LICENSE,sha256=WNHhf_5RCaeuKWyq_K39vmp9F28LxKsB4SpomwSZ2L0,11357
123
+ langfun-0.1.2.dev202411090804.dist-info/METADATA,sha256=Ez5vUJUc5-XDAdDMyR6Wcgj4fiDL1RwJpu1NI3i3lwE,8890
124
+ langfun-0.1.2.dev202411090804.dist-info/WHEEL,sha256=P9jw-gEje8ByB7_hXoICnHtVCrEwMQh-630tKvQWehc,91
125
+ langfun-0.1.2.dev202411090804.dist-info/top_level.txt,sha256=RhlEkHxs1qtzmmtWSwYoLVJAc1YrbPtxQ52uh8Z9VvY,8
126
+ langfun-0.1.2.dev202411090804.dist-info/RECORD,,