@normful/parallel-web-pi-extension 0.0.0-stage → 1.1.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/LICENSE ADDED
@@ -0,0 +1,23 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Parallel Web
4
+ Copyright (c) 2026 Norman Sue
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ of this software and associated documentation files (the "Software"), to deal
8
+ in the Software without restriction, including without limitation the rights
9
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ copies of the Software, and to permit persons to whom the Software is
11
+ furnished to do so, subject to the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be included in all
14
+ copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ SOFTWARE.
23
+
package/README.md CHANGED
@@ -1,3 +1,250 @@
1
- # Temporary Holding Version
1
+ # @normful/parallel-web-pi-extension
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Pi extension that adds `web_search`, `web_fetch`, and `web_research` backed by
4
+ Parallel. Keep your usual coding agent and give it web tools with one install.
5
+
6
+ This is a fork: a manually maintained copy of `@parallel-web/pi-extension` 1.3.0
7
+ from `parallel-web/parallel-npm-packages`, renamed and released here. The
8
+ upstream `@parallel-web/oauth` helper (private on npm) is vendored into
9
+ `src/oauth/` so the package builds and tests standalone.
10
+
11
+ Install it with:
12
+ ```
13
+ pi install npm:@normful/parallel-web-pi-extension
14
+ ```
15
+
16
+ ## What It Does
17
+
18
+ - Registers `web_search`
19
+ - Registers `web_fetch`
20
+ - Registers `web_research` for synthesized answers with sources through the
21
+ Responses API
22
+ - Registers a `parallel` auth provider, so Pi's own `/login parallel` runs the
23
+ Parallel browser OAuth flow and stores the API key in Pi's auth store
24
+ (`auth.json`) alongside every other provider credential
25
+ - Adds a `parallel-login` command that reports current auth status
26
+
27
+ Auth resolution order (owned by Pi, not the extension):
28
+
29
+ 1. The credential Pi stored for provider `parallel`
30
+ 2. `PARALLEL_API_KEY`
31
+
32
+ Run `/parallel-login` inside Pi to check whether Parallel is configured. To
33
+ remove a stored credential, run `/logout` and select Parallel. Environment
34
+ variables are not affected by Pi's logout flow.
35
+
36
+ Requires `@earendil-works/pi-coding-agent` 0.83.0 or newer.
37
+
38
+ ## Web Research
39
+
40
+ After installing this extension, run `/login parallel` and ask your usual Pi
41
+ agent a research question. No additional package or model selection is needed:
42
+
43
+ ```text
44
+ Compare the current Node.js compatibility of Node and Bun for a production API server. Research the tradeoffs and cite primary sources.
45
+ ```
46
+
47
+ The agent can call the research tool directly:
48
+
49
+ ```javascript
50
+ web_research({
51
+ query: "Compare the current Node.js compatibility of Node and Bun for a production API server. Cite primary sources.",
52
+ effort: "medium"
53
+ });
54
+ ```
55
+
56
+ | Tool | Use it for |
57
+ | --- | --- |
58
+ | `web_research` | A complete answer that needs web research and synthesis |
59
+ | `web_search` | Discovering sources and raw excerpts to investigate yourself |
60
+ | `web_fetch` | Reading known URLs or checking original sources |
61
+
62
+ Start with a complete, self-contained `query`. Research does not see the Pi
63
+ conversation or local files, so include relevant constraints and only context
64
+ that is safe to send.
65
+
66
+ When available, the result starts with a `Response ID`. For a focused follow-up
67
+ on the same investigation, pass that ID as `previous_response_id`:
68
+
69
+ ```javascript
70
+ web_research({
71
+ query: "Which of those compatibility gaps would matter for an API server that uses native Node.js addons?",
72
+ previous_response_id: "resp_..." // Copy the actual ID from the previous result.
73
+ });
74
+ ```
75
+
76
+ Use the new ID returned by each follow-up to continue from its answer. Omit the
77
+ ID for a new or unrelated question. Calls never chain automatically, and the
78
+ extension keeps no local research-session state. Continuation reuses saved
79
+ research context, including earlier answer summaries, not every internal step
80
+ of the research process. IDs are opaque; the tool accepts non-empty IDs up to
81
+ 512 characters without whitespace or control characters.
82
+
83
+ Saved context is not guaranteed to remain available, and continuation is not
84
+ supported for zero data retention (ZDR) accounts. An unavailable ID or a ZDR
85
+ restriction returns an error without retrying as fresh research. A valid
86
+ answer without a usable new ID is still returned, but cannot be continued
87
+ through that result. If Pi loses an ID during conversation compaction, do not
88
+ invent a replacement.
89
+
90
+ `effort` is optional and defaults to `medium`, matching the Responses API
91
+ default. Use `low` for focused lookups, `medium` for general research, and
92
+ `high` for extensive research. Responses is billed per successful call; see
93
+ the [current pricing](https://docs.parallel.ai/getting-started/pricing).
94
+
95
+ Each invocation makes one non-streaming `POST /v1/responses` request, with no
96
+ automatic retries or background jobs. The local deadline
97
+ is 120 seconds, including reading the response; slower valid research can
98
+ exceed this client limit. Cancelling the tool
99
+ aborts the local request on a best-effort basis; it does not confirm that work
100
+ stopped on the server. A manual retry is a new request and may incur a new charge.
101
+
102
+ The request contains only the fixed research instructions and explicit query,
103
+ with the selected effort and `previous_response_id` only when explicitly
104
+ supplied. It does not automatically forward parent history,
105
+ local files, cwd, environment variables, Pi tools, or session metadata.
106
+ Anything the calling agent includes in `query` is sent to Parallel.
107
+
108
+ The tool rejects requests over 20,000 combined instruction and input
109
+ characters, including the separator the API counts, before sending them.
110
+ It preserves the answer and renders returned HTTP(S) citations as a
111
+ deduplicated Markdown source list. When a citation identifies a passage,
112
+ the source includes that exact quoted answer text and its location in the
113
+ original text part. These are passages from the answer, not excerpts from
114
+ the source page. Unresolved citation ranges keep the source link without
115
+ inventing a passage. Results that exceed Pi's output limits are shown as a
116
+ marked preview with a path to the complete answer and sources in a private
117
+ temporary file. The response ID stays visible in the preview and is included
118
+ in the complete report.
119
+
120
+ ## Dogfooding Locally
121
+
122
+ Pi transpiles TypeScript extensions with jiti, so it loads `src/index.ts`
123
+ directly. There is no build step: the package ships source.
124
+
125
+ ### Option 1: Load It Directly With `pi -e`
126
+
127
+ This is the fastest way to test a local checkout.
128
+
129
+ From the repo root:
130
+
131
+ ```bash
132
+ pi --no-extensions --no-skills -e ./src/index.ts
133
+ ```
134
+
135
+ If the extension loads successfully, Pi will have:
136
+
137
+ - the `web_search` tool
138
+ - the `web_fetch` tool
139
+ - `parallel` listed under `/login`
140
+ - the `parallel-login` status command
141
+ - the `web_research` tool
142
+ - per-session Parallel `session_id` reuse inside that Pi session
143
+
144
+ ### Option 2: Symlink It Into Pi Extensions
145
+
146
+ This is better if you want Pi to auto-discover it and support `/reload`.
147
+
148
+ Then symlink the package directory into Pi's global extensions folder:
149
+
150
+ ```bash
151
+ mkdir -p ~/.pi/agent/extensions
152
+ ln -s \
153
+ "$PWD" \
154
+ ~/.pi/agent/extensions/normful-parallel-pi-extension
155
+ ```
156
+
157
+ Then start Pi normally:
158
+
159
+ ```bash
160
+ pi
161
+ ```
162
+
163
+ After code changes, run `/reload` inside Pi.
164
+
165
+ ## Local Auth Testing
166
+
167
+ ### Use Stored Pi Auth
168
+
169
+ Inside Pi, run:
170
+
171
+ ```text
172
+ /login parallel
173
+ ```
174
+
175
+ That opens the browser for Parallel OAuth. On success, Pi stores the API key in
176
+ its auth store under `parallel`. Run `/parallel-login` to see the current status,
177
+ and run `/logout` and select Parallel to remove the stored credential.
178
+
179
+ ### Use Environment Variable Instead
180
+
181
+ ```bash
182
+ export PARALLEL_API_KEY=your_key_here
183
+ pi --no-extensions --no-skills -e ./src/index.ts
184
+ ```
185
+
186
+ Note: stored Pi auth is preferred over `PARALLEL_API_KEY` if both exist.
187
+
188
+ ### Override The OAuth Platform URL
189
+
190
+ For local or staging OAuth testing, set `PARALLEL_PLATFORM_URL` before starting Pi:
191
+
192
+ ```bash
193
+ export PARALLEL_PLATFORM_URL=https://your-platform-host
194
+ pi --no-extensions --no-skills -e ./src/index.ts
195
+ ```
196
+
197
+ This changes the browser login endpoints used by `/login parallel`.
198
+
199
+ ### Override The API Base URL
200
+
201
+ `PARALLEL_BASE_URL` redirects every Parallel API call the tools make — search,
202
+ extract and research all follow it, so they can be pointed at a staging or local
203
+ host together:
204
+
205
+ ```bash
206
+ export PARALLEL_BASE_URL=https://your-api-host
207
+ pi --no-extensions --no-skills -e ./src/index.ts
208
+ ```
209
+
210
+ The value is an **origin**, not a full URL: the `/v1/search`, `/v1/extract` and
211
+ `/v1/responses` paths are appended to it, and a trailing slash is tolerated.
212
+ Unset it to use `https://api.parallel.ai`.
213
+
214
+ This is separate from `PARALLEL_PLATFORM_URL`, which only affects the OAuth
215
+ login flow (that host is `platform.parallel.ai`, not `api.parallel.ai`).
216
+
217
+ ## Quick Smoke Test
218
+
219
+ Once Pi is running with the extension loaded, ask something that should force web usage, for example:
220
+
221
+ ```text
222
+ Search the web for the latest Parallel docs on OAuth and summarize them.
223
+ ```
224
+
225
+ Or ask Pi to call the tool explicitly.
226
+
227
+ `web_search` requires `search_queries`.
228
+
229
+ `web_fetch` accepts multiple URLs in a single call, so the agent can batch extraction work instead of parallelizing many single-URL requests.
230
+
231
+ ## Dev Loop
232
+
233
+ ```bash
234
+ npm test
235
+ npm run typecheck
236
+ ```
237
+
238
+ ## Notes
239
+
240
+ - Search and Fetch use the `parallel-web` TypeScript SDK; Research calls the
241
+ Responses endpoint directly.
242
+ - Search requests use Parallel SDK `fast` mode.
243
+ - Search requests include `client_model` when Pi has an active model selected.
244
+ - Search and extract requests reuse a generated `session_id` for the life of the current Pi session.
245
+ - The login flow tries to open your browser automatically.
246
+ - If automatic callback capture does not complete, the login dialog asks you to paste the callback URL.
247
+ - Credential storage is entirely Pi's; the extension only reads the resolved key
248
+ through `ctx.modelRegistry.getApiKeyForProvider("parallel")`.
249
+ - Research requests do not reuse the Search/Extract `session_id`.
250
+ - Skill suppression inside the extension is prompt-level only. If you want a clean dogfooding session without your usual skills list, start Pi with `--no-skills`.
package/package.json CHANGED
@@ -1,6 +1,66 @@
1
1
  {
2
2
  "name": "@normful/parallel-web-pi-extension",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "1.1.0",
4
+ "description": "Add Parallel web search, fetch, and research tools to your pi agent",
5
+ "author": "Norman Sue",
6
+ "license": "MIT",
7
+ "type": "module",
8
+ "pi": {
9
+ "image": "https://assets.parallel.ai/white-parallel-avatar-540.png",
10
+ "extensions": [
11
+ "./src/index.ts"
12
+ ]
13
+ },
14
+ "files": [
15
+ "src",
16
+ "!src/**/*.test.ts",
17
+ "package.json",
18
+ "README.md"
19
+ ],
20
+ "dependencies": {
21
+ "parallel-web": "1.3.0",
22
+ "typebox": "^1.1.37"
23
+ },
24
+ "peerDependencies": {
25
+ "@earendil-works/pi-coding-agent": ">=0.83.0"
26
+ },
27
+ "devDependencies": {
28
+ "@earendil-works/pi-ai": ">=0.83.0",
29
+ "@types/node": "^24.0.0",
30
+ "@typescript-eslint/eslint-plugin": "^6.13.0",
31
+ "@typescript-eslint/parser": "^6.13.0",
32
+ "@vitest/coverage-v8": "^5.0.4",
33
+ "eslint": "^8.54.0",
34
+ "prettier": "^3.1.0",
35
+ "typescript": "^5.3.2",
36
+ "vitest": "^5.0.4"
37
+ },
38
+ "scripts": {
39
+ "test": "vitest run",
40
+ "coverage": "vitest run --coverage",
41
+ "typecheck": "tsc --noEmit",
42
+ "lint": "eslint .",
43
+ "lint:fix": "eslint . --fix",
44
+ "format": "prettier --write .",
45
+ "format:check": "prettier --check ."
46
+ },
47
+ "keywords": [
48
+ "pi-package",
49
+ "pi.dev",
50
+ "pi agent",
51
+ "extension",
52
+ "parallel",
53
+ "research",
54
+ "web",
55
+ "search",
56
+ "fetch",
57
+ "ai"
58
+ ],
59
+ "repository": {
60
+ "type": "git",
61
+ "url": "git+https://github.com/normful/parallel-web-pi-extension-fork.git"
62
+ },
63
+ "publishConfig": {
64
+ "access": "public"
65
+ }
66
+ }