From bc68e7ecc89bd203dbad97aba445d7d57013e4cf Mon Sep 17 00:00:00 2001 From: Jonathan Rhyne Date: Thu, 5 Mar 2026 00:53:26 -0500 Subject: [PATCH 1/2] Add framework integration quickstarts --- README.md | 15 ++++++++ examples/README.md | 28 +++++++++++++++ examples/src/framework_crewai_scope.md | 23 ++++++++++++ examples/src/framework_langchain.mjs | 45 ++++++++++++++++++++++++ examples/src/framework_openai_agents.mjs | 38 ++++++++++++++++++++ 5 files changed, 149 insertions(+) create mode 100644 examples/src/framework_crewai_scope.md create mode 100644 examples/src/framework_langchain.mjs create mode 100644 examples/src/framework_openai_agents.mjs diff --git a/README.md b/README.md index f9c91cd..a760c6d 100644 --- a/README.md +++ b/README.md @@ -71,6 +71,21 @@ const client = new NutrientClient({ }); ``` +## Framework Quickstarts + +Framework wiring examples are available in `examples/src/`: + +- `framework_openai_agents.mjs` +- `framework_langchain.mjs` +- `framework_crewai_scope.md` (CrewAI scope note for TypeScript users) + +Syntax-check commands: + +```bash +node --check examples/src/framework_openai_agents.mjs +node --check examples/src/framework_langchain.mjs +``` + ### Working with URLs Most methods accept URLs directly. The URL is passed to the server, which fetches the content—this avoids SSRF vulnerabilities since the client never fetches URLs itself. diff --git a/examples/README.md b/examples/README.md index 52047f5..32ec93e 100644 --- a/examples/README.md +++ b/examples/README.md @@ -8,6 +8,9 @@ This example project demonstrates how to use the Nutrient DWS TypeScript Client - `src/` - Contains TypeScript source files - `direct_method.ts` - Examples using direct method calls - `workflow.ts` - Examples using the workflow builder pattern + - `framework_openai_agents.mjs` - OpenAI Agents integration sketch + - `framework_langchain.mjs` - LangChain integration sketch + - `framework_crewai_scope.md` - CrewAI scope note for TypeScript users - `output/` - Directory where processed files will be saved - `.env.example` - Example environment variables file @@ -89,6 +92,31 @@ This will: 3. Extract text with JSON output 4. Execute a complex multi-step workflow +### Framework Examples + +To run framework integration sketches: + +Install optional framework dependencies first: + +```bash +npm install @openai/agents @langchain/openai @langchain/core +``` + +```bash +node src/framework_openai_agents.mjs +node src/framework_langchain.mjs +``` + +Syntax-check: + +```bash +node --check src/framework_openai_agents.mjs +node --check src/framework_langchain.mjs +``` + +CrewAI note: +- CrewAI is Python-native. See `src/framework_crewai_scope.md` for a recommended bridge pattern when your app stack is TypeScript-first. + ## Output All processed files will be saved to the `output/` directory. You can examine these files to see the results of the document processing operations. diff --git a/examples/src/framework_crewai_scope.md b/examples/src/framework_crewai_scope.md new file mode 100644 index 0000000..b5ecb25 --- /dev/null +++ b/examples/src/framework_crewai_scope.md @@ -0,0 +1,23 @@ +# CrewAI Scope Note (TypeScript Repository) + +CrewAI is currently Python-native. This TypeScript client repo does not provide a first-party CrewAI TypeScript SDK path. + +## Recommended Pattern + +1. Run CrewAI orchestration in a Python service. +2. Call Nutrient DWS through one of these options: +- Python service uses `nutrient-dws-client-python`, or +- Python service calls your TypeScript app endpoint that wraps `@nutrient-sdk/dws-client-typescript`. +3. Return processed artifact metadata (output path, pages, extraction results) back to the TypeScript app. + +## Minimal Bridge Sketch + +```python +# Python CrewAI worker (separate service) +from crewai import Agent, Crew, Task + +# Inside task execution, call your TypeScript endpoint: +# POST /api/dws/process { "operation": "extract_text", "path": "input.pdf" } +``` + +This keeps CrewAI orchestration explicit while preserving a TypeScript-first application surface. diff --git a/examples/src/framework_langchain.mjs b/examples/src/framework_langchain.mjs new file mode 100644 index 0000000..3984a25 --- /dev/null +++ b/examples/src/framework_langchain.mjs @@ -0,0 +1,45 @@ +import { NutrientClient } from "@nutrient-sdk/dws-client-typescript"; +import { ChatOpenAI } from "@langchain/openai"; +import { tool } from "@langchain/core/tools"; + +const client = new NutrientClient({ + apiKey: process.env.NUTRIENT_API_KEY ?? "nutr_sk_placeholder", +}); + +const redactEmails = tool( + async ({ path }) => { + const response = await client.createRedactionsPreset(path, "email-address", "apply"); + return JSON.stringify(response); + }, + { + name: "redact_emails", + description: "Redact email addresses from a document via Nutrient DWS.", + } +); + +async function main() { + const model = new ChatOpenAI({ + model: "gpt-4.1-mini", + apiKey: process.env.OPENAI_API_KEY ?? "sk-placeholder", + }); + + const response = await model.bindTools([redactEmails]).invoke( + "Redact email addresses from ./assets/sample.pdf and summarize next steps." + ); + + if (response.tool_calls?.length) { + for (const call of response.tool_calls) { + if (call.name === "redact_emails") { + const args = + typeof call.args === "object" && call.args !== null ? call.args : {}; + const toolResult = await redactEmails.invoke(args); + console.log(toolResult); + return; + } + } + } + + console.log(response.content); +} + +void main(); diff --git a/examples/src/framework_openai_agents.mjs b/examples/src/framework_openai_agents.mjs new file mode 100644 index 0000000..2c8fe23 --- /dev/null +++ b/examples/src/framework_openai_agents.mjs @@ -0,0 +1,38 @@ +import { NutrientClient } from "@nutrient-sdk/dws-client-typescript"; +import { Agent, Runner, tool } from "@openai/agents"; + +const client = new NutrientClient({ + apiKey: process.env.NUTRIENT_API_KEY ?? "nutr_sk_placeholder", +}); + +const extractText = tool({ + name: "extract_text", + description: "Extract text from a document using Nutrient DWS.", + parameters: { + type: "object", + properties: { + path: { type: "string" }, + }, + required: ["path"], + }, + async execute(input) { + const result = await client.extractText(input.path); + return JSON.stringify(result); + }, +}); + +const agent = new Agent({ + name: "nutrient-openai-agents-typescript", + instructions: "Use tools to process documents and summarize outcomes.", + tools: [extractText], +}); + +async function main() { + const run = await Runner.run( + agent, + "Extract text from ./assets/sample.pdf and summarize key points." + ); + console.log(run.finalOutput); +} + +void main(); From 37f6974520227b9513a17a59b08a7673afa5791b Mon Sep 17 00:00:00 2001 From: Jonathan Rhyne Date: Thu, 5 Mar 2026 10:43:54 -0500 Subject: [PATCH 2/2] Fix framework quickstart env loading and LangChain schema --- examples/README.md | 2 +- examples/src/framework_langchain.mjs | 18 ++++++++++++++++-- examples/src/framework_openai_agents.mjs | 12 +++++++++++- 3 files changed, 28 insertions(+), 4 deletions(-) diff --git a/examples/README.md b/examples/README.md index 32ec93e..e9209d9 100644 --- a/examples/README.md +++ b/examples/README.md @@ -99,7 +99,7 @@ To run framework integration sketches: Install optional framework dependencies first: ```bash -npm install @openai/agents @langchain/openai @langchain/core +npm install @openai/agents @langchain/openai @langchain/core zod ``` ```bash diff --git a/examples/src/framework_langchain.mjs b/examples/src/framework_langchain.mjs index 3984a25..acb917b 100644 --- a/examples/src/framework_langchain.mjs +++ b/examples/src/framework_langchain.mjs @@ -1,9 +1,20 @@ +import "dotenv/config"; import { NutrientClient } from "@nutrient-sdk/dws-client-typescript"; import { ChatOpenAI } from "@langchain/openai"; import { tool } from "@langchain/core/tools"; +import { z } from "zod"; + +const nutrientApiKey = process.env.NUTRIENT_API_KEY; +if (!nutrientApiKey) { + throw new Error("Missing NUTRIENT_API_KEY. Add it to examples/.env before running."); +} + +if (!process.env.OPENAI_API_KEY) { + throw new Error("Missing OPENAI_API_KEY. Add it to examples/.env before running."); +} const client = new NutrientClient({ - apiKey: process.env.NUTRIENT_API_KEY ?? "nutr_sk_placeholder", + apiKey: nutrientApiKey, }); const redactEmails = tool( @@ -14,13 +25,16 @@ const redactEmails = tool( { name: "redact_emails", description: "Redact email addresses from a document via Nutrient DWS.", + schema: z.object({ + path: z.string().describe("Local path to the input PDF file."), + }), } ); async function main() { const model = new ChatOpenAI({ model: "gpt-4.1-mini", - apiKey: process.env.OPENAI_API_KEY ?? "sk-placeholder", + apiKey: process.env.OPENAI_API_KEY, }); const response = await model.bindTools([redactEmails]).invoke( diff --git a/examples/src/framework_openai_agents.mjs b/examples/src/framework_openai_agents.mjs index 2c8fe23..5a60e9e 100644 --- a/examples/src/framework_openai_agents.mjs +++ b/examples/src/framework_openai_agents.mjs @@ -1,8 +1,18 @@ +import "dotenv/config"; import { NutrientClient } from "@nutrient-sdk/dws-client-typescript"; import { Agent, Runner, tool } from "@openai/agents"; +const nutrientApiKey = process.env.NUTRIENT_API_KEY; +if (!nutrientApiKey) { + throw new Error("Missing NUTRIENT_API_KEY. Add it to examples/.env before running."); +} + +if (!process.env.OPENAI_API_KEY) { + throw new Error("Missing OPENAI_API_KEY. Add it to examples/.env before running."); +} + const client = new NutrientClient({ - apiKey: process.env.NUTRIENT_API_KEY ?? "nutr_sk_placeholder", + apiKey: nutrientApiKey, }); const extractText = tool({