@gavin-hu/my-pi-agent 0.17.0 → 0.19.0
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.
- package/README.md +61 -45
- package/README.zh-CN.md +54 -42
- package/docs/extensions/README.md +34 -0
- package/docs/extensions/board.md +344 -0
- package/{extensions/bytefly/README.md → docs/extensions/bytefly.md} +465 -416
- package/{extensions/check/README.md → docs/extensions/check.md} +83 -68
- package/{extensions/context/README.md → docs/extensions/context.md} +40 -23
- package/docs/extensions/file-browse.md +554 -0
- package/{extensions/file-open/README.md → docs/extensions/file-open.md} +31 -23
- package/{extensions/file-read/README.md → docs/extensions/file-read.md} +47 -55
- package/{extensions/goal/README.md → docs/extensions/goal.md} +115 -131
- package/{extensions/job/README.md → docs/extensions/job.md} +66 -53
- package/{extensions/memory/README.md → docs/extensions/memory.md} +74 -63
- package/docs/extensions/plan.md +976 -0
- package/{extensions/question/README.md → docs/extensions/question.md} +54 -28
- package/{extensions/rewind/README.md → docs/extensions/rewind.md} +115 -122
- package/docs/extensions/session-bus.md +285 -0
- package/{extensions/subagent/README.md → docs/extensions/subagent.md} +166 -119
- package/docs/extensions/team.md +226 -0
- package/{extensions/todo/README.md → docs/extensions/todo.md} +85 -88
- package/{extensions/watch/README.md → docs/extensions/watch.md} +60 -38
- package/{extensions/web-access/README.md → docs/extensions/web-access.md} +93 -50
- package/{extensions/wechat/README.md → docs/extensions/wechat.md} +275 -192
- package/{extensions/worktree/README.md → docs/extensions/worktree.md} +115 -72
- package/extensions/board/commands.ts +87 -0
- package/extensions/board/config.ts +36 -0
- package/extensions/board/format.ts +72 -0
- package/extensions/board/index.ts +40 -0
- package/extensions/board/input.ts +54 -0
- package/extensions/board/join.ts +42 -0
- package/extensions/board/page.ts +312 -0
- package/extensions/board/result.ts +99 -0
- package/extensions/board/rows.ts +48 -0
- package/extensions/board/schema.ts +75 -0
- package/extensions/board/seat.ts +29 -0
- package/extensions/board/snapshot.ts +41 -0
- package/extensions/board/tools.ts +279 -0
- package/extensions/board/transport/router.ts +172 -0
- package/extensions/board/transport/server.ts +149 -0
- package/extensions/board/types.ts +54 -0
- package/extensions/board/view/actions.ts +306 -0
- package/extensions/board/view/client.ts +41 -0
- package/extensions/board/view/keys.ts +121 -0
- package/extensions/board/view/live.ts +397 -0
- package/extensions/board/view/page.ts +158 -0
- package/extensions/board/view/render.ts +496 -0
- package/extensions/board/view/styles.ts +211 -0
- package/extensions/board/view/team.ts +305 -0
- package/extensions/board/writes.ts +99 -0
- package/extensions/bytefly/notify/types.ts +1 -1
- package/extensions/bytefly/panel/commands.ts +40 -7
- package/extensions/bytefly/panel/settings-runtime.ts +0 -6
- package/extensions/bytefly/panel/settings.ts +11 -21
- package/extensions/bytefly/panel/tui/settings-view.ts +1 -1
- package/extensions/bytefly/picker/discovery.ts +0 -2
- package/extensions/bytefly/picker/types.ts +0 -2
- package/extensions/bytefly/update/check.ts +39 -0
- package/extensions/bytefly/update/format.ts +15 -0
- package/extensions/bytefly/update/register.ts +73 -34
- package/extensions/bytefly/update/state.ts +6 -3
- package/extensions/context/tui.ts +1 -1
- package/extensions/file-browse/{config.ts → config/config.ts} +13 -4
- package/extensions/file-browse/{files.ts → files/files.ts} +1 -14
- package/extensions/file-browse/{paths.ts → files/paths.ts} +1 -1
- package/extensions/file-browse/{git.ts → git/git.ts} +10 -3
- package/extensions/file-browse/index.ts +4 -4
- package/extensions/file-browse/{live.ts → live/live.ts} +54 -82
- package/extensions/file-browse/live/rev.ts +42 -0
- package/extensions/file-browse/{router.ts → transport/router.ts} +44 -17
- package/extensions/file-browse/transport/server.ts +110 -0
- package/extensions/file-browse/view/chrome.ts +83 -0
- package/extensions/file-browse/{client.ts → view/client.ts} +63 -1
- package/extensions/file-browse/view/diff-html.ts +94 -0
- package/extensions/file-browse/{html.ts → view/html.ts} +32 -158
- package/extensions/file-browse/{icons.ts → view/icons.ts} +1 -1
- package/extensions/file-browse/{live-client.ts → view/live-client.ts} +47 -1
- package/extensions/file-browse/{markdown.ts → view/markdown.ts} +7 -7
- package/extensions/file-browse/{raw-html.ts → view/raw-html.ts} +1 -1
- package/extensions/file-browse/{styles.ts → view/styles.ts} +31 -5
- package/extensions/file-browse/{tree.ts → view/tree.ts} +1 -1
- package/extensions/file-browse/{urls.ts → view/urls.ts} +1 -1
- package/extensions/file-read/schema.ts +2 -1
- package/extensions/goal/plan-route.ts +8 -2
- package/extensions/job/index.ts +15 -7
- package/extensions/memory/store.ts +12 -5
- package/extensions/plan/blocks.ts +23 -2
- package/extensions/plan/commands.ts +77 -21
- package/extensions/plan/feedback.ts +409 -63
- package/extensions/plan/index.ts +7 -5
- package/extensions/plan/plan-index.ts +44 -10
- package/extensions/plan/plan-text.ts +51 -24
- package/extensions/plan/plans.ts +162 -57
- package/extensions/plan/policy.ts +20 -12
- package/extensions/plan/review-prompt.ts +93 -0
- package/extensions/plan/review.ts +51 -95
- package/extensions/plan/runtime.ts +22 -10
- package/extensions/plan/sections.ts +112 -0
- package/extensions/plan/steps.ts +63 -95
- package/extensions/plan/tools/enter.ts +8 -3
- package/extensions/plan/tools/exit.ts +13 -19
- package/extensions/plan/tools/write.ts +8 -3
- package/extensions/plan/tools.ts +1 -1
- package/extensions/plan/tui.ts +29 -15
- package/extensions/plan/types.ts +29 -3
- package/extensions/plan/web-chrome.ts +2 -1
- package/extensions/plan/web-client.ts +122 -178
- package/extensions/plan/web-collab.ts +207 -0
- package/extensions/plan/web-comments.ts +269 -0
- package/extensions/plan/web-page.ts +96 -17
- package/extensions/plan/web-router.ts +109 -47
- package/extensions/plan/web-share-session.ts +191 -0
- package/extensions/plan/web-share.ts +169 -0
- package/extensions/plan/web-streams.ts +124 -0
- package/extensions/plan/web-tokens.ts +63 -0
- package/extensions/plan/web.ts +245 -151
- package/extensions/question/dialogs.ts +91 -1
- package/extensions/question/tools.ts +2 -1
- package/extensions/rewind/{commands.ts → commands/commands.ts} +5 -5
- package/extensions/rewind/{review.ts → commands/review.ts} +13 -13
- package/extensions/rewind/{rewind.ts → commands/rewind.ts} +6 -6
- package/extensions/rewind/{config.ts → config/config.ts} +1 -1
- package/extensions/rewind/index.ts +3 -3
- package/extensions/rewind/{policy.ts → state/policy.ts} +4 -4
- package/extensions/rewind/{runtime.ts → state/runtime.ts} +11 -11
- package/extensions/rewind/{snapshot-run.ts → state/snapshot-run.ts} +1 -1
- package/extensions/rewind/{timeline.ts → state/timeline.ts} +2 -2
- package/extensions/rewind/{format.ts → text/format.ts} +3 -3
- package/extensions/rewind/{git.ts → transport/git.ts} +2 -2
- package/extensions/rewind/{restore.ts → transport/restore.ts} +2 -2
- package/extensions/rewind/{snapshot.ts → transport/snapshot.ts} +1 -1
- package/extensions/rewind/{store.ts → transport/store.ts} +1 -1
- package/extensions/rewind/{checklist.ts → view/checklist.ts} +6 -6
- package/extensions/rewind/{hunk-picker.ts → view/hunk-picker.ts} +8 -8
- package/extensions/rewind/{path-picker.ts → view/path-picker.ts} +7 -7
- package/extensions/rewind/{review-tui.ts → view/review-tui.ts} +11 -11
- package/extensions/rewind/{rewind-tui.ts → view/rewind-tui.ts} +17 -11
- package/extensions/rewind/{status.ts → view/status.ts} +4 -4
- package/extensions/session-bus/commands.ts +113 -0
- package/extensions/session-bus/format.ts +101 -0
- package/extensions/session-bus/index.ts +75 -0
- package/extensions/session-bus/join-request.ts +40 -0
- package/extensions/session-bus/mail-watch.ts +134 -0
- package/extensions/session-bus/notice.ts +86 -0
- package/extensions/session-bus/overlap.ts +36 -0
- package/extensions/session-bus/protocol.ts +104 -0
- package/extensions/session-bus/resolve.ts +67 -0
- package/extensions/session-bus/result.ts +208 -0
- package/extensions/session-bus/rows.ts +171 -0
- package/extensions/session-bus/runtime.ts +466 -0
- package/extensions/session-bus/store.ts +365 -0
- package/extensions/session-bus/tools.ts +192 -0
- package/extensions/session-bus/tui.ts +394 -0
- package/extensions/session-bus/types.ts +98 -0
- package/extensions/subagent/agents.ts +9 -8
- package/extensions/subagent/invocation.ts +4 -2
- package/extensions/team/commands.ts +112 -0
- package/extensions/team/dispatch.ts +133 -0
- package/extensions/team/format.ts +105 -0
- package/extensions/team/index.ts +33 -0
- package/extensions/team/schema.ts +29 -0
- package/extensions/team/tools.ts +246 -0
- package/extensions/team/types.ts +48 -0
- package/extensions/watch/index.ts +15 -9
- package/extensions/web-access/fetch/page.ts +4 -1
- package/extensions/web-access/fetch/structured.ts +447 -0
- package/extensions/web-access/fetch/tool.ts +2 -1
- package/extensions/web-access/search/tool.ts +2 -1
- package/extensions/wechat/bridge.ts +76 -92
- package/extensions/wechat/{commands.ts → commands/commands.ts} +26 -18
- package/extensions/wechat/{doctor.ts → commands/doctor.ts} +5 -5
- package/extensions/wechat/{history.ts → commands/history.ts} +1 -1
- package/extensions/wechat/{login.ts → commands/login.ts} +3 -3
- package/extensions/wechat/{slash.ts → commands/slash.ts} +38 -2
- package/extensions/wechat/dialog/channels.ts +136 -0
- package/extensions/wechat/{interaction.ts → dialog/interaction.ts} +66 -51
- package/extensions/wechat/{prompt.ts → dialog/prompt.ts} +40 -25
- package/extensions/wechat/{remote-ui.ts → dialog/remote-ui.ts} +1 -1
- package/extensions/wechat/index.ts +10 -10
- package/extensions/wechat/{admission.ts → peer/admission.ts} +2 -2
- package/extensions/wechat/{peer-session.ts → peer/peer-session.ts} +2 -2
- package/extensions/wechat/{peer-worker.ts → peer/peer-worker.ts} +119 -56
- package/extensions/wechat/{presence.ts → peer/presence.ts} +11 -11
- package/extensions/wechat/{reply-pipeline.ts → peer/reply-pipeline.ts} +13 -5
- package/extensions/wechat/{credentials.ts → state/credentials.ts} +2 -2
- package/extensions/wechat/{state.ts → state/state.ts} +14 -2
- package/extensions/wechat/{format.ts → text/format.ts} +3 -3
- package/extensions/wechat/{notices.ts → text/notices.ts} +15 -7
- package/extensions/wechat/tools.ts +29 -12
- package/extensions/wechat/{client.ts → transport/client.ts} +26 -2
- package/extensions/wechat/{deliver.ts → transport/deliver.ts} +104 -40
- package/extensions/wechat/{inbound.ts → transport/inbound.ts} +5 -5
- package/extensions/wechat/{media.ts → transport/media.ts} +11 -5
- package/extensions/wechat/transport/outbound.ts +142 -0
- package/extensions/wechat/{poll.ts → transport/poll.ts} +3 -3
- package/extensions/wechat/types.ts +10 -1
- package/extensions/wechat/{login-screen.ts → view/login-screen.ts} +4 -4
- package/extensions/wechat/{status-screen.ts → view/status-screen.ts} +31 -26
- package/extensions/worktree/git.ts +5 -0
- package/extensions/worktree/guard.ts +3 -5
- package/extensions/worktree/registry.ts +11 -5
- package/extensions/worktree/status.ts +1 -3
- package/lib/README.md +12 -6
- package/lib/board/card.ts +290 -0
- package/lib/board/links.ts +117 -0
- package/lib/board/page-pointer.ts +256 -0
- package/lib/board/round-text.ts +72 -0
- package/lib/board/round.ts +89 -0
- package/lib/board/rules.ts +304 -0
- package/lib/board/session.ts +105 -0
- package/lib/board/store.ts +310 -0
- package/lib/board/view.ts +150 -0
- package/lib/errors.ts +12 -4
- package/lib/format.ts +13 -0
- package/lib/http/guard.ts +112 -0
- package/lib/http/index.ts +16 -5
- package/lib/http/router.ts +40 -13
- package/lib/http/serve.ts +234 -0
- package/lib/http/server.ts +29 -13
- package/lib/http/sink.ts +110 -0
- package/lib/http/token.ts +38 -0
- package/lib/interaction.ts +10 -0
- package/lib/notice.ts +29 -2
- package/lib/plan-entry.ts +7 -2
- package/lib/policy.ts +12 -2
- package/lib/qr.ts +64 -0
- package/lib/repo-key.ts +74 -0
- package/lib/report.ts +52 -33
- package/lib/requirements.ts +7 -9
- package/lib/session-label.ts +64 -0
- package/lib/session-roster.ts +130 -0
- package/lib/session-tool.ts +184 -0
- package/lib/tool-names.ts +25 -2
- package/lib/tui/README.md +16 -2
- package/lib/tui/dock-screen.ts +85 -17
- package/lib/tui/glyphs.ts +2 -0
- package/lib/tui/line-pane.ts +15 -4
- package/lib/tui/tool.ts +23 -4
- package/lib/web/README.md +5 -2
- package/lib/web/components.ts +6 -1
- package/lib/web/runtime.ts +7 -1
- package/lib/web/tokens.ts +25 -2
- package/package.json +27 -14
- package/skills/init/SKILL.md +80 -45
- package/skills/init/references/agents-md-quality.md +26 -2
- package/skills/init/references/interview-questions.md +36 -14
- package/skills/next/SKILL.md +77 -51
- package/skills/project-docs/SKILL.md +133 -0
- package/skills/project-docs/references/audit.md +131 -0
- package/skills/project-docs/references/changelog.md +105 -0
- package/skills/project-docs/references/discovery.md +127 -0
- package/skills/project-docs/references/readme.md +80 -0
- package/skills/project-docs/references/release.md +84 -0
- package/skills/project-docs/references/roadmap.md +93 -0
- package/skills/project-docs/scripts/state.ts +316 -0
- package/skills/refactor/SKILL.md +100 -125
- package/skills/refactor/references/handoff.md +35 -0
- package/skills/refactor/references/signals.md +54 -0
- package/skills/refactor/scripts/inventory.ts +587 -0
- package/extensions/file-browse/README.md +0 -467
- package/extensions/file-browse/server.ts +0 -134
- package/extensions/plan/README.md +0 -709
- package/extensions/plan/config.ts +0 -27
- package/extensions/wechat/outbound.ts +0 -100
- package/extensions/wechat/qrcode.ts +0 -46
- package/skills/changelog/SKILL.md +0 -148
- /package/extensions/file-browse/{diff.ts → text/diff.ts} +0 -0
- /package/extensions/file-browse/{fuzzy.ts → text/fuzzy.ts} +0 -0
- /package/extensions/file-browse/{palette.ts → view/palette.ts} +0 -0
- /package/extensions/rewind/{patch.ts → text/patch.ts} +0 -0
- /package/extensions/rewind/{paths.ts → text/paths.ts} +0 -0
- /package/extensions/rewind/{queue.ts → transport/queue.ts} +0 -0
- /package/extensions/rewind/{temp-index.ts → transport/temp-index.ts} +0 -0
- /package/extensions/wechat/{lock.ts → state/lock.ts} +0 -0
- /package/extensions/wechat/{channel.ts → text/channel.ts} +0 -0
|
@@ -3,53 +3,57 @@
|
|
|
3
3
|
One extension, two tools, keyless and dependency-free (native `fetch`, no
|
|
4
4
|
`curl`): `web_search` runs general web search through a pluggable provider
|
|
5
5
|
(keyless DuckDuckGo by default; optional SearXNG or Brave), and `web_fetch`
|
|
6
|
-
reads a URL as text. Both are `direct
|
|
7
|
-
|
|
6
|
+
reads a URL as text. Both are `direct`, active on registration, and read the
|
|
7
|
+
`web-access` section of the shared `bytefly.json`.
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
## Capabilities
|
|
10
|
+
|
|
11
|
+
Status records what a reader can rely on: **Shipped** is in a tagged release, **Unreleased** is complete in the current tree but not yet tagged, and **Partial** has one released part and one unreleased part. Rows are ordered by user value, highest first.
|
|
12
|
+
|
|
13
|
+
| Capability | How | What you get | Status |
|
|
14
|
+
|---|---|---|---|
|
|
15
|
+
| Web search | `web_search` | Titles, URLs, snippets, and a direct answer when the provider has one. | Shipped |
|
|
16
|
+
| Page reading | `web_fetch` | A URL's readable text, with links kept as `[text](url)`. | Shipped |
|
|
17
|
+
| Structured bodies | `web_fetch` | A JSON, CSV, or XML body arrives as an aligned table or an indented tree instead of the raw blob. | Unreleased |
|
|
18
|
+
| Write-style fetch | `web_fetch` (`method`, `headers`, `body`) | POST with custom headers and a bounded body, so form and GraphQL endpoints are reachable; a body implies POST. | Shipped |
|
|
19
|
+
| Paged output | `web_fetch`, `startIndex`, `maxChars` | A long page arrives in budgeted slices and names the offset that continues it. | Shipped |
|
|
20
|
+
| Passage search | `web_fetch`, `find`, `contextChars` | Matching passages instead of the whole page, with a note when a cap hid the rest. | Shipped |
|
|
21
|
+
| Private-address refusal | `web_fetch`, `fetch.allowPrivateHosts` | Loopback, private, link-local, and metadata targets are refused on the first request and on every redirect hop. | Shipped |
|
|
22
|
+
| Charset-aware decoding | `web_fetch` | A GBK/GB18030 or `<meta charset>` page reads as text instead of replacement characters. | Shipped |
|
|
23
|
+
| Page cache | `web_fetch`, `refresh`, `fetch.cacheEnabled` | Paging and `find` reuse one fetch, and `refresh: true` bypasses a stale entry. | Shipped |
|
|
24
|
+
| PDF extraction | `web_fetch`, `fetch.pdfEnabled` | A PDF becomes text once the optional `unpdf` package is installed. | Shipped |
|
|
25
|
+
| Provider choice | `search.provider`, `search.endpoint`, `search.apiKeyEnv` | The keyless default works with no configuration; SearXNG or Brave add full result lists. | Shipped |
|
|
26
|
+
| Structured result | `nextIndex`, `matchesTruncated`, `cached` | A caller can continue paging and tell a capped match set from a complete one without parsing the text. | Shipped |
|
|
27
|
+
| Politeness throttle | `minIntervalMs` | Search requests are spaced instead of hammering a provider on a rapid series of calls. | Shipped |
|
|
28
|
+
|
|
29
|
+
## Quickstart
|
|
30
|
+
|
|
31
|
+
```bash
|
|
10
32
|
pi --extension ./extensions/web-access # load just this extension
|
|
11
33
|
pi -e . # load the whole @gavin-hu/my-pi-agent package
|
|
12
34
|
pi install ./ # or install the package
|
|
13
35
|
```
|
|
14
36
|
|
|
15
|
-
|
|
37
|
+
```text
|
|
38
|
+
web_search({ query: "pi coding agent" }) # keyless, no configuration
|
|
39
|
+
web_fetch({ url: "https://pi.dev/" }) # the page as readable text
|
|
40
|
+
```
|
|
16
41
|
|
|
17
|
-
|
|
42
|
+
## Tools
|
|
18
43
|
|
|
19
44
|
<img src="../../assets/tools/web_search.png" alt="The web_search tool's call and result: the call line and an indented body with the query and the ranked results" width="100%">
|
|
20
45
|
|
|
21
46
|
<img src="../../assets/tools/web_fetch.png" alt="The web_fetch tool's call and result: the call line and an indented body with the URL, title, and fetched text preview" width="100%">
|
|
22
47
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
- Registers `web_search`, general web search through a pluggable provider:
|
|
26
|
-
keyless DuckDuckGo by default, or a self-hosted SearXNG instance / keyed Brave
|
|
27
|
-
search. Returns titles, URLs, snippets, and a direct answer when available,
|
|
28
|
-
always with no configuration required.
|
|
29
|
-
- Registers `web_fetch`, which fetches a URL (GET or POST) and
|
|
30
|
-
returns readable text with links kept as `[text](url)`.
|
|
31
|
-
- Decodes by the byte-order mark, the declared `Content-Type` charset, or the
|
|
32
|
-
page's own `<meta charset>`, so a GBK/GB18030 page reads as text instead of
|
|
33
|
-
replacement characters.
|
|
34
|
-
- Pages long output and reports the next `startIndex` (`nextIndex` in
|
|
35
|
-
`structuredContent`); `find` returns matching passages instead of the whole
|
|
36
|
-
page, and says when the match cap hid further hits.
|
|
37
|
-
- Re-validates every redirect hop against private/internal addresses, and
|
|
38
|
-
refuses transport headers and oversized bodies.
|
|
39
|
-
- Optionally extracts PDFs (`unpdf`); the package loads lazily and is never
|
|
40
|
-
required.
|
|
41
|
-
- Caches fetched pages in one in-process cache per registration, so paging and
|
|
42
|
-
`find` do not refetch; the cache is cleared on `session_start` and
|
|
43
|
-
`session_shutdown`.
|
|
44
|
-
|
|
45
|
-
## Tools
|
|
48
|
+
Both tools are `direct` (the default) and active on registration; neither needs
|
|
49
|
+
configuration to run.
|
|
46
50
|
|
|
47
51
|
| Tool | What it does |
|
|
48
52
|
|---|---|
|
|
49
53
|
| `web_search` | General web search; keyless by default, SearXNG or Brave optional. |
|
|
50
54
|
| `web_fetch` | Fetch a URL and return readable text, pageable and searchable. |
|
|
51
55
|
|
|
52
|
-
```
|
|
56
|
+
```text
|
|
53
57
|
web_search({ query: "pi coding agent" })
|
|
54
58
|
web_fetch({ url: "https://pi.dev/" })
|
|
55
59
|
web_fetch({ url: "https://pi.dev/", find: ["documentation", "extensions"] })
|
|
@@ -68,7 +72,7 @@ flight it draws a railed `Searching… 8s` or `Fetching example.com… 3s` line,
|
|
|
68
72
|
a finished call appends its duration. A failed page or a host-rejected call
|
|
69
73
|
renders one sanitized `Error:` line in the error role.
|
|
70
74
|
|
|
71
|
-
```
|
|
75
|
+
```text
|
|
72
76
|
web_search "pi coding agent" (max 8)
|
|
73
77
|
|
|
74
78
|
via searxng · 8 results · 2.1s
|
|
@@ -80,7 +84,7 @@ Answer: Pi is a coding agent harness …
|
|
|
80
84
|
+3 more (ctrl+o to expand)
|
|
81
85
|
```
|
|
82
86
|
|
|
83
|
-
```
|
|
87
|
+
```text
|
|
84
88
|
web_fetch https://pi.dev/
|
|
85
89
|
Pi — a coding-agent component · 200 · 12k chars (cached) · 3.4s
|
|
86
90
|
```
|
|
@@ -90,9 +94,10 @@ which URL supplied the text.
|
|
|
90
94
|
|
|
91
95
|
## Configuration
|
|
92
96
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
and
|
|
97
|
+
The `web-access` section of the shared `bytefly.json`: `search` configures
|
|
98
|
+
`web_search`, `fetch` configures `web_fetch`. Resolution rules are in
|
|
99
|
+
[`../configuration.md#web-access--search-and-fetch`](../configuration.md#web-access--search-and-fetch),
|
|
100
|
+
which also lists every key with its default and accepted values.
|
|
96
101
|
|
|
97
102
|
```jsonc
|
|
98
103
|
// bytefly.json → "web-access"
|
|
@@ -183,7 +188,7 @@ whether it came from an explicit choice, the `auto` rule, or the keyless default
|
|
|
183
188
|
the API-key variable when the provider takes one and no literal `apiKey` is set,
|
|
184
189
|
and whether that variable is present; and, only on an explicit `refresh`, whether
|
|
185
190
|
the configured `endpoint` answers. The key is never reported, only its variable
|
|
186
|
-
name. See [`bytefly`](
|
|
191
|
+
name. See [`bytefly`](./bytefly.md#capabilities) for the report.
|
|
187
192
|
|
|
188
193
|
| Parameter | Type | Notes |
|
|
189
194
|
|---|---|---|
|
|
@@ -199,11 +204,16 @@ web_search({ query: "python list comprehension", maxResults: 3 })
|
|
|
199
204
|
## `web_fetch`
|
|
200
205
|
|
|
201
206
|
GETs (or POSTs) an http(s) URL and returns readable text. HTML becomes
|
|
202
|
-
plain text with links kept as `[text](url)`; JSON
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
+
plain text with links kept as `[text](url)`; a JSON, CSV, or XML body becomes a
|
|
208
|
+
table or an indented tree ([Structured bodies](#structured-bodies)); other textual
|
|
209
|
+
content is returned as-is; PDFs are text-extracted when the optional `unpdf`
|
|
210
|
+
package is installed; other binary content is reported by type and size. Bodies
|
|
211
|
+
are decoded by the
|
|
212
|
+
byte-order mark, the declared `Content-Type` charset, or the page's own
|
|
213
|
+
`<meta charset>`, so a GBK/GB18030 page reads as text instead of replacement
|
|
214
|
+
characters. Redirects are followed manually and **every hop is re-validated**, so
|
|
215
|
+
a public URL cannot redirect into a private address. Loopback, private,
|
|
216
|
+
link-local, and cloud-metadata addresses are refused.
|
|
207
217
|
|
|
208
218
|
| Parameter | Type | Notes |
|
|
209
219
|
|---|---|---|
|
|
@@ -237,6 +247,32 @@ web_fetch({ url: "https://pi.dev/", find: ["documentation", "extensions"] })
|
|
|
237
247
|
web_fetch({ url: "https://api.example/graphql", method: "POST", headers: { "Content-Type": "application/json" }, body: '{"query":"{ viewer { login } }"}' })
|
|
238
248
|
```
|
|
239
249
|
|
|
250
|
+
### Structured bodies
|
|
251
|
+
|
|
252
|
+
A JSON, CSV, or XML body is rendered as text instead of the blob it downloaded: an
|
|
253
|
+
array of records becomes a table with the union of their keys and padded columns,
|
|
254
|
+
an object becomes indented `key: value` lines, comma-separated rows become the same
|
|
255
|
+
table, and XML becomes an indented tree with attributes as `@name`. The declared
|
|
256
|
+
content type decides first; a body that declares nothing usable (`text/plain`) is
|
|
257
|
+
sniffed only when it has a shape — an opening brace, a uniform comma count, a root
|
|
258
|
+
tag — and anything that does not parse keeps its raw form, so a malformed document
|
|
259
|
+
is never made harder to read than it already was.
|
|
260
|
+
|
|
261
|
+
```text
|
|
262
|
+
URL: https://api.example/users
|
|
263
|
+
Status: 200 (application/json)
|
|
264
|
+
|
|
265
|
+
id name role
|
|
266
|
+
1 Ada admin
|
|
267
|
+
2 Grace user
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
Rendering happens once per fetch, before the result is cached, so `startIndex`,
|
|
271
|
+
`find`, and a second call all read the same string. Two bounds keep it honest: a
|
|
272
|
+
body past `MAX_SOURCE_CHARS` is returned raw, because a paged raw body beats a
|
|
273
|
+
rendered one, and the rendered text stops at `MAX_RENDERED_CHARS` with a note saying
|
|
274
|
+
so — both constants live in `fetch/structured.ts`.
|
|
275
|
+
|
|
240
276
|
### Optional dependencies
|
|
241
277
|
|
|
242
278
|
PDF extraction needs a package that is not installed by default; it is loaded
|
|
@@ -259,6 +295,11 @@ the content type and size.
|
|
|
259
295
|
- **Heuristic extraction**: `web_fetch` strips scripts/styles/nav/footer and
|
|
260
296
|
prefers `<main>`/`<article>`, but is not a full readability engine. PDF
|
|
261
297
|
extraction is optional (`unpdf`) and off unless installed.
|
|
298
|
+
- **A structured body is rendered by a reader, not a parser.** JSON, CSV, and XML
|
|
299
|
+
are read well enough to show a shape — CSV by RFC 4180 quoting, XML by balancing
|
|
300
|
+
tags — but a body it cannot parse keeps its raw form rather than a partial one,
|
|
301
|
+
and the `text/plain` sniff is a heuristic: a page of prose with a uniform comma
|
|
302
|
+
in every line reads as a one-row table.
|
|
262
303
|
- **`find` output is budgeted.** With `maxMatches: 50` and `contextChars: 2000`
|
|
263
304
|
the passages alone would exceed `maxOutputChars`; the result shows the passages
|
|
264
305
|
that fit and names the knob to change.
|
|
@@ -296,11 +337,11 @@ the content type and size.
|
|
|
296
337
|
`config.ts`, `schema.ts`, `types.ts`, `format.ts`, and `tool.ts`, and do not
|
|
297
338
|
import each other; `index.ts` only registers. Shared text and HTML helpers
|
|
298
339
|
live at the top level (`text.ts`, `html.ts`, `transcript.ts`, `http.ts`).
|
|
299
|
-
- **Shared transport.** [`http.ts`](
|
|
340
|
+
- **Shared transport.** [`http.ts`](../../extensions/web-access/http.ts) holds the fetch runner
|
|
300
341
|
(`HttpRunner`, `createFetchRunner`, HTTP error types), used by both halves and
|
|
301
342
|
injectable for tests. It reads the body through a byte-counting stream, so
|
|
302
343
|
`maxBytes` stops a chunked or compressed response before it is buffered whole.
|
|
303
|
-
- **Charset-aware decoding.** [`charset.ts`](
|
|
344
|
+
- **Charset-aware decoding.** [`charset.ts`](../../extensions/web-access/charset.ts) is the one place a
|
|
304
345
|
byte body becomes text: BOM first, then the declared `Content-Type` charset,
|
|
305
346
|
then the page's own `<meta charset>`, then UTF-8. An unknown label falls back
|
|
306
347
|
to UTF-8 instead of failing the fetch.
|
|
@@ -311,9 +352,9 @@ the content type and size.
|
|
|
311
352
|
lazily and falls back to a binary note when it is absent.
|
|
312
353
|
- **Per-hop SSRF validation.** Redirects are followed with `redirect: "manual"`
|
|
313
354
|
under one shared deadline, re-resolving and re-checking each `Location`.
|
|
314
|
-
- **Pluggable search providers.** [`registry.ts`](
|
|
355
|
+
- **Pluggable search providers.** [`registry.ts`](../../extensions/web-access/search/registry.ts) holds a
|
|
315
356
|
value-only provider list (`duckduckgo`, `searxng`, `brave`) and a pure
|
|
316
|
-
`resolveProvider`; [`search.ts`](
|
|
357
|
+
`resolveProvider`; [`search.ts`](../../extensions/web-access/search/search.ts) owns selection, key
|
|
317
358
|
resolution, a per-instance throttle, and error mapping. A provider with no
|
|
318
359
|
answer and no results reports `provider: "none"`.
|
|
319
360
|
- **Find-in-page.** `exact` is case-sensitive, `insensitive` lowercases both
|
|
@@ -328,17 +369,17 @@ the content type and size.
|
|
|
328
369
|
truncation note against `maxChars`, so a paged page always carries its
|
|
329
370
|
`startIndex` hint inside the limit. `formatMatches` applies the same rule to
|
|
330
371
|
`find`: it includes the passages that fit and names the knob that hid the rest.
|
|
331
|
-
- **Code points without a copy.** [`text.ts`](
|
|
372
|
+
- **Code points without a copy.** [`text.ts`](../../extensions/web-access/text.ts) counts and slices by
|
|
332
373
|
walking the string in place, so a multi-megabyte page is never expanded into an
|
|
333
374
|
array of one-character strings on every call.
|
|
334
375
|
- **One JSON boundary per concern.** `search/json.ts` owns `requestJson` (status
|
|
335
376
|
check and parse error) and `collectResults` (title + http(s) URL + de-dupe), so
|
|
336
377
|
the three providers cannot drift on either.
|
|
337
|
-
- **Page cache.** [`fetch/cache.ts`](
|
|
378
|
+
- **Page cache.** [`fetch/cache.ts`](../../extensions/web-access/fetch/cache.ts) is a factory
|
|
338
379
|
(`createPageCache`) holding an LRU/TTL map keyed by requested URL, so paging and
|
|
339
380
|
find are a single fetch; entries evict by count and total bytes, and one
|
|
340
381
|
instance belongs to one registration.
|
|
341
|
-
- **Transcript sanitization and reuse.** [`transcript.ts`](
|
|
382
|
+
- **Transcript sanitization and reuse.** [`transcript.ts`](../../extensions/web-access/transcript.ts)
|
|
342
383
|
holds `oneLine`, shared by both tools to collapse untrusted web text to one
|
|
343
384
|
sanitized, optionally clipped line; the renderers reuse
|
|
344
385
|
`context.lastComponent` instead of allocating each render.
|
|
@@ -357,6 +398,7 @@ the content type and size.
|
|
|
357
398
|
| `search/tool.ts` | `web_search` definition, activation, rendering |
|
|
358
399
|
| `search/provider.ts` | Provider interface (`SearchProvider`, `ProviderContext`) |
|
|
359
400
|
| `search/registry.ts` | Value-only provider list, `resolveProvider`, labels |
|
|
401
|
+
| `search/facts.ts` | What this session resolved to, published for `doctor` (`providerFacts`) |
|
|
360
402
|
| `search/config.ts` | Search config type, defaults, clamping, API-key resolution |
|
|
361
403
|
| `search/schema.ts` | Params/output schema, `resolveRequest()` |
|
|
362
404
|
| `search/search.ts` | Provider resolution, throttle, and outcome mapping |
|
|
@@ -368,10 +410,10 @@ the content type and size.
|
|
|
368
410
|
| `fetch/tool.ts` | `web_fetch` definition, activation, rendering |
|
|
369
411
|
| `fetch/config.ts` | Fetch config type, defaults, clamping |
|
|
370
412
|
| `fetch/schema.ts` | Params/output schema, `resolveRequest()` |
|
|
371
|
-
| `fetch/page.ts` | Fetch + redirect-following + content-type routing |
|
|
413
|
+
| `fetch/page.ts` | Fetch + redirect-following + content-type routing; PDF extraction is injected via `FetchDeps` from the shared `lib/pdf.ts` |
|
|
414
|
+
| `fetch/structured.ts` | JSON/CSV/XML body → readable text, or `undefined` to keep the raw body |
|
|
372
415
|
| `fetch/ssrf.ts` | URL/host validation and private-address blocking |
|
|
373
416
|
| `fetch/extract.ts` | HTML → title + readable text |
|
|
374
|
-
| `fetch/page.ts` | Fetch + redirect-following + content-type routing; PDF extraction is injected via `FetchDeps` from the shared `lib/pdf.ts` |
|
|
375
417
|
| `fetch/find.ts` | Passage search (exact/insensitive/fuzzy) |
|
|
376
418
|
| `fetch/cache.ts` | Per-registration LRU/TTL page cache (`createPageCache`) |
|
|
377
419
|
| `fetch/format.ts`, `fetch/types.ts` | Result text and data types |
|
|
@@ -386,7 +428,8 @@ charset decoding (declared, `<meta>`, and BOM precedence), a streamed body over
|
|
|
386
428
|
the byte cap, redirect re-validation (per-hop SSRF with literal IPs),
|
|
387
429
|
method/header/body validation, the nested config merge and section isolation,
|
|
388
430
|
extraction, formatting/paging through the tool (including a regression test that
|
|
389
|
-
a truncated page keeps its `startIndex` hint),
|
|
431
|
+
a truncated page keeps its `startIndex` hint), structured rendering per format and
|
|
432
|
+
its malformed fallbacks, find and its cap/budget notices,
|
|
390
433
|
the per-registration cache, the SSRF guard, the injected PDF dependency, and both
|
|
391
434
|
tools' registration/execution. Tests inject the runner, throttle, and PDF extractor
|
|
392
435
|
through the tools' dependencies, so no network or PDF library is needed; the
|