localagentbrowser 1.53__tar.gz → 1.57__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {localagentbrowser-1.53 → localagentbrowser-1.57}/CHANGELOG.md +58 -1
- {localagentbrowser-1.53/localagentbrowser.egg-info → localagentbrowser-1.57}/PKG-INFO +71 -40
- {localagentbrowser-1.53 → localagentbrowser-1.57}/README.md +70 -39
- {localagentbrowser-1.53 → localagentbrowser-1.57}/agent_browser.py +288 -13
- {localagentbrowser-1.53 → localagentbrowser-1.57/localagentbrowser.egg-info}/PKG-INFO +71 -40
- {localagentbrowser-1.53 → localagentbrowser-1.57}/pyproject.toml +1 -1
- localagentbrowser-1.57/tests/test_checklist.py +251 -0
- {localagentbrowser-1.53 → localagentbrowser-1.57}/tests/test_decisions.py +38 -5
- {localagentbrowser-1.53 → localagentbrowser-1.57}/tests/test_main_loop.py +26 -4
- {localagentbrowser-1.53 → localagentbrowser-1.57}/tests/test_model_turns.py +9 -1
- {localagentbrowser-1.53 → localagentbrowser-1.57}/tests/test_regression.py +8 -0
- {localagentbrowser-1.53 → localagentbrowser-1.57}/tools/regression.py +18 -2
- localagentbrowser-1.53/tests/test_checklist.py +0 -90
- {localagentbrowser-1.53 → localagentbrowser-1.57}/LICENSE +0 -0
- {localagentbrowser-1.53 → localagentbrowser-1.57}/MANIFEST.in +0 -0
- {localagentbrowser-1.53 → localagentbrowser-1.57}/localagentbrowser.egg-info/SOURCES.txt +0 -0
- {localagentbrowser-1.53 → localagentbrowser-1.57}/localagentbrowser.egg-info/dependency_links.txt +0 -0
- {localagentbrowser-1.53 → localagentbrowser-1.57}/localagentbrowser.egg-info/entry_points.txt +0 -0
- {localagentbrowser-1.53 → localagentbrowser-1.57}/localagentbrowser.egg-info/requires.txt +0 -0
- {localagentbrowser-1.53 → localagentbrowser-1.57}/localagentbrowser.egg-info/top_level.txt +0 -0
- {localagentbrowser-1.53 → localagentbrowser-1.57}/setup.cfg +0 -0
- {localagentbrowser-1.53 → localagentbrowser-1.57}/tests/conftest.py +0 -0
- {localagentbrowser-1.53 → localagentbrowser-1.57}/tests/fakes.py +0 -0
- {localagentbrowser-1.53 → localagentbrowser-1.57}/tests/test_duplicates.py +0 -0
- {localagentbrowser-1.53 → localagentbrowser-1.57}/tests/test_journal.py +0 -0
- {localagentbrowser-1.53 → localagentbrowser-1.57}/tests/test_page_text.py +0 -0
- {localagentbrowser-1.53 → localagentbrowser-1.57}/tools/live_test.py +0 -0
|
@@ -1,9 +1,66 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
Every version of `agent_browser.py`, newest first. Each version is also a tagged commit (`v1.11` … `v1.
|
|
3
|
+
Every version of `agent_browser.py`, newest first. Each released version is also a tagged commit (`v1.11` … `v1.57`); 1.54 to 1.56 were internal steps
|
|
4
|
+
measured on the regression suite and released as part of 1.57 (see
|
|
5
|
+
[docs/regression-history.md](docs/regression-history.md)).
|
|
4
6
|
Timings are from live runs on the development machine (Intel i5-9500, 6 cores, no GPU, Qwen2.5-7B-Instruct
|
|
5
7
|
Q4_K_M in LM Studio), where reading the prompt takes about 90% of every model call.
|
|
6
8
|
|
|
9
|
+
## [1.57] - 2026-10-19
|
|
10
|
+
Released together with the internal steps 1.54, 1.55 and 1.56, each of which was measured on the regression suite
|
|
11
|
+
but not released on its own. [docs/regression-history.md](docs/regression-history.md) has every step's results,
|
|
12
|
+
task by task, and what each one showed.
|
|
13
|
+
### Added
|
|
14
|
+
- Coverage check before finishing. The 1.53 suite left two problems open: an explanation finished from one overview
|
|
15
|
+
paragraph that the model said covered every item (no oxygen or water), and a list named WPS Office as
|
|
16
|
+
"free, open-source". Before a FINISH goes through, each checklist item is now checked against the full findings
|
|
17
|
+
in a short call of its own, with the item last so the instructions are read once (about 1-3 minutes for a
|
|
18
|
+
checklist). The code checks the verdict rather than taking it on trust: an item nothing was copied for counts as
|
|
19
|
+
unanswered; an item asking for a number of things gets "only 1 of 3 found" when fewer are named; for such items,
|
|
20
|
+
each thing named must be shown to meet the item's conditions in words copied from a finding about that thing; and
|
|
21
|
+
a claim that something is missing is dropped when every word of it is already in the findings. With gaps, the
|
|
22
|
+
FINISH is sent back once, naming the next step for a condition ("SEARCH for 'OnlyOffice free and open-source' to
|
|
23
|
+
check it, or replace it"), and the next turn starts from a fresh prompt. Finishing with nothing recorded is sent
|
|
24
|
+
back too.
|
|
25
|
+
- What no finding answers is reported by the code. Checked once more just before the final result, checklist items
|
|
26
|
+
nothing answers and things not shown to meet a condition are left out of what the final result is asked to write
|
|
27
|
+
and added after it ("Not found in the pages read", "Left out, not shown to meet the conditions in the pages read").
|
|
28
|
+
The final result had filled a gap from the model's own knowledge (a care routine for repotted plants).
|
|
29
|
+
- The first turn asks for one short search for the whole objective, keeping its conditions: with the checklist, the
|
|
30
|
+
first search had gone after the first item only, and the documentation task had dropped "official". Two system
|
|
31
|
+
prompt rules say the same for later searches.
|
|
32
|
+
### Changed
|
|
33
|
+
- A DISCOVER refused as not on the page now quotes the page sentence closest to it (chosen by the refused text and
|
|
34
|
+
the objective), to record instead, or names what the parts shown never mention ("Japan, Navajo"); it is no longer
|
|
35
|
+
wrapped in "Do NOT choose DISCOVER again ... choose a different action", which outweighed the quoted sentence.
|
|
36
|
+
Replayed on the saved runs: the page's real aftercare line was recorded 6 times out of 6 (0 of 3 before), a refusal
|
|
37
|
+
where the real steps came on the next part still led to READ_MORE 6 of 6, and an owl case read on 5 of 6.
|
|
38
|
+
- The final result gives as many items as asked for without ever repeating one, and says how many were not found:
|
|
39
|
+
a list run had listed LibreOffice three times.
|
|
40
|
+
- Opinion items are shown in the checklist as "written by you at FINISH, not found on a page": shown as having no
|
|
41
|
+
discoveries yet, an owl task kept collecting cultures after it had the three asked for.
|
|
42
|
+
- Fundraising banners and other site notices are hidden like cookie banners: Wikipedia's filled the whole first part
|
|
43
|
+
of an article.
|
|
44
|
+
- Regression suite: the core how-to is now "make cold brew coffee at home" (`howto-coldbrew`), since the repotting
|
|
45
|
+
task went to the same guide in three runs and that guide has no section on care in the first two weeks; repotting
|
|
46
|
+
stays as an extra task under its old id. The summary flags a task that fails again on the same site as before. The
|
|
47
|
+
documentation task has 45 minutes, like the others.
|
|
48
|
+
### Fixed
|
|
49
|
+
- The not-on-page check refused the real Kilimanjaro answer as unseen because the banner hid the article (above).
|
|
50
|
+
- Numbered headings ("#### 1. Setup") were flagged as numbers missing from the findings (1.53).
|
|
51
|
+
|
|
52
|
+
Regression runs, finished out of 7 (model minutes): 1.53 5 (200), 1.54 4 (239), 1.54 with fixes 5 (225), 1.55 5
|
|
53
|
+
(233), 1.56 4 (272), 1.57 4 (270). Across these runs the result quality rose where the checks fired: the
|
|
54
|
+
explanation went from thin to complete and cited, the comparison stopped inventing features, the list stopped naming
|
|
55
|
+
WPS Office as open source, and every documentation finding since 1.55 is from python.org. What is not better: about
|
|
56
|
+
half of the coverage check's send-backs were for gaps that were not real, and each costs 8-10 minutes on this
|
|
57
|
+
hardware (a fresh prompt reads 3,000-4,000 tokens), so finishes were lost: on 1.57, a list of three correct
|
|
58
|
+
open-source suites sent back because no words showed them to be "free", and a comparison sent back for "official
|
|
59
|
+
documentation" it was not asked for. The next step is to send the agent back only for gaps the code verifies.
|
|
60
|
+
Also still open: on the documentation task the Windows line repeats the create command instead of the activate
|
|
61
|
+
one (1.56 and 1.57), and on 1.57 the opinion task ran out of time on a page that covered two of the three
|
|
62
|
+
cultures asked for.
|
|
63
|
+
|
|
7
64
|
## [1.53] - 2026-10-17
|
|
8
65
|
### Added
|
|
9
66
|
- Regression suite (`tools/regression.py`): seven objectives, one of each kind of task tested so far, run one
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: localagentbrowser
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.57
|
|
4
4
|
Summary: An autonomous web agent driven by a local LLM (LM Studio) and Playwright. Runs entirely on your own machine.
|
|
5
5
|
Author: SnowFX
|
|
6
6
|
License-Expression: MIT
|
|
@@ -56,7 +56,7 @@ and tuned to work well with a **small 7B model on a CPU, no GPU required**.
|
|
|
56
56
|
- ⚡ **Built for slow hardware.** It reuses LM Studio's prompt cache, so most turns process only what changed.
|
|
57
57
|
- 📝 **A readable report every time.** `research_report.md` holds the final result and every finding with its
|
|
58
58
|
source, written however the run ends; `research_log.txt` keeps every action and reason.
|
|
59
|
-
- ✅ **Tested.**
|
|
59
|
+
- ✅ **Tested.** 165 tests on Linux and Windows, Python 3.10–3.13, run in a few seconds with no model or browser,
|
|
60
60
|
plus a [regression suite](#regression-suite) of live runs on seven different kinds of task.
|
|
61
61
|
|
|
62
62
|
📖 **The story behind it:** [Teaching a 7B model on a CPU to finish what it starts](https://dev.to/snowfxxx/teaching-a-7b-model-on-a-cpu-to-finish-what-it-starts-1amc),
|
|
@@ -199,17 +199,19 @@ does not generalise; the [changelog](https://github.com/SnowFXXX/LocalAgentBrows
|
|
|
199
199
|
|
|
200
200
|
Since 1.53, every change is measured on the same seven objectives, one of each kind above, run one after the other
|
|
201
201
|
with a time limit each (`tools/regression.py`, see [Testing](#testing)). Single runs vary with the pages a search
|
|
202
|
-
turns up, so the suite compares versions on all seven at once
|
|
202
|
+
turns up, so the suite compares versions on all seven at once. 1.54 to 1.56 were internal steps measured this way
|
|
203
|
+
and released together as 1.57; [docs/regression-history.md](https://github.com/SnowFXXX/LocalAgentBrowser/blob/main/docs/regression-history.md)
|
|
204
|
+
has every step's results and what each one showed.
|
|
203
205
|
|
|
204
|
-
| Task | 1.52 | 1.53 (objective checklist) |
|
|
205
|
-
|
|
206
|
-
| Factual question | Finished, 12 min | Finished, 14 min |
|
|
207
|
-
| List of three office suites | Time limit
|
|
208
|
-
| Comparison and recommendation | Time limit
|
|
209
|
-
| How-to (repotting) | Time limit
|
|
210
|
-
| Explanation (photosynthesis) | Time limit
|
|
211
|
-
| Opinion (owls) | Time limit
|
|
212
|
-
| Documentation (venv, official docs) | Finished, 15 min, from a tutorial site | Time limit (30 min)
|
|
206
|
+
| Task | 1.52 | 1.53 (objective checklist) | 1.57 (coverage check) |
|
|
207
|
+
|---|---|---|---|
|
|
208
|
+
| Factual question | Finished, 12 min | Finished, 14 min | Finished, 13 min |
|
|
209
|
+
| List of three office suites | Time limit | Finished, 30 min; but WPS Office is not open source | Time limit: three correct open-source suites by turn 7, sent back because no words showed them to be "free" |
|
|
210
|
+
| Comparison and recommendation | Time limit | Finished, 39 min | Time limit, after a send-back for "official documentation", which the objective does not ask for |
|
|
211
|
+
| How-to (cold brew from 1.55; repotting before) | Time limit | Time limit | Finished, 36 min; but "how long it keeps" answered with the steeping time |
|
|
212
|
+
| Explanation (photosynthesis) | Time limit | Finished, 13 min, but thin: no oxygen or water | Finished, 59 min: inputs, outputs and both stages, cited |
|
|
213
|
+
| Opinion (owls) | Time limit | Finished, 38 min | Time limit: its first page covered two of the three cultures asked for |
|
|
214
|
+
| Documentation (venv, official docs) | Finished, 15 min, from a tutorial site | Time limit (30 min) | Finished, 37 min, all from python.org; but the Windows line repeats the create command instead of the activate one |
|
|
213
215
|
|
|
214
216
|
## How it works
|
|
215
217
|
|
|
@@ -248,12 +250,22 @@ flowchart LR
|
|
|
248
250
|
- **Findings must match the page.** A finding that shares too few word pairs with the page text shown so far
|
|
249
251
|
(or has a sentence that does) is sent back once, asking for only what the page says in its own words, and
|
|
250
252
|
one far from anything on the page is refused outright. A small model will otherwise "complete" a list from
|
|
251
|
-
its own knowledge when a page says "follow these 6 steps" and the steps come later.
|
|
253
|
+
its own knowledge when a page says "follow these 6 steps" and the steps come later. The refusal points the way:
|
|
254
|
+
it quotes the one page sentence closest to what the model wrote, to record instead, or names what the parts
|
|
255
|
+
shown never mention ("Japan, Navajo"), so the model reads on.
|
|
252
256
|
- **An objective checklist.** At the start, one short model call splits the objective into a fixed checklist of
|
|
253
257
|
what the result must contain, keeping conditions like "free, open-source" or "three". Each finding names the
|
|
254
258
|
items it serves, the checklist with its findings is in every prompt, and every check goes through these items
|
|
255
259
|
instead of asking the model to split the objective again from memory, which drifted: it once blocked its own
|
|
256
|
-
finish over "migration strategies", which the objective never asked for.
|
|
260
|
+
finish over "migration strategies", which the objective never asked for. Opinion items are shown as written
|
|
261
|
+
at FINISH, not as gaps to fill, and the first search covers the whole objective in one short query, keeping
|
|
262
|
+
its conditions ("official python documentation venv").
|
|
263
|
+
- **A coverage check before finishing.** Each checklist item is checked against the findings in a short call of
|
|
264
|
+
its own, and the code checks the verdict instead of taking it on trust: an item nothing was copied for, fewer
|
|
265
|
+
things than asked for ("only 1 of 3 found"), and things not shown, in words copied from a finding about them,
|
|
266
|
+
to meet a condition such as "open-source". A claim that something is missing is dropped when every word of it is
|
|
267
|
+
already in the findings. With gaps, the FINISH is sent back once, with the next step named ("SEARCH for
|
|
268
|
+
'OnlyOffice free and open-source' to check it, or replace it"), and the next turn starts from a fresh prompt.
|
|
257
269
|
- **Numbered findings.** Findings are numbered in the prompt and listed with every check, and the model names
|
|
258
270
|
the finding that covers each part of the objective ("covered by [2]") instead of just saying "covered".
|
|
259
271
|
- **Knowing when it's done.** After every new finding the model is asked whether the objective is now fully
|
|
@@ -265,12 +277,16 @@ flowchart LR
|
|
|
265
277
|
A part that cannot be found after several tries can be reported as missing instead of blocking for good.
|
|
266
278
|
- **Writing is a separate step.** When the agent finishes, one more model call writes the final result from
|
|
267
279
|
only the objective and the recorded findings, under a short list of rules: no guessing or outside knowledge,
|
|
268
|
-
cite findings by number, give
|
|
269
|
-
the objective asks for an opinion. A small model writes far
|
|
270
|
-
claim stays traceable to a recorded finding.
|
|
271
|
-
|
|
280
|
+
cite findings by number, give as many items as asked for (never repeating one, and saying how many were not
|
|
281
|
+
found), and add a "My view:" paragraph only when the objective asks for an opinion. A small model writes far
|
|
282
|
+
better when that is its only job, and every claim stays traceable to a recorded finding. What no finding
|
|
283
|
+
answers is not left to the model: those checklist items, and things not shown to meet a condition, are left out
|
|
284
|
+
of what it is asked to write, and the code adds them after the result as "Not found in the pages read" and
|
|
285
|
+
"Left out, not shown to meet the conditions". The report flags any number in the final result that appears in
|
|
286
|
+
none of the findings, the most harmful kind of slip in a how-to.
|
|
272
287
|
- **Error pages are recognised.** A page answering 404, 403 and so on counts as a failed visit, not content.
|
|
273
|
-
- **Readable pages.** Navigation menus, footers
|
|
288
|
+
- **Readable pages.** Navigation menus, footers, cookie banners and site notices such as fundraising banners are
|
|
289
|
+
hidden; code blocks and tables are
|
|
274
290
|
never split between parts; links already shown are not repeated. Long pages come with an outline of the
|
|
275
291
|
headings in each part, marking the parts already read, so the agent can jump to the part it needs instead of
|
|
276
292
|
reading in order.
|
|
@@ -303,12 +319,13 @@ Measured on an Intel i5-9500 (6 cores, no GPU) with Qwen2.5-7B-Instruct Q4_K_M a
|
|
|
303
319
|
| Follow-up on the same page (finding recorded, cheap retry) | 35–60 s |
|
|
304
320
|
| Next part of a page, or a new page appended | 100–280 s |
|
|
305
321
|
| First turn of a run | 45–110 s |
|
|
306
|
-
| Fresh prompt
|
|
322
|
+
| Fresh prompt (context budget reached, or after a coverage send-back) | 160–540 s (longest with long pages) |
|
|
323
|
+
| Coverage check before finishing (all checklist items) | about 1–3 min |
|
|
307
324
|
| Writing the final result (once, at the end) | 50–190 s, depending on how much was found |
|
|
308
325
|
|
|
309
|
-
Whole runs vary with the pages a search turns up. In the
|
|
310
|
-
minutes of model time
|
|
311
|
-
GPU or a smaller model will be much faster.
|
|
326
|
+
Whole runs vary with the pages a search turns up. In the regression runs since 1.53, a factual question took 13 to
|
|
327
|
+
19 minutes of model time; the list, comparison, how-to, opinion and documentation tasks 21 to 44 when they finished;
|
|
328
|
+
and the explanation 13 to 59. A GPU or a smaller model will be much faster.
|
|
312
329
|
|
|
313
330
|
## FAQ
|
|
314
331
|
|
|
@@ -343,18 +360,19 @@ turn that brings in a new page takes a few minutes. See [Performance](#performan
|
|
|
343
360
|
research, an opinion from several sources, a factual question, a comparison, a how-to, a list and an
|
|
344
361
|
explanation of a topic. Each one
|
|
345
362
|
exposed something that did not generalise and was fixed; other kinds of tasks may expose more.
|
|
346
|
-
- **
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
363
|
+
- **Judging whether a finding covers an item is the weakest area.** The model's verdict is unreliable both ways:
|
|
364
|
+
on 1.53 the explanation finished from one overview paragraph without oxygen or water, and in the regression runs
|
|
365
|
+
since 1.54 about half of the coverage check's send-backs were for gaps that were not real ("missing official
|
|
366
|
+
documentation" on a comparison that did not ask for it, "H2O, O2" already recorded). The code now verifies what
|
|
367
|
+
it can (an item nothing answers, a count, word-for-word proof of a condition), but each wrong send-back still
|
|
368
|
+
costs a finish on this hardware, since a send-back costs 8–10 minutes.
|
|
352
369
|
- **Conditions in the objective.** A small model tends to drop conditions such as "open source" or "using the
|
|
353
370
|
official documentation": a list of open-source office suites once included FreeOffice (free but not open
|
|
354
371
|
source), and a task that asked for the official Python documentation used a tutorial site. The objective
|
|
355
|
-
checklist keeps the conditions in view (the documentation task
|
|
356
|
-
|
|
357
|
-
|
|
372
|
+
checklist keeps the conditions in view (the documentation task uses python.org since 1.55), and a thing not
|
|
373
|
+
shown in the findings to meet a condition is left out of the result and listed after it. The check is strict:
|
|
374
|
+
on 1.57 it sent back three correct open-source suites because no words showed them to be "free". Check the
|
|
375
|
+
result against any conditions you set.
|
|
358
376
|
- **A small model's judgement is the ceiling.** It sometimes drifts to loosely related pages, prefers
|
|
359
377
|
secondary sources or stays with one source too long, and results vary with the first pages a search turns
|
|
360
378
|
up; every finding is in `research_report.md` regardless.
|
|
@@ -363,8 +381,9 @@ turn that brings in a new page takes a few minutes. See [Performance](#performan
|
|
|
363
381
|
minutes, but with thin findings and without naming what it could not find, so check the result against the
|
|
364
382
|
objective.
|
|
365
383
|
- **Check the citations.** The final result is told to use only recorded findings, but a 7B model sometimes
|
|
366
|
-
puts the wrong number on a citation, adds a line no finding supports
|
|
367
|
-
|
|
384
|
+
puts the wrong number on a citation, adds a line no finding supports, leaves out a step or misreads a part of
|
|
385
|
+
the question (on 1.57 it answered "how long it keeps in the fridge" with the steeping time), so verify a claim
|
|
386
|
+
against the listed findings before relying on it.
|
|
368
387
|
- **Some sites refuse automated browsers** (HTTP 403). The agent respects that and does not try to disguise
|
|
369
388
|
itself; it moves on to other sources.
|
|
370
389
|
- **Reading only.** The agent searches, opens pages and reads them. It does not click, fill in forms or sign in.
|
|
@@ -381,7 +400,13 @@ turn that brings in a new page takes a few minutes. See [Performance](#performan
|
|
|
381
400
|
- [ ] Let very strict objectives end with the gaps named instead of searching indefinitely (they finish since 1.50; naming the gaps is still open)
|
|
382
401
|
- [x] Measure every change on a regression suite of seven kinds of task (1.53)
|
|
383
402
|
- [x] Keep a fixed checklist of the objective's parts instead of re-splitting it at every check (1.53)
|
|
384
|
-
- [ ] Check that a finding really covers its checklist item, including conditions like "open source"
|
|
403
|
+
- [ ] Check that a finding really covers its checklist item, including conditions like "open source" (partly, since
|
|
404
|
+
1.57: a coverage check before finishing, with what the code can verify)
|
|
405
|
+
- [ ] Send the agent back only for gaps the code verifies, and let the model's other verdicts only shape the final
|
|
406
|
+
result (the next step after 1.57)
|
|
407
|
+
- [ ] Rewind dead ends: save the conversation before an expensive step such as reading a long page, and if it
|
|
408
|
+
leads nowhere, return to that point with a short note instead of carrying the unused page text in every later
|
|
409
|
+
prompt (LM Studio reuses its cache up to the saved point)
|
|
385
410
|
- [ ] Try more kinds of objectives (seven so far) and adjust the rules that don't generalise
|
|
386
411
|
- [ ] Make fresh prompts (the slowest kind of turn) cheaper still (31% cheaper since 1.34)
|
|
387
412
|
- [ ] Interacting with pages (clicking, forms) for tasks beyond reading
|
|
@@ -390,7 +415,7 @@ Ideas and requests are welcome in [issues](https://github.com/SnowFXXX/LocalAgen
|
|
|
390
415
|
|
|
391
416
|
## Testing
|
|
392
417
|
|
|
393
|
-
The test suite runs in
|
|
418
|
+
The test suite runs in a few seconds and needs neither LM Studio nor a browser: the model and the website
|
|
394
419
|
are replaced by scripted fakes, including an end-to-end run of the main loop.
|
|
395
420
|
|
|
396
421
|
```bash
|
|
@@ -416,8 +441,12 @@ Each run gets a folder in `regression_runs/` with every task's report, journal,
|
|
|
416
441
|
trace, and a `summary.md` that is updated after each task: whether it finished, turns, model time, how many
|
|
417
442
|
checklist items got findings, which checks fired, and problems found by simple word checks (missing answers,
|
|
418
443
|
missed conditions such as a non-open-source item, uncited paragraphs, numbers missing from the findings, a
|
|
419
|
-
missing opinion).
|
|
420
|
-
|
|
444
|
+
missing opinion). It also flags a task that fails again on the same site as in the earlier run: one site that
|
|
445
|
+
cannot answer part of an objective can decide a task whatever the agent does (the repotting how-to went to the same
|
|
446
|
+
guide in three runs, which is why the core how-to is now the cold brew one). `--suite all` adds six more tasks,
|
|
447
|
+
including the earlier how-to, `--only` runs some of them, and `--rescore` scores an earlier run again without the
|
|
448
|
+
model. Every step since 1.53 and its results are in
|
|
449
|
+
[docs/regression-history.md](https://github.com/SnowFXXX/LocalAgentBrowser/blob/main/docs/regression-history.md).
|
|
421
450
|
|
|
422
451
|
## Contributing
|
|
423
452
|
|
|
@@ -426,8 +455,10 @@ the [Code of Conduct](https://github.com/SnowFXXX/LocalAgentBrowser/blob/main/CO
|
|
|
426
455
|
|
|
427
456
|
## Project history
|
|
428
457
|
|
|
429
|
-
Every version is a tagged commit, and [CHANGELOG.md](https://github.com/SnowFXXX/LocalAgentBrowser/blob/main/CHANGELOG.md) describes what changed in each one and
|
|
430
|
-
why, with the measurements behind the decisions.
|
|
458
|
+
Every released version is a tagged commit, and [CHANGELOG.md](https://github.com/SnowFXXX/LocalAgentBrowser/blob/main/CHANGELOG.md) describes what changed in each one and
|
|
459
|
+
why, with the measurements behind the decisions. Versions 1.54 to 1.56 were internal steps, each measured on the
|
|
460
|
+
regression suite and released together as 1.57; their results are in
|
|
461
|
+
[docs/regression-history.md](https://github.com/SnowFXXX/LocalAgentBrowser/blob/main/docs/regression-history.md).
|
|
431
462
|
|
|
432
463
|
## Acknowledgements
|
|
433
464
|
|
|
@@ -24,7 +24,7 @@ and tuned to work well with a **small 7B model on a CPU, no GPU required**.
|
|
|
24
24
|
- ⚡ **Built for slow hardware.** It reuses LM Studio's prompt cache, so most turns process only what changed.
|
|
25
25
|
- 📝 **A readable report every time.** `research_report.md` holds the final result and every finding with its
|
|
26
26
|
source, written however the run ends; `research_log.txt` keeps every action and reason.
|
|
27
|
-
- ✅ **Tested.**
|
|
27
|
+
- ✅ **Tested.** 165 tests on Linux and Windows, Python 3.10–3.13, run in a few seconds with no model or browser,
|
|
28
28
|
plus a [regression suite](#regression-suite) of live runs on seven different kinds of task.
|
|
29
29
|
|
|
30
30
|
📖 **The story behind it:** [Teaching a 7B model on a CPU to finish what it starts](https://dev.to/snowfxxx/teaching-a-7b-model-on-a-cpu-to-finish-what-it-starts-1amc),
|
|
@@ -167,17 +167,19 @@ does not generalise; the [changelog](https://github.com/SnowFXXX/LocalAgentBrows
|
|
|
167
167
|
|
|
168
168
|
Since 1.53, every change is measured on the same seven objectives, one of each kind above, run one after the other
|
|
169
169
|
with a time limit each (`tools/regression.py`, see [Testing](#testing)). Single runs vary with the pages a search
|
|
170
|
-
turns up, so the suite compares versions on all seven at once
|
|
170
|
+
turns up, so the suite compares versions on all seven at once. 1.54 to 1.56 were internal steps measured this way
|
|
171
|
+
and released together as 1.57; [docs/regression-history.md](https://github.com/SnowFXXX/LocalAgentBrowser/blob/main/docs/regression-history.md)
|
|
172
|
+
has every step's results and what each one showed.
|
|
171
173
|
|
|
172
|
-
| Task | 1.52 | 1.53 (objective checklist) |
|
|
173
|
-
|
|
174
|
-
| Factual question | Finished, 12 min | Finished, 14 min |
|
|
175
|
-
| List of three office suites | Time limit
|
|
176
|
-
| Comparison and recommendation | Time limit
|
|
177
|
-
| How-to (repotting) | Time limit
|
|
178
|
-
| Explanation (photosynthesis) | Time limit
|
|
179
|
-
| Opinion (owls) | Time limit
|
|
180
|
-
| Documentation (venv, official docs) | Finished, 15 min, from a tutorial site | Time limit (30 min)
|
|
174
|
+
| Task | 1.52 | 1.53 (objective checklist) | 1.57 (coverage check) |
|
|
175
|
+
|---|---|---|---|
|
|
176
|
+
| Factual question | Finished, 12 min | Finished, 14 min | Finished, 13 min |
|
|
177
|
+
| List of three office suites | Time limit | Finished, 30 min; but WPS Office is not open source | Time limit: three correct open-source suites by turn 7, sent back because no words showed them to be "free" |
|
|
178
|
+
| Comparison and recommendation | Time limit | Finished, 39 min | Time limit, after a send-back for "official documentation", which the objective does not ask for |
|
|
179
|
+
| How-to (cold brew from 1.55; repotting before) | Time limit | Time limit | Finished, 36 min; but "how long it keeps" answered with the steeping time |
|
|
180
|
+
| Explanation (photosynthesis) | Time limit | Finished, 13 min, but thin: no oxygen or water | Finished, 59 min: inputs, outputs and both stages, cited |
|
|
181
|
+
| Opinion (owls) | Time limit | Finished, 38 min | Time limit: its first page covered two of the three cultures asked for |
|
|
182
|
+
| Documentation (venv, official docs) | Finished, 15 min, from a tutorial site | Time limit (30 min) | Finished, 37 min, all from python.org; but the Windows line repeats the create command instead of the activate one |
|
|
181
183
|
|
|
182
184
|
## How it works
|
|
183
185
|
|
|
@@ -216,12 +218,22 @@ flowchart LR
|
|
|
216
218
|
- **Findings must match the page.** A finding that shares too few word pairs with the page text shown so far
|
|
217
219
|
(or has a sentence that does) is sent back once, asking for only what the page says in its own words, and
|
|
218
220
|
one far from anything on the page is refused outright. A small model will otherwise "complete" a list from
|
|
219
|
-
its own knowledge when a page says "follow these 6 steps" and the steps come later.
|
|
221
|
+
its own knowledge when a page says "follow these 6 steps" and the steps come later. The refusal points the way:
|
|
222
|
+
it quotes the one page sentence closest to what the model wrote, to record instead, or names what the parts
|
|
223
|
+
shown never mention ("Japan, Navajo"), so the model reads on.
|
|
220
224
|
- **An objective checklist.** At the start, one short model call splits the objective into a fixed checklist of
|
|
221
225
|
what the result must contain, keeping conditions like "free, open-source" or "three". Each finding names the
|
|
222
226
|
items it serves, the checklist with its findings is in every prompt, and every check goes through these items
|
|
223
227
|
instead of asking the model to split the objective again from memory, which drifted: it once blocked its own
|
|
224
|
-
finish over "migration strategies", which the objective never asked for.
|
|
228
|
+
finish over "migration strategies", which the objective never asked for. Opinion items are shown as written
|
|
229
|
+
at FINISH, not as gaps to fill, and the first search covers the whole objective in one short query, keeping
|
|
230
|
+
its conditions ("official python documentation venv").
|
|
231
|
+
- **A coverage check before finishing.** Each checklist item is checked against the findings in a short call of
|
|
232
|
+
its own, and the code checks the verdict instead of taking it on trust: an item nothing was copied for, fewer
|
|
233
|
+
things than asked for ("only 1 of 3 found"), and things not shown, in words copied from a finding about them,
|
|
234
|
+
to meet a condition such as "open-source". A claim that something is missing is dropped when every word of it is
|
|
235
|
+
already in the findings. With gaps, the FINISH is sent back once, with the next step named ("SEARCH for
|
|
236
|
+
'OnlyOffice free and open-source' to check it, or replace it"), and the next turn starts from a fresh prompt.
|
|
225
237
|
- **Numbered findings.** Findings are numbered in the prompt and listed with every check, and the model names
|
|
226
238
|
the finding that covers each part of the objective ("covered by [2]") instead of just saying "covered".
|
|
227
239
|
- **Knowing when it's done.** After every new finding the model is asked whether the objective is now fully
|
|
@@ -233,12 +245,16 @@ flowchart LR
|
|
|
233
245
|
A part that cannot be found after several tries can be reported as missing instead of blocking for good.
|
|
234
246
|
- **Writing is a separate step.** When the agent finishes, one more model call writes the final result from
|
|
235
247
|
only the objective and the recorded findings, under a short list of rules: no guessing or outside knowledge,
|
|
236
|
-
cite findings by number, give
|
|
237
|
-
the objective asks for an opinion. A small model writes far
|
|
238
|
-
claim stays traceable to a recorded finding.
|
|
239
|
-
|
|
248
|
+
cite findings by number, give as many items as asked for (never repeating one, and saying how many were not
|
|
249
|
+
found), and add a "My view:" paragraph only when the objective asks for an opinion. A small model writes far
|
|
250
|
+
better when that is its only job, and every claim stays traceable to a recorded finding. What no finding
|
|
251
|
+
answers is not left to the model: those checklist items, and things not shown to meet a condition, are left out
|
|
252
|
+
of what it is asked to write, and the code adds them after the result as "Not found in the pages read" and
|
|
253
|
+
"Left out, not shown to meet the conditions". The report flags any number in the final result that appears in
|
|
254
|
+
none of the findings, the most harmful kind of slip in a how-to.
|
|
240
255
|
- **Error pages are recognised.** A page answering 404, 403 and so on counts as a failed visit, not content.
|
|
241
|
-
- **Readable pages.** Navigation menus, footers
|
|
256
|
+
- **Readable pages.** Navigation menus, footers, cookie banners and site notices such as fundraising banners are
|
|
257
|
+
hidden; code blocks and tables are
|
|
242
258
|
never split between parts; links already shown are not repeated. Long pages come with an outline of the
|
|
243
259
|
headings in each part, marking the parts already read, so the agent can jump to the part it needs instead of
|
|
244
260
|
reading in order.
|
|
@@ -271,12 +287,13 @@ Measured on an Intel i5-9500 (6 cores, no GPU) with Qwen2.5-7B-Instruct Q4_K_M a
|
|
|
271
287
|
| Follow-up on the same page (finding recorded, cheap retry) | 35–60 s |
|
|
272
288
|
| Next part of a page, or a new page appended | 100–280 s |
|
|
273
289
|
| First turn of a run | 45–110 s |
|
|
274
|
-
| Fresh prompt
|
|
290
|
+
| Fresh prompt (context budget reached, or after a coverage send-back) | 160–540 s (longest with long pages) |
|
|
291
|
+
| Coverage check before finishing (all checklist items) | about 1–3 min |
|
|
275
292
|
| Writing the final result (once, at the end) | 50–190 s, depending on how much was found |
|
|
276
293
|
|
|
277
|
-
Whole runs vary with the pages a search turns up. In the
|
|
278
|
-
minutes of model time
|
|
279
|
-
GPU or a smaller model will be much faster.
|
|
294
|
+
Whole runs vary with the pages a search turns up. In the regression runs since 1.53, a factual question took 13 to
|
|
295
|
+
19 minutes of model time; the list, comparison, how-to, opinion and documentation tasks 21 to 44 when they finished;
|
|
296
|
+
and the explanation 13 to 59. A GPU or a smaller model will be much faster.
|
|
280
297
|
|
|
281
298
|
## FAQ
|
|
282
299
|
|
|
@@ -311,18 +328,19 @@ turn that brings in a new page takes a few minutes. See [Performance](#performan
|
|
|
311
328
|
research, an opinion from several sources, a factual question, a comparison, a how-to, a list and an
|
|
312
329
|
explanation of a topic. Each one
|
|
313
330
|
exposed something that did not generalise and was fixed; other kinds of tasks may expose more.
|
|
314
|
-
- **
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
331
|
+
- **Judging whether a finding covers an item is the weakest area.** The model's verdict is unreliable both ways:
|
|
332
|
+
on 1.53 the explanation finished from one overview paragraph without oxygen or water, and in the regression runs
|
|
333
|
+
since 1.54 about half of the coverage check's send-backs were for gaps that were not real ("missing official
|
|
334
|
+
documentation" on a comparison that did not ask for it, "H2O, O2" already recorded). The code now verifies what
|
|
335
|
+
it can (an item nothing answers, a count, word-for-word proof of a condition), but each wrong send-back still
|
|
336
|
+
costs a finish on this hardware, since a send-back costs 8–10 minutes.
|
|
320
337
|
- **Conditions in the objective.** A small model tends to drop conditions such as "open source" or "using the
|
|
321
338
|
official documentation": a list of open-source office suites once included FreeOffice (free but not open
|
|
322
339
|
source), and a task that asked for the official Python documentation used a tutorial site. The objective
|
|
323
|
-
checklist keeps the conditions in view (the documentation task
|
|
324
|
-
|
|
325
|
-
|
|
340
|
+
checklist keeps the conditions in view (the documentation task uses python.org since 1.55), and a thing not
|
|
341
|
+
shown in the findings to meet a condition is left out of the result and listed after it. The check is strict:
|
|
342
|
+
on 1.57 it sent back three correct open-source suites because no words showed them to be "free". Check the
|
|
343
|
+
result against any conditions you set.
|
|
326
344
|
- **A small model's judgement is the ceiling.** It sometimes drifts to loosely related pages, prefers
|
|
327
345
|
secondary sources or stays with one source too long, and results vary with the first pages a search turns
|
|
328
346
|
up; every finding is in `research_report.md` regardless.
|
|
@@ -331,8 +349,9 @@ turn that brings in a new page takes a few minutes. See [Performance](#performan
|
|
|
331
349
|
minutes, but with thin findings and without naming what it could not find, so check the result against the
|
|
332
350
|
objective.
|
|
333
351
|
- **Check the citations.** The final result is told to use only recorded findings, but a 7B model sometimes
|
|
334
|
-
puts the wrong number on a citation, adds a line no finding supports
|
|
335
|
-
|
|
352
|
+
puts the wrong number on a citation, adds a line no finding supports, leaves out a step or misreads a part of
|
|
353
|
+
the question (on 1.57 it answered "how long it keeps in the fridge" with the steeping time), so verify a claim
|
|
354
|
+
against the listed findings before relying on it.
|
|
336
355
|
- **Some sites refuse automated browsers** (HTTP 403). The agent respects that and does not try to disguise
|
|
337
356
|
itself; it moves on to other sources.
|
|
338
357
|
- **Reading only.** The agent searches, opens pages and reads them. It does not click, fill in forms or sign in.
|
|
@@ -349,7 +368,13 @@ turn that brings in a new page takes a few minutes. See [Performance](#performan
|
|
|
349
368
|
- [ ] Let very strict objectives end with the gaps named instead of searching indefinitely (they finish since 1.50; naming the gaps is still open)
|
|
350
369
|
- [x] Measure every change on a regression suite of seven kinds of task (1.53)
|
|
351
370
|
- [x] Keep a fixed checklist of the objective's parts instead of re-splitting it at every check (1.53)
|
|
352
|
-
- [ ] Check that a finding really covers its checklist item, including conditions like "open source"
|
|
371
|
+
- [ ] Check that a finding really covers its checklist item, including conditions like "open source" (partly, since
|
|
372
|
+
1.57: a coverage check before finishing, with what the code can verify)
|
|
373
|
+
- [ ] Send the agent back only for gaps the code verifies, and let the model's other verdicts only shape the final
|
|
374
|
+
result (the next step after 1.57)
|
|
375
|
+
- [ ] Rewind dead ends: save the conversation before an expensive step such as reading a long page, and if it
|
|
376
|
+
leads nowhere, return to that point with a short note instead of carrying the unused page text in every later
|
|
377
|
+
prompt (LM Studio reuses its cache up to the saved point)
|
|
353
378
|
- [ ] Try more kinds of objectives (seven so far) and adjust the rules that don't generalise
|
|
354
379
|
- [ ] Make fresh prompts (the slowest kind of turn) cheaper still (31% cheaper since 1.34)
|
|
355
380
|
- [ ] Interacting with pages (clicking, forms) for tasks beyond reading
|
|
@@ -358,7 +383,7 @@ Ideas and requests are welcome in [issues](https://github.com/SnowFXXX/LocalAgen
|
|
|
358
383
|
|
|
359
384
|
## Testing
|
|
360
385
|
|
|
361
|
-
The test suite runs in
|
|
386
|
+
The test suite runs in a few seconds and needs neither LM Studio nor a browser: the model and the website
|
|
362
387
|
are replaced by scripted fakes, including an end-to-end run of the main loop.
|
|
363
388
|
|
|
364
389
|
```bash
|
|
@@ -384,8 +409,12 @@ Each run gets a folder in `regression_runs/` with every task's report, journal,
|
|
|
384
409
|
trace, and a `summary.md` that is updated after each task: whether it finished, turns, model time, how many
|
|
385
410
|
checklist items got findings, which checks fired, and problems found by simple word checks (missing answers,
|
|
386
411
|
missed conditions such as a non-open-source item, uncited paragraphs, numbers missing from the findings, a
|
|
387
|
-
missing opinion).
|
|
388
|
-
|
|
412
|
+
missing opinion). It also flags a task that fails again on the same site as in the earlier run: one site that
|
|
413
|
+
cannot answer part of an objective can decide a task whatever the agent does (the repotting how-to went to the same
|
|
414
|
+
guide in three runs, which is why the core how-to is now the cold brew one). `--suite all` adds six more tasks,
|
|
415
|
+
including the earlier how-to, `--only` runs some of them, and `--rescore` scores an earlier run again without the
|
|
416
|
+
model. Every step since 1.53 and its results are in
|
|
417
|
+
[docs/regression-history.md](https://github.com/SnowFXXX/LocalAgentBrowser/blob/main/docs/regression-history.md).
|
|
389
418
|
|
|
390
419
|
## Contributing
|
|
391
420
|
|
|
@@ -394,8 +423,10 @@ the [Code of Conduct](https://github.com/SnowFXXX/LocalAgentBrowser/blob/main/CO
|
|
|
394
423
|
|
|
395
424
|
## Project history
|
|
396
425
|
|
|
397
|
-
Every version is a tagged commit, and [CHANGELOG.md](https://github.com/SnowFXXX/LocalAgentBrowser/blob/main/CHANGELOG.md) describes what changed in each one and
|
|
398
|
-
why, with the measurements behind the decisions.
|
|
426
|
+
Every released version is a tagged commit, and [CHANGELOG.md](https://github.com/SnowFXXX/LocalAgentBrowser/blob/main/CHANGELOG.md) describes what changed in each one and
|
|
427
|
+
why, with the measurements behind the decisions. Versions 1.54 to 1.56 were internal steps, each measured on the
|
|
428
|
+
regression suite and released together as 1.57; their results are in
|
|
429
|
+
[docs/regression-history.md](https://github.com/SnowFXXX/LocalAgentBrowser/blob/main/docs/regression-history.md).
|
|
399
430
|
|
|
400
431
|
## Acknowledgements
|
|
401
432
|
|