From 93fbd3006245a72786674c90ecec11fc81eea799 Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Thu, 5 Nov 2026 10:22:31 -0500 Subject: [PATCH] docs(functions): clarify where invoke metadata reaches code functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit > 🤖 **This text was AI-generated.** The `invoke()` docstring said top-level `metadata` is passed to the function as its `metadata` argument. That is true for prompts (`{{metadata}}`), but not for code functions. The runtime sends top-level `metadata` as hook data, and a Python handler's `metadata` argument is only filled from `input`: ```python invoke(..., input={"input": "x"}, metadata={"marker": "top"}) def handler(input=None, metadata=None, hooks=None): metadata # None hooks.metadata # {"marker": "top"} ``` A customer's scorer therefore saw an empty `metadata` argument on every row. The docstring now explains that code functions receive top-level metadata through the hooks (`hooks.metadata` in Python, the second handler argument in TypeScript), and shows how to fill the `metadata` argument by nesting it in `input`: ```python invoke(..., input={"input": "x", "metadata": {"marker": "nested"}}) ``` The runtime behaviour is unchanged. The same wrong sentence also appears in the generated `_generated_types.py`. It comes from the backend typespec (`typespecs/src/functions.ts`) and needs fixing there, then regenerating. Refs: SDK-791 --- py/src/braintrust/functions/invoke.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/py/src/braintrust/functions/invoke.py b/py/src/braintrust/functions/invoke.py index c023d365..b3a9619f 100644 --- a/py/src/braintrust/functions/invoke.py +++ b/py/src/braintrust/functions/invoke.py @@ -128,8 +128,11 @@ def invoke( input: The input to the function. This will be logged as the `input` field in the span. messages: Additional OpenAI-style messages to add to the prompt (only works for llm functions). metadata: Additional metadata to add to the span. This will be logged as the `metadata` field in the span. - It will also be available as the {{metadata}} field in the prompt and as the `metadata` argument - to the function. + It will also be available as the {{metadata}} field in the prompt. For code functions, it is passed + through the hooks (`hooks.metadata` in Python, the handler's second argument in TypeScript), not + as the handler's `metadata` argument, which is read from `input`. To fill + the handler's `metadata` argument, nest it in `input`, e.g. + `invoke(..., input={"input": ..., "metadata": {...}})`. tags: Tags to add to the span. This will be logged as the `tags` field in the span. parent: The parent of the function. This can be an existing span, logger, or experiment, or the output of `.export()` if you are distributed tracing. If unspecified, will use