ctod 1.0.7 → 1.1.1

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,6 +1,6 @@
1
1
  import fs from 'fs'
2
2
  import { Anthropic } from '@anthropic-ai/sdk'
3
- import { CtoD, AnthropicCtodService, plugins } from '../lib/index.js'
3
+ import { CtoD, AnthropicCtodService, plugins, paragraph } from '../lib/index.js'
4
4
 
5
5
  /**
6
6
  * @test npx esno ./examples/anthropic.ts
@@ -38,6 +38,15 @@ const brokerBuilder = ctod.createBrokerBuilder<{
38
38
  {
39
39
  role: 'system',
40
40
  content: 'You are now a pharmacist skilled at categorizing indexes'
41
+ },
42
+ {
43
+ role: 'user',
44
+ contents: [
45
+ {
46
+ type: 'text',
47
+ content: 'I have the following indexes'
48
+ }
49
+ ]
41
50
  }
42
51
  ])
43
52
  })
@@ -49,11 +58,16 @@ const broker = brokerBuilder.create(async({ zod, data, setMessages }) => {
49
58
  setMessages([
50
59
  {
51
60
  role: 'user',
52
- content: [
53
- 'I have the following indexes',
54
- `${JSON.stringify(indexes)}`,
55
- `Please help me analyze which index "${question}" might belong to`,
56
- 'And sort by relevance from high to low with a score ranging from 0 to 1'
61
+ contents: [
62
+ {
63
+ type: 'text',
64
+ content: paragraph([
65
+ 'I have the following indexes',
66
+ `${JSON.stringify(indexes)}`,
67
+ `Please help me analyze which index "${question}" might belong to`,
68
+ 'And sort by relevance from high to low with a score ranging from 0 to 1'
69
+ ])
70
+ }
57
71
  ]
58
72
  }
59
73
  ])
@@ -1,5 +1,5 @@
1
1
  import { BedrockRuntimeClient, InvokeModelCommand } from '@aws-sdk/client-bedrock-runtime'
2
- import { CtoD, validateToJsonSchema, AnthropicChatDataGenerator, plugins } from '../lib/index.js'
2
+ import { paragraph, CtoD, validateToJsonSchema, AnthropicChatDataGenerator, plugins } from '../lib/index.js'
3
3
 
4
4
  /**
5
5
  * @test npx esno ./examples/aws-bedrock
@@ -67,11 +67,16 @@ const broker = brokerBuilder.create(async ({ zod, data, setMessages }) => {
67
67
  setMessages([
68
68
  {
69
69
  role: 'user',
70
- content: [
71
- 'I have the following indexes',
72
- `${JSON.stringify(indexes)}`,
73
- `Please help me analyze which index "${question}" might belong to`,
74
- 'And sort by relevance from high to low with a score ranging from 0 to 1'
70
+ contents: [
71
+ {
72
+ type: 'text',
73
+ content: paragraph([
74
+ 'I have the following indexes',
75
+ `${JSON.stringify(indexes)}`,
76
+ `Please help me analyze which index "${question}" might belong to`,
77
+ 'And sort by relevance from high to low with a score ranging from 0 to 1'
78
+ ])
79
+ }
75
80
  ]
76
81
  }
77
82
  ])
@@ -1,6 +1,6 @@
1
1
  import fs from 'fs'
2
2
  import { GoogleGenAI } from '@google/genai'
3
- import { CtoD, GoogleCtodService, plugins } from '../lib/index.js'
3
+ import { paragraph, CtoD, GoogleCtodService, plugins } from '../lib/index.js'
4
4
 
5
5
  /**
6
6
  * @test npx esno ./examples/google.ts
@@ -53,11 +53,16 @@ const broker = brokerBuilder.create(async({ zod, data, setMessages }) => {
53
53
  setMessages([
54
54
  {
55
55
  role: 'user',
56
- content: [
57
- 'I have the following indexes',
58
- `${JSON.stringify(indexes)}`,
59
- `Please help me analyze which index "${question}" might belong to`,
60
- 'And sort by relevance from high to low with a score ranging from 0 to 1'
56
+ contents: [
57
+ {
58
+ type: 'text',
59
+ content: paragraph([
60
+ 'I have the following indexes',
61
+ `${JSON.stringify(indexes)}`,
62
+ `Please help me analyze which index "${question}" might belong to`,
63
+ 'And sort by relevance from high to low with a score ranging from 0 to 1'
64
+ ])
65
+ }
61
66
  ]
62
67
  }
63
68
  ])
@@ -1,5 +1,5 @@
1
1
  import fs from 'fs'
2
- import { CtoD, OpenAICtodService, plugins } from '../lib/index.js'
2
+ import { CtoD, OpenAICtodService, plugins, paragraph } from '../lib/index.js'
3
3
 
4
4
  /**
5
5
  * @test npx esno ./examples/openai.ts
@@ -45,11 +45,16 @@ const broker = brokerBuilder.create(async({ zod, data, setMessages }) => {
45
45
  setMessages([
46
46
  {
47
47
  role: 'user',
48
- content: [
49
- 'I have the following indexes',
50
- `${JSON.stringify(indexes)}`,
51
- `Please help me analyze which index "${question}" might belong to`,
52
- 'And sort by relevance from high to low with a score ranging from 0 to 1'
48
+ contents: [
49
+ {
50
+ type: 'text',
51
+ content: paragraph([
52
+ 'I have the following indexes',
53
+ `${JSON.stringify(indexes)}`,
54
+ `Please help me analyze which index "${question}" might belong to`,
55
+ 'And sort by relevance from high to low with a score ranging from 0 to 1'
56
+ ])
57
+ }
53
58
  ]
54
59
  }
55
60
  ])
package/examples/x.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import fs from 'fs'
2
- import { CtoD, XCtodService, plugins } from '../lib/index.js'
2
+ import { CtoD, XCtodService, plugins, paragraph } from '../lib/index.js'
3
3
 
4
4
  /**
5
5
  * @test npx esno ./examples/x.ts
@@ -45,11 +45,16 @@ const broker = brokerBuilder.create(async({ zod, data, setMessages }) => {
45
45
  setMessages([
46
46
  {
47
47
  role: 'user',
48
- content: [
49
- 'I have the following indexes',
50
- `${JSON.stringify(indexes)}`,
51
- `Please help me analyze which index "${question}" might belong to`,
52
- 'And sort by relevance from high to low with a score ranging from 0 to 1'
48
+ contents: [
49
+ {
50
+ type: 'text',
51
+ content: paragraph([
52
+ 'I have the following indexes',
53
+ `${JSON.stringify(indexes)}`,
54
+ `Please help me analyze which index "${question}" might belong to`,
55
+ 'And sort by relevance from high to low with a score ranging from 0 to 1'
56
+ ])
57
+ }
53
58
  ]
54
59
  }
55
60
  ])
@@ -5,11 +5,18 @@ import { Translator, TranslatorParams } from '../core/translator.js'
5
5
  import { ValidateCallback, ValidateCallbackOutputs, validateToJsonSchema } from '../utils/validate.js'
6
6
  import { ParserError } from '../utils/error.js'
7
7
  import { z } from 'zod'
8
+ import { CtoD } from '../ctod.js'
9
+
10
+ export type PolymorphicMessage = {
11
+ type: 'text' | 'image'
12
+ content: string
13
+ }
8
14
 
9
15
  export type Message = {
10
16
  role: 'system' | 'user' | 'assistant' | (string & Record<string, unknown>)
11
17
  name?: string
12
- content: string
18
+ content?: string
19
+ contents?: PolymorphicMessage[]
13
20
  }
14
21
 
15
22
  export type ChatBrokerHooks<
@@ -38,7 +45,11 @@ export type ChatBrokerHooks<
38
45
  output: O
39
46
  }
40
47
  messages: Message[]
41
- setPreMessages: (messages: (Omit<Message, 'content'> & { content: string | string[] })[]) => void
48
+ setPreMessages: (messages: (
49
+ Omit<Message, 'content'>
50
+ & { content?: string | string[] }
51
+ & { contents?: PolymorphicMessage[] }
52
+ )[]) => void
42
53
  changeMessages: (messages: Message[]) => void
43
54
  changeOutputSchema: (output: O) => void
44
55
  }
@@ -213,6 +224,15 @@ export class ChatBroker<
213
224
  }
214
225
  }
215
226
 
227
+ cloneFrom(ctod: CtoD<any, any>) {
228
+ const newParams = structuredClone(this.params)
229
+ newParams.request = ctod.params.request
230
+ if (ctod.params.plugins) {
231
+ newParams.plugins = ctod.params.plugins
232
+ }
233
+ return new ChatBroker(newParams)
234
+ }
235
+
216
236
  requestWithId<T extends Translator<S, O>>(data: T['__schemeType']): {
217
237
  id: string
218
238
  request: Promise<T['__outputType']>
package/lib/ctod.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { ChatBroker, Message, Params as ChatBrokerParams, ChatBrokerHooks, RequestContext } from './broker/chat.js'
1
+ import { PolymorphicMessage, ChatBroker, Message, Params as ChatBrokerParams, ChatBrokerHooks, RequestContext } from './broker/chat.js'
2
2
  import { ChatBrokerPlugin } from './core/plugin.js'
3
3
  import * as z from 'zod'
4
4
 
@@ -29,7 +29,11 @@ export class CtoD<
29
29
  send: (data: PS[K]['__receiveData']) => void
30
30
  }
31
31
  }
32
- setMessages: (messages: (Omit<Message, 'content'> & { content: string | string[] })[]) => void
32
+ setMessages: (messages: (
33
+ Omit<Message, 'content'>
34
+ & { content?: string | string[] }
35
+ & { contents?: PolymorphicMessage[] }
36
+ )[]) => void
33
37
  metadata: Map<string, any>
34
38
  }) => Promise<O>) => {
35
39
  return new ChatBroker<
@@ -52,7 +56,8 @@ export class CtoD<
52
56
  changeMessages(messages.map(e => {
53
57
  return {
54
58
  role: e.role,
55
- content: Array.isArray(e.content) ? e.content.join('\n') : e.content
59
+ content: Array.isArray(e.content) ? e.content.join('\n') : e.content,
60
+ contents: e.contents
56
61
  }
57
62
  }))
58
63
  },
package/lib/index.ts CHANGED
@@ -4,6 +4,7 @@ export * as chineseConverter from './utils/chinese-conv.js'
4
4
  export { CtoD } from './ctod.js'
5
5
  export { validateToJsonSchema } from './utils/validate.js'
6
6
  export { parseJSONStream } from './utils/json.js'
7
+ export { paragraph } from './utils/paragraph.js'
7
8
  export { OpenAICtodService } from './service/openai/index.js'
8
9
  export { LlamaCppCtodService } from './service/llama-cpp/index.js'
9
10
  export { GoogleCtodService } from './service/google/index.js'
@@ -22,3 +23,4 @@ export { Translator } from './core/translator.js'
22
23
  export type { ValidateCallback } from './utils/validate.js'
23
24
  export type { TranslatorParams } from './core/translator.js'
24
25
  export type { ChatGPTMessage } from './service/openai/chat.js'
26
+ export type { PolymorphicMessage } from './broker/chat.js'
@@ -1,10 +1,13 @@
1
1
  import { AnthropicCtodService } from './index.js'
2
+ import { flow } from 'power-helper'
3
+ import { PolymorphicMessage } from '../../broker/chat.js'
2
4
 
3
5
  type AnthropicSdk = AnthropicCtodService['anthropicSdk']
4
6
 
5
7
  export type Message = {
6
8
  role: string
7
- content: string
9
+ content?: string
10
+ contents?: PolymorphicMessage[]
8
11
  }
9
12
 
10
13
  export type Config = {
@@ -30,8 +33,66 @@ export class AnthropicChatDataGenerator {
30
33
 
31
34
  private translateMessages(messages: any[]) {
32
35
  return {
33
- system: messages.find(e => e.role === 'system')?.content,
34
- messages: messages.filter(e => e.role !== 'system')
36
+ system: flow.run(() => {
37
+ let systemMessage = messages.find(e => e.role === 'system')
38
+ let output = ''
39
+ if (systemMessage) {
40
+ if (systemMessage.content) {
41
+ output += systemMessage.content
42
+ }
43
+ if (systemMessage.contents) {
44
+ for (let contentBlock of systemMessage.contents) {
45
+ if (contentBlock.type === 'text') {
46
+ output += `\n${contentBlock.content}`
47
+ }
48
+ }
49
+ }
50
+ }
51
+ return output
52
+ }),
53
+ messages: messages.filter(e => e.role !== 'system').map(e => {
54
+ const output: any[] = []
55
+ if (e.content) {
56
+ output.push({
57
+ type: 'text',
58
+ text: e.content
59
+ })
60
+ }
61
+ if (e.contents) {
62
+ for (let contentBlock of e.contents) {
63
+ if (contentBlock.type === 'text') {
64
+ output.push({
65
+ type: 'text',
66
+ text: contentBlock.content
67
+ })
68
+ }
69
+ if (contentBlock.type === 'image') {
70
+ if (contentBlock.content.startsWith('http')) {
71
+ output.push({
72
+ type: 'image',
73
+ source: {
74
+ type: 'url',
75
+ url: contentBlock.content
76
+ }
77
+ })
78
+ } else {
79
+ output.push({
80
+ type: 'image',
81
+ source: {
82
+ type: 'base64',
83
+ media_type: 'image/png',
84
+ data: contentBlock.content.split(',')[1]
85
+ }
86
+ })
87
+ }
88
+ }
89
+ }
90
+ }
91
+ return {
92
+ role: e.role,
93
+ content: output
94
+ }
95
+ })
35
96
  }
36
97
  }
37
98
 
@@ -215,12 +276,13 @@ export class AnthropicChat {
215
276
  messages: Message[]
216
277
  onMessage: (_message: string) => void
217
278
  onThinking?: (_thinking: string) => void
218
- onEnd: () => void
279
+ onEnd: (_params: { isManualCancelled: boolean }) => void
219
280
  onError: (_error: any) => void
220
281
  }) {
282
+ let isManualCancelled = false
221
283
  let stream: Extract<Awaited<ReturnType<typeof anthropic.messages.create>>, { controller: any }> | null = null
222
- const anthropic = this.anthropic.anthropicSdk
223
284
  const { onThinking, onMessage, onEnd, onError } = params
285
+ const anthropic = this.anthropic.anthropicSdk
224
286
  const body = this.dataGenerator.createTalkStreamBody(params.messages)
225
287
  const performStreamedChat = async () => {
226
288
  try {
@@ -238,14 +300,18 @@ export class AnthropicChat {
238
300
  }
239
301
  }
240
302
  }
241
- onEnd()
303
+ onEnd({
304
+ isManualCancelled
305
+ })
242
306
  } catch (error) {
243
307
  onError(error)
244
308
  }
245
309
  }
246
310
  performStreamedChat()
247
311
  return {
312
+ isManualCancelled: () => isManualCancelled,
248
313
  cancel: () => {
314
+ isManualCancelled = true
249
315
  const int = setInterval(() => {
250
316
  if (stream && stream.controller) {
251
317
  stream.controller.abort()
@@ -32,12 +32,22 @@ export class AnthropicCtodService {
32
32
  : e.content.map((content) => {
33
33
  if (content.type === 'image_url') {
34
34
  const url = content.image_url?.url || ''
35
- return {
36
- type: 'image',
37
- source: {
38
- type: 'base64',
39
- media_type: url.slice(5).split(';')[0],
40
- data: url.split(',')[1]
35
+ if (url.startsWith('http')) {
36
+ return {
37
+ type: 'image',
38
+ source: {
39
+ type: url,
40
+ url: url
41
+ }
42
+ }
43
+ } else {
44
+ return {
45
+ type: 'image',
46
+ source: {
47
+ type: 'base64',
48
+ media_type: url.slice(5).split(';')[0],
49
+ data: url.split(',')[1]
50
+ }
41
51
  }
42
52
  }
43
53
  }
@@ -14,6 +14,10 @@ type Part = {
14
14
  data: string
15
15
  mimeType: string
16
16
  }
17
+ } | {
18
+ fileData: {
19
+ fileUri: string
20
+ }
17
21
  }
18
22
 
19
23
  export type GoogleMessage = {
@@ -127,11 +131,12 @@ export class GoogleChat {
127
131
  system?: string
128
132
  messages: GoogleMessage[]
129
133
  onMessage: (_message: string) => void
130
- onEnd: () => void
134
+ onEnd: (_params: { isManualCancelled: boolean }) => void
131
135
  onThinking?: (_thinking: string) => void
132
136
  onError: (_error: any) => void
133
137
  }) {
134
138
  const state = {
139
+ isManualCancelled: false,
135
140
  controller: new AbortController()
136
141
  }
137
142
  const model = this.google.googleGenAI.models.generateContentStream({
@@ -166,10 +171,14 @@ export class GoogleChat {
166
171
  }
167
172
  }
168
173
  }
169
- params.onEnd()
174
+ params.onEnd({
175
+ isManualCancelled: state.isManualCancelled
176
+ })
170
177
  } catch (error) {
171
178
  if (state.controller.signal.aborted) {
172
- params.onEnd()
179
+ params.onEnd({
180
+ isManualCancelled: state.isManualCancelled
181
+ })
173
182
  } else {
174
183
  throw error
175
184
  }
@@ -179,7 +188,9 @@ export class GoogleChat {
179
188
  params.onError(error)
180
189
  })
181
190
  return {
191
+ isManualCancelled: () => state.isManualCancelled,
182
192
  cancel: () => {
193
+ state.isManualCancelled = true
183
194
  state.controller.abort()
184
195
  }
185
196
  }
@@ -1,12 +1,13 @@
1
1
  import { validateToJsonSchema } from '../../utils/validate.js'
2
2
  import { GoogleMessage, GoogleChat, Config } from './chat.js'
3
3
  import { GoogleImagesGeneration } from './images-generation.js'
4
+ import { OpenAIChat } from '../openai/chat.js'
4
5
  import type { GoogleGenAI } from '@google/genai'
5
6
 
6
7
  type GPTContent = {
7
- type: 'image_url' | 'text'
8
+ type: 'image_url' | 'text' | 'input_text' | 'input_image'
8
9
  text?: string
9
- image_url?: {
10
+ image_url?: string | {
10
11
  url: string
11
12
  detail?: string
12
13
  }
@@ -37,14 +38,21 @@ export class GoogleCtodService {
37
38
  ]
38
39
  } else if (Array.isArray(content)) {
39
40
  return content.map(({ type, image_url, text }): GoogleMessage['parts'][number] => {
40
- if (type === 'image_url') {
41
- // base64
42
- const url = image_url?.url || ''
43
- const mimeType = url.includes('data:image/png') ? 'image/png' : 'image/jpeg'
44
- return {
45
- inlineData: {
46
- data: url.split('base64,')[1] || '',
47
- mimeType
41
+ if (type === 'image_url' || type === 'input_image') {
42
+ const url = (typeof image_url === 'string' ? image_url : image_url?.url) || ''
43
+ if (url.startsWith('http')) {
44
+ return {
45
+ fileData: {
46
+ fileUri: url
47
+ }
48
+ }
49
+ } else {
50
+ const mimeType = url.includes('data:image/png') ? 'image/png' : 'image/jpeg'
51
+ return {
52
+ inlineData: {
53
+ data: url.split('base64,')[1] || '',
54
+ mimeType
55
+ }
48
56
  }
49
57
  }
50
58
  } else {
@@ -59,7 +67,18 @@ export class GoogleCtodService {
59
67
  let system = ''
60
68
  const outputMessages: GoogleMessage[] = messages.map((message) => {
61
69
  if (message.role === 'system') {
62
- system = typeof message.content === 'string' ? message.content : ''
70
+ if (typeof message.content === 'string') {
71
+ system = message.content
72
+ }
73
+ if (Array.isArray(message.content)) {
74
+ system = message.content.map(part => {
75
+ if (part.type === 'text' || part.type === 'input_text') {
76
+ return part.text || ''
77
+ } else {
78
+ return ''
79
+ }
80
+ }).join('\n')
81
+ }
63
82
  return {
64
83
  role: 'user',
65
84
  parts: []
@@ -101,7 +120,7 @@ export class GoogleCtodService {
101
120
  }
102
121
  return async (messages: any[], { schema, abortController }: any) => {
103
122
  const config = typeof params.config === 'function' ? await params.config() : params.config
104
- const context = GoogleCtodService.chatGPTMessageToGoogleChatMessage(messages)
123
+ const context = GoogleCtodService.chatGPTMessageToGoogleChatMessage(OpenAIChat.toApiMessages(messages) as GPTMessage[])
105
124
  const response = await googleGenAI.models.generateContent({
106
125
  model: params.model,
107
126
  contents: context.messages,
@@ -2,10 +2,12 @@ import { LlamaCppCtodService } from './index.js'
2
2
  import { flow, Once } from 'power-helper'
3
3
  import { s2t, t2s } from '../../utils/chinese-conv.js'
4
4
  import { Template } from '@huggingface/jinja'
5
+ import { PolymorphicMessage } from '../../broker/chat.js'
5
6
 
6
7
  type Message = {
7
8
  role: string
8
- content: string
9
+ content?: string
10
+ contents?: PolymorphicMessage[]
9
11
  }
10
12
 
11
13
  type Options = any
@@ -18,12 +20,13 @@ export type Config = {
18
20
 
19
21
  type Stream = {
20
22
  onMessage: (message: string) => void
21
- onEnd?: () => void
23
+ onEnd?: (params: { isManualCancelled: boolean }) => void
22
24
  onWarn?: (error: any) => void
23
25
  onError?: (error: any) => void
24
26
  }
25
27
 
26
28
  class Requester {
29
+ isManualCancelled = false
27
30
  private core: LlamaCppCompletion
28
31
  private streamAbortControllers: {
29
32
  id: string
@@ -139,6 +142,7 @@ class Requester {
139
142
  }
140
143
 
141
144
  cancel() {
145
+ this.isManualCancelled = true
142
146
  this.streamAbortControllers.forEach(e => e.controller.abort())
143
147
  this.streamAbortControllers = []
144
148
  }
@@ -222,7 +226,13 @@ export class LlamaCppCompletion {
222
226
  const requester = new Requester(this)
223
227
  requester.stream({
224
228
  path: 'completion',
225
- onEnd: params.onEnd || (() => null),
229
+ onEnd: () => {
230
+ if (params.onEnd) {
231
+ params.onEnd({
232
+ isManualCancelled: requester.isManualCancelled
233
+ })
234
+ }
235
+ },
226
236
  onMessage: e => {
227
237
  const message = this.config.autoConvertTraditionalChinese ? s2t(e.content) : e.content
228
238
  params.onMessage(message)
@@ -266,10 +276,22 @@ export class LlamaCppCompletion {
266
276
  ...(params.options || {}),
267
277
  response_format: params.response_format,
268
278
  messages: params.messages.map(e => {
269
- return {
279
+ const output = {
270
280
  role: e.role,
271
- content: this.config.autoConvertTraditionalChinese ? t2s(e.content) : e.content
281
+ content: ''
282
+ }
283
+ if (e.content) {
284
+ output.content = this.config.autoConvertTraditionalChinese ? t2s(e.content) : e.content
272
285
  }
286
+ if (e.contents) {
287
+ output.content += e.contents.map(item => {
288
+ if (item.type === 'text') {
289
+ return item.content
290
+ }
291
+ return ''
292
+ }).join('\n')
293
+ }
294
+ return output
273
295
  })
274
296
  }
275
297
  })
@@ -288,7 +310,13 @@ export class LlamaCppCompletion {
288
310
  const requester = new Requester(this)
289
311
  requester.stream({
290
312
  path: 'v1/chat/completions',
291
- onEnd: params.onEnd || (() => null),
313
+ onEnd: () => {
314
+ if (params.onEnd) {
315
+ params.onEnd({
316
+ isManualCancelled: requester.isManualCancelled
317
+ })
318
+ }
319
+ },
292
320
  onMessage: e => {
293
321
  let content = e.choices[0].delta.content
294
322
  if (content) {
@@ -304,7 +332,7 @@ export class LlamaCppCompletion {
304
332
  messages: params.messages.map(e => {
305
333
  return {
306
334
  role: e.role,
307
- content: this.config.autoConvertTraditionalChinese ? t2s(e.content) : e.content
335
+ content: this.config.autoConvertTraditionalChinese ? t2s(e.content || '') : e.content
308
336
  }
309
337
  })
310
338
  }
@@ -12,13 +12,13 @@ export class LlamaCppCtodService {
12
12
  talkOptions?: any
13
13
  }) {
14
14
  return async(messages: any[], { schema, onCancel }: any) => {
15
- const ll3cpp = new LlamaCppCtodService()
16
- const chat = ll3cpp.createCompletion()
15
+ const llamaCpp = new LlamaCppCtodService()
16
+ const chat = llamaCpp.createCompletion()
17
17
  const config = typeof params.config === 'function' ? await params.config() : params.config
18
18
  chat.setConfig(config)
19
19
  let formatSchema = validateToJsonSchema(schema.output)
20
20
  if (params.axios) {
21
- ll3cpp.setAxios(params.axios)
21
+ llamaCpp.setAxios(params.axios)
22
22
  }
23
23
  if (chat.config.autoConvertTraditionalChinese) {
24
24
  formatSchema = JSON.parse(t2s(JSON.stringify(formatSchema)))