@juicesharp/rpiv-web-tools 1.8.0 → 1.8.2
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/package.json +56 -53
- package/web-tools.ts +20 -41
package/package.json
CHANGED
|
@@ -1,55 +1,58 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
2
|
+
"name": "@juicesharp/rpiv-web-tools",
|
|
3
|
+
"version": "1.8.2",
|
|
4
|
+
"description": "Pi extension. Web search and fetch for the model with pluggable providers (Brave, Tavily, Serper, Exa, Jina, Firecrawl).",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"pi-package",
|
|
7
|
+
"pi-extension",
|
|
8
|
+
"rpiv",
|
|
9
|
+
"web-search",
|
|
10
|
+
"search",
|
|
11
|
+
"fetch",
|
|
12
|
+
"scrape",
|
|
13
|
+
"brave",
|
|
14
|
+
"tavily",
|
|
15
|
+
"serper",
|
|
16
|
+
"exa",
|
|
17
|
+
"jina",
|
|
18
|
+
"firecrawl"
|
|
19
|
+
],
|
|
20
|
+
"type": "module",
|
|
21
|
+
"license": "MIT",
|
|
22
|
+
"author": "juicesharp",
|
|
23
|
+
"repository": {
|
|
24
|
+
"type": "git",
|
|
25
|
+
"url": "git+https://github.com/juicesharp/rpiv-mono.git",
|
|
26
|
+
"directory": "packages/rpiv-web-tools"
|
|
27
|
+
},
|
|
28
|
+
"homepage": "https://github.com/juicesharp/rpiv-mono/tree/main/packages/rpiv-web-tools#readme",
|
|
29
|
+
"bugs": {
|
|
30
|
+
"url": "https://github.com/juicesharp/rpiv-mono/issues"
|
|
31
|
+
},
|
|
32
|
+
"publishConfig": {
|
|
33
|
+
"access": "public"
|
|
34
|
+
},
|
|
35
|
+
"scripts": {
|
|
36
|
+
"test": "vitest run"
|
|
37
|
+
},
|
|
38
|
+
"files": [
|
|
39
|
+
"index.ts",
|
|
40
|
+
"web-tools.ts",
|
|
41
|
+
"providers/",
|
|
42
|
+
"README.md",
|
|
43
|
+
"LICENSE"
|
|
44
|
+
],
|
|
45
|
+
"pi": {
|
|
46
|
+
"extensions": [
|
|
47
|
+
"./index.ts"
|
|
48
|
+
]
|
|
49
|
+
},
|
|
50
|
+
"dependencies": {
|
|
51
|
+
"@juicesharp/rpiv-config": "^1.8.2"
|
|
52
|
+
},
|
|
53
|
+
"peerDependencies": {
|
|
54
|
+
"@earendil-works/pi-coding-agent": "*",
|
|
55
|
+
"@earendil-works/pi-tui": "*",
|
|
56
|
+
"typebox": "*"
|
|
57
|
+
}
|
|
55
58
|
}
|
package/web-tools.ts
CHANGED
|
@@ -11,10 +11,9 @@
|
|
|
11
11
|
* 3. (Brave only, legacy) apiKey field in config.json
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
|
-
import { chmodSync, existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
15
14
|
import { mkdtemp, writeFile } from "node:fs/promises";
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
15
|
+
import { tmpdir } from "node:os";
|
|
16
|
+
import { join } from "node:path";
|
|
18
17
|
import type { ExtensionAPI, Theme } from "@earendil-works/pi-coding-agent";
|
|
19
18
|
import {
|
|
20
19
|
DEFAULT_MAX_BYTES,
|
|
@@ -24,6 +23,8 @@ import {
|
|
|
24
23
|
truncateHead,
|
|
25
24
|
} from "@earendil-works/pi-coding-agent";
|
|
26
25
|
import { Text } from "@earendil-works/pi-tui";
|
|
26
|
+
import type { GuidanceFields } from "@juicesharp/rpiv-config";
|
|
27
|
+
import { configPath, loadJsonConfig, saveJsonConfig, validateGuidanceFields } from "@juicesharp/rpiv-config";
|
|
27
28
|
import { Type } from "typebox";
|
|
28
29
|
import { createSearchProvider } from "./providers/factory.js";
|
|
29
30
|
import { PROVIDERS } from "./providers/index.js";
|
|
@@ -44,9 +45,7 @@ const API_KEY_MASK_VISIBLE_CHARS = 4;
|
|
|
44
45
|
const FETCH_TEMP_DIR_PREFIX = "rpiv-fetch-";
|
|
45
46
|
const FETCH_TEMP_FILE_NAME = "content.txt";
|
|
46
47
|
|
|
47
|
-
const
|
|
48
|
-
const CONFIG_PATH = join(CONFIG_DIR, "config.json");
|
|
49
|
-
const CONFIG_FILE_MODE = 0o600;
|
|
48
|
+
const CONFIG_PATH = configPath("rpiv-web-tools");
|
|
50
49
|
|
|
51
50
|
const SUPPORTED_HTTP_PROTOCOLS = new Set(["http:", "https:"]);
|
|
52
51
|
|
|
@@ -60,10 +59,7 @@ const DEFAULT_PROVIDER_NAME = "brave";
|
|
|
60
59
|
// Config file persistence
|
|
61
60
|
// ---------------------------------------------------------------------------
|
|
62
61
|
|
|
63
|
-
|
|
64
|
-
promptSnippet?: string;
|
|
65
|
-
promptGuidelines?: string[];
|
|
66
|
-
}
|
|
62
|
+
// GuidanceFields is now imported from @juicesharp/rpiv-config
|
|
67
63
|
|
|
68
64
|
interface WebToolsGuidance {
|
|
69
65
|
web_search?: GuidanceFields;
|
|
@@ -78,44 +74,18 @@ interface WebToolsConfig {
|
|
|
78
74
|
}
|
|
79
75
|
|
|
80
76
|
function loadConfig(): WebToolsConfig {
|
|
81
|
-
|
|
82
|
-
try {
|
|
83
|
-
return JSON.parse(readFileSync(CONFIG_PATH, "utf-8")) as WebToolsConfig;
|
|
84
|
-
} catch {
|
|
85
|
-
return {};
|
|
86
|
-
}
|
|
77
|
+
return loadJsonConfig<WebToolsConfig>(CONFIG_PATH);
|
|
87
78
|
}
|
|
88
79
|
|
|
89
|
-
function saveConfig(config: WebToolsConfig):
|
|
90
|
-
|
|
91
|
-
writeFileSync(CONFIG_PATH, `${JSON.stringify(config, null, 2)}\n`, "utf-8");
|
|
92
|
-
try {
|
|
93
|
-
chmodSync(CONFIG_PATH, CONFIG_FILE_MODE);
|
|
94
|
-
} catch {
|
|
95
|
-
// chmod may fail on some filesystems — best effort only
|
|
96
|
-
}
|
|
80
|
+
function saveConfig(config: WebToolsConfig): boolean {
|
|
81
|
+
return saveJsonConfig(CONFIG_PATH, config);
|
|
97
82
|
}
|
|
98
83
|
|
|
99
84
|
// ---------------------------------------------------------------------------
|
|
100
85
|
// Executor guidance — overrides + defaults
|
|
101
86
|
// ---------------------------------------------------------------------------
|
|
102
87
|
|
|
103
|
-
|
|
104
|
-
if (!fields || typeof fields !== "object") return {};
|
|
105
|
-
const g = fields as Record<string, unknown>;
|
|
106
|
-
const result: GuidanceFields = {};
|
|
107
|
-
if (typeof g.promptSnippet === "string" && g.promptSnippet.length > 0) {
|
|
108
|
-
result.promptSnippet = g.promptSnippet;
|
|
109
|
-
}
|
|
110
|
-
if (
|
|
111
|
-
Array.isArray(g.promptGuidelines) &&
|
|
112
|
-
g.promptGuidelines.length > 0 &&
|
|
113
|
-
g.promptGuidelines.every((s) => typeof s === "string" && s.length > 0)
|
|
114
|
-
) {
|
|
115
|
-
result.promptGuidelines = g.promptGuidelines;
|
|
116
|
-
}
|
|
117
|
-
return result;
|
|
118
|
-
}
|
|
88
|
+
// validateGuidanceFields is now imported from @juicesharp/rpiv-config
|
|
119
89
|
|
|
120
90
|
export const DEFAULT_WEB_SEARCH_SNIPPET = "Search the web for up-to-date information";
|
|
121
91
|
export const DEFAULT_WEB_SEARCH_GUIDELINES: string[] = [
|
|
@@ -545,7 +515,16 @@ export function registerWebSearchConfigCommand(pi: ExtensionAPI): void {
|
|
|
545
515
|
apiKeys: { ...current.apiKeys, [selectedProvider]: keyToWrite },
|
|
546
516
|
};
|
|
547
517
|
delete (toSave as { apiKey?: string }).apiKey;
|
|
548
|
-
saveConfig(toSave)
|
|
518
|
+
if (!saveConfig(toSave)) {
|
|
519
|
+
// Don't lie about persistence — a "Saved …" message followed by an
|
|
520
|
+
// auth error on the next web_search would point the user at the
|
|
521
|
+
// wrong surface (vendor) instead of the actual cause (disk write).
|
|
522
|
+
ctx.ui.notify(
|
|
523
|
+
`Failed to save ${selectedMeta.label} API key to ${CONFIG_PATH} — disk write failed`,
|
|
524
|
+
"error",
|
|
525
|
+
);
|
|
526
|
+
return;
|
|
527
|
+
}
|
|
549
528
|
ctx.ui.notify(
|
|
550
529
|
trimmed
|
|
551
530
|
? `Saved ${selectedMeta.label} API key to ${CONFIG_PATH}`
|