@plumeai/plugin-sdk 0.0.0-stage → 0.1.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/LICENSE +21 -0
- package/bin/plume-plugin.mjs +70 -0
- package/dist/client/styles/src/index.d.ts +123 -0
- package/dist/client/ui/src/avatar/AgentAvatar.d.ts +42 -0
- package/dist/client/ui/src/avatar/AvatarPile.d.ts +36 -0
- package/dist/client/ui/src/avatar/AvatarStack.d.ts +26 -0
- package/dist/client/ui/src/avatar/art.d.ts +32 -0
- package/dist/client/ui/src/fileIcon.d.ts +33 -0
- package/dist/client/ui/src/hooks/useCopied.d.ts +16 -0
- package/dist/client/ui/src/hooks/useLiveRefresh.d.ts +22 -0
- package/dist/client/ui/src/hooks/useNarrow.d.ts +16 -0
- package/dist/client/ui/src/i18n/context.d.ts +17 -0
- package/dist/client/ui/src/i18n/index.d.ts +2 -0
- package/dist/client/ui/src/i18n/list.d.ts +20 -0
- package/dist/client/ui/src/i18n/locales.d.ts +10 -0
- package/dist/client/ui/src/i18n/messages/en.d.ts +1418 -0
- package/dist/client/ui/src/i18n/messages/index.d.ts +6 -0
- package/dist/client/ui/src/i18n/messages/zh-CN.d.ts +1263 -0
- package/dist/client/ui/src/i18n/plural.d.ts +16 -0
- package/dist/client/ui/src/i18n/translate.d.ts +43 -0
- package/dist/client/ui/src/icons/index.d.ts +5 -0
- package/dist/client/ui/src/image/AnnotateCanvas.d.ts +29 -0
- package/dist/client/ui/src/image/AnnotateToolbar.d.ts +73 -0
- package/dist/client/ui/src/image/Annotator.d.ts +154 -0
- package/dist/client/ui/src/image/annotate.d.ts +227 -0
- package/dist/client/ui/src/image/paint.d.ts +35 -0
- package/dist/client/ui/src/image/screenshot-geometry.d.ts +112 -0
- package/dist/client/ui/src/image/useBarDrag.d.ts +31 -0
- package/dist/client/ui/src/image/useMovableBar.d.ts +26 -0
- package/dist/client/ui/src/image/useToolbarPlacement.d.ts +42 -0
- package/dist/client/ui/src/index.d.ts +140 -0
- package/dist/client/ui/src/inputs/ColorField.d.ts +9 -0
- package/dist/client/ui/src/inputs/ComposerToggle.d.ts +23 -0
- package/dist/client/ui/src/inputs/DateRangeField.d.ts +25 -0
- package/dist/client/ui/src/inputs/NativeField.d.ts +5 -0
- package/dist/client/ui/src/inputs/SearchField.d.ts +21 -0
- package/dist/client/ui/src/inputs/Segmented.d.ts +23 -0
- package/dist/client/ui/src/inputs/Select.d.ts +32 -0
- package/dist/client/ui/src/inputs/ShortcutRecorder.d.ts +8 -0
- package/dist/client/ui/src/inputs/Slider.d.ts +13 -0
- package/dist/client/ui/src/inputs/TextArea.d.ts +30 -0
- package/dist/client/ui/src/inputs/Toggle.d.ts +10 -0
- package/dist/client/ui/src/inputs/WorktreeToggle.d.ts +19 -0
- package/dist/client/ui/src/inputs/day-range.d.ts +57 -0
- package/dist/client/ui/src/inputs/pickers.d.ts +40 -0
- package/dist/client/ui/src/inputs/useFieldFade.d.ts +1 -0
- package/dist/client/ui/src/keyboard.d.ts +21 -0
- package/dist/client/ui/src/layout/ApprovalFrame.d.ts +33 -0
- package/dist/client/ui/src/layout/Collapse.d.ts +9 -0
- package/dist/client/ui/src/layout/CopyMark.d.ts +19 -0
- package/dist/client/ui/src/layout/Disclosure.d.ts +66 -0
- package/dist/client/ui/src/layout/ErrorBoundary.d.ts +26 -0
- package/dist/client/ui/src/layout/PageTopRow.d.ts +19 -0
- package/dist/client/ui/src/layout/PanelEmpty.d.ts +17 -0
- package/dist/client/ui/src/layout/ResizeHandle.d.ts +24 -0
- package/dist/client/ui/src/layout/RetainedViews.d.ts +32 -0
- package/dist/client/ui/src/layout/Settings.d.ts +41 -0
- package/dist/client/ui/src/layout/Splitter.d.ts +25 -0
- package/dist/client/ui/src/lib/agent-avatar.d.ts +58 -0
- package/dist/client/ui/src/lib/code/font-stack.d.ts +12 -0
- package/dist/client/ui/src/lib/code/themes.d.ts +35 -0
- package/dist/client/ui/src/lib/date-format.d.ts +8 -0
- package/dist/client/ui/src/lib/dispatches.d.ts +8 -0
- package/dist/client/ui/src/lib/hour-style.d.ts +13 -0
- package/dist/client/ui/src/lib/number-draft.d.ts +24 -0
- package/dist/client/ui/src/lib/relative-time.d.ts +18 -0
- package/dist/client/ui/src/lib/tiling.d.ts +89 -0
- package/dist/client/ui/src/lib/typing.d.ts +19 -0
- package/dist/client/ui/src/motion/RollWords.d.ts +26 -0
- package/dist/client/ui/src/motion/RollingText.d.ts +43 -0
- package/dist/client/ui/src/motion/TypedText.d.ts +9 -0
- package/dist/client/ui/src/motion/freeze.d.ts +22 -0
- package/dist/client/ui/src/motion/held.d.ts +17 -0
- package/dist/client/ui/src/motion/loaders.d.ts +65 -0
- package/dist/client/ui/src/motion/reduced.d.ts +13 -0
- package/dist/client/ui/src/motion/ticked.d.ts +24 -0
- package/dist/client/ui/src/motion/ticker.d.ts +31 -0
- package/dist/client/ui/src/motion/tokens.d.ts +29 -0
- package/dist/client/ui/src/motion/useNow.d.ts +6 -0
- package/dist/client/ui/src/overlay/Confirm.d.ts +96 -0
- package/dist/client/ui/src/overlay/ContextMenu.d.ts +40 -0
- package/dist/client/ui/src/overlay/Dialog.d.ts +60 -0
- package/dist/client/ui/src/overlay/Menu.d.ts +90 -0
- package/dist/client/ui/src/overlay/Overlay.d.ts +17 -0
- package/dist/client/ui/src/overlay/Popover.d.ts +127 -0
- package/dist/client/ui/src/overlay/Tooltip.d.ts +14 -0
- package/dist/client/ui/src/overlay/afterimage.d.ts +20 -0
- package/dist/client/ui/src/overlay/chrome-top.d.ts +8 -0
- package/dist/client/ui/src/overlay/hover-layers.d.ts +41 -0
- package/dist/client/ui/src/overlay/portal.d.ts +21 -0
- package/dist/client/ui/src/overlay/scrims.d.ts +20 -0
- package/dist/client/ui/src/overlay/tooltip-attribute.d.ts +62 -0
- package/dist/client/ui/src/primitives/Button.d.ts +64 -0
- package/dist/client/ui/src/primitives/Caret.d.ts +25 -0
- package/dist/client/ui/src/primitives/ChoiceMark.d.ts +12 -0
- package/dist/client/ui/src/primitives/ClosableTab.d.ts +23 -0
- package/dist/client/ui/src/primitives/CountUp.d.ts +21 -0
- package/dist/client/ui/src/primitives/GitHubMark.d.ts +12 -0
- package/dist/client/ui/src/primitives/IconButton.d.ts +55 -0
- package/dist/client/ui/src/primitives/MarkNumber.d.ts +12 -0
- package/dist/client/ui/src/primitives/RowDeleteButton.d.ts +6 -0
- package/dist/client/ui/src/primitives/Skeleton.d.ts +36 -0
- package/dist/client/ui/src/primitives/TabStrip.d.ts +29 -0
- package/dist/client/ui/src/primitives/Text.d.ts +341 -0
- package/dist/client/ui/src/primitives/TimeAgo.d.ts +13 -0
- package/dist/client/ui/src/primitives/useCountUp.d.ts +23 -0
- package/dist/client/ui/src/row/FlowRow.d.ts +31 -0
- package/dist/client/ui/src/row/HoverRow.d.ts +28 -0
- package/dist/client/ui/src/scroll/BackToLatest.d.ts +19 -0
- package/dist/client/ui/src/scroll/OverlayScrollbar.d.ts +9 -0
- package/dist/client/ui/src/scroll/ScrollText.d.ts +24 -0
- package/dist/client/ui/src/scroll/Scroller.d.ts +66 -0
- package/dist/client/ui/src/scroll/Sideways.d.ts +30 -0
- package/dist/client/ui/src/scroll/fade.d.ts +2 -0
- package/dist/client/ui/src/scroll/follow.d.ts +157 -0
- package/dist/client/ui/src/scroll/measure-batch.d.ts +13 -0
- package/dist/client/ui/src/scroll/memory.d.ts +22 -0
- package/dist/client/ui/src/scroll/signature.d.ts +24 -0
- package/dist/client/ui/src/scroll/useFollowBottom.d.ts +80 -0
- package/dist/client/ui/src/scroll/useSideways.d.ts +29 -0
- package/dist/contract/src/app.d.ts +16 -0
- package/dist/contract/src/changes.d.ts +50 -0
- package/dist/contract/src/diagnostics.d.ts +86 -0
- package/dist/contract/src/index.d.ts +18 -0
- package/dist/contract/src/plugin.d.ts +1391 -0
- package/dist/contract/src/resources.d.ts +79 -0
- package/dist/contract/src/service.d.ts +806 -0
- package/dist/contract/src/ui.d.ts +1039 -0
- package/dist/contract/src/usage.d.ts +102 -0
- package/dist/core/llm/ai/anthropic-messages-request.d.ts +82 -0
- package/dist/core/llm/ai/anthropic-messages.d.ts +43 -0
- package/dist/core/llm/ai/cache-routing.d.ts +53 -0
- package/dist/core/llm/ai/chat-delta.d.ts +107 -0
- package/dist/core/llm/ai/compat-key.d.ts +19 -0
- package/dist/core/llm/ai/endpoint.d.ts +57 -0
- package/dist/core/llm/ai/failure.d.ts +181 -0
- package/dist/core/llm/ai/index.d.ts +16 -0
- package/dist/core/llm/ai/openai-chat-completions-request.d.ts +49 -0
- package/dist/core/llm/ai/openai-chat-completions.d.ts +37 -0
- package/dist/core/llm/ai/openai-responses-request.d.ts +63 -0
- package/dist/core/llm/ai/openai-responses.d.ts +11 -0
- package/dist/core/llm/ai/prefix-fingerprint.d.ts +20 -0
- package/dist/core/llm/ai/reasoning-compat.d.ts +69 -0
- package/dist/core/llm/ai/request-params-compat.d.ts +39 -0
- package/dist/core/llm/ai/retry.d.ts +130 -0
- package/dist/core/llm/ai/sanitize-history.d.ts +23 -0
- package/dist/core/llm/ai/think-tag.d.ts +37 -0
- package/dist/core/llm/ai/thinking-options.d.ts +35 -0
- package/dist/core/llm/ai/tool-names.d.ts +17 -0
- package/dist/core/llm/ai/tool-pairing-compat.d.ts +53 -0
- package/dist/core/llm/ai/tool-result-images-compat.d.ts +24 -0
- package/dist/core/llm/ai/tool-schema.d.ts +20 -0
- package/dist/core/llm/ai/usage-fields.d.ts +30 -0
- package/dist/core/llm/ai/vendors/index.d.ts +20 -0
- package/dist/core/llm/ai/vendors/thinking.d.ts +39 -0
- package/dist/core/llm/ai/vendors/types.d.ts +47 -0
- package/dist/core/llm/config/image-models.d.ts +34 -0
- package/dist/core/llm/config/retry-policy.d.ts +35 -0
- package/dist/core/llm/images/chat-images.d.ts +11 -0
- package/dist/core/llm/images/dimensions.d.ts +15 -0
- package/dist/core/llm/images/generate.d.ts +15 -0
- package/dist/core/llm/images/openai-images.d.ts +11 -0
- package/dist/core/llm/images/quota.d.ts +9 -0
- package/dist/core/llm/images/shape.d.ts +44 -0
- package/dist/core/llm/images/types.d.ts +118 -0
- package/dist/core/llm/model-catalog-format.d.ts +50 -0
- package/dist/core/llm/model-catalog.d.ts +51 -0
- package/dist/core/llm/types/message.d.ts +450 -0
- package/dist/core/llm/types/provider.d.ts +169 -0
- package/dist/core/llm/types/tool.d.ts +23 -0
- package/dist/core/llm/types.d.ts +10 -0
- package/dist/core/llm/utils/pricing.d.ts +18 -0
- package/dist/core/llm/utils/record.d.ts +2 -0
- package/dist/core/llm/utils/sse.d.ts +69 -0
- package/dist/infra/rpc/src/endpoint.d.ts +36 -0
- package/dist/infra/rpc/src/index.d.ts +2 -0
- package/dist/infra/rpc/src/rpc.d.ts +54 -0
- package/dist/theme.css +336 -0
- package/dist/ui.d.ts +2 -0
- package/lib/build.mjs +143 -0
- package/lib/check.mjs +23 -0
- package/lib/dev.mjs +52 -0
- package/lib/icons.mjs +2 -0
- package/lib/init.mjs +109 -0
- package/lib/install.mjs +80 -0
- package/lib/link.mjs +44 -0
- package/lib/lint/i18n.mjs +149 -0
- package/lib/lint/imports.mjs +83 -0
- package/lib/lint/index.mjs +54 -0
- package/lib/lint/styles.mjs +160 -0
- package/lib/manifest.d.mts +9 -0
- package/lib/manifest.mjs +99 -0
- package/lib/targets.mjs +60 -0
- package/package.json +34 -4
- package/skill/SKILL.md +150 -0
- package/skill/references/components.md +2830 -0
- package/skill/references/logic.md +526 -0
- package/skill/references/style-i18n.md +70 -0
- package/skill/references/ui.md +532 -0
- package/template/AGENTS.md +17 -0
- package/template/CLAUDE.md +1 -0
- package/template/README.md +12 -0
- package/template/gitignore +2 -0
- package/template/src/index.ts +28 -0
- package/template/src/messages.ts +16 -0
- package/template/src/types.ts +8 -0
- package/template/src/ui.tsx +30 -0
- package/template/tsconfig.json +7 -0
- package/tsconfig.json +25 -0
- package/README.md +0 -3
|
@@ -0,0 +1,806 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AgentService:agent 进程给界面的服务,以及它推送的事件和返回的视图。界面经 `@plume/rpc` 调用。
|
|
3
|
+
*/
|
|
4
|
+
import type { ModelCatalogDocument } from "../../core/llm/model-catalog-format.d.ts";
|
|
5
|
+
import type { RetryPolicy } from "../../core/llm/config/retry-policy.d.ts";
|
|
6
|
+
import type { ApiFormat, AssistantMessage, Message, MessageAttachment, ModelPricing, ThinkingLevel, ThinkingOption, UserContent } from "../../core/llm/types.d.ts";
|
|
7
|
+
import type { CallContext } from "../../infra/rpc/src/index.d.ts";
|
|
8
|
+
import type { RevertPlan } from "./changes.ts";
|
|
9
|
+
import type { CommandContext, CommandResult, Locale, SlashCommand } from "./plugin.ts";
|
|
10
|
+
import type { ClearRange, ClearResult, StorageUse, UsageRequestBucket } from "./usage.ts";
|
|
11
|
+
/**
|
|
12
|
+
* 模型设置:若干供应商,每个供应商下若干模型,一个全局默认模型;会话可以另选一个。
|
|
13
|
+
* 一个模型用「供应商 id/模型 id」指代(ModelRef)。模型 id 本身可以带斜杠(如 anthropic/claude-opus-5-5),
|
|
14
|
+
* 供应商 id 不带,所以按第一个斜杠拆。
|
|
15
|
+
*/
|
|
16
|
+
export type ModelRef = string;
|
|
17
|
+
export interface ModelEntry {
|
|
18
|
+
/** 发给供应商的模型 id,同一个供应商下唯一。 */
|
|
19
|
+
modelId: string;
|
|
20
|
+
/** 界面上显示的名字。 */
|
|
21
|
+
name: string;
|
|
22
|
+
contextWindow: number;
|
|
23
|
+
maxOutputTokens: number;
|
|
24
|
+
supportsThinking: boolean;
|
|
25
|
+
supportsImages: boolean;
|
|
26
|
+
supportsTools: boolean;
|
|
27
|
+
/** 每百万 token 的美元价格;不填就不算费用。 */
|
|
28
|
+
pricing?: ModelPricing;
|
|
29
|
+
/** 可选的思考档位;不填用默认几档。 */
|
|
30
|
+
thinkingOptions?: ThinkingOption[];
|
|
31
|
+
/** 生图模型:用来画图和改图,不出现在对话模型列表里,也不当默认模型。不填按模型 id 判断(`gpt-image-1`、`…-image` 这类)。 */
|
|
32
|
+
imageOutput?: boolean;
|
|
33
|
+
}
|
|
34
|
+
export interface ProviderSettings {
|
|
35
|
+
/** 只含小写字母、数字和连字符;新建时留空,由 agent 进程分配。 */
|
|
36
|
+
id: string;
|
|
37
|
+
name: string;
|
|
38
|
+
api: ApiFormat;
|
|
39
|
+
baseUrl: string;
|
|
40
|
+
/** 停用的供应商不出现在模型选择里,也不会被当成默认模型。 */
|
|
41
|
+
enabled: boolean;
|
|
42
|
+
models: ModelEntry[];
|
|
43
|
+
}
|
|
44
|
+
export interface ProviderView extends ProviderSettings {
|
|
45
|
+
/** 已经存了 API key。key 本身不出 agent 进程。 */
|
|
46
|
+
hasKey: boolean;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* 本体的工具多大程度上不用问人就能做。`ask`:会改动工作区的工具每次都问,命令跑在只读沙箱里;
|
|
50
|
+
* `auto`(默认,「帮我批准」):只问看得出风险的,命令跑在只能写项目目录和临时目录的沙箱里;
|
|
51
|
+
* `full`:一律不问,命令不进沙箱。
|
|
52
|
+
*/
|
|
53
|
+
export type PermissionMode = "ask" | "auto" | "full";
|
|
54
|
+
/** 回复的语气,放进系统提示词的一段;`professional` 不加这一段。 */
|
|
55
|
+
export type Tone = "friendly" | "professional" | "concise" | "candid" | "humorous";
|
|
56
|
+
/** 设置 › 个性化:对所有会话都生效的全局指令和语气。 */
|
|
57
|
+
export interface Personalization {
|
|
58
|
+
/** 用户自己写的全局指令,放进每个会话的系统提示词;空的不放。 */
|
|
59
|
+
customInstructions: string;
|
|
60
|
+
tone: Tone;
|
|
61
|
+
}
|
|
62
|
+
export interface SettingsView {
|
|
63
|
+
providers: ProviderView[];
|
|
64
|
+
permissionMode: PermissionMode;
|
|
65
|
+
personalization: Personalization;
|
|
66
|
+
/** 实际生效的默认模型:设过且还可用就是它,否则是第一个可用的模型;一个都没有时为空。 */
|
|
67
|
+
defaultModel?: ModelRef;
|
|
68
|
+
/** 模型菜单里星标的模型,按星标的先后;可能含已经不可用的,界面跳过。 */
|
|
69
|
+
favoriteModels: ModelRef[];
|
|
70
|
+
/** 设置里选的默认生图模型,原样给出(可能已经不可用);没选是空,生图时用第一个生图模型。 */
|
|
71
|
+
imageModel?: ModelRef;
|
|
72
|
+
/** 新会话的思考档位:建会话时记到会话上,之后改它不影响已有的会话。 */
|
|
73
|
+
thinking: ThinkingLevel;
|
|
74
|
+
/** 模型请求的重试策略,已收好范围;改了正在重试的请求从下一次等待起就用新值。 */
|
|
75
|
+
retryPolicy: RetryPolicy;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* 登记过的项目:一件事和它所在的文件夹。同一个文件夹可以登记成几个项目,所以会话记的是项目 id,不靠目录认项目。
|
|
79
|
+
*/
|
|
80
|
+
export interface ProjectEntry {
|
|
81
|
+
id: string;
|
|
82
|
+
name: string;
|
|
83
|
+
/** 在这个项目里新开的会话在这里工作;改了它,已有的会话还在原来的目录。 */
|
|
84
|
+
path: string;
|
|
85
|
+
/** 源文件夹;第一个仍是 path,其余目录允许读取。 */
|
|
86
|
+
folders?: string[];
|
|
87
|
+
/** 手动排列的会话 id;新会话排在这些会话前面。 */
|
|
88
|
+
sessionOrder?: string[];
|
|
89
|
+
}
|
|
90
|
+
export type SessionUsage = Pick<UsageRequestBucket, "input" | "output" | "cacheRead" | "cacheWrite" | "cost" | "unpriced">;
|
|
91
|
+
/** 悬停卡片的统计;花销来自账本,不随撤回或压缩减少。 */
|
|
92
|
+
export interface SessionStats {
|
|
93
|
+
turns: number;
|
|
94
|
+
steps: number;
|
|
95
|
+
usage: SessionUsage;
|
|
96
|
+
/** 当前对话回复的输入统计;附带模型调用和子会话不计入。 */
|
|
97
|
+
replyUsage: Pick<SessionUsage, "input" | "cacheRead" | "cacheWrite">;
|
|
98
|
+
children: Array<{
|
|
99
|
+
owner?: string;
|
|
100
|
+
usage: SessionUsage;
|
|
101
|
+
}>;
|
|
102
|
+
}
|
|
103
|
+
/** 新会话开在哪:项目里、某个文件夹,都不给就是不属于任何项目的聊天,开在 agent 的公共目录里。 */
|
|
104
|
+
export interface SessionTarget {
|
|
105
|
+
project?: string;
|
|
106
|
+
cwd?: string;
|
|
107
|
+
}
|
|
108
|
+
export interface SessionSummary {
|
|
109
|
+
id: string;
|
|
110
|
+
/** 默认为第一条消息的开头,也可由用户或插件命名;空字符串时界面显示「新会话」。 */
|
|
111
|
+
title: string;
|
|
112
|
+
/** 用户手动命名过,自动标题不再覆盖。 */
|
|
113
|
+
titleEdited?: boolean;
|
|
114
|
+
/** 工作目录:工具在这里读写、执行命令。 */
|
|
115
|
+
cwd: string;
|
|
116
|
+
/** 开在哪个项目里(项目 id)。没有、或者项目已经移除,就是不属于任何项目的聊天。 */
|
|
117
|
+
project?: string;
|
|
118
|
+
createdAt: number;
|
|
119
|
+
updatedAt: number;
|
|
120
|
+
running: boolean;
|
|
121
|
+
/**
|
|
122
|
+
* 它派出去的后台运行(子智能体之类,见 `SessionAccess.start`)还没都回来,或者交回的结果攒着、还没送进会话。
|
|
123
|
+
* 和 `running` 各管各的:`running || background` 才是这件事还没做完(回答底下的交付卡片等它)。只在内存里,不存盘。
|
|
124
|
+
*/
|
|
125
|
+
background?: boolean;
|
|
126
|
+
/** 这个会话选的模型;没选、或者选的已经不可用时用默认模型。 */
|
|
127
|
+
model?: ModelRef;
|
|
128
|
+
/** 这个会话选的思考档位;没选时用模型的默认档,模型没有这一档时就近取一档。 */
|
|
129
|
+
thinking?: ThinkingLevel;
|
|
130
|
+
/** 上一轮是怎么结束的;正在跑、还没跑过、或者上次没来得及记下(进程崩了)时没有。 */
|
|
131
|
+
stop?: TurnStop;
|
|
132
|
+
/** 归档了:移出侧栏,记录和用量都还在,在设置 › 已归档的聊天里取消归档或删除。 */
|
|
133
|
+
archived?: boolean;
|
|
134
|
+
/** 置顶单独显示;归档不清掉,取消归档后回到置顶区。 */
|
|
135
|
+
pinned?: boolean;
|
|
136
|
+
/** 手动标记的未读,下一次选中会话时清除。 */
|
|
137
|
+
unread?: boolean;
|
|
138
|
+
/**
|
|
139
|
+
* 子会话挂在哪个会话下面(插件建的侧边聊天、子 Agent,见 `SessionAccess.create`)。子会话不进侧栏,
|
|
140
|
+
* 工作目录和项目随父会话,没另选模型时用父会话的模型,父会话删掉时一起删。
|
|
141
|
+
*/
|
|
142
|
+
parentId?: string;
|
|
143
|
+
/**
|
|
144
|
+
* 建这个会话的插件:只有它能在里面发起一轮。有 `owner` 没有 `parentId` 的是插件的独立会话(见 `SessionAccess.create`),
|
|
145
|
+
* 和子会话一样不进侧栏。侧栏里的会话两样都没有。
|
|
146
|
+
*/
|
|
147
|
+
owner?: string;
|
|
148
|
+
/** 插件经 `ctx.sessions.launch` 从哪个会话开出来的(计划交出去执行的那个会话、那次调用)。会话本身独立保存,侧栏同组时嵌套在来源下面。 */
|
|
149
|
+
spawnedFrom?: {
|
|
150
|
+
sessionId: string;
|
|
151
|
+
toolCallId?: string;
|
|
152
|
+
};
|
|
153
|
+
/** 从哪条会话的消息分叉;来源存在于同一分组时嵌套显示。 */
|
|
154
|
+
forkedFrom?: {
|
|
155
|
+
sessionId: string;
|
|
156
|
+
};
|
|
157
|
+
/** 记录里有几条消息(人说的、回复、工具结果都算),给已归档的页和删除前的问题说「多少」。 */
|
|
158
|
+
messageCount?: number;
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* 一轮为什么结束:答完了(done)、人按了停(aborted)、出错(error)、用满了步数(max_turns)、
|
|
162
|
+
* 原地打转被叫停(stalled)、应用退出时还在跑(interrupted)。
|
|
163
|
+
*/
|
|
164
|
+
export type NoticeLevel = "info" | "warn" | "error";
|
|
165
|
+
export type StopReason = "done" | "aborted" | "error" | "max_turns" | "stalled" | "interrupted";
|
|
166
|
+
export interface TurnStop {
|
|
167
|
+
reason: StopReason;
|
|
168
|
+
/** 出错时给人看的那句话。 */
|
|
169
|
+
error?: string;
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* 一次连接上的岔子,从开始到收场:等着重试、接上了、放弃了、等的时候被人停下。
|
|
173
|
+
* 同一次中断重试几回都是这一条,次数往上加;接上以后再断是新的一条。
|
|
174
|
+
*/
|
|
175
|
+
export interface Hiccup {
|
|
176
|
+
id: string;
|
|
177
|
+
/** 发生时会话里已经有几条消息:界面按它把这条记录插进转录。 */
|
|
178
|
+
at: number;
|
|
179
|
+
attempts: number;
|
|
180
|
+
/** 这次等待在什么时刻结束(毫秒时间戳);存时刻不存时长,时长在画出来之前就过期了。 */
|
|
181
|
+
until: number;
|
|
182
|
+
/** 一行放得下的原因。 */
|
|
183
|
+
summary: string;
|
|
184
|
+
/** 服务商的原文,展开才看。 */
|
|
185
|
+
detail?: string;
|
|
186
|
+
kind: "network" | "upstream" | "fatal";
|
|
187
|
+
/** 同一个错误的指纹:连着好几次一字不差,界面就说「一直是同一个错误」。 */
|
|
188
|
+
fingerprint: string;
|
|
189
|
+
/** 同一个指纹连续出现了几次。 */
|
|
190
|
+
repeated: number;
|
|
191
|
+
/** `switched`:等重试时人换了模型,这次请求放手,换成新模型从同一处重发。 */
|
|
192
|
+
outcome: "waiting" | "recovered" | "gave_up" | "stopped" | "switched";
|
|
193
|
+
/** 换成了哪个模型(名字),只在 `switched` 时有。 */
|
|
194
|
+
switchedTo?: string;
|
|
195
|
+
/** 下一步该去哪:查密钥(check-key)、查模型(check-model)、看额度……,来自失败分类。 */
|
|
196
|
+
hint?: string;
|
|
197
|
+
}
|
|
198
|
+
export type { ModelCatalogDocument, RetryPolicy, ThinkingLevel };
|
|
199
|
+
/** 测试连接的结果:真发一次请求,拿到第一个 token 就停。 */
|
|
200
|
+
export interface ProviderTestResult {
|
|
201
|
+
ok: boolean;
|
|
202
|
+
latencyMs: number;
|
|
203
|
+
/** 给人看的一句话:成功时说谁回答了,失败时是原因。 */
|
|
204
|
+
message: string;
|
|
205
|
+
/** 测整个供应商时,端点列出来的模型 id(端点支持列出时才有)。 */
|
|
206
|
+
models?: string[];
|
|
207
|
+
}
|
|
208
|
+
/** 从供应商的 `/v1/models` 拉到的模型 id,按名字排好。 */
|
|
209
|
+
export interface FetchModelsResult {
|
|
210
|
+
ok: boolean;
|
|
211
|
+
models: string[];
|
|
212
|
+
error?: string;
|
|
213
|
+
}
|
|
214
|
+
/** 拉一次模型目录的结果。 */
|
|
215
|
+
export interface CatalogSyncResult {
|
|
216
|
+
status: "updated" | "unchanged" | "failed";
|
|
217
|
+
/** 失败原因,给设置页显示。 */
|
|
218
|
+
error?: string;
|
|
219
|
+
source: ModelCatalogDocument["source"];
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* 导入前的预览。文件由 agent 进程读,key 不出 agent 进程,所以这里只说有没有。
|
|
223
|
+
* 读不懂时 problem 说明是哪一种:不是 JSON、不是供应商文件、比这个版本新、一个能用的供应商都没有。
|
|
224
|
+
*/
|
|
225
|
+
export type ProviderImportPreview = {
|
|
226
|
+
ok: false;
|
|
227
|
+
problem: "not-json" | "not-a-bundle" | "too-new" | "no-providers";
|
|
228
|
+
} | {
|
|
229
|
+
ok: true;
|
|
230
|
+
entries: ProviderImportEntry[];
|
|
231
|
+
/** 文件里读不懂、被丢掉的条目数。 */
|
|
232
|
+
dropped: number;
|
|
233
|
+
};
|
|
234
|
+
export interface ProviderImportEntry {
|
|
235
|
+
id: string;
|
|
236
|
+
name: string;
|
|
237
|
+
api: ApiFormat;
|
|
238
|
+
baseUrl: string;
|
|
239
|
+
models: number;
|
|
240
|
+
/** 这台机器上已经有同 id 的供应商:导入会替换它。 */
|
|
241
|
+
kind: "new" | "replace";
|
|
242
|
+
/** 文件里带了 key。 */
|
|
243
|
+
hasKey: boolean;
|
|
244
|
+
/** 文件里没带 key,被替换的那个有,导入后留着本机的。 */
|
|
245
|
+
keepsLocalKey: boolean;
|
|
246
|
+
}
|
|
247
|
+
/** 正在等用户决定的一次工具调用。 */
|
|
248
|
+
export interface ApprovalRequest {
|
|
249
|
+
toolCallId: string;
|
|
250
|
+
tool: string;
|
|
251
|
+
/** 要做的是哪一类事:本体工具是 `bash`、`write`、`edit`,插件的工具是它的名字。卡片按它写一个小标签。 */
|
|
252
|
+
kind: string;
|
|
253
|
+
title: string;
|
|
254
|
+
/** 卡片正文:命令、diff,插件的工具是它的参数。 */
|
|
255
|
+
detail: string;
|
|
256
|
+
/** 「以后不再问」记下的东西:命令或文件的绝对路径。没有时只能答这一次。 */
|
|
257
|
+
subject?: string;
|
|
258
|
+
/** 为什么要问:插件的层自己问时给的理由,或者模型申请提权时说的那句话。 */
|
|
259
|
+
reason?: string;
|
|
260
|
+
/** 申请把这一条命令放到更宽的沙箱模式里跑。只管这一次,答「以后不再问」也不会记下。 */
|
|
261
|
+
escalation?: "workspace-write" | "danger-full-access";
|
|
262
|
+
/**
|
|
263
|
+
* 问的是人的决定(批准一份计划),不是权限:完全访问、外层放行、「以后不再问」都不替人答,总是弹给人。
|
|
264
|
+
* 没有 `subject`,只能答这一次。
|
|
265
|
+
*/
|
|
266
|
+
userOnly?: boolean;
|
|
267
|
+
/**
|
|
268
|
+
* 等这张卡时一句短的状态(按界面语言),画在对话末尾的运行行、侧栏的悬停和系统通知里:「等你批准计划」「等你填写表单」。
|
|
269
|
+
* 不给时本体按 `userOnly` 说「等待你的回答」或「等待你的批准」。
|
|
270
|
+
*/
|
|
271
|
+
waiting?: string;
|
|
272
|
+
/**
|
|
273
|
+
* 这张卡等到什么时候(毫秒时间戳),到时没人答按拒绝收场:权限请求等 5 分钟,`userOnly` 的(提问、表单、计划)等
|
|
274
|
+
* 30 分钟。本体弹卡时填,插件经 `run.ask` 给的不算。给时刻而不是时长:事件跨进程送到、画出来时,时长已经不准了。
|
|
275
|
+
*/
|
|
276
|
+
expiresAt?: number;
|
|
277
|
+
}
|
|
278
|
+
/** 人怎么答:允许这一次、以后都不再问这一项、拒绝。 */
|
|
279
|
+
export type ApprovalDecision = "once" | "always" | "reject";
|
|
280
|
+
/**
|
|
281
|
+
* 用户发出去的一条消息。
|
|
282
|
+
*
|
|
283
|
+
* `content` 是给模型的:字和图片按附件在正文里的位置排好,文本附件的正文也在里面。`displayText` 是气泡里给人看的
|
|
284
|
+
* 那句话(带着 `【图片 1】` 这样的标记);`attachments` 只有名字和门类,给气泡画附件用,正文不再存一份。
|
|
285
|
+
* 图片的 `data` 是不带 `data:` 前缀的 base64;存进会话时大图挪到 `session-media` 里,消息只留 `media` 名。
|
|
286
|
+
*/
|
|
287
|
+
export interface OutgoingMessage {
|
|
288
|
+
/** `@` 选中的历史会话,正文经 session:// 引用,不把整份转录塞进消息。 */
|
|
289
|
+
sessionRefs?: {
|
|
290
|
+
id: string;
|
|
291
|
+
title: string;
|
|
292
|
+
}[];
|
|
293
|
+
content: UserContent[];
|
|
294
|
+
displayText?: string;
|
|
295
|
+
attachments?: MessageAttachment[];
|
|
296
|
+
/** 界面替人说的话(「继续」按钮发的那句):照样发给模型,对话里不画成人的气泡,也不拿来当标题。 */
|
|
297
|
+
synthetic?: boolean;
|
|
298
|
+
/** 这一轮还在跑时:先停下它、等它收完尾,再拿这条开始新的一轮(排队条上的「现在就发」)。不给时正在跑就报错。 */
|
|
299
|
+
interrupt?: boolean;
|
|
300
|
+
/**
|
|
301
|
+
* 这一轮还在跑时:插进去,模型做完手上这一步、下一次请求之前读到(命令声明的 `deliver: "steer"`)。这一轮已经在收尾、
|
|
302
|
+
* 不会再来取话时排进队尾。空闲时就是新的一轮。
|
|
303
|
+
*/
|
|
304
|
+
steer?: boolean;
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* 排在一个会话后面、等着轮到自己的一条(输入框上方那几行)。会话忙时人按下回车的,和侧边聊天交过来的任务排的是同一条队。
|
|
308
|
+
* 存在 agent 进程里、落盘:关了窗口、重开应用还在。这一轮以完成结束时发下一条;停了、出错了留着等人。
|
|
309
|
+
*/
|
|
310
|
+
export interface QueuedMessage {
|
|
311
|
+
id: string;
|
|
312
|
+
/** 行里显示的那句话。 */
|
|
313
|
+
preview: string;
|
|
314
|
+
/** 轮到它时整份发出去的东西。 */
|
|
315
|
+
message: OutgoingMessage;
|
|
316
|
+
/** 不是人在这个会话的输入框里排的:`side-chat` 是侧边聊天交过来的任务,发出去的消息带着同样的来处(`UserMessage.origin`)。 */
|
|
317
|
+
origin?: "side-chat";
|
|
318
|
+
/** 侧边聊天交过来的:是哪一个子会话交的,它的回执条(`HandedTask`)据此列出这一条。 */
|
|
319
|
+
sideId?: string;
|
|
320
|
+
createdAt: number;
|
|
321
|
+
}
|
|
322
|
+
/**
|
|
323
|
+
* 侧边聊天交给父会话的一件事走到了哪:子会话的回执条一行一件。还排着的就是父会话队列里那一条(`id` 相同),
|
|
324
|
+
* 开始跑以后的状态宿主只记在内存里,重开应用就没了;做了什么在父会话的转录里,这里只是回执。
|
|
325
|
+
*/
|
|
326
|
+
export interface HandedTask {
|
|
327
|
+
id: string;
|
|
328
|
+
/** 交过去的指令原文。 */
|
|
329
|
+
text: string;
|
|
330
|
+
/** `running` 是父会话正在为它跑一轮。 */
|
|
331
|
+
status: "queued" | "running" | "done" | "failed" | "cancelled";
|
|
332
|
+
createdAt: number;
|
|
333
|
+
startedAt?: number;
|
|
334
|
+
finishedAt?: number;
|
|
335
|
+
/** 失败时给人看的那句话。 */
|
|
336
|
+
error?: string;
|
|
337
|
+
/** 没出错却没做完:原地打转被叫停、用满了步数。 */
|
|
338
|
+
unfinished?: "stalled" | "max_turns";
|
|
339
|
+
/** 父会话被停下、这件跟着停的是 `stop`(还能继续);人从回执条或计划作废里收回的是 `user`。 */
|
|
340
|
+
cancelledBy?: "user" | "stop";
|
|
341
|
+
}
|
|
342
|
+
export interface DocumentText {
|
|
343
|
+
text: string;
|
|
344
|
+
/** 有页,但一页字都没有:多半是扫描件。 */
|
|
345
|
+
imageOnly?: boolean;
|
|
346
|
+
/** 字太多被截断了。 */
|
|
347
|
+
truncated?: boolean;
|
|
348
|
+
/** 截断时原文一共多少字,界面据此说「后面还有约多少字没附上」。 */
|
|
349
|
+
fullLength?: number;
|
|
350
|
+
}
|
|
351
|
+
export interface FileEntry {
|
|
352
|
+
name: string;
|
|
353
|
+
path: string;
|
|
354
|
+
isDirectory: boolean;
|
|
355
|
+
}
|
|
356
|
+
/** 文件面板读到的一个文件。 */
|
|
357
|
+
export interface FileContents {
|
|
358
|
+
text: string;
|
|
359
|
+
/** 比读取上限长,`text` 只是开头。 */
|
|
360
|
+
truncated: boolean;
|
|
361
|
+
bytes: number;
|
|
362
|
+
/** 不是文字(含 NUL 字节):`text` 为空,界面只说它是二进制文件。 */
|
|
363
|
+
binary?: boolean;
|
|
364
|
+
/** 读的那一刻的 `mtimeMs`。 */
|
|
365
|
+
modifiedAt?: number;
|
|
366
|
+
}
|
|
367
|
+
export interface SessionView {
|
|
368
|
+
summary: SessionSummary;
|
|
369
|
+
messages: Message[];
|
|
370
|
+
/** 正在生成、还没写完的回复。 */
|
|
371
|
+
draft?: AssistantMessage;
|
|
372
|
+
approval?: ApprovalRequest;
|
|
373
|
+
/** 排在 `approval` 后面还在等的审批张数,没有时不带。 */
|
|
374
|
+
queuedApprovals?: number;
|
|
375
|
+
/** 正在执行的工具调用到目前为止的输出。 */
|
|
376
|
+
progress: Record<string, string>;
|
|
377
|
+
/** 正在执行的工具调用开始的时刻(毫秒时间戳)。排着还没轮到的调用不在里面。 */
|
|
378
|
+
startedAt: Record<string, number>;
|
|
379
|
+
/** 这一轮里连接出的岔子,下一轮开始时清空,不存盘。 */
|
|
380
|
+
hiccups: Hiccup[];
|
|
381
|
+
/** 压缩过的上下文,旧的在前。 */
|
|
382
|
+
compactions: CompactionMark[];
|
|
383
|
+
/** 正在生成摘要。 */
|
|
384
|
+
compacting: boolean;
|
|
385
|
+
/** 排着的几条,先排的在前,见 `QueuedMessage`。 */
|
|
386
|
+
queue: QueuedMessage[];
|
|
387
|
+
/** 这个子会话(侧边聊天)交给父会话的那几件事,先交的在前,见 `HandedTask`。没交过时没有。 */
|
|
388
|
+
tasks?: HandedTask[];
|
|
389
|
+
/** 转录里那几行压缩:自动的(定下要压以后)和人敲的 `/compact`,连同进行中的那一次,旧的在前。 */
|
|
390
|
+
compactionRuns: CompactionRun[];
|
|
391
|
+
}
|
|
392
|
+
/**
|
|
393
|
+
* `/compact` 和自动压缩的结果。`done` 压完了;`too-short` 对话太短;`already-tight` 已经够紧凑、压了也不会更小;
|
|
394
|
+
* `prune-only` 只剪了几段过长的工具输出、没有要摘要的;`cancelled` 被停下;`failed` 出错(`error` 是原因)。
|
|
395
|
+
*/
|
|
396
|
+
export type CompactionCode = "done" | "too-short" | "already-tight" | "prune-only" | "cancelled" | "failed";
|
|
397
|
+
/** 转录里的一次压缩:画在开始时会话的第 `at` 条消息之前(数到末尾的画在最后)。存在会话库里,撤回截掉它时一起去掉。 */
|
|
398
|
+
export interface CompactionRun {
|
|
399
|
+
id: string;
|
|
400
|
+
at: number;
|
|
401
|
+
/** 开始的时刻。 */
|
|
402
|
+
startedAt: number;
|
|
403
|
+
/** 人敲的那一行(`/compact 保留接口设计`);自动压缩没有。 */
|
|
404
|
+
input?: string;
|
|
405
|
+
status: "running" | "done" | "skipped" | "failed" | "cancelled";
|
|
406
|
+
/** 走到哪一步了,见 `CompactionProgress`。 */
|
|
407
|
+
phase: "summarizing" | "retrying" | "fallback";
|
|
408
|
+
/** 摘要请求重试过几次。 */
|
|
409
|
+
retries: number;
|
|
410
|
+
/** 结束时为什么是这个结果;`failed` 时 `error` 是原因。 */
|
|
411
|
+
code?: CompactionCode;
|
|
412
|
+
error?: string;
|
|
413
|
+
/** 压完前后发给模型的消息条数。 */
|
|
414
|
+
before?: number;
|
|
415
|
+
after?: number;
|
|
416
|
+
/** 摘要是怎么来的,见 `CompactionVia`。 */
|
|
417
|
+
via?: "fork" | "independent" | "fallback" | "dropped";
|
|
418
|
+
/** 一轮收尾以后、人还没开口时压的:外面没有一轮在跑,这一行自己说「进行中」。 */
|
|
419
|
+
idle?: boolean;
|
|
420
|
+
}
|
|
421
|
+
/** 一次上下文压缩:界面在 `keptFrom` 那条消息前画一条分隔线。会话里的消息一条不少,只是模型从此看到的是摘要加之后的原文。 */
|
|
422
|
+
export interface CompactionMark {
|
|
423
|
+
/** 会话里从第几条起原样发给模型。 */
|
|
424
|
+
keptFrom: number;
|
|
425
|
+
/** 压缩前后发给模型的消息条数。 */
|
|
426
|
+
before: number;
|
|
427
|
+
after: number;
|
|
428
|
+
}
|
|
429
|
+
/** `/` 菜单里的一条命令,记着是哪个插件供的:发送前找它展开。 */
|
|
430
|
+
export interface CommandEntry extends SlashCommand {
|
|
431
|
+
plugin: string;
|
|
432
|
+
}
|
|
433
|
+
/** `waiting`:要用的服务还没有插件提供,补上了自动加载(见 `Plugin.inject`)。 */
|
|
434
|
+
export type PluginState = "loading" | "active" | "waiting" | "failed" | "disabled" | "disposed";
|
|
435
|
+
export interface PluginStatus {
|
|
436
|
+
name: string;
|
|
437
|
+
/** 加载时的标识(`PluginEntry.key`):插件的目录名,插件市场按它把条目和状态对上。 */
|
|
438
|
+
key: string;
|
|
439
|
+
state: PluginState;
|
|
440
|
+
error?: string;
|
|
441
|
+
/** 界面入口的地址;没有界面入口时为空。 */
|
|
442
|
+
ui?: string;
|
|
443
|
+
/** 随应用发的插件:不能停用、卸载,只能被别的插件替换(服务)或在外层接管(钩子)。 */
|
|
444
|
+
builtin?: boolean;
|
|
445
|
+
/** 等待中时,还没有插件提供的那几项服务。 */
|
|
446
|
+
waitingFor?: string[];
|
|
447
|
+
}
|
|
448
|
+
export type AgentEvent = {
|
|
449
|
+
type: "fileRemoved";
|
|
450
|
+
paths: string[];
|
|
451
|
+
}
|
|
452
|
+
/** 文件树改名成功;所有窗口里看着该文件或目录的标签同步跟随。 */
|
|
453
|
+
| {
|
|
454
|
+
type: "fileMoved";
|
|
455
|
+
from: string;
|
|
456
|
+
to: string;
|
|
457
|
+
} | {
|
|
458
|
+
type: "sessions";
|
|
459
|
+
sessions: SessionSummary[];
|
|
460
|
+
}
|
|
461
|
+
/** 一轮及其后台工作全部收尾;系统通知不能把中间停顿说成完成。 */
|
|
462
|
+
| {
|
|
463
|
+
type: "idle";
|
|
464
|
+
sessionId: string;
|
|
465
|
+
}
|
|
466
|
+
/** 项目登记、改动或移除了:全部项目,新登记的在前。 */
|
|
467
|
+
| {
|
|
468
|
+
type: "projects";
|
|
469
|
+
projects: ProjectEntry[];
|
|
470
|
+
}
|
|
471
|
+
/** 一条消息写进了会话。回复(assistant)同时顶替正在写的草稿,不另发清空草稿的 draft 事件。 */
|
|
472
|
+
| {
|
|
473
|
+
type: "message";
|
|
474
|
+
sessionId: string;
|
|
475
|
+
message: Message;
|
|
476
|
+
}
|
|
477
|
+
/** 会话截掉了尾巴(撤回、编辑重发):只留前 `count` 条消息,压缩记录和压缩行换成留下的那些。 */
|
|
478
|
+
| {
|
|
479
|
+
type: "rewound";
|
|
480
|
+
sessionId: string;
|
|
481
|
+
count: number;
|
|
482
|
+
compactions: CompactionMark[];
|
|
483
|
+
runs: CompactionRun[];
|
|
484
|
+
}
|
|
485
|
+
/** 正在生成的回复的最新快照;回复写完后以 message 事件给出完整的一条。undefined 表示草稿作废、没有落进会话。 */
|
|
486
|
+
| {
|
|
487
|
+
type: "draft";
|
|
488
|
+
sessionId: string;
|
|
489
|
+
draft: AssistantMessage | undefined;
|
|
490
|
+
}
|
|
491
|
+
/** 一次工具调用开始执行了;跑完时随它的结果(message 事件)一起作废。 */
|
|
492
|
+
| {
|
|
493
|
+
type: "toolStart";
|
|
494
|
+
sessionId: string;
|
|
495
|
+
toolCallId: string;
|
|
496
|
+
startedAt: number;
|
|
497
|
+
} | {
|
|
498
|
+
type: "progress";
|
|
499
|
+
sessionId: string;
|
|
500
|
+
toolCallId: string;
|
|
501
|
+
output: string;
|
|
502
|
+
}
|
|
503
|
+
/** 弹给人的那张审批卡换了;`queuedApprovals` 是排在它后面还在等的张数(卡上写 +N),没有时不带。 */
|
|
504
|
+
| {
|
|
505
|
+
type: "approval";
|
|
506
|
+
sessionId: string;
|
|
507
|
+
approval: ApprovalRequest | undefined;
|
|
508
|
+
queuedApprovals?: number;
|
|
509
|
+
}
|
|
510
|
+
/** 这一轮的连接岔子变了(开始重试、又重试一次、收场):全部的最新快照。 */
|
|
511
|
+
| {
|
|
512
|
+
type: "hiccups";
|
|
513
|
+
sessionId: string;
|
|
514
|
+
hiccups: Hiccup[];
|
|
515
|
+
}
|
|
516
|
+
/** 压缩开始、走了一步、收场了:`runs` 是全部压缩行的最新快照。 */
|
|
517
|
+
| {
|
|
518
|
+
type: "compaction";
|
|
519
|
+
sessionId: string;
|
|
520
|
+
compacting: boolean;
|
|
521
|
+
compactions: CompactionMark[];
|
|
522
|
+
runs: CompactionRun[];
|
|
523
|
+
}
|
|
524
|
+
/** 一个会话排着的几条变了:整条队的最新快照。 */
|
|
525
|
+
| {
|
|
526
|
+
type: "queue";
|
|
527
|
+
sessionId: string;
|
|
528
|
+
queue: QueuedMessage[];
|
|
529
|
+
}
|
|
530
|
+
/** 一个子会话交给父会话的那几件事有了变化(排上、开始、收场、拿掉):全部的最新快照。 */
|
|
531
|
+
| {
|
|
532
|
+
type: "tasks";
|
|
533
|
+
sessionId: string;
|
|
534
|
+
tasks: HandedTask[];
|
|
535
|
+
}
|
|
536
|
+
/** 这一轮出了模型调用以外的问题(如没配置模型、钩子出错)。 */
|
|
537
|
+
/** 有 `level` 的进提示条(插件经 `ctx.notice` 说的、循环在压缩或重发);没有的是这一轮出了错,写在输入框上面。 */
|
|
538
|
+
| {
|
|
539
|
+
type: "notice";
|
|
540
|
+
sessionId: string;
|
|
541
|
+
text: string;
|
|
542
|
+
level?: NoticeLevel;
|
|
543
|
+
}
|
|
544
|
+
/** 插件装上、卸下、启用或停用了:全部插件的最新状态。 */
|
|
545
|
+
| {
|
|
546
|
+
type: "plugins";
|
|
547
|
+
plugins: PluginStatus[];
|
|
548
|
+
};
|
|
549
|
+
/**
|
|
550
|
+
* 上下文窗口按来源拆开:对话消息、工具表(MCP 服务的工具 `mcpTools` 单独一段,其余是 `tools`)、系统提示词,
|
|
551
|
+
* 以及系统提示词里单独列出的技能目录(plume.skills 的 `skills` 段)、项目指令(plume.prompt 的 `projectInstructions` 段)
|
|
552
|
+
* 和项目记忆(`projectMemory` 段)。
|
|
553
|
+
*/
|
|
554
|
+
export type ContextSegmentKey = "messages" | "tools" | "mcpTools" | "skills" | "systemPrompt" | "projectInstructions" | "projectMemory";
|
|
555
|
+
export interface ContextBreakdown {
|
|
556
|
+
/** 下一轮会用的模型的上下文窗口。 */
|
|
557
|
+
limit: number;
|
|
558
|
+
/** 各段之和。`measured` 时就是最近一条写完的回复报的「输入 + 缓存读取 + 缓存写入 + 输出」。 */
|
|
559
|
+
used: number;
|
|
560
|
+
/** 总数来自服务商;否则是按字数估的。各段永远是按字数估的,有总数时按比例缩放到它。 */
|
|
561
|
+
measured: boolean;
|
|
562
|
+
/** 大的在前;是 0 的不列。 */
|
|
563
|
+
segments: Array<{
|
|
564
|
+
key: ContextSegmentKey;
|
|
565
|
+
tokens: number;
|
|
566
|
+
}>;
|
|
567
|
+
/**
|
|
568
|
+
* 项目指令和项目记忆两段里来自各文件的部分(插件经 `PromptSection.files` 标的),先项目指令、后项目记忆,各按段里的顺序。
|
|
569
|
+
* 和各段一样按字数估,按各自所在的段缩放;包在文件外面的说明文字不算哪个文件。没有标来源时是空的。
|
|
570
|
+
*/
|
|
571
|
+
memoryFiles: Array<{
|
|
572
|
+
path: string;
|
|
573
|
+
tokens: number;
|
|
574
|
+
}>;
|
|
575
|
+
}
|
|
576
|
+
export interface AgentService {
|
|
577
|
+
/** 项目覆盖的来源与差异,不返回供应商凭据。 */
|
|
578
|
+
projectLayer(cwd: string): Promise<ProjectLayerView>;
|
|
579
|
+
fileOperation(sessionId: string, operation: FileOperation): Promise<FileOpResult>;
|
|
580
|
+
getSettings(): Promise<SettingsView>;
|
|
581
|
+
/** 新建(id 为空)或整体替换一个供应商,返回它的 id。apiKey 为空表示不改已保存的 key。 */
|
|
582
|
+
saveProvider(provider: ProviderSettings & {
|
|
583
|
+
apiKey?: string;
|
|
584
|
+
}): Promise<string>;
|
|
585
|
+
deleteProvider(providerId: string): Promise<void>;
|
|
586
|
+
setDefaultModel(model: ModelRef): Promise<void>;
|
|
587
|
+
/** 设默认生图模型;传 null 回到「自动」(第一个生图模型)。 */
|
|
588
|
+
setImageModel(model: ModelRef | null): Promise<void>;
|
|
589
|
+
/** 整体替换星标的模型。 */
|
|
590
|
+
setFavoriteModels(models: ModelRef[]): Promise<void>;
|
|
591
|
+
setPermissionMode(mode: PermissionMode): Promise<void>;
|
|
592
|
+
/** 设新会话的思考档位,已有的会话不变。 */
|
|
593
|
+
setDefaultThinking(thinking: ThinkingLevel): Promise<void>;
|
|
594
|
+
/** 整体替换重试策略,存之前按 `normalizeRetryPolicy` 收好范围。 */
|
|
595
|
+
setRetryPolicy(policy: RetryPolicy): Promise<void>;
|
|
596
|
+
/** 改个性化设置里给出的几项,下一轮生效。 */
|
|
597
|
+
setPersonalization(change: Partial<Personalization>): Promise<void>;
|
|
598
|
+
/** 给会话选模型,下一轮生效;传空表示跟随默认模型。 */
|
|
599
|
+
setSessionModel(sessionId: string, model: ModelRef | undefined): Promise<void>;
|
|
600
|
+
/** 给会话选思考档位,下一轮生效;传空表示用模型的默认档。 */
|
|
601
|
+
setSessionThinking(sessionId: string, thinking: ThinkingLevel | undefined): Promise<void>;
|
|
602
|
+
/**
|
|
603
|
+
* 测试连接:测整个供应商(modelId 为空)时先列一次模型,再用第一个模型真发一次请求;指定了模型就只测它。
|
|
604
|
+
* 用的是已经保存的设置,key 不出 agent 进程。
|
|
605
|
+
*/
|
|
606
|
+
testProvider(providerId: string, modelId: string | undefined): Promise<ProviderTestResult>;
|
|
607
|
+
/** 从供应商的 `/v1/models` 拉模型列表。 */
|
|
608
|
+
fetchModels(providerId: string): Promise<FetchModelsResult>;
|
|
609
|
+
/** agent 进程当前生效的模型目录(可能比界面打包的那份新);版本和 knownRevision 相同时返回 null。 */
|
|
610
|
+
modelCatalog(knownRevision: string | undefined): Promise<ModelCatalogDocument | null>;
|
|
611
|
+
/** 立即从 pi.dev 拉一次模型目录。 */
|
|
612
|
+
updateModelCatalog(): Promise<CatalogSyncResult>;
|
|
613
|
+
/** 把全部供应商(连同 key,Magpie 的除外)写进 file,返回写了几个、带没带 key。路径由界面经主进程的保存对话框拿到。 */
|
|
614
|
+
exportProviders(file: string): Promise<{
|
|
615
|
+
providers: number;
|
|
616
|
+
containsSecrets: boolean;
|
|
617
|
+
}>;
|
|
618
|
+
/** 读 file,说明导入会做什么,不写任何东西。 */
|
|
619
|
+
previewProviderImport(file: string): Promise<ProviderImportPreview>;
|
|
620
|
+
/** 导入 file 里选中的那几个供应商(按 id),返回导入了几个。默认模型不在了就落到第一个可用的。 */
|
|
621
|
+
importProviders(file: string, providerIds: string[]): Promise<number>;
|
|
622
|
+
/** 全部项目,新登记的在前。 */
|
|
623
|
+
listProjects(): ProjectEntry[];
|
|
624
|
+
/** 登记一个项目;名字留空时用文件夹名。 */
|
|
625
|
+
createProject(name: string, path: string, folders?: string[]): Promise<ProjectEntry>;
|
|
626
|
+
updateProject(projectId: string, name: string, path: string, folders?: string[]): Promise<void>;
|
|
627
|
+
/** 只忘掉这条登记:磁盘上的文件夹不动,它的会话还在,归到「聊天」里。 */
|
|
628
|
+
removeProject(projectId: string): Promise<void>;
|
|
629
|
+
/** 调整项目顺序。 */
|
|
630
|
+
reorderProjects(sourceId: string, targetId: string, placement: "before" | "after"): Promise<void>;
|
|
631
|
+
/** 保存项目内会话的手动顺序;只接受本项目的非置顶、非归档顶层会话。 */
|
|
632
|
+
reorderProjectSessions(projectId: string, sessionIds: string[]): Promise<void>;
|
|
633
|
+
sessionStats(sessionId: string): Promise<SessionStats>;
|
|
634
|
+
listSessions(): SessionSummary[];
|
|
635
|
+
createSession(target: SessionTarget): Promise<SessionSummary>;
|
|
636
|
+
getSession(sessionId: string): Promise<SessionView>;
|
|
637
|
+
deleteSession(sessionId: string): Promise<void>;
|
|
638
|
+
/** 修改会话标题,去掉首尾空白;空标题不保存,不改变最后活动时间。 */
|
|
639
|
+
renameSession(sessionId: string, title: string): Promise<void>;
|
|
640
|
+
/** 归档或取消归档。归档的会话照样能打开、接着聊。 */
|
|
641
|
+
setSessionArchived(sessionId: string, archived: boolean): Promise<void>;
|
|
642
|
+
/** 置顶和手动未读都不改变最后活动时间。 */
|
|
643
|
+
setSessionPinned(sessionId: string, pinned: boolean): Promise<void>;
|
|
644
|
+
setSessionUnread(sessionId: string, unread: boolean): Promise<void>;
|
|
645
|
+
/** 移入项目时切换工作目录;移出时保留目录。会话或子会话运行时不允许移动。 */
|
|
646
|
+
moveSessionProject(sessionId: string, projectId: string | undefined): Promise<void>;
|
|
647
|
+
/** 删掉全部归档的会话,正在跑的不动。返回删了几条。 */
|
|
648
|
+
deleteArchivedSessions(): Promise<number>;
|
|
649
|
+
/**
|
|
650
|
+
* 这个会话的上下文窗口用到哪儿了,见 `ContextBreakdown`。各段按这个会话最近一次发出的请求量(只在内存里),
|
|
651
|
+
* 本次启动后还没发过请求时是 null。
|
|
652
|
+
*/
|
|
653
|
+
contextBreakdown(sessionId: string): Promise<ContextBreakdown | null>;
|
|
654
|
+
/** 会话记录占了多少,按最后活动日摊开。 */
|
|
655
|
+
storageUse(): Promise<StorageUse>;
|
|
656
|
+
/** 删掉最后活动日落在这一段里的会话,正在跑的跳过。花销表不动。 */
|
|
657
|
+
clearSessions(range: ClearRange): Promise<ClearResult>;
|
|
658
|
+
/** 把整个会话库另存为一个 SQLite 文件。路径由界面经主进程的保存对话框拿到。 */
|
|
659
|
+
exportSessions(file: string): Promise<void>;
|
|
660
|
+
/** 只导出这一段会话。原始库包含草稿;Markdown 只含已落盘的正文、工具摘要,附件只列名称。 */
|
|
661
|
+
exportSession(sessionId: string, file: string, format: "database" | "markdown"): Promise<void>;
|
|
662
|
+
/** 发出一条消息,开始一轮。立即返回;过程经 watch 推送。正在跑时只收带 `interrupt` 的。 */
|
|
663
|
+
send(sessionId: string, message: OutgoingMessage): void;
|
|
664
|
+
/**
|
|
665
|
+
* 排到队尾(`QueuedMessage`),返回排上的那一条。会话这会儿空着(上一轮被停下、队里还有前面的)就由这一下发出队首,
|
|
666
|
+
* 新排的这条照样排在后面。子会话里只有建它的插件能发起一轮,不收。
|
|
667
|
+
*/
|
|
668
|
+
queue(sessionId: string, message: OutgoingMessage, preview: string): Promise<QueuedMessage>;
|
|
669
|
+
/** 「现在就发」:把这一条拿出来发,正在跑就先停下那一轮(同 `interrupt`)。没有这一条时什么都不做。 */
|
|
670
|
+
sendQueued(sessionId: string, id: string): Promise<void>;
|
|
671
|
+
/**
|
|
672
|
+
* 从队里拿掉这一条,交回拿掉的那条(删除、编辑退回输入框、交给插件的「更多」项都走这里);已经发出去、不在队里时是 undefined,
|
|
673
|
+
* 调用方据此知道它没拿到,不再拿旧的那份去用。
|
|
674
|
+
*/
|
|
675
|
+
removeQueued(sessionId: string, id: string): Promise<QueuedMessage | undefined>;
|
|
676
|
+
/** 拖动、↑↓ 改先后:`id` 那一条挪到 `targetId` 前面或后面。两条有一条不在队里时什么都不做。 */
|
|
677
|
+
moveQueued(sessionId: string, id: string, targetId: string, placement: "before" | "after"): Promise<void>;
|
|
678
|
+
/**
|
|
679
|
+
* 人在子会话(侧边聊天)的卡片上点了「交给主会话」:把这件事排进 `sessionId` 这个子会话的父会话,和插件的
|
|
680
|
+
* `ParentSession.enqueue` 同一条路(标着来自侧边聊天)。只认父会话,不是子会话时报错。
|
|
681
|
+
*/
|
|
682
|
+
queueTask(sessionId: string, instruction: string): Promise<void>;
|
|
683
|
+
/**
|
|
684
|
+
* 回执条上的「重试」「继续」:子会话 `sessionId` 交过去、失败了或随父会话停下的那件事重新排进父会话队尾,和第一次交过去一样。
|
|
685
|
+
* 别的状态不动,返回排上没有。
|
|
686
|
+
*/
|
|
687
|
+
retryTask(sessionId: string, taskId: string): Promise<boolean>;
|
|
688
|
+
/** 回执条上的「移除」:收了场的那件从列表里拿掉,父会话的转录不动。还排着、在跑的不动,返回拿掉没有。 */
|
|
689
|
+
dismissTask(sessionId: string, taskId: string): Promise<boolean>;
|
|
690
|
+
/**
|
|
691
|
+
* 编辑重发:第 `index` 条(人发的消息)连同它之后的全部截掉,拿 `message` 重新开始一轮。截完就返回,这一轮经 watch 推送。
|
|
692
|
+
* 正在跑时报错。图片块可以只带 `media`(会话里存着的那张),不用把像素再传一遍。
|
|
693
|
+
* `files` 为真时先把截掉的那段改过的文件退回去(钩子 session.rewind),退不回去就报错,对话不截、也不重发。
|
|
694
|
+
* 插件的子会话也能编辑重发(插件经 `ConversationProps.reask` 同意了),但不带 `files`;撤回、演算、分叉仍然只给人自己的会话。
|
|
695
|
+
*/
|
|
696
|
+
editMessage(sessionId: string, index: number, message: OutgoingMessage, options?: {
|
|
697
|
+
files?: boolean;
|
|
698
|
+
}): Promise<void>;
|
|
699
|
+
/** 撤回:第 `index` 条(人发的消息)连同它之后的全部截掉。正在跑时报错。`files` 同 `editMessage`。 */
|
|
700
|
+
revertMessage(sessionId: string, index: number, options?: {
|
|
701
|
+
files?: boolean;
|
|
702
|
+
}): Promise<void>;
|
|
703
|
+
/** 撤回、编辑重发第 `index` 条会截掉的那段改过哪些文件、能不能一起退回,只演算,不写(钩子 session.rewind)。 */
|
|
704
|
+
revertPlan(sessionId: string, index: number): Promise<RevertPlan>;
|
|
705
|
+
/**
|
|
706
|
+
* 从第 `index` 条分叉出一个新会话,原会话不动。人发的消息:新会话停在它之前;落定的回复:新会话带着它。
|
|
707
|
+
* `timestamp` 用来核对是不是那一条,对不上时按时间戳重找。正在跑也可以分叉。
|
|
708
|
+
*/
|
|
709
|
+
forkSession(sessionId: string, index: number, timestamp: number, title: string): Promise<SessionSummary>;
|
|
710
|
+
/**
|
|
711
|
+
* 从一份文档(PDF、Word、Excel、PowerPoint 和它们的开放格式、压缩包)里抽出文字,给附件用。
|
|
712
|
+
* 认不出的格式返回 null;扫描件之类没有文字层的,`imageOnly` 为 true。
|
|
713
|
+
*/
|
|
714
|
+
documentText(name: string, data: Uint8Array): Promise<DocumentText | null>;
|
|
715
|
+
/**
|
|
716
|
+
* 给文件面板读一个文件。只认这个会话工作目录和项目源文件夹里的路径,另加这个会话最近一次请求的「记忆文件」
|
|
717
|
+
* (`ContextBreakdown.memoryFiles`,只读、按原路径给);不在这些里、不存在、是文件夹都返回 null。
|
|
718
|
+
* 太长的只读开头(`truncated`),不是文字的只报大小(`binary`)。
|
|
719
|
+
*/
|
|
720
|
+
readFile(sessionId: string, path: string): Promise<FileContents | null>;
|
|
721
|
+
/** 文档预览的原始数据,受同一会话读取边界约束,最多 64 MiB;版本不符时报错。 */
|
|
722
|
+
readFileBytes(sessionId: string, path: string, modifiedAt: number | undefined, call: CallContext): Promise<Uint8Array>;
|
|
723
|
+
/** 列出会话目录或项目源文件夹里的一级目录,不跟随软链。 */
|
|
724
|
+
/** `@` 菜单列会话或已登记项目的源目录顶层;新聊天没有目录时为空。 */
|
|
725
|
+
mentionFiles(target: SessionTarget, sessionId: string | undefined): Promise<(FileEntry & {
|
|
726
|
+
origin?: string;
|
|
727
|
+
})[]>;
|
|
728
|
+
listDirectory(sessionId: string, path: string): Promise<FileEntry[]>;
|
|
729
|
+
/** 在原目录中改名;不覆盖同名目标,不改会话根目录。 */
|
|
730
|
+
renameFile(sessionId: string, path: string, name: string): Promise<string>;
|
|
731
|
+
/**
|
|
732
|
+
* 在会话工作目录里找一个写得不全的路径:裸文件名(`approvals.ts`)或相对于某个子目录的路径。
|
|
733
|
+
* 返回找到的绝对路径,按路径排好;跳过依赖和构建产物目录。
|
|
734
|
+
*/
|
|
735
|
+
locateFiles(sessionId: string, relative: string): Promise<string[]>;
|
|
736
|
+
stop(sessionId: string): void;
|
|
737
|
+
respond(sessionId: string, toolCallId: string, decision: ApprovalDecision): void;
|
|
738
|
+
/** 插件经 `ctx.commands` 供的全部命令,给输入框的 `/` 菜单。同名的只留先加载的插件那条;哪个插件列不出来就跳过它。 */
|
|
739
|
+
listCommands(context: CommandContext): Promise<CommandEntry[]>;
|
|
740
|
+
/** 让供它的插件把 `/name rest` 展开;插件已经撤下了或不再认这个名字时报错。 */
|
|
741
|
+
expandCommand(plugin: string, name: string, rest: string, context: CommandContext): Promise<CommandResult>;
|
|
742
|
+
listPlugins(): PluginStatus[];
|
|
743
|
+
/** 启用或停用一个插件(按插件名),写进 plugins.json,立即生效。 */
|
|
744
|
+
setPluginEnabled(name: string, enabled: boolean): Promise<PluginStatus[]>;
|
|
745
|
+
/** 界面语言变了:agent 进程之后给人看的报错、提示用这种语言。发给模型的文字不跟着变。 */
|
|
746
|
+
setLocale(locale: Locale): void;
|
|
747
|
+
/** 订阅所有会话的事件,直到调用方取消。 */
|
|
748
|
+
watch(call: CallContext): AsyncGenerator<AgentEvent, void>;
|
|
749
|
+
/**
|
|
750
|
+
* 调插件逻辑入口经 `ctx.serve` 开出来的方法,给它的界面入口用(`ui.remote()`)。
|
|
751
|
+
* 方法返回异步迭代器时逐个推回,调用方取消时方法收到的 signal 中止。
|
|
752
|
+
*/
|
|
753
|
+
callPlugin(plugin: string, method: string, args: unknown[], call: CallContext): Promise<unknown>;
|
|
754
|
+
}
|
|
755
|
+
/** 项目配置错误只携带位置,不把配置原文送进界面。 */
|
|
756
|
+
export type ConfigProblem = {
|
|
757
|
+
kind: "not-object";
|
|
758
|
+
path: string;
|
|
759
|
+
} | {
|
|
760
|
+
kind: "invalid-json";
|
|
761
|
+
path: string;
|
|
762
|
+
detail: string;
|
|
763
|
+
};
|
|
764
|
+
export interface LayerOverride {
|
|
765
|
+
key: string;
|
|
766
|
+
kind: "array" | "scalar";
|
|
767
|
+
project: unknown;
|
|
768
|
+
global: unknown;
|
|
769
|
+
}
|
|
770
|
+
export interface ProjectLayerView {
|
|
771
|
+
path: string;
|
|
772
|
+
exists: boolean;
|
|
773
|
+
error?: string;
|
|
774
|
+
problem?: ConfigProblem;
|
|
775
|
+
refused: string[];
|
|
776
|
+
overrides: LayerOverride[];
|
|
777
|
+
}
|
|
778
|
+
export type FileOperation = {
|
|
779
|
+
type: "create";
|
|
780
|
+
directory: string;
|
|
781
|
+
name: string;
|
|
782
|
+
kind: "file" | "directory";
|
|
783
|
+
} | {
|
|
784
|
+
type: "rename" | "copy";
|
|
785
|
+
from: string;
|
|
786
|
+
to: string;
|
|
787
|
+
overwrite?: boolean;
|
|
788
|
+
} | {
|
|
789
|
+
type: "trash" | "remove";
|
|
790
|
+
paths: string[];
|
|
791
|
+
} | {
|
|
792
|
+
type: "unique";
|
|
793
|
+
directory: string;
|
|
794
|
+
name: string;
|
|
795
|
+
} | {
|
|
796
|
+
type: "import";
|
|
797
|
+
sources: string[];
|
|
798
|
+
directory: string;
|
|
799
|
+
};
|
|
800
|
+
export interface FileOpResult {
|
|
801
|
+
ok: boolean;
|
|
802
|
+
path?: string;
|
|
803
|
+
paths?: string[];
|
|
804
|
+
error?: string;
|
|
805
|
+
code?: "exists" | "invalid" | "denied" | "descendant";
|
|
806
|
+
}
|