From d265678cb0c70b569f1222c297d6d28b3e47b3e2 Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Thu, 5 Nov 2026 10:25:21 -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`: ```typescript await invoke({ ..., input: { input: "x" }, metadata: { marker: "top" } }); ``` ```python 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 (the second handler argument in TypeScript, `hooks.metadata` in Python), and shows how to fill the `metadata` argument by nesting it in `input`: ```typescript await invoke({ ..., input: { input: "x", metadata: { marker: "nested" } } }); ``` The runtime behaviour is unchanged. The same wrong sentence also appears in the generated `js/src/generated_plain_types.ts`. It comes from the backend typespec (`typespecs/src/functions.ts`) and needs fixing there, then regenerating. Mirrors braintrustdata/braintrust-sdk-python#1073. Refs: SDK-791 Co-Authored-By: Claude Opus 5.5 --- .changeset/clarify-invoke-metadata-docs.md | 5 +++++ js/src/functions/invoke.ts | 6 ++++-- 2 files changed, 9 insertions(+), 2 deletions(-) create mode 100644 .changeset/clarify-invoke-metadata-docs.md diff --git a/.changeset/clarify-invoke-metadata-docs.md b/.changeset/clarify-invoke-metadata-docs.md new file mode 100644 index 000000000..73f26d906 --- /dev/null +++ b/.changeset/clarify-invoke-metadata-docs.md @@ -0,0 +1,5 @@ +--- +"braintrust": patch +--- + +docs(functions): clarify where invoke metadata reaches code functions diff --git a/js/src/functions/invoke.ts b/js/src/functions/invoke.ts index f7bbb35f5..5a5ada01b 100644 --- a/js/src/functions/invoke.ts +++ b/js/src/functions/invoke.ts @@ -78,8 +78,10 @@ export interface InvokeFunctionArgs< /** * 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 (the handler's second argument in TypeScript, `hooks.metadata` in Python), 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: { ... } } })`. */ metadata?: Record; /**