### Installing Dependencies and Running LangDiff Examples with ts-node Source: https://github.com/globalaiplatform/langdiff/blob/main/ts/README.md These commands demonstrate how to install project dependencies and execute specific LangDiff examples using ts-node. This is useful for testing individual features or running the full article generation demo. ```bash # Install dependencies npm install # Run a specific example npx ts-node examples/01-basic-streaming.ts # Or with the full article demo npx ts-node examples/05-article-generation.ts ``` -------------------------------- ### Running LangDiff Examples with npm Source: https://github.com/globalaiplatform/langdiff/blob/main/ts/README.md This section provides commands to run all LangDiff examples or individual examples using npm scripts. It covers basic streaming, change tracking, OpenAI integration, frontend integration, and a comprehensive article generation demo. ```bash # Run all examples npm run examples # Or run individual examples npm run examples:basic # Basic streaming parser npm run examples:tracking # Change tracking npm run examples:openai # OpenAI integration npm run examples:frontend # Frontend integration npm run examples:article # Article generation (comprehensive) ``` -------------------------------- ### Quick Start Example (Python) Source: https://github.com/globalaiplatform/langdiff/blob/main/py/docs/index.md A concise example demonstrating how to define a structured response schema using LangDiff's `Object`, `String`, and `List` types, set up streaming callbacks, and stream data from OpenAI's chat completions API with structured response formatting. ```python import langdiff as ld import openai # Define a structured response schema using LangDiff models class ArticleResponse(ld.Object): title: ld.String sections: ld.List[ld.String] # Initialize the response object response = ArticleResponse() # Set up callbacks for title appending @response.title.on_append def on_title_chunk(chunk: str): print(f"Title: {chunk}", end="", flush=True) # Set up callbacks for section appending @response.sections.on_append def on_section_append(section: ld.String, index: int): print(f"\n\nSection {index + 1}:") # Set up callbacks for chunks within a section @section.on_append def on_section_chunk(chunk: str): print(chunk, end="", flush=True) # Initialize OpenAI client and stream chat completions client = openai.OpenAI() with client.chat.completions.stream( model="gpt-5-mini", messages=[{"role": "user", "content": "Write a short article about Python"}], response_format=ArticleResponse.to_pydantic(), # Use LangDiff schema for response format ) as stream: # Use LangDiff Parser to process the streamed events with ld.Parser(response) as parser: for event in stream: if event.type == "content.delta": parser.push(event.delta) # Push delta to the parser ``` -------------------------------- ### Example Python Script for LangDiff Demo Source: https://github.com/globalaiplatform/langdiff/blob/main/README.md This Python script demonstrates an end-to-end example of using LangDiff, showcasing both streaming parsing and diff tracking functionalities. It serves as a practical guide for implementing LangDiff in applications. ```python # This is a placeholder for the actual code from py/example.py # The actual code would demonstrate LangDiff's streaming parsing and diff tracking. # Example of schema evolution: # Original Schema: # {"summary": ["Food is great", "Nice interior"]} # New Schema with emoji support: # {"summaryV2": [{"emoji": "🍽️", "text": "Food is great"}]} # LangDiff's approach would involve defining schemas that understand streaming # and providing type-safe callbacks for partial updates. # Change-based synchronization would track mutations and send JSON Patch diffs. print("LangDiff demo script placeholder.") print("Refer to the actual py/example.py for implementation details.") ``` -------------------------------- ### Installation (Bash) Source: https://github.com/globalaiplatform/langdiff/blob/main/py/docs/index.md Provides commands for installing the LangDiff library using package managers `uv` and `pip`. ```bash uv add langdiff ``` ```bash pip install langdiff ``` -------------------------------- ### Run Main Demo Example Source: https://github.com/globalaiplatform/langdiff/blob/main/CLAUDE.md Executes the primary example script (`example.py`) for the LangDiff library. This is useful for demonstrating the library's core functionality and for quick testing. ```bash uv run python example.py # Run the main demo example ``` -------------------------------- ### Installation using npm Source: https://github.com/globalaiplatform/langdiff/blob/main/ts/README.md Provides the command to install the LangDiff library using npm, a package manager for Node.js. ```bash npm install @langdiff/langdiff ``` -------------------------------- ### Install Documentation Dependencies Source: https://github.com/globalaiplatform/langdiff/blob/main/CLAUDE.md Installs the necessary dependencies for building and serving the project's documentation using `mkdocs`. This command ensures that all documentation-related tools are available. ```bash uv sync --group docs # Install documentation dependencies ``` -------------------------------- ### Install LangDiff Library Source: https://context7.com/globalaiplatform/langdiff/llms.txt Installs the LangDiff library for Python or TypeScript. For Python, use pip. For TypeScript, use npm. ```bash pip install langdiff ``` ```bash npm install @langdiff/langdiff ``` -------------------------------- ### Serve Documentation Locally Source: https://github.com/globalaiplatform/langdiff/blob/main/CLAUDE.md Starts a local development server for the project's documentation using `mkdocs`. This allows developers to preview documentation changes in real-time at `http://127.0.0.1:8000`. ```bash uv run mkdocs serve # Start development server at http://127.0.0.1:8000 ``` -------------------------------- ### Installation using yarn Source: https://github.com/globalaiplatform/langdiff/blob/main/ts/README.md Provides the command to install the LangDiff library using yarn, an alternative package manager for Node.js. ```bash yarn add @langdiff/langdiff ``` -------------------------------- ### Install LangDiff Package Source: https://github.com/globalaiplatform/langdiff/blob/main/ts/docs/index.md Provides instructions for installing the LangDiff library using both npm and yarn package managers. This is the first step to using LangDiff in a project. ```bash npm install langdiff ``` ```bash yarn add langdiff ``` -------------------------------- ### Install Development Dependencies with uv Source: https://github.com/globalaiplatform/langdiff/blob/main/CLAUDE.md Installs all project dependencies, including those required for development, using the `uv` package manager. This command ensures that all necessary tools and libraries are available for local development and testing. ```bash uv sync --dev # Install dependencies including dev group ``` -------------------------------- ### Streaming Parsing Comparison (Python) Source: https://github.com/globalaiplatform/langdiff/blob/main/README.md Compares the process of streaming structured output parsing with and without LangDiff. The 'Without LangDiff' example shows raw token parsing, while the 'With LangDiff' example demonstrates granular, type-safe callbacks provided by the library. ```python parse_partial('{"it') parse_partial('{"items":') parse_partial('{"items": ["Buy a b') parse_partial('{"items": ["Buy a banana", "') parse_partial('{"items": ["Buy a banana", "Pack b') parse_partial('{"items": ["Buy a banana", "Pack bags"]}') ``` ```python on_item_list_append("", index=0) on_item_append("Buy a b") on_item_append("anana") on_item_list_append("", index=1) on_item_append("Pack b") on_item_append("ags") ``` -------------------------------- ### Basic Streaming Example Source: https://github.com/globalaiplatform/langdiff/blob/main/ts/docs/api/overview.md Demonstrates how to define a streaming schema using the functional API, set up event callbacks, and parse a stream of chunks using the `Parser` class. ```APIDOC ## Basic Streaming ### Description This example shows how to define a schema for a streaming JSON object, attach callbacks to its fields, and then parse incoming data chunks. ### Method N/A (Client-side code example) ### Endpoint N/A (Client-side code example) ### Request Example ```typescript import * as ld from '@langdiff/langdiff'; // Define schema using the modern functional API const Response = ld.object({ title: ld.string(), items: ld.array(ld.string()) }); // Set up callbacks const response = Response.create(); response.title.onAppend((chunk: string) => { console.log(`Title: ${chunk}`); }); // Assume streamChunks is an iterable of string chunks // const streamChunks = ...; // Parse stream const parser = new ld.Parser(response); // for (const chunk of streamChunks) { // parser.push(chunk); // } // parser.complete(); ``` ### Response N/A (This is a client-side usage example) ``` -------------------------------- ### Change Tracking Example Source: https://github.com/globalaiplatform/langdiff/blob/main/ts/docs/api/overview.md Illustrates how to use the `trackChange` utility function to automatically track modifications to an object and retrieve the generated JSON Patch operations. ```APIDOC ## Change Tracking ### Description This example demonstrates how to wrap an object with `trackChange` to automatically generate JSON Patch operations as the object is modified. ### Method N/A (Client-side code example) ### Endpoint N/A (Client-side code example) ### Request Example ```typescript import { trackChange } from '@langdiff/langdiff'; interface UI { items: string[]; } // Track changes to any object const [obj, diffBuf] = trackChange({ items: [] }); // Make modifications obj.items.push("new item"); // Get JSON Patch operations const changes = diffBuf.flush(); console.log(changes); ``` ### Response N/A (This is a client-side usage example) ``` -------------------------------- ### Streaming Parsing Example (TypeScript) Source: https://github.com/globalaiplatform/langdiff/blob/main/ts/README.md Demonstrates how LangDiff processes partial JSON strings token by token, providing granular callbacks for building structured outputs. This contrasts with traditional parsing methods that wait for complete data. ```typescript parsePartial('{"it') parsePartial('{"items":') parsePartial('{"items": ["Buy a b') parsePartial('{"items": ["Buy a banana", "') parsePartial('{"items": ["Buy a banana", "Pack b') parsePartial('{"items": ["Buy a banana", "Pack bags"]}') ``` ```typescript onItemListAppend("", index=0) onItemAppend("Buy a b") onItemAppend("anana") onItemListAppend("", index=1) onItemAppend("Pack b") onItemAppend("ags") ``` -------------------------------- ### Streaming Parsing Callbacks (Python) Source: https://github.com/globalaiplatform/langdiff/blob/main/py/docs/index.md Demonstrates how to use `on_append` callbacks to process incoming text chunks as they are streamed, updating UI elements in real-time. This example shows how to remove HTML tags from appended chunks and display them. ```python import langdiff as ld # Assume 'response' and 'ui' are defined elsewhere # For example: # class MockResponse: # text = ld.String() # response = MockResponse() # class MockUI: # body = [] # ui = MockUI() @response.text.on_append def on_text_append(chunk: str, index: int): # Example: remove tags and update UI # In a real scenario, ui.body would be managed appropriately if ui.body and isinstance(ui.body[-1], str) and ui.body[-1].endswith(''): ui.body[-1] = ui.body[-1][5:-6] # remove tags ui.body.append(f"{chunk}") # Example of generated JSON Patch diffs: # {"op": "add", "path": "/body", "value": "Hell"} # {"op": "replace", "path": "/body/0", "value": "Hell"} # {"op": "add", "path": "/body", "value": "o, world!"} ``` -------------------------------- ### Langdiff JSON Patch Operations Example (TypeScript) Source: https://github.com/globalaiplatform/langdiff/blob/main/ts/docs/api/tracker.md Provides an example of using Langdiff's supported JSON Patch operations, including standard operations like 'add', 'remove', 'replace', and a custom 'append' operation for efficient string concatenation. This snippet illustrates how to construct an array of patch operations. ```typescript const operations = [ { op: "add", path: "/items/-", value: "new item" }, { op: "replace", path: "/status", value: "active" }, { op: "remove", path: "/temp" }, { op: "append", path: "/message", value: " (updated)" } ]; ``` -------------------------------- ### Basic Streaming with LangDiff TypeScript Source: https://github.com/globalaiplatform/langdiff/blob/main/ts/examples/README.md Demonstrates fundamental streaming parser capabilities using LangDiff's `StreamingObject`, `StreamingString`, and `Parser`. It shows how to create streaming objects, set up event handlers for appending data, and progressively parse JSON. This is useful for handling real-time data streams where the full data is not available at once. ```typescript import { StreamingObject, StreamingString, Parser } from '@langdiff/langdiff'; class MyResponse extends StreamingObject { message!: StreamingString; protected _initializeFields(): void { this.addField('message', new StreamingString()); } } const response = new MyResponse(); response.message.onAppend(chunk => console.log(chunk)); const parser = new Parser(response); parser.push('{\"message\": \"Hello, '); parser.push('world!\"}'); parser.complete(); ``` -------------------------------- ### Quick Start: Streaming Article from OpenAI with LangDiff in TypeScript Source: https://github.com/globalaiplatform/langdiff/blob/main/ts/docs/index.md Illustrates a basic usage of LangDiff to stream a structured article response from OpenAI. It defines a class-based schema (`ArticleResponse`), sets up streaming callbacks for title and sections, and integrates with the OpenAI SDK to parse and process the streamed content. ```typescript import * as ld from '@langdiff/langdiff'; import OpenAI from 'openai'; class ArticleResponse extends ld.Object { title!: ld.String; sections!: ld.List; protected _initializeFields(): void { this.addField('title', new ld.String()); this.addField('sections', new ld.List(ld.String)); } } // Set up streaming callbacks const response = new ArticleResponse(); response.title.onAppend((chunk: string) => { process.stdout.write(`Title: ${chunk}`); }); response.sections.onAppend((section: ld.String, index: number) => { console.log(`\n\nSection ${index + 1}:`); section.onAppend((chunk: string) => { process.stdout.write(chunk); }); }); // Stream from OpenAI const client = new OpenAI(); const stream = await client.chat.completions.create({ model: "gpt-4o-mini", messages: [{ role: "user", content: "Write a short article about TypeScript" }], response_format: { type: "json_object" }, stream: true }); const parser = new ld.Parser(response); for await (const chunk of stream) { const content = chunk.choices[0]?.delta?.content; if (content) { parser.push(content); } } parser.complete(); ``` -------------------------------- ### Initialize Parser with Schema - TypeScript Source: https://github.com/globalaiplatform/langdiff/blob/main/ts/docs/api/parser.md Provides an example of initializing the Langdiff Parser with a streaming schema. The parser is responsible for processing JSON tokens and incrementally updating the streaming objects based on the provided schema. Requires '@langdiff/langdiff'. ```typescript import * as ld from '@langdiff/langdiff'; const schema = ld.object({ title: ld.string() }); const instance = schema.create(); const parser = new ld.Parser(instance); ``` -------------------------------- ### Change Tracking and Patch Generation with LangDiff TypeScript Source: https://github.com/globalaiplatform/langdiff/blob/main/ts/examples/README.md Illustrates how to track object mutations and generate JSON Patch operations using LangDiff's `trackChange` and `applyChange` functions. It shows how to monitor changes to a state object and then flush these changes into a diff format, which can be applied to other objects. This is essential for managing state synchronization and applying updates efficiently. ```typescript import { trackChange, applyChange } from '@langdiff/langdiff'; const [state, diffBuffer] = trackChange({ items: [] }); state.items.push('new item'); const changes = diffBuffer.flush(); // changes: [{ op: 'add', path: '/items/-', value: 'new item' }] // Apply to another object const remoteState = { items: [] }; applyChange(remoteState, changes); ``` -------------------------------- ### Server-Sent Events (SSE) Integration Pattern TypeScript Source: https://github.com/globalaiplatform/langdiff/blob/main/ts/examples/README.md Demonstrates the pattern for integrating LangDiff with Server-Sent Events (SSE) for real-time communication between server and client. The server tracks changes and streams them as SSE events, while the client listens to these events and applies the changes to its local state using `applyChange`. This is ideal for updating frontend applications in real-time. ```typescript // Server side const [state, diffBuffer] = trackChange(initialState); response.message.onAppend(() => { const changes = diffBuffer.flush(); res.write(`data: ${JSON.stringify({ changes })}\n\n`); }); // Client side const eventSource = new EventSource('/api/stream'); eventSource.onmessage = (event) => { const { changes } = JSON.parse(event.data); applyChange(clientState, changes); }; ``` -------------------------------- ### Stream Article Generation with LangDiff and OpenAI (Python) Source: https://context7.com/globalaiplatform/langdiff/llms.txt An example of a server-side function that streams article generation using OpenAI and LangDiff. It defines Pydantic models for the LLM response and UI state, attaches callbacks to handle streamed content, and yields JSON Patch changes. ```python import langdiff as ld import openai from pydantic import BaseModel # UI state model class Section(BaseModel): title: str content: str done: bool class Article(BaseModel): sections: list[Section] # LLM response schema class ArticleGenerationResponse(ld.Object): section_titles: ld.List[ld.String] section_contents: ld.List[ld.String] def stream_article(prompt: str): """Server-side: stream article generation with change tracking.""" ui, diff_buf = ld.track_change(Article(sections=[])) response = ArticleGenerationResponse() @response.section_titles.on_append def on_title(title: ld.String, index: int): ui.sections.append(Section(title="", content="", done=False)) @title.on_append def on_chunk(chunk: str): ui.sections[index].title += chunk @response.section_contents.on_append def on_content(content: ld.String, index: int): if index >= len(ui.sections): return @content.on_append def on_chunk(chunk: str): ui.sections[index].content += chunk @content.on_complete def on_done(_): ui.sections[index].done = True client = openai.OpenAI() with client.chat.completions.stream( model="gpt-4o", messages=[{"role": "user", "content": prompt}], response_format=ArticleGenerationResponse.to_pydantic(), ) as stream: with ld.Parser(response) as parser: for event in stream: if event.type == "content.delta": parser.push(event.delta) if changes := diff_buf.flush(): yield changes # Send to frontend via SSE/WebSocket if changes := diff_buf.flush(): yield changes ``` -------------------------------- ### Langdiff: String Append Optimization Example Source: https://github.com/globalaiplatform/langdiff/blob/main/ts/docs/api/tracker.md Illustrates the string append optimization feature of the `EfficientJSONPatchChangeTracker`. When simulating streaming text, consecutive appends to a string are detected and represented as 'append' operations instead of multiple 'replace' operations. ```typescript interface ChatMessage { content: string; timestamp: number; } const [message, diffBuf] = trackChange({ content: "", timestamp: Date.now() }); // Simulate streaming text - efficient append operations are detected message.content = "Hello"; message.content = "Hello world"; message.content = "Hello world! How are you?"; const changes = diffBuf.flush(); // [ // {"op": "replace", "path": "/content", "value": "Hello"}, // {"op": "append", "path": "/content", "value": " world"}, // {"op": "append", "path": "/content", "value": "! How are you?"} // ] ``` -------------------------------- ### Build Static Documentation Site Source: https://github.com/globalaiplatform/langdiff/blob/main/CLAUDE.md Generates the static HTML files for the project's documentation, outputting them to the `./site` directory. This command is used to create the final documentation site for deployment. ```bash uv run mkdocs build # Build static site to ./site directory ``` -------------------------------- ### Langdiff Event Handling: on_start() Source: https://github.com/globalaiplatform/langdiff/blob/main/py/docs/api/parser.md Demonstrates the usage of the `on_start()` event handler, which is called when streaming begins for a specific value within a langdiff type. ```python @response.title.on_start def on_title_start(): print("Title streaming started") ``` -------------------------------- ### Tracker Implementations Source: https://context7.com/globalaiplatform/langdiff/llms.txt Compares `JSONPatchChangeTracker` and `EfficientJSONPatchChangeTracker`, highlighting the default use of `append` for efficient string building. ```APIDOC ## JSONPatchChangeTracker vs EfficientJSONPatchChangeTracker ### Description Two tracker implementations: `JSONPatchChangeTracker` generates standard RFC 6902 JSON Patch operations. `EfficientJSONPatchChangeTracker` (default) adds an `append` operation for efficient string building during streaming. ### Method `track_change(data, tracker_cls=None)` (Python) ### Endpoint N/A (Library Function) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```python import langdiff as ld # Standard JSON Patch (RFC 6902 compliant) data = {"text": "Hello"} tracked, diff_buf = ld.track_change(data, tracker_cls=ld.JSONPatchChangeTracker) tracked["text"] = "Hello World" changes = diff_buf.flush() print(changes) # Output: [{"op": "add", "path": "/text", "value": "Hello World"}] # Efficient JSON Patch (default, with append) data2 = {"text": "Hello"} tracked2, diff_buf2 = ld.track_change(data2) # Uses EfficientJSONPatchChangeTracker tracked2["text"] = "Hello World" changes2 = diff_buf2.flush() print(changes2) # Output: [{"op": "append", "path": "/text", "value": " World"}] ``` ### Response #### Success Response (200) N/A (Library Function Return) #### Response Example N/A ``` -------------------------------- ### Parse Streaming JSON Chunks (TypeScript) Source: https://context7.com/globalaiplatform/langdiff/llms.txt Parses streaming JSON chunks incrementally using LangDiff's Parser in TypeScript. This example simulates receiving chunks of data for a shopping list and logs the received items, demonstrating the `push` and `complete` methods of the Parser. ```typescript import * as ld from '@langdiff/langdiff'; const ShoppingList = ld.object({ items: ld.array(ld.string()) }); const response = ShoppingList.create(); const itemsReceived: string[] = []; response.items.onAppend((item: ld.StreamingString, index: number) => { itemsReceived[index] = ''; item.onAppend((chunk: string) => { itemsReceived[index] += chunk; console.log(`Item ${index}: ${itemsReceived[index]}`); }); }); // Simulate streaming chunks const mockStreamData = [ '{"items": ["', 'Milk', '", "', 'Bread', '", "', 'Eggs', '"]}' ]; const parser = new ld.Parser(response); for (const chunk of mockStreamData) { parser.push(chunk); } parser.complete(); console.log(`Final items: ${JSON.stringify(itemsReceived)}`); // Output: Final items: ["Milk","Bread","Eggs"] ``` -------------------------------- ### Basic Streaming with LangDiff Parser Source: https://github.com/globalaiplatform/langdiff/blob/main/py/docs/api/overview.md Demonstrates how to use the LangDiff Parser module for streaming JSON data. It shows defining a schema with custom types, setting up event callbacks for streaming data, and processing tokens from a stream. ```python import langdiff as ld # Define schema class Response(ld.Object): title: ld.String items: ld.List[ld.String] # Set up callbacks response = Response() @response.title.on_append def on_title_chunk(chunk: str): print(f"Title: {chunk}") # Parse stream with ld.Parser(response) as parser: for token in stream: parser.push(token) ``` -------------------------------- ### Attach Event Handlers for Streaming Events (Python) Source: https://github.com/globalaiplatform/langdiff/blob/main/README.md Create an instance of your UI and the response model. Attach event handlers using decorators like `@response.section_titles.on_append` to respond to streaming events, updating the UI as data arrives. ```python ui = Article(sections=[]) response = ArticleGenerationResponse() @response.section_titles.on_append def on_section_title_append(title: ld.String, index: int): ui.sections.append(Section(title="", content="", done=False)) @title.on_append def on_title_append(chunk: str): ui.sections[index].title += chunk @response.section_contents.on_append def on_section_content_append(content: ld.String, index: int): if index >= len(ui.sections): return @content.on_append def on_content_append(chunk: str): ui.sections[index].content += chunk @content.on_complete def on_content_complete(_): ui.sections[index].done = True ``` -------------------------------- ### Parse Streaming JSON Chunks (Python) Source: https://context7.com/globalaiplatform/langdiff/llms.txt Uses LangDiff's Parser to incrementally process streaming JSON data and dispatch events to a schema object. This Python example demonstrates integrating with OpenAI's streaming API to parse a shopping list, with callbacks for appending item chunks. ```python import langdiff as ld import openai class ShoppingList(ld.Object): items: ld.List[ld.String] response = ShoppingList() items_received = [] @response.items.on_append def on_item(item: ld.String, index: int): items_received.append("") @item.on_append def on_chunk(chunk: str): items_received[index] += chunk print(f"Item {index}: {items_received[index]}") # Use with OpenAI streaming client = openai.OpenAI() with client.chat.completions.stream( model="gpt-4o", messages=[{"role": "user", "content": "List 3 grocery items"}], response_format=ShoppingList.to_pydantic(), ) as stream: with ld.Parser(response) as parser: for event in stream: if event.type == "content.delta": parser.push(event.delta) print(f"Final items: {items_received}") # Output: Final items: ['Milk', 'Bread', 'Eggs'] ``` -------------------------------- ### Run All Tests with pytest Source: https://github.com/globalaiplatform/langdiff/blob/main/CLAUDE.md Executes all tests defined within the project using the `pytest` framework. This is a fundamental command for verifying the integrity and correctness of the codebase. ```bash uv run pytest # Run all tests ``` -------------------------------- ### Streaming String Representation with Callbacks (Python) Source: https://context7.com/globalaiplatform/langdiff/llms.txt Demonstrates the use of ld.String for incrementally receiving string data. It utilizes 'on_start', 'on_append', and 'on_complete' callbacks to process string chunks as they arrive and handle the final complete string. ```python import langdiff as ld class Summary(ld.Object): text: ld.String response = Summary() full_text = "" @response.text.on_start def on_start(): print("Text streaming started") @response.text.on_append def on_chunk(chunk: str): global full_text full_text += chunk print(f"Received chunk: '{chunk}' (total: {len(full_text)} chars)") @response.text.on_complete def on_done(value: str): print(f"Text complete: '{value}'") # Simulate streaming with ld.Parser(response) as parser: parser.push('{"text": "Hello') # Output: Received chunk: 'Hello' (total: 5 chars) parser.push('{"text": "Hello, ') # Output: Received chunk: ', ' (total: 7 chars) parser.push('{"text": "Hello, World!"}') # Output: Received chunk: 'World!' (total: 13 chars) # Output: Text complete: 'Hello, World!' ``` -------------------------------- ### Basic Streaming Parsing with Langdiff Source: https://github.com/globalaiplatform/langdiff/blob/main/ts/docs/api/parser.md Demonstrates how to define a streaming schema for a shopping list and parse incoming JSON chunks. It includes callbacks for appending chunks to strings and completing string values. ```typescript import * as ld from '@langdiff/langdiff'; // Define schema const ShoppingList = ld.object({ items: ld.array(ld.string()), completed: ld.boolean() }); // Create instance and set up callbacks const list = ShoppingList.create(); list.items.onAppend((item: ld.StreamingString, index: number) => { console.log(`New item #${index} started`); item.onAppend((chunk: string) => { console.log(` Chunk: "${chunk}"`); }); item.onComplete((finalValue: string | null) => { console.log(` Completed: "${finalValue}"`); }); }); // Parse streaming data const parser = new ld.Parser(list); const chunks = ['{"items": ["Mi', 'lk', "Br', 'ead"], "completed": true}']; for (const chunk of chunks) { parser.push(chunk); } parser.complete(); ``` -------------------------------- ### Change Tracking and JSON Patch Generation (HTTP) Source: https://github.com/globalaiplatform/langdiff/blob/main/ts/README.md Illustrates how LangDiff tracks mutations in data streams and generates JSON Patch operations for efficient state synchronization. This is shown in contrast to raw data streams without LangDiff's change tracking. ```http data: {"it data: ems": data: ["Buy a b data: anana", " data: Pack b data: ags"]} ``` ```http data: {"op": "add", "path": "/items/-", "value": "Buy a b"} data: {"op": "append", "path": "/items/0", "value": "anana"} data: {"op": "add", "path": "/items/-", "value": "Pack b"} data: {"op": "append", "path": "/items/1", "value": "ags"} ``` -------------------------------- ### Change Tracking API: Object Mutations (Python) Source: https://context7.com/globalaiplatform/langdiff/llms.txt Explains how to use ld.track_change in Python to wrap objects and automatically capture mutations as JSON Patch operations. It shows how to append items to a list and flush changes. ```python import langdiff as ld from pydantic import BaseModel class Section(BaseModel): title: str content: str done: bool class Article(BaseModel): sections: list[Section] # Wrap object for tracking ui, diff_buf = ld.track_change(Article(sections=[])) # Mutations are automatically tracked ui.sections.append(Section(title="", content="", done=False)) changes = diff_buf.flush() print(changes) # Output: [{"op": "add", "path": "/sections/-", "value": {"title": "", "content": "", "done": false}}] # Update nested properties ui.sections[0].title = "Introduction" changes = diff_buf.flush() print(changes) # Output: [{"op": "add", "path": "/sections/0/title", "value": "Introduction"}] # Append to string (efficient diff) ui.sections[0].title = "Introduction to Python" changes = diff_buf.flush() print(changes) ``` -------------------------------- ### Basic Streaming with LangDiff Parser Source: https://github.com/globalaiplatform/langdiff/blob/main/ts/docs/api/overview.md Demonstrates how to define a streaming schema for a JSON object, set up callbacks for specific fields, and parse incoming stream chunks using the LangDiff Parser. This allows for real-time processing of structured data as it arrives. ```typescript import * as ld from '@langdiff/langdiff'; // Define schema using the modern functional API const Response = ld.object({ title: ld.string(), items: ld.array(ld.string()) }); // Set up callbacks const response = Response.create(); response.title.onAppend((chunk: string) => { console.log(`Title: ${chunk}`); }); // Parse stream const parser = new ld.Parser(response); for (const chunk of streamChunks) { parser.push(chunk); } parser.complete(); ``` -------------------------------- ### Run Tests with Verbose Output using pytest Source: https://github.com/globalaiplatform/langdiff/blob/main/CLAUDE.md Runs all project tests with verbose output enabled using `pytest`. Verbose output provides more detailed information about each test case, which can be helpful for understanding test execution flow and identifying failures. ```bash uv run pytest -v # Verbose output ``` -------------------------------- ### Restaurant Review Summarizer Schema Evolution (JSON) Source: https://github.com/globalaiplatform/langdiff/blob/main/py/README.md Demonstrates schema evolution for a restaurant review summarizer. The initial schema outputs a simple summary array, while an updated schema adds emoji support with a new 'summaryV2' field containing emoji and text objects. ```json {"summary": ["Food is great", "Nice interior"]} ``` ```json {"summaryV2": [{"emoji": "🍽️", "text": "Food is great"}]} ``` -------------------------------- ### Langdiff: Different Tracker Implementations Source: https://github.com/globalaiplatform/langdiff/blob/main/ts/docs/api/tracker.md Demonstrates how to use different change tracker implementations with the `trackChange` function. You can explicitly choose between the standard JSON Patch tracker and the efficient tracker. ```typescript import { trackChange, JSONPatchChangeTracker, EfficientJSONPatchChangeTracker } from '@langdiff/langdiff'; // Standard JSON Patch (RFC 6902 compliant) const [profile1, diffBuf1] = trackChange( { name: "", age: 0, hobbies: [] }, JSONPatchChangeTracker ); // Efficient tracker with append operations (default) const [profile2, diffBuf2] = trackChange( { name: "", age: 0, hobbies: [] }, EfficientJSONPatchChangeTracker // This is the default ); ``` -------------------------------- ### Streaming Parsing Callbacks in TypeScript Source: https://github.com/globalaiplatform/langdiff/blob/main/ts/docs/index.md Demonstrates how to use `onAppend` callbacks to process streaming text chunks, specifically for updating UI elements by removing HTML tags and adding new content. This is useful for real-time display of LLM-generated text. ```typescript response.text.onAppend((chunk: string) => { ui.body[ui.body.length - 1] = ui.body[ui.body.length - 1].slice(5, -6); // remove tags ui.body.push(`${chunk}`); }); // Tracked UI changes: // {"op": "add", "path": "/body/-", "value": "Hell"} // {"op": "replace", "path": "/body/0", "value": "Hell"} // {"op": "add", "path": "/body/-", "value": "o, world!"} ``` -------------------------------- ### Basic Object Streaming with Langdiff Source: https://github.com/globalaiplatform/langdiff/blob/main/py/docs/api/parser.md Demonstrates how to define a data structure using langdiff's Object, String, and List types, set up event handlers for data appending and completion, and parse a streaming JSON input. ```python import langdiff as ld class BlogPost(ld.Object): title: ld.String content: ld.String tags: ld.List[ld.String] post = BlogPost() # Set up event handlers @post.title.on_append def on_title_chunk(chunk: str): print(f"Title chunk: {chunk}") @post.tags.on_append def on_tag_append(tag: ld.String, index: int): @tag.on_complete def on_tag_complete(final_tag: str): print(f"New tag: {final_tag}") # Parse streaming JSON with ld.Parser(post) as parser: for token in json_stream: parser.push(token) ``` -------------------------------- ### Build Distribution Packages Source: https://github.com/globalaiplatform/langdiff/blob/main/CLAUDE.md Builds the wheel and source distribution packages for the LangDiff library. These packages are necessary for distributing the library to other users or for deployment. ```bash uv build # Build wheel and source distribution ``` -------------------------------- ### Streaming String: ld.String Source: https://context7.com/globalaiplatform/langdiff/llms.txt Represents a string value that streams incrementally. Provides callbacks for receiving chunks and completion. ```APIDOC ## Streaming String: ld.String ### Description Represents a string value that streams incrementally. Provides `on_append` callback for each new chunk and `on_complete` when the full string is received. Automatically detects continuation patterns to compute deltas. ### Method N/A (Class Definition) ### Endpoint N/A ### Parameters N/A ### Request Example ```python import langdiff as ld class Summary(ld.Object): text: ld.String response = Summary() full_text = "" @response.text.on_start def on_start(): print("Text streaming started") @response.text.on_append def on_chunk(chunk: str): global full_text full_text += chunk print(f"Received chunk: '{chunk}' (total: {len(full_text)} chars)") @response.text.on_complete def on_done(value: str): print(f"Text complete: '{value}'") # Simulate streaming with ld.Parser(response) as parser: parser.push('{"text": "Hello"}') # Output: Received chunk: 'Hello' (total: 5 chars) parser.push('{"text": "Hello, ') # Output: Received chunk: ', ' (total: 7 chars) parser.push('{"text": "Hello, World!"}') # Output: Received chunk: 'World!' (total: 13 chars) # Output: Text complete: 'Hello, World!' ``` ### Response N/A (Callbacks are triggered during parsing) ``` -------------------------------- ### Change Tracking API Source: https://context7.com/globalaiplatform/langdiff/llms.txt Wrap objects to automatically capture mutations as JSON Patch operations. ```APIDOC ## Change Tracking API ### ld.track_change (Python) / ld.trackChange (TypeScript) ### Description Wrap any object in a tracked proxy that automatically captures mutations as JSON Patch operations. Returns a tuple of the tracked object and a diff buffer. All changes to the object and its nested properties are recorded. ### Method N/A (Function Definition) ### Endpoint N/A ### Parameters N/A ### Request Example (Python) ```python import langdiff as ld from pydantic import BaseModel class Section(BaseModel): title: str content: str done: bool class Article(BaseModel): sections: list[Section] # Wrap object for tracking ui, diff_buf = ld.track_change(Article(sections=[])) # Mutations are automatically tracked ui.sections.append(Section(title="", content="", done=False)) changes = diff_buf.flush() print(changes) # Output: [{"op": "add", "path": "/sections/-", "value": {"title": "", "content": "", "done": false}}] # Update nested properties ui.sections[0].title = "Introduction" changes = diff_buf.flush() print(changes) # Output: [{"op": "add", "path": "/sections/0/title", "value": "Introduction"}] # Append to string (efficient diff) ui.sections[0].title = "Introduction to Python" changes = diff_buf.flush() print(changes) # Output: [{"op": "replace", "path": "/sections/0/title", "value": "Introduction to Python"}] ``` ### Response N/A (Returns tracked object and diff buffer) ``` -------------------------------- ### trackChange Usage (TypeScript) Source: https://context7.com/globalaiplatform/langdiff/llms.txt Demonstrates how to use the `trackChange` function in TypeScript to track changes in an object and retrieve them as JSON Patch operations. ```APIDOC ## trackChange Usage (TypeScript) ### Description Demonstrates how to use the `trackChange` function in TypeScript to track changes in an object and retrieve them as JSON Patch operations. ### Method `trackChange(initialState: T): [T, DiffBuffer]` ### Endpoint N/A (Library Function) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```typescript import { trackChange, Operation } from '@langdiff/langdiff'; interface TodoItem { id: number; text: string; completed: boolean; } interface TodoApp { todos: TodoItem[]; filter: string; } const initialState: TodoApp = { todos: [{ id: 1, text: 'Learn LangDiff', completed: false }], filter: 'all' }; const [state, diffBuffer] = trackChange(initialState); // Add new todo state.todos.push({ id: 2, text: 'Build app', completed: false }); let changes = diffBuffer.flush(); console.log(changes); // Output: [{"op":"add","path":"/todos/-","value":{"id":2,"text":"Build app","completed":false}}] // Update existing todo state.todos[0].completed = true; changes = diffBuffer.flush(); console.log(changes); // Output: [{"op":"replace","path":"/todos/0/completed","value":true}] // Efficient string append state.todos[1].text = 'Build app with LangDiff'; changes = diffBuffer.flush(); console.log(changes); // Output: [{"op":"append","path":"/todos/1/text","value":" with LangDiff"}] ``` ### Response #### Success Response (200) N/A (Library Function Return) #### Response Example N/A ``` -------------------------------- ### Stream LLM Response with LangDiff Parser (Python) Source: https://github.com/globalaiplatform/langdiff/blob/main/README.md Instantiate `langdiff.Parser` with your response model and feed token chunks from an LLM stream using the `push()` method. This allows for progressive parsing of structured data. ```python import openai import langdiff as ld client = openai.OpenAI() with client.chat.completions.stream( model="gpt-5-mini", messages=[{"role": "user", "content": "Write me a guide to open source a Python library."} ], response_format=ArticleGenerationResponse.to_pydantic(), ) as stream: with ld.Parser(response) as parser: for event in stream: if event.type == "content.delta": parser.push(event.delta) print(ui) print(ui) ``` -------------------------------- ### apply_change (Python) / applyChange (TypeScript) Source: https://context7.com/globalaiplatform/langdiff/llms.txt Details how to apply JSON Patch operations to an object using `apply_change` in Python and `applyChange` in TypeScript. ```APIDOC ## ld.apply_change (Python) / ld.applyChange (TypeScript) ### Description Apply a list of JSON Patch operations to a dictionary/object. Supports standard JSON Patch operations (add, remove, replace) plus the extended `append` operation for efficient string building. ### Method `ld.apply_change(target: dict, changes: list[dict])` (Python) `applyChange(target: object, changes: Operation[])` (TypeScript) ### Endpoint N/A (Library Function) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```python import langdiff as ld # Client-side state article = {"sections": []} # Receive changes from server (via SSE, WebSocket, etc.) changes_batch_1 = [ {"op": "add", "path": "/sections/-", "value": {"title": "", "content": "", "done": False}} ] ld.apply_change(article, changes_batch_1) print(article) # Output: {"sections": [{"title": "", "content": "", "done": false}]} changes_batch_2 = [ {"op": "append", "path": "/sections/0/title", "value": "Getting"}, {"op": "append", "path": "/sections/0/title", "value": " Started"} ] ld.apply_change(article, changes_batch_2) print(article) # Output: {"sections": [{"title": "Getting Started", "content": "", "done": false}]} changes_batch_3 = [ {"op": "add", "path": "/sections/0/done", "value": True} ] ld.apply_change(article, changes_batch_3) print(article) # Output: {"sections": [{"title": "Getting Started", "content": "", "done": true}]} ``` ```typescript import { applyChange, Operation } from '@langdiff/langdiff'; const article: any = { sections: [] }; const changes: Operation[] = [ { op: 'add', path: '/sections/-', value: { title: '', content: '' } }, { op: 'append', path: '/sections/0/title', value: 'Hello' }, { op: 'append', path: '/sections/0/title', value: ' World' } ]; applyChange(article, changes); console.log(article); // Output: { sections: [{ title: 'Hello World', content: '' }] } ``` ### Response #### Success Response (200) N/A (Library Function Return) #### Response Example N/A ``` -------------------------------- ### Track Changes and Flush in TypeScript Source: https://context7.com/globalaiplatform/langdiff/llms.txt Demonstrates how to use `trackChange` to monitor modifications to a TypeScript object and `diffBuffer.flush()` to retrieve the accumulated JSON Patch operations. This is useful for real-time updates and state synchronization. ```typescript import { trackChange, Operation } from '@langdiff/langdiff'; interface TodoItem { id: number; text: string; completed: boolean; } interface TodoApp { todos: TodoItem[]; filter: string; } const initialState: TodoApp = { todos: [{ id: 1, text: 'Learn LangDiff', completed: false }], filter: 'all' }; const [state, diffBuffer] = trackChange(initialState); // Add new todo state.todos.push({ id: 2, text: 'Build app', completed: false }); let changes = diffBuffer.flush(); console.log(changes); // Output: [{"op":"add","path":"/todos/-","value":{"id":2,"text":"Build app","completed":false}}] // Update existing todo state.todos[0].completed = true; changes = diffBuffer.flush(); console.log(changes); // Output: [{"op":"replace","path":"/todos/0/completed","value":true}] // Efficient string append state.todos[1].text = 'Build app with LangDiff'; changes = diffBuffer.flush(); console.log(changes); // Output: [{"op":"append","path":"/todos/1/text","value":" with LangDiff"}] ``` -------------------------------- ### Change Tracking with LangDiff Tracker Source: https://github.com/globalaiplatform/langdiff/blob/main/py/docs/api/overview.md Illustrates the usage of the LangDiff Tracker module for monitoring changes in an object and generating JSON Patch operations. It shows how to wrap an object for tracking and retrieve the generated diff. ```python # Track changes to any object obj, diff_buf = ld.track_change(UI(items=[])) # Make modifications obj.items.append("new item") # Get JSON Patch operations changes = diff_buf.flush() ``` -------------------------------- ### OpenAI Integration with Langdiff for Structured Output Source: https://github.com/globalaiplatform/langdiff/blob/main/py/docs/api/parser.md Shows how to convert a langdiff Object definition to a Pydantic model for use with the OpenAI SDK and parse the streaming response using the langdiff Parser. ```python import openai # Convert to Pydantic for OpenAI SDK response_format = BlogPost.to_pydantic() client = openai.OpenAI() with client.chat.completions.stream( model="gpt-5-mini", messages=[{"role": "user", "content": "Write a blog post"}], response_format=response_format, ) as stream: post = BlogPost() with ld.Parser(post) as parser: for event in stream: if event.type == "content.delta": parser.push(event.delta) ``` -------------------------------- ### Change Tracking Comparison (JSON Patch) Source: https://github.com/globalaiplatform/langdiff/blob/main/py/README.md Illustrates the difference in streaming data representation between raw JSON chunks and structured JSON Patch operations generated by LangDiff. LangDiff uses JSON Patch for efficient state synchronization. ```json data: {"it" data: ems": data: ["Buy a b" data: anana", " data: Pack b" data: ags"]} ``` ```json data: {"op": "add", "path": "/items/-", "value": "Buy a b"} data: {"op": "append", "path": "/items/0", "value": "anana"} data: {"op": "add", "path": "/items/-", "value": "Pack b"} data: {"op": "append", "path": "/items/1", "value": "ags"} ```