@botpress/vai 0.0.1-beta.6 → 0.0.1-beta.7

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/dist/index.cjs CHANGED
@@ -134,9 +134,6 @@ function compare(name, scenarios, fn) {
134
134
  }
135
135
  __name(compare, "compare");
136
136
 
137
- // src/assertions/check.ts
138
- var import_sdk3 = require("@botpress/sdk");
139
-
140
137
  // src/context.ts
141
138
  var import_vitest = require("vitest");
142
139
  var import_suite2 = require("vitest/suite");
@@ -232,30 +229,29 @@ var asyncExpect = /* @__PURE__ */ __name((output, assertion) => {
232
229
  }, "asyncExpect");
233
230
 
234
231
  // src/utils/predictJson.ts
235
- var import_sdk2 = require("@botpress/sdk");
236
232
  var import_json5 = __toESM(require("json5"), 1);
237
- var nonEmptyString = import_sdk2.z.string().trim().min(1);
238
- var nonEmptyObject = import_sdk2.z.object({}).passthrough().refine((value) => Object.keys(value).length > 0, {
233
+ var nonEmptyString = z.string().trim().min(1);
234
+ var nonEmptyObject = z.object({}).passthrough().refine((value) => Object.keys(value).length > 0, {
239
235
  message: "Expected a non-empty object"
240
236
  });
241
- var Input = nonEmptyString.or(nonEmptyObject).or(import_sdk2.z.array(import_sdk2.z.any()));
242
- var Output = import_sdk2.z.object({
237
+ var Input = nonEmptyString.or(nonEmptyObject).or(z.array(z.any()));
238
+ var Output = z.object({
243
239
  reason: nonEmptyString.describe("A human-readable explanation of the result"),
244
- result: import_sdk2.z.any().describe(
240
+ result: z.any().describe(
245
241
  "Your best guess at the output according to the instructions provided, rooted in the context of the input and the reason above"
246
242
  )
247
243
  });
248
- var Example = import_sdk2.z.object({
244
+ var Example = z.object({
249
245
  input: Input,
250
246
  output: Output
251
247
  });
252
- var Options = import_sdk2.z.object({
253
- systemMessage: import_sdk2.z.string(),
254
- examples: import_sdk2.z.array(Example).default([]),
248
+ var Options = z.object({
249
+ systemMessage: z.string(),
250
+ examples: z.array(Example).default([]),
255
251
  input: Input,
256
252
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
257
- outputSchema: import_sdk2.z.custom((value) => typeof value === "object" && value !== null && "_def" in value),
258
- model: import_sdk2.z.string()
253
+ outputSchema: z.custom((value) => typeof value === "object" && value !== null && "_def" in value),
254
+ model: z.string()
259
255
  });
260
256
  var isValidExample = /* @__PURE__ */ __name((outputSchema) => (example) => Input.safeParse(example.input).success && Output.safeParse(example.output).success && outputSchema.safeParse(example.output.result).success, "isValidExample");
261
257
  async function predictJson(_options) {
@@ -353,7 +349,7 @@ function check(value, condition, options) {
353
349
  input: value2,
354
350
  output: { reason, result: expected }
355
351
  })),
356
- outputSchema: import_sdk3.z.boolean(),
352
+ outputSchema: z.boolean(),
357
353
  model: Context.evaluatorModel,
358
354
  input: value
359
355
  });
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/utils/zui.ts","../src/task/compare.ts","../src/utils/deferred.ts","../src/assertions/check.ts","../src/context.ts","../src/utils/asyncAssertion.ts","../src/utils/predictJson.ts","../src/assertions/extension.ts","../src/assertions/extract.ts","../src/assertions/filter.ts","../src/assertions/rate.ts","../src/hooks/setEvaluator.ts","../src/hooks/setupClient.ts"],"sourcesContent":["export { compare } from './task/compare'\n\nexport { check } from './assertions/check'\nexport { extract } from './assertions/extract'\nexport { filter } from './assertions/filter'\nexport { rate } from './assertions/rate'\n\nexport { setEvaluator } from './hooks/setEvaluator'\nexport { setupClient } from './hooks/setupClient'\n","import sdk from '@botpress/sdk'\n\nexport const z = sdk.z\n","import { z as Z } from '@botpress/sdk'\nimport { z } from '../utils/zui'\n\nimport { TestFunction } from 'vitest'\nimport { createTaskCollector, getCurrentSuite } from 'vitest/suite'\nimport { TestMetadata } from '../context'\nimport { Deferred } from '../utils/deferred'\n\nconst scenarioId = z\n .string()\n .trim()\n .min(1, 'Scenario ID/name must not be empty')\n .max(50, 'Scenario ID/name is too long')\n\nexport type ScenarioLike = Z.infer<typeof ScenarioLike>\nconst ScenarioLike = z.union([\n scenarioId,\n z.object({ name: scenarioId }).passthrough(),\n z.object({ id: scenarioId }).passthrough()\n])\n\nconst getScenarioName = (scenario: ScenarioLike) =>\n (typeof scenario === 'string' ? scenario : 'name' in scenario ? scenario?.name : scenario?.id) as string\n\nconst scenarioArgs = z\n .array(ScenarioLike)\n .min(2, 'You need at least two scenarios to compare')\n .max(10, 'You can only compare up to 10 scenarios')\n .refine((scenarios) => {\n const set = new Set<string>()\n scenarios.forEach((scenario) => set.add(getScenarioName(scenario)))\n return set.size === scenarios.length\n }, 'Scenarios names must be unique')\n\nexport function compare<T extends ReadonlyArray<ScenarioLike>>(\n name: string | Function,\n scenarios: T,\n fn?: TestFunction<{\n scenario: T[number]\n }>\n) {\n scenarios = scenarioArgs.parse(scenarios) as unknown as T\n\n return createTaskCollector((_name, fn, timeout) => {\n const currentSuite = getCurrentSuite()\n\n let completedCount = 0\n const finished = new Deferred<void>()\n\n for (const scenario of scenarios) {\n const key = getScenarioName(scenario)\n\n currentSuite.task(key, {\n meta: {\n scenario: key,\n isVaiTest: true\n } satisfies TestMetadata,\n handler: async (context) => {\n const extendedContext = Object.freeze({\n scenario\n })\n context.onTestFinished(() => {\n if (++completedCount === scenarios.length) {\n finished.resolve()\n }\n })\n\n await fn({ ...context, ...extendedContext })\n },\n timeout: timeout ?? 10_000\n })\n }\n })(name, fn)\n}\n","export class Deferred<T> {\n promise: Promise<T>\n private _resolve!: (value: T | PromiseLike<T>) => void\n private _reject!: (reason?: unknown) => void\n\n constructor() {\n this.promise = new Promise<T>((resolve, reject) => {\n this._resolve = resolve\n this._reject = reject\n })\n }\n\n resolve(value: T | PromiseLike<T>): void {\n this._resolve(value)\n }\n\n reject(reason?: unknown): void {\n this._reject(reason)\n }\n}\n","import { z } from '@botpress/sdk'\nimport { Context } from '../context'\nimport { asyncExpect } from '../utils/asyncAssertion'\nimport { Input, predictJson } from '../utils/predictJson'\nimport { makeToMatchInlineSnapshot, toAssertion } from './extension'\n\nexport type CheckOptions<T> = {\n examples?: { value: T; expected: boolean; reason: string }[]\n}\n\nexport function check<T extends Input>(value: T, condition: string, options?: CheckOptions<T>) {\n const promise = predictJson({\n systemMessage: `Check that the value meets the condition: ${condition}`,\n examples: options?.examples?.map(({ value, reason, expected }) => ({\n input: value,\n output: { reason, result: expected }\n })),\n outputSchema: z.boolean(),\n model: Context.evaluatorModel,\n input: value\n })\n\n return {\n ...toAssertion(promise),\n toBe: (expected: boolean) => asyncExpect(promise, (expect) => expect.toEqual(expected)),\n toMatchInlineSnapshot: makeToMatchInlineSnapshot(promise)\n }\n}\n","import type { Client } from '@botpress/client'\nimport { onTestFinished } from 'vitest'\nimport { getCurrentTest } from 'vitest/suite'\nimport { Models } from './models'\n\nexport type EvaluatorModel = (typeof Models)[number]['id']\n\nexport type TestMetadata = {\n isVaiTest: boolean\n scenario?: string\n evaluatorModel?: EvaluatorModel\n}\n\nconst getTestMetadata = (): TestMetadata => {\n const test = getCurrentTest()\n return (test?.meta ?? {\n isVaiTest: false\n }) as TestMetadata\n}\n\nclass VaiContext {\n #client: Client | null = null\n #wrapError = false\n\n get wrapError() {\n return this.#wrapError\n }\n\n get client() {\n if (!this.#client) {\n throw new Error('Botpress client is not set')\n }\n\n return this.#client\n }\n\n get evaluatorModel(): EvaluatorModel {\n return getTestMetadata().evaluatorModel ?? 'openai__gpt-4o-mini-2024-07-18'\n }\n\n get scenario() {\n return getTestMetadata().scenario\n }\n\n get isVaiTest() {\n return getTestMetadata().isVaiTest\n }\n\n setClient(cognitive: Client) {\n this.#client = cognitive\n }\n\n swallowErrors() {\n if (!getCurrentTest()) {\n throw new Error('cancelBail is a Vitest hook and must be called within a test')\n }\n\n this.#wrapError = true\n onTestFinished(() => {\n this.#wrapError = false\n })\n }\n}\n\nexport const Context = new VaiContext()\n","import { Assertion, expect } from 'vitest'\nimport { getCurrentTest } from 'vitest/suite'\nimport { Context } from '../context'\nimport { Output } from './predictJson'\n\nexport class AsyncExpectError<T> extends Error {\n constructor(message: string, public readonly output: Output<T>) {\n super(message)\n this.name = 'AsyncExpectError'\n }\n}\n\nconst getErrorMessages = (e: unknown): string => {\n if (e instanceof Error) {\n return e.message\n } else if (typeof e === 'string') {\n return e\n } else if (typeof e === 'object' && e !== null) {\n return JSON.stringify(e)\n }\n\n return `Unknown error: ${e}`\n}\n\nexport const asyncExpect = <T>(output: Promise<Output<T>>, assertion: (assert: Assertion<T>) => void) => {\n const promise = output.then((x) => {\n try {\n assertion(expect(x.result, x.reason))\n } catch (e: unknown) {\n if (Context.wrapError) {\n return new AsyncExpectError<T>(getErrorMessages(e), x)\n }\n throw e\n }\n return x\n })\n getCurrentTest()!.promises ??= []\n getCurrentTest()!.promises!.push(promise)\n return promise\n}\n","import { z, type ZodSchema } from '@botpress/sdk'\nimport JSON5 from 'json5'\nimport { Context } from '../context'\nimport { llm } from '../sdk-interfaces/llm/generateContent'\n\nconst nonEmptyString = z.string().trim().min(1)\nconst nonEmptyObject = z\n .object({})\n .passthrough()\n .refine((value) => Object.keys(value).length > 0, {\n message: 'Expected a non-empty object'\n })\n\nexport type Input = z.infer<typeof Input>\nconst Input = nonEmptyString.or(nonEmptyObject).or(z.array(z.any()))\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type Output<T = any> = z.infer<typeof Output> & { result: T }\nconst Output = z.object({\n reason: nonEmptyString.describe('A human-readable explanation of the result'),\n result: z\n .any()\n .describe(\n 'Your best guess at the output according to the instructions provided, rooted in the context of the input and the reason above'\n )\n})\n\ntype Example = z.infer<typeof Example>\nconst Example = z.object({\n input: Input,\n output: Output\n})\n\ntype InputOptions<T extends ZodSchema = ZodSchema> = z.input<typeof Options> & { outputSchema: T }\ntype Options = z.infer<typeof Options>\nconst Options = z.object({\n systemMessage: z.string(),\n examples: z.array(Example).default([]),\n input: Input,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n outputSchema: z.custom<ZodSchema<any>>((value) => typeof value === 'object' && value !== null && '_def' in value),\n model: z.string()\n})\n\ntype Message = {\n role: 'user' | 'assistant' | 'system'\n content: string\n}\n\nconst isValidExample =\n (outputSchema: ZodSchema) =>\n (example: Example): example is Example =>\n Input.safeParse(example.input).success &&\n Output.safeParse(example.output).success &&\n outputSchema.safeParse(example.output.result).success\n\nexport async function predictJson<T extends ZodSchema>(_options: InputOptions<T>): Promise<Output<z.infer<T>>> {\n const options = Options.parse(_options)\n const [integration, model] = options.model.split('__')\n\n if (!model?.length) {\n throw new Error('Invalid model')\n }\n\n const exampleMessages = options.examples\n .filter(isValidExample(options.outputSchema))\n .flatMap(({ input, output }) => [\n { role: 'user', content: JSON.stringify(input, null, 2) } satisfies Message,\n { role: 'assistant', content: JSON.stringify(output, null, 2) } satisfies Message\n ])\n\n const outputSchema = Output.extend({\n result: options.outputSchema.describe(Output.shape.result.description!)\n })\n\n const result = await Context.client.callAction({\n type: `${integration}:generateContent`,\n input: {\n systemPrompt: `\n${options.systemMessage}\n\n---\nPlease generate a JSON response with the following format:\n\\`\\`\\`typescript\n${await outputSchema.toTypescriptAsync()}\n\\`\\`\\`\n`.trim(),\n messages: [\n ...exampleMessages,\n {\n role: 'user',\n content: JSON.stringify(options.input, null, 2)\n }\n ],\n temperature: 0,\n responseFormat: 'json_object',\n model: { id: model! }\n } satisfies llm.generateContent.Input\n })\n\n const output = result.output as llm.generateContent.Output\n\n if (!output.choices.length || typeof output.choices?.[0]?.content !== 'string') {\n throw new Error('Invalid response from the model')\n }\n\n const json = output.choices[0].content.trim()\n\n if (!json.length) {\n throw new Error('No response from the model')\n }\n\n return outputSchema.parse(JSON5.parse(json)) as Output<z.infer<T>>\n}\n","import json5 from 'json5'\nimport { expect } from 'vitest'\nimport { getCurrentTest } from 'vitest/suite'\n\nimport { asyncExpect } from '../utils/asyncAssertion'\nimport { Output } from '../utils/predictJson'\n\nexport type ExtendedPromise<T> = PromiseLike<Output<T>> & {\n value: PromiseLike<T>\n}\n\nexport const toAssertion = <T>(promise: Promise<Output<T>>): ExtendedPromise<T> => {\n return {\n then: promise.then.bind(promise),\n value: promise.then((value) => value.result)\n }\n}\n\nexport const makeToMatchInlineSnapshot =\n <T>(promise: Promise<Output<T>>) =>\n async (expected?: string) => {\n const stack = new Error().stack!.split('\\n')[2]\n const newStack = `\nat __INLINE_SNAPSHOT__ (node:internal/process/task_queues:1:1)\nat randomLine (node:internal/process/task_queues:1:1)\n${stack}\n`.trim()\n\n const obj = json5.parse(expected ?? '\"\"')\n const expectation = asyncExpect(promise, (expect) => expect.toMatchObject(obj)).catch(() => {\n // we swallow the error here, as we're going to throw a new one with the correct stack\n // this is just to make vitest happy and show a nice error message\n })\n\n try {\n expect((await promise).result).toMatchObject(obj)\n } catch (err) {\n const newError = new Error()\n newError.stack = newStack\n\n expect.getState().snapshotState.match({\n isInline: true,\n received: (await promise).result,\n testName: getCurrentTest()!.name,\n error: newError,\n inlineSnapshot: expected\n })\n }\n\n return expectation\n }\n","import { z as Z } from '@botpress/sdk'\n\nimport { Context } from '../context'\nimport { asyncExpect } from '../utils/asyncAssertion'\nimport { Input, predictJson } from '../utils/predictJson'\nimport { makeToMatchInlineSnapshot, toAssertion } from './extension'\n\nexport type ExtractOptions<T, S> = {\n description?: string\n examples?: { value: T; extracted: S; reason: string }[]\n}\n\nexport function extract<T extends Input, S extends Z.AnyZodObject>(\n value: T,\n shape: S,\n options?: ExtractOptions<T, Z.infer<S>>\n) {\n const additionalMessage = options?.description\n ? `\\nIn order to extract the right information, follow these instructions:\\n${options.description}\\n`\n : ''\n const promise = predictJson({\n systemMessage:\n 'From the given input, extract the required information into the requested format.' + additionalMessage.trim(),\n examples: options?.examples?.map(({ value, reason, extracted }) => ({\n input: value,\n output: { reason, result: extracted }\n })),\n outputSchema: shape,\n model: Context.evaluatorModel,\n input: value\n })\n\n return {\n ...toAssertion(promise),\n toBe: (expected: Z.infer<S>) => asyncExpect(promise, (expect) => expect.toEqual(expected)),\n toMatchObject: (expected: Partial<Z.infer<S>>) => asyncExpect(promise, (expect) => expect.toMatchObject(expected)),\n toMatchInlineSnapshot: makeToMatchInlineSnapshot(promise)\n }\n}\n","import { z } from '../utils/zui'\n\nimport { Context } from '../context'\nimport { asyncExpect } from '../utils/asyncAssertion'\nimport { predictJson } from '../utils/predictJson'\nimport { makeToMatchInlineSnapshot, toAssertion } from './extension'\n\nexport type FilterOptions<T> = {\n examples?: { value: T; reason: string; keep: boolean }[]\n}\n\nexport function filter<U>(values: U[], condition: string, options?: FilterOptions<U>) {\n const mappedValues = values.map((_, idx) =>\n z.object({\n index: z.literal(idx),\n reason: z.string(),\n keep: z.boolean()\n })\n )\n\n const input = values.map((value, idx) => ({\n index: idx,\n value\n }))\n\n const schema = z\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n .tuple(mappedValues as any)\n .describe(\n 'An array of the objects with the index and a boolean value indicating if the object should be kept or not'\n )\n\n const promise = predictJson({\n systemMessage: `\nBased on the following qualification criteria, you need to filter the given list of objects.\nCiteria: ${condition}\n\n---\nYou need to return an array of objects with the index and a boolean value indicating if the object should be kept or not.\n`.trim(),\n examples: options?.examples\n ? [\n {\n input: options?.examples?.map((v, index) => ({\n index,\n value: v.value\n })),\n output: {\n reason: 'Here are some examples',\n result: options?.examples?.map((v, idx) => ({\n index: idx,\n reason: v.reason,\n keep: v.keep\n }))\n }\n }\n ]\n : undefined,\n outputSchema: schema,\n model: Context.evaluatorModel,\n input\n }).then((x) => {\n const results = schema.parse(x.result) as { index: number; keep: boolean }[]\n return {\n result: values.filter((_, idx) => results.find((r) => r.index === idx)?.keep),\n reason: x.reason\n }\n })\n\n return {\n ...toAssertion(promise),\n toBe: (expected: U[]) => asyncExpect(promise, (expect) => expect.toEqual(expected)),\n toMatchInlineSnapshot: makeToMatchInlineSnapshot(promise),\n toHaveNoneFiltered: () => asyncExpect(promise, (expect) => expect.toEqual(values)),\n toHaveSomeFiltered: () => asyncExpect(promise, (expect) => expect.not.toEqual(values)),\n toBeEmpty: () => asyncExpect(promise, (expect) => expect.toHaveLength(0)),\n length: {\n toBe: (expected: number) => asyncExpect(promise, (expect) => expect.toHaveLength(expected)),\n toBeGreaterThanOrEqual: (expected: number) =>\n asyncExpect(promise, (expect) => expect.length.greaterThanOrEqual(expected)),\n toBeLessThanOrEqual: (expected: number) =>\n asyncExpect(promise, (expect) => expect.length.lessThanOrEqual(expected)),\n toBeBetween: (min: number, max: number) => asyncExpect(promise, (expect) => expect.length.within(min, max))\n }\n }\n}\n","import { z } from '../utils/zui'\n\nimport { Context } from '../context'\nimport { asyncExpect } from '../utils/asyncAssertion'\nimport { Input, predictJson } from '../utils/predictJson'\nimport { makeToMatchInlineSnapshot, toAssertion } from './extension'\n\nexport type RatingScore = 1 | 2 | 3 | 4 | 5\nexport type RateOptions<T> = {\n examples?: { value: T; rating: number; reason: string }[]\n}\n\nexport function rate<T extends Input>(value: T, condition: string, options?: RateOptions<T>) {\n const schema = z.number().min(1).max(5).describe('Rating score, higher is better (1 is the worst, 5 is the best)')\n const promise = predictJson({\n systemMessage: `Based on the following qualification criteria, you need to rate the given situation from a score of 1 to 5.\\nScoring: 1 is the worst score, 5 is the best score possible.\\nCriteria: ${condition}`,\n examples: options?.examples?.map(({ value, reason, rating }) => ({\n input: value,\n output: { reason, result: rating }\n })),\n outputSchema: schema,\n model: Context.evaluatorModel,\n input: value\n }).then((x) => {\n return {\n result: typeof x.result === 'number' ? x.result : parseInt(x.result, 10),\n reason: x.reason\n }\n })\n\n return {\n ...toAssertion(promise),\n toBe: (expected: number) => asyncExpect(promise, (expect) => expect.toEqual(expected)),\n toMatchInlineSnapshot: makeToMatchInlineSnapshot(promise),\n toBeGreaterThanOrEqual: (expected: RatingScore) =>\n asyncExpect(promise, (expect) => expect.toBeGreaterThanOrEqual(expected)),\n toBeLessThanOrEqual: (expected: RatingScore) =>\n asyncExpect(promise, (expect) => expect.toBeLessThanOrEqual(expected))\n }\n}\n","import { getCurrentTest } from 'vitest/suite'\nimport { EvaluatorModel, TestMetadata } from '../context'\n\nexport const setEvaluator = (model: EvaluatorModel) => {\n const test = getCurrentTest()\n\n if (!test) {\n throw new Error('setEvaluator is a Vitest hook and must be called within a test')\n }\n\n const meta = test.meta as TestMetadata\n meta.evaluatorModel = model\n}\n","import { Client } from '@botpress/client'\nimport { Context } from '../context'\n\nexport const setupClient = (client: Client) => {\n Context.setClient(client)\n}\n"],"mappings":"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","names":["sdk","fn","import_sdk","import_suite","import_vitest","import_suite","import_sdk","output","JSON5","import_json5","import_vitest","import_suite","json5","expect","value","expect","value","expect","_a","expect","value","expect","import_suite"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/utils/zui.ts","../src/task/compare.ts","../src/utils/deferred.ts","../src/context.ts","../src/utils/asyncAssertion.ts","../src/utils/predictJson.ts","../src/assertions/extension.ts","../src/assertions/check.ts","../src/assertions/extract.ts","../src/assertions/filter.ts","../src/assertions/rate.ts","../src/hooks/setEvaluator.ts","../src/hooks/setupClient.ts"],"sourcesContent":["export { compare } from './task/compare'\n\nexport { check } from './assertions/check'\nexport { extract } from './assertions/extract'\nexport { filter } from './assertions/filter'\nexport { rate } from './assertions/rate'\n\nexport { setEvaluator } from './hooks/setEvaluator'\nexport { setupClient } from './hooks/setupClient'\n","import sdk from '@botpress/sdk'\n\nexport const z = sdk.z\n","import { z as Z } from '@botpress/sdk'\nimport { z } from '../utils/zui'\n\nimport { TestFunction } from 'vitest'\nimport { createTaskCollector, getCurrentSuite } from 'vitest/suite'\nimport { TestMetadata } from '../context'\nimport { Deferred } from '../utils/deferred'\n\nconst scenarioId = z\n .string()\n .trim()\n .min(1, 'Scenario ID/name must not be empty')\n .max(50, 'Scenario ID/name is too long')\n\nexport type ScenarioLike = Z.infer<typeof ScenarioLike>\nconst ScenarioLike = z.union([\n scenarioId,\n z.object({ name: scenarioId }).passthrough(),\n z.object({ id: scenarioId }).passthrough()\n])\n\nconst getScenarioName = (scenario: ScenarioLike) =>\n (typeof scenario === 'string' ? scenario : 'name' in scenario ? scenario?.name : scenario?.id) as string\n\nconst scenarioArgs = z\n .array(ScenarioLike)\n .min(2, 'You need at least two scenarios to compare')\n .max(10, 'You can only compare up to 10 scenarios')\n .refine((scenarios) => {\n const set = new Set<string>()\n scenarios.forEach((scenario) => set.add(getScenarioName(scenario)))\n return set.size === scenarios.length\n }, 'Scenarios names must be unique')\n\nexport function compare<T extends ReadonlyArray<ScenarioLike>>(\n name: string | Function,\n scenarios: T,\n fn?: TestFunction<{\n scenario: T[number]\n }>\n) {\n scenarios = scenarioArgs.parse(scenarios) as unknown as T\n\n return createTaskCollector((_name, fn, timeout) => {\n const currentSuite = getCurrentSuite()\n\n let completedCount = 0\n const finished = new Deferred<void>()\n\n for (const scenario of scenarios) {\n const key = getScenarioName(scenario)\n\n currentSuite.task(key, {\n meta: {\n scenario: key,\n isVaiTest: true\n } satisfies TestMetadata,\n handler: async (context) => {\n const extendedContext = Object.freeze({\n scenario\n })\n context.onTestFinished(() => {\n if (++completedCount === scenarios.length) {\n finished.resolve()\n }\n })\n\n await fn({ ...context, ...extendedContext })\n },\n timeout: timeout ?? 10_000\n })\n }\n })(name, fn)\n}\n","export class Deferred<T> {\n promise: Promise<T>\n private _resolve!: (value: T | PromiseLike<T>) => void\n private _reject!: (reason?: unknown) => void\n\n constructor() {\n this.promise = new Promise<T>((resolve, reject) => {\n this._resolve = resolve\n this._reject = reject\n })\n }\n\n resolve(value: T | PromiseLike<T>): void {\n this._resolve(value)\n }\n\n reject(reason?: unknown): void {\n this._reject(reason)\n }\n}\n","import type { Client } from '@botpress/client'\nimport { onTestFinished } from 'vitest'\nimport { getCurrentTest } from 'vitest/suite'\nimport { Models } from './models'\n\nexport type EvaluatorModel = (typeof Models)[number]['id']\n\nexport type TestMetadata = {\n isVaiTest: boolean\n scenario?: string\n evaluatorModel?: EvaluatorModel\n}\n\nconst getTestMetadata = (): TestMetadata => {\n const test = getCurrentTest()\n return (test?.meta ?? {\n isVaiTest: false\n }) as TestMetadata\n}\n\nclass VaiContext {\n #client: Client | null = null\n #wrapError = false\n\n get wrapError() {\n return this.#wrapError\n }\n\n get client() {\n if (!this.#client) {\n throw new Error('Botpress client is not set')\n }\n\n return this.#client\n }\n\n get evaluatorModel(): EvaluatorModel {\n return getTestMetadata().evaluatorModel ?? 'openai__gpt-4o-mini-2024-07-18'\n }\n\n get scenario() {\n return getTestMetadata().scenario\n }\n\n get isVaiTest() {\n return getTestMetadata().isVaiTest\n }\n\n setClient(cognitive: Client) {\n this.#client = cognitive\n }\n\n swallowErrors() {\n if (!getCurrentTest()) {\n throw new Error('cancelBail is a Vitest hook and must be called within a test')\n }\n\n this.#wrapError = true\n onTestFinished(() => {\n this.#wrapError = false\n })\n }\n}\n\nexport const Context = new VaiContext()\n","import { Assertion, expect } from 'vitest'\nimport { getCurrentTest } from 'vitest/suite'\nimport { Context } from '../context'\nimport { Output } from './predictJson'\n\nexport class AsyncExpectError<T> extends Error {\n constructor(message: string, public readonly output: Output<T>) {\n super(message)\n this.name = 'AsyncExpectError'\n }\n}\n\nconst getErrorMessages = (e: unknown): string => {\n if (e instanceof Error) {\n return e.message\n } else if (typeof e === 'string') {\n return e\n } else if (typeof e === 'object' && e !== null) {\n return JSON.stringify(e)\n }\n\n return `Unknown error: ${e}`\n}\n\nexport const asyncExpect = <T>(output: Promise<Output<T>>, assertion: (assert: Assertion<T>) => void) => {\n const promise = output.then((x) => {\n try {\n assertion(expect(x.result, x.reason))\n } catch (e: unknown) {\n if (Context.wrapError) {\n return new AsyncExpectError<T>(getErrorMessages(e), x)\n }\n throw e\n }\n return x\n })\n getCurrentTest()!.promises ??= []\n getCurrentTest()!.promises!.push(promise)\n return promise\n}\n","import { z } from '../utils/zui'\nimport { type ZodSchema, z as Z } from '@botpress/sdk'\nimport JSON5 from 'json5'\nimport { Context } from '../context'\nimport { llm } from '../sdk-interfaces/llm/generateContent'\n\nconst nonEmptyString = z.string().trim().min(1)\nconst nonEmptyObject = z\n .object({})\n .passthrough()\n .refine((value) => Object.keys(value).length > 0, {\n message: 'Expected a non-empty object'\n })\n\nexport type Input = Z.infer<typeof Input>\nconst Input = nonEmptyString.or(nonEmptyObject).or(z.array(z.any()))\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type Output<T = any> = Z.infer<typeof Output> & { result: T }\nconst Output = z.object({\n reason: nonEmptyString.describe('A human-readable explanation of the result'),\n result: z\n .any()\n .describe(\n 'Your best guess at the output according to the instructions provided, rooted in the context of the input and the reason above'\n )\n})\n\ntype Example = Z.infer<typeof Example>\nconst Example = z.object({\n input: Input,\n output: Output\n})\n\ntype InputOptions<T extends ZodSchema = ZodSchema> = Z.input<typeof Options> & { outputSchema: T }\ntype Options = Z.infer<typeof Options>\nconst Options = z.object({\n systemMessage: z.string(),\n examples: z.array(Example).default([]),\n input: Input,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n outputSchema: z.custom<ZodSchema<any>>((value) => typeof value === 'object' && value !== null && '_def' in value),\n model: z.string()\n})\n\ntype Message = {\n role: 'user' | 'assistant' | 'system'\n content: string\n}\n\nconst isValidExample =\n (outputSchema: ZodSchema) =>\n (example: Example): example is Example =>\n Input.safeParse(example.input).success &&\n Output.safeParse(example.output).success &&\n outputSchema.safeParse(example.output.result).success\n\nexport async function predictJson<T extends ZodSchema>(_options: InputOptions<T>): Promise<Output<Z.infer<T>>> {\n const options = Options.parse(_options)\n const [integration, model] = options.model.split('__')\n\n if (!model?.length) {\n throw new Error('Invalid model')\n }\n\n const exampleMessages = options.examples\n .filter(isValidExample(options.outputSchema))\n .flatMap(({ input, output }) => [\n { role: 'user', content: JSON.stringify(input, null, 2) } satisfies Message,\n { role: 'assistant', content: JSON.stringify(output, null, 2) } satisfies Message\n ])\n\n const outputSchema = Output.extend({\n result: options.outputSchema.describe(Output.shape.result.description!)\n })\n\n const result = await Context.client.callAction({\n type: `${integration}:generateContent`,\n input: {\n systemPrompt: `\n${options.systemMessage}\n\n---\nPlease generate a JSON response with the following format:\n\\`\\`\\`typescript\n${await outputSchema.toTypescriptAsync()}\n\\`\\`\\`\n`.trim(),\n messages: [\n ...exampleMessages,\n {\n role: 'user',\n content: JSON.stringify(options.input, null, 2)\n }\n ],\n temperature: 0,\n responseFormat: 'json_object',\n model: { id: model! }\n } satisfies llm.generateContent.Input\n })\n\n const output = result.output as llm.generateContent.Output\n\n if (!output.choices.length || typeof output.choices?.[0]?.content !== 'string') {\n throw new Error('Invalid response from the model')\n }\n\n const json = output.choices[0].content.trim()\n\n if (!json.length) {\n throw new Error('No response from the model')\n }\n\n return outputSchema.parse(JSON5.parse(json)) as Output<Z.infer<T>>\n}\n","import json5 from 'json5'\nimport { expect } from 'vitest'\nimport { getCurrentTest } from 'vitest/suite'\n\nimport { asyncExpect } from '../utils/asyncAssertion'\nimport { Output } from '../utils/predictJson'\n\nexport type ExtendedPromise<T> = PromiseLike<Output<T>> & {\n value: PromiseLike<T>\n}\n\nexport const toAssertion = <T>(promise: Promise<Output<T>>): ExtendedPromise<T> => {\n return {\n then: promise.then.bind(promise),\n value: promise.then((value) => value.result)\n }\n}\n\nexport const makeToMatchInlineSnapshot =\n <T>(promise: Promise<Output<T>>) =>\n async (expected?: string) => {\n const stack = new Error().stack!.split('\\n')[2]\n const newStack = `\nat __INLINE_SNAPSHOT__ (node:internal/process/task_queues:1:1)\nat randomLine (node:internal/process/task_queues:1:1)\n${stack}\n`.trim()\n\n const obj = json5.parse(expected ?? '\"\"')\n const expectation = asyncExpect(promise, (expect) => expect.toMatchObject(obj)).catch(() => {\n // we swallow the error here, as we're going to throw a new one with the correct stack\n // this is just to make vitest happy and show a nice error message\n })\n\n try {\n expect((await promise).result).toMatchObject(obj)\n } catch (err) {\n const newError = new Error()\n newError.stack = newStack\n\n expect.getState().snapshotState.match({\n isInline: true,\n received: (await promise).result,\n testName: getCurrentTest()!.name,\n error: newError,\n inlineSnapshot: expected\n })\n }\n\n return expectation\n }\n","import { z } from '../utils/zui'\nimport { Context } from '../context'\nimport { asyncExpect } from '../utils/asyncAssertion'\nimport { Input, predictJson } from '../utils/predictJson'\nimport { makeToMatchInlineSnapshot, toAssertion } from './extension'\n\nexport type CheckOptions<T> = {\n examples?: { value: T; expected: boolean; reason: string }[]\n}\n\nexport function check<T extends Input>(value: T, condition: string, options?: CheckOptions<T>) {\n const promise = predictJson({\n systemMessage: `Check that the value meets the condition: ${condition}`,\n examples: options?.examples?.map(({ value, reason, expected }) => ({\n input: value,\n output: { reason, result: expected }\n })),\n outputSchema: z.boolean(),\n model: Context.evaluatorModel,\n input: value\n })\n\n return {\n ...toAssertion(promise),\n toBe: (expected: boolean) => asyncExpect(promise, (expect) => expect.toEqual(expected)),\n toMatchInlineSnapshot: makeToMatchInlineSnapshot(promise)\n }\n}\n","import { z as Z } from '@botpress/sdk'\n\nimport { Context } from '../context'\nimport { asyncExpect } from '../utils/asyncAssertion'\nimport { Input, predictJson } from '../utils/predictJson'\nimport { makeToMatchInlineSnapshot, toAssertion } from './extension'\n\nexport type ExtractOptions<T, S> = {\n description?: string\n examples?: { value: T; extracted: S; reason: string }[]\n}\n\nexport function extract<T extends Input, S extends Z.AnyZodObject>(\n value: T,\n shape: S,\n options?: ExtractOptions<T, Z.infer<S>>\n) {\n const additionalMessage = options?.description\n ? `\\nIn order to extract the right information, follow these instructions:\\n${options.description}\\n`\n : ''\n const promise = predictJson({\n systemMessage:\n 'From the given input, extract the required information into the requested format.' + additionalMessage.trim(),\n examples: options?.examples?.map(({ value, reason, extracted }) => ({\n input: value,\n output: { reason, result: extracted }\n })),\n outputSchema: shape,\n model: Context.evaluatorModel,\n input: value\n })\n\n return {\n ...toAssertion(promise),\n toBe: (expected: Z.infer<S>) => asyncExpect(promise, (expect) => expect.toEqual(expected)),\n toMatchObject: (expected: Partial<Z.infer<S>>) => asyncExpect(promise, (expect) => expect.toMatchObject(expected)),\n toMatchInlineSnapshot: makeToMatchInlineSnapshot(promise)\n }\n}\n","import { z } from '../utils/zui'\n\nimport { Context } from '../context'\nimport { asyncExpect } from '../utils/asyncAssertion'\nimport { predictJson } from '../utils/predictJson'\nimport { makeToMatchInlineSnapshot, toAssertion } from './extension'\n\nexport type FilterOptions<T> = {\n examples?: { value: T; reason: string; keep: boolean }[]\n}\n\nexport function filter<U>(values: U[], condition: string, options?: FilterOptions<U>) {\n const mappedValues = values.map((_, idx) =>\n z.object({\n index: z.literal(idx),\n reason: z.string(),\n keep: z.boolean()\n })\n )\n\n const input = values.map((value, idx) => ({\n index: idx,\n value\n }))\n\n const schema = z\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n .tuple(mappedValues as any)\n .describe(\n 'An array of the objects with the index and a boolean value indicating if the object should be kept or not'\n )\n\n const promise = predictJson({\n systemMessage: `\nBased on the following qualification criteria, you need to filter the given list of objects.\nCiteria: ${condition}\n\n---\nYou need to return an array of objects with the index and a boolean value indicating if the object should be kept or not.\n`.trim(),\n examples: options?.examples\n ? [\n {\n input: options?.examples?.map((v, index) => ({\n index,\n value: v.value\n })),\n output: {\n reason: 'Here are some examples',\n result: options?.examples?.map((v, idx) => ({\n index: idx,\n reason: v.reason,\n keep: v.keep\n }))\n }\n }\n ]\n : undefined,\n outputSchema: schema,\n model: Context.evaluatorModel,\n input\n }).then((x) => {\n const results = schema.parse(x.result) as { index: number; keep: boolean }[]\n return {\n result: values.filter((_, idx) => results.find((r) => r.index === idx)?.keep),\n reason: x.reason\n }\n })\n\n return {\n ...toAssertion(promise),\n toBe: (expected: U[]) => asyncExpect(promise, (expect) => expect.toEqual(expected)),\n toMatchInlineSnapshot: makeToMatchInlineSnapshot(promise),\n toHaveNoneFiltered: () => asyncExpect(promise, (expect) => expect.toEqual(values)),\n toHaveSomeFiltered: () => asyncExpect(promise, (expect) => expect.not.toEqual(values)),\n toBeEmpty: () => asyncExpect(promise, (expect) => expect.toHaveLength(0)),\n length: {\n toBe: (expected: number) => asyncExpect(promise, (expect) => expect.toHaveLength(expected)),\n toBeGreaterThanOrEqual: (expected: number) =>\n asyncExpect(promise, (expect) => expect.length.greaterThanOrEqual(expected)),\n toBeLessThanOrEqual: (expected: number) =>\n asyncExpect(promise, (expect) => expect.length.lessThanOrEqual(expected)),\n toBeBetween: (min: number, max: number) => asyncExpect(promise, (expect) => expect.length.within(min, max))\n }\n }\n}\n","import { z } from '../utils/zui'\n\nimport { Context } from '../context'\nimport { asyncExpect } from '../utils/asyncAssertion'\nimport { Input, predictJson } from '../utils/predictJson'\nimport { makeToMatchInlineSnapshot, toAssertion } from './extension'\n\nexport type RatingScore = 1 | 2 | 3 | 4 | 5\nexport type RateOptions<T> = {\n examples?: { value: T; rating: number; reason: string }[]\n}\n\nexport function rate<T extends Input>(value: T, condition: string, options?: RateOptions<T>) {\n const schema = z.number().min(1).max(5).describe('Rating score, higher is better (1 is the worst, 5 is the best)')\n const promise = predictJson({\n systemMessage: `Based on the following qualification criteria, you need to rate the given situation from a score of 1 to 5.\\nScoring: 1 is the worst score, 5 is the best score possible.\\nCriteria: ${condition}`,\n examples: options?.examples?.map(({ value, reason, rating }) => ({\n input: value,\n output: { reason, result: rating }\n })),\n outputSchema: schema,\n model: Context.evaluatorModel,\n input: value\n }).then((x) => {\n return {\n result: typeof x.result === 'number' ? x.result : parseInt(x.result, 10),\n reason: x.reason\n }\n })\n\n return {\n ...toAssertion(promise),\n toBe: (expected: number) => asyncExpect(promise, (expect) => expect.toEqual(expected)),\n toMatchInlineSnapshot: makeToMatchInlineSnapshot(promise),\n toBeGreaterThanOrEqual: (expected: RatingScore) =>\n asyncExpect(promise, (expect) => expect.toBeGreaterThanOrEqual(expected)),\n toBeLessThanOrEqual: (expected: RatingScore) =>\n asyncExpect(promise, (expect) => expect.toBeLessThanOrEqual(expected))\n }\n}\n","import { getCurrentTest } from 'vitest/suite'\nimport { EvaluatorModel, TestMetadata } from '../context'\n\nexport const setEvaluator = (model: EvaluatorModel) => {\n const test = getCurrentTest()\n\n if (!test) {\n throw new Error('setEvaluator is a Vitest hook and must be called within a test')\n }\n\n const meta = test.meta as TestMetadata\n meta.evaluatorModel = model\n}\n","import { Client } from '@botpress/client'\nimport { Context } from '../context'\n\nexport const setupClient = (client: Client) => {\n Context.setClient(client)\n}\n"],"mappings":"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","names":["sdk","fn","import_suite","import_vitest","import_suite","output","JSON5","import_json5","import_vitest","import_suite","json5","expect","value","expect","value","expect","_a","expect","value","expect","import_suite"]}
package/dist/index.js CHANGED
@@ -95,9 +95,6 @@ function compare(name, scenarios, fn) {
95
95
  }
96
96
  __name(compare, "compare");
97
97
 
98
- // src/assertions/check.ts
99
- import { z as z3 } from "@botpress/sdk";
100
-
101
98
  // src/context.ts
102
99
  import { onTestFinished } from "vitest";
103
100
  import { getCurrentTest } from "vitest/suite";
@@ -193,30 +190,29 @@ var asyncExpect = /* @__PURE__ */ __name((output, assertion) => {
193
190
  }, "asyncExpect");
194
191
 
195
192
  // src/utils/predictJson.ts
196
- import { z as z2 } from "@botpress/sdk";
197
193
  import JSON5 from "json5";
198
- var nonEmptyString = z2.string().trim().min(1);
199
- var nonEmptyObject = z2.object({}).passthrough().refine((value) => Object.keys(value).length > 0, {
194
+ var nonEmptyString = z.string().trim().min(1);
195
+ var nonEmptyObject = z.object({}).passthrough().refine((value) => Object.keys(value).length > 0, {
200
196
  message: "Expected a non-empty object"
201
197
  });
202
- var Input = nonEmptyString.or(nonEmptyObject).or(z2.array(z2.any()));
203
- var Output = z2.object({
198
+ var Input = nonEmptyString.or(nonEmptyObject).or(z.array(z.any()));
199
+ var Output = z.object({
204
200
  reason: nonEmptyString.describe("A human-readable explanation of the result"),
205
- result: z2.any().describe(
201
+ result: z.any().describe(
206
202
  "Your best guess at the output according to the instructions provided, rooted in the context of the input and the reason above"
207
203
  )
208
204
  });
209
- var Example = z2.object({
205
+ var Example = z.object({
210
206
  input: Input,
211
207
  output: Output
212
208
  });
213
- var Options = z2.object({
214
- systemMessage: z2.string(),
215
- examples: z2.array(Example).default([]),
209
+ var Options = z.object({
210
+ systemMessage: z.string(),
211
+ examples: z.array(Example).default([]),
216
212
  input: Input,
217
213
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
218
- outputSchema: z2.custom((value) => typeof value === "object" && value !== null && "_def" in value),
219
- model: z2.string()
214
+ outputSchema: z.custom((value) => typeof value === "object" && value !== null && "_def" in value),
215
+ model: z.string()
220
216
  });
221
217
  var isValidExample = /* @__PURE__ */ __name((outputSchema) => (example) => Input.safeParse(example.input).success && Output.safeParse(example.output).success && outputSchema.safeParse(example.output.result).success, "isValidExample");
222
218
  async function predictJson(_options) {
@@ -314,7 +310,7 @@ function check(value, condition, options) {
314
310
  input: value2,
315
311
  output: { reason, result: expected }
316
312
  })),
317
- outputSchema: z3.boolean(),
313
+ outputSchema: z.boolean(),
318
314
  model: Context.evaluatorModel,
319
315
  input: value
320
316
  });
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/utils/zui.ts","../src/task/compare.ts","../src/utils/deferred.ts","../src/assertions/check.ts","../src/context.ts","../src/utils/asyncAssertion.ts","../src/utils/predictJson.ts","../src/assertions/extension.ts","../src/assertions/extract.ts","../src/assertions/filter.ts","../src/assertions/rate.ts","../src/hooks/setEvaluator.ts","../src/hooks/setupClient.ts"],"sourcesContent":["import sdk from '@botpress/sdk'\n\nexport const z = sdk.z\n","import { z as Z } from '@botpress/sdk'\nimport { z } from '../utils/zui'\n\nimport { TestFunction } from 'vitest'\nimport { createTaskCollector, getCurrentSuite } from 'vitest/suite'\nimport { TestMetadata } from '../context'\nimport { Deferred } from '../utils/deferred'\n\nconst scenarioId = z\n .string()\n .trim()\n .min(1, 'Scenario ID/name must not be empty')\n .max(50, 'Scenario ID/name is too long')\n\nexport type ScenarioLike = Z.infer<typeof ScenarioLike>\nconst ScenarioLike = z.union([\n scenarioId,\n z.object({ name: scenarioId }).passthrough(),\n z.object({ id: scenarioId }).passthrough()\n])\n\nconst getScenarioName = (scenario: ScenarioLike) =>\n (typeof scenario === 'string' ? scenario : 'name' in scenario ? scenario?.name : scenario?.id) as string\n\nconst scenarioArgs = z\n .array(ScenarioLike)\n .min(2, 'You need at least two scenarios to compare')\n .max(10, 'You can only compare up to 10 scenarios')\n .refine((scenarios) => {\n const set = new Set<string>()\n scenarios.forEach((scenario) => set.add(getScenarioName(scenario)))\n return set.size === scenarios.length\n }, 'Scenarios names must be unique')\n\nexport function compare<T extends ReadonlyArray<ScenarioLike>>(\n name: string | Function,\n scenarios: T,\n fn?: TestFunction<{\n scenario: T[number]\n }>\n) {\n scenarios = scenarioArgs.parse(scenarios) as unknown as T\n\n return createTaskCollector((_name, fn, timeout) => {\n const currentSuite = getCurrentSuite()\n\n let completedCount = 0\n const finished = new Deferred<void>()\n\n for (const scenario of scenarios) {\n const key = getScenarioName(scenario)\n\n currentSuite.task(key, {\n meta: {\n scenario: key,\n isVaiTest: true\n } satisfies TestMetadata,\n handler: async (context) => {\n const extendedContext = Object.freeze({\n scenario\n })\n context.onTestFinished(() => {\n if (++completedCount === scenarios.length) {\n finished.resolve()\n }\n })\n\n await fn({ ...context, ...extendedContext })\n },\n timeout: timeout ?? 10_000\n })\n }\n })(name, fn)\n}\n","export class Deferred<T> {\n promise: Promise<T>\n private _resolve!: (value: T | PromiseLike<T>) => void\n private _reject!: (reason?: unknown) => void\n\n constructor() {\n this.promise = new Promise<T>((resolve, reject) => {\n this._resolve = resolve\n this._reject = reject\n })\n }\n\n resolve(value: T | PromiseLike<T>): void {\n this._resolve(value)\n }\n\n reject(reason?: unknown): void {\n this._reject(reason)\n }\n}\n","import { z } from '@botpress/sdk'\nimport { Context } from '../context'\nimport { asyncExpect } from '../utils/asyncAssertion'\nimport { Input, predictJson } from '../utils/predictJson'\nimport { makeToMatchInlineSnapshot, toAssertion } from './extension'\n\nexport type CheckOptions<T> = {\n examples?: { value: T; expected: boolean; reason: string }[]\n}\n\nexport function check<T extends Input>(value: T, condition: string, options?: CheckOptions<T>) {\n const promise = predictJson({\n systemMessage: `Check that the value meets the condition: ${condition}`,\n examples: options?.examples?.map(({ value, reason, expected }) => ({\n input: value,\n output: { reason, result: expected }\n })),\n outputSchema: z.boolean(),\n model: Context.evaluatorModel,\n input: value\n })\n\n return {\n ...toAssertion(promise),\n toBe: (expected: boolean) => asyncExpect(promise, (expect) => expect.toEqual(expected)),\n toMatchInlineSnapshot: makeToMatchInlineSnapshot(promise)\n }\n}\n","import type { Client } from '@botpress/client'\nimport { onTestFinished } from 'vitest'\nimport { getCurrentTest } from 'vitest/suite'\nimport { Models } from './models'\n\nexport type EvaluatorModel = (typeof Models)[number]['id']\n\nexport type TestMetadata = {\n isVaiTest: boolean\n scenario?: string\n evaluatorModel?: EvaluatorModel\n}\n\nconst getTestMetadata = (): TestMetadata => {\n const test = getCurrentTest()\n return (test?.meta ?? {\n isVaiTest: false\n }) as TestMetadata\n}\n\nclass VaiContext {\n #client: Client | null = null\n #wrapError = false\n\n get wrapError() {\n return this.#wrapError\n }\n\n get client() {\n if (!this.#client) {\n throw new Error('Botpress client is not set')\n }\n\n return this.#client\n }\n\n get evaluatorModel(): EvaluatorModel {\n return getTestMetadata().evaluatorModel ?? 'openai__gpt-4o-mini-2024-07-18'\n }\n\n get scenario() {\n return getTestMetadata().scenario\n }\n\n get isVaiTest() {\n return getTestMetadata().isVaiTest\n }\n\n setClient(cognitive: Client) {\n this.#client = cognitive\n }\n\n swallowErrors() {\n if (!getCurrentTest()) {\n throw new Error('cancelBail is a Vitest hook and must be called within a test')\n }\n\n this.#wrapError = true\n onTestFinished(() => {\n this.#wrapError = false\n })\n }\n}\n\nexport const Context = new VaiContext()\n","import { Assertion, expect } from 'vitest'\nimport { getCurrentTest } from 'vitest/suite'\nimport { Context } from '../context'\nimport { Output } from './predictJson'\n\nexport class AsyncExpectError<T> extends Error {\n constructor(message: string, public readonly output: Output<T>) {\n super(message)\n this.name = 'AsyncExpectError'\n }\n}\n\nconst getErrorMessages = (e: unknown): string => {\n if (e instanceof Error) {\n return e.message\n } else if (typeof e === 'string') {\n return e\n } else if (typeof e === 'object' && e !== null) {\n return JSON.stringify(e)\n }\n\n return `Unknown error: ${e}`\n}\n\nexport const asyncExpect = <T>(output: Promise<Output<T>>, assertion: (assert: Assertion<T>) => void) => {\n const promise = output.then((x) => {\n try {\n assertion(expect(x.result, x.reason))\n } catch (e: unknown) {\n if (Context.wrapError) {\n return new AsyncExpectError<T>(getErrorMessages(e), x)\n }\n throw e\n }\n return x\n })\n getCurrentTest()!.promises ??= []\n getCurrentTest()!.promises!.push(promise)\n return promise\n}\n","import { z, type ZodSchema } from '@botpress/sdk'\nimport JSON5 from 'json5'\nimport { Context } from '../context'\nimport { llm } from '../sdk-interfaces/llm/generateContent'\n\nconst nonEmptyString = z.string().trim().min(1)\nconst nonEmptyObject = z\n .object({})\n .passthrough()\n .refine((value) => Object.keys(value).length > 0, {\n message: 'Expected a non-empty object'\n })\n\nexport type Input = z.infer<typeof Input>\nconst Input = nonEmptyString.or(nonEmptyObject).or(z.array(z.any()))\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type Output<T = any> = z.infer<typeof Output> & { result: T }\nconst Output = z.object({\n reason: nonEmptyString.describe('A human-readable explanation of the result'),\n result: z\n .any()\n .describe(\n 'Your best guess at the output according to the instructions provided, rooted in the context of the input and the reason above'\n )\n})\n\ntype Example = z.infer<typeof Example>\nconst Example = z.object({\n input: Input,\n output: Output\n})\n\ntype InputOptions<T extends ZodSchema = ZodSchema> = z.input<typeof Options> & { outputSchema: T }\ntype Options = z.infer<typeof Options>\nconst Options = z.object({\n systemMessage: z.string(),\n examples: z.array(Example).default([]),\n input: Input,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n outputSchema: z.custom<ZodSchema<any>>((value) => typeof value === 'object' && value !== null && '_def' in value),\n model: z.string()\n})\n\ntype Message = {\n role: 'user' | 'assistant' | 'system'\n content: string\n}\n\nconst isValidExample =\n (outputSchema: ZodSchema) =>\n (example: Example): example is Example =>\n Input.safeParse(example.input).success &&\n Output.safeParse(example.output).success &&\n outputSchema.safeParse(example.output.result).success\n\nexport async function predictJson<T extends ZodSchema>(_options: InputOptions<T>): Promise<Output<z.infer<T>>> {\n const options = Options.parse(_options)\n const [integration, model] = options.model.split('__')\n\n if (!model?.length) {\n throw new Error('Invalid model')\n }\n\n const exampleMessages = options.examples\n .filter(isValidExample(options.outputSchema))\n .flatMap(({ input, output }) => [\n { role: 'user', content: JSON.stringify(input, null, 2) } satisfies Message,\n { role: 'assistant', content: JSON.stringify(output, null, 2) } satisfies Message\n ])\n\n const outputSchema = Output.extend({\n result: options.outputSchema.describe(Output.shape.result.description!)\n })\n\n const result = await Context.client.callAction({\n type: `${integration}:generateContent`,\n input: {\n systemPrompt: `\n${options.systemMessage}\n\n---\nPlease generate a JSON response with the following format:\n\\`\\`\\`typescript\n${await outputSchema.toTypescriptAsync()}\n\\`\\`\\`\n`.trim(),\n messages: [\n ...exampleMessages,\n {\n role: 'user',\n content: JSON.stringify(options.input, null, 2)\n }\n ],\n temperature: 0,\n responseFormat: 'json_object',\n model: { id: model! }\n } satisfies llm.generateContent.Input\n })\n\n const output = result.output as llm.generateContent.Output\n\n if (!output.choices.length || typeof output.choices?.[0]?.content !== 'string') {\n throw new Error('Invalid response from the model')\n }\n\n const json = output.choices[0].content.trim()\n\n if (!json.length) {\n throw new Error('No response from the model')\n }\n\n return outputSchema.parse(JSON5.parse(json)) as Output<z.infer<T>>\n}\n","import json5 from 'json5'\nimport { expect } from 'vitest'\nimport { getCurrentTest } from 'vitest/suite'\n\nimport { asyncExpect } from '../utils/asyncAssertion'\nimport { Output } from '../utils/predictJson'\n\nexport type ExtendedPromise<T> = PromiseLike<Output<T>> & {\n value: PromiseLike<T>\n}\n\nexport const toAssertion = <T>(promise: Promise<Output<T>>): ExtendedPromise<T> => {\n return {\n then: promise.then.bind(promise),\n value: promise.then((value) => value.result)\n }\n}\n\nexport const makeToMatchInlineSnapshot =\n <T>(promise: Promise<Output<T>>) =>\n async (expected?: string) => {\n const stack = new Error().stack!.split('\\n')[2]\n const newStack = `\nat __INLINE_SNAPSHOT__ (node:internal/process/task_queues:1:1)\nat randomLine (node:internal/process/task_queues:1:1)\n${stack}\n`.trim()\n\n const obj = json5.parse(expected ?? '\"\"')\n const expectation = asyncExpect(promise, (expect) => expect.toMatchObject(obj)).catch(() => {\n // we swallow the error here, as we're going to throw a new one with the correct stack\n // this is just to make vitest happy and show a nice error message\n })\n\n try {\n expect((await promise).result).toMatchObject(obj)\n } catch (err) {\n const newError = new Error()\n newError.stack = newStack\n\n expect.getState().snapshotState.match({\n isInline: true,\n received: (await promise).result,\n testName: getCurrentTest()!.name,\n error: newError,\n inlineSnapshot: expected\n })\n }\n\n return expectation\n }\n","import { z as Z } from '@botpress/sdk'\n\nimport { Context } from '../context'\nimport { asyncExpect } from '../utils/asyncAssertion'\nimport { Input, predictJson } from '../utils/predictJson'\nimport { makeToMatchInlineSnapshot, toAssertion } from './extension'\n\nexport type ExtractOptions<T, S> = {\n description?: string\n examples?: { value: T; extracted: S; reason: string }[]\n}\n\nexport function extract<T extends Input, S extends Z.AnyZodObject>(\n value: T,\n shape: S,\n options?: ExtractOptions<T, Z.infer<S>>\n) {\n const additionalMessage = options?.description\n ? `\\nIn order to extract the right information, follow these instructions:\\n${options.description}\\n`\n : ''\n const promise = predictJson({\n systemMessage:\n 'From the given input, extract the required information into the requested format.' + additionalMessage.trim(),\n examples: options?.examples?.map(({ value, reason, extracted }) => ({\n input: value,\n output: { reason, result: extracted }\n })),\n outputSchema: shape,\n model: Context.evaluatorModel,\n input: value\n })\n\n return {\n ...toAssertion(promise),\n toBe: (expected: Z.infer<S>) => asyncExpect(promise, (expect) => expect.toEqual(expected)),\n toMatchObject: (expected: Partial<Z.infer<S>>) => asyncExpect(promise, (expect) => expect.toMatchObject(expected)),\n toMatchInlineSnapshot: makeToMatchInlineSnapshot(promise)\n }\n}\n","import { z } from '../utils/zui'\n\nimport { Context } from '../context'\nimport { asyncExpect } from '../utils/asyncAssertion'\nimport { predictJson } from '../utils/predictJson'\nimport { makeToMatchInlineSnapshot, toAssertion } from './extension'\n\nexport type FilterOptions<T> = {\n examples?: { value: T; reason: string; keep: boolean }[]\n}\n\nexport function filter<U>(values: U[], condition: string, options?: FilterOptions<U>) {\n const mappedValues = values.map((_, idx) =>\n z.object({\n index: z.literal(idx),\n reason: z.string(),\n keep: z.boolean()\n })\n )\n\n const input = values.map((value, idx) => ({\n index: idx,\n value\n }))\n\n const schema = z\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n .tuple(mappedValues as any)\n .describe(\n 'An array of the objects with the index and a boolean value indicating if the object should be kept or not'\n )\n\n const promise = predictJson({\n systemMessage: `\nBased on the following qualification criteria, you need to filter the given list of objects.\nCiteria: ${condition}\n\n---\nYou need to return an array of objects with the index and a boolean value indicating if the object should be kept or not.\n`.trim(),\n examples: options?.examples\n ? [\n {\n input: options?.examples?.map((v, index) => ({\n index,\n value: v.value\n })),\n output: {\n reason: 'Here are some examples',\n result: options?.examples?.map((v, idx) => ({\n index: idx,\n reason: v.reason,\n keep: v.keep\n }))\n }\n }\n ]\n : undefined,\n outputSchema: schema,\n model: Context.evaluatorModel,\n input\n }).then((x) => {\n const results = schema.parse(x.result) as { index: number; keep: boolean }[]\n return {\n result: values.filter((_, idx) => results.find((r) => r.index === idx)?.keep),\n reason: x.reason\n }\n })\n\n return {\n ...toAssertion(promise),\n toBe: (expected: U[]) => asyncExpect(promise, (expect) => expect.toEqual(expected)),\n toMatchInlineSnapshot: makeToMatchInlineSnapshot(promise),\n toHaveNoneFiltered: () => asyncExpect(promise, (expect) => expect.toEqual(values)),\n toHaveSomeFiltered: () => asyncExpect(promise, (expect) => expect.not.toEqual(values)),\n toBeEmpty: () => asyncExpect(promise, (expect) => expect.toHaveLength(0)),\n length: {\n toBe: (expected: number) => asyncExpect(promise, (expect) => expect.toHaveLength(expected)),\n toBeGreaterThanOrEqual: (expected: number) =>\n asyncExpect(promise, (expect) => expect.length.greaterThanOrEqual(expected)),\n toBeLessThanOrEqual: (expected: number) =>\n asyncExpect(promise, (expect) => expect.length.lessThanOrEqual(expected)),\n toBeBetween: (min: number, max: number) => asyncExpect(promise, (expect) => expect.length.within(min, max))\n }\n }\n}\n","import { z } from '../utils/zui'\n\nimport { Context } from '../context'\nimport { asyncExpect } from '../utils/asyncAssertion'\nimport { Input, predictJson } from '../utils/predictJson'\nimport { makeToMatchInlineSnapshot, toAssertion } from './extension'\n\nexport type RatingScore = 1 | 2 | 3 | 4 | 5\nexport type RateOptions<T> = {\n examples?: { value: T; rating: number; reason: string }[]\n}\n\nexport function rate<T extends Input>(value: T, condition: string, options?: RateOptions<T>) {\n const schema = z.number().min(1).max(5).describe('Rating score, higher is better (1 is the worst, 5 is the best)')\n const promise = predictJson({\n systemMessage: `Based on the following qualification criteria, you need to rate the given situation from a score of 1 to 5.\\nScoring: 1 is the worst score, 5 is the best score possible.\\nCriteria: ${condition}`,\n examples: options?.examples?.map(({ value, reason, rating }) => ({\n input: value,\n output: { reason, result: rating }\n })),\n outputSchema: schema,\n model: Context.evaluatorModel,\n input: value\n }).then((x) => {\n return {\n result: typeof x.result === 'number' ? x.result : parseInt(x.result, 10),\n reason: x.reason\n }\n })\n\n return {\n ...toAssertion(promise),\n toBe: (expected: number) => asyncExpect(promise, (expect) => expect.toEqual(expected)),\n toMatchInlineSnapshot: makeToMatchInlineSnapshot(promise),\n toBeGreaterThanOrEqual: (expected: RatingScore) =>\n asyncExpect(promise, (expect) => expect.toBeGreaterThanOrEqual(expected)),\n toBeLessThanOrEqual: (expected: RatingScore) =>\n asyncExpect(promise, (expect) => expect.toBeLessThanOrEqual(expected))\n }\n}\n","import { getCurrentTest } from 'vitest/suite'\nimport { EvaluatorModel, TestMetadata } from '../context'\n\nexport const setEvaluator = (model: EvaluatorModel) => {\n const test = getCurrentTest()\n\n if (!test) {\n throw new Error('setEvaluator is a Vitest hook and must be called within a test')\n }\n\n const meta = test.meta as TestMetadata\n meta.evaluatorModel = model\n}\n","import { Client } from '@botpress/client'\nimport { Context } from '../context'\n\nexport const setupClient = (client: Client) => {\n Context.setClient(client)\n}\n"],"mappings":"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","names":["fn","z","getCurrentTest","getCurrentTest","z","z","output","expect","getCurrentTest","expect","getCurrentTest","value","z","expect","value","expect","_a","expect","value","expect","getCurrentTest","getCurrentTest"]}
1
+ {"version":3,"sources":["../src/utils/zui.ts","../src/task/compare.ts","../src/utils/deferred.ts","../src/context.ts","../src/utils/asyncAssertion.ts","../src/utils/predictJson.ts","../src/assertions/extension.ts","../src/assertions/check.ts","../src/assertions/extract.ts","../src/assertions/filter.ts","../src/assertions/rate.ts","../src/hooks/setEvaluator.ts","../src/hooks/setupClient.ts"],"sourcesContent":["import sdk from '@botpress/sdk'\n\nexport const z = sdk.z\n","import { z as Z } from '@botpress/sdk'\nimport { z } from '../utils/zui'\n\nimport { TestFunction } from 'vitest'\nimport { createTaskCollector, getCurrentSuite } from 'vitest/suite'\nimport { TestMetadata } from '../context'\nimport { Deferred } from '../utils/deferred'\n\nconst scenarioId = z\n .string()\n .trim()\n .min(1, 'Scenario ID/name must not be empty')\n .max(50, 'Scenario ID/name is too long')\n\nexport type ScenarioLike = Z.infer<typeof ScenarioLike>\nconst ScenarioLike = z.union([\n scenarioId,\n z.object({ name: scenarioId }).passthrough(),\n z.object({ id: scenarioId }).passthrough()\n])\n\nconst getScenarioName = (scenario: ScenarioLike) =>\n (typeof scenario === 'string' ? scenario : 'name' in scenario ? scenario?.name : scenario?.id) as string\n\nconst scenarioArgs = z\n .array(ScenarioLike)\n .min(2, 'You need at least two scenarios to compare')\n .max(10, 'You can only compare up to 10 scenarios')\n .refine((scenarios) => {\n const set = new Set<string>()\n scenarios.forEach((scenario) => set.add(getScenarioName(scenario)))\n return set.size === scenarios.length\n }, 'Scenarios names must be unique')\n\nexport function compare<T extends ReadonlyArray<ScenarioLike>>(\n name: string | Function,\n scenarios: T,\n fn?: TestFunction<{\n scenario: T[number]\n }>\n) {\n scenarios = scenarioArgs.parse(scenarios) as unknown as T\n\n return createTaskCollector((_name, fn, timeout) => {\n const currentSuite = getCurrentSuite()\n\n let completedCount = 0\n const finished = new Deferred<void>()\n\n for (const scenario of scenarios) {\n const key = getScenarioName(scenario)\n\n currentSuite.task(key, {\n meta: {\n scenario: key,\n isVaiTest: true\n } satisfies TestMetadata,\n handler: async (context) => {\n const extendedContext = Object.freeze({\n scenario\n })\n context.onTestFinished(() => {\n if (++completedCount === scenarios.length) {\n finished.resolve()\n }\n })\n\n await fn({ ...context, ...extendedContext })\n },\n timeout: timeout ?? 10_000\n })\n }\n })(name, fn)\n}\n","export class Deferred<T> {\n promise: Promise<T>\n private _resolve!: (value: T | PromiseLike<T>) => void\n private _reject!: (reason?: unknown) => void\n\n constructor() {\n this.promise = new Promise<T>((resolve, reject) => {\n this._resolve = resolve\n this._reject = reject\n })\n }\n\n resolve(value: T | PromiseLike<T>): void {\n this._resolve(value)\n }\n\n reject(reason?: unknown): void {\n this._reject(reason)\n }\n}\n","import type { Client } from '@botpress/client'\nimport { onTestFinished } from 'vitest'\nimport { getCurrentTest } from 'vitest/suite'\nimport { Models } from './models'\n\nexport type EvaluatorModel = (typeof Models)[number]['id']\n\nexport type TestMetadata = {\n isVaiTest: boolean\n scenario?: string\n evaluatorModel?: EvaluatorModel\n}\n\nconst getTestMetadata = (): TestMetadata => {\n const test = getCurrentTest()\n return (test?.meta ?? {\n isVaiTest: false\n }) as TestMetadata\n}\n\nclass VaiContext {\n #client: Client | null = null\n #wrapError = false\n\n get wrapError() {\n return this.#wrapError\n }\n\n get client() {\n if (!this.#client) {\n throw new Error('Botpress client is not set')\n }\n\n return this.#client\n }\n\n get evaluatorModel(): EvaluatorModel {\n return getTestMetadata().evaluatorModel ?? 'openai__gpt-4o-mini-2024-07-18'\n }\n\n get scenario() {\n return getTestMetadata().scenario\n }\n\n get isVaiTest() {\n return getTestMetadata().isVaiTest\n }\n\n setClient(cognitive: Client) {\n this.#client = cognitive\n }\n\n swallowErrors() {\n if (!getCurrentTest()) {\n throw new Error('cancelBail is a Vitest hook and must be called within a test')\n }\n\n this.#wrapError = true\n onTestFinished(() => {\n this.#wrapError = false\n })\n }\n}\n\nexport const Context = new VaiContext()\n","import { Assertion, expect } from 'vitest'\nimport { getCurrentTest } from 'vitest/suite'\nimport { Context } from '../context'\nimport { Output } from './predictJson'\n\nexport class AsyncExpectError<T> extends Error {\n constructor(message: string, public readonly output: Output<T>) {\n super(message)\n this.name = 'AsyncExpectError'\n }\n}\n\nconst getErrorMessages = (e: unknown): string => {\n if (e instanceof Error) {\n return e.message\n } else if (typeof e === 'string') {\n return e\n } else if (typeof e === 'object' && e !== null) {\n return JSON.stringify(e)\n }\n\n return `Unknown error: ${e}`\n}\n\nexport const asyncExpect = <T>(output: Promise<Output<T>>, assertion: (assert: Assertion<T>) => void) => {\n const promise = output.then((x) => {\n try {\n assertion(expect(x.result, x.reason))\n } catch (e: unknown) {\n if (Context.wrapError) {\n return new AsyncExpectError<T>(getErrorMessages(e), x)\n }\n throw e\n }\n return x\n })\n getCurrentTest()!.promises ??= []\n getCurrentTest()!.promises!.push(promise)\n return promise\n}\n","import { z } from '../utils/zui'\nimport { type ZodSchema, z as Z } from '@botpress/sdk'\nimport JSON5 from 'json5'\nimport { Context } from '../context'\nimport { llm } from '../sdk-interfaces/llm/generateContent'\n\nconst nonEmptyString = z.string().trim().min(1)\nconst nonEmptyObject = z\n .object({})\n .passthrough()\n .refine((value) => Object.keys(value).length > 0, {\n message: 'Expected a non-empty object'\n })\n\nexport type Input = Z.infer<typeof Input>\nconst Input = nonEmptyString.or(nonEmptyObject).or(z.array(z.any()))\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type Output<T = any> = Z.infer<typeof Output> & { result: T }\nconst Output = z.object({\n reason: nonEmptyString.describe('A human-readable explanation of the result'),\n result: z\n .any()\n .describe(\n 'Your best guess at the output according to the instructions provided, rooted in the context of the input and the reason above'\n )\n})\n\ntype Example = Z.infer<typeof Example>\nconst Example = z.object({\n input: Input,\n output: Output\n})\n\ntype InputOptions<T extends ZodSchema = ZodSchema> = Z.input<typeof Options> & { outputSchema: T }\ntype Options = Z.infer<typeof Options>\nconst Options = z.object({\n systemMessage: z.string(),\n examples: z.array(Example).default([]),\n input: Input,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n outputSchema: z.custom<ZodSchema<any>>((value) => typeof value === 'object' && value !== null && '_def' in value),\n model: z.string()\n})\n\ntype Message = {\n role: 'user' | 'assistant' | 'system'\n content: string\n}\n\nconst isValidExample =\n (outputSchema: ZodSchema) =>\n (example: Example): example is Example =>\n Input.safeParse(example.input).success &&\n Output.safeParse(example.output).success &&\n outputSchema.safeParse(example.output.result).success\n\nexport async function predictJson<T extends ZodSchema>(_options: InputOptions<T>): Promise<Output<Z.infer<T>>> {\n const options = Options.parse(_options)\n const [integration, model] = options.model.split('__')\n\n if (!model?.length) {\n throw new Error('Invalid model')\n }\n\n const exampleMessages = options.examples\n .filter(isValidExample(options.outputSchema))\n .flatMap(({ input, output }) => [\n { role: 'user', content: JSON.stringify(input, null, 2) } satisfies Message,\n { role: 'assistant', content: JSON.stringify(output, null, 2) } satisfies Message\n ])\n\n const outputSchema = Output.extend({\n result: options.outputSchema.describe(Output.shape.result.description!)\n })\n\n const result = await Context.client.callAction({\n type: `${integration}:generateContent`,\n input: {\n systemPrompt: `\n${options.systemMessage}\n\n---\nPlease generate a JSON response with the following format:\n\\`\\`\\`typescript\n${await outputSchema.toTypescriptAsync()}\n\\`\\`\\`\n`.trim(),\n messages: [\n ...exampleMessages,\n {\n role: 'user',\n content: JSON.stringify(options.input, null, 2)\n }\n ],\n temperature: 0,\n responseFormat: 'json_object',\n model: { id: model! }\n } satisfies llm.generateContent.Input\n })\n\n const output = result.output as llm.generateContent.Output\n\n if (!output.choices.length || typeof output.choices?.[0]?.content !== 'string') {\n throw new Error('Invalid response from the model')\n }\n\n const json = output.choices[0].content.trim()\n\n if (!json.length) {\n throw new Error('No response from the model')\n }\n\n return outputSchema.parse(JSON5.parse(json)) as Output<Z.infer<T>>\n}\n","import json5 from 'json5'\nimport { expect } from 'vitest'\nimport { getCurrentTest } from 'vitest/suite'\n\nimport { asyncExpect } from '../utils/asyncAssertion'\nimport { Output } from '../utils/predictJson'\n\nexport type ExtendedPromise<T> = PromiseLike<Output<T>> & {\n value: PromiseLike<T>\n}\n\nexport const toAssertion = <T>(promise: Promise<Output<T>>): ExtendedPromise<T> => {\n return {\n then: promise.then.bind(promise),\n value: promise.then((value) => value.result)\n }\n}\n\nexport const makeToMatchInlineSnapshot =\n <T>(promise: Promise<Output<T>>) =>\n async (expected?: string) => {\n const stack = new Error().stack!.split('\\n')[2]\n const newStack = `\nat __INLINE_SNAPSHOT__ (node:internal/process/task_queues:1:1)\nat randomLine (node:internal/process/task_queues:1:1)\n${stack}\n`.trim()\n\n const obj = json5.parse(expected ?? '\"\"')\n const expectation = asyncExpect(promise, (expect) => expect.toMatchObject(obj)).catch(() => {\n // we swallow the error here, as we're going to throw a new one with the correct stack\n // this is just to make vitest happy and show a nice error message\n })\n\n try {\n expect((await promise).result).toMatchObject(obj)\n } catch (err) {\n const newError = new Error()\n newError.stack = newStack\n\n expect.getState().snapshotState.match({\n isInline: true,\n received: (await promise).result,\n testName: getCurrentTest()!.name,\n error: newError,\n inlineSnapshot: expected\n })\n }\n\n return expectation\n }\n","import { z } from '../utils/zui'\nimport { Context } from '../context'\nimport { asyncExpect } from '../utils/asyncAssertion'\nimport { Input, predictJson } from '../utils/predictJson'\nimport { makeToMatchInlineSnapshot, toAssertion } from './extension'\n\nexport type CheckOptions<T> = {\n examples?: { value: T; expected: boolean; reason: string }[]\n}\n\nexport function check<T extends Input>(value: T, condition: string, options?: CheckOptions<T>) {\n const promise = predictJson({\n systemMessage: `Check that the value meets the condition: ${condition}`,\n examples: options?.examples?.map(({ value, reason, expected }) => ({\n input: value,\n output: { reason, result: expected }\n })),\n outputSchema: z.boolean(),\n model: Context.evaluatorModel,\n input: value\n })\n\n return {\n ...toAssertion(promise),\n toBe: (expected: boolean) => asyncExpect(promise, (expect) => expect.toEqual(expected)),\n toMatchInlineSnapshot: makeToMatchInlineSnapshot(promise)\n }\n}\n","import { z as Z } from '@botpress/sdk'\n\nimport { Context } from '../context'\nimport { asyncExpect } from '../utils/asyncAssertion'\nimport { Input, predictJson } from '../utils/predictJson'\nimport { makeToMatchInlineSnapshot, toAssertion } from './extension'\n\nexport type ExtractOptions<T, S> = {\n description?: string\n examples?: { value: T; extracted: S; reason: string }[]\n}\n\nexport function extract<T extends Input, S extends Z.AnyZodObject>(\n value: T,\n shape: S,\n options?: ExtractOptions<T, Z.infer<S>>\n) {\n const additionalMessage = options?.description\n ? `\\nIn order to extract the right information, follow these instructions:\\n${options.description}\\n`\n : ''\n const promise = predictJson({\n systemMessage:\n 'From the given input, extract the required information into the requested format.' + additionalMessage.trim(),\n examples: options?.examples?.map(({ value, reason, extracted }) => ({\n input: value,\n output: { reason, result: extracted }\n })),\n outputSchema: shape,\n model: Context.evaluatorModel,\n input: value\n })\n\n return {\n ...toAssertion(promise),\n toBe: (expected: Z.infer<S>) => asyncExpect(promise, (expect) => expect.toEqual(expected)),\n toMatchObject: (expected: Partial<Z.infer<S>>) => asyncExpect(promise, (expect) => expect.toMatchObject(expected)),\n toMatchInlineSnapshot: makeToMatchInlineSnapshot(promise)\n }\n}\n","import { z } from '../utils/zui'\n\nimport { Context } from '../context'\nimport { asyncExpect } from '../utils/asyncAssertion'\nimport { predictJson } from '../utils/predictJson'\nimport { makeToMatchInlineSnapshot, toAssertion } from './extension'\n\nexport type FilterOptions<T> = {\n examples?: { value: T; reason: string; keep: boolean }[]\n}\n\nexport function filter<U>(values: U[], condition: string, options?: FilterOptions<U>) {\n const mappedValues = values.map((_, idx) =>\n z.object({\n index: z.literal(idx),\n reason: z.string(),\n keep: z.boolean()\n })\n )\n\n const input = values.map((value, idx) => ({\n index: idx,\n value\n }))\n\n const schema = z\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n .tuple(mappedValues as any)\n .describe(\n 'An array of the objects with the index and a boolean value indicating if the object should be kept or not'\n )\n\n const promise = predictJson({\n systemMessage: `\nBased on the following qualification criteria, you need to filter the given list of objects.\nCiteria: ${condition}\n\n---\nYou need to return an array of objects with the index and a boolean value indicating if the object should be kept or not.\n`.trim(),\n examples: options?.examples\n ? [\n {\n input: options?.examples?.map((v, index) => ({\n index,\n value: v.value\n })),\n output: {\n reason: 'Here are some examples',\n result: options?.examples?.map((v, idx) => ({\n index: idx,\n reason: v.reason,\n keep: v.keep\n }))\n }\n }\n ]\n : undefined,\n outputSchema: schema,\n model: Context.evaluatorModel,\n input\n }).then((x) => {\n const results = schema.parse(x.result) as { index: number; keep: boolean }[]\n return {\n result: values.filter((_, idx) => results.find((r) => r.index === idx)?.keep),\n reason: x.reason\n }\n })\n\n return {\n ...toAssertion(promise),\n toBe: (expected: U[]) => asyncExpect(promise, (expect) => expect.toEqual(expected)),\n toMatchInlineSnapshot: makeToMatchInlineSnapshot(promise),\n toHaveNoneFiltered: () => asyncExpect(promise, (expect) => expect.toEqual(values)),\n toHaveSomeFiltered: () => asyncExpect(promise, (expect) => expect.not.toEqual(values)),\n toBeEmpty: () => asyncExpect(promise, (expect) => expect.toHaveLength(0)),\n length: {\n toBe: (expected: number) => asyncExpect(promise, (expect) => expect.toHaveLength(expected)),\n toBeGreaterThanOrEqual: (expected: number) =>\n asyncExpect(promise, (expect) => expect.length.greaterThanOrEqual(expected)),\n toBeLessThanOrEqual: (expected: number) =>\n asyncExpect(promise, (expect) => expect.length.lessThanOrEqual(expected)),\n toBeBetween: (min: number, max: number) => asyncExpect(promise, (expect) => expect.length.within(min, max))\n }\n }\n}\n","import { z } from '../utils/zui'\n\nimport { Context } from '../context'\nimport { asyncExpect } from '../utils/asyncAssertion'\nimport { Input, predictJson } from '../utils/predictJson'\nimport { makeToMatchInlineSnapshot, toAssertion } from './extension'\n\nexport type RatingScore = 1 | 2 | 3 | 4 | 5\nexport type RateOptions<T> = {\n examples?: { value: T; rating: number; reason: string }[]\n}\n\nexport function rate<T extends Input>(value: T, condition: string, options?: RateOptions<T>) {\n const schema = z.number().min(1).max(5).describe('Rating score, higher is better (1 is the worst, 5 is the best)')\n const promise = predictJson({\n systemMessage: `Based on the following qualification criteria, you need to rate the given situation from a score of 1 to 5.\\nScoring: 1 is the worst score, 5 is the best score possible.\\nCriteria: ${condition}`,\n examples: options?.examples?.map(({ value, reason, rating }) => ({\n input: value,\n output: { reason, result: rating }\n })),\n outputSchema: schema,\n model: Context.evaluatorModel,\n input: value\n }).then((x) => {\n return {\n result: typeof x.result === 'number' ? x.result : parseInt(x.result, 10),\n reason: x.reason\n }\n })\n\n return {\n ...toAssertion(promise),\n toBe: (expected: number) => asyncExpect(promise, (expect) => expect.toEqual(expected)),\n toMatchInlineSnapshot: makeToMatchInlineSnapshot(promise),\n toBeGreaterThanOrEqual: (expected: RatingScore) =>\n asyncExpect(promise, (expect) => expect.toBeGreaterThanOrEqual(expected)),\n toBeLessThanOrEqual: (expected: RatingScore) =>\n asyncExpect(promise, (expect) => expect.toBeLessThanOrEqual(expected))\n }\n}\n","import { getCurrentTest } from 'vitest/suite'\nimport { EvaluatorModel, TestMetadata } from '../context'\n\nexport const setEvaluator = (model: EvaluatorModel) => {\n const test = getCurrentTest()\n\n if (!test) {\n throw new Error('setEvaluator is a Vitest hook and must be called within a test')\n }\n\n const meta = test.meta as TestMetadata\n meta.evaluatorModel = model\n}\n","import { Client } from '@botpress/client'\nimport { Context } from '../context'\n\nexport const setupClient = (client: Client) => {\n Context.setClient(client)\n}\n"],"mappings":"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","names":["fn","getCurrentTest","getCurrentTest","output","expect","getCurrentTest","expect","getCurrentTest","value","expect","value","expect","_a","expect","value","expect","getCurrentTest","getCurrentTest"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@botpress/vai",
3
- "version": "0.0.1-beta.6",
3
+ "version": "0.0.1-beta.7",
4
4
  "type": "module",
5
5
  "description": "Vitest AI (vai) – a vitest extension for testing with LLMs",
6
6
  "exports": {