Skip to content

Read the user's own instrument manuals (#120) - #131

Merged
TGoodhew merged 1 commit into
mainfrom
issue-120-manual-library
Jul 31, 2026
Merged

Read the user's own instrument manuals (#120)#131
TGoodhew merged 1 commit into
mainfrom
issue-120-manual-library

Conversation

@TGoodhew

Copy link
Copy Markdown
Owner

Closes #120.

The command database answers first and answers fast, but it is necessarily incomplete — and the manual an entry was derived from is often sitting on the same disk. Point GPIB_MCP_MANUALS at a folder and one tool appears, manual_search, returning the matching passages with the file and page they came from.

Passages, not answers — deliberately

Turning a page of prose into "the command is CF" is the model's job, done in front of the user with the quote visible. A server that synthesised commands out of manuals would be guessing with far more confidence than the evidence supports, and the thing on the other end of a wrong guess is real hardware. Every hit carries its citation, and when a manual yields a command the database lacks, the result says to offer instrument_db_save — so the catalogue grows from the user's own documents, which the issue rightly called the biggest win.

PDFs: the deciding constraint, as predicted

.NET Framework can't read one, and bundling a PDF engine into a server whose whole shape is "no external dependencies" is a poor trade for a feature that's off by default. Three routes, in order: the file is already text; a sidecar <name>.txt sits beside the PDF; or pdftotext (Poppler/xpdf) is on PATH, run with -layout so command tables keep their columns. If none applies, the result names which file couldn't be read and how to fix it — a manual that can't be extracted must never look like a manual with no match. Extracted text is cached by path/size/mtime.

What running it against the real library changed

I pointed it at the actual 570-PDF, 5 GB library on this machine. Two things surfaced that tests alone would not have:

1. Series manuals count. An 8563E's programming manual is filed as 8560E Programming Guide.pdf — the bench's own analyzer, and the first cut found nothing. A human would reach for the series manual, so the search does too, at a much lower rank, with the result flagged familyMatchOnly so the substitution is stated rather than hidden. It now finds CF Center Frequency on page 434.

2. When nothing is named for the model, nothing is searched. The first cut fell back to the smallest files and dutifully searched a 0-byte PDF and readme.txt, reporting "searched 12 files, no match" — which reads as your library doesn't have this when the truth is I never opened the right file. It now says exactly that and lists the closest names it does have.

Also from that run: with a model given, a candidate must be related to that instrument — one shared word in a filename ("frequency") dragged in application notes for other boxes, costing seconds of extraction to answer a different question. Zero-byte files aren't manuals. A caller-supplied file= path cannot escape the library root.

Verification

  • 21 new tests, with text fixtures rather than PDFs — the search, ranking and citations are what they test, and a test needing Poppler installed would be testing the machine instead of the code.
  • Full suite green: 445 GpibMcp + 113 Hpgl, 0 failures (Release|x86) — was 422 + 113.
  • Against the real library: 3458A + "NPLC integration time" → User's Guide p61, the right passage (4.3 s cold, 1.5 s cached); 8563E + "CF center frequency" → 8560E.pdf p434 with the family flag set; 3325B + "sweep start frequency" → 3325B-OM.pdf p67; a model with no manual → an honest "nothing was searched" plus the nearest names.

README: new "Your own manual library" section, features bullet, project layout.

The command database answers first and answers fast, but it is necessarily
incomplete - and the manual an entry was derived from is often sitting on the
same disk. Point GPIB_MCP_MANUALS at a folder and one tool appears,
manual_search, which returns the matching PASSAGES with the file and page they
came from.

Passages, not answers, deliberately. Turning a page of prose into "the command
is CF" is the models job, done in front of the user with the quote visible; a
server that synthesised commands out of manuals would be guessing with far more
confidence than the evidence supports, and the thing on the other end of a wrong
guess is real hardware. Every result carries its citation, and when a manual
yields a command the database lacks the result says to offer instrument_db_save,
so the catalogue grows from the users own documents.

Reading PDFs was the deciding constraint the issue predicted. .NET Framework
cannot, and bundling a PDF engine into a server whose whole shape is "no
external dependencies" is a poor trade for a feature that is off by default. So:
text files read directly; a sidecar <name>.txt beside the PDF read instead; or
pdftotext (Poppler/xpdf) run with -layout, which keeps the columns that make a
command table readable. If none applies the result names the file and the
remedy - a manual that cannot be extracted must never look like a manual with no
match. Extracted text is cached, keyed by path, size and mtime.

Two behaviours came from running it against the real 570-PDF, 5 GB library here,
and neither would have surfaced from tests alone:

- An 8563E's programming manual is filed as "8560E Programming Guide.pdf". A
  human would reach for the series manual, so the search does too, at a much
  lower rank - and the result is flagged familyMatchOnly so the substitution is
  stated rather than hidden. It now finds CF Center Frequency on page 434.
- When nothing is named for the model, NOTHING is searched. The first cut fell
  back to the smallest files and dutifully searched a 0-byte PDF and readme.txt,
  reporting "searched 12 files, no match" - which reads as "your library does
  not have this" when the truth is "I never opened the right file". It now says
  so and lists the closest names it does have.

Also: with a model given, a file must be related to THAT instrument - one shared
word in a filename dragged in application notes for other boxes, seconds of
extraction to answer a different question. Zero-byte files are not manuals. A
caller-supplied path cannot escape the library root.

21 tests, with text fixtures rather than PDFs: the search, ranking and citations
are what they are about, and a test needing Poppler installed would be testing
the machine.
@TGoodhew
TGoodhew merged commit b036417 into main Jul 31, 2026
1 check passed
@TGoodhew
TGoodhew deleted the issue-120-manual-library branch July 31, 2026 19:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Point the server at a local folder of instrument manuals so commands can be looked up from the source documents

1 participant