@foxnose/langchain
v0.2.0
Published
LangChain.js integration for FoxNose — the knowledge layer for RAG and AI agents
Downloads
26
Maintainers
Readme
@foxnose/langchain
Official LangChain.js integration for FoxNose — the knowledge layer for RAG and AI agents.
Features
- FoxNoseRetriever — a LangChain
BaseRetrieverwith 4 search modes: text, vector, hybrid, and vector-boosted - FoxNoseLoader — a LangChain
BaseDocumentLoaderwith automatic cursor-based pagination - createFoxNoseTool — factory to wrap retrieval into a LangChain agent tool
- Content mapping — single field, multiple fields, or a custom mapper function
- Metadata control — whitelist, blacklist, or toggle system metadata
- Structured filtering — pass a
whereparameter for server-side filtering - Type-safe — full TypeScript types with strict mode
Installation
npm install @foxnose/langchain @foxnose/sdk @langchain/core
# or
pnpm add @foxnose/langchain @foxnose/sdk @langchain/coreRequires @foxnose/sdk >= 0.3.0 and @langchain/core >= 0.3.0.
Quick Start
Retriever
import { FluxClient, SimpleKeyAuth } from '@foxnose/sdk';
import { FoxNoseRetriever } from '@foxnose/langchain';
const client = new FluxClient({
baseUrl: 'https://<env_key>.fxns.io',
apiPrefix: 'content',
auth: new SimpleKeyAuth('YOUR_PUBLIC_KEY', 'YOUR_SECRET_KEY'),
});
const retriever = new FoxNoseRetriever({
client,
folderPath: 'articles',
pageContentField: 'body',
searchMode: 'hybrid',
topK: 5,
});
const docs = await retriever.invoke('How do I reset my password?');
for (const doc of docs) {
console.log(doc.pageContent.slice(0, 200));
}Document Loader
import { FoxNoseLoader } from '@foxnose/langchain';
const loader = new FoxNoseLoader({
client,
folderPath: 'articles',
pageContentField: 'body',
batchSize: 50,
});
const docs = await loader.load();
console.log(`Loaded ${docs.length} documents`);Agent Tool
import { createFoxNoseTool } from '@foxnose/langchain';
const tool = createFoxNoseTool({
client,
folderPath: 'articles',
pageContentField: 'body',
name: 'search_knowledge_base',
description: 'Search the knowledge base for relevant articles.',
});
// Use with any LangChain agent
const result = await tool.invoke({ query: 'vector search best practices' });Search Modes
| Mode | Description |
|------|-------------|
| "text" | Full-text keyword search only |
| "vector" | Pure semantic (vector) search only |
| "hybrid" | Combines text and vector search with configurable weights |
| "vector_boosted" | Text search with vector-based re-ranking boost |
Vector Search
const retriever = new FoxNoseRetriever({
client,
folderPath: 'articles',
pageContentField: 'body',
searchMode: 'vector',
topK: 10,
similarityThreshold: 0.7,
});Hybrid Search with Custom Weights
const retriever = new FoxNoseRetriever({
client,
folderPath: 'articles',
pageContentField: 'body',
searchMode: 'hybrid',
hybridConfig: {
vectorWeight: 0.7,
textWeight: 0.3,
rerankResults: true,
},
});Custom Embeddings
Use your own embedding model for vector search via the embeddings and vectorField options:
import { OpenAIEmbeddings } from '@langchain/openai';
const retriever = new FoxNoseRetriever({
client,
folderPath: 'articles',
pageContentField: 'body',
searchMode: 'vector',
embeddings: new OpenAIEmbeddings({ model: 'text-embedding-3-small' }),
vectorField: 'embedding',
topK: 10,
});Or with a pre-computed vector:
const retriever = new FoxNoseRetriever({
client,
folderPath: 'articles',
pageContentField: 'body',
searchMode: 'vector',
queryVector: [0.1, 0.2, 0.3, /* ... */],
vectorField: 'embedding',
});Note: When using
embeddings, the query text is sent to the embedding provider (e.g. OpenAI) on every invocation.
Filtered Retrieval
const retriever = new FoxNoseRetriever({
client,
folderPath: 'articles',
pageContentField: 'body',
searchMode: 'hybrid',
where: {
$: {
all_of: [
{ status__eq: 'published' },
{ category__in: ['tech', 'science'] },
],
},
},
});Content Mapping
Single Field
new FoxNoseRetriever({
client,
folderPath: 'articles',
pageContentField: 'body',
});Multiple Fields
new FoxNoseRetriever({
client,
folderPath: 'articles',
pageContentFields: ['title', 'body'],
pageContentSeparator: '\n\n', // default
});Custom Mapper
new FoxNoseRetriever({
client,
folderPath: 'articles',
pageContentMapper: (result) =>
`# ${result.data?.title}\n\n${result.data?.body}`,
});Metadata Control
// Whitelist specific fields
new FoxNoseRetriever({
client,
folderPath: 'articles',
pageContentField: 'body',
metadataFields: ['title', 'category'],
});
// Blacklist specific fields
new FoxNoseRetriever({
client,
folderPath: 'articles',
pageContentField: 'body',
excludeMetadataFields: ['internal_notes'],
});
// Disable system metadata (_sys fields)
new FoxNoseRetriever({
client,
folderPath: 'articles',
pageContentField: 'body',
includeSysMetadata: false,
});API Reference
FoxNoseRetriever
Extends BaseRetriever from @langchain/core.
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| client | FluxClient | required | FoxNose Flux client instance |
| folderPath | string | required | Folder path in FoxNose |
| pageContentField | string | — | Single data field for pageContent |
| pageContentFields | string[] | — | Multiple fields concatenated |
| pageContentSeparator | string | "\n\n" | Separator for multi-field content |
| pageContentMapper | (result) => string | — | Custom content extractor |
| searchMode | SearchMode | "hybrid" | Search mode |
| topK | number | 5 | Max results |
| searchFields | string[] | — | Text search fields |
| textThreshold | number | — | Text search typo tolerance (0–1) |
| vectorFields | string[] | — | Vector search fields (not supported in vector_boosted mode) |
| similarityThreshold | number | — | Min cosine similarity (0–1) |
| where | object | — | Structured filter |
| hybridConfig | HybridConfig | — | Hybrid mode weights |
| vectorBoostConfig | VectorBoostConfig | — | Vector-boosted config |
| sort | string[] | — | Sort fields |
| searchKwargs | object | — | Extra search body params |
| embeddings | EmbeddingsInterface | — | LangChain embeddings model for custom vectors |
| queryVector | number[] | — | Pre-computed query vector |
| vectorField | string | — | Field name for custom-embedding search |
| metadataFields | string[] | — | Metadata whitelist |
| excludeMetadataFields | string[] | — | Metadata blacklist |
| includeSysMetadata | boolean | true | Include _sys metadata |
FoxNoseLoader
Extends BaseDocumentLoader from @langchain/core.
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| client | FluxClient | required | FoxNose Flux client instance |
| folderPath | string | required | Folder path in FoxNose |
| batchSize | number | 100 | Page size for pagination |
| params | object | — | Query params for listResources |
| (content mapping) | | | Same as FoxNoseRetriever |
| (metadata control) | | | Same as FoxNoseRetriever |
createFoxNoseTool
Factory function that returns a DynamicStructuredTool.
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| retriever | FoxNoseRetriever | — | Pre-built retriever (or provide client config) |
| name | string | "foxnose_search" | Tool name for agents |
| description | string | (auto) | Tool description |
| documentSeparator | string | "\n\n" | Separator between docs |
| (retriever options) | | | Same as FoxNoseRetriever |
Development
# Install dependencies
pnpm install
# Run tests
pnpm test
# Run tests with coverage
pnpm test:coverage
# Type check
pnpm typecheck
# Build
pnpm build
# Lint
pnpm lint
# Format
pnpm formatLicense
Apache 2.0 — see LICENSE.
