langfun 0.0.2.dev20240717__py3-none-any.whl → 0.1.1__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.
- langfun/__init__.py +1 -1
- langfun/core/coding/python/parsing.py +2 -1
- langfun/core/concurrent_test.py +6 -6
- langfun/core/language_model.py +7 -4
- langfun/core/message.py +7 -5
- langfun/core/message_test.py +3 -6
- langfun/core/modalities/image.py +6 -0
- langfun/core/modalities/image_test.py +6 -0
- langfun/core/structured/prompting.py +5 -0
- langfun/core/structured/prompting_test.py +11 -0
- langfun-0.1.1.dist-info/METADATA +167 -0
- {langfun-0.0.2.dev20240717.dist-info → langfun-0.1.1.dist-info}/RECORD +15 -15
- {langfun-0.0.2.dev20240717.dist-info → langfun-0.1.1.dist-info}/WHEEL +1 -1
- langfun-0.0.2.dev20240717.dist-info/METADATA +0 -103
- {langfun-0.0.2.dev20240717.dist-info → langfun-0.1.1.dist-info}/LICENSE +0 -0
- {langfun-0.0.2.dev20240717.dist-info → langfun-0.1.1.dist-info}/top_level.txt +0 -0
langfun/__init__.py
CHANGED
@@ -161,7 +161,8 @@ class PythonCodeParser(lf.Component):
|
|
161
161
|
|
162
162
|
# Peek forward to see if it could be a valid string.
|
163
163
|
nt, nnt_start = _next_token(code_text, i + 1)
|
164
|
-
if
|
164
|
+
if (len(c) == 3
|
165
|
+
or nt in (',', '[', ']', '}', ')', '+', '*', '%', '\n', ':')):
|
165
166
|
end_quote = True
|
166
167
|
elif nt == ' ':
|
167
168
|
# Detect if . could be a method invocation.
|
langfun/core/concurrent_test.py
CHANGED
@@ -256,18 +256,18 @@ class ProgressBarTest(unittest.TestCase):
|
|
256
256
|
with contextlib.redirect_stderr(string_io):
|
257
257
|
bar_id = concurrent.ProgressBar.install(None, 4)
|
258
258
|
concurrent.ProgressBar.update(bar_id, 1, postfix=None)
|
259
|
-
self.assertIn('1/4', string_io.getvalue())
|
260
259
|
concurrent.ProgressBar.update(bar_id, 1, postfix='hello')
|
261
|
-
self.assertIn('2/4', string_io.getvalue())
|
262
|
-
self.assertIn('hello', string_io.getvalue())
|
263
260
|
concurrent.ProgressBar.update(bar_id, color='lightgreen')
|
264
|
-
self.assertIn('2/4', string_io.getvalue())
|
265
261
|
concurrent.ProgressBar.update(bar_id, 2, postfix=dict(x=1))
|
266
|
-
self.assertIn('4/4', string_io.getvalue())
|
267
|
-
self.assertIn('x=1', string_io.getvalue())
|
268
262
|
with self.assertRaisesRegex(ValueError, 'Unsupported postfix'):
|
269
263
|
concurrent.ProgressBar.update(bar_id, 0, postfix=1)
|
270
264
|
concurrent.ProgressBar.uninstall(bar_id)
|
265
|
+
self.assertIn('1/4', string_io.getvalue())
|
266
|
+
self.assertIn('2/4', string_io.getvalue())
|
267
|
+
self.assertIn('hello', string_io.getvalue())
|
268
|
+
self.assertNotIn('3/4', string_io.getvalue())
|
269
|
+
self.assertIn('4/4', string_io.getvalue())
|
270
|
+
self.assertIn('x=1', string_io.getvalue())
|
271
271
|
|
272
272
|
|
273
273
|
class ConcurrentMapTest(unittest.TestCase):
|
langfun/core/language_model.py
CHANGED
@@ -17,6 +17,7 @@ import abc
|
|
17
17
|
import contextlib
|
18
18
|
import dataclasses
|
19
19
|
import enum
|
20
|
+
import threading
|
20
21
|
import time
|
21
22
|
from typing import Annotated, Any, Callable, Iterator, Sequence, Tuple, Type, Union
|
22
23
|
from langfun.core import component
|
@@ -728,6 +729,7 @@ class _UsageTracker:
|
|
728
729
|
|
729
730
|
def __init__(self, model_ids: set[str] | None):
|
730
731
|
self.model_ids = model_ids
|
732
|
+
self._lock = threading.Lock()
|
731
733
|
self.usages = {
|
732
734
|
m: LMSamplingUsage(0, 0, 0, 0) for m in model_ids
|
733
735
|
} if model_ids else {}
|
@@ -735,10 +737,11 @@ class _UsageTracker:
|
|
735
737
|
def track(self, model_id: str, usage: LMSamplingUsage):
|
736
738
|
if self.model_ids is not None and model_id not in self.model_ids:
|
737
739
|
return
|
738
|
-
|
739
|
-
self.usages
|
740
|
-
|
741
|
-
|
740
|
+
with self._lock:
|
741
|
+
if not isinstance(usage, UsageNotAvailable) and model_id in self.usages:
|
742
|
+
self.usages[model_id] += usage
|
743
|
+
else:
|
744
|
+
self.usages[model_id] = usage
|
742
745
|
|
743
746
|
|
744
747
|
@contextlib.contextmanager
|
langfun/core/message.py
CHANGED
@@ -318,7 +318,7 @@ class Message(natural_language.NaturalLanguageFormattable, pg.Object):
|
|
318
318
|
while chunk_start < len(text):
|
319
319
|
ref_start = text.find(modality.Modality.REF_START, ref_end)
|
320
320
|
if ref_start == -1:
|
321
|
-
add_text_chunk(text[chunk_start:].strip())
|
321
|
+
add_text_chunk(text[chunk_start:].strip(' '))
|
322
322
|
break
|
323
323
|
|
324
324
|
var_start = ref_start + len(modality.Modality.REF_START)
|
@@ -330,29 +330,31 @@ class Message(natural_language.NaturalLanguageFormattable, pg.Object):
|
|
330
330
|
var_name = text[var_start:ref_end].strip()
|
331
331
|
var_value = self.get_modality(var_name)
|
332
332
|
if var_value is not None:
|
333
|
-
add_text_chunk(text[chunk_start:ref_start].strip())
|
333
|
+
add_text_chunk(text[chunk_start:ref_start].strip(' '))
|
334
334
|
chunks.append(var_value)
|
335
335
|
chunk_start = ref_end + len(modality.Modality.REF_END)
|
336
336
|
return chunks
|
337
337
|
|
338
338
|
@classmethod
|
339
339
|
def from_chunks(
|
340
|
-
cls, chunks: list[str | modality.Modality], separator: str = '
|
340
|
+
cls, chunks: list[str | modality.Modality], separator: str = ' '
|
341
341
|
) -> 'Message':
|
342
342
|
"""Assembly a message from a list of string or modality objects."""
|
343
343
|
fused_text = io.StringIO()
|
344
344
|
ref_index = 0
|
345
345
|
metadata = dict()
|
346
|
-
|
346
|
+
last_char = None
|
347
347
|
for i, chunk in enumerate(chunks):
|
348
|
-
if i > 0:
|
348
|
+
if i > 0 and last_char not in ('\t', ' ', '\n'):
|
349
349
|
fused_text.write(separator)
|
350
350
|
if isinstance(chunk, str):
|
351
351
|
fused_text.write(chunk)
|
352
|
+
last_char = chunk[-1]
|
352
353
|
else:
|
353
354
|
assert isinstance(chunk, modality.Modality), chunk
|
354
355
|
var_name = f'obj{ref_index}'
|
355
356
|
fused_text.write(modality.Modality.text_marker(var_name))
|
357
|
+
last_char = modality.Modality.REF_END[-1]
|
356
358
|
# Make a reference if the chunk is already owned by another object
|
357
359
|
# to avoid copy.
|
358
360
|
metadata[var_name] = pg.maybe_ref(chunk)
|
langfun/core/message_test.py
CHANGED
@@ -295,7 +295,7 @@ class MessageTest(unittest.TestCase):
|
|
295
295
|
[
|
296
296
|
'Hi, this is',
|
297
297
|
CustomModality('foo'),
|
298
|
-
'and this is {{b}}
|
298
|
+
'and this is {{b}}.\n',
|
299
299
|
CustomModality('bar'),
|
300
300
|
'{{something else',
|
301
301
|
],
|
@@ -306,11 +306,8 @@ class MessageTest(unittest.TestCase):
|
|
306
306
|
message.AIMessage.from_chunks(chunks),
|
307
307
|
message.AIMessage(
|
308
308
|
inspect.cleandoc("""
|
309
|
-
Hi, this is
|
310
|
-
<<[[
|
311
|
-
and this is {{b}}.
|
312
|
-
<<[[obj1]]>>
|
313
|
-
{{something else
|
309
|
+
Hi, this is <<[[obj0]]>> and this is {{b}}.
|
310
|
+
<<[[obj1]]>> {{something else
|
314
311
|
"""),
|
315
312
|
obj0=pg.Ref(m.a),
|
316
313
|
obj1=pg.Ref(m.x.c),
|
langfun/core/modalities/image.py
CHANGED
@@ -14,7 +14,9 @@
|
|
14
14
|
"""Image modality."""
|
15
15
|
|
16
16
|
import functools
|
17
|
+
import io
|
17
18
|
from langfun.core.modalities import mime
|
19
|
+
from PIL import Image as pil_image
|
18
20
|
|
19
21
|
|
20
22
|
class Image(mime.Mime):
|
@@ -28,3 +30,7 @@ class Image(mime.Mime):
|
|
28
30
|
|
29
31
|
def _html(self, uri: str) -> str:
|
30
32
|
return f'<img src="{uri}">'
|
33
|
+
|
34
|
+
def size(self) -> tuple[int, int]:
|
35
|
+
img = pil_image.open(io.BytesIO(self.to_bytes()))
|
36
|
+
return img.size
|
@@ -77,6 +77,12 @@ class ImageTest(unittest.TestCase):
|
|
77
77
|
self.assertEqual(image._repr_html_(), '<img src="http://mock/web/a.png">')
|
78
78
|
self.assertEqual(image.to_bytes(), image_content)
|
79
79
|
|
80
|
+
def test_image_size(self):
|
81
|
+
image = image_lib.Image.from_uri('http://mock/web/a.png')
|
82
|
+
with mock.patch('requests.get') as mock_requests_get:
|
83
|
+
mock_requests_get.side_effect = mock_request
|
84
|
+
self.assertEqual(image.size(), (24, 24))
|
85
|
+
|
80
86
|
|
81
87
|
if __name__ == '__main__':
|
82
88
|
unittest.main()
|
@@ -193,6 +193,11 @@ def query(
|
|
193
193
|
if isinstance(prompt, pg.Symbolic) and prompt.sym_partial and schema is None:
|
194
194
|
schema = prompt.__class__
|
195
195
|
|
196
|
+
# Create a copy of the prompt if it has a parent object, so all child modality
|
197
|
+
# objects could be referred by path relative to the prompt.
|
198
|
+
if isinstance(prompt, lf.Template) and prompt.sym_parent:
|
199
|
+
prompt = prompt.clone()
|
200
|
+
|
196
201
|
if schema in (None, str):
|
197
202
|
# Query with natural language output.
|
198
203
|
output = lf.LangFunc.from_value(prompt, **kwargs)(
|
@@ -361,6 +361,17 @@ class QueryTest(unittest.TestCase):
|
|
361
361
|
"""),
|
362
362
|
)
|
363
363
|
|
364
|
+
def test_query_prompt_with_unrooted_template(self):
|
365
|
+
output = prompting.query_prompt(
|
366
|
+
pg.Dict(
|
367
|
+
input=lf.Template(
|
368
|
+
'what is {{image}}',
|
369
|
+
image=modalities.Image.from_bytes(b'mock_image')
|
370
|
+
)
|
371
|
+
).input,
|
372
|
+
)
|
373
|
+
self.assertIsNotNone(output.get_modality('image'))
|
374
|
+
|
364
375
|
def test_query_output(self):
|
365
376
|
self.assertEqual(
|
366
377
|
prompting.query_output(
|
@@ -0,0 +1,167 @@
|
|
1
|
+
Metadata-Version: 2.1
|
2
|
+
Name: langfun
|
3
|
+
Version: 0.1.1
|
4
|
+
Summary: Langfun: Language as Functions.
|
5
|
+
Home-page: https://github.com/google/langfun
|
6
|
+
Author: Langfun Authors
|
7
|
+
Author-email: langfun-authors@google.com
|
8
|
+
License: Apache License 2.0
|
9
|
+
Keywords: llm generative-ai machine-learning
|
10
|
+
Classifier: Development Status :: 3 - Alpha
|
11
|
+
Classifier: Intended Audience :: Developers
|
12
|
+
Classifier: Intended Audience :: Education
|
13
|
+
Classifier: Intended Audience :: Science/Research
|
14
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
18
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
19
|
+
Classifier: Topic :: Scientific/Engineering :: Human Machine Interfaces
|
20
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
21
|
+
Classifier: Topic :: Software Development :: Libraries
|
22
|
+
Description-Content-Type: text/markdown
|
23
|
+
License-File: LICENSE
|
24
|
+
Requires-Dist: google-cloud-aiplatform >=1.5.0
|
25
|
+
Requires-Dist: google-generativeai >=0.3.2
|
26
|
+
Requires-Dist: jinja2 >=3.1.2
|
27
|
+
Requires-Dist: openai ==0.27.2
|
28
|
+
Requires-Dist: openpyxl >=3.1.0
|
29
|
+
Requires-Dist: pandas >=2.0.3
|
30
|
+
Requires-Dist: pyglove >=0.4.5.dev20240423
|
31
|
+
Requires-Dist: python-docx >=0.8.11
|
32
|
+
Requires-Dist: python-magic >=0.4.27
|
33
|
+
Requires-Dist: requests >=2.31.0
|
34
|
+
Requires-Dist: termcolor ==1.1.0
|
35
|
+
Requires-Dist: tqdm >=4.64.1
|
36
|
+
Requires-Dist: pillow >=10.0.0
|
37
|
+
|
38
|
+
<div align="center">
|
39
|
+
<img src="https://raw.githubusercontent.com/google/langfun/main/docs/_static/logo.svg" width="520px" alt="logo"></img>
|
40
|
+
</div>
|
41
|
+
|
42
|
+
# Langfun
|
43
|
+
|
44
|
+
[](https://badge.fury.io/py/langfun)
|
45
|
+
[](https://codecov.io/gh/google/langfun)
|
46
|
+

|
47
|
+
|
48
|
+
[**Installation**](#install) | [**Getting started**](#hello-langfun) | [**Tutorial**](https://colab.research.google.com/github/google/langfun/blob/main/docs/notebooks/langfun101.ipynb)
|
49
|
+
|
50
|
+
## Introduction
|
51
|
+
|
52
|
+
Langfun is a [PyGlove](https://github.com/google/pyglove) powered library that
|
53
|
+
aims to *make language models (LM) fun to work with*. Its central principle is
|
54
|
+
to enable seamless integration between natural language and programming by
|
55
|
+
treating language as functions. Through the introduction of *Object-Oriented Prompting*,
|
56
|
+
Langfun empowers users to prompt LLMs using objects and types, offering enhanced
|
57
|
+
control and simplifying agent development.
|
58
|
+
|
59
|
+
To unlock the magic of Langfun, you can start with
|
60
|
+
[Langfun 101](https://colab.research.google.com/github/google/langfun/blob/main/docs/notebooks/langfun101.ipynb). Notably, Langfun is compatible with popular LLMs such as Gemini, GPT,
|
61
|
+
Claude, all without the need for additional fine-tuning.
|
62
|
+
|
63
|
+
## Why Langfun?
|
64
|
+
|
65
|
+
Langfun is *powerful and scalable*:
|
66
|
+
|
67
|
+
* Seamless integration between natural language and computer programs.
|
68
|
+
* Modular prompts, which allows a natural blend of texts and modalities;
|
69
|
+
* Efficient for both request-based workflows and batch jobs;
|
70
|
+
* A powerful eval framework that thrives dimension explosions.
|
71
|
+
|
72
|
+
Langfun is *simple and elegant*:
|
73
|
+
|
74
|
+
* An intuitive programming model, graspable in 5 minutes;
|
75
|
+
* Plug-and-play into any Python codebase, making an immediate difference;
|
76
|
+
* Comprehensive LLMs under a unified API: Gemini, GPT, Claude, Llama3, and more.
|
77
|
+
* Designed for agile developement: offering intellisense, easy debugging, with minimal overhead;
|
78
|
+
|
79
|
+
## Hello, Langfun
|
80
|
+
|
81
|
+
```python
|
82
|
+
import langfun as lf
|
83
|
+
import pyglove as pg
|
84
|
+
|
85
|
+
from IPython import display
|
86
|
+
|
87
|
+
class Item(pg.Object):
|
88
|
+
name: str
|
89
|
+
color: str
|
90
|
+
|
91
|
+
class ImageDescription(pg.Object):
|
92
|
+
items: list[Item]
|
93
|
+
|
94
|
+
image = lf.Image.from_uri('https://upload.wikimedia.org/wikipedia/commons/thumb/8/83/Solar_system.jpg/1646px-Solar_system.jpg')
|
95
|
+
display.display(image)
|
96
|
+
|
97
|
+
desc = lf.query(
|
98
|
+
'Describe objects in {{my_image}} from top to bottom.',
|
99
|
+
ImageDescription,
|
100
|
+
lm=lf.llms.Gpt4o(api_key='<your-openai-api-key>'),
|
101
|
+
my_image=image,
|
102
|
+
)
|
103
|
+
print(desc)
|
104
|
+
```
|
105
|
+
*Output:*
|
106
|
+
|
107
|
+
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/8/83/Solar_system.jpg/1646px-Solar_system.jpg" width="520px" alt="my_image"></img>
|
108
|
+
|
109
|
+
```
|
110
|
+
ImageDescription(
|
111
|
+
items = [
|
112
|
+
0 : Item(
|
113
|
+
name = 'Mercury',
|
114
|
+
color = 'Gray'
|
115
|
+
),
|
116
|
+
1 : Item(
|
117
|
+
name = 'Venus',
|
118
|
+
color = 'Yellow'
|
119
|
+
),
|
120
|
+
2 : Item(
|
121
|
+
name = 'Earth',
|
122
|
+
color = 'Blue and white'
|
123
|
+
),
|
124
|
+
3 : Item(
|
125
|
+
name = 'Moon',
|
126
|
+
color = 'Gray'
|
127
|
+
),
|
128
|
+
4 : Item(
|
129
|
+
name = 'Mars',
|
130
|
+
color = 'Red'
|
131
|
+
),
|
132
|
+
5 : Item(
|
133
|
+
name = 'Jupiter',
|
134
|
+
color = 'Brown and white'
|
135
|
+
),
|
136
|
+
6 : Item(
|
137
|
+
name = 'Saturn',
|
138
|
+
color = 'Yellowish-brown with rings'
|
139
|
+
),
|
140
|
+
7 : Item(
|
141
|
+
name = 'Uranus',
|
142
|
+
color = 'Light blue'
|
143
|
+
),
|
144
|
+
8 : Item(
|
145
|
+
name = 'Neptune',
|
146
|
+
color = 'Dark blue'
|
147
|
+
)
|
148
|
+
]
|
149
|
+
)
|
150
|
+
```
|
151
|
+
See [Langfun 101](https://colab.research.google.com/github/google/langfun/blob/main/docs/notebooks/langfun101.ipynb) for more examples.
|
152
|
+
|
153
|
+
## Install
|
154
|
+
|
155
|
+
```
|
156
|
+
pip install langfun
|
157
|
+
```
|
158
|
+
|
159
|
+
Or install nightly build with:
|
160
|
+
|
161
|
+
```
|
162
|
+
pip install langfun --pre
|
163
|
+
```
|
164
|
+
|
165
|
+
|
166
|
+
|
167
|
+
*Disclaimer: this is not an officially supported Google product.*
|
@@ -1,20 +1,20 @@
|
|
1
|
-
langfun/__init__.py,sha256=
|
1
|
+
langfun/__init__.py,sha256=ZqERg4fvvtFwr5L41Lfev9FSuCBm8PbQrZmcKvvloxE,2274
|
2
2
|
langfun/core/__init__.py,sha256=Mdp1a2YnXdSmfTfbUwuAnEWYbjA3rXXGtbxl5fljZyg,4812
|
3
3
|
langfun/core/component.py,sha256=Icyoj9ICoJoK2r2PHbrFXbxnseOr9QZZOvKWklLWNo8,10276
|
4
4
|
langfun/core/component_test.py,sha256=q15Xn51cVTu2RKxZ9U5VQgT3bm6RQ4638bKhWBtvW5o,8220
|
5
5
|
langfun/core/concurrent.py,sha256=TRc49pJ3HQro2kb5FtcWkHjhBm8UcgE8RJybU5cU3-0,24537
|
6
|
-
langfun/core/concurrent_test.py,sha256=
|
6
|
+
langfun/core/concurrent_test.py,sha256=9HWnS4ja5Ji1ALfJs2zIt7w4w0oNm9dOZM7bgzoX5ag,15176
|
7
7
|
langfun/core/console.py,sha256=bk5rNPNm9rMGW5YT2HixxU04p2umnoabn5SDz6Dqe88,2317
|
8
8
|
langfun/core/console_test.py,sha256=5SYJdxpJGLgdSSQqqMPoA1X6jpsLD8rgcyk-EgI65oE,1077
|
9
9
|
langfun/core/langfunc.py,sha256=RvIcRjIq0jWYRu1xim-FYe4HSrt97r3GMBO_PuagUmw,11060
|
10
10
|
langfun/core/langfunc_test.py,sha256=lyt-UzkD8972cxZwzCkps0_RMLeSsOBrcUFIW-fB6us,8653
|
11
|
-
langfun/core/language_model.py,sha256=
|
11
|
+
langfun/core/language_model.py,sha256=ihcLy7WWrUByZ4Yfikb2OBppM6QGwMyjTYecBzelNCs,24028
|
12
12
|
langfun/core/language_model_test.py,sha256=TlNmVUfBfDQZzIiiBqCBTrxgcoyj2qNp3kONvmr2pX4,21273
|
13
13
|
langfun/core/logging.py,sha256=FyZRxUy2TTF6tWLhQCRpCvfH55WGUdNgQjUTK_SQLnY,5320
|
14
14
|
langfun/core/logging_test.py,sha256=qvm3RObYP3knO2PnXR9evBRl4gH621GnjnwywbGbRfg,1833
|
15
15
|
langfun/core/memory.py,sha256=f-asN1F7Vehgdn_fK84v73GrEUOxRtaW934keutTKjk,2416
|
16
|
-
langfun/core/message.py,sha256=
|
17
|
-
langfun/core/message_test.py,sha256=
|
16
|
+
langfun/core/message.py,sha256=3tm9HW_mnh0GmlyuJxMK8_KpQvx9GtXgVXYQTzoegJo,15882
|
17
|
+
langfun/core/message_test.py,sha256=74W5odVTvhY2U4KBBnHfTbCqD0z4cexO-9GWJQzRLO8,9516
|
18
18
|
langfun/core/modality.py,sha256=Tla4t86DUYHpbZ2G7dy1r19fTj_Ga5XOvlYp6lbWa-Q,3512
|
19
19
|
langfun/core/modality_test.py,sha256=HyZ5xONKQ0Fw18SzoWAq-Ob9njOXIIjBo1hNtw-rudw,2400
|
20
20
|
langfun/core/natural_language.py,sha256=3ynSnaYQnjE60LIPK5fyMgdIjubnPYZwzGq4rWPeloE,1177
|
@@ -39,7 +39,7 @@ langfun/core/coding/python/execution.py,sha256=raZix62g2fwt6Lgykll2DFzkLlEjVqN9E
|
|
39
39
|
langfun/core/coding/python/execution_test.py,sha256=lExY6GMLeuCsCKXgM2KbAPJ6kqSlfHmz3RG0-dqfVcI,7197
|
40
40
|
langfun/core/coding/python/generation.py,sha256=xivSeOKGN00HnG1TLuFhPfP-JyRuRrSELxVJW2ngqIQ,7750
|
41
41
|
langfun/core/coding/python/generation_test.py,sha256=54bgKr1DgzYFLoqR8bTn7Yjol0gPCuR6XvRltR4l6YM,2777
|
42
|
-
langfun/core/coding/python/parsing.py,sha256=
|
42
|
+
langfun/core/coding/python/parsing.py,sha256=LMg8REP4VDY0YQjtPAGNAW4rKlMNdSXF8m19wMT9yrY,7128
|
43
43
|
langfun/core/coding/python/parsing_test.py,sha256=9vAWF484kWIm6JZq8NFiMgKUDhXV-deRl1QMmNERfAA,7386
|
44
44
|
langfun/core/coding/python/permissions.py,sha256=1QWGHvzL8MM0Ok_auQ9tURqZHtdOfJaDpBzZ29GUE-c,2544
|
45
45
|
langfun/core/coding/python/permissions_test.py,sha256=w5EDb8QxpxgJyZkojyzVWQvDfg366zn99-g__6TbPQ0,2699
|
@@ -79,8 +79,8 @@ langfun/core/memories/conversation_history_test.py,sha256=AaW8aNoFjxNusanwJDV0r3
|
|
79
79
|
langfun/core/modalities/__init__.py,sha256=F8P72IwFiTpEseTR2tYEJyQMlDW7fd9csvGJquLKJNg,1269
|
80
80
|
langfun/core/modalities/audio.py,sha256=Qxo7bYjLKQ1gVJVomr9RqR2SvxY826QgXhTzzk437Sk,952
|
81
81
|
langfun/core/modalities/audio_test.py,sha256=gWCB9h3FyrdGqro3ajBXqkw0lU0W1sBjOOq6wZbl7Fg,2027
|
82
|
-
langfun/core/modalities/image.py,sha256=
|
83
|
-
langfun/core/modalities/image_test.py,sha256=
|
82
|
+
langfun/core/modalities/image.py,sha256=sMMmjNYUTdPViDOqc93WtSFrzE1-GRrEv-6I3eb8iYY,1083
|
83
|
+
langfun/core/modalities/image_test.py,sha256=Rcq4b77E9-Vp6rhqJ5ZIh0yJkEtcJbZZwjTjlu9dx8E,3282
|
84
84
|
langfun/core/modalities/mime.py,sha256=7oYvwYZHb3uhjiL2rF6kvQWsWufY0UXl72wfDXC59ys,5918
|
85
85
|
langfun/core/modalities/mime_test.py,sha256=kmRiPP-3Py02NnKPu0oPexSIJ-MXaaE2UYY82ga0TV8,2913
|
86
86
|
langfun/core/modalities/ms_office.py,sha256=jOidMSdWCaV9RILpGz8VJkpTSpHJNoirD53jzQvcytM,3388
|
@@ -100,8 +100,8 @@ langfun/core/structured/mapping.py,sha256=QKbSnvOgut-sx2mZPjHJcdlDLxR8b3ZC16ZLWo
|
|
100
100
|
langfun/core/structured/mapping_test.py,sha256=PiXklMeIa8L6KtMi3ju7J9Y39gZy0hIGz-Oeq4A_7XE,3835
|
101
101
|
langfun/core/structured/parsing.py,sha256=keoVqEfzAbdULh6GawWFsTQzU91MzJXYFZjXGXLaD8g,11492
|
102
102
|
langfun/core/structured/parsing_test.py,sha256=34wDrXaQ-EYhJLfDL8mX9K53oQMSzh5pVYdKjnESmK8,20895
|
103
|
-
langfun/core/structured/prompting.py,sha256=
|
104
|
-
langfun/core/structured/prompting_test.py,sha256=
|
103
|
+
langfun/core/structured/prompting.py,sha256=_U6Z65AwXvVvfaQFCY9GawB_QV9S3u7P7BOU2URABmw,8873
|
104
|
+
langfun/core/structured/prompting_test.py,sha256=Yc5GevbTyxtW6FAORXiqzakcuoJF-IPjoZ8kvLJW5is,23057
|
105
105
|
langfun/core/structured/schema.py,sha256=oiT4P4Q9pG-QOnFzxETN2EQZqNln8nG4zAJHxcmeX9U,27729
|
106
106
|
langfun/core/structured/schema_generation.py,sha256=U3nRQsqmMZg_qIVDh2fiY3K4JLfsAL1LcKzIFP1iXFg,5316
|
107
107
|
langfun/core/structured/schema_generation_test.py,sha256=RM9s71kMNg2jTePwInkiW9fK1ACN37eyPeF8OII-0zw,2950
|
@@ -117,8 +117,8 @@ langfun/core/templates/demonstration.py,sha256=vCrgYubdZM5Umqcgp8NUVGXgr4P_c-fik
|
|
117
117
|
langfun/core/templates/demonstration_test.py,sha256=SafcDQ0WgI7pw05EmPI2S4v1t3ABKzup8jReCljHeK4,2162
|
118
118
|
langfun/core/templates/selfplay.py,sha256=yhgrJbiYwq47TgzThmHrDQTF4nDrTI09CWGhuQPNv-s,2273
|
119
119
|
langfun/core/templates/selfplay_test.py,sha256=rBW2Qr8yi-aWYwoTwRR-n1peKyMX9QXPZXURjLgoiRs,2264
|
120
|
-
langfun-0.
|
121
|
-
langfun-0.
|
122
|
-
langfun-0.
|
123
|
-
langfun-0.
|
124
|
-
langfun-0.
|
120
|
+
langfun-0.1.1.dist-info/LICENSE,sha256=WNHhf_5RCaeuKWyq_K39vmp9F28LxKsB4SpomwSZ2L0,11357
|
121
|
+
langfun-0.1.1.dist-info/METADATA,sha256=wQ1jpdRAOtWbpPuoXL9m_0v0yUiFxraPcmJ8X6k6qms,5235
|
122
|
+
langfun-0.1.1.dist-info/WHEEL,sha256=Wyh-_nZ0DJYolHNn1_hMa4lM7uDedD_RGVwbmTjyItk,91
|
123
|
+
langfun-0.1.1.dist-info/top_level.txt,sha256=RhlEkHxs1qtzmmtWSwYoLVJAc1YrbPtxQ52uh8Z9VvY,8
|
124
|
+
langfun-0.1.1.dist-info/RECORD,,
|
@@ -1,103 +0,0 @@
|
|
1
|
-
Metadata-Version: 2.1
|
2
|
-
Name: langfun
|
3
|
-
Version: 0.0.2.dev20240717
|
4
|
-
Summary: Langfun: Language as Functions.
|
5
|
-
Home-page: https://github.com/google/langfun
|
6
|
-
Author: Langfun Authors
|
7
|
-
Author-email: langfun-authors@google.com
|
8
|
-
License: Apache License 2.0
|
9
|
-
Keywords: llm generative-ai machine-learning
|
10
|
-
Classifier: Development Status :: 3 - Alpha
|
11
|
-
Classifier: Intended Audience :: Developers
|
12
|
-
Classifier: Intended Audience :: Education
|
13
|
-
Classifier: Intended Audience :: Science/Research
|
14
|
-
Classifier: License :: OSI Approved :: Apache Software License
|
15
|
-
Classifier: Programming Language :: Python :: 3
|
16
|
-
Classifier: Programming Language :: Python :: 3.10
|
17
|
-
Classifier: Programming Language :: Python :: 3.11
|
18
|
-
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
19
|
-
Classifier: Topic :: Scientific/Engineering :: Human Machine Interfaces
|
20
|
-
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
21
|
-
Classifier: Topic :: Software Development :: Libraries
|
22
|
-
Description-Content-Type: text/markdown
|
23
|
-
License-File: LICENSE
|
24
|
-
Requires-Dist: google-cloud-aiplatform >=1.5.0
|
25
|
-
Requires-Dist: google-generativeai >=0.3.2
|
26
|
-
Requires-Dist: jinja2 >=3.1.2
|
27
|
-
Requires-Dist: openai ==0.27.2
|
28
|
-
Requires-Dist: openpyxl >=3.1.0
|
29
|
-
Requires-Dist: pandas >=2.1.4
|
30
|
-
Requires-Dist: pyglove >=0.4.5.dev20240423
|
31
|
-
Requires-Dist: python-docx >=0.8.11
|
32
|
-
Requires-Dist: python-magic >=0.4.27
|
33
|
-
Requires-Dist: requests >=2.31.0
|
34
|
-
Requires-Dist: termcolor ==1.1.0
|
35
|
-
Requires-Dist: tqdm >=4.64.1
|
36
|
-
|
37
|
-
<div align="center">
|
38
|
-
<img src="https://raw.githubusercontent.com/google/langfun/main/docs/_static/logo.svg" width="520px" alt="logo"></img>
|
39
|
-
</div>
|
40
|
-
|
41
|
-
# Langfun
|
42
|
-
|
43
|
-
[](https://badge.fury.io/py/langfun)
|
44
|
-
[](https://codecov.io/gh/google/langfun)
|
45
|
-

|
46
|
-
|
47
|
-
[**Installation**](#install) | [**Getting started**](#hello-world)
|
48
|
-
|
49
|
-
## What is Langfun
|
50
|
-
|
51
|
-
Langfun is a Python library that aims to make language models (LM) fun
|
52
|
-
to work with. Its design enables a programming model that flows naturally,
|
53
|
-
resembling the human thought process. It emphasizes the reuse and combination of
|
54
|
-
language pieces to form prompts, thereby accelerating innovation. In contrast to
|
55
|
-
other LM frameworks, which feed program-generated data into the LM, langfun
|
56
|
-
takes a distinct approach: It starts with natural language, allowing for
|
57
|
-
seamless interactions between language and program logic, and concludes with
|
58
|
-
natural language and optional structured output. Consequently, langfun can
|
59
|
-
aptly be described as Language as functions, capturing the core of its
|
60
|
-
methodology.
|
61
|
-
|
62
|
-
## Install
|
63
|
-
|
64
|
-
```
|
65
|
-
pip install langfun
|
66
|
-
```
|
67
|
-
|
68
|
-
Or install nightly build with:
|
69
|
-
|
70
|
-
```
|
71
|
-
pip install langfun --pre
|
72
|
-
```
|
73
|
-
|
74
|
-
## Hello World
|
75
|
-
|
76
|
-
```python
|
77
|
-
import langfun as lf
|
78
|
-
|
79
|
-
class NumericAnswerExtractor(lf.LangFunc):
|
80
|
-
"""Numeric answer extractor.
|
81
|
-
|
82
|
-
Here is my question:
|
83
|
-
{{question}}
|
84
|
-
|
85
|
-
Here is the response:
|
86
|
-
{{question()}}
|
87
|
-
|
88
|
-
Can you help me extract a number from the response as the answer to my
|
89
|
-
question? Your response should only contain a number in numeric form.
|
90
|
-
If the answer is not a number or you cannot extract it, respond with UNKNOWN.
|
91
|
-
"""
|
92
|
-
output_transform = lf.transforms.Match('\d+').to_int()
|
93
|
-
|
94
|
-
l = NumericAnswerExtractor()
|
95
|
-
|
96
|
-
with lf.context(lm=lf.llms.Gpt35(debug=True)):
|
97
|
-
r = l(question=lf.LangFunc('What is result of {{x}} plus {{y}}?'),
|
98
|
-
x='one',
|
99
|
-
y='two')
|
100
|
-
print('Result:', r.result)
|
101
|
-
```
|
102
|
-
|
103
|
-
*Disclaimer: this is not an officially supported Google product.*
|
File without changes
|
File without changes
|