generated from tailored/app-template
test
This commit is contained in:
parent
b07bcc5454
commit
4a2d3e8d32
2
.gitignore
vendored
2
.gitignore
vendored
@ -19,3 +19,5 @@ logs
|
||||
config.json
|
||||
|
||||
pack-dist
|
||||
|
||||
videos/output*
|
@ -44,7 +44,7 @@
|
||||
"@kevisual/mark": "0.0.7",
|
||||
"@kevisual/router": "0.0.13",
|
||||
"@kevisual/types": "^0.0.9",
|
||||
"@kevisual/use-config": "^1.0.11",
|
||||
"@kevisual/use-config": "^1.0.12",
|
||||
"@types/bun": "^1.2.11",
|
||||
"@types/crypto-js": "^4.2.2",
|
||||
"@types/formidable": "^3.4.5",
|
||||
@ -71,6 +71,6 @@
|
||||
"tape": "^5.9.0",
|
||||
"tiktoken": "^1.0.21",
|
||||
"typescript": "^5.8.3",
|
||||
"vite": "^6.3.3"
|
||||
"vite": "^6.3.4"
|
||||
}
|
||||
}
|
48
pnpm-lock.yaml
generated
48
pnpm-lock.yaml
generated
@ -10,7 +10,7 @@ importers:
|
||||
devDependencies:
|
||||
'@kevisual/code-center-module':
|
||||
specifier: 0.0.18
|
||||
version: 0.0.18(@kevisual/auth@1.0.5)(@kevisual/router@0.0.13)(@kevisual/use-config@1.0.11(dotenv@16.5.0))(ioredis@5.6.1)(pg@8.14.1)(sequelize@6.37.7(pg@8.14.1))
|
||||
version: 0.0.18(@kevisual/auth@1.0.5)(@kevisual/router@0.0.13)(@kevisual/use-config@1.0.12(dotenv@16.5.0))(ioredis@5.6.1)(pg@8.14.1)(sequelize@6.37.7(pg@8.14.1))
|
||||
'@kevisual/mark':
|
||||
specifier: 0.0.7
|
||||
version: 0.0.7(dotenv@16.5.0)(esbuild@0.25.2)
|
||||
@ -21,8 +21,8 @@ importers:
|
||||
specifier: ^0.0.9
|
||||
version: 0.0.9
|
||||
'@kevisual/use-config':
|
||||
specifier: ^1.0.11
|
||||
version: 1.0.11(dotenv@16.5.0)
|
||||
specifier: ^1.0.12
|
||||
version: 1.0.12(dotenv@16.5.0)
|
||||
'@types/bun':
|
||||
specifier: ^1.2.11
|
||||
version: 1.2.11
|
||||
@ -40,7 +40,7 @@ importers:
|
||||
version: 22.15.3
|
||||
'@vitejs/plugin-basic-ssl':
|
||||
specifier: ^2.0.0
|
||||
version: 2.0.0(vite@6.3.3(@types/node@22.15.3)(tsx@4.19.3))
|
||||
version: 2.0.0(vite@6.3.4(@types/node@22.15.3)(tsx@4.19.3))
|
||||
cookie:
|
||||
specifier: ^1.0.2
|
||||
version: 1.0.2
|
||||
@ -102,8 +102,8 @@ importers:
|
||||
specifier: ^5.8.3
|
||||
version: 5.8.3
|
||||
vite:
|
||||
specifier: ^6.3.3
|
||||
version: 6.3.3(@types/node@22.15.3)(tsx@4.19.3)
|
||||
specifier: ^6.3.4
|
||||
version: 6.3.4(@types/node@22.15.3)(tsx@4.19.3)
|
||||
|
||||
packages:
|
||||
|
||||
@ -307,8 +307,8 @@ packages:
|
||||
'@kevisual/types@0.0.9':
|
||||
resolution: {integrity: sha512-SDJ7GMbOx7Ghz2kreHqym56ccAJS3t93y+NS0+afTLxcq2+cKcoEy2F8WXEv0mnJ6EsDp5AbA7Jv5TZA1Jbc3A==}
|
||||
|
||||
'@kevisual/use-config@1.0.11':
|
||||
resolution: {integrity: sha512-ccilQTRZTpO075L67ZBXhr8Lp3i73/W5cCMT5enMjVrnJT5K0i5JH5IbzBhF6WY5Rj8dmVsAyyjJe24ClyM7Eg==}
|
||||
'@kevisual/use-config@1.0.12':
|
||||
resolution: {integrity: sha512-PNoZqj6vdhv6DvjRMNwoGH9HJupm7QvjkvtCEYW2ryK7J8sI73r2ThCl4OEbXdRYVgl1EeK/e2IJh0Rf51bVwA==}
|
||||
peerDependencies:
|
||||
dotenv: ^16.4.7
|
||||
|
||||
@ -1054,14 +1054,6 @@ packages:
|
||||
fclone@1.0.11:
|
||||
resolution: {integrity: sha512-GDqVQezKzRABdeqflsgMr7ktzgF9CyS+p2oe0jJqUY6izSSbhPIQJDpoU4PtGcD7VPM9xh/dVrTu6z1nwgmEGw==}
|
||||
|
||||
fdir@6.4.3:
|
||||
resolution: {integrity: sha512-PMXmW2y1hDDfTSRc9gaXIuCCRpuoz3Kaz8cUelp3smouvfT632ozg2vrT6lJsHKKOF59YLbOGfAWGUcKEfRMQw==}
|
||||
peerDependencies:
|
||||
picomatch: ^3 || ^4
|
||||
peerDependenciesMeta:
|
||||
picomatch:
|
||||
optional: true
|
||||
|
||||
fdir@6.4.4:
|
||||
resolution: {integrity: sha512-1NZP+GK4GfuAv3PqKvxQRDMjdSRZjnkq7KfhlNrCNNlZ0ygQFpebfrnfnq/W7fpUnAv9aGWmY1zKx7FYL3gwhg==}
|
||||
peerDependencies:
|
||||
@ -2194,8 +2186,8 @@ packages:
|
||||
resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==}
|
||||
engines: {node: '>= 0.8'}
|
||||
|
||||
vite@6.3.3:
|
||||
resolution: {integrity: sha512-5nXH+QsELbFKhsEfWLkHrvgRpTdGJzqOZ+utSdmPTvwHmvU6ITTm3xx+mRusihkcI8GeC7lCDyn3kDtiki9scw==}
|
||||
vite@6.3.4:
|
||||
resolution: {integrity: sha512-BiReIiMS2fyFqbqNT/Qqt4CVITDU9M9vE+DKcVAsB+ZV0wvTKd+3hMbkpxz1b+NmEDMegpVbisKiAZOnvO92Sw==}
|
||||
engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0}
|
||||
hasBin: true
|
||||
peerDependencies:
|
||||
@ -2431,11 +2423,11 @@ snapshots:
|
||||
|
||||
'@kevisual/auth@1.0.5': {}
|
||||
|
||||
'@kevisual/code-center-module@0.0.18(@kevisual/auth@1.0.5)(@kevisual/router@0.0.13)(@kevisual/use-config@1.0.11(dotenv@16.5.0))(ioredis@5.6.1)(pg@8.14.1)(sequelize@6.37.7(pg@8.14.1))':
|
||||
'@kevisual/code-center-module@0.0.18(@kevisual/auth@1.0.5)(@kevisual/router@0.0.13)(@kevisual/use-config@1.0.12(dotenv@16.5.0))(ioredis@5.6.1)(pg@8.14.1)(sequelize@6.37.7(pg@8.14.1))':
|
||||
dependencies:
|
||||
'@kevisual/auth': 1.0.5
|
||||
'@kevisual/router': 0.0.13
|
||||
'@kevisual/use-config': 1.0.11(dotenv@16.5.0)
|
||||
'@kevisual/use-config': 1.0.12(dotenv@16.5.0)
|
||||
ioredis: 5.6.1
|
||||
nanoid: 5.1.5
|
||||
pg: 8.14.1
|
||||
@ -2456,7 +2448,7 @@ snapshots:
|
||||
'@kevisual/auth': 1.0.5
|
||||
'@kevisual/rollup-tools': 0.0.1(esbuild@0.25.2)
|
||||
'@kevisual/router': 0.0.7
|
||||
'@kevisual/use-config': 1.0.11(dotenv@16.5.0)
|
||||
'@kevisual/use-config': 1.0.12(dotenv@16.5.0)
|
||||
cookie: 1.0.2
|
||||
nanoid: 5.1.5
|
||||
pg: 8.14.1
|
||||
@ -2516,7 +2508,7 @@ snapshots:
|
||||
|
||||
'@kevisual/types@0.0.9': {}
|
||||
|
||||
'@kevisual/use-config@1.0.11(dotenv@16.5.0)':
|
||||
'@kevisual/use-config@1.0.12(dotenv@16.5.0)':
|
||||
dependencies:
|
||||
'@kevisual/load': 0.0.6
|
||||
dotenv: 16.5.0
|
||||
@ -2607,7 +2599,7 @@ snapshots:
|
||||
'@rollup/pluginutils': 5.1.4(rollup@4.40.1)
|
||||
commondir: 1.0.1
|
||||
estree-walker: 2.0.2
|
||||
fdir: 6.4.3(picomatch@4.0.2)
|
||||
fdir: 6.4.4(picomatch@4.0.2)
|
||||
is-reference: 1.2.1
|
||||
magic-string: 0.30.17
|
||||
picomatch: 4.0.2
|
||||
@ -2778,9 +2770,9 @@ snapshots:
|
||||
|
||||
'@types/validator@13.12.3': {}
|
||||
|
||||
'@vitejs/plugin-basic-ssl@2.0.0(vite@6.3.3(@types/node@22.15.3)(tsx@4.19.3))':
|
||||
'@vitejs/plugin-basic-ssl@2.0.0(vite@6.3.4(@types/node@22.15.3)(tsx@4.19.3))':
|
||||
dependencies:
|
||||
vite: 6.3.3(@types/node@22.15.3)(tsx@4.19.3)
|
||||
vite: 6.3.4(@types/node@22.15.3)(tsx@4.19.3)
|
||||
|
||||
abort-controller@3.0.0:
|
||||
dependencies:
|
||||
@ -3304,10 +3296,6 @@ snapshots:
|
||||
|
||||
fclone@1.0.11: {}
|
||||
|
||||
fdir@6.4.3(picomatch@4.0.2):
|
||||
optionalDependencies:
|
||||
picomatch: 4.0.2
|
||||
|
||||
fdir@6.4.4(picomatch@4.0.2):
|
||||
optionalDependencies:
|
||||
picomatch: 4.0.2
|
||||
@ -4616,7 +4604,7 @@ snapshots:
|
||||
|
||||
vary@1.1.2: {}
|
||||
|
||||
vite@6.3.3(@types/node@22.15.3)(tsx@4.19.3):
|
||||
vite@6.3.4(@types/node@22.15.3)(tsx@4.19.3):
|
||||
dependencies:
|
||||
esbuild: 0.25.2
|
||||
fdir: 6.4.4(picomatch@4.0.2)
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { BaseChat, BaseChatOptions } from '../core/chat.ts';
|
||||
import { OpenAI } from 'openai';
|
||||
|
||||
type SiliconFlowOptions = Partial<BaseChatOptions>;
|
||||
export type SiliconFlowOptions = Partial<BaseChatOptions>;
|
||||
|
||||
type SiliconFlowUsageData = {
|
||||
id: string;
|
||||
|
@ -107,4 +107,11 @@ export class BaseChat implements BaseChatInterface, BaseChatUsageInterface {
|
||||
completion_tokens: this.completion_tokens,
|
||||
};
|
||||
}
|
||||
getHeaders(headers?: Record<string, string>) {
|
||||
return {
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `Bearer ${this.apiKey}`,
|
||||
...headers,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
1
src/provider/media/index.ts
Normal file
1
src/provider/media/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export * from './video/siliconflow.ts';
|
37
src/provider/media/video/siliconflow.ts
Normal file
37
src/provider/media/video/siliconflow.ts
Normal file
@ -0,0 +1,37 @@
|
||||
import { SiliconFlow } from './../../chat-adapter/siliconflow.ts';
|
||||
export class VideoSiliconFlow extends SiliconFlow {
|
||||
constructor(opts: any) {
|
||||
super(opts);
|
||||
}
|
||||
|
||||
async uploadAudioVoice(audioBase64: string | Blob | File) {
|
||||
const pathname = 'uploads/audio/voice';
|
||||
const url = `${this.baseURL}/${pathname}`;
|
||||
const headers = {
|
||||
'Content-Type': 'multipart/form-data',
|
||||
Authorization: `Bearer ${this.apiKey}`,
|
||||
};
|
||||
const formData = new FormData();
|
||||
// formData.append('audio', 'data:audio/mpeg;base64,aGVsbG93b3JsZA==');
|
||||
// formData.append('audio', audioBase64);
|
||||
formData.append('file', audioBase64);
|
||||
formData.append('model', 'FunAudioLLM/CosyVoice2-0.5B');
|
||||
formData.append('customName', 'test_name');
|
||||
formData.append('text', '在一无所知中, 梦里的一天结束了,一个新的轮回便会开始');
|
||||
|
||||
const res = await fetch(url, {
|
||||
method: 'POST',
|
||||
headers,
|
||||
body: formData,
|
||||
}).then((res) => res.json());
|
||||
console.log('uploadAudioVoice', res);
|
||||
}
|
||||
async audioSpeech() {
|
||||
this.openai.audio.speech.create({
|
||||
model: 'FunAudioLLM/CosyVoice2-0.5B',
|
||||
voice: 'alloy',
|
||||
input: '在一无所知中, 梦里的一天结束了,一个新的轮回便会开始',
|
||||
response_format: 'mp3',
|
||||
});
|
||||
}
|
||||
}
|
100
src/test/siliconflow/videos/index.ts
Normal file
100
src/test/siliconflow/videos/index.ts
Normal file
@ -0,0 +1,100 @@
|
||||
import { SiliconFlow } from '../../../provider/chat-adapter/siliconflow.ts';
|
||||
import { VideoSiliconFlow } from '../../../provider/media/video/siliconflow.ts';
|
||||
import dotenv from 'dotenv';
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import Stream from 'stream';
|
||||
|
||||
dotenv.config();
|
||||
const siliconflow = new SiliconFlow({
|
||||
apiKey: process.env.SILICONFLOW_API_KEY,
|
||||
model: 'Qwen/Qwen2-7B-Instruct',
|
||||
});
|
||||
const videoSiliconflow = new VideoSiliconFlow({
|
||||
apiKey: process.env.SILICONFLOW_API_KEY,
|
||||
model: 'Qwen/Qwen2-7B-Instruct',
|
||||
});
|
||||
|
||||
const main = async () => {
|
||||
const usage = await siliconflow.getUsageInfo();
|
||||
console.log(usage);
|
||||
};
|
||||
|
||||
// main();
|
||||
const mainChat = async () => {
|
||||
const test2=`我永远记得那个改变一切的下午。十八岁生日后的第三天,我正坐在自家后院的老橡树杈上,用平板电脑调试我最新设计的森林动物追踪程序。我的红发——妈妈总说像"燃烧的枫叶"——在午后的阳光下泛着铜色的光泽,有几缕不听话的发丝被微风拂过我的脸颊。
|
||||
|
||||
"芮薇!"妈妈的声音从厨房窗口传来,"外婆发来加密信息,说需要你马上过去一趟。"
|
||||
|
||||
我差点从树上掉下来。外婆从不发加密信息——除非情况紧急。作为退休的网络安全专家,外婆一直教导我"过度谨慎总比后悔莫及"。`
|
||||
try {
|
||||
const res = await siliconflow.openai.audio.speech.create({
|
||||
model: 'FunAudioLLM/CosyVoice2-0.5B',
|
||||
// voice: 'FunAudioLLM/CosyVoice2-0.5B:diana',
|
||||
voice: 'speech:test:h36jngt7ms:zarwclhblfjfyonslejr',
|
||||
// input: '在一无所知中, 梦里的一天结束了,一个新的轮回便会开始',
|
||||
// input: '这是一个新的轮回,非常有趣的故事。',
|
||||
input: test2,
|
||||
response_format: 'mp3',
|
||||
});
|
||||
|
||||
console.log(res);
|
||||
|
||||
const dir = path.join(process.cwd(), 'videos');
|
||||
if (!fs.existsSync(dir)) {
|
||||
fs.mkdirSync(dir, { recursive: true });
|
||||
}
|
||||
|
||||
const filePath = path.join(dir, `output-${Date.now()}.mp3`);
|
||||
|
||||
// 假设 res 是一个可读流
|
||||
if (res instanceof Stream.Readable) {
|
||||
const writeStream = fs.createWriteStream(filePath);
|
||||
res.pipe(writeStream);
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
writeStream.on('finish', () => {
|
||||
console.log('文件已保存至:', filePath);
|
||||
resolve(filePath);
|
||||
});
|
||||
writeStream.on('error', reject);
|
||||
});
|
||||
}
|
||||
// 假设 res 是一个 ArrayBuffer 或 Buffer
|
||||
else if (res.arrayBuffer) {
|
||||
const buffer = Buffer.from(await res.arrayBuffer());
|
||||
fs.writeFileSync(filePath, buffer);
|
||||
console.log('文件已保存至:', filePath);
|
||||
return filePath;
|
||||
}
|
||||
// 假设 res 是一个包含 blob 的对象
|
||||
else if (res.blob) {
|
||||
// @ts-ignore
|
||||
const buffer = Buffer.from(res.blob, 'base64');
|
||||
fs.writeFileSync(filePath, buffer);
|
||||
console.log('文件已保存至:', filePath);
|
||||
return filePath;
|
||||
} else {
|
||||
throw new Error('无法识别的响应格式');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('保存音频文件时出错:', error);
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
mainChat();
|
||||
|
||||
const vidioUpload = async () => {
|
||||
const filePath = path.join(process.cwd(), 'videos', 'my_speech_text.mp3');
|
||||
const fileBuffer = fs.readFileSync(filePath);
|
||||
const fileBase64 = 'data:audio/mpeg;base64,' + fileBuffer.toString('base64');
|
||||
console.log('fileBase64', fileBase64.slice(0, 100));
|
||||
const fileBlob = new Blob([fileBuffer], { type: 'audio/wav' });
|
||||
const file = new File([fileBlob], 'my_speech_text.mp3', { type: 'audio/mp3' });
|
||||
const res = await videoSiliconflow.uploadAudioVoice(file);
|
||||
// console.log('vidioUpload', res);
|
||||
// uri:speech:test:h36jngt7ms:zarwclhblfjfyonslejr
|
||||
return res;
|
||||
};
|
||||
// vidioUpload();
|
@ -1,25 +1,7 @@
|
||||
{
|
||||
"extends": "@kevisual/types/json/backend.json",
|
||||
"compilerOptions": {
|
||||
"module": "nodenext",
|
||||
"target": "esnext",
|
||||
"noImplicitAny": false,
|
||||
"outDir": "./dist",
|
||||
"sourceMap": false,
|
||||
"allowJs": true,
|
||||
"newLine": "LF",
|
||||
"baseUrl": "./",
|
||||
"typeRoots": [
|
||||
"node_modules/@types",
|
||||
"node_modules/@kevisual/types"
|
||||
],
|
||||
"declaration": true,
|
||||
"noEmit": false,
|
||||
"allowImportingTsExtensions": true,
|
||||
"emitDeclarationOnly": true,
|
||||
"moduleResolution": "NodeNext",
|
||||
"experimentalDecorators": true,
|
||||
"emitDecoratorMetadata": true,
|
||||
"esModuleInterop": true,
|
||||
"paths": {
|
||||
"@/*": [
|
||||
"src/*"
|
||||
|
BIN
videos/my_speech_text.mp3
Normal file
BIN
videos/my_speech_text.mp3
Normal file
Binary file not shown.
1
videos/my_speech_text.txt
Normal file
1
videos/my_speech_text.txt
Normal file
@ -0,0 +1 @@
|
||||
在一无所知中, 梦里的一天结束了,一个新的轮回便会开始
|
BIN
videos/my_speech_text.wav
Normal file
BIN
videos/my_speech_text.wav
Normal file
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user