@xiongtao.xt/tau-plugins 0.31.1 → 0.33.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/CHANGELOG.md +20 -0
- package/README.md +2 -2
- package/client/{chunk-ECEBBIHP.js → chunk-SVY5LBAT.js} +44 -0
- package/docs/README.md +43 -0
- package/docs/ai.md +169 -0
- package/docs/backend.md +168 -0
- package/docs/editor.md +590 -0
- package/docs/excerpts.md +126 -0
- package/docs/flashcards.md +127 -0
- package/docs/getting-started.md +134 -0
- package/docs/mcp.md +173 -0
- package/docs/plugin-basics.md +209 -0
- package/docs/providers/README.md +108 -0
- package/docs/providers/images.md +65 -0
- package/docs/providers/publish.md +144 -0
- package/docs/providers/sync.md +75 -0
- package/docs/providers/tts.md +62 -0
- package/docs/providers/upload.md +77 -0
- package/docs/providers/video.md +118 -0
- package/docs/release.md +130 -0
- package/docs/services.md +159 -0
- package/docs/site-data.md +90 -0
- package/docs/skills.md +129 -0
- package/docs/storage-and-network.md +62 -0
- package/docs/ui.md +336 -0
- package/docs/user-data.md +389 -0
- package/docs/whiteboard.md +290 -0
- package/package.js +1 -1
- package/package.json +1 -1
- package/publish-artifacts.js +38 -1
- package/types/packages/db-schema/content-resources.d.ts +76 -0
- package/types/packages/editor/contracts.d.ts +1 -1
- package/types/packages/editor/source-contracts.d.ts +41 -1
- package/types/packages/editor/src/core/api/extension.d.ts +15 -0
- package/types/packages/editor/src/core/api/index.d.ts +5 -1
- package/types/packages/editor/src/core/api/resources.d.ts +6 -0
- package/types/packages/editor/src/core/components/ElementFrame/index.d.ts +25 -0
- package/types/packages/editor/src/core/utils/blockKeyTarget.d.ts +9 -0
- package/types/packages/plugins/src/categories.d.ts +3 -0
- package/types/packages/plugins/src/contract.d.ts +0 -2
- package/types/packages/plugins/src/editor.d.ts +1 -0
- package/types/packages/plugins/src/element.d.ts +11 -0
- package/types/packages/plugins/src/index.d.ts +4 -1
- package/types/packages/plugins/src/media.d.ts +69 -0
- package/types/packages/plugins/src/package.d.ts +2 -0
- package/types/packages/ui/src/index.d.ts +1 -0
- package/types/packages/ui/src/primitives/Sortable.d.ts +32 -0
- package/types/packages/ui/src/primitives/Tabs.d.ts +1 -3
- package/AI.md +0 -116
- package/API.md +0 -881
- package/BACKEND.md +0 -68
- package/DEVELOPMENT.md +0 -173
- package/EDITOR.md +0 -192
- package/FLASHCARDS.md +0 -92
- package/IMAGES.md +0 -16
- package/MCP.md +0 -118
- package/NOTIFICATIONS.md +0 -48
- package/PUBLISH-DATA.md +0 -48
- package/PUBLISH.md +0 -50
- package/SERVICES.md +0 -119
- package/SYNC.md +0 -37
- package/TTS.md +0 -20
- package/UPLOAD.md +0 -35
- package/VIDEO.md +0 -65
- package/WHITEBOARD.md +0 -115
- package/types/packages/plugins/src/skills.d.ts +0 -8
|
@@ -12,6 +12,10 @@ export { SourceBlockEditor, useSourceBlock, useReportPreviewError, insertSourceB
|
|
|
12
12
|
export type { SourceBlockEditorProps, PluginRuntimeStyleCompiler } from "./source-editor";
|
|
13
13
|
export { useInlineSource, insertInlineSource, InlineSourceBoundary } from "./inline-source";
|
|
14
14
|
export { ContentEditor, ContentPreview } from "./components";
|
|
15
|
+
export { useElement, useMediaViewer, BlockToolbar, BlockToolbarButton, BlockToolbarGap, } from "./element";
|
|
16
|
+
export type { ElementAccess, BlockToolbarProps, BlockToolbarButtonProps, EditorElementFrame, } from "./element";
|
|
17
|
+
export { MediaImage, MediaVideo, MediaAudio, useResource, useResourceUpload, useMediaAppearance, } from "./media";
|
|
18
|
+
export type { ResourceKind, ResourceState, ResourceUpload, MediaAppearance, MediaAppearancePreset, MediaImageProps, MediaVideoProps, MediaAudioProps, MediaRuntime, } from "./media";
|
|
15
19
|
export type { ContentEditorProps, ContentPreviewProps } from "./components";
|
|
16
20
|
export * from "./sidebar";
|
|
17
21
|
export type * from "./icons";
|
|
@@ -29,7 +33,6 @@ export type { PluginPermission, PluginPermissions, PluginPermissionState, Plugin
|
|
|
29
33
|
export type * from "./flashcards";
|
|
30
34
|
export type * from "./services";
|
|
31
35
|
export { usePluginServices } from "./service-access";
|
|
32
|
-
export type { PluginSkill } from "./skills";
|
|
33
36
|
export type { PluginMCP, PluginMCPDefinition, PluginMCPTool, PluginMCPTransport } from "./mcp";
|
|
34
37
|
export type { PluginMCPToolResult } from "./mcp";
|
|
35
38
|
export type { PluginChat, PluginToolRendererDefinition, PluginToolRendererProps, ToolCallExecutionState, } from "./chat";
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import type { CSSProperties, ImgHTMLAttributes, MouseEventHandler, ReactElement, ReactNode, Ref, SyntheticEvent, VideoHTMLAttributes } from "react";
|
|
2
|
+
import type { ContentResourceKind } from "../../db-schema/content-resources";
|
|
3
|
+
export type ResourceKind = ContentResourceKind;
|
|
4
|
+
export interface ResourceState {
|
|
5
|
+
/** 可直接给 img / video / audio 的地址;解析中或失败时为 undefined */
|
|
6
|
+
src: string | undefined;
|
|
7
|
+
status: "loading" | "ready" | "error";
|
|
8
|
+
/** 元素加载失败时调用:作废宿主缓存后重新解析 */
|
|
9
|
+
retry(): void;
|
|
10
|
+
}
|
|
11
|
+
/** 上传到用户当前的资源存储(本地库、远端或共享文档),返回可写入节点的地址 */
|
|
12
|
+
export type ResourceUpload = (file: File) => Promise<string>;
|
|
13
|
+
export type MediaAppearancePreset = "none" | "sm" | "md" | "lg";
|
|
14
|
+
/** 用户设置(发布站为发布设置)里的媒体默认外观;节点自身的设置优先 */
|
|
15
|
+
export interface MediaAppearance {
|
|
16
|
+
borderRadius?: MediaAppearancePreset;
|
|
17
|
+
shadow?: MediaAppearancePreset | boolean;
|
|
18
|
+
}
|
|
19
|
+
export interface MediaImageProps {
|
|
20
|
+
url: string;
|
|
21
|
+
alt?: string;
|
|
22
|
+
className?: string;
|
|
23
|
+
style?: CSSProperties;
|
|
24
|
+
onClick?: MouseEventHandler<HTMLImageElement>;
|
|
25
|
+
onDoubleClick?: MouseEventHandler<HTMLImageElement>;
|
|
26
|
+
onLoad?: (event: SyntheticEvent<HTMLImageElement>) => void;
|
|
27
|
+
/** 宿主的回退地址也加载失败后回调 */
|
|
28
|
+
onLoadError?: () => void;
|
|
29
|
+
crossOrigin?: ImgHTMLAttributes<HTMLImageElement>["crossOrigin"];
|
|
30
|
+
/** 默认懒加载 */
|
|
31
|
+
loading?: "eager" | "lazy";
|
|
32
|
+
draggable?: boolean;
|
|
33
|
+
ref?: Ref<HTMLImageElement>;
|
|
34
|
+
}
|
|
35
|
+
export type MediaVideoProps = VideoHTMLAttributes<HTMLVideoElement> & {
|
|
36
|
+
src: string;
|
|
37
|
+
playbackRate?: number;
|
|
38
|
+
onPlaybackRateChange?: (rate: number) => void;
|
|
39
|
+
/** 播放器底栏信息位,宿主播放器不支持时忽略 */
|
|
40
|
+
info?: ReactNode;
|
|
41
|
+
ref?: Ref<HTMLVideoElement>;
|
|
42
|
+
};
|
|
43
|
+
export interface MediaAudioProps {
|
|
44
|
+
src: string;
|
|
45
|
+
controls?: boolean;
|
|
46
|
+
label?: string;
|
|
47
|
+
labelSlot?: ReactNode;
|
|
48
|
+
className?: string;
|
|
49
|
+
ref?: Ref<HTMLAudioElement>;
|
|
50
|
+
}
|
|
51
|
+
/** 宿主注入的实现;在编辑器内按当前文档的作用域生效(共享文档走协作资源),编辑器外用应用默认实现。 */
|
|
52
|
+
export interface MediaRuntime {
|
|
53
|
+
useResource(url: string, options: {
|
|
54
|
+
kind: ResourceKind;
|
|
55
|
+
}): ResourceState;
|
|
56
|
+
/** 只读编辑器与没有资源存储的宿主(发布站)返回 undefined */
|
|
57
|
+
useResourceUpload(): ResourceUpload | undefined;
|
|
58
|
+
useMediaAppearance(): MediaAppearance | undefined;
|
|
59
|
+
MediaImage(props: MediaImageProps): ReactElement | null;
|
|
60
|
+
MediaVideo(props: MediaVideoProps): ReactElement | null;
|
|
61
|
+
MediaAudio(props: MediaAudioProps): ReactElement | null;
|
|
62
|
+
}
|
|
63
|
+
export declare function configureMedia(value: MediaRuntime): void;
|
|
64
|
+
export declare const useResource: MediaRuntime["useResource"];
|
|
65
|
+
export declare const useResourceUpload: MediaRuntime["useResourceUpload"];
|
|
66
|
+
export declare const useMediaAppearance: MediaRuntime["useMediaAppearance"];
|
|
67
|
+
export declare const MediaImage: (props: MediaImageProps) => ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | null;
|
|
68
|
+
export declare const MediaVideo: (props: MediaVideoProps) => ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | null;
|
|
69
|
+
export declare const MediaAudio: (props: MediaAudioProps) => ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | null;
|
|
@@ -29,6 +29,8 @@ export interface PluginManifest {
|
|
|
29
29
|
keywords?: readonly string[];
|
|
30
30
|
/** 可申请的业务数据权限上限;实际授权由用户在调用时决定。 */
|
|
31
31
|
permissions?: readonly PluginPermission[];
|
|
32
|
+
/** 包内 `skills/<id>/` 目录,随插件启停。 */
|
|
33
|
+
skills?: readonly string[];
|
|
32
34
|
integrity: Record<string, string>;
|
|
33
35
|
}
|
|
34
36
|
/** 宿主内部传输的已读取产物,不属于作者运行时 API。 */
|
|
@@ -44,6 +44,7 @@ export * from "./primitives/datepicker/DateRangePicker";
|
|
|
44
44
|
export * from "./primitives/ImagePreview";
|
|
45
45
|
export * from "./primitives/Tabs";
|
|
46
46
|
export * from "./primitives/FileDropZone";
|
|
47
|
+
export * from "./primitives/Sortable";
|
|
47
48
|
export * from "./primitives/LoadingOverlay";
|
|
48
49
|
export { lockBodyScroll } from "./hooks/lockBodyScroll";
|
|
49
50
|
export { mergeRefs } from "./primitives/mergeRefs";
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { type KeyboardEvent, type PointerEvent, type ReactNode } from "react";
|
|
2
|
+
export interface SortableHandleProps {
|
|
3
|
+
onPointerDown(event: PointerEvent<HTMLElement>): void;
|
|
4
|
+
onKeyDown(event: KeyboardEvent<HTMLElement>): void;
|
|
5
|
+
tabIndex: number;
|
|
6
|
+
"aria-roledescription": string;
|
|
7
|
+
}
|
|
8
|
+
export interface SortableItemState {
|
|
9
|
+
index: number;
|
|
10
|
+
/** 正在被拖动的那一项 */
|
|
11
|
+
dragging: boolean;
|
|
12
|
+
/** 拖动经过、松手后会放到这里 */
|
|
13
|
+
over: boolean;
|
|
14
|
+
/** 展开到拖动手柄上;也可以展开到整项上,整项都能拖 */
|
|
15
|
+
handleProps: SortableHandleProps;
|
|
16
|
+
}
|
|
17
|
+
export interface SortableProps<T> {
|
|
18
|
+
items: readonly T[];
|
|
19
|
+
getKey(item: T): string;
|
|
20
|
+
/** 把 from 位置的项移到 to 位置 */
|
|
21
|
+
onMove(from: number, to: number): void;
|
|
22
|
+
renderItem(item: T, state: SortableItemState): ReactNode;
|
|
23
|
+
className?: string;
|
|
24
|
+
/** 每一项外层容器的类名 */
|
|
25
|
+
itemClassName?: string;
|
|
26
|
+
disabled?: boolean;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* 列表与网格排序:按住手柄拖到另一项上松手即移到那里;手柄获得焦点时方向键前后移动一位,Esc 取消拖动。
|
|
30
|
+
* 用指针事件实现,不依赖拖放 API,任何容器(含编辑器里的块)都能用。
|
|
31
|
+
*/
|
|
32
|
+
export declare function Sortable<T>({ items, getKey, onMove, renderItem, className, itemClassName, disabled, }: SortableProps<T>): import("react/jsx-runtime").JSX.Element;
|
|
@@ -12,8 +12,6 @@ export interface TabsProps<K extends string = string> {
|
|
|
12
12
|
/** 标签居中(默认左对齐) */
|
|
13
13
|
centered?: boolean;
|
|
14
14
|
className?: string;
|
|
15
|
-
/** 面板容器类名:标签栏固定、面板独立滚动时由调用方给出高度约束 */
|
|
16
|
-
panelClassName?: string;
|
|
17
15
|
}
|
|
18
16
|
/** 下划线式标签页(与 desktop 设置页同一视觉语言);方向键在标签间移动 */
|
|
19
|
-
export declare function Tabs<K extends string = string>({ items, activeKey: activeKeyProp, defaultActiveKey, onChange, centered, className,
|
|
17
|
+
export declare function Tabs<K extends string = string>({ items, activeKey: activeKeyProp, defaultActiveKey, onChange, centered, className, }: TabsProps<K>): import("react/jsx-runtime").JSX.Element;
|
package/AI.md
DELETED
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
# AI 服务
|
|
2
|
-
|
|
3
|
-
自定义 AI 功能需要 SDK 0.7.0;申请应用已有的模型分配需要 SDK 0.27.0。两者都需要包含对应实现的 Tau 客户端。
|
|
4
|
-
|
|
5
|
-
自定义 AI 功能由插件声明,用户在插件详情的「设置 → AI 配置」分配已有模型并开启授权。全局「大语言模型」设置管理服务商和密钥;这类功能通过 `ctx.ai` 请求模型,接口不返回密钥、连接地址或用户的聊天历史。
|
|
6
|
-
|
|
7
|
-
## 使用应用已有模型分配
|
|
8
|
-
|
|
9
|
-
无需声明 `ai.features` 或另配模型。先在 manifest 中声明 `ai:<能力名>` 权限,再申请对应客户端:
|
|
10
|
-
|
|
11
|
-
```json
|
|
12
|
-
{ "permissions": ["ai:titleSummary"] }
|
|
13
|
-
```
|
|
14
|
-
|
|
15
|
-
```ts
|
|
16
|
-
const model = await context.ai.requestCapability("titleSummary");
|
|
17
|
-
const result = await model.chat({
|
|
18
|
-
messages: [{ role: "user", content: "为这段文字拟一个简短标题:……" }],
|
|
19
|
-
});
|
|
20
|
-
console.log(result.text);
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
申请时由用户选择允许或拒绝;能力分别授权,未声明的申请会被拒绝。返回客户端提供 `chat(request)` 和 `stream(request)`,参数与下文自定义 AI 相同,但不传 `feature`。每次调用复核权限,撤权、停用或切库取消在途生成;额度、并发和用量审计按插件统计。缺少应用模型分配时明确失败,不自动选择其他模型。
|
|
24
|
-
|
|
25
|
-
当前全部 12 项大模型功能分配均可申请,能力清单也可从 `PLUGIN_AI_CAPABILITIES` 导入:
|
|
26
|
-
|
|
27
|
-
| 能力名 | 沿用的应用分配 |
|
|
28
|
-
| ------------------------------ | -------------- |
|
|
29
|
-
| `chat` | 对话功能 |
|
|
30
|
-
| `titleSummary` | 标题总结 |
|
|
31
|
-
| `webClip` | 网页剪藏 |
|
|
32
|
-
| `podcastGeneration` | 播客生成 |
|
|
33
|
-
| `flashcardGeneration` | 闪卡生成 |
|
|
34
|
-
| `aiJudgement` | 答案评判 |
|
|
35
|
-
| `transcriptionOptimization` | 转录断句优化 |
|
|
36
|
-
| `videoSummary` | 视频总结 |
|
|
37
|
-
| `videoEbookRewrite` | 视频电子书重写 |
|
|
38
|
-
| `vibeLearningImageDescription` | 图片理解 |
|
|
39
|
-
| `contentMetadata` | 笔记元信息 |
|
|
40
|
-
| `contentInsights` | AI 洞见 |
|
|
41
|
-
|
|
42
|
-
这里复用模型分配,不自动执行宿主的业务流程或读取业务数据;插件传入自己的消息。已有闪卡业务流程由 `context.flashcards` 提供,它内部调用同一通用机制,需声明 `ai:flashcardGeneration`,详见 [FLASHCARDS.md](FLASHCARDS.md)。
|
|
43
|
-
|
|
44
|
-
图片理解可在 user 消息中传入 `images: [{ data: imageBase64, mimeType: "image/png" }]`。`data` 不带 data: 前缀;支持 PNG、JPEG、WebP、GIF,每条消息最多 10 张,整次请求的 Base64 总长最多 20 MiB,模型须支持图片。图片与消息正文不会写入用量审计。
|
|
45
|
-
|
|
46
|
-
## 声明自定义 AI 功能
|
|
47
|
-
|
|
48
|
-
```ts
|
|
49
|
-
import { definePlugin } from "@tau/plugins";
|
|
50
|
-
|
|
51
|
-
declare const __PLUGIN_META__: { id: string; name: string; version: string };
|
|
52
|
-
|
|
53
|
-
export default definePlugin({
|
|
54
|
-
...__PLUGIN_META__,
|
|
55
|
-
ai: {
|
|
56
|
-
features: [{ id: "summary", name: "文章摘要", description: "概括用户选择的文章" }],
|
|
57
|
-
},
|
|
58
|
-
create: () => ({
|
|
59
|
-
activate(ctx) {
|
|
60
|
-
ctx.commands.register({
|
|
61
|
-
id: "summary",
|
|
62
|
-
title: "生成摘要",
|
|
63
|
-
async run(input) {
|
|
64
|
-
const status = await ctx.ai.getStatus("summary");
|
|
65
|
-
if (!status.configured || !status.enabled) {
|
|
66
|
-
ctx.ai.openSettings("summary");
|
|
67
|
-
return null;
|
|
68
|
-
}
|
|
69
|
-
const result = await ctx.ai.chat({
|
|
70
|
-
feature: "summary",
|
|
71
|
-
messages: [
|
|
72
|
-
{ role: "system", content: "概括主要内容,不添加原文以外的信息。" },
|
|
73
|
-
{ role: "user", content: typeof input === "string" ? input : "请先选择正文。" },
|
|
74
|
-
],
|
|
75
|
-
maxOutputTokens: 1024,
|
|
76
|
-
});
|
|
77
|
-
return result.text;
|
|
78
|
-
},
|
|
79
|
-
});
|
|
80
|
-
},
|
|
81
|
-
}),
|
|
82
|
-
});
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
## 接口
|
|
86
|
-
|
|
87
|
-
| 接口 | 返回与用途 |
|
|
88
|
-
| ------------------------ | ----------------------------------------------------------------------------------- |
|
|
89
|
-
| `getStatus(feature)` | `{ configured, enabled }`;模型被删除也视为未配置 |
|
|
90
|
-
| `openSettings(feature?)` | 打开当前插件设置,由用户分配模型、管理授权 |
|
|
91
|
-
| `chat(request)` | `{ text, usage }`;usage 未知时为 null |
|
|
92
|
-
| `stream(request)` | 异步迭代器,依次产生 `{ type: "text", delta }`,最后产生 `{ type: "done", result }` |
|
|
93
|
-
|
|
94
|
-
请求字段:`feature` 必须是插件声明的功能 ID;`messages` 为 system/user/assistant 文本消息数组;`maxOutputTokens` 是可选的最大输出 Token;`signal` 为可选的取消信号。多轮历史由插件传入。多个 system 消息合并为系统提示,不提供工具调用或自动代理执行。
|
|
95
|
-
|
|
96
|
-
```ts
|
|
97
|
-
const controller = new AbortController();
|
|
98
|
-
for await (const event of ctx.ai.stream({
|
|
99
|
-
feature: "summary",
|
|
100
|
-
messages: [{ role: "user", content: article }],
|
|
101
|
-
signal: controller.signal,
|
|
102
|
-
})) {
|
|
103
|
-
if (event.type === "text") appendText(event.delta);
|
|
104
|
-
else showUsage(event.result.usage);
|
|
105
|
-
}
|
|
106
|
-
```
|
|
107
|
-
|
|
108
|
-
退出迭代、取消 signal、停用插件或用户撤销 AI 授权都会请求取消。不要在模块顶层调用 AI,也不要在遇到额度不足或拒绝授权后自动循环重试。
|
|
109
|
-
|
|
110
|
-
## 审计与额度
|
|
111
|
-
|
|
112
|
-
所有模型调用由宿主归属到插件及功能,进入「大语言模型 → 用量统计」,插件设置的「查看用量」会跳转并筛选本插件。记录包含时间、模型、状态、Token、估算费用和耗时,不保存提示词或回复正文。运行中的请求可取消,也可一次关闭插件的 AI 授权。
|
|
113
|
-
|
|
114
|
-
额度按本机自然日统计,所有窗口共用,并在重启后保留。每日请求次数、每日 Token 和并发限制由用户设置;并发达到上限直接拒绝,不排队。宿主按模型上下文容量加输出上限保守预占 Token,结束后按实际已知用量结算;未知用量保留预占。供应商未报告用量时不能当作零消费;费用为估算,不替代账单。取消无法撤销已经产生的消费。
|
|
115
|
-
|
|
116
|
-
错误消息以稳定代码开头:`AI_NOT_CONFIGURED`(未配置)、`AI_DISABLED`(未授权或插件已停用)、`AI_UNDECLARED_FEATURE`(未声明)、`AI_QUOTA_EXCEEDED`(每日额度不足)、`AI_CONCURRENCY_LIMIT`(并发已满)、`AI_CONFIG_CHANGED`(模型分配变化)、`AI_ABORTED`(取消)、`AI_REQUEST_FAILED`(模型或审计失败)。本地 AbortSignal 取消也可能抛出标准 AbortError。
|