or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

advanced.mdauthentication.mdcallbacks.mdindex.mdinput-widgets.mdintegrations.mdmessaging.mdui-elements.mduser-management.md

integrations.mddocs/

0

# Integrations

1

2

Seamless integration with popular ML/AI frameworks including automatic step tracking, observability, and LLM call monitoring. These integrations provide zero-configuration observability for AI applications built with industry-standard libraries.

3

4

## Capabilities

5

6

### OpenAI Integration

7

8

Automatic instrumentation of the OpenAI SDK with step tracking, token usage monitoring, and conversation logging.

9

10

```python { .api }

11

import chainlit as cl

12

13

def instrument_openai() -> None:

14

"""

15

Automatically instrument OpenAI SDK for step tracking and observability.

16

Call once during application startup to enable automatic LLM step creation.

17

18

Requirements:

19

- openai >= 1.0.0

20

21

Features:

22

- Automatic step creation for all OpenAI API calls

23

- Model name, timing, and token usage capture

24

- Message history tracking for chat completions

25

- Support for streaming responses

26

- Error handling and retry monitoring

27

28

Usage:

29

Call this function once at startup, then use OpenAI SDK normally.

30

All calls will automatically appear as steps in the Chainlit UI.

31

32

Returns:

33

None

34

"""

35

```

36

37

Usage examples for OpenAI integration:

38

39

```python

40

import chainlit as cl

41

import openai

42

43

# Initialize OpenAI instrumentation (call once at startup)

44

cl.instrument_openai()

45

46

# Initialize OpenAI client

47

openai_client = openai.AsyncOpenAI(api_key="your-api-key")

48

49

@cl.on_message

50

async def chat_with_openai(message: cl.Message):

51

"""Chat with OpenAI using automatic step tracking"""

52

53

# This call will automatically create a step in the UI

54

response = await openai_client.chat.completions.create(

55

model="gpt-3.5-turbo",

56

messages=[

57

{"role": "system", "content": "You are a helpful assistant."},

58

{"role": "user", "content": message.content}

59

],

60

temperature=0.7,

61

max_tokens=150

62

)

63

64

# Response is automatically tracked with:

65

# - Model used (gpt-3.5-turbo)

66

# - Token usage (prompt + completion tokens)

67

# - Timing information

68

# - Input messages and output response

69

70

await cl.Message(response.choices[0].message.content).send()

71

72

@cl.on_message

73

async def streaming_openai_example(message: cl.Message):

74

"""Example with streaming responses"""

75

76

# Streaming calls are also automatically instrumented

77

stream = await openai_client.chat.completions.create(

78

model="gpt-4",

79

messages=[{"role": "user", "content": message.content}],

80

stream=True,

81

temperature=0.8

82

)

83

84

# Stream response to UI

85

msg = cl.Message("")

86

await msg.send()

87

88

async for chunk in stream:

89

if chunk.choices[0].delta.content:

90

await msg.stream_token(chunk.choices[0].delta.content)

91

92

# Step automatically tracks full conversation and final token counts

93

94

@cl.on_message

95

async def function_calling_example(message: cl.Message):

96

"""Example with OpenAI function calling"""

97

98

# Function definitions

99

functions = [

100

{

101

"name": "get_weather",

102

"description": "Get current weather information",

103

"parameters": {

104

"type": "object",

105

"properties": {

106

"location": {"type": "string", "description": "City name"}

107

},

108

"required": ["location"]

109

}

110

}

111

]

112

113

# Function call - automatically tracked

114

response = await openai_client.chat.completions.create(

115

model="gpt-3.5-turbo",

116

messages=[{"role": "user", "content": message.content}],

117

functions=functions,

118

function_call="auto"

119

)

120

121

# Handle function call if requested

122

if response.choices[0].message.function_call:

123

function_name = response.choices[0].message.function_call.name

124

# Function execution is tracked in the same step

125

126

# Execute function (example)

127

if function_name == "get_weather":

128

result = "Sunny, 72°F"

129

130

# Send function result back to OpenAI

131

final_response = await openai_client.chat.completions.create(

132

model="gpt-3.5-turbo",

133

messages=[

134

{"role": "user", "content": message.content},

135

response.choices[0].message,

136

{"role": "function", "name": function_name, "content": result}

137

]

138

)

139

140

await cl.Message(final_response.choices[0].message.content).send()

141

else:

142

await cl.Message(response.choices[0].message.content).send()

143

```

