Choose how to run this agent
Download Agent
Choose how you want to use this agent:
Use Security Settings Key (Recommended)
Use the API key you've already saved in Security Settings. Quick and convenient!
- No need to re-enter API key
- Works offline after download
- Centralized key management
No API key found in Security Settings. Add one now
Enter API Key Manually
Enter your API key now for this specific agent download.
- Use different key for this agent
- One-time use (not saved)
- Works offline after download
Configure Agent Encryption
Description
Upload a PDF or text file and ask questions answered only from that document — fully in your browser, nothing uploaded to a server.
Source Code
import json
# How many document passages to retrieve per question (tunable at generation).
RAG_TOP_K = [[[RAG_TOP_K|4]]]
async def _ingest_document(source, text):
"""(JS-callable) Chunk + embed + index one document's text.
Underscore-prefixed so it is never exposed to the LLM as a tool.
Returns the number of chunks stored, as a string (for the UI).
"""
count = await agentop_rag.add_document(source, text)
return str(count)
def _extract_pdf_text(pdf_bytes):
"""(JS-callable) Extract plain text from a PDF's raw bytes via pypdf."""
import io
from pypdf import PdfReader
reader = PdfReader(io.BytesIO(pdf_bytes))
return "\n\n".join((page.extract_text() or "") for page in reader.pages)
async def process_user_query(query):
"""RAG-first answering: retrieve the most relevant passages from the uploaded
document(s), then answer grounded ONLY in them.
Overrides the default router so retrieval is deterministic (small local
models are unreliable at deciding to call a search tool themselves).
"""
hits = await agentop_rag.search(query, RAG_TOP_K)
if not hits:
context = "(No document has been uploaded yet, or nothing relevant was found.)"
else:
context = "\n\n".join(
f"[{i + 1}] (from {h['source']}) {h['text']}" for i, h in enumerate(hits)
)
grounded_prompt = (
"Answer the QUESTION using ONLY the CONTEXT passages below. "
"If the answer is not in the context, say you could not find it in the "
"document. Cite passage numbers like [1] where relevant.\n\n"
f"CONTEXT:\n{context}\n\nQUESTION: {query}"
)
# TEMPLATE_SYSTEM_PROMPT only exists as a JS global; the query bridge falls
# back to it when custom_prompt is empty (same idiom as the base template).
return await process_user_query_wllama(
grounded_prompt, globals().get("TEMPLATE_SYSTEM_PROMPT", "")
)
More by ozzo
Semantic Search
Search your own notes or documents by meaning, not keywords — instant results with no LLM download.
Meeting Minutes
Turn a meeting recording into a summary, key decisions, and action items, then ask follow-up questi…
Voice Transcriber
Upload a voice note or audio file and get an instant transcript, then ask questions about it — all …
Freelancer Tax Q&A Helper
Freelancer Tax Q&A Helper is a browser-executable AI agent template built on AgentOp. It runs entir…
ATS Resume Optimizer Agent
The ATS Resume Optimizer Agent helps you tailor your resume to specific job postings and stand out …
Contract Plain-Language Explainer Agent
Contracts are written by lawyers, for lawyers — but you’re the one signing them. The Contract Plain…