lyrenth-agents 0.1.0__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.
@@ -0,0 +1,8 @@
1
+ __pycache__/
2
+ *.pyc
3
+ build/
4
+ dist/
5
+ *.egg-info/
6
+ .venv/
7
+ .pytest_cache/
8
+ .env
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Aleksma AI, Inc.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,156 @@
1
+ Metadata-Version: 2.5
2
+ Name: lyrenth-agents
3
+ Version: 0.1.0
4
+ Summary: A library of small agents that read the web through Lyrenth: pick a recipe, give it URLs, get a cited answer.
5
+ Project-URL: Homepage, https://lyrenth.com
6
+ Project-URL: Documentation, https://lyrenth.com/docs/quickstart
7
+ Author: Lyrenth
8
+ License-Expression: MIT
9
+ License-File: LICENSE
10
+ Keywords: agents,aidocument,citations,llm,lyrenth,prompt,recipes,web
11
+ Classifier: Environment :: Console
12
+ Classifier: License :: OSI Approved :: MIT License
13
+ Classifier: Operating System :: OS Independent
14
+ Classifier: Programming Language :: Python :: 3
15
+ Requires-Python: >=3.9
16
+ Requires-Dist: lyrenth>=0.1.1
17
+ Description-Content-Type: text/markdown
18
+
19
+ # lyrenth-agents
20
+
21
+ Ten agents that read the web and finish the job.
22
+
23
+ Give one a few URLs and it hands back the thing you actually wanted: a
24
+ comparison table, a brief on a company, the answer to a documentation
25
+ question with the heading it came from, a sheet you open in Excel. Every
26
+ claim carries the number of the page it came from, and every page that
27
+ could not be read is named with the reason.
28
+
29
+ The reading goes through [Lyrenth](https://lyrenth.com), which serves each
30
+ page as clean text instead of HTML, so the pages arrive without the menus,
31
+ banners, scripts and markup.
32
+
33
+ ```bash
34
+ export LYRENTH_API_KEY=... # free key: https://lyrenth.com/signup
35
+
36
+ uvx lyrenth-agents compare \
37
+ https://en.wikipedia.org/wiki/PostgreSQL \
38
+ https://en.wikipedia.org/wiki/MySQL
39
+ ```
40
+
41
+ With that key alone, the agent reads the pages and prints the finished
42
+ prompt with its numbered sources, ready to paste into whichever assistant
43
+ you already use. Point it at a model and it answers on its own:
44
+
45
+ ```bash
46
+ export LLM_BASE_URL=https://api.example.com/v1 # any OpenAI-compatible endpoint
47
+ export LLM_MODEL=your-model-name
48
+ export LLM_API_KEY=...
49
+ ```
50
+
51
+ ## The ten
52
+
53
+ | Command | Give it | Get back |
54
+ |---|---|---|
55
+ | `compare` | Two or more product pages | One table of what is actually different |
56
+ | `brief` | A company's own pages | What they do, who they sell to, and what their pages never answer |
57
+ | `answers -q "..."` | The documentation that should hold the answer | The answer with the page and heading behind every line |
58
+ | `research -q "..."` | The pages you trust | Plain prose with a number on every claim |
59
+ | `summarise` | A long article | What it claims, what that rests on, what it leaves out |
60
+ | `extract` | Several pages of the same kind | One row per page, a column for every shared field |
61
+ | `terms` | A terms page or a privacy policy | What you agree to, what data is taken, what happens in a dispute |
62
+ | `people` | A team page and a careers page | Who the pages name, and what the company is hiring for |
63
+ | `integrations` | The pages that say what a product connects to | The tools, grouped, and how firmly each one is claimed |
64
+ | `digest` | The last few days of articles | What happened, what is new, where the sources disagree |
65
+
66
+ `lyrenth-agents --list` prints the same list with an example command for
67
+ each one. Every agent also has a page at
68
+ [lyrenth.com/agents](https://lyrenth.com/agents) showing a real run.
69
+
70
+ ## A real run
71
+
72
+ Against the live API on 21 September 2026, unedited. The progress lines go
73
+ to stderr, the answer to stdout.
74
+
75
+ ```text
76
+ $ uvx lyrenth-agents compare https://en.wikipedia.org/wiki/PostgreSQL https://en.wikipedia.org/wiki/MySQL
77
+ recipe compare: Product comparison
78
+ read [1] PostgreSQL - Wikipedia 30,000 tokens https://en.wikipedia.org/wiki/PostgreSQL
79
+ read [2] MySQL - Wikipedia 30,000 tokens https://en.wikipedia.org/wiki/MySQL
80
+ context 60,000 tokens from 2 sources (raw HTML would be 412,333)
81
+
82
+ | Feature | PostgreSQL | MySQL |
83
+ | :--- | :--- | :--- |
84
+ | Software Type | Free and open-source object relational database management system [1] | free and open-source relational database management system (RDBMS) [2] |
85
+ | License | PostgreSQL License (free and open-source, permissive) [1] | GPLv2 or proprietary [2] |
86
+ | Developer | PostgreSQL Global Development Group [1] | Oracle Corporation [2] |
87
+ | Initial Release | 8 July 1996; 30 years ago (1996-07-08) [1] | 23 May 1995; 31 years ago (1995-05-23) [2] |
88
+ | Stable Release | 18.6 / 13 August 2026 [1] | 26.7.0 / 28 July 2026 [2] |
89
+ | Written In | C (and C++ for the LLVM dependency) [1] | C, C++ [2] |
90
+ ...
91
+ ```
92
+
93
+ Two encyclopedia articles that weigh 412,333 tokens as raw HTML arrived as
94
+ 60,000 tokens of text, and the answer cites which of the two every cell
95
+ came from.
96
+
97
+ ## What it does with the pages
98
+
99
+ 1. **Reads text, not markup.** Each page arrives as an AIDocument: the
100
+ content, its canonical URL, when it was read, and what it costs in
101
+ tokens.
102
+ 2. **Shares the budget between the pages.** Every page gets an equal share
103
+ and a short page gives its leftover back to the long ones, so a
104
+ comparison never comes back with one product filled in and the other
105
+ column empty.
106
+ 3. **Reads each page once.** A mobile copy, a tracking parameter or an old
107
+ redirect resolves to the same canonical URL and is dropped as a
108
+ duplicate.
109
+ 4. **Keeps provenance.** Title, canonical URL and read time go into the
110
+ prompt with the source number, which is what makes the citations
111
+ checkable.
112
+ 5. **Fails out loud.** A page that could not be read is listed with the
113
+ reason, and a citation pointing at a source number that does not exist
114
+ is flagged.
115
+
116
+ ## Write your own
117
+
118
+ A recipe is data: the instructions for the model and the shape of the
119
+ output. Register one and it runs on the same engine.
120
+
121
+ ```python
122
+ from lyrenth_agents import Recipe, get, register, run
123
+
124
+ register(
125
+ Recipe(
126
+ slug="changelog",
127
+ name="Release notes",
128
+ category="content",
129
+ tagline="Turn release pages into one list of what changed.",
130
+ what_you_give="The release or changelog pages, newest first.",
131
+ what_you_get="One list of changes, newest first, with the page each came from.",
132
+ system_prompt="You read release pages and list what changed...",
133
+ output_hint="One list, newest first, with a source number on every line.",
134
+ example_urls=["https://example.com/releases"],
135
+ )
136
+ )
137
+
138
+ result = run(get("changelog"), ["https://example.com/releases"])
139
+ print(result.answer or result.prompt)
140
+ ```
141
+
142
+ ## Options
143
+
144
+ | Flag | What it does |
145
+ |---|---|
146
+ | `--list` | The recipes, with an example command for each |
147
+ | `-q`, `--question` | What to ask of the pages (`answers` and `research` need one) |
148
+ | `--sources-only` | Print the numbered sources and stop |
149
+ | `--json` | The whole result as JSON, including the prompt |
150
+ | `--budget` | Token budget for all the pages together |
151
+ | `--fresh` | Ask Lyrenth for a fresh fetch instead of the stored page |
152
+ | `--model-url`, `--model` | The model endpoint, instead of the environment |
153
+
154
+ ## Licence
155
+
156
+ MIT. See [LICENSE](LICENSE).
@@ -0,0 +1,138 @@
1
+ # lyrenth-agents
2
+
3
+ Ten agents that read the web and finish the job.
4
+
5
+ Give one a few URLs and it hands back the thing you actually wanted: a
6
+ comparison table, a brief on a company, the answer to a documentation
7
+ question with the heading it came from, a sheet you open in Excel. Every
8
+ claim carries the number of the page it came from, and every page that
9
+ could not be read is named with the reason.
10
+
11
+ The reading goes through [Lyrenth](https://lyrenth.com), which serves each
12
+ page as clean text instead of HTML, so the pages arrive without the menus,
13
+ banners, scripts and markup.
14
+
15
+ ```bash
16
+ export LYRENTH_API_KEY=... # free key: https://lyrenth.com/signup
17
+
18
+ uvx lyrenth-agents compare \
19
+ https://en.wikipedia.org/wiki/PostgreSQL \
20
+ https://en.wikipedia.org/wiki/MySQL
21
+ ```
22
+
23
+ With that key alone, the agent reads the pages and prints the finished
24
+ prompt with its numbered sources, ready to paste into whichever assistant
25
+ you already use. Point it at a model and it answers on its own:
26
+
27
+ ```bash
28
+ export LLM_BASE_URL=https://api.example.com/v1 # any OpenAI-compatible endpoint
29
+ export LLM_MODEL=your-model-name
30
+ export LLM_API_KEY=...
31
+ ```
32
+
33
+ ## The ten
34
+
35
+ | Command | Give it | Get back |
36
+ |---|---|---|
37
+ | `compare` | Two or more product pages | One table of what is actually different |
38
+ | `brief` | A company's own pages | What they do, who they sell to, and what their pages never answer |
39
+ | `answers -q "..."` | The documentation that should hold the answer | The answer with the page and heading behind every line |
40
+ | `research -q "..."` | The pages you trust | Plain prose with a number on every claim |
41
+ | `summarise` | A long article | What it claims, what that rests on, what it leaves out |
42
+ | `extract` | Several pages of the same kind | One row per page, a column for every shared field |
43
+ | `terms` | A terms page or a privacy policy | What you agree to, what data is taken, what happens in a dispute |
44
+ | `people` | A team page and a careers page | Who the pages name, and what the company is hiring for |
45
+ | `integrations` | The pages that say what a product connects to | The tools, grouped, and how firmly each one is claimed |
46
+ | `digest` | The last few days of articles | What happened, what is new, where the sources disagree |
47
+
48
+ `lyrenth-agents --list` prints the same list with an example command for
49
+ each one. Every agent also has a page at
50
+ [lyrenth.com/agents](https://lyrenth.com/agents) showing a real run.
51
+
52
+ ## A real run
53
+
54
+ Against the live API on 21 September 2026, unedited. The progress lines go
55
+ to stderr, the answer to stdout.
56
+
57
+ ```text
58
+ $ uvx lyrenth-agents compare https://en.wikipedia.org/wiki/PostgreSQL https://en.wikipedia.org/wiki/MySQL
59
+ recipe compare: Product comparison
60
+ read [1] PostgreSQL - Wikipedia 30,000 tokens https://en.wikipedia.org/wiki/PostgreSQL
61
+ read [2] MySQL - Wikipedia 30,000 tokens https://en.wikipedia.org/wiki/MySQL
62
+ context 60,000 tokens from 2 sources (raw HTML would be 412,333)
63
+
64
+ | Feature | PostgreSQL | MySQL |
65
+ | :--- | :--- | :--- |
66
+ | Software Type | Free and open-source object relational database management system [1] | free and open-source relational database management system (RDBMS) [2] |
67
+ | License | PostgreSQL License (free and open-source, permissive) [1] | GPLv2 or proprietary [2] |
68
+ | Developer | PostgreSQL Global Development Group [1] | Oracle Corporation [2] |
69
+ | Initial Release | 8 July 1996; 30 years ago (1996-07-08) [1] | 23 May 1995; 31 years ago (1995-05-23) [2] |
70
+ | Stable Release | 18.6 / 13 August 2026 [1] | 26.7.0 / 28 July 2026 [2] |
71
+ | Written In | C (and C++ for the LLVM dependency) [1] | C, C++ [2] |
72
+ ...
73
+ ```
74
+
75
+ Two encyclopedia articles that weigh 412,333 tokens as raw HTML arrived as
76
+ 60,000 tokens of text, and the answer cites which of the two every cell
77
+ came from.
78
+
79
+ ## What it does with the pages
80
+
81
+ 1. **Reads text, not markup.** Each page arrives as an AIDocument: the
82
+ content, its canonical URL, when it was read, and what it costs in
83
+ tokens.
84
+ 2. **Shares the budget between the pages.** Every page gets an equal share
85
+ and a short page gives its leftover back to the long ones, so a
86
+ comparison never comes back with one product filled in and the other
87
+ column empty.
88
+ 3. **Reads each page once.** A mobile copy, a tracking parameter or an old
89
+ redirect resolves to the same canonical URL and is dropped as a
90
+ duplicate.
91
+ 4. **Keeps provenance.** Title, canonical URL and read time go into the
92
+ prompt with the source number, which is what makes the citations
93
+ checkable.
94
+ 5. **Fails out loud.** A page that could not be read is listed with the
95
+ reason, and a citation pointing at a source number that does not exist
96
+ is flagged.
97
+
98
+ ## Write your own
99
+
100
+ A recipe is data: the instructions for the model and the shape of the
101
+ output. Register one and it runs on the same engine.
102
+
103
+ ```python
104
+ from lyrenth_agents import Recipe, get, register, run
105
+
106
+ register(
107
+ Recipe(
108
+ slug="changelog",
109
+ name="Release notes",
110
+ category="content",
111
+ tagline="Turn release pages into one list of what changed.",
112
+ what_you_give="The release or changelog pages, newest first.",
113
+ what_you_get="One list of changes, newest first, with the page each came from.",
114
+ system_prompt="You read release pages and list what changed...",
115
+ output_hint="One list, newest first, with a source number on every line.",
116
+ example_urls=["https://example.com/releases"],
117
+ )
118
+ )
119
+
120
+ result = run(get("changelog"), ["https://example.com/releases"])
121
+ print(result.answer or result.prompt)
122
+ ```
123
+
124
+ ## Options
125
+
126
+ | Flag | What it does |
127
+ |---|---|
128
+ | `--list` | The recipes, with an example command for each |
129
+ | `-q`, `--question` | What to ask of the pages (`answers` and `research` need one) |
130
+ | `--sources-only` | Print the numbered sources and stop |
131
+ | `--json` | The whole result as JSON, including the prompt |
132
+ | `--budget` | Token budget for all the pages together |
133
+ | `--fresh` | Ask Lyrenth for a fresh fetch instead of the stored page |
134
+ | `--model-url`, `--model` | The model endpoint, instead of the environment |
135
+
136
+ ## Licence
137
+
138
+ MIT. See [LICENSE](LICENSE).
@@ -0,0 +1,30 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "lyrenth-agents"
7
+ version = "0.1.0"
8
+ description = "A library of small agents that read the web through Lyrenth: pick a recipe, give it URLs, get a cited answer."
9
+ requires-python = ">=3.9"
10
+ license = "MIT"
11
+ authors = [{ name = "Lyrenth" }]
12
+ keywords = ["agents", "recipes", "citations", "llm", "web", "lyrenth", "aidocument", "prompt"]
13
+ classifiers = [
14
+ "Programming Language :: Python :: 3",
15
+ "License :: OSI Approved :: MIT License",
16
+ "Operating System :: OS Independent",
17
+ "Environment :: Console",
18
+ ]
19
+ dependencies = ["lyrenth>=0.1.1"]
20
+ readme = "README.md"
21
+
22
+ [project.scripts]
23
+ lyrenth-agents = "lyrenth_agents.cli:main"
24
+
25
+ [project.urls]
26
+ Homepage = "https://lyrenth.com"
27
+ Documentation = "https://lyrenth.com/docs/quickstart"
28
+
29
+ [tool.hatch.build.targets.wheel]
30
+ packages = ["src/lyrenth_agents"]
@@ -0,0 +1,72 @@
1
+ """A library of small agents that read the web through Lyrenth.
2
+
3
+ One engine, many recipes. A recipe is data: the instructions for the model and
4
+ the shape of the output. The engine reads the pages, numbers them so they can
5
+ be cited, and either asks a model or hands you the finished prompt.
6
+
7
+ from lyrenth_agents import get, run
8
+
9
+ result = run(get("some-recipe"), ["https://example.com/page"])
10
+ print(result.answer or result.prompt)
11
+
12
+ Reading goes through Lyrenth (LYRENTH_API_KEY, free key at
13
+ https://lyrenth.com/signup). A model is optional: with none configured,
14
+ `result.answer` is None and `result.prompt` holds the finished prompt, ready
15
+ to paste into any assistant. Configure one with LLM_BASE_URL and LLM_MODEL
16
+ (any OpenAI-compatible endpoint) to have the engine answer directly.
17
+ """
18
+
19
+ __version__ = "0.1.0"
20
+
21
+ from .engine import ( # noqa: E402
22
+ AgentResult,
23
+ Gathered,
24
+ ModelError,
25
+ Skipped,
26
+ Source,
27
+ answer_into,
28
+ build_messages,
29
+ build_prompt,
30
+ build_sources_block,
31
+ call_model,
32
+ check_citations,
33
+ gather,
34
+ model_is_configured,
35
+ read_for,
36
+ run,
37
+ )
38
+ from .recipes import ( # noqa: E402
39
+ REGISTRY,
40
+ Recipe,
41
+ UnknownRecipe,
42
+ all_recipes,
43
+ get,
44
+ load_error,
45
+ register,
46
+ )
47
+
48
+ __all__ = [
49
+ "AgentResult",
50
+ "Gathered",
51
+ "ModelError",
52
+ "REGISTRY",
53
+ "Recipe",
54
+ "Skipped",
55
+ "Source",
56
+ "UnknownRecipe",
57
+ "all_recipes",
58
+ "answer_into",
59
+ "build_messages",
60
+ "build_prompt",
61
+ "build_sources_block",
62
+ "call_model",
63
+ "check_citations",
64
+ "gather",
65
+ "get",
66
+ "load_error",
67
+ "model_is_configured",
68
+ "read_for",
69
+ "register",
70
+ "run",
71
+ "__version__",
72
+ ]