diff --git a/.github/workflows/val.yaml b/.github/workflows/val.yaml new file mode 100644 index 000000000..1139c0bed --- /dev/null +++ b/.github/workflows/val.yaml @@ -0,0 +1,26 @@ +name: val.town + +on: + workflow_dispatch: + pull_request: + paths: + - "integrations/val.town/vals/**" + push: + branches: [main] + paths: + - "integrations/val.town/vals/**" + +jobs: + update: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + - uses: denoland/setup-deno@v2 + with: + deno-version: v2.x + - name: Update val + env: + VALTOWN_API_KEY: ${{ secrets.VALTOWN_API_KEY }} + run: | + ./integrations/val.town/src/cli.ts update diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index e8b969a73..d28fc7266 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -25,6 +25,7 @@ repos: (?x)^( .*\.(json|prisma|svg) |.*pnpm-lock.yaml + |.*deno.lock )$ args: - "-L" diff --git a/README.md b/README.md index 7f60ccb1e..2a4ba468c 100644 --- a/README.md +++ b/README.md @@ -96,6 +96,15 @@ BRAINTRUST_API_KEY= \ braintrust eval eval_tutorial.py ``` +## Integrations + +Braintrust provides integrations with several popular AI development tools and platforms: + +- **LangChain.js**: A callback handler to automatically log LangChain.js executions to Braintrust. [Learn more](integrations/langchain-js) +- **LangChain Python**: Integration for logging LangChain Python executions to Braintrust. [Learn more](integrations/langchain-py) +- **Val Town**: Examples and templates for using Braintrust with Val Town's serverless JavaScript/TypeScript environment. [Learn more](integrations/val.town) +- **Vercel AI SDK**: Integration with Vercel's AI SDK for building AI-powered applications. [Learn more](integrations/vercel-ai-sdk) + ## Documentation For more information, check out the [docs](https://www.braintrust.dev/docs): diff --git a/integrations/val.town/.cursor/rules/deno.mdc b/integrations/val.town/.cursor/rules/deno.mdc new file mode 100644 index 000000000..740783b1f --- /dev/null +++ b/integrations/val.town/.cursor/rules/deno.mdc @@ -0,0 +1,280 @@ +--- +description: Extra Deno 2.0 Context +globs: deno.json, deno.jsonc +alwaysApply: false +--- +# Deno 2.0 Project Best Practices +This project uses the latest Deno 2 +Full documentation for the Deno namespace is at [https://docs.deno.com/api/deno/~/Deno](mdc:https:/docs.deno.com/api/deno/~/Deno). You must adhere to the best practices for Deno. + +## Deno Rules +### 1) Prefer Deno Methods +- **Environment Variables**: `Deno.env.get` `Deno.env.set` +- **Console and Logging**: `Console.table`, `Deno.inspect` +- **File System**: `Deno.chown`, `Deno.chmod`, `Deno.create`, `Deno.mkdir`, `Deno.realpath`, `Deno.remove`, `Deno.rename`, `Deno.umask`, `Deno.utime`, `Deno.watchFs`, `Deno.writeTextFile`, `Deno.stat` +- **Networking**: `Deno.connect`, `Deno.connectQuic`, `Deno.connectTls`, `Deno.listen`, `Deno.listenDatagram`, `Deno.listenTls`, `Deno.networkInterfaces`, `Deno.resolveDns`, `Deno.startTls` +- **Runtime**: `Deno.addSignalListener`, `Deno.bench`, `Deno.chdir`, `Deno.chmod`, `Deno.chmodSync`, `Deno.chown`, `Deno.chownSync`, `Deno.consoleSize`, `Deno.copyFile`, `Deno.copyFileSync`, `Deno.create`, `Deno.createHttpClient`, `Deno.createSync`, `Deno.cron`, `Deno.cwd`, `Deno.dlopen`, `Deno.execPath`, `Deno.exit`, `Deno.gid`, `Deno.hostname`, `Deno.inspect`, `Deno.kill`, `Deno.link`, `Deno.linkSync`, `Deno.loadavg`, `Deno.lstat`, `Deno.lstatSync`, `Deno.makeTempDir`, `Deno.makeTempDirSync`, `Deno.makeTempFile`, `Deno.makeTempFileSync`, `Deno.memoryUsage`, `Deno.mkdir`, `Deno.mkdirSync`, `Deno.open`, `Deno.openKv`, `Deno.openSync`, `Deno.osRelease`, `Deno.osUptime`, `Deno.refTimer`, `Deno.removeSignalListener`, `Deno.startTls`, `Deno.stat`, `Deno.statSync`, `Deno.systemMemoryInfo`, `Deno.uid`, `Deno.unrefTimer`, `Deno.utime`, `Deno.utimeSync`, `Deno.version` +- **Process and Commands**: CRITICAL: ALWAYS USE `Deno.command`. There is also `Deno.ChildProcess`. [Full documentation can be found here](mdc:https:/docs.deno.com/api/deno/~/Deno.Command) + + +### 2) Prefer `@std` Libraries + +Deno's standard library, written in TypeScript, offers audited, reusable modules for common tasks, ensuring consistency and reliability. Modules are independently versioned following semantic versioning, allowing version pinning to prevent breaking changes. To import modules, use the `deno add` command to update your `deno.json` import map, or import directly with the `jsr:` specifier. + +#### Full list of `@std` packages +@std/assert, @std/async, @std/bytes, @std/cache, @std/cbor, @std/cli, @std/collections, @std/crypto, @std/csv, @std/data-structures, @std/datetime, @std/dotenv, @std/encoding, @std/expect, @std/fmt, @std/front-matter, @std/fs, @std/html, @std/http, @std/ini, @std/internal, @std/io, @std/json, @std/jsonc, @std/log, @std/media-types, @std/msgpack, @std/net, @std/path, @std/random, @std/regexp, @std/semver, @std/streams, @std/tar, @std/testing, @std/text, @std/toml, @std/ulid, @std/uuid, @std/webgpu, @std/yaml + +### 3) Understand the Deno CLI for Building, Testing, Running, Formatting, Linting and Debugging +It provides helpful functionality. Most common methods: + +- `deno add [OPTIONS] [packages]`: Add dependencies to your configuration file. +- `deno install`: Installs dependencies either in the local project or globally to a bin directory. Allows " --global" flag to install globally. +- `deno task`: runs a task specified in deno.json or deno.jsonc. +- `deno info [OPTIONS] [file]`:Show information about a module or the cache directories. +- `deno compile [OPTIONS] [SCRIPT_ARG]`: Cross-compiling to different target architectures is supported using the --target flag. On the first invocation with deno will download the proper binary and cache it in $DENO_DIR. +- `deno run [OPTIONS] [file]`: Run a JavaScript or TypeScript program, or a task or script. By default all programs are run in sandbox without access to disk, network or ability to spawn subprocesses. Should rarely be used over "deno task". +- `deno publish [options]`: Publish the current working directory's package or workspace to JSR. Options "--token", "--dry-run" etc. +- `deno repl [OPTIONS] [-- [ARGS]...]`: Starts a read-eval-print-loop, which lets you interactively build up program state in the global context. It is especially useful for quick prototyping and checking snippets of code. +- Debugging flags: `--inspect`, `--inspect-wait`, `--inspect-brk`. Deno supports the V8 Inspector Protocol. This makes it possible to debug Deno programs using Chrome DevTools or other clients that support the protocol (for example VSCode). Visit chrome://inspect in a Chromium derived browser to connect Deno to the inspector server. + +**NOTE ON CACHING AND RLOADING:** By default, Deno uses a global cache directory (DENO_DIR) for downloaded dependencies. This cache is shared across all projects.You can force deno to refetch and recompile modules into the cache using the `--reload` flag. + +## 4) Know the Latest Deno 2 Methods +### Deno Serve +`deno serve [OPTIONS] [SCRIPT_ARG]...`: Run a server defined in a main module.he serve command uses the default exports of the main module to determine which servers to start. For example, it can run a file as a server which exports: +``` +export default { + async fetch(request) { + if (request.url.startsWith("/json")) { + return Response.json({ hello: "world" }) + } + return new Response("Hello world!") + // You can also respond with a stream: + // Setup readable stream... then: + // return new Response(body.pipeThrough(new TextEncoderStream()), { + // headers: { + // "content-type": "text/plain; charset=utf-8", + // }, + // }); + }, +} satisfies Deno.ServeDefaultExport; +``` +[Full documentation on Deno.serve](mdc:https:/docs.deno.com/runtime/fundamentals/http_server) + +### Deno Native APIs +[Full documentation of Deno Native APIs](mdc:https:/docs.deno.com/api/deno/~/Deno). + +#### Example Deno Native API Classes +Deno.AtomicOperation, Deno.ChildProcess, Deno.Command, Deno.FsFile, Deno.HttpClient, Deno.Kv, Deno.KvListIterator, Deno.KvU64, Deno.Permissions, Deno.PermissionStatus, Deno.QuicEndpoint, Deno.UnsafeCallback, Deno.UnsafeFnPointer, Deno.UnsafePointer, Deno.UnsafePointerView, Deno.UnsafeWindowSurface + + +### Web APIs +[Full documentation of Deno Web APIs](mdc:https:/docs.deno.com/api/web). + +#### Supported Web APIs: +AbortController, AbortSignal, addEventListener, atob, Blob, btoa, BroadcastChannel, caches, CacheStorage, clearInterval, clearTimeout, console, createImageBitmap, crypto, Crypto, CryptoKey, CustomEvent, DOMException, ErrorEvent, Event, EventSource, EventTarget, fetch, File, FileReader, FormData, Headers, localStorage, location, MessageChannel, MessageEvent, MessagePort, navigator, offscreenCanvas, Performance, performance, removeEventListener, Request, Response, setInterval, setTimeout, Storage, TextDecoder, TextEncoder, URL, URLSearchParams, WebSocket, Worker, WritableStream, ReadableStream, TransformStream, XMLHttpRequest + +## 5) Know How to Test in Deno 2 +`deno test [OPTIONS] [files]... [-- [SCRIPT_ARG]...]`: Run tests using Deno's built-in test runner. Evaluate the given modules, run all tests declared with Deno.test() and report results to standard output. Directory arguments are expanded to all contained files matching the glob `{*_,*.,}test.{js,mjs,ts,mts,jsx,tsx}` or `**/__tests__/**`. Typechecking errors can be skipped with `--no-check`. + +### Deno Native Test Methods +``` +import { assertEquals } from "@std/assert" +Deno.test("simple test", () => { + const x = 1 + 2 + assertEquals(x, 3) +}) + +import { delay } from "@std/async" +Deno.test("async test", async () => { + const x = 1 + 2 + await delay(100) + assertEquals(x, 3) +}) + +import { expect } from "@std/expect" +Deno.test("add function adds two numbers correctly", () => { + const wrongValue = false + expect(wrongValue).toBe(true) +}) + +// Example of test steps +Deno.test("database operations", async (t) => { + await t.step("insert", async () => { + // Insert logic goes here + }) + await t.step("delete", async () => { + // Delete logic goes here + }) +}) +``` + +### Filter Tests with Test Steps +Deno allows you to run specific tests or groups of tests using the --filter option on the command line. This option accepts either a string or a pattern to match test names. Filtering does not affect steps; if a test name matches the filter, all of its steps are executed. Example: + +``` +Deno.test("my-test", () => {}); +Deno.test("test-1", () => {}); +Deno.test("test-2", () => {}); +// Run just "my-test" with `deno test --filter "my" tests/` +``` + +### Ignoring Deno Tests +``` +Deno.test({ + name: "do macOS feature", + ignore: Deno.build.os !== "darwin", // This test will be ignored if not running on macOS + fn() { + // do MacOS feature here + }, +}) + +// OR a ignore a test with the ".ignore" method +Deno.test.ignore("my test", () => { +}) +``` +### Failing Fast +Fail log test suites fast with `deno test --fail-fast` + +### Reporters +``` +// Use the default pretty reporter +deno test +// Use the dot reporter for concise output +deno test --reporter=dot +// Use the JUnit reporter +deno test --reporter=junit +``` + +### Mocking Spying and Complicated Testing +Must use [@std/testing](mdc:https:/jsr.io/@std/testing/doc) +``` +import { describe, it } from "@std/testing/bdd" +import { assertEquals } from "@std/assert" +describe("Math operations", () => { + it("should add numbers correctly", () => { + assertEquals(1 + 2, 3) + }) +}) +import { spy, assertSpyCalls } from "@std/testing/mock" +function greet() { + console.log("Hello") +} +const greetSpy = spy(greet) +greetSpy() +assertSpyCalls(greetSpy, 1) +``` + +### Documentation Tests +Deno supports both type-checking evaluating your documentation examples. This makes sure that examples within your documentation are up to date and working. + +#### Example +If this example was in a file named foo.ts, running deno test --doc foo.ts will extract this example, and then both type-check and evaluate it as a standalone module living in the same directory as the module being documented. + +The basic idea is this: +``` +/** + * # Examples + * + * ```ts + * const x = 42; + * ``` + */ +``` +The triple backticks mark the start and end of code blocks, the language is determined by the language identifier attribute which may be any of the following: + +To document your exports, import the module using a relative path specifier: +``` +/** + * # Examples + * + * ```ts + * import { foo } from "./foo.ts"; + * ``` + */ +export function foo(): string { + return "foo"; +} +``` + +## 6) Understand the Extras + +### ClI Usages +Use `@std/cli`. Methods: parseArgs, promptSecret, unicodeWidth, ProgressBar, ProgressBarStream, promptMultipleSelect, promptSelect, Spinner + +Example +``` +import cli from "@std/cli" + +// For proper use, one should use `parseArgs(Deno.args)` +cli.parseArgs(["--foo", "--bar=baz", "./deno.txt"], { + foo: true, + bar: "baz", + _: ["./deno.txt"], +}) +const userSelection = cli.promptSelect("Please select a browser:", ["safari", "chrome", "firefox"], { clear: true }) + +``` + +### Module Metadata +import.meta can provide information on the context of the module. +The boolean import.meta.main will let you know if the current module is the program entry point. +The string import.meta.url will give you the URL of the current module. +The string import.meta.filename will give you the fully resolved path to the current module. For local modules only. +The string import.meta.dirname will give you the fully resolved path to the directory containing the current module. For local modules only. +The import.meta.resolve allows you to resolve specifier relative to the current module. This function takes into account an import map (if one was provided on startup). +The string Deno.mainModule will give you the URL of the main module entry point, i.e. the module invoked by the deno runtime. + +### Formatting +The Deno CLI comes with a built-in formatter which can be accessed using `deno fmt` but can also be configured to be used by VS Code in ".vscode/settings.json" and adding "editor.defaultFormatter": "denoland.vscode-deno". + +### Workspaces and Monorepos +Deno supports [workspaces](mdc:https:/docs.deno.com/runtime/fundamentals/workspaces), also known as "monorepos", which allow you to manage multiple related and interdependent packages simultaneously. A "workspace" is a collection of folders containing deno.json or deno.jsonc configuration file. The root configuration file defines the workspace: +``` +// deno.jsonc +{ + "workspace": ["./add", "./subtract"] +} +``` + +### Compiler Options / Typescript Options +`deno.json` or `deno.jsonc` configuration files can specify a `compilerOptions`. The full possible list of compiler options someone could choose are: +``` +{ + // Just an example, you will rarely need most of these. + "compilerOptions": { + "allowJs": true, // Allow JavaScript files to be compiled + "allowUnreachableCode": false, // Allow unreachable code in functions + "allowUnusedLabels": false, // Allow unused labels in code + "checkJs": false, // Enable type checking in JavaScript files + "jsx": "react", // Set JSX mode, can be "preserve", "react", "react-jsx", "react-jsxdev" + "jsxFactory": "React.createElement", // Specify the function used to create JSX elements + "jsxFragmentFactory": "React.Fragment", // Specify the function used for JSX fragments + "keyofStringsOnly": false, // Restrict keyof to only return string keys + "lib": ["deno.window"], // Specify the libraries available (default: "deno.window" for Deno) + "noErrorTruncation": false, // Disable error message truncation + "noFallthroughCasesInSwitch": false, // Disallow fallthrough cases in switch statements + "noImplicitAny": true, // Disallow implicit "any" type + "noImplicitOverride": true, // Ensure methods overridden in subclasses are explicitly marked with "override" + "noImplicitReturns": false, // Report error when not all code paths in a function return a value + "noImplicitThis": true, // Disallow "this" being used implicitly + "noImplicitUseStrict": true, // Disable implicit strict mode in modules + "noStrictGenericChecks": false, // Disable strict checking for generic function calls + "noUnusedLocals": false, // Report unused local variables as errors + "noUnusedParameters": false, // Report unused parameters in functions as errors + "noUncheckedIndexedAccess": false, // Treat indexed access types as potentially undefined + "reactNamespace": "React", // Specify the React namespace for JSX support + "strict": true, // Enable all strict type-checking options + "strictBindCallApply": true, // Enable stricter rules for `call`, `apply`, and `bind` + "strictFunctionTypes": true, // Enable strict checking of function types + "strictPropertyInitialization": true, // Require initialization of class properties + "strictNullChecks": true, // Enable strict null checks + "suppressExcessPropertyErrors": false, // Suppress excess property errors in object literals + "suppressImplicitAnyIndexErrors": false, // Suppress implicit any errors for index signatures + "useUnknownInCatchVariables": true // Use "unknown" type for variables caught in "catch" blocks + } +} +``` + +### VS Code Extension and Debugger +You're using the Deno extension. This extension provides integration with the built-in VS Code debugger. You can generate a configuration by: going to Run and Debug panel, clicking create a launch.json file and selecting Deno option from the available debugger options. diff --git a/integrations/val.town/.env.example b/integrations/val.town/.env.example new file mode 100644 index 000000000..099f7d548 --- /dev/null +++ b/integrations/val.town/.env.example @@ -0,0 +1 @@ +VALTOWN_API_KEY=your_api_key_here diff --git a/integrations/val.town/.envrc b/integrations/val.town/.envrc new file mode 100644 index 000000000..43edf50a3 --- /dev/null +++ b/integrations/val.town/.envrc @@ -0,0 +1,2 @@ +source_up_if_exists +dotenv_if_exists diff --git a/integrations/val.town/.gitignore b/integrations/val.town/.gitignore new file mode 100644 index 000000000..4c49bd78f --- /dev/null +++ b/integrations/val.town/.gitignore @@ -0,0 +1 @@ +.env diff --git a/integrations/val.town/README.md b/integrations/val.town/README.md new file mode 100644 index 000000000..3349c294a --- /dev/null +++ b/integrations/val.town/README.md @@ -0,0 +1,26 @@ +# Braintrust Val Town examples + +A collection of example vals showing how to use Braintrust with Val Town. + +## Examples + +### Tutorial + +[![Open Val Town Template](https://stevekrouse-badge.web.val.run/?3)](https://esm.town/v/braintrust/sdk) + +A simple example showing how to use the Braintrust SDK to evaluate an AI function: + +- Sets up a basic evaluation using the `Eval` framework +- Uses the Levenshtein scorer to compare outputs +- Shows how to structure test cases + +## Running the examples + +1. Navigate to the example you want to try (e.g., `vals/tutorial`) +2. Follow the setup instructions in the example's README +3. Fork and run the val to see it in action + +## Resources + +- [Braintrust documentation](https://www.braintrust.dev/docs) +- [Val Town documentation](https://docs.val.town) diff --git a/integrations/val.town/deno.json b/integrations/val.town/deno.json new file mode 100644 index 000000000..f21f43c25 --- /dev/null +++ b/integrations/val.town/deno.json @@ -0,0 +1,14 @@ +{ + "tasks": { + "up": "deno run cli.ts update" + }, + "imports": { + "@cliffy/ansi": "jsr:@cliffy/ansi@^1.0.0-rc.7", + "@cliffy/command": "jsr:@cliffy/command@^1.0.0-rc.7", + "@std/fs": "jsr:@std/fs@^1.0.14", + "@std/path": "jsr:@std/path@^1.0.8", + "autoevals": "npm:autoevals@^0.0.122", + "braintrust": "npm:braintrust@^0.0.187", + "zod": "npm:zod@^3.24.2" + } +} diff --git a/integrations/val.town/deno.lock b/integrations/val.town/deno.lock new file mode 100644 index 000000000..50df406a5 --- /dev/null +++ b/integrations/val.town/deno.lock @@ -0,0 +1,1121 @@ +{ + "version": "4", + "specifiers": { + "jsr:@cliffy/ansi@^1.0.0-rc.7": "1.0.0-rc.7", + "jsr:@cliffy/command@^1.0.0-rc.7": "1.0.0-rc.7", + "jsr:@cliffy/flags@1.0.0-rc.7": "1.0.0-rc.7", + "jsr:@cliffy/internal@1.0.0-rc.7": "1.0.0-rc.7", + "jsr:@cliffy/table@1.0.0-rc.7": "1.0.0-rc.7", + "jsr:@std/encoding@~1.0.5": "1.0.7", + "jsr:@std/fmt@*": "1.0.6", + "jsr:@std/fmt@^1.0.6": "1.0.6", + "jsr:@std/fmt@~1.0.2": "1.0.6", + "jsr:@std/fs@^1.0.14": "1.0.14", + "jsr:@std/io@~0.224.9": "0.224.9", + "jsr:@std/path@^1.0.8": "1.0.8", + "jsr:@std/text@~1.0.7": "1.0.11", + "npm:autoevals@*": "0.0.122_zod@3.24.2", + "npm:autoevals@^0.0.122": "0.0.122_zod@3.24.2", + "npm:braintrust@*": "0.0.187_zod@3.24.2", + "npm:braintrust@^0.0.187": "0.0.187_zod@3.24.2", + "npm:zod@^3.24.2": "3.24.2" + }, + "jsr": { + "@cliffy/ansi@1.0.0-rc.7": { + "integrity": "f71c921cce224c13d322e5cedba4f38e8f7354c7d855c9cb22729362a53f25aa", + "dependencies": [ + "jsr:@cliffy/internal", + "jsr:@std/encoding", + "jsr:@std/fmt@~1.0.2", + "jsr:@std/io" + ] + }, + "@cliffy/command@1.0.0-rc.7": { + "integrity": "1288808d7a3cd18b86c24c2f920e47a6d954b7e23cadc35c8cbd78f8be41f0cd", + "dependencies": [ + "jsr:@cliffy/flags", + "jsr:@cliffy/internal", + "jsr:@cliffy/table", + "jsr:@std/fmt@~1.0.2", + "jsr:@std/text" + ] + }, + "@cliffy/flags@1.0.0-rc.7": { + "integrity": "318d9be98f6a6417b108e03dec427dea96cdd41a15beb21d2554ae6da450a781", + "dependencies": [ + "jsr:@std/text" + ] + }, + "@cliffy/internal@1.0.0-rc.7": { + "integrity": "10412636ab3e67517d448be9eaab1b70c88eba9be22617b5d146257a11cc9b17" + }, + "@cliffy/table@1.0.0-rc.7": { + "integrity": "9fdd9776eda28a0b397981c400eeb1aa36da2371b43eefe12e6ff555290e3180", + "dependencies": [ + "jsr:@std/fmt@~1.0.2" + ] + }, + "@std/encoding@1.0.7": { + "integrity": "f631247c1698fef289f2de9e2a33d571e46133b38d042905e3eac3715030a82d" + }, + "@std/fmt@1.0.6": { + "integrity": "a2c56a69a2369876ddb3ad6a500bb6501b5bad47bb3ea16bfb0c18974d2661fc" + }, + "@std/fs@1.0.14": { + "integrity": "1e84bf0b95fe08f41f1f4aea9717bbf29f45408a56ce073b0114474ce1c9fccf", + "dependencies": [ + "jsr:@std/path" + ] + }, + "@std/io@0.224.9": { + "integrity": "4414664b6926f665102e73c969cfda06d2c4c59bd5d0c603fd4f1b1c840d6ee3" + }, + "@std/path@1.0.8": { + "integrity": "548fa456bb6a04d3c1a1e7477986b6cffbce95102d0bb447c67c4ee70e0364be" + }, + "@std/text@1.0.11": { + "integrity": "f191fa22590cac8b1cdba6cc4ab97940e720f7cc67b3084e54405b428bf5843d" + } + }, + "npm": { + "@ai-sdk/provider-utils@1.0.22_zod@3.24.2": { + "integrity": "sha512-YHK2rpj++wnLVc9vPGzGFP3Pjeld2MwhKinetA0zKXOoHAT/Jit5O8kZsxcSlJPu9wvcGT1UGZEjZrtO7PfFOQ==", + "dependencies": [ + "@ai-sdk/provider@0.0.26", + "eventsource-parser", + "nanoid", + "secure-json-parse", + "zod" + ] + }, + "@ai-sdk/provider@0.0.26": { + "integrity": "sha512-dQkfBDs2lTYpKM8389oopPdQgIU007GQyCbuPPrV+K6MtSII3HBfE0stUIMXUb44L+LK1t6GXPP7wjSzjO6uKg==", + "dependencies": [ + "json-schema" + ] + }, + "@ai-sdk/provider@1.0.10": { + "integrity": "sha512-pco8Zl9U0xwXI+nCLc0woMtxbvjU8hRmGTseAUiPHFLYAAL8trRPCukg69IDeinOvIeo1SmXxAIdWWPZOLb4Cg==", + "dependencies": [ + "json-schema" + ] + }, + "@ai-sdk/react@0.0.70_zod@3.24.2": { + "integrity": "sha512-GnwbtjW4/4z7MleLiW+TOZC2M29eCg1tOUpuEiYFMmFNZK8mkrqM0PFZMo6UsYeUYMWqEOOcPOU9OQVJMJh7IQ==", + "dependencies": [ + "@ai-sdk/provider-utils", + "@ai-sdk/ui-utils", + "swr", + "throttleit", + "zod" + ] + }, + "@ai-sdk/solid@0.0.54_zod@3.24.2": { + "integrity": "sha512-96KWTVK+opdFeRubqrgaJXoNiDP89gNxFRWUp0PJOotZW816AbhUf4EnDjBjXTLjXL1n0h8tGSE9sZsRkj9wQQ==", + "dependencies": [ + "@ai-sdk/provider-utils", + "@ai-sdk/ui-utils" + ] + }, + "@ai-sdk/svelte@0.0.57_zod@3.24.2": { + "integrity": "sha512-SyF9ItIR9ALP9yDNAD+2/5Vl1IT6kchgyDH8xkmhysfJI6WrvJbtO1wdQ0nylvPLcsPoYu+cAlz1krU4lFHcYw==", + "dependencies": [ + "@ai-sdk/provider-utils", + "@ai-sdk/ui-utils", + "sswr" + ] + }, + "@ai-sdk/ui-utils@0.0.50_zod@3.24.2": { + "integrity": "sha512-Z5QYJVW+5XpSaJ4jYCCAVG7zIAuKOOdikhgpksneNmKvx61ACFaf98pmOd+xnjahl0pIlc/QIe6O4yVaJ1sEaw==", + "dependencies": [ + "@ai-sdk/provider@0.0.26", + "@ai-sdk/provider-utils", + "json-schema", + "secure-json-parse", + "zod", + "zod-to-json-schema" + ] + }, + "@ai-sdk/vue@0.0.59_zod@3.24.2": { + "integrity": "sha512-+ofYlnqdc8c4F6tM0IKF0+7NagZRAiqBJpGDJ+6EYhDW8FHLUP/JFBgu32SjxSxC6IKFZxEnl68ZoP/Z38EMlw==", + "dependencies": [ + "@ai-sdk/provider-utils", + "@ai-sdk/ui-utils", + "swrv" + ] + }, + "@ampproject/remapping@2.3.0": { + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "dependencies": [ + "@jridgewell/gen-mapping", + "@jridgewell/trace-mapping" + ] + }, + "@asteasolutions/zod-to-openapi@6.4.0_zod@3.24.2": { + "integrity": "sha512-8cxfF7AHHx2PqnN4Cd8/O8CBu/nVYJP9DpnfVLW3BFb66VJDnqI/CczZnkqMc3SNh6J9GiX7JbJ5T4BSP4HZ2Q==", + "dependencies": [ + "openapi3-ts", + "zod" + ] + }, + "@babel/helper-string-parser@7.25.9": { + "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==" + }, + "@babel/helper-validator-identifier@7.25.9": { + "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==" + }, + "@babel/parser@7.26.9": { + "integrity": "sha512-81NWa1njQblgZbQHxWHpxxCzNsa3ZwvFqpUg7P+NNUU6f3UU2jBEg4OlF/J6rl8+PQGh1q6/zWScd001YwcA5A==", + "dependencies": [ + "@babel/types" + ] + }, + "@babel/types@7.26.9": { + "integrity": "sha512-Y3IR1cRnOxOCDvMmNiym7XpXQ93iGDDPHx+Zj+NM+rg0fBaShfQLkg+hKPaZCEvg5N/LeCo4+Rj/i3FuJsIQaw==", + "dependencies": [ + "@babel/helper-string-parser", + "@babel/helper-validator-identifier" + ] + }, + "@braintrust/core@0.0.81_zod@3.24.2": { + "integrity": "sha512-izwl3I31sQu6qeDHZB+gYvqpKXNIHNXc7idBgrAolDXyQX2MtK9Wdnw1lnkjiXl5y2ww3gcLiy0jHDB3zaiOrw==", + "dependencies": [ + "@asteasolutions/zod-to-openapi", + "uuid", + "zod" + ] + }, + "@esbuild/aix-ppc64@0.25.0": { + "integrity": "sha512-O7vun9Sf8DFjH2UtqK8Ku3LkquL9SZL8OLY1T5NZkA34+wG3OQF7cl4Ql8vdNzM6fzBbYfLaiRLIOZ+2FOCgBQ==" + }, + "@esbuild/android-arm64@0.25.0": { + "integrity": "sha512-grvv8WncGjDSyUBjN9yHXNt+cq0snxXbDxy5pJtzMKGmmpPxeAmAhWxXI+01lU5rwZomDgD3kJwulEnhTRUd6g==" + }, + "@esbuild/android-arm@0.25.0": { + "integrity": "sha512-PTyWCYYiU0+1eJKmw21lWtC+d08JDZPQ5g+kFyxP0V+es6VPPSUhM6zk8iImp2jbV6GwjX4pap0JFbUQN65X1g==" + }, + "@esbuild/android-x64@0.25.0": { + "integrity": "sha512-m/ix7SfKG5buCnxasr52+LI78SQ+wgdENi9CqyCXwjVR2X4Jkz+BpC3le3AoBPYTC9NHklwngVXvbJ9/Akhrfg==" + }, + "@esbuild/darwin-arm64@0.25.0": { + "integrity": "sha512-mVwdUb5SRkPayVadIOI78K7aAnPamoeFR2bT5nszFUZ9P8UpK4ratOdYbZZXYSqPKMHfS1wdHCJk1P1EZpRdvw==" + }, + "@esbuild/darwin-x64@0.25.0": { + "integrity": "sha512-DgDaYsPWFTS4S3nWpFcMn/33ZZwAAeAFKNHNa1QN0rI4pUjgqf0f7ONmXf6d22tqTY+H9FNdgeaAa+YIFUn2Rg==" + }, + "@esbuild/freebsd-arm64@0.25.0": { + "integrity": "sha512-VN4ocxy6dxefN1MepBx/iD1dH5K8qNtNe227I0mnTRjry8tj5MRk4zprLEdG8WPyAPb93/e4pSgi1SoHdgOa4w==" + }, + "@esbuild/freebsd-x64@0.25.0": { + "integrity": "sha512-mrSgt7lCh07FY+hDD1TxiTyIHyttn6vnjesnPoVDNmDfOmggTLXRv8Id5fNZey1gl/V2dyVK1VXXqVsQIiAk+A==" + }, + "@esbuild/linux-arm64@0.25.0": { + "integrity": "sha512-9QAQjTWNDM/Vk2bgBl17yWuZxZNQIF0OUUuPZRKoDtqF2k4EtYbpyiG5/Dk7nqeK6kIJWPYldkOcBqjXjrUlmg==" + }, + "@esbuild/linux-arm@0.25.0": { + "integrity": "sha512-vkB3IYj2IDo3g9xX7HqhPYxVkNQe8qTK55fraQyTzTX/fxaDtXiEnavv9geOsonh2Fd2RMB+i5cbhu2zMNWJwg==" + }, + "@esbuild/linux-ia32@0.25.0": { + "integrity": "sha512-43ET5bHbphBegyeqLb7I1eYn2P/JYGNmzzdidq/w0T8E2SsYL1U6un2NFROFRg1JZLTzdCoRomg8Rvf9M6W6Gg==" + }, + "@esbuild/linux-loong64@0.25.0": { + "integrity": "sha512-fC95c/xyNFueMhClxJmeRIj2yrSMdDfmqJnyOY4ZqsALkDrrKJfIg5NTMSzVBr5YW1jf+l7/cndBfP3MSDpoHw==" + }, + "@esbuild/linux-mips64el@0.25.0": { + "integrity": "sha512-nkAMFju7KDW73T1DdH7glcyIptm95a7Le8irTQNO/qtkoyypZAnjchQgooFUDQhNAy4iu08N79W4T4pMBwhPwQ==" + }, + "@esbuild/linux-ppc64@0.25.0": { + "integrity": "sha512-NhyOejdhRGS8Iwv+KKR2zTq2PpysF9XqY+Zk77vQHqNbo/PwZCzB5/h7VGuREZm1fixhs4Q/qWRSi5zmAiO4Fw==" + }, + "@esbuild/linux-riscv64@0.25.0": { + "integrity": "sha512-5S/rbP5OY+GHLC5qXp1y/Mx//e92L1YDqkiBbO9TQOvuFXM+iDqUNG5XopAnXoRH3FjIUDkeGcY1cgNvnXp/kA==" + }, + "@esbuild/linux-s390x@0.25.0": { + "integrity": "sha512-XM2BFsEBz0Fw37V0zU4CXfcfuACMrppsMFKdYY2WuTS3yi8O1nFOhil/xhKTmE1nPmVyvQJjJivgDT+xh8pXJA==" + }, + "@esbuild/linux-x64@0.25.0": { + "integrity": "sha512-9yl91rHw/cpwMCNytUDxwj2XjFpxML0y9HAOH9pNVQDpQrBxHy01Dx+vaMu0N1CKa/RzBD2hB4u//nfc+Sd3Cw==" + }, + "@esbuild/netbsd-arm64@0.25.0": { + "integrity": "sha512-RuG4PSMPFfrkH6UwCAqBzauBWTygTvb1nxWasEJooGSJ/NwRw7b2HOwyRTQIU97Hq37l3npXoZGYMy3b3xYvPw==" + }, + "@esbuild/netbsd-x64@0.25.0": { + "integrity": "sha512-jl+qisSB5jk01N5f7sPCsBENCOlPiS/xptD5yxOx2oqQfyourJwIKLRA2yqWdifj3owQZCL2sn6o08dBzZGQzA==" + }, + "@esbuild/openbsd-arm64@0.25.0": { + "integrity": "sha512-21sUNbq2r84YE+SJDfaQRvdgznTD8Xc0oc3p3iW/a1EVWeNj/SdUCbm5U0itZPQYRuRTW20fPMWMpcrciH2EJw==" + }, + "@esbuild/openbsd-x64@0.25.0": { + "integrity": "sha512-2gwwriSMPcCFRlPlKx3zLQhfN/2WjJ2NSlg5TKLQOJdV0mSxIcYNTMhk3H3ulL/cak+Xj0lY1Ym9ysDV1igceg==" + }, + "@esbuild/sunos-x64@0.25.0": { + "integrity": "sha512-bxI7ThgLzPrPz484/S9jLlvUAHYMzy6I0XiU1ZMeAEOBcS0VePBFxh1JjTQt3Xiat5b6Oh4x7UC7IwKQKIJRIg==" + }, + "@esbuild/win32-arm64@0.25.0": { + "integrity": "sha512-ZUAc2YK6JW89xTbXvftxdnYy3m4iHIkDtK3CLce8wg8M2L+YZhIvO1DKpxrd0Yr59AeNNkTiic9YLf6FTtXWMw==" + }, + "@esbuild/win32-ia32@0.25.0": { + "integrity": "sha512-eSNxISBu8XweVEWG31/JzjkIGbGIJN/TrRoiSVZwZ6pkC6VX4Im/WV2cz559/TXLcYbcrDN8JtKgd9DJVIo8GA==" + }, + "@esbuild/win32-x64@0.25.0": { + "integrity": "sha512-ZENoHJBxA20C2zFzh6AI4fT6RraMzjYw4xKWemRTRmRVtN9c5DcH9r/f2ihEkMjOW5eGgrwCslG/+Y/3bL+DHQ==" + }, + "@jridgewell/gen-mapping@0.3.8": { + "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==", + "dependencies": [ + "@jridgewell/set-array", + "@jridgewell/sourcemap-codec", + "@jridgewell/trace-mapping" + ] + }, + "@jridgewell/resolve-uri@3.1.2": { + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==" + }, + "@jridgewell/set-array@1.2.1": { + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==" + }, + "@jridgewell/sourcemap-codec@1.5.0": { + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==" + }, + "@jridgewell/trace-mapping@0.3.25": { + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dependencies": [ + "@jridgewell/resolve-uri", + "@jridgewell/sourcemap-codec" + ] + }, + "@kwsites/file-exists@1.1.1": { + "integrity": "sha512-m9/5YGR18lIwxSFDwfE3oA7bWuq9kdau6ugN4H2rJeyhFQZcG9AgSHkQtSD15a8WvTgfz9aikZMrKPHvbpqFiw==", + "dependencies": [ + "debug" + ] + }, + "@kwsites/promise-deferred@1.1.1": { + "integrity": "sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==" + }, + "@next/env@14.2.24": { + "integrity": "sha512-LAm0Is2KHTNT6IT16lxT+suD0u+VVfYNQqM+EJTKuFRRuY2z+zj01kueWXPCxbMBDt0B5vONYzabHGUNbZYAhA==" + }, + "@opentelemetry/api@1.9.0": { + "integrity": "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==" + }, + "@sveltejs/acorn-typescript@1.0.5_acorn@8.14.1": { + "integrity": "sha512-IwQk4yfwLdibDlrXVE04jTZYlLnwsTT2PIOQQGNLWfjavGifnk1JD1LcZjZaBTRcxZu2FfPfNLOE04DSu9lqtQ==", + "dependencies": [ + "acorn" + ] + }, + "@types/diff-match-patch@1.0.36": { + "integrity": "sha512-xFdR6tkm0MWvBfO8xXCSsinYxHcqkQUlcHeSpMC2ukzOb6lwQAfDmW+Qt0AvlGd8HpsS28qKsB+oPeJn9I39jg==" + }, + "@types/estree@1.0.6": { + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==" + }, + "@types/node-fetch@2.6.12": { + "integrity": "sha512-8nneRWKCg3rMtF69nLQJnOYUcbafYeFSjqkw3jCRLsqkWFlHaoQrr5mXmofFGOx3DKn7UfmBMyov8ySvLRVldA==", + "dependencies": [ + "@types/node@22.12.0", + "form-data" + ] + }, + "@types/node@18.19.80": { + "integrity": "sha512-kEWeMwMeIvxYkeg1gTc01awpwLbfMRZXdIhwRcakd/KlK53jmRC26LqcbIt7fnAQTu5GzlnWmzA3H6+l1u6xxQ==", + "dependencies": [ + "undici-types@5.26.5" + ] + }, + "@types/node@22.12.0": { + "integrity": "sha512-Fll2FZ1riMjNmlmJOdAyY5pUbkftXslB5DgEzlIuNaiWhXd00FhWxVC/r4yV/4wBb9JfImTu+jiSvXTkJ7F/gA==", + "dependencies": [ + "undici-types@6.20.0" + ] + }, + "@vercel/functions@1.6.0": { + "integrity": "sha512-R6FKQrYT5MZs5IE1SqeCJWxMuBdHawFcCZboKKw8p7s+6/mcd55Gx6tWmyKnQTyrSEA04NH73Tc9CbqpEle8RA==" + }, + "@vue/compiler-core@3.5.13": { + "integrity": "sha512-oOdAkwqUfW1WqpwSYJce06wvt6HljgY3fGeM9NcVA1HaYOij3mZG9Rkysn0OHuyUAGMbEbARIpsG+LPVlBJ5/Q==", + "dependencies": [ + "@babel/parser", + "@vue/shared", + "entities", + "estree-walker", + "source-map-js" + ] + }, + "@vue/compiler-dom@3.5.13": { + "integrity": "sha512-ZOJ46sMOKUjO3e94wPdCzQ6P1Lx/vhp2RSvfaab88Ajexs0AHeV0uasYhi99WPaogmBlRHNRuly8xV75cNTMDA==", + "dependencies": [ + "@vue/compiler-core", + "@vue/shared" + ] + }, + "@vue/compiler-sfc@3.5.13": { + "integrity": "sha512-6VdaljMpD82w6c2749Zhf5T9u5uLBWKnVue6XWxprDobftnletJ8+oel7sexFfM3qIxNmVE7LSFGTpv6obNyaQ==", + "dependencies": [ + "@babel/parser", + "@vue/compiler-core", + "@vue/compiler-dom", + "@vue/compiler-ssr", + "@vue/shared", + "estree-walker", + "magic-string", + "postcss", + "source-map-js" + ] + }, + "@vue/compiler-ssr@3.5.13": { + "integrity": "sha512-wMH6vrYHxQl/IybKJagqbquvxpWCuVYpoUJfCqFZwa/JY1GdATAQ+TgVtgrwwMZ0D07QhA99rs/EAAWfvG6KpA==", + "dependencies": [ + "@vue/compiler-dom", + "@vue/shared" + ] + }, + "@vue/reactivity@3.5.13": { + "integrity": "sha512-NaCwtw8o48B9I6L1zl2p41OHo/2Z4wqYGGIK1Khu5T7yxrn+ATOixn/Udn2m+6kZKB/J7cuT9DbWWhRxqixACg==", + "dependencies": [ + "@vue/shared" + ] + }, + "@vue/runtime-core@3.5.13": { + "integrity": "sha512-Fj4YRQ3Az0WTZw1sFe+QDb0aXCerigEpw418pw1HBUKFtnQHWzwojaukAs2X/c9DQz4MQ4bsXTGlcpGxU/RCIw==", + "dependencies": [ + "@vue/reactivity", + "@vue/shared" + ] + }, + "@vue/runtime-dom@3.5.13": { + "integrity": "sha512-dLaj94s93NYLqjLiyFzVs9X6dWhTdAlEAciC3Moq7gzAc13VJUdCnjjRurNM6uTLFATRHexHCTu/Xp3eW6yoog==", + "dependencies": [ + "@vue/reactivity", + "@vue/runtime-core", + "@vue/shared", + "csstype" + ] + }, + "@vue/server-renderer@3.5.13_vue@3.5.13": { + "integrity": "sha512-wAi4IRJV/2SAW3htkTlB+dHeRmpTiVIK1OGLWV1yeStVSebSQQOwGwIq0D3ZIoBj2C2qpgz5+vX9iEBkTdk5YA==", + "dependencies": [ + "@vue/compiler-ssr", + "@vue/shared", + "vue" + ] + }, + "@vue/shared@3.5.13": { + "integrity": "sha512-/hnE/qP5ZoGpol0a5mDi45bOd7t3tjYJBjsgCsivow7D48cJeV5l05RD82lPqi7gRiphZM37rnhW1l6ZoCNNnQ==" + }, + "abort-controller@3.0.0": { + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "dependencies": [ + "event-target-shim" + ] + }, + "acorn@8.14.1": { + "integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==" + }, + "agentkeepalive@4.6.0": { + "integrity": "sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ==", + "dependencies": [ + "humanize-ms" + ] + }, + "ai@3.4.33_zod@3.24.2": { + "integrity": "sha512-plBlrVZKwPoRTmM8+D1sJac9Bq8eaa2jiZlHLZIWekKWI1yMWYZvCCEezY9ASPwRhULYDJB2VhKOBUUeg3S5JQ==", + "dependencies": [ + "@ai-sdk/provider@0.0.26", + "@ai-sdk/provider-utils", + "@ai-sdk/react", + "@ai-sdk/solid", + "@ai-sdk/svelte", + "@ai-sdk/ui-utils", + "@ai-sdk/vue", + "@opentelemetry/api", + "eventsource-parser", + "json-schema", + "jsondiffpatch", + "secure-json-parse", + "zod", + "zod-to-json-schema" + ] + }, + "ajv@8.17.1": { + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "dependencies": [ + "fast-deep-equal", + "fast-uri", + "json-schema-traverse", + "require-from-string" + ] + }, + "ansi-regex@5.0.1": { + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" + }, + "ansi-styles@4.3.0": { + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": [ + "color-convert" + ] + }, + "argparse@2.0.1": { + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + }, + "aria-query@5.3.2": { + "integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==" + }, + "asynckit@0.4.0": { + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "autoevals@0.0.122_zod@3.24.2": { + "integrity": "sha512-w1CtvPu2Ku8wWGFriYKFjSCWJMvkCrWCNE4sAmTp8gXsVCcTLhlWXQVVgZUtV3j6y1wRV8P9b9xcjpYplSZwrw==", + "dependencies": [ + "@braintrust/core", + "ajv", + "compute-cosine-similarity", + "js-levenshtein", + "js-yaml", + "linear-sum-assignment", + "mustache", + "openai", + "zod", + "zod-to-json-schema" + ] + }, + "axobject-query@4.1.0": { + "integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==" + }, + "balanced-match@1.0.2": { + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "binary-search@1.3.6": { + "integrity": "sha512-nbE1WxOTTrUWIfsfZ4aHGYu5DOuNkbxGokjV6Z2kxfJK3uaAb8zNK1muzOeipoLHZjInT4Br88BHpzevc681xA==" + }, + "brace-expansion@2.0.1": { + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dependencies": [ + "balanced-match" + ] + }, + "braintrust@0.0.187_zod@3.24.2": { + "integrity": "sha512-sDq/IHFqsbA6iJoMnf747uXT7SRCS0x925+h3+DSQIPdtxK0xp41/k/jTaVjpKaeCQjdp3jyQ8lpGiYqVtE6rQ==", + "dependencies": [ + "@ai-sdk/provider@1.0.10", + "@braintrust/core", + "@next/env", + "@vercel/functions", + "ai", + "argparse", + "chalk@4.1.2", + "cli-progress", + "dotenv", + "esbuild", + "eventsource-parser", + "graceful-fs", + "minimatch", + "mustache", + "pluralize", + "simple-git", + "slugify", + "source-map", + "uuid", + "zod", + "zod-to-json-schema" + ] + }, + "call-bind-apply-helpers@1.0.2": { + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dependencies": [ + "es-errors", + "function-bind" + ] + }, + "chalk@4.1.2": { + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": [ + "ansi-styles", + "supports-color" + ] + }, + "chalk@5.4.1": { + "integrity": "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==" + }, + "cheminfo-types@1.8.1": { + "integrity": "sha512-FRcpVkox+cRovffgqNdDFQ1eUav+i/Vq/CUd1hcfEl2bevntFlzznL+jE8g4twl6ElB7gZjCko6pYpXyMn+6dA==" + }, + "cli-progress@3.12.0": { + "integrity": "sha512-tRkV3HJ1ASwm19THiiLIXLO7Im7wlTuKnvkYaTkyoAPefqjNg7W7DHKUlGRxy9vxDvbyCYQkQozvptuMkGCg8A==", + "dependencies": [ + "string-width" + ] + }, + "clsx@2.1.1": { + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==" + }, + "color-convert@2.0.1": { + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": [ + "color-name" + ] + }, + "color-name@1.1.4": { + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "combined-stream@1.0.8": { + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dependencies": [ + "delayed-stream" + ] + }, + "compute-cosine-similarity@1.1.0": { + "integrity": "sha512-FXhNx0ILLjGi9Z9+lglLzM12+0uoTnYkHm7GiadXDAr0HGVLm25OivUS1B/LPkbzzvlcXz/1EvWg9ZYyJSdhTw==", + "dependencies": [ + "compute-dot", + "compute-l2norm", + "validate.io-array", + "validate.io-function" + ] + }, + "compute-dot@1.1.0": { + "integrity": "sha512-L5Ocet4DdMrXboss13K59OK23GXjiSia7+7Ukc7q4Bl+RVpIXK2W9IHMbWDZkh+JUEvJAwOKRaJDiFUa1LTnJg==", + "dependencies": [ + "validate.io-array", + "validate.io-function" + ] + }, + "compute-l2norm@1.1.0": { + "integrity": "sha512-6EHh1Elj90eU28SXi+h2PLnTQvZmkkHWySpoFz+WOlVNLz3DQoC4ISUHSV9n5jMxPHtKGJ01F4uu2PsXBB8sSg==", + "dependencies": [ + "validate.io-array", + "validate.io-function" + ] + }, + "csstype@3.1.3": { + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" + }, + "debug@4.4.0": { + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "dependencies": [ + "ms" + ] + }, + "delayed-stream@1.0.0": { + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" + }, + "dequal@2.0.3": { + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==" + }, + "diff-match-patch@1.0.5": { + "integrity": "sha512-IayShXAgj/QMXgB0IWmKx+rOPuGMhqm5w6jvFxmVenXKIzRqTAAsbBPT3kWQeGANj3jGgvcvv4yK6SxqYmikgw==" + }, + "dotenv@16.4.7": { + "integrity": "sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==" + }, + "dunder-proto@1.0.1": { + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dependencies": [ + "call-bind-apply-helpers", + "es-errors", + "gopd" + ] + }, + "emoji-regex@8.0.0": { + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "entities@4.5.0": { + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==" + }, + "es-define-property@1.0.1": { + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==" + }, + "es-errors@1.3.0": { + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==" + }, + "es-object-atoms@1.1.1": { + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "dependencies": [ + "es-errors" + ] + }, + "es-set-tostringtag@2.1.0": { + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "dependencies": [ + "es-errors", + "get-intrinsic", + "has-tostringtag", + "hasown" + ] + }, + "esbuild@0.25.0": { + "integrity": "sha512-BXq5mqc8ltbaN34cDqWuYKyNhX8D/Z0J1xdtdQ8UcIIIyJyz+ZMKUt58tF3SrZ85jcfN/PZYhjR5uDQAYNVbuw==", + "dependencies": [ + "@esbuild/aix-ppc64", + "@esbuild/android-arm", + "@esbuild/android-arm64", + "@esbuild/android-x64", + "@esbuild/darwin-arm64", + "@esbuild/darwin-x64", + "@esbuild/freebsd-arm64", + "@esbuild/freebsd-x64", + "@esbuild/linux-arm", + "@esbuild/linux-arm64", + "@esbuild/linux-ia32", + "@esbuild/linux-loong64", + "@esbuild/linux-mips64el", + "@esbuild/linux-ppc64", + "@esbuild/linux-riscv64", + "@esbuild/linux-s390x", + "@esbuild/linux-x64", + "@esbuild/netbsd-arm64", + "@esbuild/netbsd-x64", + "@esbuild/openbsd-arm64", + "@esbuild/openbsd-x64", + "@esbuild/sunos-x64", + "@esbuild/win32-arm64", + "@esbuild/win32-ia32", + "@esbuild/win32-x64" + ] + }, + "esm-env@1.2.2": { + "integrity": "sha512-Epxrv+Nr/CaL4ZcFGPJIYLWFom+YeV1DqMLHJoEd9SYRxNbaFruBwfEX/kkHUJf55j2+TUbmDcmuilbP1TmXHA==" + }, + "esrap@1.4.5": { + "integrity": "sha512-CjNMjkBWWZeHn+VX+gS8YvFwJ5+NDhg8aWZBSFJPR8qQduDNjbJodA2WcwCm7uQa5Rjqj+nZvVmceg1RbHFB9g==", + "dependencies": [ + "@jridgewell/sourcemap-codec" + ] + }, + "estree-walker@2.0.2": { + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==" + }, + "event-target-shim@5.0.1": { + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==" + }, + "eventsource-parser@1.1.2": { + "integrity": "sha512-v0eOBUbiaFojBu2s2NPBfYUoRR9GjcDNvCXVaqEf5vVfpIAh9f8RCo4vXTP8c63QRKCFwoLpMpTdPwwhEKVgzA==" + }, + "fast-deep-equal@3.1.3": { + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, + "fast-uri@3.0.6": { + "integrity": "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==" + }, + "fft.js@4.0.4": { + "integrity": "sha512-f9c00hphOgeQTlDyavwTtu6RiK8AIFjD6+jvXkNkpeQ7rirK3uFWVpalkoS4LAwbdX7mfZ8aoBfFVQX1Re/8aw==" + }, + "form-data-encoder@1.7.2": { + "integrity": "sha512-qfqtYan3rxrnCk1VYaA4H+Ms9xdpPqvLZa6xmMgFvhO32x7/3J/ExcTd6qpxM0vH2GdMI+poehyBZvqfMTto8A==" + }, + "form-data@4.0.2": { + "integrity": "sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w==", + "dependencies": [ + "asynckit", + "combined-stream", + "es-set-tostringtag", + "mime-types" + ] + }, + "formdata-node@4.4.1": { + "integrity": "sha512-0iirZp3uVDjVGt9p49aTaqjk84TrglENEDuqfdlZQ1roC9CWlPk6Avf8EEnZNcAqPonwkG35x4n3ww/1THYAeQ==", + "dependencies": [ + "node-domexception", + "web-streams-polyfill@4.0.0-beta.3" + ] + }, + "function-bind@1.1.2": { + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==" + }, + "get-intrinsic@1.3.0": { + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "dependencies": [ + "call-bind-apply-helpers", + "es-define-property", + "es-errors", + "es-object-atoms", + "function-bind", + "get-proto", + "gopd", + "has-symbols", + "hasown", + "math-intrinsics" + ] + }, + "get-proto@1.0.1": { + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dependencies": [ + "dunder-proto", + "es-object-atoms" + ] + }, + "gopd@1.2.0": { + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==" + }, + "graceful-fs@4.2.11": { + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" + }, + "has-flag@4.0.0": { + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "has-symbols@1.1.0": { + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==" + }, + "has-tostringtag@1.0.2": { + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dependencies": [ + "has-symbols" + ] + }, + "hasown@2.0.2": { + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dependencies": [ + "function-bind" + ] + }, + "humanize-ms@1.2.1": { + "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==", + "dependencies": [ + "ms" + ] + }, + "install@0.13.0": { + "integrity": "sha512-zDml/jzr2PKU9I8J/xyZBQn8rPCAY//UOYNmR01XwNwyfhEWObo2SWfSl1+0tm1u6PhxLwDnfsT/6jB7OUxqFA==" + }, + "is-any-array@2.0.1": { + "integrity": "sha512-UtilS7hLRu++wb/WBAw9bNuP1Eg04Ivn1vERJck8zJthEvXCBEBpGR/33u/xLKWEQf95803oalHrVDptcAvFdQ==" + }, + "is-fullwidth-code-point@3.0.0": { + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" + }, + "is-reference@3.0.3": { + "integrity": "sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw==", + "dependencies": [ + "@types/estree" + ] + }, + "js-levenshtein@1.1.6": { + "integrity": "sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g==" + }, + "js-yaml@4.1.0": { + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dependencies": [ + "argparse" + ] + }, + "json-schema-traverse@1.0.0": { + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + }, + "json-schema@0.4.0": { + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==" + }, + "jsondiffpatch@0.6.0": { + "integrity": "sha512-3QItJOXp2AP1uv7waBkao5nCvhEv+QmJAd38Ybq7wNI74Q+BBmnLn4EDKz6yI9xGAIQoUF87qHt+kc1IVxB4zQ==", + "dependencies": [ + "@types/diff-match-patch", + "chalk@5.4.1", + "diff-match-patch" + ] + }, + "linear-sum-assignment@1.0.7": { + "integrity": "sha512-jfLoSGwZNyjfY8eK4ayhjfcIu3BfWvP6sWieYzYI3AWldwXVoWEz1gtrQL10v/8YltYLBunqNjeVFXPMUs+MJg==", + "dependencies": [ + "cheminfo-types", + "install", + "ml-matrix", + "ml-spectra-processing" + ] + }, + "locate-character@3.0.0": { + "integrity": "sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==" + }, + "magic-string@0.30.17": { + "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", + "dependencies": [ + "@jridgewell/sourcemap-codec" + ] + }, + "math-intrinsics@1.1.0": { + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==" + }, + "mime-db@1.52.0": { + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" + }, + "mime-types@2.1.35": { + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": [ + "mime-db" + ] + }, + "minimatch@9.0.5": { + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dependencies": [ + "brace-expansion" + ] + }, + "ml-array-max@1.2.4": { + "integrity": "sha512-BlEeg80jI0tW6WaPyGxf5Sa4sqvcyY6lbSn5Vcv44lp1I2GR6AWojfUvLnGTNsIXrZ8uqWmo8VcG1WpkI2ONMQ==", + "dependencies": [ + "is-any-array" + ] + }, + "ml-array-min@1.2.3": { + "integrity": "sha512-VcZ5f3VZ1iihtrGvgfh/q0XlMobG6GQ8FsNyQXD3T+IlstDv85g8kfV0xUG1QPRO/t21aukaJowDzMTc7j5V6Q==", + "dependencies": [ + "is-any-array" + ] + }, + "ml-array-rescale@1.3.7": { + "integrity": "sha512-48NGChTouvEo9KBctDfHC3udWnQKNKEWN0ziELvY3KG25GR5cA8K8wNVzracsqSW1QEkAXjTNx+ycgAv06/1mQ==", + "dependencies": [ + "is-any-array", + "ml-array-max", + "ml-array-min" + ] + }, + "ml-matrix@6.12.0": { + "integrity": "sha512-AGfR+pWaC0GmzjUnB6BfwhndPEUGz0i7QUYdqNuw1zhTov/vSRJ9pP2hs6BoGpaSbtXgrKjZz2zjD1M0xuur6A==", + "dependencies": [ + "is-any-array", + "ml-array-rescale" + ] + }, + "ml-spectra-processing@14.10.0": { + "integrity": "sha512-4fyF6tojgVgh6m9nmFvaIlGhrvHq+swn64IxQ44F4k4o7Qkl8xKOJWfQ4EsfoX66GqZn2PFfcn1xUGRNwB8+3w==", + "dependencies": [ + "binary-search", + "cheminfo-types", + "fft.js", + "is-any-array", + "ml-matrix", + "ml-xsadd" + ] + }, + "ml-xsadd@3.0.1": { + "integrity": "sha512-Fz2q6dwgzGM8wYKGArTUTZDGa4lQFA2Vi6orjGeTVRy22ZnQFKlJuwS9n8NRviqz1KHAHAzdKJwbnYhdo38uYg==" + }, + "ms@2.1.3": { + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "mustache@4.2.0": { + "integrity": "sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==" + }, + "nanoid@3.3.9": { + "integrity": "sha512-SppoicMGpZvbF1l3z4x7No3OlIjP7QJvC9XR7AhZr1kL133KHnKPztkKDc+Ir4aJ/1VhTySrtKhrsycmrMQfvg==" + }, + "node-domexception@1.0.0": { + "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==" + }, + "node-fetch@2.7.0": { + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "dependencies": [ + "whatwg-url" + ] + }, + "openai@4.47.1": { + "integrity": "sha512-WWSxhC/69ZhYWxH/OBsLEirIjUcfpQ5+ihkXKp06hmeYXgBBIUCa9IptMzYx6NdkiOCsSGYCnTIsxaic3AjRCQ==", + "dependencies": [ + "@types/node@18.19.80", + "@types/node-fetch", + "abort-controller", + "agentkeepalive", + "form-data-encoder", + "formdata-node", + "node-fetch", + "web-streams-polyfill@3.3.3" + ] + }, + "openapi3-ts@4.4.0": { + "integrity": "sha512-9asTNB9IkKEzWMcHmVZE7Ts3kC9G7AFHfs8i7caD8HbI76gEjdkId4z/AkP83xdZsH7PLAnnbl47qZkXuxpArw==", + "dependencies": [ + "yaml" + ] + }, + "picocolors@1.1.1": { + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==" + }, + "pluralize@8.0.0": { + "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==" + }, + "postcss@8.5.3": { + "integrity": "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==", + "dependencies": [ + "nanoid", + "picocolors", + "source-map-js" + ] + }, + "react@19.0.0": { + "integrity": "sha512-V8AVnmPIICiWpGfm6GLzCR/W5FXLchHop40W4nXBmdlEceh16rCN8O8LNWm5bh5XUX91fh7KpA+W0TgMKmgTpQ==" + }, + "require-from-string@2.0.2": { + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==" + }, + "secure-json-parse@2.7.0": { + "integrity": "sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==" + }, + "simple-git@3.27.0": { + "integrity": "sha512-ivHoFS9Yi9GY49ogc6/YAi3Fl9ROnF4VyubNylgCkA+RVqLaKWnDSzXOVzya8csELIaWaYNutsEuAhZrtOjozA==", + "dependencies": [ + "@kwsites/file-exists", + "@kwsites/promise-deferred", + "debug" + ] + }, + "slugify@1.6.6": { + "integrity": "sha512-h+z7HKHYXj6wJU+AnS/+IH8Uh9fdcX1Lrhg1/VMdf9PwoBQXFcXiAdsy2tSK0P6gKwJLXp02r90ahUCqHk9rrw==" + }, + "source-map-js@1.2.1": { + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==" + }, + "source-map@0.7.4": { + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==" + }, + "sswr@2.2.0_svelte@5.22.6__acorn@8.14.1": { + "integrity": "sha512-clTszLPZkmycALTHD1mXGU+mOtA/MIoLgS1KGTTzFNVm9rytQVykgRaP+z1zl572cz0bTqj4rFVoC2N+IGK4Sg==", + "dependencies": [ + "svelte", + "swrev" + ] + }, + "string-width@4.2.3": { + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": [ + "emoji-regex", + "is-fullwidth-code-point", + "strip-ansi" + ] + }, + "strip-ansi@6.0.1": { + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": [ + "ansi-regex" + ] + }, + "supports-color@7.2.0": { + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": [ + "has-flag" + ] + }, + "svelte@5.22.6_acorn@8.14.1": { + "integrity": "sha512-dxHyh3USJyayafSt5I5QD7KuoCM5ZGdIOtLQiKHEro7tymdh0jMcNkiSBVHW+LOA2jEqZEHhyfwN6/pCjx0Fug==", + "dependencies": [ + "@ampproject/remapping", + "@jridgewell/sourcemap-codec", + "@sveltejs/acorn-typescript", + "@types/estree", + "acorn", + "aria-query", + "axobject-query", + "clsx", + "esm-env", + "esrap", + "is-reference", + "locate-character", + "magic-string", + "zimmerframe" + ] + }, + "swr@2.3.3_react@19.0.0": { + "integrity": "sha512-dshNvs3ExOqtZ6kJBaAsabhPdHyeY4P2cKwRCniDVifBMoG/SVI7tfLWqPXriVspf2Rg4tPzXJTnwaihIeFw2A==", + "dependencies": [ + "dequal", + "react", + "use-sync-external-store" + ] + }, + "swrev@4.0.0": { + "integrity": "sha512-LqVcOHSB4cPGgitD1riJ1Hh4vdmITOp+BkmfmXRh4hSF/t7EnS4iD+SOTmq7w5pPm/SiPeto4ADbKS6dHUDWFA==" + }, + "swrv@1.1.0_vue@3.5.13": { + "integrity": "sha512-pjllRDr2s0iTwiE5Isvip51dZGR7GjLH1gCSVyE8bQnbAx6xackXsFdojau+1O5u98yHF5V73HQGOFxKUXO9gQ==", + "dependencies": [ + "vue" + ] + }, + "throttleit@2.1.0": { + "integrity": "sha512-nt6AMGKW1p/70DF/hGBdJB57B8Tspmbp5gfJ8ilhLnt7kkr2ye7hzD6NVG8GGErk2HWF34igrL2CXmNIkzKqKw==" + }, + "tr46@0.0.3": { + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, + "undici-types@5.26.5": { + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" + }, + "undici-types@6.20.0": { + "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==" + }, + "use-sync-external-store@1.4.0_react@19.0.0": { + "integrity": "sha512-9WXSPC5fMv61vaupRkCKCxsPxBocVnwakBEkMIHHpkTTg6icbJtg6jzgtLDm4bl3cSHAca52rYWih0k4K3PfHw==", + "dependencies": [ + "react" + ] + }, + "uuid@9.0.1": { + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==" + }, + "validate.io-array@1.0.6": { + "integrity": "sha512-DeOy7CnPEziggrOO5CZhVKJw6S3Yi7e9e65R1Nl/RTN1vTQKnzjfvks0/8kQ40FP/dsjRAOd4hxmJ7uLa6vxkg==" + }, + "validate.io-function@1.0.2": { + "integrity": "sha512-LlFybRJEriSuBnUhQyG5bwglhh50EpTL2ul23MPIuR1odjO7XaMLFV8vHGwp7AZciFxtYOeiSCT5st+XSPONiQ==" + }, + "vue@3.5.13": { + "integrity": "sha512-wmeiSMxkZCSc+PM2w2VRsOYAZC8GdipNFRTsLSfodVqI9mbejKeXEGr8SckuLnrQPGe3oJN5c3K0vpoU9q/wCQ==", + "dependencies": [ + "@vue/compiler-dom", + "@vue/compiler-sfc", + "@vue/runtime-dom", + "@vue/server-renderer", + "@vue/shared" + ] + }, + "web-streams-polyfill@3.3.3": { + "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==" + }, + "web-streams-polyfill@4.0.0-beta.3": { + "integrity": "sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug==" + }, + "webidl-conversions@3.0.1": { + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + }, + "whatwg-url@5.0.0": { + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dependencies": [ + "tr46", + "webidl-conversions" + ] + }, + "yaml@2.7.0": { + "integrity": "sha512-+hSoy/QHluxmC9kCIJyL/uyFmLmc+e5CFR5Wa+bpIhIj85LVb9ZH2nVnqrHoSvKogwODv0ClqZkmiSSaIH5LTA==" + }, + "zimmerframe@1.1.2": { + "integrity": "sha512-rAbqEGa8ovJy4pyBxZM70hg4pE6gDgaQ0Sl9M3enG3I0d6H4XSAM3GeNGLKnsBpuijUow064sf7ww1nutC5/3w==" + }, + "zod-to-json-schema@3.24.3_zod@3.24.2": { + "integrity": "sha512-HIAfWdYIt1sssHfYZFCXp4rU1w2r8hVVXYIlmoa0r0gABLs5di3RCqPU5DDROogVz1pAdYBaz7HK5n9pSUNs3A==", + "dependencies": [ + "zod" + ] + }, + "zod@3.24.2": { + "integrity": "sha512-lY7CDW43ECgW9u1TcT3IoXHflywfVqDYze4waEz812jR/bZ8FHDsl7pFQoSZTz5N+2NqRXs8GBwnAwo3ZNxqhQ==" + } + }, + "redirects": { + "https://deno.land/std/cli/parse_args.ts": "https://deno.land/std@0.224.0/cli/parse_args.ts" + }, + "remote": { + "https://deno.land/std@0.224.0/assert/assert.ts": "09d30564c09de846855b7b071e62b5974b001bb72a4b797958fe0660e7849834", + "https://deno.land/std@0.224.0/assert/assertion_error.ts": "ba8752bd27ebc51f723702fac2f54d3e94447598f54264a6653d6413738a8917", + "https://deno.land/std@0.224.0/cli/parse_args.ts": "5250832fb7c544d9111e8a41ad272c016f5a53f975ef84d5a9fe5fcb70566ece" + }, + "workspace": { + "dependencies": [ + "jsr:@cliffy/ansi@^1.0.0-rc.7", + "jsr:@cliffy/command@^1.0.0-rc.7", + "jsr:@std/fs@^1.0.14", + "jsr:@std/path@^1.0.8", + "npm:autoevals@^0.0.122", + "npm:braintrust@^0.0.187", + "npm:zod@^3.24.2" + ] + } +} diff --git a/integrations/val.town/src/cli.ts b/integrations/val.town/src/cli.ts new file mode 100755 index 000000000..8677f0d07 --- /dev/null +++ b/integrations/val.town/src/cli.ts @@ -0,0 +1,18 @@ +#!/usr/bin/env -S deno run --allow-read --allow-env --allow-net + +import { Command } from "@cliffy/command"; +import { command as updateCommand } from "./commands/update.ts"; +import { colors } from "@cliffy/ansi/colors"; + +await new Command() + .name("cli") + .version("0.0.1") + .description("File processing CLI") + .command("update", updateCommand) + .error((error) => { + console.error( + colors.red(error instanceof Error ? error.message : String(error)), + ); + Deno.exit(1); + }) + .parse(Deno.args); diff --git a/integrations/val.town/src/commands/update.ts b/integrations/val.town/src/commands/update.ts new file mode 100644 index 000000000..9027cd6f9 --- /dev/null +++ b/integrations/val.town/src/commands/update.ts @@ -0,0 +1,105 @@ +import { Command } from "@cliffy/command"; +import { colors } from "@cliffy/ansi/colors"; +import { expandGlob } from "@std/fs"; +import { z } from "zod"; +import { join } from "@std/path"; + +const configSchema = z.object({ + val_id: z.string(), +}); + +async function updateVal(valDir: string) { + const configPath = join(valDir, "config.json"); + const codePath = join(valDir, "code.ts"); + const readmePath = join(valDir, "README.md"); + + try { + const [configContent, code, readme] = await Promise.all([ + Deno.readTextFile(configPath), + Deno.readTextFile(codePath), + Deno.readTextFile(readmePath), + ]); + + const { val_id: valId } = configSchema.parse(JSON.parse(configContent)); + + const apiKey = Deno.env.get("VALTOWN_API_KEY"); + if (!apiKey) { + throw new Error("VALTOWN_API_KEY environment variable is required"); + } + + await Promise.all([ + updateValCode(valId, code, apiKey), + updateValReadme(valId, readme, apiKey), + ]); + } catch (error) { + if (error instanceof Deno.errors.NotFound) { + console.log( + colors.yellow( + `Skipping ${valDir} because it's missing required files (config.json, code.ts, or README.md)`, + ), + ); + } else { + console.log( + colors.red( + `Error processing ${valDir}: ${ + error instanceof Error ? error.message : String(error) + }`, + ), + ); + } + } +} + +export const command = new Command() + .name("update") + .description("Update vals from the vals directory") + .action(async () => { + for await (const dir of expandGlob("vals/*")) { + if (dir.isDirectory) { + await updateVal(dir.path); + } + } + }); + +const updateValCode = async (valId: string, code: string, apiKey: string) => { + const response = await fetch( + `https://api.val.town/v1/vals/${valId}/versions`, + { + method: "POST", + headers: { + Authorization: `Bearer ${apiKey}`, + "Content-Type": "application/json", + }, + body: JSON.stringify({ code }), + }, + ); + + if (!response.ok) { + const error = await response.text(); + console.log(colors.red(`✗ Failed to update ${valId} code: ${error}`)); + } else { + console.log(colors.green(`✓ Successfully updated ${valId} code`)); + } +}; + +const updateValReadme = async ( + valId: string, + readme: string, + apiKey: string, +) => { + const response = await fetch(`https://api.val.town/v1/vals/${valId}`, { + method: "PUT", + headers: { + Authorization: `Bearer ${apiKey}`, + "Content-Type": "application/json", + }, + body: JSON.stringify({ readme }), + }); + + if (!response.ok) { + const error = await response.text(); + console.log(colors.red(`✗ Failed to update ${valId} readme: ${error}`)); + } else { + console.log(colors.green(`✓ Successfully updated ${valId} readme`)); + } +}; diff --git a/integrations/val.town/vals/tutorial/README.md b/integrations/val.town/vals/tutorial/README.md new file mode 100644 index 000000000..c7f82d267 --- /dev/null +++ b/integrations/val.town/vals/tutorial/README.md @@ -0,0 +1,24 @@ +# Build better AI products with Braintrust + +[![Open Val Town Template](https://stevekrouse-badge.web.val.run/?3)](https://www.val.town/v/braintrust/sdk) + +[Braintrust](https://www.braintrust.dev/) helps you evaluate and ship AI products with confidence. Whether you're building a new AI application or improving an existing one, Braintrust gives you the tools to iterate faster and deploy with confidence. + +## What you can do with this SDK + +The Braintrust SDK enables you to: + +- Log experiments and production data to understand your AI system's behavior +- Run comprehensive evaluations using the `Eval` framework +- Track and improve your model's performance over time + +This template helps you get started with the Braintrust SDK. It's based on our [official GitHub repository](https://github.com/braintrustdata/braintrust-sdk). + +## Getting started + +1. Click **Fork** on this val to create your own copy +2. Get your API key from the [Braintrust settings page](https://www.braintrust.dev/app/settings?subroute=api-keys) +3. Add your API key to your project's [Environment Variables](https://www.val.town/settings/environment-variables) as `BRAINTRUST_API_KEY` +4. Click **Run** on the `tutorial` val to start experimenting + +Want to learn more? Visit our [documentation](https://www.braintrust.dev/docs) or sign up for a [free account](https://www.braintrust.dev/). diff --git a/integrations/val.town/vals/tutorial/code.ts b/integrations/val.town/vals/tutorial/code.ts new file mode 100644 index 000000000..d4f8e830c --- /dev/null +++ b/integrations/val.town/vals/tutorial/code.ts @@ -0,0 +1,21 @@ +import { LevenshteinScorer } from "npm:autoevals"; +import { Eval } from "npm:braintrust"; + +Eval("Say Hi Bot", { + data: () => { + return [ + { + input: "Foo", + expected: "Hi Foo", + }, + { + input: "Bar", + expected: "Hello Bar", + }, + ]; // Replace with your eval dataset + }, + task: (input) => { + return "Hi " + input; // Replace with your LLM call + }, + scores: [LevenshteinScorer], +}); diff --git a/integrations/val.town/vals/tutorial/config.json b/integrations/val.town/vals/tutorial/config.json new file mode 100644 index 000000000..10e20ee37 --- /dev/null +++ b/integrations/val.town/vals/tutorial/config.json @@ -0,0 +1,3 @@ +{ + "val_id": "3bb6b7c2-fc96-11ef-ad54-569c3dd06744" +}