@botpress/zai 2.0.8 → 2.0.11

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/e2e/utils.ts CHANGED
@@ -4,10 +4,9 @@ import fs from 'node:fs'
4
4
  import path from 'node:path'
5
5
  import { beforeAll } from 'vitest'
6
6
  import { Zai } from '../src'
7
- import { fastHash } from '../src/utils'
7
+ import { getCachedCognitiveClient } from './client'
8
8
 
9
9
  const DATA_PATH = path.join(__dirname, 'data')
10
- const CACHE_PATH = path.join(DATA_PATH, 'cache.jsonl')
11
10
  const DOC_PATH = path.join(DATA_PATH, 'botpress_docs.txt')
12
11
 
13
12
  export const getClient = () => {
@@ -18,59 +17,8 @@ export const getClient = () => {
18
17
  })
19
18
  }
20
19
 
21
- function readJSONL<T>(filePath: string, keyProperty: keyof T): Map<string, T> {
22
- const lines = fs.readFileSync(filePath, 'utf-8').split(/\r?\n/).filter(Boolean)
23
-
24
- const map = new Map<string, T>()
25
-
26
- for (const line of lines) {
27
- const obj = JSON.parse(line) as T
28
- const key = String(obj[keyProperty])
29
- map.set(key, obj)
30
- }
31
-
32
- return map
33
- }
34
-
35
- const cache: Map<string, { key: string; value: any }> = readJSONL(CACHE_PATH, 'key')
36
-
37
20
  export const getCachedClient = () => {
38
- const client = getClient()
39
-
40
- const proxy = new Proxy(client, {
41
- get(target, prop) {
42
- if (prop === 'callAction') {
43
- return async (...args: Parameters<Client['callAction']>) => {
44
- const key = fastHash(JSON.stringify(args))
45
- const cached = cache.get(key)
46
-
47
- if (cached) {
48
- return cached.value
49
- }
50
-
51
- const response = await target.callAction(...args)
52
- cache.set(key, { key, value: response })
53
-
54
- fs.appendFileSync(
55
- CACHE_PATH,
56
- JSON.stringify({
57
- key,
58
- value: response,
59
- }) + '\n'
60
- )
61
-
62
- return response
63
- }
64
- }
65
- return Reflect.get(target, prop)
66
- },
67
- })
68
-
69
- ;(proxy as any).clone = () => {
70
- return getCachedClient()
71
- }
72
-
73
- return proxy
21
+ return getCachedCognitiveClient()
74
22
  }
75
23
 