144

145

### LangChain Integration

146

147

Comprehensive LangChain integration with callback handlers for step tracking and component monitoring.

148

149

```python { .api }

150

class LangchainCallbackHandler:

151

"""

152

Callback handler for LangChain integration with automatic step tracking.

153

154

Requirements:

155

- langchain >= 0.0.198

156

157

Args:

158

answer_prefix_tokens: Optional[List[str]] - Tokens that mark final answer

159

stream_final_answer: bool - Whether to stream final responses (default: False)

160

to_ignore: List[str] - LangChain component names to ignore in tracking

161

to_keep: List[str] - Components to keep even if parent is ignored

162

163

Features:

164

- Automatic step creation for LangChain components (chains, agents, tools)

165

- LLM call tracking with generation metadata

166

- Token streaming support for real-time responses

167

- Tool execution and retrieval step monitoring

168

- Hierarchical step organization matching LangChain execution flow

169

170

Returns:

171

LangchainCallbackHandler instance for use with LangChain

172

"""

173

def __init__(

174

self,

175

answer_prefix_tokens: Optional[List[str]] = None,

176

stream_final_answer: bool = False,

177

to_ignore: List[str] = [],

178

to_keep: List[str] = []

179

): ...

180

181

# Async version for async LangChain components

182

AsyncLangchainCallbackHandler = LangchainCallbackHandler

183

```

184

185

Usage examples for LangChain integration:

186

187

