diff --git a/modules/tool/packages/linkMemo/config.ts b/modules/tool/packages/linkMemo/config.ts
deleted file mode 100644
index c3646820..00000000
--- a/modules/tool/packages/linkMemo/config.ts
+++ /dev/null
@@ -1,92 +0,0 @@
-import { defineTool } from '@tool/type';
-import {
- FlowNodeInputTypeEnum,
- FlowNodeOutputTypeEnum,
- WorkflowIOValueTypeEnum
-} from '@tool/type/fastgpt';
-import { ToolTypeEnum } from '@tool/type/tool';
-
-export default defineTool({
- name: {
- 'zh-CN': '钉钉 Memo',
- en: 'Template tool'
- },
- type: ToolTypeEnum.tools,
- description: {
- 'zh-CN': '钉钉Memo工具',
- en: 'DingTalk Memo Tool'
- },
- secretInputConfig: [
- {
- key: 'dingdingUrl',
- label: '钉钉Memo服务根地址',
- description: '根地址,例如:http://example.com',
- required: true,
- inputType: 'secret'
- },
- {
- key: 'sysAccessKey',
- label: '钉钉Memo系统AccessKey',
- description: '系统AccessKey',
- required: true,
- inputType: 'secret'
- },
- {
- key: 'corpId',
- label: '钉钉Memo企业ID',
- description: '企业ID',
- required: true,
- inputType: 'secret'
- }
- ],
- versionList: [
- {
- value: '0.1.0',
- description: 'Default version',
- inputs: [
- {
- key: 'query',
- label: '用户提问内容',
- renderTypeList: [FlowNodeInputTypeEnum.input, FlowNodeInputTypeEnum.reference],
- valueType: WorkflowIOValueTypeEnum.string,
- required: true
- },
- {
- key: 'appId',
- label: '钉钉Memo应用ID',
- renderTypeList: [FlowNodeInputTypeEnum.input, FlowNodeInputTypeEnum.reference],
- valueType: WorkflowIOValueTypeEnum.string,
- required: true
- },
- {
- key: 'appAccessKey',
- label: '钉钉Memo应用AccessKey',
- renderTypeList: [FlowNodeInputTypeEnum.input, FlowNodeInputTypeEnum.reference],
- valueType: WorkflowIOValueTypeEnum.string,
- required: true
- },
- {
- key: 'iscontact',
- label: '是否使用职级',
- renderTypeList: [FlowNodeInputTypeEnum.switch, FlowNodeInputTypeEnum.reference],
- valueType: WorkflowIOValueTypeEnum.boolean,
- required: false
- }
- ],
- outputs: [
- {
- valueType: WorkflowIOValueTypeEnum.string,
- key: 'content',
- label: '答案内容',
- description: '工具返回的完整答案'
- },
- {
- valueType: WorkflowIOValueTypeEnum.arrayObject,
- key: 'citeLinks',
- label: '参考文档',
- description: '相关的参考文档链接列表'
- }
- ]
- }
- ]
-});
diff --git a/modules/tool/packages/linkMemo/index.ts b/modules/tool/packages/linkMemo/index.ts
deleted file mode 100644
index d698ed48..00000000
--- a/modules/tool/packages/linkMemo/index.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-import config from './config';
-import { InputType, OutputType, tool as toolCb } from './src';
-import { exportTool } from '@tool/utils/tool';
-
-export default exportTool({
- toolCb,
- InputType,
- OutputType,
- config
-});
diff --git a/modules/tool/packages/linkMemo/logo.svg b/modules/tool/packages/linkMemo/logo.svg
deleted file mode 100644
index ca10cec3..00000000
--- a/modules/tool/packages/linkMemo/logo.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/modules/tool/packages/linkMemo/package.json b/modules/tool/packages/linkMemo/package.json
deleted file mode 100644
index d7e33192..00000000
--- a/modules/tool/packages/linkMemo/package.json
+++ /dev/null
@@ -1,17 +0,0 @@
-{
- "name": "@fastgpt-plugins/tool-link-memo",
- "module": "index.ts",
- "type": "module",
- "scripts": {
- "build": "bun ../../../../scripts/build.ts"
- },
- "devDependencies": {
- "@types/bun": "latest"
- },
- "peerDependencies": {
- "typescript": "^5.0.0"
- },
- "dependencies": {
- "zod": "^3.24.2"
- }
-}
diff --git a/modules/tool/packages/linkMemo/src/index.ts b/modules/tool/packages/linkMemo/src/index.ts
deleted file mode 100644
index 5a1fc5fb..00000000
--- a/modules/tool/packages/linkMemo/src/index.ts
+++ /dev/null
@@ -1,195 +0,0 @@
-import { z } from 'zod';
-import type { RunToolSecondParamsType } from '@tool/type/tool';
-import { StreamDataAnswerTypeEnum } from '@tool/type/tool';
-import { getErrText } from '@tool/utils/err';
-
-export const InputType = z.object({
- query: z.string().describe('用户提问内容'),
- dingdingUrl: z.string().describe('钉钉Memo服务根地址'),
- sysAccessKey: z.string().describe('钉钉Memo系统AccessKey'),
- corpId: z.string().describe('钉钉Memo企业ID'),
- appId: z.string().describe('钉钉Memo应用ID'),
- appAccessKey: z.string().describe('钉钉Memo应用AccessKey'),
- iscontact: z.boolean().optional().describe('是否使用职级')
-});
-
-export const OutputType = z.object({
- content: z.string().describe('完整答案'),
- citeLinks: z
- .array(
- z.object({
- name: z.string().describe('知识参考文档显示名称'),
- url: z.string().describe('文档链接')
- })
- )
- .optional()
- .describe('参考文档列表')
-});
-
-type ReferenceDocument = {
- name: string;
- webUrl: string;
- dingUrl: string;
-};
-
-type StreamData = {
- streamData?: string;
- isFinished?: boolean;
- customMessage?: {
- memoChainData?: {
- referenceDocuments?: ReferenceDocument[];
- };
- completedContent?: string;
- };
-};
-
-function buildQueryString(query: string, iscontact: boolean, userContact?: string): string {
- const userParts: string[] = [];
-
- if (iscontact && userContact) {
- userParts.push(`我的职级是${userContact}`);
- }
-
- return userParts.length > 0 ? userParts.join(',') + ',' + query : query;
-}
-
-function extractCiteLinks(docs: ReferenceDocument[]) {
- const citeLinks: Array<{ name: string; url: string }> = [];
-
- docs.forEach((doc) => {
- citeLinks.push({
- name: `${doc.name}`,
- url: doc.webUrl
- });
- });
-
- return citeLinks;
-}
-
-function parseDataString(
- line: string,
- lines: string[],
- index: number
-): { dataStr: string; nextIndex: number } {
- let dataStr = '';
- let nextIndex = index;
-
- if (line.startsWith('data: ')) {
- dataStr = line.slice(6);
- } else if (line === 'data:' && index + 1 < lines.length) {
- dataStr = lines[index + 1];
- nextIndex = index + 1;
- } else if (line.startsWith('data:') && line.length > 5) {
- dataStr = line.slice(5);
- }
-
- return { dataStr, nextIndex };
-}
-
-export async function tool(
- {
- query,
- dingdingUrl,
- sysAccessKey,
- corpId,
- appId,
- appAccessKey,
- iscontact
- }: z.infer,
- { systemVar, streamResponse }: RunToolSecondParamsType
-): Promise> {
- try {
- const url = new URL('/v2/open/api/onpremise/memo/stream/query', dingdingUrl);
-
- url.searchParams.append('userId', systemVar.user.username);
- url.searchParams.append('sysAccessKey', sysAccessKey);
- url.searchParams.append('corpId', corpId);
- url.searchParams.append('appId', appId.toString());
- url.searchParams.append('appAccessKey', appAccessKey);
-
- const queryString = buildQueryString(query, iscontact || false, systemVar.user.contact);
-
- url.searchParams.append('query', queryString);
-
- const response = await fetch(url.toString(), {
- method: 'GET',
- headers: {
- Accept: 'text/event-stream',
- 'Cache-Control': 'no-cache'
- }
- });
-
- if (!response.ok) {
- return Promise.reject(`HTTP ${response.status}: ${response.statusText}`);
- }
-
- const reader = response.body?.getReader();
- if (!reader) {
- return Promise.reject('无法获取响应流');
- }
-
- const decoder = new TextDecoder();
- let buffer = '';
- let completedContent = '';
- let accumulatedContent = '';
- let citeLinks: Array<{ name: string; url: string }> = [];
- let isFinished = false;
-
- while (!isFinished) {
- const { done, value } = await reader.read();
-
- if (done) break;
-
- const chunk = decoder.decode(value, { stream: true });
- buffer += chunk;
-
- const lines = buffer.split('\n');
- buffer = lines.pop() || '';
-
- for (let i = 0; i < lines.length; i++) {
- const line = lines[i];
- const { dataStr, nextIndex } = parseDataString(line, lines, i);
- i = nextIndex;
-
- if (!dataStr.trim()) continue;
-
- try {
- const data: StreamData = JSON.parse(dataStr);
-
- if (data.streamData && !data.isFinished) {
- await streamResponse({
- type: StreamDataAnswerTypeEnum.answer,
- content: data.streamData
- });
- accumulatedContent += data.streamData;
- }
-
- if (data.customMessage?.memoChainData?.referenceDocuments) {
- citeLinks = extractCiteLinks(data.customMessage.memoChainData.referenceDocuments);
- }
-
- if (data.customMessage?.completedContent) {
- completedContent = data.customMessage.completedContent;
- }
-
- if (data.isFinished === true) {
- isFinished = true;
- break;
- }
- } catch {
- // Ignore parse errors for malformed SSE data
- continue;
- }
- }
- }
-
- reader.releaseLock();
-
- return {
- content: completedContent || accumulatedContent,
- citeLinks: citeLinks.length > 0 ? citeLinks : undefined
- };
- } catch (error) {
- return Promise.reject(getErrText(error));
- }
-}
diff --git a/modules/tool/packages/linkMemo/test/index.test.ts b/modules/tool/packages/linkMemo/test/index.test.ts
deleted file mode 100644
index b70e289f..00000000
--- a/modules/tool/packages/linkMemo/test/index.test.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-import { expect, test } from 'vitest';
-import tool from '..';
-
-test(async () => {
- expect(tool.name).toBeDefined();
- expect(tool.description).toBeDefined();
- expect(tool.cb).toBeDefined();
-});