@plumeai/plugin-sdk 0.2.0 → 0.3.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/dist/client/ui/src/avatar/AgentAvatar.d.ts +2 -5
- package/dist/client/ui/src/i18n/messages/en.d.ts +3 -0
- package/dist/client/ui/src/i18n/messages/zh-CN.d.ts +3 -0
- package/dist/client/ui/src/image/AnnotateToolbar.d.ts +2 -4
- package/dist/client/ui/src/image/Annotator.d.ts +3 -2
- package/dist/client/ui/src/image/screenshot-geometry.d.ts +2 -2
- package/dist/client/ui/src/inputs/SearchField.d.ts +1 -1
- package/dist/client/ui/src/inputs/pickers.d.ts +1 -1
- package/dist/client/ui/src/layout/PageTopRow.d.ts +5 -6
- package/dist/client/ui/src/motion/RollingText.d.ts +1 -1
- package/dist/client/ui/src/motion/loaders.d.ts +4 -4
- package/dist/client/ui/src/overlay/Confirm.d.ts +1 -2
- package/dist/client/ui/src/overlay/ContextMenu.d.ts +2 -2
- package/dist/client/ui/src/overlay/Dialog.d.ts +5 -6
- package/dist/client/ui/src/overlay/Menu.d.ts +3 -4
- package/dist/client/ui/src/overlay/Popover.d.ts +1 -1
- package/dist/client/ui/src/overlay/Tooltip.d.ts +1 -1
- package/dist/client/ui/src/primitives/IconButton.d.ts +2 -2
- package/dist/client/ui/src/primitives/Text.d.ts +2 -2
- package/dist/client/ui/src/scroll/ScrollText.d.ts +1 -1
- package/dist/client/ui/src/scroll/Scroller.d.ts +2 -1
- package/dist/contract/src/diagnostics.d.ts +39 -1
- package/dist/contract/src/plugin.d.ts +70 -1
- package/dist/contract/src/service.d.ts +15 -2
- package/dist/contract/src/ui.d.ts +73 -69
- package/package.json +1 -1
- package/skill/SKILL.md +86 -78
- package/skill/references/components.md +233 -1418
- package/skill/references/logic.md +240 -74
- package/skill/references/style-i18n.md +16 -12
- package/skill/references/ui.md +171 -124
|
@@ -22,12 +22,9 @@ export interface AgentAvatarProps {
|
|
|
22
22
|
/** 像素边长。 */
|
|
23
23
|
size?: number;
|
|
24
24
|
mood?: AvatarMood;
|
|
25
|
-
/**
|
|
26
|
-
* 悬停时眼睛跟着指针、身子弹一下。默认开。
|
|
27
|
-
*
|
|
28
|
-
* `host` 是往上找的那个容器:一整行的任何地方悬停都算,而不是非得对准这 20 像素。
|
|
29
|
-
*/
|
|
25
|
+
/** 悬停时眼睛跟着指针、身子弹一下。默认开。 */
|
|
30
26
|
interactive?: boolean;
|
|
27
|
+
/** 往上找的那个容器的选择器(`closest`):在它里面任何地方悬停都算,而不是非得对准这 20 像素。 */
|
|
31
28
|
host?: string;
|
|
32
29
|
/** 名字,决定眨眼的节奏——七张脸不该踩着同一个拍子。 */
|
|
33
30
|
seed?: string;
|
|
@@ -1107,6 +1107,9 @@ export declare const en: {
|
|
|
1107
1107
|
"retry.fixedDetail": string;
|
|
1108
1108
|
"plugins.failed": string;
|
|
1109
1109
|
"plugins.waiting": string;
|
|
1110
|
+
"plugins.provides": string;
|
|
1111
|
+
"plugins.serviceReplaces": string;
|
|
1112
|
+
"plugins.serviceReplacedBy": string;
|
|
1110
1113
|
"plugins.observesAll": string;
|
|
1111
1114
|
"about.intro": string;
|
|
1112
1115
|
"about.checking": string;
|
|
@@ -969,6 +969,9 @@ export declare const zhCN: {
|
|
|
969
969
|
readonly "retry.fixedDetail": "每次大致等这么久,上下浮动两成,免得断线后大家同时重连;服务端明确要求等更久时按服务端(最多 5 分钟)。";
|
|
970
970
|
readonly "plugins.failed": "加载失败";
|
|
971
971
|
readonly "plugins.waiting": "等待服务:{services}";
|
|
972
|
+
readonly "plugins.provides": "提供服务:{services}";
|
|
973
|
+
readonly "plugins.serviceReplaces": "{service}(替换了 {plugins} 提供的)";
|
|
974
|
+
readonly "plugins.serviceReplacedBy": "{service}(没生效,生效的是 {plugin} 提供的)";
|
|
972
975
|
readonly "plugins.observesAll": "能看到所有会话的运行情况:发给模型的内容、模型的回复、等人答的卡";
|
|
973
976
|
readonly "about.intro": "查看当前版本、更新内容,手动检查更新、设置自动检查的频率。";
|
|
974
977
|
readonly "about.checking": "正在检查…";
|
|
@@ -22,13 +22,11 @@ export declare function AnnotateToolbar({ annotator, onCancel, onSave, onPin, on
|
|
|
22
22
|
/** 把这张图写进下载目录。理由同 `onPin`。 */
|
|
23
23
|
onDownload?: () => void;
|
|
24
24
|
/**
|
|
25
|
-
*
|
|
25
|
+
* 这一条要挪窝了:从哪儿按下的,按下时它在哪儿。挪到哪儿由调用方定;不传就是不能挪。
|
|
26
26
|
*
|
|
27
|
-
*
|
|
27
|
+
* 它飘在一张截好的屏幕上,得留在屏幕里,所以这里只说「开始了」,外加
|
|
28
28
|
* 两个位置。带上 `origin` 而不是让调用方自己去 DOM 里量:这一条的位置只有它自己最清楚,而且
|
|
29
29
|
* 按住按钮触发的那一次是从定时器里发出的,那会儿 React 的合成事件早就没有 `currentTarget` 了。
|
|
30
|
-
*
|
|
31
|
-
* 不传就是不能挪。
|
|
32
30
|
*/
|
|
33
31
|
onGrab?: (grab: {
|
|
34
32
|
from: {
|
|
@@ -61,9 +61,10 @@ export interface Annotator {
|
|
|
61
61
|
*/
|
|
62
62
|
render: () => string | null;
|
|
63
63
|
/**
|
|
64
|
-
*
|
|
64
|
+
* 把正在写的那段文字提交掉,如果有的话。返回有没有。任何要把这幅画变成一张图的操作(`render`)都得先调它;
|
|
65
|
+
* 返回 `true` 时画布还没重画,调用方等一帧再读。
|
|
65
66
|
*
|
|
66
|
-
*
|
|
67
|
+
* 文字在提交之前住在一个 `<textarea>` 里,提交它的是这个
|
|
67
68
|
* 输入框失去焦点——可工具条故意不拿焦点(`onMouseDown` → `preventDefault`),因为写字时按「粗」必须
|
|
68
69
|
* 是改这段字的大小,而不是结束它。于是光标还在文字里就按「完成」,什么也没提交:字在屏幕上,在画布
|
|
69
70
|
* 上面的一个输入框里,而被裁出来的是画布。出来的图上没有那段字。
|
|
@@ -26,9 +26,9 @@ export declare const HANDLE_CURSOR: Record<Handle, string>;
|
|
|
26
26
|
/** 手柄在哪,表示为选区边上的一个点。 */
|
|
27
27
|
export declare function handlePoint(rect: Rect, handle: Handle): Point;
|
|
28
28
|
/**
|
|
29
|
-
* 指针在哪个手柄上,没有就是 null
|
|
29
|
+
* 指针在哪个手柄上,没有就是 null。`tolerance` 是屏幕像素的半径,而不是手柄画出来的大小。
|
|
30
30
|
*
|
|
31
|
-
*
|
|
31
|
+
* 目标得比记号大,理由和滚动条一样——八个像素见方
|
|
32
32
|
* 的一块,手落不准。
|
|
33
33
|
*/
|
|
34
34
|
export declare function hitHandle(rect: Rect, at: Point, tolerance: number): Handle | null;
|
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
import type { HTMLAttributes, ReactNode, Ref } from "react";
|
|
2
2
|
/**
|
|
3
3
|
* 自己画顶行的页面(`ui.page` 给了 `topRow: true`)每一栏最上面那一行:坐在窗口顶行的高度上,和侧栏顶上那一行齐平。
|
|
4
|
+
* 整行拖得动窗口、双击能缩放,行里能点的控件(按钮、链接、输入框)自动不拖动,不用一个个标。贴着页面左边的那一栏给
|
|
5
|
+
* `start`(两栏页面的右栏在窄窗口里换成整页时也给),给侧栏收起时浮在这里的红绿灯和前进、后退让出宽度。
|
|
6
|
+
* 高度、内边距之外的排法(间距、两端对齐)由 `className` 补;行里不折行,放不下的东西自己截断。
|
|
4
7
|
*
|
|
5
|
-
*
|
|
6
|
-
* no-drag:那样这一栏宽的一段就既拖不动窗口、也双击不了。Windows、Linux 上窗口顶上另有一条拖窗口的带子,宿主在根元素上
|
|
8
|
+
* 不给整行 no-drag:那样这一栏宽的一段就既拖不动窗口、也双击不了。Windows、Linux 上窗口顶上另有一条拖窗口的带子,宿主在根元素上
|
|
7
9
|
* 标 `data-plume-window-header`,这一行跟着改成不拖动(`app-region` 不认 `var()`,只能按选择器切):在卡片里拖窗口会带上系统标题栏的行为(右键系统菜单、拖到屏幕边贴边)。
|
|
8
10
|
*
|
|
9
|
-
* `start`
|
|
10
|
-
* `--plume-top-row-inset` 给,侧栏开着时是 0)。两栏页面的右栏在窄窗口里换成整页时,也给 `start`。
|
|
11
|
-
*
|
|
12
|
-
* 高度、内边距之外的排法(间距、两端对齐)由 `className` 补;行里不折行,放不下的东西自己截断。
|
|
11
|
+
* `start` 让出的宽度由宿主经 `--plume-top-row-inset` 给,侧栏开着时是 0。
|
|
13
12
|
*/
|
|
14
13
|
export declare function PageTopRow({ start, className, children, ...rest }: {
|
|
15
14
|
start?: boolean;
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
* 几何和那些数字怎么定的,写在 `@plume/styles` 的 `ui/motion.css` 的加载记号一节。
|
|
23
23
|
*/
|
|
24
24
|
/**
|
|
25
|
-
*
|
|
25
|
+
* 一圈虚线,匀速转:这一条正在跑,顶替的是状态图标(任务清单的一步、工具卡的运行中)。颜色跟着周围的文字。
|
|
26
26
|
*
|
|
27
27
|
* 六段等分,所以转过 60° 就回到自身:没有可追踪的端点,眼睛抓不到锚点。这是它敢转、而一段
|
|
28
28
|
* 弧不敢的原因——一段弧有头,十几个同时在屏幕上,每一个都在自己的相位上把视线勾一下。
|
|
@@ -35,7 +35,7 @@ export declare function StatusSpinner({ size, className }: {
|
|
|
35
35
|
className?: string;
|
|
36
36
|
}): import("react").JSX.Element;
|
|
37
37
|
/**
|
|
38
|
-
*
|
|
38
|
+
* 一段亮弧沿着一圈淡轨道跑:你按的那下正在回来,顶替的是刚按下的动作图标或角标。
|
|
39
39
|
*
|
|
40
40
|
* 轨道是这个记号的重点,不是装饰:亮弧单独转的话,图形的轮廓跟着弧一起走,在按钮那个方寸
|
|
41
41
|
* 之间会读成「有东西在里面甩」。垫一圈淡的,形状就恒定是一个完整的圆,动的只有亮处。
|
|
@@ -45,9 +45,9 @@ export declare function ActionSpinner({ size, className }: {
|
|
|
45
45
|
className?: string;
|
|
46
46
|
}): import("react").JSX.Element;
|
|
47
47
|
/**
|
|
48
|
-
*
|
|
48
|
+
* 一圈波纹离开静止的中心,颜色一路走过调色板:这个会话在跑,给侧栏的会话行和替一个会话报状态的地方。
|
|
49
49
|
*
|
|
50
|
-
*
|
|
50
|
+
* 同一个会话在两处是同一个记号。那一列可能同时有好几行在跑,而你还要用它读标题——所以这里连「亮处在走」都不
|
|
51
51
|
* 要:什么都不旋转、什么都不位移,余光里它只是缓缓涨落的一团。换成上面那两个的话,一列里并排
|
|
52
52
|
* 三四个各自明灭,读标题时总有东西在旁边闪。
|
|
53
53
|
*
|
|
@@ -27,9 +27,8 @@ export interface ConfirmOptions {
|
|
|
27
27
|
/** 取消按钮上的字,默认「取消」。 */
|
|
28
28
|
cancelLabel?: string;
|
|
29
29
|
/**
|
|
30
|
-
* `danger`
|
|
30
|
+
* `danger` 是默认,给删除这类拿不回来的事;`normal` 给「以后要不要自动做这件事」这类问题。
|
|
31
31
|
*
|
|
32
|
-
* `normal` 留给另一类问题:不是「这个删了拿不回来」,而是「以后要不要自动做这件事」。
|
|
33
32
|
* 两种都该停下一切来问,但只有前一种该是红的——把每个问题都画成危险,等于没画过危险。
|
|
34
33
|
*/
|
|
35
34
|
tone?: "danger" | "normal";
|
|
@@ -24,9 +24,9 @@ export declare function useContextMenu<T = void>(): {
|
|
|
24
24
|
close: () => void;
|
|
25
25
|
};
|
|
26
26
|
/**
|
|
27
|
-
*
|
|
27
|
+
* 面本身。点了任何一行都会关掉它。
|
|
28
28
|
*
|
|
29
|
-
*
|
|
29
|
+
* 在这里处理而不是每一项各自记得:右键菜单里没有不是动作的行,点完还开着的那个会是
|
|
30
30
|
* 应用里唯一这样的菜单。监听在冒泡阶段,所以行自己的处理已经先运行了。
|
|
31
31
|
*/
|
|
32
32
|
export declare function ContextMenu({ anchor, onClose, width, children, }: {
|
|
@@ -7,9 +7,9 @@
|
|
|
7
7
|
import type { ButtonHTMLAttributes, HTMLAttributes, ReactNode } from "react";
|
|
8
8
|
import { type Dismiss } from "./Overlay.tsx";
|
|
9
9
|
/**
|
|
10
|
-
*
|
|
10
|
+
* 对话框底下的那一颗按钮。上面写着它会做的那件事:写字,不画图标。
|
|
11
11
|
*
|
|
12
|
-
*
|
|
12
|
+
* 这些按钮曾经有好几处只放一个 ✕ 和一个 ✓,名字挂在 tooltip 上。工具栏
|
|
13
13
|
* 里的图标按钮可以这么省——周围一排东西替它说明它属于哪一类;对话框底下这两颗没有这个周围,
|
|
14
14
|
* 它们是这次操作的结论本身,一个要说清按下去会发生什么,另一个要说清不按会怎样。一个勾在
|
|
15
15
|
* 「删除会话」「卸载插件」「导入 33 个模型」上长得一模一样,而读出区别的唯一办法是把鼠标停
|
|
@@ -44,11 +44,10 @@ export declare function DialogFrame({ title, icon, detail, status, children, act
|
|
|
44
44
|
className?: string;
|
|
45
45
|
} & Omit<HTMLAttributes<HTMLDivElement>, "title" | "children">): import("react").JSX.Element;
|
|
46
46
|
/**
|
|
47
|
-
* 里面放着 `DialogFrame` 的 `Overlay
|
|
47
|
+
* 里面放着 `DialogFrame` 的 `Overlay`。`actions` 和 `children` 可以是 `dismiss` 的函数,关对话框的按钮
|
|
48
|
+
* 应该用它:`dismiss()` 播完退场再运行 `onClose`,`dismiss(after)` 改为运行 `after`。
|
|
48
49
|
*
|
|
49
|
-
*
|
|
50
|
-
* `onClose`,`dismiss(after)` 改为运行 `after`。按钮直接调用 `onClose` 会在那一帧卸掉对话框——那样
|
|
51
|
-
* 只有 Escape 和点遮罩是怎么来的就怎么走。
|
|
50
|
+
* 按钮直接调用 `onClose` 会在那一帧卸掉对话框——那样只有 Escape 和点遮罩是怎么来的就怎么走。
|
|
52
51
|
*/
|
|
53
52
|
export declare function Dialog({ onClose, width, label, returnFocus, actions, children, ...frame }: {
|
|
54
53
|
onClose: () => void;
|
|
@@ -73,12 +73,11 @@ export declare function MenuLabel({ children }: {
|
|
|
73
73
|
children: React.ReactNode;
|
|
74
74
|
}): import("react").JSX.Element;
|
|
75
75
|
/**
|
|
76
|
-
*
|
|
76
|
+
* 列出超过一屏的菜单顶上的筛选框,放进 `Popover` 的 `header` 槽位,列表滚动时它不动。Escape 先清空再关闭。
|
|
77
77
|
*
|
|
78
78
|
* 每个菜单各写一份的话,同样的高度、同样的放大镜、同样的占位文案,每多一份就多一次走样的机会。
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
* Escape 先清空再关闭,和 `SearchField` 一样:第一次按撤销输入,只有没东西可撤销时按才关掉菜单。
|
|
79
|
+
* 它下面那条线属于 `header` 槽位,不在这里画。Escape 和 `SearchField` 一样:第一次按撤销输入,
|
|
80
|
+
* 只有没东西可撤销时按才关掉菜单。
|
|
82
81
|
*/
|
|
83
82
|
export declare function MenuSearch({ value, onChange, placeholder, autoFocus, onKeyDown, }: {
|
|
84
83
|
value: string;
|
|
@@ -93,7 +93,7 @@ export interface PopoverProps {
|
|
|
93
93
|
/** 加在滚动正文上,给自己给内容加内衬的面。 */
|
|
94
94
|
bodyClassName?: string;
|
|
95
95
|
/**
|
|
96
|
-
*
|
|
96
|
+
* 一列行(`menu`),还是一样东西(`panel`:整个正文交给内容,滑块浮在上面)。
|
|
97
97
|
*
|
|
98
98
|
* `menu` 是每个菜单要的内衬:圆角需要地方,行不能跑到滚动条底下,渐隐的边说明列表在那之外还有。
|
|
99
99
|
* 这三样对只装一块自己画底色的面板的面都是错的——比如一段 diff,它的代码底色会在离卡片右边 25px、
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import type { DataAttributes } from "./Button.tsx";
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
3
|
+
* 标签是一个图标的按钮。`label` 同时是悬停提示和无障碍名。
|
|
4
4
|
*
|
|
5
5
|
* 各个工具栏各写各的,会长出五种高度、三种圆角,按下的反馈从没有到缩小 10% 都有。缩小是有意去掉的——
|
|
6
6
|
* 一个在接触那一刻从指针底下跳开的控件读起来不稳,在这么小的尺寸上那是一下晃动而不是按下。按下用底色
|
|
7
7
|
* 深一档表示,真的按钮就是这样:它待在原地,只是换了状态。
|
|
8
8
|
*
|
|
9
|
-
*
|
|
9
|
+
* 标签的两个用处调用方没法只给一个——只有图标的工具栏就是这样变得读屏读不出来的。
|
|
10
10
|
* 类名组合在 `@plume/styles` 的 `iconButton`。
|
|
11
11
|
*/
|
|
12
12
|
export declare function IconButton({ label, ariaLabel, icon, onClick, active, disabled, emphasis, badge, explainDisabled, tone, size, tipSide, menu, expanded, className, ...data }: DataAttributes & {
|
|
@@ -50,9 +50,9 @@ export declare function Text({ size, tone, weight, as, mono, numeric, className,
|
|
|
50
50
|
/** 等宽字体,给正文里引用的标识符和路径。 */
|
|
51
51
|
mono?: boolean;
|
|
52
52
|
/**
|
|
53
|
-
*
|
|
53
|
+
* 等宽数字,给原地变化的数——token 数、计时、diff 统计。
|
|
54
54
|
*
|
|
55
|
-
*
|
|
55
|
+
* 比例数字每跳一下字就左右挪,读起来是闪烁。
|
|
56
56
|
*/
|
|
57
57
|
numeric?: boolean;
|
|
58
58
|
className?: string;
|
|
@@ -19,7 +19,8 @@ export declare function Scroller({ children, className, contentClassName, top, f
|
|
|
19
19
|
className?: string;
|
|
20
20
|
contentClassName?: string;
|
|
21
21
|
/**
|
|
22
|
-
*
|
|
22
|
+
* 滚到自己的边界之后,滚轮还传不传给外面。页面里的一段内容(嵌在外层滚动面里的工具卡片、代码输出、
|
|
23
|
+
* 一列搜索结果)给 `"auto"`;独立的面(弹窗、浮层、菜单)用默认的 `"contain"`。
|
|
23
24
|
*
|
|
24
25
|
* 判断标准是这一块**是页面里的一段内容,还是一块独立的面**。一段内容——设置页里的发版说明、一列
|
|
25
26
|
* 搜索结果——读到底了还想接着往下看页面,是很自然的一件事,那就该给 `"auto"`。一块
|
|
@@ -1,5 +1,33 @@
|
|
|
1
1
|
import type { AssistantMessage, Message, ToolSpec } from "../../core/llm/types.d.ts";
|
|
2
|
+
import type { HookName } from "./plugin.ts";
|
|
2
3
|
import type { AgentEvent, TurnStop } from "./service.ts";
|
|
4
|
+
/**
|
|
5
|
+
* 钩子的一层在一次钩子调用里做了什么。只记有没有改,不记改成了什么:观察里不因此多出参数、结果的内容。
|
|
6
|
+
* 「改了」按值比较(同一个对象、或逐个字段一样都算没改),所以照原样展开再交下去不算改。
|
|
7
|
+
*/
|
|
8
|
+
export interface HookPass {
|
|
9
|
+
plugin: string;
|
|
10
|
+
order: number;
|
|
11
|
+
/**
|
|
12
|
+
* `next`:往里交了;`answered`:没往里交,自己给了结果;`failed`:这一层抛了错。里层的错原样往外传时只记在出错的那一层,
|
|
13
|
+
* 外面的层照样是 `next`(和 `HookError` 的归因一样)。
|
|
14
|
+
*/
|
|
15
|
+
outcome: "next" | "answered" | "failed";
|
|
16
|
+
/** 交给里层的和自己收到的不一样:改了参数,或在输入上设了别的(`approved`、`readOnly`……)。 */
|
|
17
|
+
changedInput?: true;
|
|
18
|
+
/** 交回外层的和里层交给它的不一样:改了结果。 */
|
|
19
|
+
changedOutput?: true;
|
|
20
|
+
}
|
|
21
|
+
/** 一次钩子调用穿过的层,外层在前;一层交了几次(重试)就记几次。 */
|
|
22
|
+
export interface HookTrace {
|
|
23
|
+
hook: HookName;
|
|
24
|
+
layers: HookPass[];
|
|
25
|
+
/**
|
|
26
|
+
* 最里层(本体):`ran` 走到了;`stopped` 本体按外层设下的东西在某一层之前就停下、不再往里交(如外层设了 `readOnly`,写、改文件的工具不跑)。
|
|
27
|
+
* 没有时是某一层自己交了结果或出错,没走到最里层。
|
|
28
|
+
*/
|
|
29
|
+
inner?: "ran" | "stopped";
|
|
30
|
+
}
|
|
3
31
|
/** 会话的只读运行观察,不包含供应商配置、请求头和密钥。观察者失败不影响运行。 */
|
|
4
32
|
export interface SessionObservation {
|
|
5
33
|
sessionId: string;
|
|
@@ -20,7 +48,17 @@ export interface SessionObservation {
|
|
|
20
48
|
type: "response";
|
|
21
49
|
id: string;
|
|
22
50
|
reply: AssistantMessage;
|
|
23
|
-
}
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* 一次钩子调用经过了哪几层、每层做了什么,有插件挂了这个钩子时才有。`tool.execute`、`tool.approve` 带它所在的那次工具调用
|
|
54
|
+
* (`tool.approve` 一次调用里问几次就有几条),`model.context` 带组出来的那次请求(同 `request` 的 `id`;组了没发出去的不记),
|
|
55
|
+
* `prompt.submit` 两样都不带(每条要写进会话的消息一条,拦下的也记)。`step.end`、`context.compact` 不记。
|
|
56
|
+
*/
|
|
57
|
+
| ({
|
|
58
|
+
type: "hooks";
|
|
59
|
+
toolCallId?: string;
|
|
60
|
+
requestId?: string;
|
|
61
|
+
} & HookTrace) | {
|
|
24
62
|
type: "running";
|
|
25
63
|
running: boolean;
|
|
26
64
|
}
|
|
@@ -37,7 +37,7 @@ export interface ToolOutput {
|
|
|
37
37
|
* 给工具卡片和插件自己用的结构化数据,存进会话,不发给模型。形状由插件定,本体不看里面,只认这几个通用声明:
|
|
38
38
|
* 带 `checklist`(`ChecklistDetails`)是一份进度清单,带 `job`(`BackgroundJobDetails`)是在后台起了一个任务,
|
|
39
39
|
* 带 `path`、`added`、`removed`、`hunks`(`FileDiffDetails`)是改了一个文件、通用卡片画出 diff,
|
|
40
|
-
* 出错的结果带 `cancelled: true`(`CancelledDetails
|
|
40
|
+
* 出错的结果带 `cancelled: true`(`CancelledDetails`)是人按了停、不是失败,带 `spill`(`SpillDetails`)是结果截过、全文在别处。
|
|
41
41
|
* 插件之间另认一个:让模型看了文件的哪一块(`FileViewDetails`)。改了哪些文件不在这里,见 `changes`。
|
|
42
42
|
*/
|
|
43
43
|
details?: unknown;
|
|
@@ -110,6 +110,19 @@ export interface FileViewDetails {
|
|
|
110
110
|
verbatim: boolean;
|
|
111
111
|
};
|
|
112
112
|
}
|
|
113
|
+
/**
|
|
114
|
+
* 工具结果的 `details` 带上 `spill`,就是声明「这次结果截过,全文在 `address`」:`address` 是资源地址(`run.files.spill` 给的
|
|
115
|
+
* `artifact://`),`read` 能按行、按窗口读回来;`path` 是它在磁盘上的位置,给人打开、给别的插件核对用;`characters` 是全文多少字。
|
|
116
|
+
*
|
|
117
|
+
* 本体和插件都不按工具名找它:诊断从结果上认出它就能看全文,不再拼某个插件的目录。`details` 里别的字段照旧归插件。
|
|
118
|
+
*/
|
|
119
|
+
export interface SpillDetails {
|
|
120
|
+
spill: {
|
|
121
|
+
address: string;
|
|
122
|
+
path: string;
|
|
123
|
+
characters: number;
|
|
124
|
+
};
|
|
125
|
+
}
|
|
113
126
|
/**
|
|
114
127
|
* 出错的工具结果(`isError`)的 `details` 带上 `cancelled: true`,就是声明「没做完是因为人按了停,不是失败」:转录画成「已停止」,
|
|
115
128
|
* 不画成出错。工具被停下时自己交结果的(命令跑到一半被杀)自己带上;本体替停下的调用交结果、或停下以后工具交回的错误结果
|
|
@@ -377,6 +390,22 @@ export interface RunFiles {
|
|
|
377
390
|
ok: false;
|
|
378
391
|
message: string;
|
|
379
392
|
}>;
|
|
393
|
+
/**
|
|
394
|
+
* 结果截过以后,把没交给模型的那份原文存在会话的临时目录里,交回它的地址和位置(`SpillDetails` 的形状,直接放进
|
|
395
|
+
* `ToolOutput.details.spill`)。地址是 `artifact://<id>`,按 `tool` 和内容算:同一段原文每次换回同一个地址,后来重发的历史里
|
|
396
|
+
* 那句提示逐字不变。模型要读了经 `read` 按行、按窗口取回;会话删掉时一起清掉,重开应用以后还在。
|
|
397
|
+
*
|
|
398
|
+
* 每个会话最多留 30 份,超了丢最旧的。写不进去(磁盘满、会话没有临时目录)时抛错,由工具自己决定少说一句还是报错——
|
|
399
|
+
* 截断本身不该因此失败。不记改动快照、不问人:临时目录是会话自己的草稿。只在这次调用里用。
|
|
400
|
+
*
|
|
401
|
+
* 同步的:调用它的都在同步地生成一条结果(压缩剪一条结果、mcp 把服务器的回复换成交给模型的样子),内容已经在内存里,
|
|
402
|
+
* 写成异步只会把「这条结果长什么样」摊成两步,还得让这些路径都变成异步。写的是几百 KB 到磁盘。
|
|
403
|
+
*/
|
|
404
|
+
spill(tool: string, content: string): {
|
|
405
|
+
address: string;
|
|
406
|
+
path: string;
|
|
407
|
+
characters: number;
|
|
408
|
+
};
|
|
380
409
|
/**
|
|
381
410
|
* 这次调用的结果也算上一条命令改的文件:`process` 是经 `exec`(`recordChanges`)起的进程或它留下的进程,可以是之前的调用起的(后台命令)。
|
|
382
411
|
* 命令已经结束就算上它记下的,还在跑就记一句「结束后才记」。读后台命令输出的调用用。不是这个会话里经 `exec` 观测的进程时什么都不做。
|
|
@@ -1912,7 +1941,47 @@ export interface PluginWorkspace {
|
|
|
1912
1941
|
* 不在 git 仓库里、或 git 答不上来时是 null,由调用方自己走目录。不问人:要不要读 `root` 由调用方先经 `ToolRun.files.read` 判。
|
|
1913
1942
|
*/
|
|
1914
1943
|
files(root: string): Promise<string[] | null>;
|
|
1944
|
+
/**
|
|
1945
|
+
* 在同一个隔离视图里跑一组 git 命令,结束即删:HEAD、引用、分支的上游和远端地址都照着真实仓库抄好,分支、ahead / behind、
|
|
1946
|
+
* 日志上的装饰和在真实仓库里跑一样,读不到仓库自己的配置(`core.fsmonitor`、过滤器、`diff.external`、钩子)、也不会连网。
|
|
1947
|
+
* 一组读共用一个视图:搭一个要先跑几条命令,每条命令各搭一个就是每次刷新几十个进程。
|
|
1948
|
+
*
|
|
1949
|
+
* `root` 不在检出里时 `work` 不跑,交回 null。只读:暂存、提交、推送、切分支这些人点了才做的事仍由插件自己在真实仓库上跑,
|
|
1950
|
+
* 那样钩子、凭据助手正是人要的。除了要写 stdin 的那一个(`gitWithInput`,`cat-file --batch`),
|
|
1951
|
+
* 要按二进制读的用 `gitBuffer`:`git show HEAD:logo.png` 回的不是文字。
|
|
1952
|
+
*/
|
|
1953
|
+
git<T>(root: string, work: (view: PluginGitView) => Promise<T>): Promise<T | null>;
|
|
1954
|
+
}
|
|
1955
|
+
/**
|
|
1956
|
+
* `ctx.workspace.git` 给的视图。路径、pathspec 相对 `cwd`,和在该目录直接跑 git 一样。
|
|
1957
|
+
* 读的结果没有替调用方决定是不是文字,失败时抛错(和 git 自己一样:非零退出就算失败,stderr 上那些不是错误的话不管)。
|
|
1958
|
+
*/
|
|
1959
|
+
export interface PluginGitView {
|
|
1960
|
+
/** 调用方给的目录:命令在这里跑。 */
|
|
1961
|
+
readonly cwd: string;
|
|
1962
|
+
git(args: string[]): Promise<string>;
|
|
1963
|
+
gitBuffer(args: string[]): Promise<Uint8Array>;
|
|
1964
|
+
gitWithInput(args: string[], input: string): Promise<Uint8Array>;
|
|
1965
|
+
/**
|
|
1966
|
+
* 没人点的那种获取(面板露面时、之后每五分钟):在视图里 `fetch --prune`,再把变了的引用搬回真实仓库。
|
|
1967
|
+
* 别人的改动被拒时整批不搬(每条引用带着抄快照时的旧值)。浅克隆的边界变了就不搬,留给人点的那次获取。
|
|
1968
|
+
*
|
|
1969
|
+
* `cancelled` 是调用方叫停的,不算失败;`timedOut` 是到了时限被杀;其余失败带 git 自己的话(`stderr`),原话交给调用方去说。
|
|
1970
|
+
*/
|
|
1971
|
+
fetch(options: {
|
|
1972
|
+
signal?: AbortSignal;
|
|
1973
|
+
timeoutMs: number;
|
|
1974
|
+
}): Promise<PluginGitFetch>;
|
|
1915
1975
|
}
|
|
1976
|
+
/** 见 `PluginGitView.fetch`。 */
|
|
1977
|
+
export type PluginGitFetch = {
|
|
1978
|
+
ok: true;
|
|
1979
|
+
} | {
|
|
1980
|
+
ok: false;
|
|
1981
|
+
cancelled?: boolean;
|
|
1982
|
+
timedOut?: boolean;
|
|
1983
|
+
stderr?: string;
|
|
1984
|
+
};
|
|
1916
1985
|
/**
|
|
1917
1986
|
* 沙箱的模式:只读、能写项目目录、不设限。权限模式对应哪一档由本体定:请求批准只读,帮我批准能写项目目录和临时目录,
|
|
1918
1987
|
* 完全访问不设限;`ToolExecution.readOnly` 一律只读。macOS 用 seatbelt,Windows 用受限令牌,Linux 没有后端。
|
|
@@ -515,6 +515,19 @@ export interface PluginStatus {
|
|
|
515
515
|
waitingFor?: string[];
|
|
516
516
|
/** 插件声明了要看全部会话的运行观察(`Plugin.observe`)。 */
|
|
517
517
|
observe?: "all";
|
|
518
|
+
/** 这个插件经 `ctx.provide` 提供的服务,按服务名排;没提供时没有。 */
|
|
519
|
+
provides?: ProvidedService[];
|
|
520
|
+
}
|
|
521
|
+
/**
|
|
522
|
+
* 插件提供的一项服务。同名服务只有一个生效的提供方(非内置的优先,同类里先加载的优先),别的插件 `ctx.use` 拿到的是它那一份。
|
|
523
|
+
* 同名的还有别的插件在提供时,生效的那一份写 `replaces`、没生效的写 `replacedBy`。
|
|
524
|
+
*/
|
|
525
|
+
export interface ProvidedService {
|
|
526
|
+
name: string;
|
|
527
|
+
/** 这一份生效,同名服务另几个提供方的插件名被它顶下(装一个提供同名服务的插件替换内置的,就是这样)。 */
|
|
528
|
+
replaces?: string[];
|
|
529
|
+
/** 这一份没生效:生效的是这个插件的。 */
|
|
530
|
+
replacedBy?: string;
|
|
518
531
|
}
|
|
519
532
|
export type AgentEvent = {
|
|
520
533
|
type: "fileRemoved";
|
|
@@ -843,8 +856,8 @@ export interface AgentService {
|
|
|
843
856
|
* 图标和回复里的文件签,不认工具名;变了推 `tools` 事件。
|
|
844
857
|
*/
|
|
845
858
|
listTools(): RegisteredToolInfo[];
|
|
846
|
-
/**
|
|
847
|
-
setPluginEnabled(
|
|
859
|
+
/** 启用或停用一个插件(按 `PluginStatus.key`),写进 plugins.json,立即生效。停用着的插件不导入。 */
|
|
860
|
+
setPluginEnabled(key: string, enabled: boolean): Promise<PluginStatus[]>;
|
|
848
861
|
/** 界面语言变了:agent 进程之后给人看的报错、提示用这种语言。发给模型的文字不跟着变。 */
|
|
849
862
|
setLocale(locale: Locale): void;
|
|
850
863
|
/** 订阅所有会话的事件,直到调用方取消。 */
|