@hlw-zbzs/ai 1.0.2 → 1.0.3

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.
@@ -1,142 +0,0 @@
1
- /**
2
- * @file 大模型底层适配引擎 (基于官方 OpenAI SDK,单单词极简命名)
3
- */
4
-
5
- import OpenAI from 'openai'
6
- import type { AiConfig, AiEngine, AiHandler, AiMsg, AiOption, AiResult, AiTest } from '../types'
7
-
8
- export const URLS: Record<AiEngine, string> = {
9
- deepseek: 'https://api.deepseek.com/v1',
10
- qwen: 'https://dashscope.aliyuncs.com/compatible-mode/v1',
11
- chatgpt: 'https://api.openai.com/v1',
12
- zhipu: 'https://open.bigmodel.cn/api/paas/v4',
13
- doubao: 'https://ark.cn-beijing.volces.com/api/v3',
14
- moonshot: 'https://api.moonshot.cn/v1',
15
- claude: 'https://api.anthropic.com/v1',
16
- ollama: 'http://localhost:11434/v1',
17
- custom: 'https://api.openai.com/v1'
18
- }
19
-
20
- export class Engine {
21
- public type: AiEngine
22
- public conf: AiConfig
23
- private client: OpenAI | null = null
24
-
25
- constructor(type: AiEngine, conf: AiConfig) {
26
- this.type = type
27
- this.conf = { ...conf }
28
- this.init()
29
- }
30
-
31
- private init() {
32
- const url = (this.conf.url || '').trim().replace(/\/+$/, '') || URLS[this.type]
33
- const key = (this.conf.key || '').trim() || 'dummy-key'
34
- this.client = new OpenAI({
35
- baseURL: url,
36
- apiKey: key,
37
- dangerouslyAllowBrowser: true
38
- })
39
- }
40
-
41
- public save(conf: Partial<AiConfig>) {
42
- Object.assign(this.conf, conf)
43
- this.init()
44
- }
45
-
46
- private build(option: AiOption): OpenAI.Chat.ChatCompletionMessageParam[] {
47
- const list: OpenAI.Chat.ChatCompletionMessageParam[] = []
48
- const sys = option.sys ?? this.conf.sys
49
- if (sys && sys.trim()) {
50
- list.push({ role: 'system', content: sys.trim() })
51
- }
52
- for (const item of option.list) {
53
- if (item.role === 'system' && sys) continue
54
- list.push({
55
- role: item.role as 'user' | 'assistant' | 'system',
56
- content: item.text
57
- })
58
- }
59
- return list
60
- }
61
-
62
- public async chat(option: AiOption): Promise<AiResult> {
63
- if (!this.client) this.init()
64
- const list = this.build(option)
65
- const res = await this.client!.chat.completions.create(
66
- {
67
- model: option.model || this.conf.model,
68
- messages: list,
69
- temperature: option.temp ?? this.conf.temp ?? 0.7,
70
- max_tokens: option.tokens ?? this.conf.tokens ?? 2048,
71
- stream: false
72
- },
73
- { signal: option.signal }
74
- )
75
- const choice = res.choices?.[0]
76
- const text = choice?.message?.content || ''
77
- const think = (choice?.message as any)?.reasoning_content || ''
78
- return { text, think }
79
- }
80
-
81
- public async stream(option: AiOption, handler: AiHandler = {}): Promise<AiResult> {
82
- if (!this.client) this.init()
83
- const list = this.build(option)
84
- let text = ''
85
- let think = ''
86
- try {
87
- const stream = await this.client!.chat.completions.create(
88
- {
89
- model: option.model || this.conf.model,
90
- messages: list,
91
- temperature: option.temp ?? this.conf.temp ?? 0.7,
92
- max_tokens: option.tokens ?? this.conf.tokens ?? 2048,
93
- stream: true
94
- },
95
- { signal: option.signal }
96
- )
97
- for await (const chunk of stream) {
98
- const delta = chunk.choices?.[0]?.delta
99
- if (!delta) continue
100
- const thought = (delta as any)?.reasoning_content
101
- if (thought) {
102
- think += thought
103
- handler.onThink?.(thought)
104
- }
105
- if (delta.content) {
106
- text += delta.content
107
- handler.onToken?.(delta.content)
108
- }
109
- }
110
- handler.onDone?.(text, think)
111
- return { text, think }
112
- } catch (error: any) {
113
- handler.onError?.(error)
114
- throw error
115
- }
116
- }
117
-
118
- public async test(tempConfig?: Partial<AiConfig>): Promise<AiTest> {
119
- const prev = { ...this.conf }
120
- if (tempConfig) this.save(tempConfig)
121
- const time = Date.now()
122
- try {
123
- const res = await this.chat({
124
- list: [{ role: 'user', text: 'Hi' }],
125
- tokens: 5
126
- })
127
- return {
128
- success: true,
129
- msg: '连接成功',
130
- latency: Date.now() - time
131
- }
132
- } catch (error: any) {
133
- return {
134
- success: false,
135
- msg: error?.message || '连接失败',
136
- latency: Date.now() - time
137
- }
138
- } finally {
139
- this.save(prev)
140
- }
141
- }
142
- }
@@ -1,12 +0,0 @@
1
- /**
2
- * @file 大模型引擎聚合与工厂
3
- */
4
-
5
- import { Engine } from './base'
6
- import type { AiConfig, AiEngine } from '../types'
7
-
8
- export * from './base'
9
-
10
- export function createEngine(type: AiEngine, conf: AiConfig): Engine {
11
- return new Engine(type, conf)
12
- }
@@ -1,158 +0,0 @@
1
- /**
2
- * @file AI 状态管理 (单单词极简设计,支持各主流模型配置持久化)
3
- */
4
-
5
- import { defineStore } from 'pinia'
6
- import { electronStorage } from '@hlw-zbzs/core'
7
- import { URLS } from '../engines/base'
8
- import type { AiConfig, AiEngine, AiInfo } from '../types'
9
-
10
- export const ENGINES: AiInfo[] = [
11
- {
12
- type: 'deepseek',
13
- name: 'DeepSeek',
14
- tag: '超高性价比 / 深度思考',
15
- enable: true,
16
- models: ['deepseek-chat', 'deepseek-reasoner'],
17
- model: 'deepseek-chat',
18
- url: 'https://platform.deepseek.com/api_keys'
19
- },
20
- {
21
- type: 'qwen',
22
- name: '通义千问',
23
- tag: '阿里百炼 / 国产领先',
24
- enable: true,
25
- models: ['qwen-max', 'qwen-plus', 'qwen-turbo', 'qwen-long', 'qwen2.5-72b-instruct'],
26
- model: 'qwen-plus',
27
- url: 'https://bailian.console.aliyun.com/?apiKey=1#/api-key'
28
- },
29
- {
30
- type: 'chatgpt',
31
- name: 'ChatGPT',
32
- tag: 'OpenAI / 强大通用',
33
- enable: true,
34
- models: ['gpt-4o', 'gpt-4o-mini', 'o1', 'o3-mini', 'gpt-4-turbo', 'gpt-3.5-turbo'],
35
- model: 'gpt-4o-mini',
36
- url: 'https://platform.openai.com/api-keys'
37
- },
38
- {
39
- type: 'zhipu',
40
- name: '智谱 GLM',
41
- tag: '清华基座 / 智能体',
42
- enable: true,
43
- models: ['glm-4-plus', 'glm-4-air', 'glm-4-flash', 'glm-4-long', 'glm-zero-preview'],
44
- model: 'glm-4-flash',
45
- url: 'https://bigmodel.cn/usercenter/apikeys'
46
- },
47
- {
48
- type: 'doubao',
49
- name: '字节豆包',
50
- tag: '火山引擎 / 低延迟',
51
- enable: true,
52
- models: ['doubao-pro-32k', 'doubao-lite-32k', 'doubao-pro-128k'],
53
- model: 'doubao-pro-32k',
54
- url: 'https://console.volcengine.com/ark/region:ark+cn-beijing/apiKey'
55
- },
56
- {
57
- type: 'moonshot',
58
- name: 'Moonshot',
59
- tag: 'Kimi / 超长上下文',
60
- enable: true,
61
- models: ['moonshot-v1-8k', 'moonshot-v1-32k', 'moonshot-v1-128k'],
62
- model: 'moonshot-v1-8k',
63
- url: 'https://platform.moonshot.cn/console/api-keys'
64
- },
65
- {
66
- type: 'claude',
67
- name: 'Claude',
68
- tag: 'Anthropic / 顶尖逻辑',
69
- enable: true,
70
- models: ['claude-3-5-sonnet-20241022', 'claude-3-5-haiku-20241022', 'claude-3-opus-20240229'],
71
- model: 'claude-3-5-sonnet-20241022',
72
- url: 'https://console.anthropic.com/settings/keys'
73
- },
74
- {
75
- type: 'ollama',
76
- name: 'Ollama',
77
- tag: '本地私有 / 免密免Key',
78
- free: true,
79
- enable: true,
80
- models: ['deepseek-r1', 'llama3.3', 'qwen2.5', 'gemma2', 'mistral'],
81
- model: 'deepseek-r1',
82
- url: 'https://ollama.com'
83
- },
84
- {
85
- type: 'custom',
86
- name: '自定义 API',
87
- tag: '第三方中转 / 兼容协议',
88
- enable: true,
89
- models: ['default'],
90
- model: 'default'
91
- }
92
- ]
93
-
94
- export function getDefaults(): Record<AiEngine, AiConfig> {
95
- const result: Partial<Record<AiEngine, AiConfig>> = {}
96
- for (const item of ENGINES) {
97
- result[item.type] = {
98
- key: '',
99
- url: URLS[item.type],
100
- model: item.model,
101
- temp: 0.7,
102
- tokens: 2048,
103
- sys: '你是一名专业热情的直播间智能助手,负责协助主播进行弹幕互动与话术生成。'
104
- }
105
- }
106
- return result as Record<AiEngine, AiConfig>
107
- }
108
-
109
- export const useAiStore = defineStore('ai', {
110
- state: () => ({
111
- engine: 'deepseek' as AiEngine,
112
- enabled: true,
113
- configs: getDefaults()
114
- }),
115
-
116
- getters: {
117
- conf: (state): AiConfig => state.configs[state.engine] || getDefaults()[state.engine],
118
- ready: (state): boolean => {
119
- if (state.engine === 'ollama') return true
120
- const target = state.configs[state.engine]
121
- return Boolean(target?.key?.trim())
122
- },
123
- list: () => ENGINES,
124
- info: (state): AiInfo => ENGINES.find((item) => item.type === state.engine) || ENGINES[0]
125
- },
126
-
127
- actions: {
128
- set(type: AiEngine) {
129
- this.engine = type
130
- },
131
- toggle() {
132
- this.enabled = !this.enabled
133
- },
134
- save(type: AiEngine, conf: Partial<AiConfig>) {
135
- if (!this.configs[type]) {
136
- this.configs[type] = getDefaults()[type]
137
- }
138
- Object.assign(this.configs[type], conf)
139
- },
140
- reset(type?: AiEngine) {
141
- const defaults = getDefaults()
142
- if (type) {
143
- this.configs[type] = defaults[type]
144
- } else {
145
- this.configs = defaults
146
- this.engine = 'deepseek'
147
- this.enabled = true
148
- }
149
- }
150
- },
151
-
152
- persist: {
153
- key: 'ai.config',
154
- storage: electronStorage
155
- }
156
- })
157
-
158
- export default useAiStore
package/src/types.d.ts DELETED
@@ -1 +0,0 @@
1
- export type * from '../types'