@cloudbase/ai 2.8.21-beta.0 → 2.8.22-beta.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.
Files changed (106) hide show
  1. package/dist/cjs/AI.d.ts +27 -0
  2. package/dist/cjs/AI.js +154 -0
  3. package/dist/cjs/index.d.ts +13 -38
  4. package/dist/cjs/index.js +9 -73
  5. package/dist/cjs/models/Ark/index.d.ts +4 -18
  6. package/dist/cjs/models/Ark/index.js +45 -82
  7. package/dist/cjs/models/Ark/type.d.ts +52 -19
  8. package/dist/cjs/models/Ark/type.js +1 -1
  9. package/dist/cjs/models/DashScope/index.d.ts +4 -18
  10. package/dist/cjs/models/DashScope/index.js +45 -82
  11. package/dist/cjs/models/DashScope/type.d.ts +55 -24
  12. package/dist/cjs/models/DashScope/type.js +1 -1
  13. package/dist/cjs/models/HunYuan/index.d.ts +4 -19
  14. package/dist/cjs/models/HunYuan/index.js +47 -107
  15. package/dist/cjs/models/HunYuan/type.d.ts +68 -48
  16. package/dist/cjs/models/HunYuan/type.js +1 -1
  17. package/dist/cjs/models/HunYuan/util.d.ts +4 -0
  18. package/dist/cjs/models/HunYuan/util.js +58 -0
  19. package/dist/cjs/models/HunYuanBeta/index.d.ts +4 -19
  20. package/dist/cjs/models/HunYuanBeta/index.js +42 -110
  21. package/dist/cjs/models/Moonshot/index.d.ts +4 -18
  22. package/dist/cjs/models/Moonshot/index.js +45 -82
  23. package/dist/cjs/models/Moonshot/type.d.ts +63 -9
  24. package/dist/cjs/models/Moonshot/type.js +1 -1
  25. package/dist/cjs/models/Yi/index.d.ts +4 -18
  26. package/dist/cjs/models/Yi/index.js +48 -82
  27. package/dist/cjs/models/Yi/type.d.ts +41 -15
  28. package/dist/cjs/models/Yi/type.js +1 -1
  29. package/dist/cjs/models/ZhiPu/index.d.ts +4 -18
  30. package/dist/cjs/models/ZhiPu/index.js +59 -87
  31. package/dist/cjs/models/ZhiPu/type.d.ts +19 -19
  32. package/dist/cjs/models/ZhiPu/type.js +1 -1
  33. package/dist/cjs/models/index.d.ts +16 -15
  34. package/dist/cjs/models/index.js +26 -23
  35. package/dist/cjs/models/model.d.ts +38 -0
  36. package/dist/cjs/models/model.js +481 -0
  37. package/dist/cjs/type.d.ts +76 -15
  38. package/dist/cjs/type.js +6 -12
  39. package/dist/cjs/utils.d.ts +9 -1
  40. package/dist/cjs/utils.js +46 -2
  41. package/dist/esm/AI.d.ts +27 -0
  42. package/dist/esm/AI.js +128 -0
  43. package/dist/esm/index.d.ts +13 -38
  44. package/dist/esm/index.js +4 -70
  45. package/dist/esm/models/Ark/index.d.ts +4 -18
  46. package/dist/esm/models/Ark/index.js +45 -82
  47. package/dist/esm/models/Ark/type.d.ts +52 -19
  48. package/dist/esm/models/Ark/type.js +1 -1
  49. package/dist/esm/models/DashScope/index.d.ts +4 -18
  50. package/dist/esm/models/DashScope/index.js +45 -82
  51. package/dist/esm/models/DashScope/type.d.ts +55 -24
  52. package/dist/esm/models/DashScope/type.js +1 -1
  53. package/dist/esm/models/HunYuan/index.d.ts +4 -19
  54. package/dist/esm/models/HunYuan/index.js +47 -107
  55. package/dist/esm/models/HunYuan/type.d.ts +68 -48
  56. package/dist/esm/models/HunYuan/type.js +1 -1
  57. package/dist/esm/models/HunYuan/util.d.ts +4 -0
  58. package/dist/esm/models/HunYuan/util.js +53 -0
  59. package/dist/esm/models/HunYuanBeta/index.d.ts +4 -19
  60. package/dist/esm/models/HunYuanBeta/index.js +42 -110
  61. package/dist/esm/models/Moonshot/index.d.ts +4 -18
  62. package/dist/esm/models/Moonshot/index.js +45 -82
  63. package/dist/esm/models/Moonshot/type.d.ts +63 -9
  64. package/dist/esm/models/Moonshot/type.js +1 -1
  65. package/dist/esm/models/Yi/index.d.ts +4 -18
  66. package/dist/esm/models/Yi/index.js +48 -82
  67. package/dist/esm/models/Yi/type.d.ts +41 -15
  68. package/dist/esm/models/Yi/type.js +1 -1
  69. package/dist/esm/models/ZhiPu/index.d.ts +4 -18
  70. package/dist/esm/models/ZhiPu/index.js +59 -87
  71. package/dist/esm/models/ZhiPu/type.d.ts +19 -19
  72. package/dist/esm/models/ZhiPu/type.js +1 -1
  73. package/dist/esm/models/index.d.ts +16 -15
  74. package/dist/esm/models/index.js +17 -16
  75. package/dist/esm/models/model.d.ts +38 -0
  76. package/dist/esm/models/model.js +478 -0
  77. package/dist/esm/type.d.ts +76 -15
  78. package/dist/esm/type.js +5 -11
  79. package/dist/esm/utils.d.ts +9 -1
  80. package/dist/esm/utils.js +41 -1
  81. package/package.json +3 -3
  82. package/src/AI.ts +77 -0
  83. package/src/index.ts +3 -60
  84. package/src/models/Ark/index.ts +52 -54
  85. package/src/models/Ark/type.ts +60 -19
  86. package/src/models/DashScope/index.ts +56 -55
  87. package/src/models/DashScope/type.ts +63 -21
  88. package/src/models/HunYuan/index.ts +44 -67
  89. package/src/models/HunYuan/type.ts +68 -46
  90. package/src/models/HunYuan/util.ts +59 -0
  91. package/src/models/HunYuanBeta/index.ts +41 -75
  92. package/src/models/Moonshot/index.ts +52 -54
  93. package/src/models/Moonshot/type.ts +61 -7
  94. package/src/models/Yi/index.ts +59 -55
  95. package/src/models/Yi/type.ts +47 -19
  96. package/src/models/ZhiPu/index.ts +60 -52
  97. package/src/models/ZhiPu/type.ts +20 -9
  98. package/src/models/index.ts +25 -15
  99. package/src/models/model.ts +415 -0
  100. package/src/type.ts +100 -13
  101. package/src/utils.ts +53 -1
  102. package/dist/cjs/models/HunYuanBeta/type.d.ts +0 -52
  103. package/dist/cjs/models/HunYuanBeta/type.js +0 -3
  104. package/dist/esm/models/HunYuanBeta/type.d.ts +0 -52
  105. package/dist/esm/models/HunYuanBeta/type.js +0 -2
  106. package/src/models/HunYuanBeta/type.ts +0 -61
