CUGA LogoCUGA AGENT
Customization

Knowledge Base

Self-contained document ingestion and retrieval for CUGA agents using Docling and local vector stores.

CUGA includes a built-in knowledge base powered by LangChain and local vector stores. Docling is integrated for document ingestion: it parses and normalizes PDFs, Office files, HTML, Markdown, images, and other supported types before chunking and embedding, so the pipeline stays self-contained with no external document services.

When enabled, the agent can search, ingest, and manage documents — and it automatically becomes aware of what documents are available.

Enabling Knowledge

Knowledge is enabled by default via settings.toml (see Storage for the embedding provider). To opt out for a specific agent in the SDK:

from cuga import CugaAgent

agent = CugaAgent(tools=[...], enable_knowledge=False)

The SDK auto-injects knowledge tools and an awareness block into the agent prompt, so the agent knows what documents are available and how to search them.

Try the Demo

cuga start demo_knowledge

This is the same surface as cuga start demo_crm but with the knowledge engine on — you can upload documents through the UI and query them.

Programmatic Access

from cuga import CugaAgent
import asyncio

agent = CugaAgent(enable_knowledge=True)

async def main():
    # Ingest a document
    await agent.knowledge.ingest("/path/to/quarterly_report.pdf")

    # The agent now automatically knows about this document
    result = await agent.invoke("What does the report say about Q4 revenue?")
    print(result.answer)

    # Direct search (skip the agent loop)
    results = await agent.knowledge.search("Q4 revenue figures")
    for r in results:
        print(f"{r['filename']} (page {r['page']}): {r['text'][:100]}")

    # List documents
    docs = await agent.knowledge.list_documents()

    # Clean up
    await agent.aclose()

asyncio.run(main())

Scopes

Documents can be agent-scoped (the default — permanent and shared across conversations) or session-scoped (tied to a single thread).

# Permanent, shared across conversations
await agent.knowledge.ingest("/path/to/file.pdf", scope="agent")

results = await agent.knowledge.search("query", scope="agent")
thread_id = "user-session-123"

# Temporary, per-conversation
await agent.knowledge.ingest(
    "/path/to/file.pdf",
    scope="session",
    thread_id=thread_id,
)

results = await agent.knowledge.search(
    "query",
    scope="session",
    thread_id=thread_id,
)

Supported Document Types

PDF, DOCX, XLSX, PPTX, HTML, Markdown, images, and more — anything Docling can parse.

Storage and Embeddings

The knowledge backend is selected by the global [storage].mode setting:

Datamode = "local"mode = "prod"
Knowledge vectors{knowledge.persist_dir}/knowledge_vectors.db (vec0 tables per collection)storage.postgres_url (pgvector)
Knowledge metadata{knowledge.persist_dir}/metadata.dbPostgres tables cuga_knowledge_meta_*. Uploaded files still live under persist_dir/files/.

Embeddings are configured under [storage.embedding] and default to a local BAAI/bge-small-en-v1.5 model (no OpenAI key required). See Storage for full options.

The knowledge persistence directory defaults to <cwd>/.cuga/knowledge/ and can be overridden in knowledge_settings.toml.

Routing Knowledge Through CugaLite

The [advanced_features].force_lite_mode_apps list defaults to ["knowledge"], so knowledge queries always run through CugaLite's faster execution path regardless of lite_mode_tool_threshold. To change this, edit settings.toml:

[advanced_features]
force_lite_mode_apps = ["knowledge", "crm"]   # add more apps as needed

The agent's awareness block is rebuilt as documents are ingested or removed, so newly added documents are usable immediately on the next invocation.