```python

188

import chainlit as cl

189

from langchain.chains import LLMChain

190

from langchain.prompts import ChatPromptTemplate

191

from langchain.chat_models import ChatOpenAI

192

from langchain.agents import create_openai_functions_agent, AgentExecutor

193

from langchain.tools import Tool

194

195

@cl.on_message

196

async def langchain_basic_example(message: cl.Message):

197

"""Basic LangChain integration example"""

198

199

# Create LangChain callback handler

200

callback_handler = cl.AsyncLangchainCallbackHandler(

201

stream_final_answer=True,

202

answer_prefix_tokens=["Final", "Answer"]

203

)

204

205

# Create LangChain components

206

llm = ChatOpenAI(

207

model="gpt-3.5-turbo",

208

temperature=0.7,

209

streaming=True,

210

callbacks=[callback_handler]

211

)

212

213

prompt = ChatPromptTemplate.from_messages([

214

("system", "You are a helpful assistant."),

215

("human", "{input}")

216

])

217

218

# Create and run chain - automatically creates steps

219

chain = prompt | llm

220

221

response = await chain.ainvoke(

222

{"input": message.content},

223

config={"callbacks": [callback_handler]}

224

)

225

226

# Response is automatically streamed to UI via callback handler

227

# Steps show: Chain execution -> LLM call -> Response streaming

228

229

@cl.on_message

230

async def langchain_agent_example(message: cl.Message):

231

"""LangChain agent with tools example"""

232

233

callback_handler = cl.AsyncLangchainCallbackHandler(

234

stream_final_answer=True

235

)

236

237

# Define tools

238

def calculate(expression: str) -> str:

239

"""Calculate mathematical expressions."""

240

try:

241

result = eval(expression) # Note: Use safe eval in production

242

return str(result)

243

except Exception as e:

244

return f"Error: {str(e)}"

245

246

def search_web(query: str) -> str:

247

"""Search the web for information."""

248

# Mock implementation

249

return f"Search results for: {query}"

250

251

tools = [

252

Tool(

253

name="Calculator",

254

func=calculate,

255

description="Calculate mathematical expressions"

256

),

257

Tool(

258

name="WebSearch",

259

func=search_web,

260

description="Search the web for current information"

261

)

262

]

263

264

# Create agent

265

llm = ChatOpenAI(

266

model="gpt-3.5-turbo",

267

temperature=0,

268

callbacks=[callback_handler]

269

)

270

271

agent = create_openai_functions_agent(llm, tools,

272

ChatPromptTemplate.from_messages([

273

("system", "You are a helpful assistant with access to tools."),

274

("human", "{input}"),

275

("placeholder", "{agent_scratchpad}")

276

])

277

)

278

279

agent_executor = AgentExecutor(

280

agent=agent,

281

tools=tools,

282

callbacks=[callback_handler],

283

verbose=True

284

)

285

286

# Execute agent - creates hierarchical steps:

287

# Agent Execution -> Tool Selection -> Tool Execution -> LLM Response

288

response = await agent_executor.ainvoke(

289

{"input": message.content},

290

config={"callbacks": [callback_handler]}

291

)

292

293

await cl.Message(response["output"]).send()

294

295

@cl.on_message

296

async def langchain_rag_example(message: cl.Message):

297

"""LangChain RAG (Retrieval Augmented Generation) example"""

298

299

callback_handler = cl.AsyncLangchainCallbackHandler(

300

stream_final_answer=True,

301

to_ignore=["VectorStoreRetriever"], # Ignore noisy retriever logs

302

to_keep=["RetrievalQA"] # But keep the main QA chain

303

)

304

305

# Mock retrieval setup (replace with real vector store)

306

from langchain.vectorstores import FAISS

307

from langchain.embeddings import OpenAIEmbeddings

308

from langchain.chains import RetrievalQA

309

310

# Create mock vector store

311

embeddings = OpenAIEmbeddings(callbacks=[callback_handler])

312

313

# Mock documents (replace with real document loading)

314

docs = ["Document content 1", "Document content 2"]

315

vectorstore = FAISS.from_texts(docs, embeddings)

316

317

# Create RAG chain

318

llm = ChatOpenAI(

319

model="gpt-3.5-turbo",

320

callbacks=[callback_handler]

321

)

322

323

qa_chain = RetrievalQA.from_chain_type(

324

llm=llm,

325

chain_type="stuff",

326

retriever=vectorstore.as_retriever(),

327

callbacks=[callback_handler]

328

)

329

330

# Execute RAG - creates steps for:

331

# Question Processing -> Document Retrieval -> Context Assembly -> LLM Generation

332

response = await qa_chain.ainvoke(

333

{"query": message.content},

334

config={"callbacks": [callback_handler]}

335

)

336

337

await cl.Message(response["result"]).send()

338

```

339

340

### LlamaIndex Integration

341

342

LlamaIndex integration with callback handlers for query engines, retrievers, and index operations.

343

344

```python { .api }

345

class LlamaIndexCallbackHandler:

346

"""

347

Callback handler for LlamaIndex integration with step tracking.

348

349

Args:

350

event_starts_to_ignore: List[CBEventType] - Event types to ignore at start

351

event_ends_to_ignore: List[CBEventType] - Event types to ignore at end

352

353

Features:

354

- Automatic step creation for LlamaIndex operations

355

- Query engine and retriever monitoring

356

- LLM call tracking with generation data

357

- Retrieval and embedding step tracking

358

- Source document display and citations

359

- Index construction and update monitoring

360

361

Returns:

362

LlamaIndexCallbackHandler instance for use with LlamaIndex

363

"""

364

def __init__(

365

self,

366

event_starts_to_ignore: List = [],

367

event_ends_to_ignore: List = []

368

): ...

369

```

370

371

Usage examples for LlamaIndex integration:

372

373

