> ## Documentation Index
> Fetch the complete documentation index at: https://docs.onecortex.io/llms.txt
> Use this file to discover all available pages before exploring further.

# LangChain.js

> Deploy a LangChain.js runnable as it is, with its tool calls and results.

## What is supported

`@langchain/core` 1.x. Onecortex recognises any runnable: an object with `invoke` that LangChain.js marks as its own. It streams it with `streamEvents` when it can.

## A complete agent

```yaml agent.yml theme={null}
apiVersion: v1
runtime: node22
entrypoint: agent.ts#chain
dependencies: package.json
```

```json package.json theme={null}
{
  "type": "module",
  "dependencies": {
    "@langchain/core": "^1.0.0",
    "@langchain/openai": "^1.0.0"
  }
}
```

```ts agent.ts theme={null}
import { ChatPromptTemplate } from '@langchain/core/prompts'
import { StringOutputParser } from '@langchain/core/output_parsers'
import { RunnableSequence } from '@langchain/core/runnables'
import { ChatOpenAI } from '@langchain/openai'

// Reads OPENAI_API_KEY, which you add as a secret on the agent's Config tab.
const prompt = ChatPromptTemplate.fromMessages([
  ['system', 'Summarise what the user says in one line.'],
  ['human', '{input}'],
])

// The prompt arrives as a string, so the first step shapes it for the template.
export const chain = RunnableSequence.from([
  (input: string) => ({ input }),
  prompt,
  new ChatOpenAI({ model: 'gpt-5' }),
  new StringOutputParser(),
])
```

Add `OPENAI_API_KEY` as a secret on the agent's **Config** tab, then deploy. Any model works: this one is an example. See [Configuration and secrets](/build/configuration).

<Card title="A complete LangChain.js example" icon="github" href="https://github.com/onecortex-io/examples/tree/main/ticket-summarizer">
  `ticket-summarizer`: A runnable calling two tools, then writing a one line summary, routed by a team the caller sends. It runs with no model key.
</Card>

## The prompt and the reply

The prompt is passed to `invoke` as a string, so a chain that starts with a prompt template needs a first step that turns it into the template's variables, as above.

## Events it reports

| Events | From |
| - | - |
| `text` | The runnable's final output |
| `tool_call_start`, `tool_call_args`, `tool_call_end` | Each tool the runnable calls |
| `tool_result` | Each tool's output, with `isError` when it failed |
| `done` or `error` | The end of the run: always exactly one |

See [Streaming and events](/build/streaming).

## The caller's fields

Under `configurable.onecortex` in the run's config, which every runnable receives:

```ts theme={null}
const route = RunnableLambda.from(async (input: string, config) => {
  const sent = config?.configurable?.['onecortex'] as { params?: { team?: string } } | undefined
  const team = sent?.params?.team ?? 'support'
  // ...
})
```

## Known limits

* The reply is the runnable's final output, not streamed token by token.

## Troubleshooting

| You see | Do this |
| - | - |
| The reply is `[object Object]` | Return a string from the runnable: end the chain with `StringOutputParser`. |

More on [Troubleshooting](/production/troubleshooting) and [Errors](/production/errors).
