docs(otel): document remappings#2989
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
@claude review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ad01125db6
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| --- | ||
| description: Langfuse automatically renders tool definitions and tool calls from your agent traces, making it easy to debug function calling. | ||
| sidebarTitle: Tool Calls | ||
| --- |
There was a problem hiding this comment.
Add required title frontmatter to tool-calls docs page
This new docs file omits the required title frontmatter key, which causes the docs loader to fail during build ([MDX] invalid frontmatter ... title: expected string, received undefined when running pnpm next build). Because this page is part of the content/docs collection, the missing field breaks site compilation rather than just degrading this one page.
Useful? React with 👍 / 👎.
| --- | ||
| description: Langfuse automatically renders tool definitions and tool calls from your agent traces, making it easy to debug function calling. | ||
| sidebarTitle: Tool Calls | ||
| --- |
There was a problem hiding this comment.
🔴 Missing required title: field in this new file's frontmatter — it's the only file in all of content/docs/ that omits it. The Fumadocs frontmatter schema (baseFrontmatterSchema → frontmatterSchema in source.config.ts) declares title as a required z.string(), so the MDX collection build will fail with a Zod ValidationError; even if it didn't, lib/mdx-page.ts buildSectionMetadata would crash because enrichOgTitle calls title.toLowerCase() on undefined. Fix: add e.g. title: Tool Calls (or title: Tool Call Visualization to match the H1) on a new line in the frontmatter.
Extended reasoning...
What the bug is
The new content/docs/observability/features/tool-calls.mdx file has only description: and sidebarTitle: in its frontmatter — no title:. A scan of every .mdx under content/docs confirms it is the only file out of ~99 docs without title:, and the only one out of 20 sibling features/*.mdx pages without it. So it is at minimum a glaring convention violation, but more importantly it breaks two real code paths.
Code path 1: MDX collection build fails on frontmatter validation
source.config.ts:26 defines:
const baseFrontmatterSchema = frontmatterSchema.extend({ ... });frontmatterSchema is imported from fumadocs-mdx/config. In fumadocs-mdx 14.2.7 (per the package.json pin ^14.2.7), this is pageSchema = z.object({ title: z.string(), description: z.string().optional(), ... }) — title is required, not optional. The docs collection uses sidebarFrontmatterSchema = baseFrontmatterSchema.extend({ shortTitle, sidebarTitle }) (source.config.ts:80), and z.extend preserves the required-ness of title. fumadocs-mdx's compile path then calls validate(collection.schema, data, …) and throws a ValidationError("invalid frontmatter in …") on missing fields, so pnpm build (or the MDX collection step) will fail with something like invalid frontmatter in .../tool-calls.mdx: title: Required.
Code path 2: Metadata generation crashes
Even if validation were lenient, lib/mdx-page.ts:119 reads:
const seoTitle = pageData.seoTitle || page.data.title;
const ogTitle = pageData.seoTitle ? seoTitle : enrichOgTitle(seoTitle, slug, sectionTitle);With no title and no seoTitle, seoTitle is undefined and we enter enrichOgTitle at lib/mdx-page.ts:84:
const lower = title.toLowerCase().trim();That throws TypeError: Cannot read properties of undefined (reading 'toLowerCase') while rendering /docs/observability/features/tool-calls. Note sidebarTitle: Tool Calls doesn't help — lib/source.ts's shortTitleTransformer consumes sidebarTitle only for the sidebar label, never as a title fallback for metadata.
Step-by-step proof (what happens if you build right now)
- fumadocs-mdx scans
content/docsand loads each.mdxfrontmatter. - It calls
sidebarFrontmatterSchema.parse({ description: "…", sidebarTitle: "Tool Calls" })for this file (notitlekey). title: z.string()frompageSchemafails with{ code: "invalid_type", expected: "string", received: "undefined", path: ["title"] }.- fumadocs-mdx throws
ValidationError("invalid frontmatter in content/docs/observability/features/tool-calls.mdx: title: Required"). Build aborts. - Hypothetically bypassing Signup for product updates via email #4: rendering
/docs/observability/features/tool-callscallsbuildSectionMetadata,seoTitle = undefined || undefined = undefined,enrichOgTitle(undefined, …)→undefined.toLowerCase()→TypeError. Page 500s.
How to fix
One-line change in the frontmatter:
---
title: Tool Calls
description: Langfuse automatically renders tool definitions and tool calls from your agent traces, making it easy to debug function calling.
sidebarTitle: Tool Calls
---Or title: Tool Call Visualization to mirror the H1. The same fix should be applied to the duplicate pages/docs/observability/features/tool-calls.mdx file (or that file should be deleted — both copies currently lack title:).
| --- | ||
| description: Langfuse automatically renders tool definitions and tool calls from your agent traces, making it easy to debug function calling. | ||
| sidebarTitle: Tool Calls | ||
| --- | ||
|
|
||
| # Tool Call Visualization | ||
|
|
||
| Tool calls are the heartbeat of agents. Langfuse automatically renders all tools available to an LLM at the top of each generation, allowing you to instantly see if the LLM selected the right one. | ||
|
|
||
| <Frame fullWidth> |
There was a problem hiding this comment.
🔴 This PR adds a stray duplicate pages/docs/observability/features/tool-calls.mdx alongside the canonical content/docs/observability/features/tool-calls.mdx. This site uses Fumadocs App Router (routes resolved from content/docs via app/docs/[[...slug]]) and next.config.mjs does not extend pageExtensions to .mdx, so the pages/ file is never served — it is dead content that has already drifted from the canonical copy within this same PR. Please delete pages/docs/observability/features/tool-calls.mdx.
Extended reasoning...
What the bug is
This PR adds two copies of the same documentation page:
content/docs/observability/features/tool-calls.mdx— the canonical page, wired into the sidebar viacontent/docs/observability/features/meta.jsonpages/docs/observability/features/tool-calls.mdx— a stray duplicate
The pages/ copy is the only file in the entire pages/ directory (git log --all -- pages/ shows only this PR's commit ad01125), and it is never rendered by the site.
Why it is dead
The repo migrated from Nextra to Fumadocs and now routes /docs/* exclusively through the Next.js App Router:
source.config.tsdeclaresdefineDocs({ dir: 'content/docs', ... }).app/docs/[[...slug]]/page.tsxis a catch-all that resolves slugs viasource.getPage()from the Fumadocs collection rooted atcontent/docs.next.config.mjswires onlycreateMDX()fromfumadocs-mdx/next; it does not overridepageExtensions, so Next.js's default['tsx','ts','jsx','js']applies..mdxfiles inpages/are not picked up as routes.scripts/authors/config.jseven contains an explicit comment that thepages/directory is retained only so the pre-migration git history can be walked for author attribution — not for routing.
So the pages/ file is invisible to users; the /docs/observability/features/tool-calls URL is served from the content/ copy.
Concrete proof of the drift hazard
The two files differ already, in the same PR that introduced them:
- Line 38 of
pages/.../tool-calls.mdx:No changes to your instrumentation code required—if you're using tools with a supported framework, visualization appears automatically.(em-dash, one sentence) - Line 40 of
content/.../tool-calls.mdx:No changes to your instrumentation code required. If you're using tools with a supported framework, visualization appears automatically.(period, two sentences) - The
GhDiscussionsPreviewimportstatement is at the top of thecontent/copy and at the bottom of thepages/copy.
This is exactly the maintenance hazard the deletion avoids: future copy edits will land on only one of the two files, and the dead copy will silently bit-rot.
Step-by-step proof of impact
- A reader visits
https://langfuse.com/docs/observability/features/tool-calls. - Next.js App Router matches
app/docs/[[...slug]]/page.tsxwithslug = ['observability','features','tool-calls']. - That page calls
source.getPage(slug), which reads the Fumadocs content collection rooted atcontent/docs. - The reader sees
content/docs/observability/features/tool-calls.mdx— never thepages/copy. - A future contributor edits one copy (say, fixing a typo in the em-dash line). The other copy is now stale, but no build error fires because the dead file is never rendered or type-checked.
Fix
Delete pages/docs/observability/features/tool-calls.mdx. The canonical file in content/docs/observability/features/tool-calls.mdx already has the correct sidebar entry in meta.json and the correct import placement at the top.
Greptile Summary
This PR documents how Langfuse normalizes tool definitions and called tool invocations from OpenTelemetry and framework-specific metadata, and adds a new "Tool Call Visualization" feature page.
content/docs/observability/features/tool-calls.mdxand itspages/mirror with a new doc covering the tool-call UI, supported frameworks, and detection logic.opentelemetry.mdxdescribing howgen_ai.tool.definitions, Vercel AI SDK, Pydantic-AI, OpenInference, and metadata-fallback sources are remapped intoinput.tools,tool_definitions,tool_calls, andtool_call_names.meta.jsonso it appears in the sidebar.Confidence Score: 4/5
Safe to merge — all changes are documentation-only with no runtime code affected.
The pages/ version of the new doc places its import at the bottom of the file rather than at the top, inconsistent with the repo convention and with the content/ version of the same file.
pages/docs/observability/features/tool-calls.mdx — import placement and minor wording divergence from its content/ counterpart.
Flowchart
%%{init: {'theme': 'neutral'}}%% flowchart TD A[Incoming OTel Span] --> B{Source attribute?} B -->|gen_ai.tool.definitions| C[Move to input.tools\nremove duplicate attribute] B -->|ai.prompt.tools| D[Vercel AI SDK\nNamed tools → tool_definitions\nProvider tools stay in input.tools] B -->|model_request_parameters.function_tools| E[Pydantic-AI\nMove to input.tools\nremove nested key] B -->|llm.tools.N.tool.json_schema| F[OpenInference-style\nMove to input.tools in index order\nremove moved attributes] B -->|metadata.tools fallback| G{All items named\ntool definitions?} G -->|Yes| H[Move to input.tools] G -->|No| I[Preserve in metadata] C --> J[Langfuse Generation] D --> J E --> J F --> J H --> J J --> K[input.tools / tool_definitions\nfor display filtering exports] A --> L{Output contains\ntool calls?} L -->|output.tool_calls / toolCalls\nchoices message tool_calls\nAI SDK tool-call parts\nAnthropic tool_use parts| M[tool_calls + tool_call_names] M --> KPrompt To Fix All With AI
Reviews (1): Last reviewed commit: "docs(otel): document remappings" | Re-trigger Greptile
Context used:
Learned From
langfuse/langfuse-python#1387