```python

374

import chainlit as cl

375

from llama_index import VectorStoreIndex, SimpleDirectoryReader, ServiceContext

376

from llama_index.llms import OpenAI

377

from llama_index.callbacks import CallbackManager

378

379

@cl.on_chat_start

380

async def setup_llamaindex():

381

"""Initialize LlamaIndex with Chainlit integration"""

382

383

# Create callback handler

384

callback_handler = cl.LlamaIndexCallbackHandler()

385

callback_manager = CallbackManager([callback_handler])

386

387

# Setup LlamaIndex components

388

llm = OpenAI(

389

model="gpt-3.5-turbo",

390

temperature=0.7

391

)

392

393

service_context = ServiceContext.from_defaults(

394

llm=llm,

395

callback_manager=callback_manager

396

)

397

398

# Load documents (creates steps for document processing)

399

documents = SimpleDirectoryReader("./docs").load_data()

400

401

# Create index (creates steps for embedding and indexing)

402

index = VectorStoreIndex.from_documents(

403

documents,

404

service_context=service_context

405

)

406

407

# Store in session

408

cl.user_session.set("index", index)

409

cl.user_session.set("service_context", service_context)

410

411

await cl.Message("Knowledge base initialized! Ask me anything about the documents.").send()

412

413

@cl.on_message

414

async def llamaindex_query(message: cl.Message):

415

"""Query LlamaIndex with automatic step tracking"""

416

417

index = cl.user_session.get("index")

418

service_context = cl.user_session.get("service_context")

419

420

if not index:

421

await cl.Message("Please wait for the knowledge base to initialize.").send()

422

return

423

424

# Create query engine - automatically tracked

425

query_engine = index.as_query_engine(

426

service_context=service_context,

427

similarity_top_k=3,

428

response_mode="compact"

429

)

430

431

# Execute query - creates hierarchical steps:

432

# Query Processing -> Document Retrieval -> Context Ranking -> LLM Generation

433

response = await query_engine.aquery(message.content)

434

435

# Send response with source citations

436

response_text = str(response)

437

438

# Extract and display source documents

439

source_nodes = response.source_nodes

440

if source_nodes:

441

sources_text = "\n\n**Sources:**\n"

442

for i, node in enumerate(source_nodes, 1):

443

source_text = node.text[:200] + "..." if len(node.text) > 200 else node.text

444

sources_text += f"{i}. {source_text}\n"

445

446

response_text += sources_text

447

448

await cl.Message(response_text).send()

449

450

@cl.on_message

451

async def llamaindex_chat_engine(message: cl.Message):

452

"""Use LlamaIndex chat engine for conversational queries"""

453

454

index = cl.user_session.get("index")

455

456

# Get or create chat engine

457

chat_engine = cl.user_session.get("chat_engine")

458

if not chat_engine:

459

chat_engine = index.as_chat_engine(

460

chat_mode="condense_question",

461

verbose=True

462

)

463

cl.user_session.set("chat_engine", chat_engine)

464

465

# Chat with context awareness - automatically creates steps

466

response = await chat_engine.achat(message.content)

467

468

await cl.Message(str(response)).send()

469

```

470

471

### Mistral AI Integration

472

473

Automatic instrumentation for Mistral AI SDK with step tracking and model monitoring.

474

475

```python { .api }

476

def instrument_mistralai() -> None:

477

"""

478

Instrument Mistral AI SDK for automatic step tracking and observability.

479

Similar to OpenAI instrumentation but for Mistral AI models.

480

481

Requirements:

482

- mistralai SDK

483

484

Features:

485

- Automatic step creation for Mistral AI API calls

486

- Model performance and token usage monitoring

487

- Support for Mistral's chat and completion endpoints

488

- Error tracking and retry monitoring

489

490

Usage:

491

Call once at startup, then use Mistral AI SDK normally.

492

All API calls automatically appear as steps in Chainlit UI.

493

494

Returns:

495

None

496

"""

497

```

498

499

Usage example for Mistral AI integration:

500

501

```python

502

import chainlit as cl

503

from mistralai.client import MistralClient

504

from mistralai.models.chat_completion import ChatMessage

505

506

# Initialize Mistral AI instrumentation

507

cl.instrument_mistralai()

508

509

# Initialize Mistral client

510

mistral_client = MistralClient(api_key="your-mistral-api-key")

511

512

@cl.on_message

513

async def chat_with_mistral(message: cl.Message):

514

"""Chat with Mistral AI using automatic step tracking"""

515

516

# This call will automatically create a step in the UI

517

response = mistral_client.chat(

518

model="mistral-large-latest",

519

messages=[

520

ChatMessage(role="system", content="You are a helpful assistant."),

521

ChatMessage(role="user", content=message.content)

522

],

523

temperature=0.7,

524

max_tokens=150

525

)

526

527

# Automatically tracked with model info, timing, and token usage

528

await cl.Message(response.choices[0].message.content).send()

529

```

