import type { Metadata } from "next";
import { CodeBlock } from "@/components/code-block";

export const metadata: Metadata = {
  title: "LangChain Integration",
  description:
    "Use the AgentLensCallbackHandler to trace LangChain chains, agents, and tool invocations.",
};

export default function LangChainIntegrationPage() {
  return (
    <div>
      <h1 className="text-4xl font-bold tracking-tight mb-4">
        LangChain Integration
      </h1>
      <p className="text-lg text-neutral-400 mb-10 leading-relaxed">
        The AgentLensCallbackHandler plugs into LangChain&apos;s callback system
        to automatically trace chains, agents, LLM calls, and tool invocations
        without changing your existing code.
      </p>

      <section className="mb-12">
        <h2 className="text-2xl font-semibold mb-4">Installation</h2>
        <CodeBlock title="terminal" language="bash">{`pip install vectry-agentlens langchain langchain-openai`}</CodeBlock>
      </section>

      <section className="mb-12">
        <h2 className="text-2xl font-semibold mb-4">Quick setup</h2>
        <CodeBlock title="main.py" language="python">{`import agentlens
from agentlens.integrations.langchain import AgentLensCallbackHandler

agentlens.init(
    api_key="your-api-key",
    endpoint="https://agentlens.vectry.tech",
)

handler = AgentLensCallbackHandler()`}</CodeBlock>
      </section>

      <section className="mb-12">
        <h2 className="text-2xl font-semibold mb-4">Using with chains</h2>
        <p className="text-neutral-400 leading-relaxed mb-4">
          Pass the handler in the <code className="text-emerald-400 font-mono text-xs bg-emerald-500/5 px-1.5 py-0.5 rounded">callbacks</code> config:
        </p>
        <CodeBlock title="chain_example.py" language="python">{`from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser

llm = ChatOpenAI(model="gpt-4o")
prompt = ChatPromptTemplate.from_messages([
    ("system", "You are a helpful assistant."),
    ("user", "{input}"),
])

chain = prompt | llm | StrOutputParser()

result = chain.invoke(
    {"input": "Explain recursion"},
    config={"callbacks": [handler]},
)`}</CodeBlock>
      </section>

      <section className="mb-12">
        <h2 className="text-2xl font-semibold mb-4">Using with agents</h2>
        <CodeBlock title="agent_example.py" language="python">{`from langchain_openai import ChatOpenAI
from langchain.agents import AgentExecutor, create_tool_calling_agent
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.tools import tool

@tool
def calculator(expression: str) -> str:
    """Evaluate a math expression."""
    return str(eval(expression))

llm = ChatOpenAI(model="gpt-4o")
prompt = ChatPromptTemplate.from_messages([
    ("system", "You are a helpful math assistant."),
    ("user", "{input}"),
    ("placeholder", "{agent_scratchpad}"),
])

agent = create_tool_calling_agent(llm, [calculator], prompt)
executor = AgentExecutor(agent=agent, tools=[calculator])

result = executor.invoke(
    {"input": "What is 42 * 17 + 3?"},
    config={"callbacks": [handler]},
)`}</CodeBlock>
      </section>

      <section className="mb-12">
        <h2 className="text-2xl font-semibold mb-4">What gets captured</h2>
        <p className="text-neutral-400 leading-relaxed mb-4">
          The callback handler maps LangChain events to AgentLens concepts:
        </p>
        <div className="overflow-x-auto">
          <table className="w-full text-sm">
            <thead>
              <tr className="border-b border-neutral-800">
                <th className="text-left py-2 pr-4 text-neutral-400 font-medium">LangChain Event</th>
                <th className="text-left py-2 pr-4 text-neutral-400 font-medium">AgentLens Type</th>
                <th className="text-left py-2 text-neutral-400 font-medium">Captured Data</th>
              </tr>
            </thead>
            <tbody className="text-neutral-300">
              <tr className="border-b border-neutral-800/50">
                <td className="py-2 pr-4 text-neutral-400">Chain start/end</td>
                <td className="py-2 pr-4 font-mono text-emerald-400 text-xs">CHAIN span</td>
                <td className="py-2">Input/output, duration</td>
              </tr>
              <tr className="border-b border-neutral-800/50">
                <td className="py-2 pr-4 text-neutral-400">LLM start/end</td>
                <td className="py-2 pr-4 font-mono text-emerald-400 text-xs">LLM_CALL span</td>
                <td className="py-2">Model, messages, tokens, cost, duration</td>
              </tr>
              <tr className="border-b border-neutral-800/50">
                <td className="py-2 pr-4 text-neutral-400">Tool start/end</td>
                <td className="py-2 pr-4 font-mono text-emerald-400 text-xs">TOOL_CALL span</td>
                <td className="py-2">Tool name, input args, output, duration</td>
              </tr>
              <tr className="border-b border-neutral-800/50">
                <td className="py-2 pr-4 text-neutral-400">Agent action</td>
                <td className="py-2 pr-4 font-mono text-emerald-400 text-xs">TOOL_SELECTION decision</td>
                <td className="py-2">Selected tool, reasoning</td>
              </tr>
              <tr className="border-b border-neutral-800/50">
                <td className="py-2 pr-4 text-neutral-400">Retry</td>
                <td className="py-2 pr-4 font-mono text-emerald-400 text-xs">RETRY event</td>
                <td className="py-2">Error message, attempt count</td>
              </tr>
              <tr>
                <td className="py-2 pr-4 text-neutral-400">Error</td>
                <td className="py-2 pr-4 font-mono text-emerald-400 text-xs">ERROR event</td>
                <td className="py-2">Exception type, message, traceback</td>
              </tr>
            </tbody>
          </table>
        </div>
      </section>

      <section className="mb-12">
        <h2 className="text-2xl font-semibold mb-4">Global callbacks</h2>
        <p className="text-neutral-400 leading-relaxed mb-4">
          To trace all LangChain operations without passing callbacks
          individually, set the handler globally:
        </p>
        <CodeBlock title="global.py" language="python">{`from langchain_core.globals import set_llm_cache
from langchain.callbacks.manager import set_handler

set_handler(handler)

# Now all chains and agents are traced automatically
result = chain.invoke({"input": "Hello"})
# No need to pass config={"callbacks": [handler]}`}</CodeBlock>
      </section>

      <section>
        <h2 className="text-2xl font-semibold mb-4">Handler options</h2>
        <div className="overflow-x-auto">
          <table className="w-full text-sm">
            <thead>
              <tr className="border-b border-neutral-800">
                <th className="text-left py-2 pr-4 text-neutral-400 font-medium">Parameter</th>
                <th className="text-left py-2 pr-4 text-neutral-400 font-medium">Type</th>
                <th className="text-left py-2 pr-4 text-neutral-400 font-medium">Default</th>
                <th className="text-left py-2 text-neutral-400 font-medium">Description</th>
              </tr>
            </thead>
            <tbody className="text-neutral-300">
              <tr className="border-b border-neutral-800/50">
                <td className="py-2 pr-4 font-mono text-emerald-400 text-xs">trace_name</td>
                <td className="py-2 pr-4 text-neutral-500">str | None</td>
                <td className="py-2 pr-4 text-neutral-500">None</td>
                <td className="py-2">Override the default trace name</td>
              </tr>
              <tr className="border-b border-neutral-800/50">
                <td className="py-2 pr-4 font-mono text-emerald-400 text-xs">tags</td>
                <td className="py-2 pr-4 text-neutral-500">list[str]</td>
                <td className="py-2 pr-4 text-neutral-500">[]</td>
                <td className="py-2">Tags to attach to all traces</td>
              </tr>
              <tr>
                <td className="py-2 pr-4 font-mono text-emerald-400 text-xs">capture_io</td>
                <td className="py-2 pr-4 text-neutral-500">bool</td>
                <td className="py-2 pr-4 text-neutral-500">True</td>
                <td className="py-2">Capture input/output payloads</td>
              </tr>
            </tbody>
          </table>
        </div>
        <CodeBlock title="options.py" language="python">{`handler = AgentLensCallbackHandler(
    trace_name="my-langchain-app",
    tags=["production", "langchain"],
    capture_io=True,
)`}</CodeBlock>
      </section>
    </div>
  );
}
