wtfai 1.0.0 → 1.1.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/README.md CHANGED
@@ -10,6 +10,16 @@ npm install wtfai
10
10
  pnpm add wtfai
11
11
  ```
12
12
 
13
+ ## 使用前准备
14
+
15
+ - 前往 `https://www.ourteacher.cc/` 联系客服申请开通 API 访问权限,获取 API Key;
16
+
17
+ - 您的后端需要代理 `https://llm-api.ourschool.cc/workflows/` 开头的接口,在代理过程中需要给请求头添加 `x-tenant-secret`,值为 API Key;
18
+
19
+ - 后续将 `baseUrl` 改为您的后端代理地址即可;
20
+
21
+ - 为方便开发调试,前端可以在创建 Wtfai 实例时传入 `tenantSecret`,值为 API Key,切记不要在生产环境使用。
22
+
13
23
  ## 快速开始
14
24
 
15
25
  ```typescript
@@ -98,8 +108,8 @@ const session = client.createSession('workflow-id', {
98
108
  监听事件。
99
109
 
100
110
  ```typescript
101
- session.on('start', ({ threadId }) => {
102
- // 工作流开始执行,获取到 threadId
111
+ session.on('start', ({ threadId, title }) => {
112
+ // 工作流开始执行,获取到 threadId 和默认标题
103
113
  })
104
114
 
105
115
  session.on('nodeStart', ({ nodeId }) => {
@@ -119,6 +129,11 @@ session.on('loading', ({ nodeId, message }) => {
119
129
  console.log('Loading:', message)
120
130
  })
121
131
 
132
+ session.on('title', ({ title }) => {
133
+ // 收到标题事件,用于更新会话标题
134
+ console.log('会话标题:', title)
135
+ })
136
+
122
137
  session.on('complete', () => {
123
138
  // 工作流执行完成
124
139
  })
@@ -232,16 +247,20 @@ const url = await client.upload.uploadFile({
232
247
  })
233
248
  ```
234
249
 
235
- ##### `uploadImage(file, resourceType, onProgress?)`
250
+ ##### `uploadImage(params)`
236
251
 
237
252
  上传图片(自动压缩)。
238
253
 
239
254
  ```typescript
240
- const url = await client.upload.uploadImage(
241
- imageFile,
242
- 'conversation',
243
- (percent) => console.log(`${percent * 100}%`),
244
- )
255
+ const url = await client.upload.uploadImage({
256
+ file: imageFile,
257
+ resourceType: 'conversation',
258
+ onProgress: (percent) => console.log(`${percent * 100}%`),
259
+ compressOptions: { // 可选
260
+ quality: 0.8,
261
+ maxWidth: 1920,
262
+ },
263
+ })
245
264
  ```
246
265
 
247
266
  ---
@@ -304,7 +323,7 @@ interface SendInput {
304
323
  import { useState, useEffect, useRef } from 'react'
305
324
  import Wtfai, { type SimpleMessage, type WorkflowSession } from 'wtfai'
306
325
 
307
- const client = new W't'fa'i({
326
+ const client = new Wtfai({
308
327
  baseUrl: 'https://api.example.com',
309
328
  })
310
329
 
package/dist/client.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import type { Workflow, WorkflowListResponse } from '@our-llm/shared/workflow.types';
2
- import type { OurLLMClientConfig, SessionOptions } from './types';
2
+ import type { ClientConfig, SessionOptions } from './types';
3
3
  import { WorkflowSession } from './session';
4
4
  import { UploadService } from './upload';
5
5
  /**
@@ -39,7 +39,7 @@ export declare class Wtfai {
39
39
  */
40
40
  readonly upload: UploadService;
41
41
  private readonly headers;
42
- constructor(config: OurLLMClientConfig);
42
+ constructor(config: ClientConfig);
43
43
  /**
44
44
  * 获取工作流列表
45
45
  */
package/dist/client.js CHANGED
@@ -1,23 +1,16 @@
1
1
  import { WorkflowSession } from "./session.js";
2
2
  import { UploadService } from "./upload.js";
3
+ function _define_property(obj, key, value) {
4
+ if (key in obj) Object.defineProperty(obj, key, {
5
+ value: value,
6
+ enumerable: true,
7
+ configurable: true,
8
+ writable: true
9
+ });
10
+ else obj[key] = value;
11
+ return obj;
12
+ }
3
13
  class Wtfai {
4
- baseUrl;
5
- uploadService;
6
- upload;
7
- headers;
8
- constructor(config){
9
- this.baseUrl = config.baseUrl.replace(/\/$/, '');
10
- const headers = {
11
- ...config.headers
12
- };
13
- if (config.tenantSecret) {
14
- console.warn('%c[OurLLM SDK] ⚠️ Warning: tenantSecret is provided. This should ONLY be used for debugging purposes. DO NOT use in production.', 'color: red; font-weight: bold; font-size: 14px;');
15
- headers['x-tenant-secret'] = config.tenantSecret;
16
- }
17
- this.headers = headers;
18
- this.uploadService = new UploadService(this.baseUrl, this.headers);
19
- this.upload = this.uploadService;
20
- }
21
14
  async getWorkflows(page = 1, pageSize = 10) {
22
15
  const params = new URLSearchParams({
23
16
  current: String(page),
@@ -39,5 +32,22 @@ class Wtfai {
39
32
  createSession(workflowId, options) {
40
33
  return new WorkflowSession(workflowId, this.baseUrl, this.uploadService, this.headers, options);
41
34
  }
35
+ constructor(config){
36
+ _define_property(this, "baseUrl", void 0);
37
+ _define_property(this, "uploadService", void 0);
38
+ _define_property(this, "upload", void 0);
39
+ _define_property(this, "headers", void 0);
40
+ this.baseUrl = config.baseUrl.replace(/\/$/, '');
41
+ const headers = {
42
+ ...config.headers
43
+ };
44
+ if (config.tenantSecret) {
45
+ console.warn('%c[OurLLM SDK] ⚠️ Warning: tenantSecret is provided. This should ONLY be used for debugging purposes. DO NOT use in production.', 'color: red; font-weight: bold; font-size: 14px;');
46
+ headers['x-tenant-secret'] = config.tenantSecret;
47
+ }
48
+ this.headers = headers;
49
+ this.uploadService = new UploadService(this.baseUrl, this.headers);
50
+ this.upload = this.uploadService;
51
+ }
42
52
  }
43
53
  export { Wtfai };
package/dist/index.d.ts CHANGED
@@ -2,6 +2,6 @@ import { Wtfai } from './client';
2
2
  export default Wtfai;
3
3
  export { WorkflowSession } from './session';
4
4
  export { UploadService } from './upload';
5
- export type { OurLLMClientConfig, SessionOptions, SessionState, SessionEventListeners, SendInput, UploadParams, CompressOptions, WorkflowInfo, } from './types';
5
+ export type { ClientConfig, SessionOptions, SessionState, SessionEventListeners, SendInput, UploadParams, UploadImageParams, CompressOptions, WorkflowInfo, } from './types';
6
6
  export type { SimpleMessage } from '@our-llm/shared/workflow-events';
7
7
  export type { Workflow, WorkflowConfig } from '@our-llm/shared/workflow.types';
package/dist/session.js CHANGED
@@ -1,31 +1,24 @@
1
1
  import { executeWorkflowSSE } from "./sse.js";
2
2
  import { v7 } from "uuid";
3
+ function _define_property(obj, key, value) {
4
+ if (key in obj) Object.defineProperty(obj, key, {
5
+ value: value,
6
+ enumerable: true,
7
+ configurable: true,
8
+ writable: true
9
+ });
10
+ else obj[key] = value;
11
+ return obj;
12
+ }
3
13
  class WorkflowSession {
4
- workflowId;
5
- baseUrl;
6
- uploadService;
7
- headers;
8
- state = {
9
- messages: [],
10
- isExecuting: false
11
- };
12
- listeners = new Map();
13
- abortController;
14
- constructor(workflowId, baseUrl, uploadService, headers = {}, options = {}){
15
- this.workflowId = workflowId;
16
- this.baseUrl = baseUrl;
17
- this.uploadService = uploadService;
18
- this.headers = headers;
19
- if (options.threadId) this.state.threadId = options.threadId;
20
- else this.state.threadId = v7();
21
- }
22
14
  on(event, listener) {
23
15
  if (!this.listeners.has(event)) this.listeners.set(event, new Set());
24
16
  this.listeners.get(event).add(listener);
25
17
  return this;
26
18
  }
27
19
  off(event, listener) {
28
- this.listeners.get(event)?.delete(listener);
20
+ var _this_listeners_get;
21
+ null == (_this_listeners_get = this.listeners.get(event)) || _this_listeners_get.delete(listener);
29
22
  return this;
30
23
  }
31
24
  emit(event, ...args) {
@@ -72,7 +65,10 @@ class WorkflowSession {
72
65
  text: input.content
73
66
  });
74
67
  if (input.images && input.images.length > 0) {
75
- const imageUrls = await Promise.all(input.images.map((file)=>this.uploadService.uploadImage(file, 'conversation')));
68
+ const imageUrls = await Promise.all(input.images.map((file)=>this.uploadService.uploadImage({
69
+ file,
70
+ resourceType: 'conversation'
71
+ })));
76
72
  for (const url of imageUrls)contentParts.push({
77
73
  type: 'image',
78
74
  url
@@ -142,7 +138,8 @@ class WorkflowSession {
142
138
  threadId: data.t
143
139
  });
144
140
  this.emit('start', {
145
- threadId: data.t
141
+ threadId: data.t,
142
+ title: data.ti
146
143
  });
147
144
  },
148
145
  onNodeStart: (data)=>{
@@ -206,6 +203,11 @@ class WorkflowSession {
206
203
  message: data.m
207
204
  });
208
205
  },
206
+ onTitle: (data)=>{
207
+ this.emit('title', {
208
+ title: data.ti
209
+ });
210
+ },
209
211
  onComplete: ()=>{
210
212
  this.updateState({
211
213
  isExecuting: false,
@@ -241,5 +243,25 @@ class WorkflowSession {
241
243
  });
242
244
  }
243
245
  }
246
+ constructor(workflowId, baseUrl, uploadService, headers = {}, options = {}){
247
+ _define_property(this, "workflowId", void 0);
248
+ _define_property(this, "baseUrl", void 0);
249
+ _define_property(this, "uploadService", void 0);
250
+ _define_property(this, "headers", void 0);
251
+ _define_property(this, "state", void 0);
252
+ _define_property(this, "listeners", void 0);
253
+ _define_property(this, "abortController", void 0);
254
+ this.workflowId = workflowId;
255
+ this.baseUrl = baseUrl;
256
+ this.uploadService = uploadService;
257
+ this.headers = headers;
258
+ this.state = {
259
+ messages: [],
260
+ isExecuting: false
261
+ };
262
+ this.listeners = new Map();
263
+ if (options.threadId) this.state.threadId = options.threadId;
264
+ else this.state.threadId = v7();
265
+ }
244
266
  }
245
267
  export { WorkflowSession };
package/dist/sse.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { WorkflowStartData, NodeStartData, NodeEndData, TokenData, LoadingData } from '@our-llm/shared/workflow-events';
1
+ import type { WorkflowStartData, NodeStartData, NodeEndData, TokenData, LoadingData, TitleData } from '@our-llm/shared/workflow-events';
2
2
  /**
3
3
  * SSE 事件回调
4
4
  */
@@ -8,6 +8,7 @@ export interface SSECallbacks {
8
8
  onNodeEnd?: (data: NodeEndData) => void;
9
9
  onToken?: (data: TokenData) => void;
10
10
  onLoading?: (data: LoadingData) => void;
11
+ onTitle?: (data: TitleData) => void;
11
12
  onComplete?: () => void;
12
13
  onError?: (error: {
13
14
  message: string;
package/dist/sse.js CHANGED
@@ -12,11 +12,13 @@ async function executeWorkflowSSE(url, body, callbacks, headers = {}) {
12
12
  onmessage (msg) {
13
13
  const eventType = msg.event;
14
14
  if ('ok' === eventType) {
15
- callbacks.onComplete?.();
15
+ var _callbacks_onComplete;
16
+ null == (_callbacks_onComplete = callbacks.onComplete) || _callbacks_onComplete.call(callbacks);
16
17
  ctrl.abort();
17
18
  } else if ('err' === eventType) {
19
+ var _callbacks_onError;
18
20
  const data = JSON.parse(msg.data);
19
- callbacks.onError?.({
21
+ null == (_callbacks_onError = callbacks.onError) || _callbacks_onError.call(callbacks, {
20
22
  message: data.m
21
23
  });
22
24
  ctrl.abort();
@@ -24,19 +26,28 @@ async function executeWorkflowSSE(url, body, callbacks, headers = {}) {
24
26
  const data = JSON.parse(msg.data);
25
27
  switch(eventType){
26
28
  case 'ws':
27
- callbacks.onWorkflowStart?.(data);
29
+ var _callbacks_onWorkflowStart;
30
+ null == (_callbacks_onWorkflowStart = callbacks.onWorkflowStart) || _callbacks_onWorkflowStart.call(callbacks, data);
28
31
  break;
29
32
  case 'ns':
30
- callbacks.onNodeStart?.(data);
33
+ var _callbacks_onNodeStart;
34
+ null == (_callbacks_onNodeStart = callbacks.onNodeStart) || _callbacks_onNodeStart.call(callbacks, data);
31
35
  break;
32
36
  case 'ne':
33
- callbacks.onNodeEnd?.(data);
37
+ var _callbacks_onNodeEnd;
38
+ null == (_callbacks_onNodeEnd = callbacks.onNodeEnd) || _callbacks_onNodeEnd.call(callbacks, data);
34
39
  break;
35
40
  case 'tk':
36
- callbacks.onToken?.(data);
41
+ var _callbacks_onToken;
42
+ null == (_callbacks_onToken = callbacks.onToken) || _callbacks_onToken.call(callbacks, data);
37
43
  break;
38
44
  case 'l':
39
- callbacks.onLoading?.(data);
45
+ var _callbacks_onLoading;
46
+ null == (_callbacks_onLoading = callbacks.onLoading) || _callbacks_onLoading.call(callbacks, data);
47
+ break;
48
+ case 'tt':
49
+ var _callbacks_onTitle;
50
+ null == (_callbacks_onTitle = callbacks.onTitle) || _callbacks_onTitle.call(callbacks, data);
40
51
  break;
41
52
  }
42
53
  } catch (e) {
@@ -44,14 +55,16 @@ async function executeWorkflowSSE(url, body, callbacks, headers = {}) {
44
55
  }
45
56
  },
46
57
  onerror (err) {
47
- callbacks.onError?.({
58
+ var _callbacks_onError;
59
+ null == (_callbacks_onError = callbacks.onError) || _callbacks_onError.call(callbacks, {
48
60
  message: String(err)
49
61
  });
50
62
  ctrl.abort();
51
63
  throw err;
52
64
  },
53
65
  onclose () {
54
- callbacks.onComplete?.();
66
+ var _callbacks_onComplete;
67
+ null == (_callbacks_onComplete = callbacks.onComplete) || _callbacks_onComplete.call(callbacks);
55
68
  ctrl.abort();
56
69
  }
57
70
  });
package/dist/types.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * SDK 配置类型
3
3
  */
4
- export interface OurLLMClientConfig {
4
+ export interface ClientConfig {
5
5
  /** API 服务器地址 */
6
6
  baseUrl: string;
7
7
  /** 请求超时时间(毫秒) */
@@ -29,6 +29,13 @@ export interface UploadParams {
29
29
  /** 上传进度回调 */
30
30
  onProgress?: (percent: number) => void;
31
31
  }
32
+ /**
33
+ * 上传图片参数
34
+ */
35
+ export interface UploadImageParams extends UploadParams {
36
+ /** 压缩选项 */
37
+ compressOptions?: CompressOptions;
38
+ }
32
39
  /**
33
40
  * 图片压缩选项
34
41
  */
@@ -87,6 +94,7 @@ export type SessionEventType = 'start' | 'nodeStart' | 'nodeEnd' | 'token' | 'lo
87
94
  export interface SessionEventListeners {
88
95
  start: (data: {
89
96
  threadId: string;
97
+ title: string;
90
98
  }) => void;
91
99
  nodeStart: (data: {
92
100
  nodeId: string;
@@ -105,6 +113,9 @@ export interface SessionEventListeners {
105
113
  nodeId: string;
106
114
  message: string;
107
115
  }) => void;
116
+ title: (data: {
117
+ title: string;
118
+ }) => void;
108
119
  complete: () => void;
109
120
  error: (error: {
110
121
  message: string;
package/dist/upload.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { UploadParams } from './types';
1
+ import type { UploadParams, UploadImageParams } from './types';
2
2
  /**
3
3
  * 文件上传服务
4
4
  */
@@ -21,5 +21,5 @@ export declare class UploadService {
21
21
  /**
22
22
  * 上传图片(自动压缩)
23
23
  */
24
- uploadImage(file: File, resourceType: 'conversation' | 'workflow' | 'knowledge-base', onProgress?: (percent: number) => void): Promise<string>;
24
+ uploadImage(params: UploadImageParams): Promise<string>;
25
25
  }
package/dist/upload.js CHANGED
@@ -1,12 +1,16 @@
1
1
  import cos_js_sdk_v5 from "cos-js-sdk-v5";
2
2
  import compressorjs from "compressorjs";
3
+ function _define_property(obj, key, value) {
4
+ if (key in obj) Object.defineProperty(obj, key, {
5
+ value: value,
6
+ enumerable: true,
7
+ configurable: true,
8
+ writable: true
9
+ });
10
+ else obj[key] = value;
11
+ return obj;
12
+ }
3
13
  class UploadService {
4
- baseUrl;
5
- headers;
6
- constructor(baseUrl, headers = {}){
7
- this.baseUrl = baseUrl;
8
- this.headers = headers;
9
- }
10
14
  compressImage(file, options = {}) {
11
15
  const { quality = 0.8, maxWidth = 1920, maxHeight = 1920, convertSize = 1000000 } = options;
12
16
  return new Promise((resolve)=>{
@@ -91,13 +95,20 @@ class UploadService {
91
95
  });
92
96
  });
93
97
  }
94
- async uploadImage(file, resourceType, onProgress) {
95
- const compressedFile = await this.compressImage(file);
98
+ async uploadImage(params) {
99
+ const { file, resourceType, onProgress, compressOptions } = params;
100
+ const compressedFile = await this.compressImage(file, compressOptions);
96
101
  return this.uploadFile({
97
102
  file: compressedFile,
98
103
  resourceType,
99
104
  onProgress
100
105
  });
101
106
  }
107
+ constructor(baseUrl, headers = {}){
108
+ _define_property(this, "baseUrl", void 0);
109
+ _define_property(this, "headers", void 0);
110
+ this.baseUrl = baseUrl;
111
+ this.headers = headers;
112
+ }
102
113
  }
103
114
  export { UploadService };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wtfai",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {
@@ -35,7 +35,7 @@
35
35
  "compressorjs": "^1.2.1",
36
36
  "cos-js-sdk-v5": "^1.10.1",
37
37
  "uuid": "^13.0.0",
38
- "@our-llm/shared": "2.0.0"
38
+ "@our-llm/shared": "2.0.1"
39
39
  },
40
40
  "scripts": {
41
41
  "build": "rslib build",