530

531

### Generic Integration Patterns

532

533

Common patterns for integrating other AI/ML libraries with Chainlit observability.

534

535

```python { .api }

536

# Manual step creation for custom integrations

537

async def integrate_custom_ai_library(input_data: str) -> str:

538

"""Example of manual step tracking for custom AI libraries"""

539

540

async with cl.Step(name="Custom AI Processing", type="llm") as step:

541

step.input = {"prompt": input_data, "model": "custom-model"}

542

543

# Call your custom AI library

544

result = await your_ai_library.process(input_data)

545

546

step.output = {"response": result, "tokens_used": 150}

547

548

return result

549

550

# Step decorator for function-level tracking

551

@cl.step(name="Document Processing", type="tool")

552

async def process_document(file_path: str) -> dict:

553

"""Process document with automatic step tracking"""

554

# Function execution is automatically wrapped in a step

555

556

# Your processing logic here

557

content = await extract_text(file_path)

558

analysis = await analyze_content(content)

559

560

return {

561

"content_length": len(content),

562

"analysis": analysis

563

}

564

```

565

566

## Integration Usage Patterns

567

568

### Multi-Framework Integration

569

570

Using multiple AI frameworks together with unified observability:

571

572

```python

573

import chainlit as cl

574

575

# Initialize all integrations

576

cl.instrument_openai()

577

cl.instrument_mistralai()

578

579

@cl.on_message

580

async def multi_framework_example(message: cl.Message):

581

"""Example using multiple AI frameworks with unified tracking"""

582

583

# LangChain for complex reasoning

584

langchain_handler = cl.AsyncLangchainCallbackHandler()

585

586

# OpenAI for quick responses (automatically tracked)

587

quick_response = await openai_client.chat.completions.create(

588

model="gpt-3.5-turbo",

589

messages=[{"role": "user", "content": f"Summarize: {message.content}"}],

590

max_tokens=50

591

)

592

593

# LlamaIndex for document queries (with callback handler)

594

index = cl.user_session.get("index")

595

if index:

596

llamaindex_handler = cl.LlamaIndexCallbackHandler()

597

query_engine = index.as_query_engine(

598

callback_manager=CallbackManager([llamaindex_handler])

599

)

600

doc_response = await query_engine.aquery(message.content)

601

602

# Mistral AI for creative tasks (automatically tracked)

603

creative_response = await mistral_client.chat(

604

model="mistral-large-latest",

605

messages=[{"role": "user", "content": f"Create a creative response to: {message.content}"}]

606

)

607

608

# All calls automatically appear as separate steps with proper attribution

609

final_response = f"""

610

**Quick Summary:** {quick_response.choices[0].message.content}

611

612

**Document Context:** {str(doc_response) if 'doc_response' in locals() else 'No documents loaded'}

613

614

**Creative Take:** {creative_response.choices[0].message.content}

615

"""

616

617

await cl.Message(final_response).send()

618

```

619

620

## Core Types

621

622

```python { .api }

623

from typing import List, Optional, Any, Dict

624

from enum import Enum

625

626

# LangChain integration types

627

LangchainComponent = str # Component name for filtering

628

629

# LlamaIndex integration types

630

class CBEventType(Enum):

631

"""LlamaIndex callback event types"""

632

CHUNKING = "chunking"

633

NODE_PARSING = "node_parsing"

634

EMBEDDING = "embedding"

635

LLM = "llm"

636

QUERY = "query"

637

RETRIEVE = "retrieve"

638

SYNTHESIZE = "synthesize"

639

640

# Generic integration types

641

ModelMetadata = Dict[str, Any] # Model configuration and metadata

642

TokenUsage = Dict[str, int] # Token usage statistics

643

GenerationInfo = Dict[str, Any] # Generation metadata and settings

644

```