langfun 0.1.2.dev202510230805__py3-none-any.whl → 0.1.2.dev202511160804__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.
- langfun/core/__init__.py +1 -0
- langfun/core/agentic/action.py +107 -12
- langfun/core/agentic/action_eval.py +9 -2
- langfun/core/agentic/action_test.py +25 -0
- langfun/core/async_support.py +32 -3
- langfun/core/coding/python/correction.py +19 -9
- langfun/core/coding/python/execution.py +14 -12
- langfun/core/coding/python/generation.py +21 -16
- langfun/core/coding/python/sandboxing.py +23 -3
- langfun/core/component.py +42 -3
- langfun/core/concurrent.py +70 -6
- langfun/core/concurrent_test.py +1 -0
- langfun/core/console.py +1 -1
- langfun/core/data/conversion/anthropic.py +12 -3
- langfun/core/data/conversion/anthropic_test.py +8 -6
- langfun/core/data/conversion/gemini.py +9 -2
- langfun/core/data/conversion/gemini_test.py +12 -9
- langfun/core/data/conversion/openai.py +145 -31
- langfun/core/data/conversion/openai_test.py +161 -17
- langfun/core/eval/base.py +47 -43
- langfun/core/eval/base_test.py +4 -4
- langfun/core/eval/matching.py +5 -2
- langfun/core/eval/patching.py +3 -3
- langfun/core/eval/scoring.py +4 -3
- langfun/core/eval/v2/__init__.py +1 -0
- langfun/core/eval/v2/checkpointing.py +39 -5
- langfun/core/eval/v2/checkpointing_test.py +1 -1
- langfun/core/eval/v2/eval_test_helper.py +96 -0
- langfun/core/eval/v2/evaluation.py +87 -15
- langfun/core/eval/v2/evaluation_test.py +9 -3
- langfun/core/eval/v2/example.py +45 -39
- langfun/core/eval/v2/example_test.py +3 -3
- langfun/core/eval/v2/experiment.py +51 -8
- langfun/core/eval/v2/metric_values.py +31 -3
- langfun/core/eval/v2/metric_values_test.py +32 -0
- langfun/core/eval/v2/metrics.py +157 -44
- langfun/core/eval/v2/metrics_test.py +39 -18
- langfun/core/eval/v2/progress.py +30 -1
- langfun/core/eval/v2/progress_test.py +27 -0
- langfun/core/eval/v2/progress_tracking_test.py +3 -0
- langfun/core/eval/v2/reporting.py +90 -71
- langfun/core/eval/v2/reporting_test.py +20 -6
- langfun/core/eval/v2/runners/__init__.py +26 -0
- langfun/core/eval/v2/{runners.py → runners/base.py} +22 -124
- langfun/core/eval/v2/runners/debug.py +40 -0
- langfun/core/eval/v2/runners/debug_test.py +79 -0
- langfun/core/eval/v2/runners/parallel.py +100 -0
- langfun/core/eval/v2/runners/parallel_test.py +98 -0
- langfun/core/eval/v2/runners/sequential.py +47 -0
- langfun/core/eval/v2/runners/sequential_test.py +175 -0
- langfun/core/langfunc.py +45 -130
- langfun/core/langfunc_test.py +6 -4
- langfun/core/language_model.py +103 -16
- langfun/core/language_model_test.py +9 -3
- langfun/core/llms/__init__.py +7 -1
- langfun/core/llms/anthropic.py +157 -2
- langfun/core/llms/azure_openai.py +29 -17
- langfun/core/llms/cache/base.py +25 -3
- langfun/core/llms/cache/in_memory.py +48 -7
- langfun/core/llms/cache/in_memory_test.py +14 -4
- langfun/core/llms/compositional.py +25 -1
- langfun/core/llms/deepseek.py +30 -2
- langfun/core/llms/fake.py +32 -1
- langfun/core/llms/gemini.py +14 -9
- langfun/core/llms/google_genai.py +29 -1
- langfun/core/llms/groq.py +28 -3
- langfun/core/llms/llama_cpp.py +23 -4
- langfun/core/llms/openai.py +36 -3
- langfun/core/llms/openai_compatible.py +148 -27
- langfun/core/llms/openai_compatible_test.py +207 -20
- langfun/core/llms/openai_test.py +0 -2
- langfun/core/llms/rest.py +12 -1
- langfun/core/llms/vertexai.py +51 -8
- langfun/core/logging.py +1 -1
- langfun/core/mcp/client.py +77 -22
- langfun/core/mcp/client_test.py +8 -35
- langfun/core/mcp/session.py +94 -29
- langfun/core/mcp/session_test.py +54 -0
- langfun/core/mcp/tool.py +151 -22
- langfun/core/mcp/tool_test.py +197 -0
- langfun/core/memory.py +1 -0
- langfun/core/message.py +160 -55
- langfun/core/message_test.py +65 -81
- langfun/core/modalities/__init__.py +8 -0
- langfun/core/modalities/audio.py +21 -1
- langfun/core/modalities/image.py +19 -1
- langfun/core/modalities/mime.py +62 -3
- langfun/core/modalities/pdf.py +19 -1
- langfun/core/modalities/video.py +21 -1
- langfun/core/modality.py +167 -29
- langfun/core/modality_test.py +42 -12
- langfun/core/natural_language.py +1 -1
- langfun/core/sampling.py +4 -4
- langfun/core/sampling_test.py +20 -4
- langfun/core/structured/__init__.py +2 -24
- langfun/core/structured/completion.py +34 -44
- langfun/core/structured/completion_test.py +23 -43
- langfun/core/structured/description.py +54 -50
- langfun/core/structured/function_generation.py +29 -12
- langfun/core/structured/mapping.py +81 -37
- langfun/core/structured/parsing.py +95 -79
- langfun/core/structured/parsing_test.py +0 -3
- langfun/core/structured/querying.py +215 -142
- langfun/core/structured/querying_test.py +65 -29
- langfun/core/structured/schema/__init__.py +48 -0
- langfun/core/structured/schema/base.py +664 -0
- langfun/core/structured/schema/base_test.py +531 -0
- langfun/core/structured/schema/json.py +174 -0
- langfun/core/structured/schema/json_test.py +121 -0
- langfun/core/structured/schema/python.py +316 -0
- langfun/core/structured/schema/python_test.py +410 -0
- langfun/core/structured/schema_generation.py +33 -14
- langfun/core/structured/scoring.py +47 -36
- langfun/core/structured/tokenization.py +26 -11
- langfun/core/subscription.py +2 -2
- langfun/core/template.py +174 -49
- langfun/core/template_test.py +123 -17
- langfun/env/__init__.py +8 -2
- langfun/env/base_environment.py +320 -128
- langfun/env/base_environment_test.py +473 -0
- langfun/env/base_feature.py +92 -15
- langfun/env/base_feature_test.py +228 -0
- langfun/env/base_sandbox.py +84 -361
- langfun/env/base_sandbox_test.py +1235 -0
- langfun/env/event_handlers/__init__.py +1 -1
- langfun/env/event_handlers/chain.py +233 -0
- langfun/env/event_handlers/chain_test.py +253 -0
- langfun/env/event_handlers/event_logger.py +95 -98
- langfun/env/event_handlers/event_logger_test.py +21 -21
- langfun/env/event_handlers/metric_writer.py +225 -140
- langfun/env/event_handlers/metric_writer_test.py +23 -6
- langfun/env/interface.py +854 -40
- langfun/env/interface_test.py +112 -2
- langfun/env/load_balancers_test.py +23 -2
- langfun/env/test_utils.py +126 -84
- {langfun-0.1.2.dev202510230805.dist-info → langfun-0.1.2.dev202511160804.dist-info}/METADATA +1 -1
- langfun-0.1.2.dev202511160804.dist-info/RECORD +211 -0
- langfun/core/eval/v2/runners_test.py +0 -343
- langfun/core/structured/schema.py +0 -987
- langfun/core/structured/schema_test.py +0 -982
- langfun/env/base_test.py +0 -1481
- langfun/env/event_handlers/base.py +0 -350
- langfun-0.1.2.dev202510230805.dist-info/RECORD +0 -195
- {langfun-0.1.2.dev202510230805.dist-info → langfun-0.1.2.dev202511160804.dist-info}/WHEEL +0 -0
- {langfun-0.1.2.dev202510230805.dist-info → langfun-0.1.2.dev202511160804.dist-info}/licenses/LICENSE +0 -0
- {langfun-0.1.2.dev202510230805.dist-info → langfun-0.1.2.dev202511160804.dist-info}/top_level.txt +0 -0
|
@@ -24,7 +24,7 @@ import pyglove as pg
|
|
|
24
24
|
|
|
25
25
|
@lf.use_init_args(['schema', 'default', 'examples'])
|
|
26
26
|
class _ParseStructure(mapping.Mapping):
|
|
27
|
-
"""
|
|
27
|
+
"""Parses an object out from a natural language text."""
|
|
28
28
|
|
|
29
29
|
context_title = 'USER_REQUEST'
|
|
30
30
|
input_title = 'LM_RESPONSE'
|
|
@@ -39,7 +39,7 @@ class _ParseStructure(mapping.Mapping):
|
|
|
39
39
|
|
|
40
40
|
|
|
41
41
|
class _ParseStructureJson(_ParseStructure):
|
|
42
|
-
"""
|
|
42
|
+
"""Parses an object out from a NL text using JSON as the protocol."""
|
|
43
43
|
|
|
44
44
|
preamble = """
|
|
45
45
|
Please help translate the last LM response into JSON based on the request and the schema:
|
|
@@ -55,7 +55,7 @@ class _ParseStructureJson(_ParseStructure):
|
|
|
55
55
|
|
|
56
56
|
|
|
57
57
|
class _ParseStructurePython(_ParseStructure):
|
|
58
|
-
"""
|
|
58
|
+
"""Parses an object out from a NL text using Python as the protocol."""
|
|
59
59
|
|
|
60
60
|
preamble = """
|
|
61
61
|
Please help translate the last {{ input_title }} into {{ output_title}} based on {{ schema_title }}.
|
|
@@ -84,59 +84,59 @@ def parse(
|
|
|
84
84
|
cache_seed: int | None = 0,
|
|
85
85
|
autofix: int = 0,
|
|
86
86
|
autofix_lm: lf.LanguageModel | None = None,
|
|
87
|
-
protocol:
|
|
87
|
+
protocol: str = 'python',
|
|
88
88
|
returns_message: bool = False,
|
|
89
89
|
**kwargs,
|
|
90
90
|
) -> Any:
|
|
91
|
-
"""
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
```
|
|
91
|
+
"""Parses a natural language message into a structured object using an LLM.
|
|
92
|
+
|
|
93
|
+
`lf.parse` extracts structured information from a natural language string
|
|
94
|
+
or message according to a provided schema. It is the inverse of
|
|
95
|
+
`lf.describe`.
|
|
96
|
+
|
|
97
|
+
**Example:**
|
|
98
|
+
|
|
99
|
+
```python
|
|
100
|
+
import langfun as lf
|
|
101
|
+
import pyglove as pg
|
|
102
|
+
|
|
103
|
+
class FlightDuration(pg.Object):
|
|
104
|
+
hours: int
|
|
105
|
+
minutes: int
|
|
106
|
+
|
|
107
|
+
class Flight(pg.Object):
|
|
108
|
+
airline: str
|
|
109
|
+
flight_number: str
|
|
110
|
+
departure_airport_code: str
|
|
111
|
+
arrival_airport_code: str
|
|
112
|
+
duration: FlightDuration
|
|
113
|
+
price: float
|
|
114
|
+
|
|
115
|
+
text = '''
|
|
116
|
+
The flight is UA2631 of United Airlines, from SFO to JFK,
|
|
117
|
+
duration is 7 hours and 57 minutes, costing $227.
|
|
118
|
+
'''
|
|
119
|
+
|
|
120
|
+
flight = lf.parse(text, Flight, lm=lf.llms.Gemini25Flash())
|
|
121
|
+
assert flight.airline == 'United Airlines'
|
|
122
|
+
assert flight.duration.hours == 7
|
|
123
|
+
```
|
|
125
124
|
|
|
126
125
|
Args:
|
|
127
126
|
message: A `lf.Message` object or a string as the natural language input.
|
|
128
127
|
It provides the complete context for the parsing.
|
|
129
|
-
schema: A `lf.
|
|
130
|
-
default: The default value if parsing
|
|
131
|
-
be raised
|
|
128
|
+
schema: A `lf.Schema` object or equivalent annotations.
|
|
129
|
+
default: The default value to return if parsing fails. If
|
|
130
|
+
`lf.RAISE_IF_HAS_ERROR` is used (default), an error will be raised
|
|
131
|
+
instead.
|
|
132
132
|
user_prompt: An optional user prompt as the description or ask for the
|
|
133
|
-
message, which
|
|
133
|
+
message, which provides more context for parsing.
|
|
134
134
|
lm: The language model to use. If not specified, the language model from
|
|
135
135
|
`lf.context` context manager will be used.
|
|
136
|
-
examples: An optional list of fewshot examples for
|
|
137
|
-
|
|
136
|
+
examples: An optional list of fewshot examples for guiding parsing. If None,
|
|
137
|
+
default examples will be used.
|
|
138
138
|
include_context: If True, include the request sent to LLM for obtaining the
|
|
139
|
-
response to
|
|
139
|
+
response to parse. Otherwise include only the response.
|
|
140
140
|
cache_seed: Seed for computing cache key. The cache key is determined by a
|
|
141
141
|
tuple of (lm, prompt, cache seed). If None, cache will be disabled for
|
|
142
142
|
the query even cache is configured by the LM.
|
|
@@ -146,10 +146,10 @@ def parse(
|
|
|
146
146
|
`autofix_lm` from `lf.context` context manager will be used. Otherwise it
|
|
147
147
|
will use `lm`.
|
|
148
148
|
protocol: The protocol for schema/value representation. Applicable values
|
|
149
|
-
are 'json' and 'python'. By default 'python' will be used
|
|
149
|
+
are 'json' and 'python'. By default 'python' will be used.
|
|
150
150
|
returns_message: If True, returns `lf.Message` as the output, instead of
|
|
151
151
|
returning the structured `message.result`.
|
|
152
|
-
**kwargs: Keyword arguments passed to the `
|
|
152
|
+
**kwargs: Keyword arguments passed to the `_ParseStructure`
|
|
153
153
|
transform.
|
|
154
154
|
|
|
155
155
|
Returns:
|
|
@@ -198,7 +198,7 @@ async def aparse(
|
|
|
198
198
|
cache_seed: int | None = 0,
|
|
199
199
|
autofix: int = 0,
|
|
200
200
|
autofix_lm: lf.LanguageModel | None = None,
|
|
201
|
-
protocol:
|
|
201
|
+
protocol: str = 'python',
|
|
202
202
|
returns_message: bool = False,
|
|
203
203
|
**kwargs,
|
|
204
204
|
) -> Any:
|
|
@@ -223,7 +223,7 @@ async def aparse(
|
|
|
223
223
|
|
|
224
224
|
|
|
225
225
|
def call(
|
|
226
|
-
prompt: str
|
|
226
|
+
prompt: Union[str, lf.Template, lf.Message],
|
|
227
227
|
schema: Union[
|
|
228
228
|
None, schema_lib.Schema, Type[Any], list[Type[Any]], dict[str, Any]
|
|
229
229
|
] = None,
|
|
@@ -236,31 +236,47 @@ def call(
|
|
|
236
236
|
autofix: int = 0,
|
|
237
237
|
autofix_lm: lf.LanguageModel | None = None,
|
|
238
238
|
response_postprocess: Callable[[str], str] | None = None,
|
|
239
|
-
protocol:
|
|
239
|
+
protocol: str = 'python',
|
|
240
240
|
returns_message: bool = False,
|
|
241
241
|
**kwargs,
|
|
242
242
|
) -> Any:
|
|
243
|
-
"""
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
243
|
+
"""Calls a language model and parses the response according to a schema.
|
|
244
|
+
|
|
245
|
+
`lf.call` first calls a language model with a prompt to obtain a natural
|
|
246
|
+
language response, then calls the language model again to parse this
|
|
247
|
+
response into a structured format defined by `schema`. If `schema` is not
|
|
248
|
+
provided, it returns the raw natural language response.
|
|
249
|
+
|
|
250
|
+
**Example:**
|
|
251
|
+
|
|
252
|
+
1. **Call with a Natural Language Prompt**:
|
|
253
|
+
By default, `lf.call` with a string prompt returns a natural language
|
|
254
|
+
response:
|
|
255
|
+
```python
|
|
256
|
+
r = lf.call('Compute one plus one', lm=lf.llms.Gpt4())
|
|
257
|
+
print(r)
|
|
258
|
+
# Output: 2
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
2. **Call with Structured Output**:
|
|
262
|
+
If `schema` is provided, `lf.call` parses the LLM response into the
|
|
263
|
+
specified schema using a second LM call:
|
|
264
|
+
```python
|
|
265
|
+
r = lf.call('Compute one plus one', int, lm=lf.llms.Gpt4())
|
|
266
|
+
print(r)
|
|
267
|
+
# Output: 2
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
3. **Call with Templated Prompt**:
|
|
271
|
+
The prompt can be a template string with placeholders (e.g., `{{x}}`,
|
|
272
|
+
`{{y}}`), whose values are provided as keyword arguments:
|
|
273
|
+
```python
|
|
274
|
+
r = lf.call(
|
|
275
|
+
'Compute {{x}} plus {{y}}',
|
|
276
|
+
int, x='one', y='one', lm=lf.llms.Gpt4())
|
|
277
|
+
print(r)
|
|
278
|
+
# Output: 2
|
|
279
|
+
```
|
|
264
280
|
|
|
265
281
|
Args:
|
|
266
282
|
prompt: User prompt that will be sent to LM, which could be a string or a
|
|
@@ -272,10 +288,10 @@ def call(
|
|
|
272
288
|
If not specified, `lm` from `lf.context` context manager will be used.
|
|
273
289
|
parsing_lm: Language model that will be used for parsing. If None, the `lm`
|
|
274
290
|
for prompting the LM will be used.
|
|
275
|
-
parsing_examples: Examples for parsing the output. If None,
|
|
276
|
-
|
|
291
|
+
parsing_examples: Examples for parsing the output. If None, no examples
|
|
292
|
+
will be used for parsing.
|
|
277
293
|
parsing_include_context: If True, include the request sent to LLM for
|
|
278
|
-
obtaining the response to
|
|
294
|
+
obtaining the response to parse. Otherwise include only the response.
|
|
279
295
|
cache_seed: Seed for computing cache key. The cache key is determined by a
|
|
280
296
|
tuple of (lm, prompt, cache seed). If None, cache will be disabled for
|
|
281
297
|
the query even cache is configured by the LM.
|
|
@@ -284,10 +300,10 @@ def call(
|
|
|
284
300
|
autofix_lm: The language model to use for autofix. If not specified, the
|
|
285
301
|
`autofix_lm` from `lf.context` context manager will be used. Otherwise it
|
|
286
302
|
will use `parsing_lm`.
|
|
287
|
-
response_postprocess: A callback function to post
|
|
303
|
+
response_postprocess: A callback function to post-process the text response
|
|
288
304
|
before sending for parsing.
|
|
289
305
|
protocol: The protocol for schema/value representation. Applicable values
|
|
290
|
-
are 'json' and 'python'. By default 'python' will be used
|
|
306
|
+
are 'json' and 'python'. By default 'python' will be used.
|
|
291
307
|
returns_message: If True, return a `lf.Message` object instead of its text
|
|
292
308
|
or result.
|
|
293
309
|
**kwargs: Keyword arguments. Including options that control the calling
|
|
@@ -351,7 +367,7 @@ async def acall(
|
|
|
351
367
|
autofix: int = 0,
|
|
352
368
|
autofix_lm: lf.LanguageModel | None = None,
|
|
353
369
|
response_postprocess: Callable[[str], str] | None = None,
|
|
354
|
-
protocol:
|
|
370
|
+
protocol: str = 'python',
|
|
355
371
|
returns_message: bool = False,
|
|
356
372
|
**kwargs,
|
|
357
373
|
) -> Any:
|
|
@@ -376,7 +392,7 @@ async def acall(
|
|
|
376
392
|
|
|
377
393
|
|
|
378
394
|
def _parse_structure_cls(
|
|
379
|
-
protocol:
|
|
395
|
+
protocol: str,
|
|
380
396
|
) -> Type[_ParseStructure]:
|
|
381
397
|
if protocol == 'json':
|
|
382
398
|
return _ParseStructureJson
|
|
@@ -387,7 +403,7 @@ def _parse_structure_cls(
|
|
|
387
403
|
|
|
388
404
|
|
|
389
405
|
def default_parse_examples() -> list[mapping.MappingExample]:
|
|
390
|
-
"""
|
|
406
|
+
"""Returns default parsing examples."""
|
|
391
407
|
|
|
392
408
|
class AdditionResults(pg.Object):
|
|
393
409
|
one_plus_one_equals: int | None
|
|
@@ -745,9 +745,6 @@ class CallTest(unittest.TestCase):
|
|
|
745
745
|
parsing.call('what is one plus two?', int, lm=lm, autofix=3), 3
|
|
746
746
|
)
|
|
747
747
|
|
|
748
|
-
def test_call_with_structured_input(self):
|
|
749
|
-
self.assertEqual(parsing.call(1, lm=fake.StaticResponse('2')), '2')
|
|
750
|
-
|
|
751
748
|
def test_call_with_response_postprocess(self):
|
|
752
749
|
target_str = '@TARGET_STR@'
|
|
753
750
|
random_str = '!RANDOM_STR!'
|