npm package: @langinsight/langchain
Description: LangInsight callback handler for LangChain. Sends input/output traces to LangInsight in parallel on each LLM end and supports feedback (thumbs up/down) via `score()`.
Author: iZ.Inc
Latest version: 0.1.0

# @langinsight/langchain

LangInsight callback handler for LangChain. Sends input/output traces to LangInsight in parallel on each LLM end and supports feedback (thumbs up/down) via `score()`.

## Usage

### Basic usage

```typescript
import { ChatOllama } from "@langchain/ollama";
import { LangInsight } from "@langinsight/langchain";

const model = new ChatOllama({ model: "gpt-oss:20b" });

const { LANGINSIGHT_ENDPOINT, LANGINSIGHT_API_KEY } = process.env;

await model.invoke("hi!", {
  callbacks: [
    new LangInsight.CallbackHandler({
      apiKey: LANGINSIGHT_API_KEY,
      endpoint: LANGINSIGHT_ENDPOINT,
      metadata: { userId: "admin", sessionId: "admin" },
      onSuccess: (input, output) => console.log("Trace sent:", output.id),
      onFailure: (err) => console.error("Trace failed:", err),
    }),
  ],
});
```

### With LangGraph

```typescript
import { Annotation, END, START, StateGraph } from "@langchain/langgraph";
import { ChatOllama } from "@langchain/ollama";
import { LangInsight } from "@langinsight/langchain";

const model = new ChatOllama({ model: "gpt-oss:20b" });

const callbacks = [
  new LangInsight.CallbackHandler({
    apiKey: process.env.LANGINSIGHT_API_KEY,
    endpoint: process.env.LANGINSIGHT_ENDPOINT,
    metadata: { userId: "admin", sessionId: "langgraph-example" },
  }),
];

const GraphState = Annotation.Root({
  input: Annotation<string>,
  response: Annotation<string>,
});

async function processInput(state: typeof GraphState.State) {
  const response = await model.invoke(state.input, { callbacks });
  return {
    response: response.content as string,
  };
}

const workflow = new StateGraph(GraphState)
  .addNode("process", processInput)
  .addEdge(START, "process")
  .addEdge("process", END);

const app = workflow.compile();

const result = await app.invoke(
  { input: "What is LangGraph?" },
  { callbacks }
);
```

### Feedback (score)

Trace ID は `handler.result` で取得し、その `output.id` を `score()` に渡してフィードバックを送信する。DB 永続化などは `onSuccess` コールバックでも行える。

```typescript
const handler = new LangInsight.CallbackHandler({
  apiKey: LANGINSIGHT_API_KEY,
  endpoint: LANGINSIGHT_ENDPOINT,
  metadata: { userId: "admin", sessionId: "admin" },
});

await model.invoke("hi!", { callbacks: [handler] });

const { input, output } = await handler.result;
await handler.score({ traceId: output.id, value: 1 });  // 👍
await handler.score({ traceId: output.id, value: -1 }); // 👎
```

## Options

| Option      | Type                      | Required | Description                                                             |
| ----------- | -------------------------- | -------- | ----------------------------------------------------------------------- |
| `apiKey`    | `string`                   | Yes      | LangInsight API key                                                     |
| `endpoint`  | `string`                   | Yes      | LangInsight API endpoint (e.g. `https://api.langinsight.example.com`)   |
| `metadata`  | `object`                   | Yes      | Metadata attached to traces                                             |
| `metadata.userId`    | `string` | Yes      | User ID                                                                 |
| `metadata.sessionId`| `string` | Yes      | Session ID (e.g. conversation id)                                       |
| `metadata.modelName`| `string` | No       | Model name (defaults to run metadata when not set)                      |
| `metadata.*`        | `any`   | No       | Additional key-value pairs                                              |
| `onSuccess` | `(input: Trace, output: Trace) => void` | No | Callback invoked with both input and output traces when trace submission succeeds. Use `output.id` to get traceId and persist to DB. |
| `onFailure` | `(error: Error) => void`   | No       | Callback invoked with the error when trace submission fails             |

## API

- **`score({ traceId, value })`** — Submits feedback (1 = thumbs up, -1 = thumbs down) for the given trace. Use `(await handler.result).output.id` as `traceId`.
- **`result`** — A promise that resolves with `{ input: Trace, output: Trace }` when traces are sent successfully.