76
24
  export const getZai = () => {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@botpress/zai",
3
3
  "description": "Zui AI (zai) – An LLM utility library written on top of Zui and the Botpress API",
4
- "version": "2.0.8",
4
+ "version": "2.0.11",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
7
7
  "exports": {
@@ -23,7 +23,7 @@
23
23
  "author": "",
24
24
  "license": "ISC",
25
25
  "dependencies": {
26
- "@botpress/cognitive": "0.1.23",
26
+ "@botpress/cognitive": "0.1.25",
27
27
  "json5": "^2.2.3",
28
28
  "jsonrepair": "^3.10.0",
29
29
  "lodash-es": "^4.17.21"
@@ -33,6 +33,7 @@
33
33
  "@botpress/common": "workspace:*",
34
34
  "@botpress/vai": "workspace:*",
35
35
  "@types/lodash-es": "^4.17.12",
36
+ "diff": "^8.0.1",
36
37
  "dotenv": "^16.4.4",
37
38
  "esbuild": "^0.16.12",
38
39
  "glob": "^9.3.4",
@@ -41,7 +42,7 @@
41
42
  },
42
43
  "peerDependencies": {
43
44
  "@bpinternal/thicktoken": "^1.0.0",
44
- "@bpinternal/zui": "^0.22.5"
45
+ "@bpinternal/zui": "^1.0.0"
45
46
  },
46
47
  "engines": {
47
48
  "node": ">=18.0.0"
@@ -1,5 +1,5 @@
1
1
  import { type Client } from '@botpress/client'
2
- import { z } from '@bpinternal/zui'
2
+ import { transforms, z } from '@bpinternal/zui'
3
3
 
4
4
  import { GenerationMetadata } from '../utils'
5
5
  import { Adapter, GetExamplesProps, SaveExampleProps } from './adapter'
@@ -73,7 +73,7 @@ const TableSchema = z.object({
73
73
  const searchableColumns = ['input'] as const satisfies Array<keyof typeof TableSchema.shape> as string[]
74
74
 
75
75
  const TableJsonSchema = Object.entries(TableSchema.shape).reduce((acc, [key, value]) => {
76
- acc[key] = value.toJsonSchema()
76
+ acc[key] = transforms.toJSONSchemaLegacy(value)
77
77
  acc[key]['x-zui'] ??= {}
78
78
  acc[key]['x-zui'].searchable = searchableColumns.includes(key)
79
79
  return acc
@@ -9,15 +9,19 @@ const _Example = z.object({
9
9
  input: z.any(),
10
10
  check: z.boolean(),
11
11
  reason: z.string().optional(),
12
+ condition: z.string().optional(),
12
13
  })
13
14
 
15
+ type Example = {
16
+ input: unknown
17
+ check: boolean
18
+ reason?: string
19
+ condition?: string
20
+ }
21
+
14
22
  export type Options = {
15
23
  /** Examples to check the condition against */
16
- examples?: Array<{
17
- input: unknown
18
- check: boolean
19
- reason?: string
20
- }>
24
+ examples?: Array<Example>
21
25
  }
22
26
 
23
27
  const _Options = z.object({
@@ -88,14 +92,20 @@ Zai.prototype.check = async function (this: Zai, input: unknown, condition: stri
88
92
  }
89
93
 
90
94
  const defaultExamples = [
91
- { input: '50 Cent', check: true, reason: '50 Cent is widely recognized as a public personality.' },
95
+ {
96
+ input: '50 Cent',
97
+ check: true,
98
+ reason: '50 Cent is widely recognized as a public personality.',
99
+ condition: 'Is the input a public personality?',
100
+ },
92
101
  {
93
102
  input: ['apple', 'banana', 'carrot', 'house'],
94
103
  check: false,
95
104
  reason:
96
105
  'The list contains a house, which is not a fruit. Also, the list contains a carrot, which is a vegetable.',
106
+ condition: 'Is the input exclusively a list of fruits?',
97
107
  },
98
- ]
108
+ ] satisfies Example[]
99
109
 
100
110
  const userExamples = [
101
111
  ...examples.map((e) => ({ input: e.input, check: e.output, reason: e.explanation })),
@@ -123,8 +133,12 @@ ${END}
123
133
  `.trim()
124
134
  }
125
135
 
126
- const formatExample = (example: { input?: any; check: boolean; reason?: string }) => [
127
- { type: 'text' as const, content: formatInput(stringify(example.input ?? null), condition), role: 'user' as const },
136
+ const formatExample = (example: Example) => [
137
+ {
138
+ type: 'text' as const,
139
+ content: formatInput(stringify(example.input ?? null), example.condition ?? condition),
140
+ role: 'user' as const,
141
+ },
128
142
  {
129
143
  type: 'text' as const,
130
144
  content: formatOutput(example.check, example.reason ?? ''),
@@ -82,7 +82,7 @@ Zai.prototype.extract = async function <S extends OfType<AnyObjectOrArray>>(
82
82
  throw new Error('Schema must be either a ZuiObject or a ZuiArray<ZuiObject>')
83
83
  }
84
84
 
85
- const schemaTypescript = schema.toTypescript({ declaration: false })
85
+ const schemaTypescript = schema.toTypescriptType({ declaration: false })
86
86
  const schemaLength = tokenizer.count(schemaTypescript)
87
87
 
88
88
  options.chunkLength = Math.min(
package/src/zai.ts CHANGED
@@ -92,7 +92,7 @@ export class Zai {
92
92
 
93
93
  public constructor(config: ZaiConfig) {
94
94
  this._originalConfig = config
95
- const parsed = _ZaiConfig.parse(config)
95
+ const parsed = _ZaiConfig.parse(config) as ZaiConfig
96
96
 
97
97
  this.client = Cognitive.isCognitiveClient(parsed.client)
98
98
  ? (parsed.client as unknown as Cognitive)