u1s1-cli 0.16.5 → 0.16.6
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/dist/tools.d.ts +2 -10
- package/dist/tools.js +50 -0
- package/package.json +1 -1
package/dist/tools.d.ts
CHANGED
|
@@ -4,10 +4,7 @@ import type { CliConfig } from "./config.js";
|
|
|
4
4
|
export declare function createSearchTool(cfg: Pick<CliConfig, "baseUrl" | "apiKey">): import("@earendil-works/pi-coding-agent").ToolDefinition<Type.TObject<{
|
|
5
5
|
query: Type.TString;
|
|
6
6
|
maxResults: Type.TOptional<Type.TNumber>;
|
|
7
|
-
}>,
|
|
8
|
-
query: string;
|
|
9
|
-
count: number;
|
|
10
|
-
}, any> & import("@earendil-works/pi-coding-agent").ToolDefinition<any, any, any>;
|
|
7
|
+
}>, unknown, any> & import("@earendil-works/pi-coding-agent").ToolDefinition<any, any, any>;
|
|
11
8
|
/** 生图工具:走 u1s1 网关代理火山方舟 Seedream,上游 key 不落到用户机器上。 */
|
|
12
9
|
export declare function createImageTool(cfg: Pick<CliConfig, "baseUrl" | "apiKey">): import("@earendil-works/pi-coding-agent").ToolDefinition<Type.TObject<{
|
|
13
10
|
prompt: Type.TString;
|
|
@@ -31,9 +28,4 @@ export interface FetchToolConfig {
|
|
|
31
28
|
*/
|
|
32
29
|
export declare function createFetchTool(cfg: FetchToolConfig): import("@earendil-works/pi-coding-agent").ToolDefinition<Type.TObject<{
|
|
33
30
|
url: Type.TString;
|
|
34
|
-
}>,
|
|
35
|
-
url: string;
|
|
36
|
-
contentType: string;
|
|
37
|
-
via: "direct" | "render";
|
|
38
|
-
chars: number;
|
|
39
|
-
}, any> & import("@earendil-works/pi-coding-agent").ToolDefinition<any, any, any>;
|
|
31
|
+
}>, unknown, any> & import("@earendil-works/pi-coding-agent").ToolDefinition<any, any, any>;
|
package/dist/tools.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { existsSync, mkdirSync, readFileSync, statSync, writeFileSync } from "node:fs";
|
|
2
2
|
import { dirname, extname, resolve } from "node:path";
|
|
3
3
|
import { defineTool } from "@earendil-works/pi-coding-agent";
|
|
4
|
+
import { Text } from "@earendil-works/pi-tui";
|
|
4
5
|
import { Type } from "typebox";
|
|
5
6
|
import { generateImage, renderPage, searchWeb } from "./api.js";
|
|
6
7
|
const FETCH_TIMEOUT_MS = 20_000;
|
|
@@ -75,6 +76,32 @@ function decodeBody(bytes, contentType) {
|
|
|
75
76
|
return new TextDecoder("utf-8").decode(bytes);
|
|
76
77
|
}
|
|
77
78
|
}
|
|
79
|
+
/** 压成单行并截断,给联网工具的精简展示用 */
|
|
80
|
+
function previewLine(text, max = 100) {
|
|
81
|
+
const flat = String(text).replace(/\s*\n\s*/g, " ").trim();
|
|
82
|
+
return flat.length > max ? `${flat.slice(0, max - 1)}…` : flat;
|
|
83
|
+
}
|
|
84
|
+
/** 从工具结果里取纯文本内容 */
|
|
85
|
+
function resultText(result) {
|
|
86
|
+
const c = result.content.find((x) => x.type === "text");
|
|
87
|
+
return c && c.type === "text" ? (c.text ?? "") : "";
|
|
88
|
+
}
|
|
89
|
+
/** 联网工具通用渲染:调用行不占位,收起时只显一行摘要,ctrl+o 展开全文,出错显一行 ✗ */
|
|
90
|
+
function compactResultRender(result, options,
|
|
91
|
+
// 放宽成 any 只为避开 pi 的 ThemeColor 联合类型在结构化匹配时的逆变报错;
|
|
92
|
+
// 实际传入的就是 pi 的 Theme,取值只用 "warning"/"muted" 两色
|
|
93
|
+
theme, context, summaryLine) {
|
|
94
|
+
if (context.isError) {
|
|
95
|
+
// 低调处理:✗ 用警示色,内容用灰色弱化(与内置工具的错误展示一致)
|
|
96
|
+
const msg = previewLine(resultText(result) || "error", 160);
|
|
97
|
+
return new Text(theme.fg("warning", "✗ ") + theme.fg("muted", msg), 0, 0);
|
|
98
|
+
}
|
|
99
|
+
if (!options.expanded) {
|
|
100
|
+
return new Text(theme.fg("muted", summaryLine), 0, 0);
|
|
101
|
+
}
|
|
102
|
+
const text = resultText(result);
|
|
103
|
+
return new Text(text, 0, 0);
|
|
104
|
+
}
|
|
78
105
|
/** 联网搜索工具:走 u1s1 网关代理,上游 key 不落到用户机器上。 */
|
|
79
106
|
export function createSearchTool(cfg) {
|
|
80
107
|
return defineTool({
|
|
@@ -90,6 +117,17 @@ export function createSearchTool(cfg) {
|
|
|
90
117
|
query: Type.String({ description: "Search query. Be specific; keep it under ~15 words." }),
|
|
91
118
|
maxResults: Type.Optional(Type.Number({ description: "How many results to return (1-10, default 5).", minimum: 1, maximum: 10 })),
|
|
92
119
|
}),
|
|
120
|
+
// 精简展示:收起时一行摘要(🔍 搜索 "…" · N 条结果),ctrl+o 展开全文
|
|
121
|
+
renderShell: "self",
|
|
122
|
+
renderCall() {
|
|
123
|
+
return new Text("", 0, 0);
|
|
124
|
+
},
|
|
125
|
+
renderResult(result, options, theme, context) {
|
|
126
|
+
const d = result.details;
|
|
127
|
+
const q = d?.query ? `"${previewLine(d.query, 80)}"` : "…";
|
|
128
|
+
const n = typeof d?.count === "number" ? ` · ${d.count} 条结果` : "";
|
|
129
|
+
return compactResultRender(result, options, theme, context, `🔍 搜索 ${q}${n}`);
|
|
130
|
+
},
|
|
93
131
|
async execute(_toolCallId, params, signal) {
|
|
94
132
|
const data = await searchWeb(cfg, params.query, params.maxResults, signal);
|
|
95
133
|
const lines = [];
|
|
@@ -275,6 +313,18 @@ export function createFetchTool(cfg) {
|
|
|
275
313
|
parameters: Type.Object({
|
|
276
314
|
url: Type.String({ description: "Absolute http(s) URL to fetch." }),
|
|
277
315
|
}),
|
|
316
|
+
// 精简展示:收起时一行摘要(🌐 url · N 字符 · ☁ 渲染),ctrl+o 展开全文
|
|
317
|
+
renderShell: "self",
|
|
318
|
+
renderCall() {
|
|
319
|
+
return new Text("", 0, 0);
|
|
320
|
+
},
|
|
321
|
+
renderResult(result, options, theme, context) {
|
|
322
|
+
const d = result.details;
|
|
323
|
+
const u = previewLine(d?.url ?? "…", 90);
|
|
324
|
+
const n = typeof d?.chars === "number" ? ` · ${d.chars} 字符` : "";
|
|
325
|
+
const cloud = d?.via === "render" ? " · ☁ 浏览器渲染" : "";
|
|
326
|
+
return compactResultRender(result, options, theme, context, `🌐 ${u}${n}${cloud}`);
|
|
327
|
+
},
|
|
278
328
|
async execute(_toolCallId, params, signal) {
|
|
279
329
|
let url;
|
|
280
330
|
try {
|