AI Powered Contextual Reader is a minimal document reader for language study.
You can open a .docx, Markdown, plain text file, or a text-based .pdf,
click a word in the text, and get an AI explanation that is grounded in the
surrounding context instead of showing an isolated dictionary gloss.
This repository currently ships the first usable baseline:
- Open
.docx, Markdown, plain text, and text-based PDF files in the browser - Click a word to request an explanation from an OpenAI-compatible API
- See the explanation in a sticky panel while you continue reading
- Adjust the reader layout with a draggable divider
- Change API settings and Chinese spacing display from the topbar
This app is useful if you read long-form documents and want fast contextual help without copying text into a separate chatbot window. It is especially suited to:
- bilingual reading
- test-prep and intensive reading
- vocabulary study inside academic or nonfiction texts
- comparing a word's local meaning with its broader sentence context
This is an early but runnable release.
It is intentionally narrow in scope. The goal of this version is to make the core reading loop work well:
- open a supported file
- click a word
- read the contextual AI explanation
- keep moving through the document
If you are looking for OCR, Anki sync, EPUB support, or advanced annotation workflows, those are not included yet. See docs/roadmap.md.
.docx.md.markdown.txt- text-based
.pdf
- scanned PDF files that require OCR
- legacy
.doc - EPUB
- images
- handwriting
For PDFs, the text must be selectable. If the PDF behaves like a stack of images, this version will not extract usable text.
For Markdown files, the reader preserves a limited set of useful inline formatting, including:
- bold
- emphasis
- underline via inline HTML such as
<u>...</u> - highlight via inline HTML such as
<mark>...</mark> - inline code
The app uses a split workspace:
- left side: document reader
- right side: contextual explanation panel
When you click a word, the app extracts nearby context from the current block of text and sends a request to the local server. The server then calls your OpenAI-compatible provider and returns a structured explanation.
The explanation panel is sticky on desktop layouts, so you do not need to scroll back to the top of the page to see the result.
- Bun 1.3 or later
- an OpenAI-compatible API key
bun install
bun run devThen open:
http://localhost:3000
If port 3000 is already in use, set PORT before running the server.
If you want the server to build the frontend and then serve the built app:
bun run startYou can configure the provider in two ways.
Open the Settings panel in the topbar and fill in:
OpenAI API KeyBase URLModel
Settings are saved automatically into project config files.
You can also use the Test provider button in the settings panel to verify that
your current API key, base URL, and model can complete a minimal request before
you start clicking words in the reader.
This is the easiest option for local use.
Copy .env.example to .env and fill in your values.
OPENAI_API_KEY=your_key_here
OPENAI_BASE_URL=https://api.openai.com/v1
OPENAI_MODEL=gpt-4o-mini
PORT=3000Values entered in the Settings panel override the server defaults for requests made from the currently active config profile.
- Start the app with
bun run devorbun run start. - Click
Open a documentin the topbar. - Choose a supported file from your computer.
- Click a word in the document.
- Read the explanation in the right panel.
- Drag the center divider if you want more space for the document or the explanation panel.
The topbar Settings panel currently includes:
- config profile switching
- config profile creation and deletion
OpenAI API KeyBase URLModelEnable Chinese segmented spacingPrompt systemPrompt templateTest provider
This setting is off by default.
When disabled, Chinese text is displayed like a normal article. When enabled, the reader inserts visible spacing between adjacent Chinese word segments to make token boundaries easier to inspect during study.
This setting only changes display behavior. It does not disable word clicking.
Reader and provider settings are stored as real JSON files inside the project so they can be migrated or versioned with the repository.
Current config storage layout:
config/
active.json
profiles/
default.json
your-profile.json
The app auto-saves edits to the active profile after a short debounce. There is no manual save button.
Prompt templates currently support these placeholders:
{{word}}{{documentName}}{{context}}{{system}}
Document parsing happens locally in the app.
When you click a word, the app sends the following information to the local server:
- the selected word
- nearby text context
- basic document metadata needed for the explanation request
The local server then forwards the request to your configured OpenAI-compatible provider.
Do not use this version for confidential material unless you are comfortable with the selected context being sent to that provider.
- text extraction from some PDFs can still be imperfect
- scanned PDFs are not supported
- the app currently focuses on single-word click explanations
- there is no saved vocabulary list yet
- there is no annotation system yet
- there is no account system or sync
Check the following:
- your API key is valid
- your
Base URLpoints to an OpenAI-compatible endpoint - the chosen model exists on that provider
- the local server is running
- the
Test providerbutton succeeds with the same settings
If you use a provider such as SiliconFlow, enter the provider URL exactly as the base API root, for example:
https://api.siliconflow.cn/v1
This usually means the PDF text layer is low quality. Try:
- selecting a different text-based PDF source
- using the original
.docxwhen available - confirming the PDF text is selectable outside this app
Turn off Enable Chinese segmented spacing in Settings.
Planned work is tracked in docs/roadmap.md.
The short version:
- better PDF robustness
- richer explanation controls
- saved history and vocabulary workflows
- optional study integrations such as Anki
Useful local commands:
bun test
bun run typecheck
bun run build