@astralyn/pi 0.84.13 → 0.84.15
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/CHANGELOG.md +33 -0
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +12 -6
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/extensions/types.d.ts +4 -1
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/tools/bash.d.ts +1 -0
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +4 -1
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/find.d.ts +2 -0
- package/dist/core/tools/find.d.ts.map +1 -1
- package/dist/core/tools/find.js +18 -15
- package/dist/core/tools/find.js.map +1 -1
- package/dist/extensions/background/actions.d.ts.map +1 -1
- package/dist/extensions/background/actions.js +3 -2
- package/dist/extensions/background/actions.js.map +1 -1
- package/dist/extensions/background/manager.d.ts.map +1 -1
- package/dist/extensions/background/manager.js +8 -9
- package/dist/extensions/background/manager.js.map +1 -1
- package/dist/extensions/background/registry.d.ts +4 -1
- package/dist/extensions/background/registry.d.ts.map +1 -1
- package/dist/extensions/background/registry.js +30 -17
- package/dist/extensions/background/registry.js.map +1 -1
- package/dist/extensions/background/task-view.d.ts +6 -0
- package/dist/extensions/background/task-view.d.ts.map +1 -1
- package/dist/extensions/background/task-view.js +11 -6
- package/dist/extensions/background/task-view.js.map +1 -1
- package/dist/extensions/deepwiki/client.d.ts.map +1 -1
- package/dist/extensions/deepwiki/client.js +3 -0
- package/dist/extensions/deepwiki/client.js.map +1 -1
- package/dist/extensions/deepwiki/execute.d.ts +2 -1
- package/dist/extensions/deepwiki/execute.d.ts.map +1 -1
- package/dist/extensions/deepwiki/execute.js +17 -2
- package/dist/extensions/deepwiki/execute.js.map +1 -1
- package/dist/extensions/deepwiki/http.d.ts +1 -0
- package/dist/extensions/deepwiki/http.d.ts.map +1 -1
- package/dist/extensions/deepwiki/http.js +16 -2
- package/dist/extensions/deepwiki/http.js.map +1 -1
- package/dist/extensions/deepwiki/schema.d.ts +1 -1
- package/dist/extensions/deepwiki/schema.d.ts.map +1 -1
- package/dist/extensions/deepwiki/schema.js +8 -2
- package/dist/extensions/deepwiki/schema.js.map +1 -1
- package/dist/extensions/question/dialog.d.ts.map +1 -1
- package/dist/extensions/question/dialog.js +80 -9
- package/dist/extensions/question/dialog.js.map +1 -1
- package/dist/extensions/question/index.d.ts.map +1 -1
- package/dist/extensions/question/index.js +8 -0
- package/dist/extensions/question/index.js.map +1 -1
- package/dist/extensions/question/schema.d.ts +2 -2
- package/dist/extensions/question/schema.d.ts.map +1 -1
- package/dist/extensions/question/schema.js +41 -11
- package/dist/extensions/question/schema.js.map +1 -1
- package/dist/extensions/question/types.d.ts +1 -1
- package/dist/extensions/question/types.d.ts.map +1 -1
- package/dist/extensions/question/types.js.map +1 -1
- package/dist/extensions/router/probe.d.ts.map +1 -1
- package/dist/extensions/router/probe.js +10 -29
- package/dist/extensions/router/probe.js.map +1 -1
- package/dist/extensions/router/register.d.ts.map +1 -1
- package/dist/extensions/router/register.js +16 -6
- package/dist/extensions/router/register.js.map +1 -1
- package/dist/extensions/router/store.d.ts.map +1 -1
- package/dist/extensions/router/store.js +108 -51
- package/dist/extensions/router/store.js.map +1 -1
- package/dist/extensions/router/ui.d.ts +6 -0
- package/dist/extensions/router/ui.d.ts.map +1 -1
- package/dist/extensions/router/ui.js +14 -6
- package/dist/extensions/router/ui.js.map +1 -1
- package/dist/extensions/statusline/index.d.ts.map +1 -1
- package/dist/extensions/statusline/index.js +40 -43
- package/dist/extensions/statusline/index.js.map +1 -1
- package/dist/extensions/subagent/activity.d.ts +7 -1
- package/dist/extensions/subagent/activity.d.ts.map +1 -1
- package/dist/extensions/subagent/activity.js +69 -6
- package/dist/extensions/subagent/activity.js.map +1 -1
- package/dist/extensions/subagent/agents-command.js +1 -1
- package/dist/extensions/subagent/agents-command.js.map +1 -1
- package/dist/extensions/subagent/agents.d.ts.map +1 -1
- package/dist/extensions/subagent/agents.js +0 -3
- package/dist/extensions/subagent/agents.js.map +1 -1
- package/dist/extensions/subagent/budget.d.ts.map +1 -1
- package/dist/extensions/subagent/budget.js +29 -2
- package/dist/extensions/subagent/budget.js.map +1 -1
- package/dist/extensions/subagent/cancellation.d.ts +4 -4
- package/dist/extensions/subagent/cancellation.d.ts.map +1 -1
- package/dist/extensions/subagent/cancellation.js +31 -13
- package/dist/extensions/subagent/cancellation.js.map +1 -1
- package/dist/extensions/subagent/constants.d.ts +1 -0
- package/dist/extensions/subagent/constants.d.ts.map +1 -1
- package/dist/extensions/subagent/constants.js +1 -0
- package/dist/extensions/subagent/constants.js.map +1 -1
- package/dist/extensions/subagent/index.d.ts.map +1 -1
- package/dist/extensions/subagent/index.js +1 -0
- package/dist/extensions/subagent/index.js.map +1 -1
- package/dist/extensions/subagent/render.d.ts +8 -1
- package/dist/extensions/subagent/render.d.ts.map +1 -1
- package/dist/extensions/subagent/render.js +148 -178
- package/dist/extensions/subagent/render.js.map +1 -1
- package/dist/extensions/subagent/runner.d.ts +1 -0
- package/dist/extensions/subagent/runner.d.ts.map +1 -1
- package/dist/extensions/subagent/runner.js +53 -44
- package/dist/extensions/subagent/runner.js.map +1 -1
- package/dist/extensions/subagent/sdk-runner.d.ts.map +1 -1
- package/dist/extensions/subagent/sdk-runner.js +0 -3
- package/dist/extensions/subagent/sdk-runner.js.map +1 -1
- package/dist/extensions/subagent/settings.d.ts +1 -1
- package/dist/extensions/subagent/settings.d.ts.map +1 -1
- package/dist/extensions/subagent/settings.js +74 -25
- package/dist/extensions/subagent/settings.js.map +1 -1
- package/dist/extensions/subagent/state.d.ts +1 -0
- package/dist/extensions/subagent/state.d.ts.map +1 -1
- package/dist/extensions/subagent/state.js +46 -16
- package/dist/extensions/subagent/state.js.map +1 -1
- package/dist/extensions/subagent/types.d.ts +0 -7
- package/dist/extensions/subagent/types.d.ts.map +1 -1
- package/dist/extensions/subagent/types.js.map +1 -1
- package/dist/extensions/subagent/ui/agents-dialog.js +1 -1
- package/dist/extensions/subagent/ui/agents-dialog.js.map +1 -1
- package/dist/extensions/subagent/ui/model-list.d.ts.map +1 -1
- package/dist/extensions/subagent/ui/model-list.js +3 -4
- package/dist/extensions/subagent/ui/model-list.js.map +1 -1
- package/dist/extensions/subagent/ui/model-picker.d.ts.map +1 -1
- package/dist/extensions/subagent/ui/model-picker.js +2 -1
- package/dist/extensions/subagent/ui/model-picker.js.map +1 -1
- package/dist/extensions/web-search/constants.d.ts +2 -2
- package/dist/extensions/web-search/constants.d.ts.map +1 -1
- package/dist/extensions/web-search/constants.js +4 -5
- package/dist/extensions/web-search/constants.js.map +1 -1
- package/dist/extensions/web-search/execute.d.ts +13 -0
- package/dist/extensions/web-search/execute.d.ts.map +1 -0
- package/dist/extensions/web-search/execute.js +101 -0
- package/dist/extensions/web-search/execute.js.map +1 -0
- package/dist/extensions/web-search/format.d.ts +12 -0
- package/dist/extensions/web-search/format.d.ts.map +1 -0
- package/dist/extensions/web-search/format.js +109 -0
- package/dist/extensions/web-search/format.js.map +1 -0
- package/dist/extensions/web-search/index.d.ts.map +1 -1
- package/dist/extensions/web-search/index.js +12 -9
- package/dist/extensions/web-search/index.js.map +1 -1
- package/dist/extensions/web-search/providers/deepseek.d.ts +0 -2
- package/dist/extensions/web-search/providers/deepseek.d.ts.map +1 -1
- package/dist/extensions/web-search/providers/deepseek.js +82 -34
- package/dist/extensions/web-search/providers/deepseek.js.map +1 -1
- package/dist/extensions/web-search/providers/http.d.ts +2 -7
- package/dist/extensions/web-search/providers/http.d.ts.map +1 -1
- package/dist/extensions/web-search/providers/http.js +30 -13
- package/dist/extensions/web-search/providers/http.js.map +1 -1
- package/dist/extensions/web-search/providers/minimax.d.ts +0 -2
- package/dist/extensions/web-search/providers/minimax.d.ts.map +1 -1
- package/dist/extensions/web-search/providers/minimax.js +43 -50
- package/dist/extensions/web-search/providers/minimax.js.map +1 -1
- package/dist/extensions/web-search/render.d.ts +1 -2
- package/dist/extensions/web-search/render.d.ts.map +1 -1
- package/dist/extensions/web-search/render.js +22 -17
- package/dist/extensions/web-search/render.js.map +1 -1
- package/dist/extensions/web-search/results.d.ts +35 -0
- package/dist/extensions/web-search/results.d.ts.map +1 -0
- package/dist/extensions/web-search/results.js +172 -0
- package/dist/extensions/web-search/results.js.map +1 -0
- package/dist/extensions/web-search/schema.d.ts +0 -2
- package/dist/extensions/web-search/schema.d.ts.map +1 -1
- package/dist/extensions/web-search/schema.js +4 -25
- package/dist/extensions/web-search/schema.js.map +1 -1
- package/dist/extensions/web-search/types.d.ts +0 -62
- package/dist/extensions/web-search/types.d.ts.map +1 -1
- package/dist/extensions/web-search/types.js.map +1 -1
- package/dist/modes/interactive/components/tool-execution.d.ts +1 -0
- package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/tool-execution.js +7 -0
- package/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/dist/modes/interactive/components/tool-group.d.ts.map +1 -1
- package/dist/modes/interactive/components/tool-group.js +10 -0
- package/dist/modes/interactive/components/tool-group.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +3 -40
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/theme/theme.d.ts +0 -4
- package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme.js +16 -23
- package/dist/modes/interactive/theme/theme.js.map +1 -1
- package/dist/utils/http-response.d.ts +10 -0
- package/dist/utils/http-response.d.ts.map +1 -0
- package/dist/utils/http-response.js +68 -0
- package/dist/utils/http-response.js.map +1 -0
- package/docs/bundled/extensions/background.md +2 -1
- package/docs/bundled/extensions/deepwiki.md +7 -5
- package/docs/bundled/extensions/question.md +6 -4
- package/docs/bundled/extensions/router.md +1 -1
- package/docs/bundled/extensions/statusline.md +1 -0
- package/docs/bundled/extensions/subagent.md +29 -39
- package/docs/bundled/extensions/web-search.md +8 -12
- package/docs/development.md +7 -2
- package/docs/docs.json +4 -0
- package/docs/extensions.md +2 -2
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
- package/dist/extensions/web-search/fusion.d.ts +0 -36
- package/dist/extensions/web-search/fusion.d.ts.map +0 -1
- package/dist/extensions/web-search/fusion.js +0 -272
- package/dist/extensions/web-search/fusion.js.map +0 -1
|
@@ -1,23 +1,69 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* deepseek.ts — DeepSeek Messages API search provider (claude-sonnet-search model with web_search_20250305).
|
|
3
3
|
*/
|
|
4
|
+
import { MAX_PROVIDER_HIT_SCAN } from "../results.js";
|
|
4
5
|
import { postJson } from "./http.js";
|
|
5
6
|
const DEFAULT_DEEPSEEK_MESSAGES_ENDPOINT = "https://api.deepseek.com/anthropic/v1/messages";
|
|
6
7
|
const DEFAULT_DEEPSEEK_SEARCH_MODEL = "claude-sonnet-search";
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
8
|
+
function isRecord(value) {
|
|
9
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
10
|
+
}
|
|
11
|
+
function stringField(record, key) {
|
|
12
|
+
const value = record[key];
|
|
13
|
+
return typeof value === "string" ? value : undefined;
|
|
14
|
+
}
|
|
15
|
+
function parseSearchHit(value) {
|
|
16
|
+
if (!isRecord(value) || value.type !== "web_search_result")
|
|
17
|
+
return undefined;
|
|
18
|
+
const url = stringField(value, "url")?.trim();
|
|
19
|
+
if (!url)
|
|
20
|
+
return undefined;
|
|
21
|
+
const title = stringField(value, "title")?.trim();
|
|
22
|
+
const pageAge = stringField(value, "page_age")?.trim();
|
|
23
|
+
return {
|
|
24
|
+
title: title || url,
|
|
25
|
+
url,
|
|
26
|
+
date: pageAge || undefined,
|
|
27
|
+
sources: ["DeepSeek"],
|
|
13
28
|
};
|
|
14
|
-
|
|
15
|
-
|
|
29
|
+
}
|
|
30
|
+
function errorMessage(value) {
|
|
31
|
+
if (!isRecord(value))
|
|
32
|
+
return undefined;
|
|
33
|
+
return stringField(value, "message") || stringField(value, "type") || "Unknown error";
|
|
34
|
+
}
|
|
35
|
+
function searchToolErrorMessage(value) {
|
|
36
|
+
return (stringField(value, "message")?.trim() ||
|
|
37
|
+
stringField(value, "error_code")?.trim() ||
|
|
38
|
+
stringField(value, "type")?.trim() ||
|
|
39
|
+
"Unknown search tool error");
|
|
40
|
+
}
|
|
41
|
+
function parseSearchToolContent(value) {
|
|
42
|
+
if (Array.isArray(value)) {
|
|
43
|
+
const hits = [];
|
|
44
|
+
for (const item of value) {
|
|
45
|
+
const hit = parseSearchHit(item);
|
|
46
|
+
if (!hit)
|
|
47
|
+
throw new Error("DeepSeek returned malformed web_search_tool_result content");
|
|
48
|
+
if (hits.length < MAX_PROVIDER_HIT_SCAN)
|
|
49
|
+
hits.push(hit);
|
|
50
|
+
}
|
|
51
|
+
return hits;
|
|
16
52
|
}
|
|
17
|
-
|
|
18
|
-
|
|
53
|
+
if (isRecord(value)) {
|
|
54
|
+
if (value.type === "web_search_tool_result_error" ||
|
|
55
|
+
value.error_code !== undefined ||
|
|
56
|
+
value.message !== undefined) {
|
|
57
|
+
throw new Error(`DeepSeek web search failed: ${searchToolErrorMessage(value)}`);
|
|
58
|
+
}
|
|
59
|
+
throw new Error("DeepSeek returned malformed web_search_tool_result content");
|
|
19
60
|
}
|
|
20
|
-
|
|
61
|
+
throw new Error("DeepSeek returned malformed web_search_tool_result content");
|
|
62
|
+
}
|
|
63
|
+
export async function searchDeepSeek(options) {
|
|
64
|
+
const endpoint = options.baseUrl || DEFAULT_DEEPSEEK_MESSAGES_ENDPOINT;
|
|
65
|
+
const model = options.model || DEFAULT_DEEPSEEK_SEARCH_MODEL;
|
|
66
|
+
const rawData = await postJson(endpoint, {
|
|
21
67
|
"Content-Type": "application/json",
|
|
22
68
|
"x-api-key": options.apiKey,
|
|
23
69
|
Authorization: `Bearer ${options.apiKey}`,
|
|
@@ -26,38 +72,40 @@ export async function searchDeepSeek(options) {
|
|
|
26
72
|
model,
|
|
27
73
|
max_tokens: 1024,
|
|
28
74
|
messages: [{ role: "user", content: options.query }],
|
|
29
|
-
tools: [
|
|
75
|
+
tools: [{ type: "web_search_20250305", name: "web_search" }],
|
|
30
76
|
}, options.signal, 90_000, "DeepSeek Messages search API");
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
77
|
+
const data = isRecord(rawData) ? rawData : {};
|
|
78
|
+
const upstreamError = errorMessage(data.error);
|
|
79
|
+
if (upstreamError)
|
|
80
|
+
throw new Error(`DeepSeek search error: ${upstreamError}`);
|
|
34
81
|
const hits = [];
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
});
|
|
47
|
-
}
|
|
82
|
+
const synthesisParts = [];
|
|
83
|
+
let sawStructuredResult = false;
|
|
84
|
+
const content = Array.isArray(data.content) ? data.content : [];
|
|
85
|
+
for (const value of content) {
|
|
86
|
+
if (!isRecord(value))
|
|
87
|
+
continue;
|
|
88
|
+
if (value.type === "web_search_tool_result") {
|
|
89
|
+
sawStructuredResult = true;
|
|
90
|
+
for (const hit of parseSearchToolContent(value.content)) {
|
|
91
|
+
if (hits.length < MAX_PROVIDER_HIT_SCAN)
|
|
92
|
+
hits.push(hit);
|
|
48
93
|
}
|
|
94
|
+
continue;
|
|
49
95
|
}
|
|
50
|
-
|
|
51
|
-
const
|
|
52
|
-
if (
|
|
53
|
-
|
|
54
|
-
}
|
|
96
|
+
if (value.type === "text") {
|
|
97
|
+
const text = stringField(value, "text")?.trim();
|
|
98
|
+
if (text)
|
|
99
|
+
synthesisParts.push(text);
|
|
55
100
|
}
|
|
56
101
|
}
|
|
102
|
+
if (!sawStructuredResult) {
|
|
103
|
+
throw new Error("DeepSeek returned no web_search_tool_result block");
|
|
104
|
+
}
|
|
57
105
|
return {
|
|
58
106
|
source: "DeepSeek",
|
|
59
107
|
hits,
|
|
60
|
-
synthesisText:
|
|
108
|
+
synthesisText: synthesisParts.length > 0 ? synthesisParts.join("\n\n") : undefined,
|
|
61
109
|
};
|
|
62
110
|
}
|
|
63
111
|
//# sourceMappingURL=deepseek.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deepseek.js","sourceRoot":"","sources":["../../../../src/extensions/web-search/providers/deepseek.ts"],"names":[],"mappings":"AAAA;;GAEG;
|
|
1
|
+
{"version":3,"file":"deepseek.js","sourceRoot":"","sources":["../../../../src/extensions/web-search/providers/deepseek.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * deepseek.ts — DeepSeek Messages API search provider (claude-sonnet-search model with web_search_20250305).\n */\n\nimport { MAX_PROVIDER_HIT_SCAN } from \"../results.ts\";\nimport type { ProviderSearchResult, WebSearchHit } from \"../types.ts\";\nimport { postJson } from \"./http.ts\";\n\nexport interface DeepSeekSearchOptions {\n\tquery: string;\n\tapiKey: string;\n\tbaseUrl?: string;\n\tmodel?: string;\n\tsignal?: AbortSignal;\n}\n\nconst DEFAULT_DEEPSEEK_MESSAGES_ENDPOINT = \"https://api.deepseek.com/anthropic/v1/messages\";\nconst DEFAULT_DEEPSEEK_SEARCH_MODEL = \"claude-sonnet-search\";\n\ntype JsonRecord = Record<string, unknown>;\n\nfunction isRecord(value: unknown): value is JsonRecord {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction stringField(record: JsonRecord, key: string): string | undefined {\n\tconst value = record[key];\n\treturn typeof value === \"string\" ? value : undefined;\n}\n\nfunction parseSearchHit(value: unknown): WebSearchHit | undefined {\n\tif (!isRecord(value) || value.type !== \"web_search_result\") return undefined;\n\tconst url = stringField(value, \"url\")?.trim();\n\tif (!url) return undefined;\n\tconst title = stringField(value, \"title\")?.trim();\n\tconst pageAge = stringField(value, \"page_age\")?.trim();\n\treturn {\n\t\ttitle: title || url,\n\t\turl,\n\t\tdate: pageAge || undefined,\n\t\tsources: [\"DeepSeek\"],\n\t};\n}\n\nfunction errorMessage(value: unknown): string | undefined {\n\tif (!isRecord(value)) return undefined;\n\treturn stringField(value, \"message\") || stringField(value, \"type\") || \"Unknown error\";\n}\n\nfunction searchToolErrorMessage(value: JsonRecord): string {\n\treturn (\n\t\tstringField(value, \"message\")?.trim() ||\n\t\tstringField(value, \"error_code\")?.trim() ||\n\t\tstringField(value, \"type\")?.trim() ||\n\t\t\"Unknown search tool error\"\n\t);\n}\n\nfunction parseSearchToolContent(value: unknown): WebSearchHit[] {\n\tif (Array.isArray(value)) {\n\t\tconst hits: WebSearchHit[] = [];\n\t\tfor (const item of value) {\n\t\t\tconst hit = parseSearchHit(item);\n\t\t\tif (!hit) throw new Error(\"DeepSeek returned malformed web_search_tool_result content\");\n\t\t\tif (hits.length < MAX_PROVIDER_HIT_SCAN) hits.push(hit);\n\t\t}\n\t\treturn hits;\n\t}\n\tif (isRecord(value)) {\n\t\tif (\n\t\t\tvalue.type === \"web_search_tool_result_error\" ||\n\t\t\tvalue.error_code !== undefined ||\n\t\t\tvalue.message !== undefined\n\t\t) {\n\t\t\tthrow new Error(`DeepSeek web search failed: ${searchToolErrorMessage(value)}`);\n\t\t}\n\t\tthrow new Error(\"DeepSeek returned malformed web_search_tool_result content\");\n\t}\n\tthrow new Error(\"DeepSeek returned malformed web_search_tool_result content\");\n}\n\nexport async function searchDeepSeek(options: DeepSeekSearchOptions): Promise<ProviderSearchResult> {\n\tconst endpoint = options.baseUrl || DEFAULT_DEEPSEEK_MESSAGES_ENDPOINT;\n\tconst model = options.model || DEFAULT_DEEPSEEK_SEARCH_MODEL;\n\tconst rawData = await postJson<unknown>(\n\t\tendpoint,\n\t\t{\n\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\"x-api-key\": options.apiKey,\n\t\t\tAuthorization: `Bearer ${options.apiKey}`,\n\t\t\t\"anthropic-version\": \"2023-06-01\",\n\t\t},\n\t\t{\n\t\t\tmodel,\n\t\t\tmax_tokens: 1024,\n\t\t\tmessages: [{ role: \"user\", content: options.query }],\n\t\t\ttools: [{ type: \"web_search_20250305\", name: \"web_search\" }],\n\t\t},\n\t\toptions.signal,\n\t\t90_000,\n\t\t\"DeepSeek Messages search API\",\n\t);\n\tconst data = isRecord(rawData) ? rawData : {};\n\tconst upstreamError = errorMessage(data.error);\n\tif (upstreamError) throw new Error(`DeepSeek search error: ${upstreamError}`);\n\n\tconst hits: WebSearchHit[] = [];\n\tconst synthesisParts: string[] = [];\n\tlet sawStructuredResult = false;\n\tconst content = Array.isArray(data.content) ? data.content : [];\n\tfor (const value of content) {\n\t\tif (!isRecord(value)) continue;\n\t\tif (value.type === \"web_search_tool_result\") {\n\t\t\tsawStructuredResult = true;\n\t\t\tfor (const hit of parseSearchToolContent(value.content)) {\n\t\t\t\tif (hits.length < MAX_PROVIDER_HIT_SCAN) hits.push(hit);\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\t\tif (value.type === \"text\") {\n\t\t\tconst text = stringField(value, \"text\")?.trim();\n\t\t\tif (text) synthesisParts.push(text);\n\t\t}\n\t}\n\tif (!sawStructuredResult) {\n\t\tthrow new Error(\"DeepSeek returned no web_search_tool_result block\");\n\t}\n\n\treturn {\n\t\tsource: \"DeepSeek\",\n\t\thits,\n\t\tsynthesisText: synthesisParts.length > 0 ? synthesisParts.join(\"\\n\\n\") : undefined,\n\t};\n}\n"]}
|
|
@@ -1,9 +1,4 @@
|
|
|
1
|
-
/**
|
|
2
|
-
|
|
3
|
-
* per-request timeout, bounded upstream error bodies, clear parse errors.
|
|
4
|
-
*/
|
|
5
|
-
/**
|
|
6
|
-
* POST a JSON body and return the parsed response.
|
|
7
|
-
*/
|
|
1
|
+
/** JSON POST plumbing for search providers. */
|
|
2
|
+
/** POST a JSON body and return the parsed response. */
|
|
8
3
|
export declare function postJson<T>(url: string, headers: Record<string, string>, body: unknown, signal: AbortSignal | undefined, timeoutMs: number, errorLabel: string): Promise<T>;
|
|
9
4
|
//# sourceMappingURL=http.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../../../src/extensions/web-search/providers/http.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../../../src/extensions/web-search/providers/http.ts"],"names":[],"mappings":"AAAA,+CAA+C;AAU/C,uDAAuD;AACvD,wBAAsB,QAAQ,CAAC,CAAC,EAC/B,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC/B,IAAI,EAAE,OAAO,EACb,MAAM,EAAE,WAAW,GAAG,SAAS,EAC/B,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,GAChB,OAAO,CAAC,CAAC,CAAC,CAiCZ"}
|
|
@@ -1,25 +1,42 @@
|
|
|
1
|
-
/**
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
/** JSON POST plumbing for search providers. */
|
|
2
|
+
import { readResponseTextBounded } from "../../../utils/http-response.js";
|
|
3
|
+
/** Successful response bodies are model-facing; keep them bounded. */
|
|
4
|
+
const MAX_RESPONSE_BODY_BYTES = 2 * 1024 * 1024;
|
|
5
5
|
/** Error bodies are surfaced to the model; keep them bounded. */
|
|
6
|
-
const
|
|
7
|
-
/**
|
|
8
|
-
* POST a JSON body and return the parsed response.
|
|
9
|
-
*/
|
|
6
|
+
const MAX_ERROR_BODY_BYTES = 200;
|
|
7
|
+
/** POST a JSON body and return the parsed response. */
|
|
10
8
|
export async function postJson(url, headers, body, signal, timeoutMs, errorLabel) {
|
|
9
|
+
const timeoutSignal = AbortSignal.timeout(timeoutMs);
|
|
10
|
+
const requestSignal = signal ? AbortSignal.any([signal, timeoutSignal]) : timeoutSignal;
|
|
11
11
|
const response = await fetch(url, {
|
|
12
12
|
method: "POST",
|
|
13
13
|
headers,
|
|
14
14
|
body: JSON.stringify(body),
|
|
15
|
-
signal:
|
|
15
|
+
signal: requestSignal,
|
|
16
16
|
});
|
|
17
17
|
if (!response.ok) {
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
let errorText = "";
|
|
19
|
+
try {
|
|
20
|
+
errorText = await readResponseTextBounded(response, {
|
|
21
|
+
maxBytes: MAX_ERROR_BODY_BYTES,
|
|
22
|
+
signal: requestSignal,
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
requestSignal.throwIfAborted();
|
|
27
|
+
}
|
|
28
|
+
throw new Error(`${errorLabel} returned HTTP ${response.status} ${response.statusText}: ${errorText}`);
|
|
20
29
|
}
|
|
21
|
-
|
|
30
|
+
const responseText = await readResponseTextBounded(response, {
|
|
31
|
+
maxBytes: MAX_RESPONSE_BODY_BYTES,
|
|
32
|
+
overflowMessage: `${errorLabel} response exceeded ${MAX_RESPONSE_BODY_BYTES} bytes`,
|
|
33
|
+
signal: requestSignal,
|
|
34
|
+
});
|
|
35
|
+
try {
|
|
36
|
+
return JSON.parse(responseText);
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
22
39
|
throw new Error(`${errorLabel} returned invalid JSON`);
|
|
23
|
-
}
|
|
40
|
+
}
|
|
24
41
|
}
|
|
25
42
|
//# sourceMappingURL=http.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http.js","sourceRoot":"","sources":["../../../../src/extensions/web-search/providers/http.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"http.js","sourceRoot":"","sources":["../../../../src/extensions/web-search/providers/http.ts"],"names":[],"mappings":"AAAA,+CAA+C;AAE/C,OAAO,EAAE,uBAAuB,EAAE,MAAM,iCAAiC,CAAC;AAE1E,sEAAsE;AACtE,MAAM,uBAAuB,GAAG,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC;AAEhD,iEAAiE;AACjE,MAAM,oBAAoB,GAAG,GAAG,CAAC;AAEjC,uDAAuD;AACvD,MAAM,CAAC,KAAK,UAAU,QAAQ,CAC7B,GAAW,EACX,OAA+B,EAC/B,IAAa,EACb,MAA+B,EAC/B,SAAiB,EACjB,UAAkB;IAElB,MAAM,aAAa,GAAG,WAAW,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IACrD,MAAM,aAAa,GAAG,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC;IACxF,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;QACjC,MAAM,EAAE,MAAM;QACd,OAAO;QACP,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;QAC1B,MAAM,EAAE,aAAa;KACrB,CAAC,CAAC;IAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QAClB,IAAI,SAAS,GAAG,EAAE,CAAC;QACnB,IAAI,CAAC;YACJ,SAAS,GAAG,MAAM,uBAAuB,CAAC,QAAQ,EAAE;gBACnD,QAAQ,EAAE,oBAAoB;gBAC9B,MAAM,EAAE,aAAa;aACrB,CAAC,CAAC;QACJ,CAAC;QAAC,MAAM,CAAC;YACR,aAAa,CAAC,cAAc,EAAE,CAAC;QAChC,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,GAAG,UAAU,kBAAkB,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC,CAAC;IACxG,CAAC;IAED,MAAM,YAAY,GAAG,MAAM,uBAAuB,CAAC,QAAQ,EAAE;QAC5D,QAAQ,EAAE,uBAAuB;QACjC,eAAe,EAAE,GAAG,UAAU,sBAAsB,uBAAuB,QAAQ;QACnF,MAAM,EAAE,aAAa;KACrB,CAAC,CAAC;IACH,IAAI,CAAC;QACJ,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,CAAM,CAAC;IACtC,CAAC;IAAC,MAAM,CAAC;QACR,MAAM,IAAI,KAAK,CAAC,GAAG,UAAU,wBAAwB,CAAC,CAAC;IACxD,CAAC;AACF,CAAC","sourcesContent":["/** JSON POST plumbing for search providers. */\n\nimport { readResponseTextBounded } from \"../../../utils/http-response.ts\";\n\n/** Successful response bodies are model-facing; keep them bounded. */\nconst MAX_RESPONSE_BODY_BYTES = 2 * 1024 * 1024;\n\n/** Error bodies are surfaced to the model; keep them bounded. */\nconst MAX_ERROR_BODY_BYTES = 200;\n\n/** POST a JSON body and return the parsed response. */\nexport async function postJson<T>(\n\turl: string,\n\theaders: Record<string, string>,\n\tbody: unknown,\n\tsignal: AbortSignal | undefined,\n\ttimeoutMs: number,\n\terrorLabel: string,\n): Promise<T> {\n\tconst timeoutSignal = AbortSignal.timeout(timeoutMs);\n\tconst requestSignal = signal ? AbortSignal.any([signal, timeoutSignal]) : timeoutSignal;\n\tconst response = await fetch(url, {\n\t\tmethod: \"POST\",\n\t\theaders,\n\t\tbody: JSON.stringify(body),\n\t\tsignal: requestSignal,\n\t});\n\n\tif (!response.ok) {\n\t\tlet errorText = \"\";\n\t\ttry {\n\t\t\terrorText = await readResponseTextBounded(response, {\n\t\t\t\tmaxBytes: MAX_ERROR_BODY_BYTES,\n\t\t\t\tsignal: requestSignal,\n\t\t\t});\n\t\t} catch {\n\t\t\trequestSignal.throwIfAborted();\n\t\t}\n\t\tthrow new Error(`${errorLabel} returned HTTP ${response.status} ${response.statusText}: ${errorText}`);\n\t}\n\n\tconst responseText = await readResponseTextBounded(response, {\n\t\tmaxBytes: MAX_RESPONSE_BODY_BYTES,\n\t\toverflowMessage: `${errorLabel} response exceeded ${MAX_RESPONSE_BODY_BYTES} bytes`,\n\t\tsignal: requestSignal,\n\t});\n\ttry {\n\t\treturn JSON.parse(responseText) as T;\n\t} catch {\n\t\tthrow new Error(`${errorLabel} returned invalid JSON`);\n\t}\n}\n"]}
|
|
@@ -7,8 +7,6 @@ export interface MiniMaxSearchOptions {
|
|
|
7
7
|
apiKey: string;
|
|
8
8
|
apiHost?: string;
|
|
9
9
|
signal?: AbortSignal;
|
|
10
|
-
allowedDomains?: string[];
|
|
11
|
-
blockedDomains?: string[];
|
|
12
10
|
}
|
|
13
11
|
export declare function searchMiniMax(options: MiniMaxSearchOptions): Promise<ProviderSearchResult>;
|
|
14
12
|
//# sourceMappingURL=minimax.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"minimax.d.ts","sourceRoot":"","sources":["../../../../src/extensions/web-search/providers/minimax.ts"],"names":[],"mappings":"AAAA;;GAEG;
|
|
1
|
+
{"version":3,"file":"minimax.d.ts","sourceRoot":"","sources":["../../../../src/extensions/web-search/providers/minimax.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,oBAAoB,EAAgB,MAAM,aAAa,CAAC;AAGtE,MAAM,WAAW,oBAAoB;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,WAAW,CAAC;CACrB;AA0BD,wBAAsB,aAAa,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,oBAAoB,CAAC,CA4ChG"}
|
|
@@ -1,69 +1,62 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* minimax.ts — MiniMax Coding Plan Search REST API provider.
|
|
3
3
|
*/
|
|
4
|
+
import { MAX_PROVIDER_HIT_SCAN, MAX_PROVIDER_RELATED_SCAN, MAX_RELATED_SEARCHES } from "../results.js";
|
|
4
5
|
import { postJson } from "./http.js";
|
|
5
|
-
function
|
|
6
|
-
|
|
7
|
-
if (allowedDomains && allowedDomains.length > 0) {
|
|
8
|
-
const siteFilter = allowedDomains.map((d) => `site:${d.trim()}`).join(" OR ");
|
|
9
|
-
q = `${q} (${siteFilter})`;
|
|
10
|
-
}
|
|
11
|
-
else if (blockedDomains && blockedDomains.length > 0) {
|
|
12
|
-
const blockFilter = blockedDomains.map((d) => `-site:${d.trim()}`).join(" ");
|
|
13
|
-
q = `${q} ${blockFilter}`;
|
|
14
|
-
}
|
|
15
|
-
return q;
|
|
6
|
+
function isRecord(value) {
|
|
7
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
16
8
|
}
|
|
17
|
-
function
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
9
|
+
function stringField(record, key) {
|
|
10
|
+
const value = record[key];
|
|
11
|
+
return typeof value === "string" ? value : undefined;
|
|
12
|
+
}
|
|
13
|
+
function parseSearchHit(value) {
|
|
14
|
+
if (!isRecord(value))
|
|
15
|
+
return undefined;
|
|
16
|
+
const url = stringField(value, "link")?.trim();
|
|
17
|
+
if (!url)
|
|
18
|
+
return undefined;
|
|
19
|
+
return {
|
|
20
|
+
title: stringField(value, "title")?.trim() || url,
|
|
21
|
+
url,
|
|
22
|
+
snippet: stringField(value, "snippet")?.trim() || undefined,
|
|
23
|
+
date: stringField(value, "date")?.trim() || undefined,
|
|
24
|
+
sources: ["MiniMax"],
|
|
25
|
+
};
|
|
32
26
|
}
|
|
33
27
|
export async function searchMiniMax(options) {
|
|
34
28
|
const host = options.apiHost?.replace(/\/+$/, "") || "https://api.minimaxi.com";
|
|
35
|
-
const
|
|
36
|
-
const data = await postJson(`${host}/v1/coding_plan/search`, {
|
|
29
|
+
const rawData = await postJson(`${host}/v1/coding_plan/search`, {
|
|
37
30
|
"Content-Type": "application/json",
|
|
38
31
|
Authorization: `Bearer ${options.apiKey}`,
|
|
39
|
-
}, { q:
|
|
40
|
-
|
|
41
|
-
|
|
32
|
+
}, { q: options.query.trim() }, options.signal, 60_000, "MiniMax search API");
|
|
33
|
+
const data = isRecord(rawData) ? rawData : {};
|
|
34
|
+
const baseResponse = isRecord(data.base_resp) ? data.base_resp : undefined;
|
|
35
|
+
const statusCode = baseResponse?.status_code;
|
|
36
|
+
if (baseResponse && typeof statusCode === "number" && statusCode !== 0) {
|
|
37
|
+
throw new Error(`MiniMax search failed: [${statusCode}] ${stringField(baseResponse, "status_msg") ?? "Unknown error"}`);
|
|
42
38
|
}
|
|
43
|
-
const rawHits = data.organic || [];
|
|
44
39
|
const hits = [];
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
const
|
|
49
|
-
if (
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
40
|
+
const organic = Array.isArray(data.organic) ? data.organic : [];
|
|
41
|
+
const hitScanLimit = Math.min(organic.length, MAX_PROVIDER_HIT_SCAN);
|
|
42
|
+
for (let index = 0; index < hitScanLimit; index++) {
|
|
43
|
+
const hit = parseSearchHit(organic[index]);
|
|
44
|
+
if (hit)
|
|
45
|
+
hits.push(hit);
|
|
46
|
+
}
|
|
47
|
+
const relatedSearches = [];
|
|
48
|
+
const related = Array.isArray(data.related_searches) ? data.related_searches : [];
|
|
49
|
+
const relatedScanLimit = Math.min(related.length, MAX_PROVIDER_RELATED_SCAN);
|
|
50
|
+
for (let index = 0; index < relatedScanLimit && relatedSearches.length < MAX_RELATED_SEARCHES; index++) {
|
|
51
|
+
const value = related[index];
|
|
52
|
+
const query = isRecord(value) ? stringField(value, "query")?.trim() : undefined;
|
|
53
|
+
if (query)
|
|
54
|
+
relatedSearches.push(query);
|
|
59
55
|
}
|
|
60
|
-
const relatedSearches = data.related_searches
|
|
61
|
-
?.map((r) => r.query?.trim())
|
|
62
|
-
.filter((q) => Boolean(q && q.length > 0));
|
|
63
56
|
return {
|
|
64
57
|
source: "MiniMax",
|
|
65
58
|
hits,
|
|
66
|
-
relatedSearches: relatedSearches
|
|
59
|
+
relatedSearches: relatedSearches.length > 0 ? relatedSearches : undefined,
|
|
67
60
|
};
|
|
68
61
|
}
|
|
69
62
|
//# sourceMappingURL=minimax.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"minimax.js","sourceRoot":"","sources":["../../../../src/extensions/web-search/providers/minimax.ts"],"names":[],"mappings":"AAAA;;GAEG;
|
|
1
|
+
{"version":3,"file":"minimax.js","sourceRoot":"","sources":["../../../../src/extensions/web-search/providers/minimax.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * minimax.ts — MiniMax Coding Plan Search REST API provider.\n */\n\nimport { MAX_PROVIDER_HIT_SCAN, MAX_PROVIDER_RELATED_SCAN, MAX_RELATED_SEARCHES } from \"../results.ts\";\nimport type { ProviderSearchResult, WebSearchHit } from \"../types.ts\";\nimport { postJson } from \"./http.ts\";\n\nexport interface MiniMaxSearchOptions {\n\tquery: string;\n\tapiKey: string;\n\tapiHost?: string;\n\tsignal?: AbortSignal;\n}\n\ntype JsonRecord = Record<string, unknown>;\n\nfunction isRecord(value: unknown): value is JsonRecord {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction stringField(record: JsonRecord, key: string): string | undefined {\n\tconst value = record[key];\n\treturn typeof value === \"string\" ? value : undefined;\n}\n\nfunction parseSearchHit(value: unknown): WebSearchHit | undefined {\n\tif (!isRecord(value)) return undefined;\n\tconst url = stringField(value, \"link\")?.trim();\n\tif (!url) return undefined;\n\treturn {\n\t\ttitle: stringField(value, \"title\")?.trim() || url,\n\t\turl,\n\t\tsnippet: stringField(value, \"snippet\")?.trim() || undefined,\n\t\tdate: stringField(value, \"date\")?.trim() || undefined,\n\t\tsources: [\"MiniMax\"],\n\t};\n}\n\nexport async function searchMiniMax(options: MiniMaxSearchOptions): Promise<ProviderSearchResult> {\n\tconst host = options.apiHost?.replace(/\\/+$/, \"\") || \"https://api.minimaxi.com\";\n\tconst rawData = await postJson<unknown>(\n\t\t`${host}/v1/coding_plan/search`,\n\t\t{\n\t\t\t\"Content-Type\": \"application/json\",\n\t\t\tAuthorization: `Bearer ${options.apiKey}`,\n\t\t},\n\t\t{ q: options.query.trim() },\n\t\toptions.signal,\n\t\t60_000,\n\t\t\"MiniMax search API\",\n\t);\n\tconst data = isRecord(rawData) ? rawData : {};\n\tconst baseResponse = isRecord(data.base_resp) ? data.base_resp : undefined;\n\tconst statusCode = baseResponse?.status_code;\n\tif (baseResponse && typeof statusCode === \"number\" && statusCode !== 0) {\n\t\tthrow new Error(\n\t\t\t`MiniMax search failed: [${statusCode}] ${stringField(baseResponse, \"status_msg\") ?? \"Unknown error\"}`,\n\t\t);\n\t}\n\n\tconst hits: WebSearchHit[] = [];\n\tconst organic = Array.isArray(data.organic) ? data.organic : [];\n\tconst hitScanLimit = Math.min(organic.length, MAX_PROVIDER_HIT_SCAN);\n\tfor (let index = 0; index < hitScanLimit; index++) {\n\t\tconst hit = parseSearchHit(organic[index]);\n\t\tif (hit) hits.push(hit);\n\t}\n\n\tconst relatedSearches: string[] = [];\n\tconst related = Array.isArray(data.related_searches) ? data.related_searches : [];\n\tconst relatedScanLimit = Math.min(related.length, MAX_PROVIDER_RELATED_SCAN);\n\tfor (let index = 0; index < relatedScanLimit && relatedSearches.length < MAX_RELATED_SEARCHES; index++) {\n\t\tconst value = related[index];\n\t\tconst query = isRecord(value) ? stringField(value, \"query\")?.trim() : undefined;\n\t\tif (query) relatedSearches.push(query);\n\t}\n\n\treturn {\n\t\tsource: \"MiniMax\",\n\t\thits,\n\t\trelatedSearches: relatedSearches.length > 0 ? relatedSearches : undefined,\n\t};\n}\n"]}
|
|
@@ -4,8 +4,7 @@
|
|
|
4
4
|
import { type Component } from "@earendil-works/pi-tui";
|
|
5
5
|
import type { AgentToolResult, ToolRenderResultOptions } from "../../core/extensions/types.ts";
|
|
6
6
|
import { type Theme } from "../../modes/interactive/theme/theme.ts";
|
|
7
|
-
import type { WebSearchParams } from "./schema.ts";
|
|
8
7
|
import type { WebSearchDetails } from "./types.ts";
|
|
9
|
-
export declare function renderWebSearchCall(args:
|
|
8
|
+
export declare function renderWebSearchCall(args: unknown, theme: Theme): Component;
|
|
10
9
|
export declare function renderWebSearchResult(result: AgentToolResult<WebSearchDetails>, options: ToolRenderResultOptions, theme: Theme, isError: boolean, elapsedMs?: number): Component;
|
|
11
10
|
//# sourceMappingURL=render.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../../src/extensions/web-search/render.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,KAAK,SAAS,EAAqC,MAAM,wBAAwB,CAAC;AAC3F,OAAO,KAAK,EAAE,eAAe,EAAE,uBAAuB,EAAE,MAAM,gCAAgC,CAAC;AAE/F,OAAO,EAAoB,KAAK,KAAK,EAAE,MAAM,wCAAwC,CAAC;
|
|
1
|
+
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../../src/extensions/web-search/render.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,KAAK,SAAS,EAAqC,MAAM,wBAAwB,CAAC;AAC3F,OAAO,KAAK,EAAE,eAAe,EAAE,uBAAuB,EAAE,MAAM,gCAAgC,CAAC;AAE/F,OAAO,EAAoB,KAAK,KAAK,EAAE,MAAM,wCAAwC,CAAC;AAItF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AA4CnD,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,GAAG,SAAS,CAO1E;AASD,wBAAgB,qBAAqB,CACpC,MAAM,EAAE,eAAe,CAAC,gBAAgB,CAAC,EACzC,OAAO,EAAE,uBAAuB,EAChC,KAAK,EAAE,KAAK,EACZ,OAAO,EAAE,OAAO,EAChB,SAAS,CAAC,EAAE,MAAM,GAChB,SAAS,CA8DX"}
|
|
@@ -5,7 +5,8 @@ import { Container, Markdown, Spacer, Text } from "@earendil-works/pi-tui";
|
|
|
5
5
|
import { keyHint } from "../../modes/interactive/components/keybinding-hints.js";
|
|
6
6
|
import { getMarkdownTheme } from "../../modes/interactive/theme/theme.js";
|
|
7
7
|
import { getEngineLabel, WEB_SEARCH_LABEL } from "./constants.js";
|
|
8
|
-
import { formatResultsMarkdown } from "./
|
|
8
|
+
import { formatResultsMarkdown } from "./format.js";
|
|
9
|
+
import { MAX_HISTORICAL_HIT_SCAN } from "./results.js";
|
|
9
10
|
/** Matches the bash/deepwiki progress display: sub-2s calls stay quiet. */
|
|
10
11
|
const ELAPSED_DISPLAY_THRESHOLD_MS = 2000;
|
|
11
12
|
function singleLine(text) {
|
|
@@ -24,11 +25,20 @@ function firstText(result) {
|
|
|
24
25
|
return "";
|
|
25
26
|
}
|
|
26
27
|
/** " · github.com, react.dev, +3" from the first-seen unique hit domains. */
|
|
27
|
-
function domainSummary(
|
|
28
|
+
function domainSummary(value) {
|
|
29
|
+
if (!Array.isArray(value))
|
|
30
|
+
return "";
|
|
28
31
|
const seen = new Set();
|
|
29
|
-
|
|
32
|
+
const scanLimit = Math.min(value.length, MAX_HISTORICAL_HIT_SCAN);
|
|
33
|
+
for (let index = 0; index < scanLimit; index++) {
|
|
34
|
+
const hit = value[index];
|
|
35
|
+
if (!hit || typeof hit !== "object")
|
|
36
|
+
continue;
|
|
37
|
+
const url = hit.url;
|
|
38
|
+
if (typeof url !== "string")
|
|
39
|
+
continue;
|
|
30
40
|
try {
|
|
31
|
-
const host = new URL(
|
|
41
|
+
const host = new URL(url).hostname.replace(/^www\./, "");
|
|
32
42
|
if (host)
|
|
33
43
|
seen.add(host);
|
|
34
44
|
}
|
|
@@ -44,14 +54,8 @@ function domainSummary(hits) {
|
|
|
44
54
|
}
|
|
45
55
|
export function renderWebSearchCall(args, theme) {
|
|
46
56
|
let line = theme.fg("toolTitle", theme.bold(`${WEB_SEARCH_LABEL} `));
|
|
47
|
-
const query = singleLine(args.query
|
|
57
|
+
const query = singleLine(args && typeof args === "object" && !Array.isArray(args) ? args.query : "");
|
|
48
58
|
line += theme.fg("accent", `"${truncateText(query, 60)}"`);
|
|
49
|
-
if (args.allowed_domains && args.allowed_domains.length > 0) {
|
|
50
|
-
line += ` ${theme.fg("muted", `[sites: ${args.allowed_domains.join(", ")}]`)}`;
|
|
51
|
-
}
|
|
52
|
-
else if (args.blocked_domains && args.blocked_domains.length > 0) {
|
|
53
|
-
line += ` ${theme.fg("muted", `[-sites: ${args.blocked_domains.join(", ")}]`)}`;
|
|
54
|
-
}
|
|
55
59
|
return new Text(line, 0, 0);
|
|
56
60
|
}
|
|
57
61
|
function markdownBlock(text) {
|
|
@@ -73,15 +77,15 @@ export function renderWebSearchResult(result, options, theme, isError, elapsedMs
|
|
|
73
77
|
}
|
|
74
78
|
const text = firstText(result);
|
|
75
79
|
const errorMessage = details?.errorMessage;
|
|
76
|
-
if (isError || details?.status === "error") {
|
|
77
|
-
const line = truncateText(errorMessage ?? (singleLine(text) || "Search request failed"), 160);
|
|
78
|
-
return new Text(theme.fg("error", `failed · ${line}`), 0, 0);
|
|
79
|
-
}
|
|
80
80
|
if (details?.status === "disabled") {
|
|
81
81
|
// Only reachable when the tool was force-enabled without credentials, or in
|
|
82
82
|
// historical sessions: the session_start hook keeps it hidden otherwise.
|
|
83
83
|
return new Text(theme.fg("warning", "disabled · no MiniMax/DeepSeek key — /login minimax-cn or export MINIMAX_API_KEY / DEEPSEEK_API_KEY"), 0, 0);
|
|
84
84
|
}
|
|
85
|
+
if (isError || details?.status === "error") {
|
|
86
|
+
const line = truncateText(errorMessage ?? (singleLine(text) || "Search request failed"), 160);
|
|
87
|
+
return new Text(theme.fg("error", `failed · ${line}`), 0, 0);
|
|
88
|
+
}
|
|
85
89
|
if (!options.expanded) {
|
|
86
90
|
const hint = `${theme.fg("muted", " (")}${keyHint("app.tools.expand", "to expand")}${theme.fg("muted", ")")}`;
|
|
87
91
|
if (!details) {
|
|
@@ -89,12 +93,13 @@ export function renderWebSearchResult(result, options, theme, isError, elapsedMs
|
|
|
89
93
|
const line = truncateText(singleLine(text), 100) || "done";
|
|
90
94
|
return new Text(`${theme.fg("toolOutput", line)}${hint}`, 0, 0);
|
|
91
95
|
}
|
|
92
|
-
const
|
|
96
|
+
const historicalHits = Array.isArray(details.hits) ? details.hits : [];
|
|
97
|
+
const hitCount = details.totalHits ?? historicalHits.length;
|
|
93
98
|
const engine = getEngineLabel(details.engine);
|
|
94
99
|
const engineLabel = engine ? ` via ${engine}` : "";
|
|
95
100
|
const duration = details.durationMs ? ` · ${(details.durationMs / 1000).toFixed(1)}s` : "";
|
|
96
101
|
const countText = hitCount === 1 ? "1 result" : hitCount === 0 ? "no results" : `${hitCount} results`;
|
|
97
|
-
const summary = theme.fg("toolOutput", truncateText(`${countText}${engineLabel}${duration}${domainSummary(
|
|
102
|
+
const summary = theme.fg("toolOutput", truncateText(`${countText}${engineLabel}${duration}${domainSummary(historicalHits)}`, 100));
|
|
98
103
|
return new Text(`${summary}${hint}`, 0, 0);
|
|
99
104
|
}
|
|
100
105
|
// Expanded: structured sections from details, without the model-facing agent
|