@cloudbase/ai 2.19.1 → 2.19.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.
package/src/AI.ts CHANGED
@@ -3,6 +3,8 @@ import { Bot } from './bot'
3
3
  import * as models from './models'
4
4
  import * as types from './type'
5
5
  import { readableStream2JsonObject } from './utils'
6
+ import { ICloudbaseConfig } from '@cloudbase/types'
7
+ import { langEvent } from '@cloudbase/utilities'
6
8
 
7
9
  const { MODELS } = models
8
10
 
@@ -10,16 +12,52 @@ class AI {
10
12
  public aiBaseUrl: string
11
13
  public aiBotBaseUrl: string
12
14
  public bot: Bot
15
+ public i18n: ICloudbaseConfig['i18n']
16
+ defaultHeaders: { [x: string]: any }
13
17
 
14
- constructor(private req: SDKRequestInterface, public baseUrl: string) {
18
+ constructor(private req: SDKRequestInterface, public baseUrl: string, i18n: ICloudbaseConfig['i18n']) {
15
19
  this.aiBaseUrl = `${baseUrl}/ai`
16
20
  this.aiBotBaseUrl = `${baseUrl}/aibot`
17
21
  this.bot = new Bot(this.botRequest, this.aiBotBaseUrl)
22
+ this.i18n = i18n
23
+
24
+ langEvent.bus.on(langEvent.LANG_CHANGE_EVENT, (params) => {
25
+ this.i18n = params.data?.i18n || this.i18n
26
+ })
27
+ }
28
+
29
+ async handleResponseData(responseData: Promise<unknown> | ReadableStream<Uint8Array>, header?: Headers) {
30
+ const GO_TO_AI_TEXT = `${this.i18n.t('请检查调用方式,或前往云开发 AI+ 首页查看文档')}:https://tcb.cloud.tencent.com/dev#/ai`
31
+
32
+ if (typeof responseData === 'object' && responseData && 'then' in responseData) {
33
+ // 非流式请求,直接返回 json 数据
34
+ const json = (await responseData) as Record<string, unknown>
35
+ if (typeof json === 'object' && json && 'code' in json && json.code !== 'NORMAL') {
36
+ throw new Error(`${this.i18n.t('AI+ 请求出错,错误码')}:${json.code},${this.i18n.t('错误信息')}:${
37
+ json.message
38
+ }\n${GO_TO_AI_TEXT}\n${JSON.stringify(json, null, 2)}`,)
39
+ }
40
+
41
+ return responseData
42
+ }
43
+ // 流式请求,如果接口出错,会变成传 json 格式的响应,通过 header 判断格式
44
+ if (header?.get?.('content-type')?.includes('application/json')) {
45
+ const json = await readableStream2JsonObject(responseData as ReadableStream<Uint8Array>)
46
+ if (typeof json === 'object' && json && 'code' in json && json.code !== 'NORMAL') {
47
+ throw new Error(`${this.i18n.t('AI+ 请求出错,错误码')}:${json.code},${this.i18n.t('错误信息')}:${
48
+ json.message
49
+ }\n${GO_TO_AI_TEXT}\n${JSON.stringify(json, null, 2)}`,)
50
+ }
51
+ }
52
+ return responseData
18
53
  }
19
54
 
20
- createModel(model: string, options?: {
21
- defaultModelSubUrl?: string
22
- }) {
55
+ createModel(
56
+ model: string,
57
+ options?: {
58
+ defaultModelSubUrl?: string
59
+ },
60
+ ) {
23
61
  let simpleModel: types.SimpleChatModel
24
62
 
25
63
  const SimpleModelConstructor = MODELS[model]
@@ -52,19 +90,19 @@ class AI {
52
90
 
53
91
  const { data: responseData, header } = (await this.req.fetch({
54
92
  method: 'post',
55
- headers: { ...fetchHeaders, ...headers },
93
+ headers: { [this.i18n?.LANG_HEADER_KEY]: this.i18n?.lang, ...fetchHeaders, ...headers },
56
94
  body: JSON.stringify(data),
57
95
  url,
58
96
  stream,
59
97
  timeout,
60
98
  })) as { data: Promise<unknown> | ReadableStream<Uint8Array>; header?: Headers }
61
99
 
62
- return handleResponseData(responseData, header) as any
100
+ return this.handleResponseData(responseData, header) as any
63
101
  }
64
102
 
65
103
  botRequest: types.BotReq = async ({ method, url, data = {}, headers, stream, timeout }) => {
66
104
  if (method === 'get') {
67
- return handleResponseData((await this.req.fetch({ url: `${url}?${objectToParam(data)}`, method, headers, stream, timeout })).data,)
105
+ return this.handleResponseData((await this.req.fetch({ url: `${url}?${objectToParam(data)}`, method, headers, stream, timeout })).data,)
68
106
  }
69
107
 
70
108
  const fetchHeaders = {
@@ -77,6 +115,7 @@ class AI {
77
115
  url,
78
116
  body: JSON.stringify(data),
79
117
  headers: {
118
+ [this.i18n?.LANG_HEADER_KEY]: this.i18n?.lang,
80
119
  ...fetchHeaders,
81
120
  ...headers,
82
121
  },
@@ -85,7 +124,7 @@ class AI {
85
124
  timeout,
86
125
  })) as { data: Promise<unknown> | ReadableStream<Uint8Array>; header?: Headers }
87
126
 
88
- return handleResponseData(responseData, header) as any
127
+ return this.handleResponseData(responseData, header) as any
89
128
 
90
129
  function objectToParam(obj: Object) {
91
130
  return Object.entries(obj)
@@ -103,33 +142,3 @@ class AI {
103
142
  }
104
143
 
105
144
  export { AI }
106
-
107
- const GO_TO_AI_TEXT = '请检查调用方式,或前往云开发 AI+ 首页查看文档:https://tcb.cloud.tencent.com/dev#/ai'
108
-
109
- async function handleResponseData(responseData: Promise<unknown> | ReadableStream<Uint8Array>, header?: Headers) {
110
- if (typeof responseData === 'object' && responseData && 'then' in responseData) {
111
- // 非流式请求,直接返回 json 数据
112
- const json = (await responseData) as Record<string, unknown>
113
- if (typeof json === 'object' && json && 'code' in json && json.code !== 'NORMAL') {
114
- throw new Error(`AI+ 请求出错,错误码:${json.code},错误信息:${json.message}\n${GO_TO_AI_TEXT}\n${JSON.stringify(
115
- json,
116
- null,
117
- 2,
118
- )}`,)
119
- }
120
-
121
- return responseData
122
- }
123
- // 流式请求,如果接口出错,会变成传 json 格式的响应,通过 header 判断格式
124
- if (header?.get?.('content-type')?.includes('application/json')) {
125
- const json = await readableStream2JsonObject(responseData as ReadableStream<Uint8Array>)
126
- if (typeof json === 'object' && json && 'code' in json && json.code !== 'NORMAL') {
127
- throw new Error(`AI+ 请求出错,错误码:${json.code},错误信息:${json.message}\n${GO_TO_AI_TEXT}\n${JSON.stringify(
128
- json,
129
- null,
130
- 2,
131
- )}`,)
132
- }
133
- }
134
- return responseData
135
- }
package/src/index.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import type { IFetchOptions, SDKRequestInterface } from '@cloudbase/adapter-interface'
2
- import type { ICloudbase } from '@cloudbase/types'
2
+ import type { ICloudbase, ICloudbaseConfig } from '@cloudbase/types'
3
3
  import type { ICloudbaseComponent } from '@cloudbase/types/component'
4
4
  import { AI } from './AI'
5
5
  import { Bot } from './bot'
@@ -60,6 +60,7 @@ interface ICreateAi {
60
60
  env?: string
61
61
  getAccessToken?: () => Promise<{ accessToken: string }>
62
62
  handleReqInstance?: HandleRequestInstanceFunc
63
+ i18n?: ICloudbaseConfig['i18n']
63
64
  }
64
65
 
65
66
  /**
@@ -72,7 +73,7 @@ interface ICreateAi {
72
73
  *
73
74
  * 其他参数可按需传入覆盖函数逻辑。
74
75
  */
75
- function createAi({ env, baseUrl, req, getAccessToken, handleReqInstance }: ICreateAi) {
76
+ function createAi({ env, baseUrl, req, getAccessToken, handleReqInstance, i18n }: ICreateAi) {
76
77
  const getBaseUrl = () => {
77
78
  if (baseUrl != null) {
78
79
  return baseUrl
@@ -93,7 +94,7 @@ function createAi({ env, baseUrl, req, getAccessToken, handleReqInstance }: ICre
93
94
  return handleReqInstance({ req })
94
95
  }
95
96
 
96
- return new AI(getReq(), getBaseUrl())
97
+ return new AI(getReq(), getBaseUrl(), i18n)
97
98
  }
98
99
 
99
100
  /**
@@ -124,7 +125,7 @@ function ai(
124
125
 
125
126
  const baseUrl = options?.baseUrl ?? getUrlFromCloud()
126
127
 
127
- return createAi({ req, baseUrl, handleReqInstance: ({ req }) => req })
128
+ return createAi({ req, baseUrl, handleReqInstance: ({ req }) => req, i18n: this.config.i18n })
128
129
  }
129
130
 
130
131
  const component: ICloudbaseComponent = {
@@ -0,0 +1,100 @@
1
+ const path = require('path')
2
+ const webpack = require('webpack')
3
+ const TerserPlugin = require('terser-webpack-plugin')
4
+ // const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
5
+ module.exports = function (options) {
6
+ const { context, entry, output, mode, watch, externals, definePlugin = {}, optimization = {} } = options
7
+ const isDevelopment = mode !== 'production'
8
+ let plugins = [
9
+ new webpack.DefinePlugin(definePlugin),
10
+ // new BundleAnalyzerPlugin()
11
+ ].filter((item) => !!item)
12
+
13
+ const BABEL_LOADER = {
14
+ loader: 'babel-loader',
15
+ options: {
16
+ presets: [
17
+ [
18
+ '@babel/preset-env',
19
+ {
20
+ modules: false,
21
+ targets: {
22
+ esmodules: true,
23
+ },
24
+ },
25
+ ],
26
+ ],
27
+ },
28
+ }
29
+
30
+ return {
31
+ context,
32
+ entry,
33
+ mode,
34
+ watch,
35
+ watchOptions: {
36
+ ignored: [output.path],
37
+ },
38
+ output,
39
+ externals,
40
+ cache: {
41
+ type: 'memory',
42
+ },
43
+ devtool: false,
44
+ resolve: {
45
+ extensions: ['.ts', '.js', '.json'],
46
+ },
47
+ module: {
48
+ rules: [
49
+ {
50
+ test: /\.ts$/,
51
+ exclude: [/node_modules/],
52
+ use: [
53
+ BABEL_LOADER,
54
+ {
55
+ loader: require.resolve('ts-loader'),
56
+ options: {
57
+ configFile: path.resolve(context, './tsconfig.esm.json'),
58
+ },
59
+ },
60
+ ],
61
+ },
62
+ {
63
+ test: /\.js$/,
64
+ exclude: [/node_modules/],
65
+ use: [BABEL_LOADER],
66
+ },
67
+ {
68
+ test: /package\.json$/,
69
+ loader: 'package-json-cleanup-loader',
70
+ options: {
71
+ only: ['version'],
72
+ },
73
+ },
74
+ ],
75
+ noParse: [/sjcl\.js$/],
76
+ },
77
+ plugins,
78
+ optimization: {
79
+ emitOnErrors: false,
80
+ removeEmptyChunks: true,
81
+ usedExports: true,
82
+ ...optimization,
83
+ ...(isDevelopment
84
+ ? {
85
+ minimize: false,
86
+ removeAvailableModules: false,
87
+ concatenateModules: true,
88
+ }
89
+ : {
90
+ minimizer: [
91
+ new TerserPlugin({
92
+ test: /\.js(\?.*)?$/i,
93
+ cache: false,
94
+ parallel: true,
95
+ }),
96
+ ],
97
+ }),
98
+ },
99
+ }
100
+ }
@@ -0,0 +1,24 @@
1
+ const path = require('path')
2
+
3
+ const params = {
4
+ context: path.resolve(__dirname, '../'),
5
+ mode: 'production',
6
+ watch: false,
7
+ entry: path.resolve(__dirname, '../src/index.ts'),
8
+ output: {
9
+ path: path.resolve(__dirname, '../dist/miniprogram'),
10
+ filename: 'index.js',
11
+ library: `tcbauth`,
12
+ libraryTarget: 'umd',
13
+ umdNamedDefine: true,
14
+ globalObject: 'typeof window !== "undefined"?window:this',
15
+ },
16
+ externals: {
17
+ },
18
+ definePlugin: {
19
+ 'process.env.NODE_ENV': JSON.stringify('production'), // 注入环境变量,用于业务代码判断
20
+ 'globalThis.IS_MP_BUILD': true,
21
+ },
22
+ }
23
+
24
+ module.exports = require('./web.prod.js')(params)