@@ -1,15 +1,22 @@
1
- import { type ParsedEvent } from '../../eventsource_parser'
2
1
  import {
3
2
  createAsyncIterable,
4
3
  TransformStream,
5
- TextDecoderStream,
6
- createEventSourceParserTransformStream,
7
4
  toPolyfillReadable,
5
+ intoStandardStream,
6
+ isToolCallAssistantMessage,
8
7
  } from '../../utils'
9
- import type { HunYuanInputData, HunYaunGenerateTextOutput, HunYaunStreamTextOutput } from './type'
10
- import type { ChatModel, StreamTextResult, ModelReq, BaseChatModelInput } from '../../type'
8
+ import type {
9
+ ModelReq,
10
+ BaseChatModelInput,
11
+ SimpleChatModel,
12
+ DoStreamOutput,
13
+ BaseDoStreamOutputChunk,
14
+ DoGenerateOutput,
15
+ } from '../../type'
16
+ import { processInput } from '../HunYuan/util'
17
+ import { HunYuanGenerateTextOutput, HunYuanStreamTextOutput } from '../HunYuan/type'
11
18
 
12
- export class HunYuanBetaModel implements ChatModel {
19
+ export class HunYuanBetaSimpleModel implements SimpleChatModel {
13
20
  public subUrl = 'hunyuan-beta/openapi/v1/chat/completions'
14
21
  constructor(private req: ModelReq, public baseUrl: string, subUrl?: string) {
15
22
  if (subUrl != null) {
@@ -21,92 +28,51 @@ export class HunYuanBetaModel implements ChatModel {
21
28
  return `${this.baseUrl}/${this.subUrl}`
22
29
  }
23
30
 
24
- async generateText(data: BaseChatModelInput) {
25
- const processedData = this.processInput(data)
31
+ public async doGenerate(data: BaseChatModelInput): Promise<DoGenerateOutput> {
26
32
  const res = (await this.req({
27
33
  url: this.url,
28
- headers: {
29
- 'X-Tc-Action': 'ChatCompletions',
30
- },
31
34
  data: {
32
- ...processedData,
33
- Stream: false,
35
+ ...processInput(data),
36
+ stream: false,
34
37
  },
35
38
  stream: false,
36
- })) as HunYaunGenerateTextOutput
37
- return {
38
- text: (res?.choices?.[0]?.message?.content as string) ?? '',
39
- rawResponse: res,
40
- }
39
+ })) as HunYuanGenerateTextOutput
40
+ return { ...res, rawResponse: res }
41
41
  }
42
42
 
43
- async streamText(data: BaseChatModelInput) {
44
- const processedData = this.processInput(data)
45
- const stream = await this.req({
43
+ public async doStream(data: BaseChatModelInput): Promise<DoStreamOutput> {
44
+ let isToolCall: null | boolean = null
45
+
46
+ const _stream = await this.req({
46
47
  url: this.url,
47
- headers: {
48
- 'X-Tc-Action': 'ChatCompletions',
49
- },
50
48
  data: {
51
- ...processedData,
52
- Stream: true,
49
+ ...data,
50
+ stream: true,
53
51
  },
54
52
  stream: true,
55
53
  })
56
- return new HunyuanModelStreamResult(stream)
57
- }
58
-
59
- private processInput({ messages, model, temperature, top_p, ...rest }: BaseChatModelInput): HunYuanInputData {
60
- return {
61
- Messages: messages.map(({ content, role }) => ({ Content: content, Role: role })),
62
- Model: model as any,
63
- Temperature: temperature,
64
- TopP: top_p,
65
- ...rest,
66
- }
67
- }
68
- }
69
-
70
- class HunyuanModelStreamResult implements StreamTextResult {
71
- private _eventSourceStream: ReadableStream<ParsedEvent>
72
-
73
- constructor(_stream: ReadableStream<Uint8Array>) {
74
54
  const stream = toPolyfillReadable(_stream) as typeof _stream
75
- this._eventSourceStream = stream
76
- .pipeThrough(new TextDecoderStream())
77
- .pipeThrough(createEventSourceParserTransformStream())
78
- }
79
55
 
80
- private get teeedStream() {
81
- const [s1, s2] = this._eventSourceStream.tee()
82
- this._eventSourceStream = s2
83
- return s1
84
- }
85
-
86
- get eventSourceStream() {
87
- return createAsyncIterable(this.teeedStream)
88
- }
89
-
90
- get dataStream() {
91
- return createAsyncIterable(this.eventSourceStream.pipeThrough(new TransformStream<ParsedEvent, HunYaunStreamTextOutput>({
56
+ const hunyuanBetaStream = intoStandardStream<HunYuanStreamTextOutput>(stream)
57
+ const streamWithRaw = hunyuanBetaStream.pipeThrough(new TransformStream<HunYuanStreamTextOutput, BaseDoStreamOutputChunk & { rawResponse?: any }>({
92
58
  transform(chunk, controller) {
93
- try {
94
- const data = JSON.parse(chunk.data) as HunYaunStreamTextOutput
95
- controller.enqueue(data)
96
- } catch (e) {
97
- if (chunk.data !== '[DONE]') {
98
- console.warn('Error when transforming event source data to json', e)
59
+ const newChoices = chunk.choices.map((choice) => {
60
+ const message = choice.delta
61
+ if (isToolCall == null) isToolCall = isToolCallAssistantMessage(message)
62
+ if (isToolCall) {
63
+ return {
64
+ ...choice,
65
+ finish_reason: 'tool_calls',
66
+ delta: message,
67
+ }
99
68
  }
100
- }
69
+ return choice
70
+ })
71
+ const newChunk = { ...chunk, choices: newChoices }
72
+ controller.enqueue({ ...newChunk, rawResponse: chunk })
101
73
  },
102
- }),),)
103
- }
74
+ }),)
104
75
 
105
- get textStream() {
106
- return createAsyncIterable(this.dataStream.pipeThrough(new TransformStream<HunYaunStreamTextOutput, string>({
107
- transform(chunk, controller) {
108
- controller.enqueue(chunk?.choices?.[0]?.delta?.content ?? '')
109
- },
110
- }),),)
76
+ return createAsyncIterable(streamWithRaw)
111
77
  }
112
78
  }
@@ -1,15 +1,37 @@
1
- import { type ParsedEvent } from '../../eventsource_parser'
2
1
  import {
3
2
  createAsyncIterable,
4
3
  TransformStream,
5
- TextDecoderStream,
6
- createEventSourceParserTransformStream,
7
4
  toPolyfillReadable,
5
+ intoStandardStream,
6
+ isToolCallAssistantMessage,
8
7
  } from '../../utils'
9
- import type { MoonshotInputData, MoonshotGenerateTextOutput, MoonshotStreamTextOutput } from './type'
10
- import type { ChatModel, StreamTextResult, ModelReq } from '../../type'
8
+ import type { MoonshotGenerateTextOutput, MoonshotStreamTextOutput, MoonshotInputData } from './type'
9
+ import type {
10
+ ModelReq,
11
+ BaseDoStreamOutputChunk,
12
+ DoGenerateOutput,
13
+ DoStreamOutput,
14
+ SimpleChatModel,
15
+ BaseChatModelInput,
16
+ } from '../../type'
11
17
 
12
- export class MoonshotModel implements ChatModel {
18
+ function processInput(input: BaseChatModelInput): MoonshotInputData {
19
+ const { messages, model, temperature, tools, top_p } = input
20
+
21
+ return {
22
+ ...input,
23
+ messages,
24
+ model,
25
+ tools: tools?.map(tool => ({
26
+ ...tool,
27
+ function: { ...tool.function, parameters: JSON.parse(tool.function.parameters) },
28
+ })),
29
+ top_p,
30
+ temperature,
31
+ }
32
+ }
33
+
34
+ export class MoonshotSimpleModel implements SimpleChatModel {
13
35
  public subUrl = 'moonshot/v1/chat/completions'
14
36
  constructor(private req: ModelReq, public baseUrl: string, subUrl?: string) {
15
37
  if (subUrl != null) {
@@ -21,74 +43,50 @@ export class MoonshotModel implements ChatModel {
21
43
  return `${this.baseUrl}/${this.subUrl}`
22
44
  }
23
45
 
24
- async generateText(data: MoonshotInputData) {
46
+ public async doGenerate(data: BaseChatModelInput): Promise<DoGenerateOutput> {
25
47
  const res = (await this.req({
26
48
  url: this.url,
27
49
  data: {
28
- ...data,
50
+ ...processInput(data),
29
51
  stream: false,
30
52
  },
31
53
  stream: false,
32
54
  })) as MoonshotGenerateTextOutput
33
- return {
34
- text: (res?.choices?.[0]?.message?.content as string) ?? '',
35
- rawResponse: res,
36
- }
55
+ return { ...res, rawResponse: res }
37
56
  }
38
57
 
39
- async streamText(data: MoonshotInputData) {
40
- const stream = await this.req({
58
+ public async doStream(data: BaseChatModelInput): Promise<DoStreamOutput> {
59
+ let isToolCall: null | boolean = null
60
+ const _stream = await this.req({
41
61
  url: this.url,
42
62
  data: {
43
- ...data,
63
+ ...processInput(data),
44
64
  stream: true,
45
65
  },
46
66
  stream: true,
47
67
  })
48
- return new MoonshotModelStreamResult(stream)
49
- }
50
- }
51
-
52
- class MoonshotModelStreamResult implements StreamTextResult {
53
- private _eventSourceStream: ReadableStream<ParsedEvent>
54
-
55
- constructor(_stream: ReadableStream<Uint8Array>) {
56
68
  const stream = toPolyfillReadable(_stream) as typeof _stream
57
- this._eventSourceStream = stream
58
- .pipeThrough(new TextDecoderStream())
59
- .pipeThrough(createEventSourceParserTransformStream())
60
- }
61
-
62
- private get teeedStream() {
63
- const [s1, s2] = this._eventSourceStream.tee()
64
- this._eventSourceStream = s2
65
- return s1
66
- }
67
-
68
- get eventSourceStream() {
69
- return createAsyncIterable(this.teeedStream)
70
- }
71
69
 
72
- get dataStream() {
73
- return createAsyncIterable(this.eventSourceStream.pipeThrough(new TransformStream<ParsedEvent, MoonshotStreamTextOutput>({
70
+ const arkStream = intoStandardStream<MoonshotStreamTextOutput>(stream)
71
+ const streamWithRaw = arkStream.pipeThrough(new TransformStream<MoonshotStreamTextOutput, BaseDoStreamOutputChunk & { rawResponse?: any }>({
74
72
  transform(chunk, controller) {
75
- try {
76
- const data = JSON.parse(chunk.data) as MoonshotStreamTextOutput
77
- controller.enqueue(data)
78
- } catch (e) {
79
- if (chunk.data !== '[DONE]') {
80
- console.warn('Error when transforming event source data to json', e)
73
+ const newChoices = chunk.choices.map((choice) => {
74
+ const message = choice.delta
75
+ if (isToolCall == null) isToolCall = isToolCallAssistantMessage(message)
76
+ if (isToolCall) {
77
+ return {
78
+ ...choice,
79
+ finish_reason: 'tool_calls' as const,
80
+ delta: message,
81
+ }
81
82
  }
82
- }
83
+ return choice
84
+ })
85
+ const newChunk = { ...chunk, choices: newChoices }
86
+ controller.enqueue({ ...newChunk, rawResponse: chunk })
83
87
  },
84
- }),),)
85
- }
88
+ }),)
86
89
 
87
- get textStream() {
88
- return createAsyncIterable(this.dataStream.pipeThrough(new TransformStream<MoonshotStreamTextOutput, string>({
89
- transform(chunk, controller) {
90
- controller.enqueue(chunk?.choices?.[0]?.delta?.content ?? '')
91
- },
92
- }),),)
90
+ return createAsyncIterable(streamWithRaw)
93
91
  }
94
92
  }
@@ -1,12 +1,42 @@
1
- type MoonshotMessage = { role: 'user' | 'system' | 'assistant'; content: string }
1
+ type SystemMessage = {
2
+ role: 'system'
3
+ content: string
4
+ }
5
+
6
+ type UserMessage = {
7
+ role: 'user'
8
+ content: string
9
+ }
10
+
11
+ type AssistantMessage = {
12
+ role: 'assistant'
13
+ content?: string
14
+ tool_calls?: Array<{
15
+ id: string
16
+ type: string
17
+ function?: { name: string; arguments: string }
18
+ }>
19
+ }
20
+
21
+ type ToolMessage = {
22
+ role: 'tool'
23
+ content: string
24
+ tool_call_id: string
25
+ }
26
+
27
+ type MoonshotMessage = SystemMessage | UserMessage | AssistantMessage | ToolMessage
2
28
 
3
29
  export type MoonshotInputData = {
4
30
  messages: Array<MoonshotMessage>
5
- model: 'moonshot-v1-8k' | 'moonshot-v1-32k' | 'moonshot-v1-128k'
31
+ model: string
6
32
  max_tokens?: number
7
33
  temperature?: number
8
34
  top_p?: number
9
35
  n?: number
36
+ tools?: Array<{
37
+ type: string
38
+ function: { name: string; description: string; parameters: object }
39
+ }>
10
40
  presence_penalty?: number
11
41
  frequency_penalty?: number
12
42
  response_format?: object
@@ -15,14 +45,38 @@ export type MoonshotInputData = {
15
45
 
16
46
  // todo: more precise
17
47
  export type MoonshotGenerateTextOutput = {
18
- choices?: Array<{
19
- message?: { content?: string }
48
+ choices: Array<{
49
+ finish_reason: string
50
+ message: {
51
+ content: string
52
+ role: 'assistant'
53
+ tool_calls?: Array<ToolCall>
54
+ }
20
55
  }>
56
+ usage: {
57
+ prompt_tokens: number
58
+ completion_tokens: number
59
+ total_tokens: number
60
+ }
21
61
  }
22
-
23
62
  // todo: more precise
24
63
  export type MoonshotStreamTextOutput = {
25
- choices?: Array<{
26
- delta?: { content?: string }
64
+ choices: Array<{
65
+ delta: {
66
+ content: string
67
+ tool_calls?: Array<ToolCall>
68
+ role: 'assistant'
69
+ }
70
+ finish_reason: string
27
71
  }>
72
+ usage?: {
73
+ prompt_tokens: number
74
+ completion_tokens: number
75
+ total_tokens: number
76
+ }
77
+ }
78
+ type ToolCall = {
79
+ id: string
80
+ type: string
81
+ function: { name: string; arguments: string }
28
82
  }
@@ -1,16 +1,39 @@
1
- import { type ParsedEvent } from '../../eventsource_parser'
2
1
  import {
3
2
  createAsyncIterable,
4
3
  TransformStream,
5
- TextDecoderStream,
6
- createEventSourceParserTransformStream,
7
4
  toPolyfillReadable,
5
+ intoStandardStream,
6
+ isToolCallAssistantMessage,
8
7
  } from '../../utils'
9
- import type { YiGenerateTextOutput, YiStreamTextOutput } from './type'
10
- import type { ChatModel, StreamTextResult, ModelReq, BaseChatModelInput } from '../../type'
8
+ import type { YiInput, YiGenerateOutput, YiStreamOutput } from './type'
9
+ import type {
10
+ ModelReq,
11
+ BaseChatModelInput,
12
+ DoGenerateOutput,
13
+ DoStreamOutput,
14
+ BaseDoStreamOutputChunk,
15
+ SimpleChatModel,
16
+ } from '../../type'
11
17
 
12
- export class YiModel implements ChatModel {
18
+ function processInput(input: BaseChatModelInput): YiInput {
19
+ const { messages, model, temperature, tools, top_p } = input
20
+
21
+ return {
22
+ ...input,
23
+ messages,
24
+ model,
25
+ tools: tools?.map(tool => ({
26
+ ...tool,
27
+ function: { ...tool.function, parameters: JSON.parse(tool.function.parameters) },
28
+ })),
29
+ top_p,
30
+ temperature,
31
+ }
32
+ }
33
+
34
+ export class YiSimpleModel implements SimpleChatModel {
13
35
  public subUrl = '01-ai/v1/chat/completions'
36
+
14
37
  constructor(private req: ModelReq, public baseUrl: string, subUrl?: string) {
15
38
  if (subUrl != null) {
16
39
  this.subUrl = subUrl
@@ -21,74 +44,55 @@ export class YiModel implements ChatModel {
21
44
  return `${this.baseUrl}/${this.subUrl}`
22
45
  }
23
46
 
24
- async generateText(data: BaseChatModelInput) {
47
+ public async doGenerate(data: BaseChatModelInput): Promise<DoGenerateOutput> {
25
48
  const res = (await this.req({
26
49
  url: this.url,
27
50
  data: {
28
- ...data,
51
+ ...processInput(data),
29
52
  stream: false,
30
53
  },
31
54
  stream: false,
32
- })) as YiGenerateTextOutput
33
- return {
34
- text: (res?.choices?.[0]?.message?.content as string) ?? '',
35
- rawResponse: res,
36
- }
55
+ })) as YiGenerateOutput
56
+ return { ...res, rawResponse: res }
37
57
  }
38
58
 
39
- async streamText(data: BaseChatModelInput) {
40
- const stream = await this.req({
59
+ public async doStream(data: BaseChatModelInput): Promise<DoStreamOutput> {
60
+ let isToolCall: null | boolean = null
61
+ const _stream = await this.req({
41
62
  url: this.url,
42
63
  data: {
43
- ...data,
64
+ ...processInput(data),
44
65
  stream: true,
45
66
  },
46
67
  stream: true,
47
68
  })
48
- return new YiModelStreamResult(stream)
49
- }
50
- }
51
-
52
- class YiModelStreamResult implements StreamTextResult {
53
- private _eventSourceStream: ReadableStream<ParsedEvent>
54
-
55
- constructor(_stream: ReadableStream<Uint8Array>) {
56
69
  const stream = toPolyfillReadable(_stream) as typeof _stream
57
- this._eventSourceStream = stream
58
- .pipeThrough(new TextDecoderStream())
59
- .pipeThrough(createEventSourceParserTransformStream())
60
- }
61
-
62
- private get teeedStream() {
63
- const [s1, s2] = this._eventSourceStream.tee()
64
- this._eventSourceStream = s2
65
- return s1
66
- }
67
-
68
- get eventSourceStream() {
69
- return createAsyncIterable(this.teeedStream)
70
- }
71
70
 
72
- get dataStream() {
73
- return createAsyncIterable(this.eventSourceStream.pipeThrough(new TransformStream<ParsedEvent, YiStreamTextOutput>({
71
+ const arkStream = intoStandardStream<YiStreamOutput>(stream)
72
+ const streamWithRaw = arkStream.pipeThrough(new TransformStream<YiStreamOutput, BaseDoStreamOutputChunk & { rawResponse?: any }>({
74
73
  transform(chunk, controller) {
75
- try {
76
- const data = JSON.parse(chunk.data) as YiStreamTextOutput
77
- controller.enqueue(data)
78
- } catch (e) {
79
- if (chunk.data !== '[DONE]') {
80
- console.warn('Error when transforming event source data to json', e)
74
+ // 非常奇葩
75
+ if (!(chunk?.choices?.[0]?.delta?.content || chunk?.choices?.[0]?.delta?.tool_calls)) return
76
+
77
+ const newChoices = chunk.choices.map((choice) => {
78
+ const message = Object.assign(choice.delta, { role: 'assistant' }) as typeof choice.delta & {
79
+ role: 'assistant'
80
+ }
81
+ if (isToolCall == null) isToolCall = isToolCallAssistantMessage(message)
82
+ if (isToolCall) {
83
+ return {
84
+ ...choice,
85
+ finish_reason: 'tool_calls' as const,
86
+ delta: message,
87
+ }
81
88
  }
82
- }
89
+ return { ...choice, delta: message }
90
+ })
91
+ const newChunk = { ...chunk, choices: newChoices }
92
+ controller.enqueue({ ...newChunk, rawResponse: chunk })
83
93
  },
84
- }),),)
85
- }
94
+ }),)
86
95
 
87
- get textStream() {
88
- return createAsyncIterable(this.dataStream.pipeThrough(new TransformStream<YiStreamTextOutput, string>({
89
- transform(chunk, controller) {
90
- controller.enqueue(chunk?.choices?.[0]?.delta?.content ?? '')
91
- },
92
- }),),)
96
+ return createAsyncIterable(streamWithRaw)
93
97
  }
94
98
  }
@@ -8,10 +8,16 @@ type UserMessage = {
8
8
  content: string
9
9
  }
10
10
 
11
- type AssistantMessage = {
12
- role: 'assistant'
13
- content: string
14
- }
11
+ type AssistantMessage =
12
+ | {
13
+ role: 'assistant'
14
+ content: string
15
+ }
16
+ | {
17
+ role: 'assistant'
18
+ tool_calls: Array<ToolCall>
19
+ content?: string
20
+ }
15
21
 
16
22
  type ToolMessage = {
17
23
  role: 'tool'
@@ -21,29 +27,51 @@ type ToolMessage = {
21
27
 
22
28
  type YiMessage = SystemMessage | UserMessage | AssistantMessage | ToolMessage
23
29
 
24
- export type YiInputData = {
30
+ export type YiInput = {
25
31
  model: string
26
32
  messages: Array<YiMessage>
33
+ temperature?: number
34
+ top_p?: number
27
35
  tools?: Array<{
28
- type: 'function'
29
- function: { name: string; description?: string; parameters: object }
36
+ type: string
37
+ function: { name: string; description: string; parameters: object }
30
38
  }>
31
- tool_choice?: string | object
32
- max_tokens?: number | null
33
- top_p?: number
34
- temperature?: number
35
39
  }
36
40
 
37
- // todo: more precise
38
- export type YiGenerateTextOutput = {
39
- choices?: Array<{
40
- message?: { content?: string }
41
+ type ToolCall = {
42
+ id: string
43
+ type: string
44
+ function: { name: string; arguments: string }
45
+ }
46
+
47
+ export type YiGenerateOutput = {
48
+ choices: Array<{
49
+ finish_reason: string
50
+ message: {
51
+ content: string
52
+ role: 'assistant'
53
+ tool_calls?: Array<ToolCall>
54
+ }
41
55
  }>
56
+ usage: {
57
+ prompt_tokens: number
58
+ completion_tokens: number
59
+ total_tokens: number
60
+ }
42
61
  }
43
62
 
44
- // todo: more precise
45
- export type YiStreamTextOutput = {
46
- choices?: Array<{
47
- delta?: { content?: string }
63
+ export type YiStreamOutput = {
64
+ choices: Array<{
65
+ delta: {
66
+ content: string
67
+ tool_calls?: Array<ToolCall>
68
+ role?: 'assistant'
69
+ }
70
+ finish_reason: string
48
71
  }>
72
+ usage?: {
73
+ prompt_tokens: number
74
+ completion_tokens: number
75
+ total_tokens: number
76
+ }
49
77
  }