diff --git a/README.md b/README.md index 17f9e7a3b..994266983 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@

- OpenTiny Logo + OpenTiny Logo

@@ -22,7 +22,7 @@ - 🔄 **Streaming Support**: Built-in support for streaming AI responses - 💾 **Storage Strategy**: Flexible storage strategies (LocalStorage, IndexedDB, custom) -English | [简体中文](README_zh.md) +English | [简体中文](https://github.com/opentiny/tiny-robot/blob/HEAD/README.zh-CN.md) [![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/opentiny/tiny-robot) @@ -30,11 +30,11 @@ English | [简体中文](README_zh.md) TinyRobot is a monorepo containing the following packages: -| Package | Description | Version | -| ----------------------------------------------- | ------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------- | -| [`@opentiny/tiny-robot`](./packages/components) | Core component library with all AI interaction components | [![npm](https://img.shields.io/npm/v/@opentiny/tiny-robot.svg)](https://www.npmjs.com/package/@opentiny/tiny-robot) | -| [`@opentiny/tiny-robot-kit`](./packages/kit) | Utility functions and AI client tools for model interactions | [![npm](https://img.shields.io/npm/v/@opentiny/tiny-robot-kit.svg)](https://www.npmjs.com/package/@opentiny/tiny-robot-kit) | -| [`@opentiny/tiny-robot-svgs`](./packages/svgs) | SVG icon library with all component icons | [![npm](https://img.shields.io/npm/v/@opentiny/tiny-robot-svgs.svg)](https://www.npmjs.com/package/@opentiny/tiny-robot-svgs) | +| Package | Description | Version | +| --------------------------- | ------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------- | +| `@opentiny/tiny-robot` | Core component library with all AI interaction components | [![npm](https://img.shields.io/npm/v/@opentiny/tiny-robot.svg)](https://www.npmjs.com/package/@opentiny/tiny-robot) | +| `@opentiny/tiny-robot-kit` | Utility functions and AI client tools for model interactions | [![npm](https://img.shields.io/npm/v/@opentiny/tiny-robot-kit.svg)](https://www.npmjs.com/package/@opentiny/tiny-robot-kit) | +| `@opentiny/tiny-robot-svgs` | SVG icon library with all component icons | [![npm](https://img.shields.io/npm/v/@opentiny/tiny-robot-svgs.svg)](https://www.npmjs.com/package/@opentiny/tiny-robot-svgs) | ## 🚀 Quick Start @@ -171,11 +171,11 @@ pnpm dev ## 📄 License -MIT License - see [LICENSE](./LICENSE) file for details. +MIT License - see [LICENSE](https://github.com/opentiny/tiny-robot/blob/HEAD/LICENSE) file for details. ## 🤝 Contributing -Contributions are welcome! Please read our [Contributing Guide](./CONTRIBUTING.md) to understand the recommended workflow, commit message conventions, and how to submit Issues and Pull Requests. +Contributions are welcome! Please read our [Contributing Guide](https://github.com/opentiny/tiny-robot/blob/HEAD/CONTRIBUTING.md) to understand the recommended workflow, commit message conventions, and how to submit Issues and Pull Requests. ## 📞 Support diff --git a/README_zh.md b/README.zh-CN.md similarity index 80% rename from README_zh.md rename to README.zh-CN.md index 662b879df..b99ae591e 100644 --- a/README_zh.md +++ b/README.zh-CN.md @@ -2,7 +2,7 @@

- OpenTiny Logo + OpenTiny Logo

@@ -22,7 +22,7 @@ - 🔄 **流式支持**:内置流式 AI 响应支持 - 💾 **存储策略**:灵活的存储策略(LocalStorage、IndexedDB、自定义) -[English](README.md) | 简体中文 +[English](https://github.com/opentiny/tiny-robot/blob/HEAD/README.md) | 简体中文 [![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/opentiny/tiny-robot) @@ -30,11 +30,11 @@ TinyRobot 是一个 monorepo,包含以下包: -| 包 | 说明 | 版本 | -| ----------------------------------------------- | -------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | -| [`@opentiny/tiny-robot`](./packages/components) | 核心组件库,包含所有 AI 交互组件 | [![npm](https://img.shields.io/npm/v/@opentiny/tiny-robot.svg)](https://www.npmjs.com/package/@opentiny/tiny-robot) | -| [`@opentiny/tiny-robot-kit`](./packages/kit) | 工具函数和 AI 客户端工具,用于模型交互 | [![npm](https://img.shields.io/npm/v/@opentiny/tiny-robot-kit.svg)](https://www.npmjs.com/package/@opentiny/tiny-robot-kit) | -| [`@opentiny/tiny-robot-svgs`](./packages/svgs) | SVG 图标库,包含所有组件所需的图标 | [![npm](https://img.shields.io/npm/v/@opentiny/tiny-robot-svgs.svg)](https://www.npmjs.com/package/@opentiny/tiny-robot-svgs) | +| 包 | 说明 | 版本 | +| --------------------------- | -------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | +| `@opentiny/tiny-robot` | 核心组件库,包含所有 AI 交互组件 | [![npm](https://img.shields.io/npm/v/@opentiny/tiny-robot.svg)](https://www.npmjs.com/package/@opentiny/tiny-robot) | +| `@opentiny/tiny-robot-kit` | 工具函数和 AI 客户端工具,用于模型交互 | [![npm](https://img.shields.io/npm/v/@opentiny/tiny-robot-kit.svg)](https://www.npmjs.com/package/@opentiny/tiny-robot-kit) | +| `@opentiny/tiny-robot-svgs` | SVG 图标库,包含所有组件所需的图标 | [![npm](https://img.shields.io/npm/v/@opentiny/tiny-robot-svgs.svg)](https://www.npmjs.com/package/@opentiny/tiny-robot-svgs) | ## 🚀 快速开始 @@ -171,11 +171,11 @@ pnpm dev ## 📄 许可证 -MIT 许可证 - 查看 [LICENSE](./LICENSE) 文件了解详情。 +MIT 许可证 - 查看 [LICENSE](https://github.com/opentiny/tiny-robot/blob/HEAD/LICENSE) 文件了解详情。 ## 🤝 贡献 -欢迎贡献!请阅读[贡献指南](./CONTRIBUTING_zh.md)了解推荐的工作流程、Commit 规范以及如何提交 Issue 和 Pull Request。 +欢迎贡献!请阅读[贡献指南](https://github.com/opentiny/tiny-robot/blob/HEAD/CONTRIBUTING_zh.md)了解推荐的工作流程、Commit 规范以及如何提交 Issue 和 Pull Request。 ## 📞 支持 diff --git a/packages/components/.gitignore b/packages/components/.gitignore new file mode 100644 index 000000000..1831db00f --- /dev/null +++ b/packages/components/.gitignore @@ -0,0 +1,2 @@ +/README* +/LICENSE diff --git a/packages/components/README.md b/packages/components/README.md deleted file mode 100644 index ff9cc5598..000000000 --- a/packages/components/README.md +++ /dev/null @@ -1 +0,0 @@ -# 组件 diff --git a/packages/components/package.json b/packages/components/package.json index 964dc458f..56e185fa3 100644 --- a/packages/components/package.json +++ b/packages/components/package.json @@ -1,6 +1,34 @@ { "name": "@opentiny/tiny-robot", "version": "0.4.0", + "license": "MIT", + "description": "TinyRobot 是一个 AI 对话组件库,提供了丰富的 AI 交互组件,助力开发者快速构建企业级 AI 应用;同时也是一个智能助手,支持普通 AI 问答、也支持集成 MCP Server,让 AI 真正帮人“干活”。", + "homepage": "https://docs.opentiny.design/tiny-robot/", + "repository": { + "type": "git", + "url": "git+https://github.com/opentiny/tiny-robot.git" + }, + "bugs": { + "url": "https://github.com/opentiny/tiny-robot/issues" + }, + "keywords": [ + "vue", + "vue3", + "vue-components", + "component-library", + "ai", + "ai-components", + "chat", + "chat-ui", + "chatbot", + "llm", + "openai", + "assistant", + "streaming", + "conversation", + "tiny-robot", + "opentiny" + ], "publishConfig": { "access": "public" }, @@ -9,7 +37,8 @@ "module": "./dist/index.js", "sideEffects": false, "files": [ - "dist" + "dist", + "README*" ], "scripts": { "dev": "vue-tsc && vite build --watch", diff --git a/packages/components/vite.config.ts b/packages/components/vite.config.ts index 25485051f..a68b60dca 100644 --- a/packages/components/vite.config.ts +++ b/packages/components/vite.config.ts @@ -1,10 +1,31 @@ import vue from '@vitejs/plugin-vue' import vuejsx from '@vitejs/plugin-vue-jsx' -import { readdirSync } from 'fs' +import { readdirSync, copyFileSync, existsSync } from 'fs' import { resolve } from 'path' -import { defineConfig } from 'vite' +import { defineConfig, Plugin } from 'vite' import dts from 'vite-plugin-dts' +function copyRootReadmeToComponents(): Plugin { + return { + name: 'copy-root-readme-to-components', + apply: 'build' as const, + closeBundle() { + const rootFiles = ['README.md', 'README.zh-CN.md', 'LICENSE'] + + for (const file of rootFiles) { + const rootFile = resolve(__dirname, `../../${file}`) + const targetFile = resolve(__dirname, `./${file}`) + + if (!existsSync(rootFile)) { + console.warn(`[tiny-robot] Root ${file} not found: ${rootFile}`) + continue + } + copyFileSync(rootFile, targetFile) + } + }, + } +} + // 构建入口 const entries = { index: './src/index.ts', @@ -31,6 +52,7 @@ export default defineConfig({ entryRoot: 'src', tsconfigPath: './tsconfig.json', }), + copyRootReadmeToComponents(), ], resolve: { extensions: ['.js', '.ts', '.jsx', '.tsx', '.json', '.vue'], diff --git a/packages/kit/README.md b/packages/kit/README.md index 33be159a8..2e5a9b4c2 100644 --- a/packages/kit/README.md +++ b/packages/kit/README.md @@ -1,289 +1,86 @@ # tiny-robot-kit -封装与与AI大模型的交互逻辑与数据处理,适配多种模型提供商,提供统一的API接口。 +@opentiny/tiny-robot-kit 是 TinyRobot 提供的数据层工具包,用于统一处理 AI 大模型调用、消息状态与多会话管理。 +它帮助你在任意 UI 上快速实现聊天、流式响应和会话持久化等常见 AI 交互能力。 -## API参考 +## 功能概览 -### AIClient +- **消息管理**:`useMessage` 管理消息状态与模型交互流程。 +- **会话管理**:`useConversation` 在 useMessage 之上提供多会话能力。 +- **工具函数(Utils)**:处理 SSE、消息格式与响应解析。 -主要客户端类,用于与AI模型交互。 +完整 API 请参考文档: -#### 构造函数 +- `useMessage`: +- `useConversation`: +- 工具函数: -```typescript -new AIClient(config: AIModelConfig) -``` - -#### 方法 - -- `chat(request: ChatCompletionRequest): Promise` - 发送聊天请求并获取响应。 - -- `chatStream(request: ChatCompletionRequest, handler: StreamHandler): Promise` - 发送流式聊天请求并通过处理器处理响应。 - - -## 基本用法 - -### 创建客户端并发送消息 - -```typescript -import { AIClient } from '@opentiny/tiny-robot-kit'; - -// 创建客户端 -const client = new AIClient({ - provider: 'openai', - apiKey: 'your-api-key', - defaultModel: 'gpt-3.5-turbo' -}); +## 安装 -// 发送消息并获取响应 -async function chat() { - try { - const response = await client.chat({ - messages: [ - { role: 'system', content: '你是一个有用的助手。' }, - { role: 'user', content: '你好,请介绍一下自己。' } - ], - options: { - temperature: 0.7 - } - }); - - console.log(response.choices[0].message.content); - } catch (error) { - console.error('聊天出错:', error); - } -} - -chat(); -``` - -### 使用流式响应 - -```typescript -import { AIClient } from '@opentiny/tiny-robot-kit'; - -const client = new AIClient({ - provider: 'openai', - apiKey: 'your-api-key' -}); - -async function streamChat() { - try { - const controller: AbortController = new AbortController() - await client.chatStream({ - messages: [ - { role: 'user', content: '写一个简短的故事。' } - ], - options: { - stream: true, // 启用流式响应 - signal: controller.signal // 传递 AbortController 的 signal用于中断请求 - } - }, { - onData: (data) => { - // 处理流式数据 - const content = data.choices[0]?.delta?.content || ''; - process.stdout.write(content); - }, - onError: (error) => { - console.error('流式响应错误:', error); - }, - onDone: () => { - console.log('\n流式响应完成'); - } - }); - // controller.abort() // 中断请求 - } catch (error) { - console.error('流式聊天出错:', error); - } -} - -streamChat(); +```bash +pnpm add @opentiny/tiny-robot-kit +# 或 +npm install @opentiny/tiny-robot-kit +yarn add @opentiny/tiny-robot-kit ``` -### useMessage - -#### 选项 - -`useMessage` 接受以下选项: - -```typescript -interface UseMessageOptions { - /** AI客户端实例 */ - client: AIClient; - /** 是否默认使用流式响应 */ - useStreamByDefault?: boolean; - /** 错误消息模板 */ - errorMessage?: string; - /** 初始消息列表 */ - initialMessages?: ChatMessage[]; -} -``` - -#### 返回值 - -`useMessage` 返回以下内容: -```typescript -interface UseMessageReturn { - messages: ChatMessage[]; - /** 消息状态 */ - messageState: Reactive; - /** 输入消息 */ - inputMessage: Ref; - /** 是否使用流式响应 */ - useStream: Ref; - /** 发送消息 */ - sendMessage: (content?: string, clearInput?: boolean) => Promise - /** 清空消息 */ - clearMessages: () => void; - /** 添加消息 */ - addMessage: (message: ChatMessage) => void; - /** 中止请求 */ - abortRequest: () => void; - /** 重试请求 */ - retryRequest: () => Promise; -} -``` - -#### MessageState 接口 -```typescript -interface MessageState { - status: STATUS - errorMsg: string | null -} - -enum STATUS { - INIT = 'init', // 初始状态 - PROCESSING = 'processing', // AI请求正在处理中, 还未响应,显示加载动画 - STREAMING = 'streaming', // 流式响应中分块数据返回中 - FINISHED = 'finished', // AI请求已完成 - ABORTED = 'aborted', // 用户中止请求 - ERROR = 'error', // AI请求发生错误 -} -``` - -### useConversation - -对话管理与数据持久化 - -#### 基本用法 +## 基本用法 -```typescript -import { useConversation, AIClient } from '@opentiny/tiny-robot-kit' +### useMessage —— 管理 AI 消息 -const client = new AIClient({ - provider: 'openai', - apiKey: 'your-api-key', - defaultModel: 'gpt-3.5-turbo' -}); +`useMessage` 管理消息列表、请求/处理状态、流式响应、插件体系以及工具调用逻辑,而真正的 HTTP 请求由你提供的 `responseProvider` 负责。 -const { - state, - messageManager, // 与 useMessage 返回一致,具体查看useMessage - createConversation, - switchConversation, - deleteConversation, - // ... -} = useConversation({ client }) +```ts +import { useMessage } from '@opentiny/tiny-robot-kit' -const conversationId = createConversation('新对话') +const message = useMessage({ + // responseProvider 负责调用你的后端 / 模型接口 + async responseProvider(requestBody, abortSignal) { + const res = await fetch('/api/chat', { + method: 'POST', + body: JSON.stringify(requestBody), + signal: abortSignal, + headers: { 'Content-Type': 'application/json' }, + }) -messageManager.sendMessage('你好,请介绍一下自己') + return await res.json() + }, +}) ``` -#### 返回值 +更多进阶用法(流式响应、插件、自定义分块(chunk)处理、工具调用等),请查看 。 -`useConversation` 返回以下内容: +### useConversation —— 管理多会话 -```typescript -interface UseConversationReturn { - /** 会话状态 */ - state: ConversationState; - /** 消息管理 */ - messageManager: UseMessageReturn; - /** 创建新会话 */ - createConversation: (title?: string, metadata?: Record) => string; - /** 切换会话 */ - switchConversation: (id: string) => void; - /** 删除会话 */ - deleteConversation: (id: string) => void; - /** 更新会话标题 */ - updateTitle: (id: string, title: string) => void; - /** 更新会话元数据 */ - updateMetadata: (id: string, metadata: Record) => void; - /** 保存会话 */ - saveConversations: () => Promise; - /** 加载会话 */ - loadConversations: () => Promise; - /** 生成会话标题 */ - generateTitle: (id: string) => Promise; - /** 获取当前会话 */ - getCurrentConversation: () => Conversation | null; -} -``` +`useConversation` 基于 `useMessage` 之上,提供多会话管理能力,并支持多种存储策略(LocalStorage、IndexedDB、自定义等)。 -#### 会话状态 +```ts +import { useConversation } from '@opentiny/tiny-robot-kit' -```typescript -interface ConversationState { - /** 会话列表 */ - conversations: Conversation[]; - /** 当前会话ID */ - currentId: string | null; - /** 是否正在加载 */ - loading: boolean; -} +const { conversations, activeConversation, createConversation, switchConversation } = useConversation({ + useMessageOptions: { + async responseProvider(requestBody, abortSignal) { + const res = await fetch('/api/chat', { + method: 'POST', + body: JSON.stringify(requestBody), + signal: abortSignal, + headers: { 'Content-Type': 'application/json' }, + }) + return await res.json() + }, + }, +}) ``` -#### 会话接口 - -```typescript - -interface Conversation { - /** 会话ID */ - id: string; - /** 会话标题 */ - title: string; - /** 创建时间 */ - createdAt: number; - /** 更新时间 */ - updatedAt: number; - /** 自定义元数据 */ - metadata?: Record; - /** 消息 */ - messages: ChatMessage[]; -} -``` +例如 `localStorageStrategyFactory` 和 `indexedDBStorageStrategyFactory` 等存储策略的详细用法,请参考 。 -#### 自定义存储策略 +### 工具函数 Utils —— 处理 SSE 与响应 -默认使用 LocalStorage 存储会话数据,你也可以实现自定义的存储策略: +Utils 模块提供了一些与 `useMessage` 搭配使用的常用工具函数: -```typescript -interface ConversationStorageStrategy { - /** 保存会话列表 */ - saveConversations: (conversations: Conversation[]) => Promise | void; - /** 加载会话列表 */ - loadConversations: () => Promise | Conversation[]; -} - -// 自定义存储策略示例 -class CustomStorageStrategy implements ConversationStorageStrategy { - async saveConversations(conversations: Conversation[]) { - // 实现自定义存储逻辑 - } - - async loadConversations(): Promise { - // 实现自定义加载逻辑 - return []; - } -} - -// 使用自定义存储策略 -const conversationManager = useConversation({ - client, - storage: new CustomStorageStrategy(), -}); -``` +- `sseStreamToGenerator`:把 SSE `Response` 转换为异步生成器。 +- `formatMessages`:将多种形式的消息统一为 `ChatMessage[]`。 +- `extractTextFromResponse`:从大模型响应中提取纯文本内容。 +- `handleSSEStream`:通过回调方式消费 SSE 流式响应。 +详细函数签名与行为说明,请查看 。 diff --git a/packages/kit/package.json b/packages/kit/package.json index 142080e61..9d58d2b47 100644 --- a/packages/kit/package.json +++ b/packages/kit/package.json @@ -1,10 +1,36 @@ { "name": "@opentiny/tiny-robot-kit", "version": "0.4.0", + "homepage": "https://docs.opentiny.design/tiny-robot/", + "repository": { + "type": "git", + "url": "git+https://github.com/opentiny/tiny-robot.git" + }, + "bugs": { + "url": "https://github.com/opentiny/tiny-robot/issues" + }, "publishConfig": { "access": "public" }, "description": "AI大模型请求与数据处理工具包", + "keywords": [ + "vue", + "vue3", + "ai", + "ai-client", + "ai-sdk", + "chat", + "chatbot", + "llm", + "openai", + "assistant", + "streaming", + "composables", + "conversation", + "model-provider", + "tiny-robot", + "opentiny" + ], "main": "dist/index.js", "module": "dist/index.mjs", "types": "dist/index.d.ts", diff --git a/packages/svgs/README.md b/packages/svgs/README.md index 8a50bed6b..5f6da062c 100644 --- a/packages/svgs/README.md +++ b/packages/svgs/README.md @@ -1,18 +1,32 @@ - # tiny-robot-svgs -管理 svg 资源,提供 SVG 图标组件 +`@opentiny/tiny-robot-svgs` 是 TinyRobot 使用的 SVG 图标库。 +它将每一个图标都封装为独立的 Vue 3 组件,方便在 TinyRobot 内外复用同一套图标资源。 + +## 安装 +```bash +pnpm add @opentiny/tiny-robot-svgs +# 或 +npm install @opentiny/tiny-robot-svgs +yarn add @opentiny/tiny-robot-svgs +``` -### 使用 +## 基本用法 ```vue - +``` + +将 `IconXxx` 替换为你实际需要的图标组件名称(例如 `IconSend`、`IconStop` 等)。 + +## 适用场景 -``` \ No newline at end of file +- 你在使用 **TinyRobot 组件库**,希望在应用其他部分复用同一套图标。 +- 你需要一个 **独立的 SVG 图标集合** 来服务任意 Vue 3 项目,而不希望引入完整的 TinyRobot 组件库。 diff --git a/packages/svgs/package.json b/packages/svgs/package.json index 491b0901c..e1a0fc447 100644 --- a/packages/svgs/package.json +++ b/packages/svgs/package.json @@ -1,6 +1,15 @@ { "name": "@opentiny/tiny-robot-svgs", "version": "0.4.0", + "license": "MIT", + "homepage": "https://docs.opentiny.design/tiny-robot/", + "repository": { + "type": "git", + "url": "git+https://github.com/opentiny/tiny-robot.git" + }, + "bugs": { + "url": "https://github.com/opentiny/tiny-robot/issues" + }, "publishConfig": { "access": "public" }, @@ -18,9 +27,14 @@ "convert": "tsx ./scripts/convert.ts -F" }, "keywords": [ + "vue", + "vue3", "svg", "icons", - "vue" + "icon-library", + "icon-set", + "tiny-robot", + "opentiny" ], "description": "SVG图标组件库", "devDependencies": {