diff --git a/.gitignore b/.gitignore index a82d4d444..15e8215d2 100644 --- a/.gitignore +++ b/.gitignore @@ -122,10 +122,6 @@ $RECYCLE.BIN/ /dist /node_modules /out/ -engine/language_client_typescript/*.d.ts -engine/language_client_typescript/*.d.ts.map -engine/language_client_typescript/*.js -!engine/language_client_typescript/cli.js engine/language_client_ruby/**/*.bundle engine/target/ Cargo.lock diff --git a/CHANGELOG.md b/CHANGELOG.md index 109c3a2eb..4be4d398b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,13 @@ All notable changes to this project will be documented in this file. See [conventional commits](https://www.conventionalcommits.org/) for commit guidelines. +## [0.48.0](https://github.com/boundaryml/baml/compare/0.47.0..0.48.0) - 2024-07-04 + + +### UNMATCHED +- improve error handling when submitting logs to api (#754) - ([49c768f](https://github.com/boundaryml/baml/commit/49c768fbe8eb8023cba28b8dc68c2553d8b2318a)) - aaronvg +- readd ts files - ([1635bf0](https://github.com/boundaryml/baml/commit/1635bf06f87a18b1f933b6c112cd38044239d5c5)) - Aaron Villalpando + ## [0.47.0](https://github.com/boundaryml/baml/compare/0.46.0..0.47.0) - 2024-07-03 ### Bug Fixes diff --git a/engine/Cargo.lock b/engine/Cargo.lock index ebe39a80b..2e9f3d418 100644 --- a/engine/Cargo.lock +++ b/engine/Cargo.lock @@ -687,7 +687,7 @@ dependencies = [ [[package]] name = "baml" -version = "0.47.0" +version = "0.48.0" dependencies = [ "anyhow", "baml-lib", @@ -728,7 +728,7 @@ dependencies = [ [[package]] name = "baml-fmt" -version = "0.47.0" +version = "0.48.0" dependencies = [ "anyhow", "baml-lib", @@ -750,7 +750,7 @@ dependencies = [ [[package]] name = "baml-lib" -version = "0.47.0" +version = "0.48.0" dependencies = [ "base64 0.13.1", "dissimilar", @@ -788,7 +788,7 @@ dependencies = [ [[package]] name = "baml-runtime" -version = "0.47.0" +version = "0.48.0" dependencies = [ "ambassador", "anyhow", @@ -865,7 +865,7 @@ dependencies = [ [[package]] name = "baml-schema-build" -version = "0.47.0" +version = "0.48.0" dependencies = [ "anyhow", "baml-runtime", @@ -897,7 +897,7 @@ dependencies = [ [[package]] name = "baml-types" -version = "0.47.0" +version = "0.48.0" dependencies = [ "indexmap 2.2.6", "minijinja", @@ -2269,7 +2269,7 @@ dependencies = [ [[package]] name = "internal-baml-codegen" -version = "0.47.0" +version = "0.48.0" dependencies = [ "anyhow", "askama", @@ -2289,7 +2289,7 @@ dependencies = [ [[package]] name = "internal-baml-core" -version = "0.47.0" +version = "0.48.0" dependencies = [ "anyhow", "baml-types", @@ -2323,7 +2323,7 @@ dependencies = [ [[package]] name = "internal-baml-diagnostics" -version = "0.47.0" +version = "0.48.0" dependencies = [ "anyhow", "colored", @@ -2336,7 +2336,7 @@ dependencies = [ [[package]] name = "internal-baml-jinja" -version = "0.47.0" +version = "0.48.0" dependencies = [ "anyhow", "askama", @@ -2353,7 +2353,7 @@ dependencies = [ [[package]] name = "internal-baml-parser-database" -version = "0.47.0" +version = "0.48.0" dependencies = [ "baml-types", "colored", @@ -2375,7 +2375,7 @@ dependencies = [ [[package]] name = "internal-baml-prompt-parser" -version = "0.47.0" +version = "0.48.0" dependencies = [ "internal-baml-diagnostics", "internal-baml-schema-ast", @@ -2387,7 +2387,7 @@ dependencies = [ [[package]] name = "internal-baml-schema-ast" -version = "0.47.0" +version = "0.48.0" dependencies = [ "baml-types", "either", @@ -2463,7 +2463,7 @@ checksum = "9dbbfed4e59ba9750e15ba154fdfd9329cee16ff3df539c2666b70f58cc32105" [[package]] name = "jsonish" -version = "0.47.0" +version = "0.48.0" dependencies = [ "anyhow", "assert-json-diff", diff --git a/engine/Cargo.toml b/engine/Cargo.toml index b04ea10fc..7310a35e2 100644 --- a/engine/Cargo.toml +++ b/engine/Cargo.toml @@ -60,7 +60,7 @@ internal-baml-core = { path = "baml-lib/baml-core" } internal-baml-jinja = { path = "baml-lib/jinja" } [workspace.package] -version = "0.47.0" +version = "0.48.0" authors = ["Boundary "] description = "BAML Toolchain" diff --git a/engine/language_client_python/pyproject.toml b/engine/language_client_python/pyproject.toml index 307d0f596..be9e2107c 100644 --- a/engine/language_client_python/pyproject.toml +++ b/engine/language_client_python/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "baml-py" -version = "0.47.0" +version = "0.48.0" description = "BAML python bindings (pyproject.toml)" readme = "README.md" authors = [["Boundary", "contact@boundaryml.com"]] diff --git a/engine/language_client_ruby/baml.gemspec b/engine/language_client_ruby/baml.gemspec index b15cd3245..a8557ba43 100644 --- a/engine/language_client_ruby/baml.gemspec +++ b/engine/language_client_ruby/baml.gemspec @@ -2,7 +2,7 @@ Gem::Specification.new do |spec| spec.name = "baml" - spec.version = "0.47.0" + spec.version = "0.48.0" spec.authors = ["BoundaryML"] spec.email = ["contact@boundaryml.com"] diff --git a/engine/language_client_typescript/async_context_vars.d.ts b/engine/language_client_typescript/async_context_vars.d.ts new file mode 100644 index 000000000..5092ab813 --- /dev/null +++ b/engine/language_client_typescript/async_context_vars.d.ts @@ -0,0 +1,15 @@ +import { BamlSpan, RuntimeContextManager, BamlRuntime, BamlLogEvent } from './native'; +export declare class BamlCtxManager { + private rt; + private ctx; + constructor(rt: BamlRuntime); + upsertTags(tags: Record): void; + cloneContext(): RuntimeContextManager; + startTrace(name: string, args: Record): [RuntimeContextManager, BamlSpan]; + endTrace(span: BamlSpan, response: any): void; + flush(): void; + onLogEvent(callback: (event: BamlLogEvent) => void): void; + traceFnSync ReturnType>(name: string, func: F): F; + traceFnAsync Promise>(name: string, func: F): F; +} +//# sourceMappingURL=async_context_vars.d.ts.map \ No newline at end of file diff --git a/engine/language_client_typescript/async_context_vars.d.ts.map b/engine/language_client_typescript/async_context_vars.d.ts.map new file mode 100644 index 000000000..04cf16e47 --- /dev/null +++ b/engine/language_client_typescript/async_context_vars.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"async_context_vars.d.ts","sourceRoot":"","sources":["typescript_src/async_context_vars.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,qBAAqB,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AAGrF,qBAAa,cAAc;IACzB,OAAO,CAAC,EAAE,CAAa;IACvB,OAAO,CAAC,GAAG,CAA0C;gBAEzC,EAAE,EAAE,WAAW;IAS3B,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI;IAK9C,YAAY,IAAI,qBAAqB;IASrC,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,CAAC,qBAAqB,EAAE,QAAQ,CAAC;IAKtF,QAAQ,CAAC,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,GAAG,IAAI;IAa7C,KAAK,IAAI,IAAI;IAIb,UAAU,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,GAAG,IAAI;IAQzD,WAAW,CAAC,UAAU,EAAE,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,GAAG,CAAC;IAuB3F,YAAY,CAAC,UAAU,EAAE,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,OAAO,CAAC,UAAU,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,GAAG,CAAC;CAuBtG"} \ No newline at end of file diff --git a/engine/language_client_typescript/async_context_vars.js b/engine/language_client_typescript/async_context_vars.js new file mode 100644 index 000000000..9b4d60636 --- /dev/null +++ b/engine/language_client_typescript/async_context_vars.js @@ -0,0 +1,98 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.BamlCtxManager = void 0; +const native_1 = require("./native"); +const async_hooks_1 = require("async_hooks"); +class BamlCtxManager { + rt; + ctx; + constructor(rt) { + this.rt = rt; + this.ctx = new async_hooks_1.AsyncLocalStorage(); + this.ctx.enterWith(rt.createContextManager()); + process.on('exit', () => { + this.rt.flush(); + }); + } + upsertTags(tags) { + const manager = this.ctx.getStore(); + manager.upsertTags(tags); + } + cloneContext() { + let store = this.ctx.getStore(); + if (store === undefined) { + store = this.rt.createContextManager(); + this.ctx.enterWith(store); + } + return store.deepClone(); + } + startTrace(name, args) { + const mng = this.cloneContext(); + return [mng, native_1.BamlSpan.new(this.rt, name, args, mng)]; + } + endTrace(span, response) { + const manager = this.ctx.getStore(); + if (!manager) { + console.error('Context lost before span could be finished\n'); + return; + } + try { + span.finish(response, manager); + } + catch (e) { + console.error('BAML internal error', e); + } + } + flush() { + this.rt.flush(); + } + onLogEvent(callback) { + this.rt.setLogEventCallback((error, param) => { + if (!error) { + callback(param); + } + }); + } + traceFnSync(name, func) { + return ((...args) => { + const params = args.reduce((acc, arg, i) => ({ + ...acc, + [`arg${i}`]: arg, // generic way to label args + }), {}); + const [mng, span] = this.startTrace(name, params); + this.ctx.run(mng, () => { + try { + const response = func(...args); + this.endTrace(span, response); + return response; + } + catch (e) { + this.endTrace(span, e); + throw e; + } + }); + }); + } + traceFnAsync(name, func) { + const funcName = name; + return (async (...args) => { + const params = args.reduce((acc, arg, i) => ({ + ...acc, + [`arg${i}`]: arg, // generic way to label args + }), {}); + const [mng, span] = this.startTrace(name, params); + await this.ctx.run(mng, async () => { + try { + const response = await func(...args); + this.endTrace(span, response); + return response; + } + catch (e) { + this.endTrace(span, e); + throw e; + } + }); + }); + } +} +exports.BamlCtxManager = BamlCtxManager; diff --git a/engine/language_client_typescript/index.d.ts b/engine/language_client_typescript/index.d.ts new file mode 100644 index 000000000..d7fb1b238 --- /dev/null +++ b/engine/language_client_typescript/index.d.ts @@ -0,0 +1,4 @@ +export { BamlRuntime, FunctionResult, FunctionResultStream, BamlImage as Image, BamlAudio as Audio, invoke_runtime_cli, } from './native'; +export { BamlStream } from './stream'; +export { BamlCtxManager } from './async_context_vars'; +//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/engine/language_client_typescript/index.d.ts.map b/engine/language_client_typescript/index.d.ts.map new file mode 100644 index 000000000..3640d5f40 --- /dev/null +++ b/engine/language_client_typescript/index.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["typescript_src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,cAAc,EACd,oBAAoB,EACpB,SAAS,IAAI,KAAK,EAClB,SAAS,IAAI,KAAK,EAClB,kBAAkB,GACnB,MAAM,UAAU,CAAA;AACjB,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AACrC,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA"} \ No newline at end of file diff --git a/engine/language_client_typescript/index.js b/engine/language_client_typescript/index.js new file mode 100644 index 000000000..1aac1f0cf --- /dev/null +++ b/engine/language_client_typescript/index.js @@ -0,0 +1,14 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.BamlCtxManager = exports.BamlStream = exports.invoke_runtime_cli = exports.Audio = exports.Image = exports.FunctionResultStream = exports.FunctionResult = exports.BamlRuntime = void 0; +var native_1 = require("./native"); +Object.defineProperty(exports, "BamlRuntime", { enumerable: true, get: function () { return native_1.BamlRuntime; } }); +Object.defineProperty(exports, "FunctionResult", { enumerable: true, get: function () { return native_1.FunctionResult; } }); +Object.defineProperty(exports, "FunctionResultStream", { enumerable: true, get: function () { return native_1.FunctionResultStream; } }); +Object.defineProperty(exports, "Image", { enumerable: true, get: function () { return native_1.BamlImage; } }); +Object.defineProperty(exports, "Audio", { enumerable: true, get: function () { return native_1.BamlAudio; } }); +Object.defineProperty(exports, "invoke_runtime_cli", { enumerable: true, get: function () { return native_1.invoke_runtime_cli; } }); +var stream_1 = require("./stream"); +Object.defineProperty(exports, "BamlStream", { enumerable: true, get: function () { return stream_1.BamlStream; } }); +var async_context_vars_1 = require("./async_context_vars"); +Object.defineProperty(exports, "BamlCtxManager", { enumerable: true, get: function () { return async_context_vars_1.BamlCtxManager; } }); diff --git a/engine/language_client_typescript/native.d.ts b/engine/language_client_typescript/native.d.ts new file mode 100644 index 000000000..eb8b4ba74 --- /dev/null +++ b/engine/language_client_typescript/native.d.ts @@ -0,0 +1,117 @@ +/* auto-generated by NAPI-RS */ +/* eslint-disable */ +export class BamlAudio { + static fromUrl(url: string): BamlAudio + static fromBase64(mediaType: string, base64: string): BamlAudio + isUrl(): boolean + asUrl(): string + asBase64(): [string, string] + toJSON(): any +} + +export class BamlImage { + static fromUrl(url: string): BamlImage + static fromBase64(mediaType: string, base64: string): BamlImage + isUrl(): boolean + asUrl(): string + asBase64(): [string, string] + toJSON(): any +} + +export class BamlRuntime { + static fromDirectory(directory: string, envVars: Record): BamlRuntime + static fromFiles(rootPath: string, files: Record, envVars: Record): BamlRuntime + createContextManager(): RuntimeContextManager + callFunction(functionName: string, args: { [string]: any }, ctx: RuntimeContextManager, tb?: TypeBuilder | undefined | null): Promise + streamFunction(functionName: string, args: { [string]: any }, cb: (err: any, param: FunctionResult) => void, ctx: RuntimeContextManager, tb?: TypeBuilder | undefined | null): FunctionResultStream + setLogEventCallback(func: (err: any, param: BamlLogEvent) => void): void + flush(): void + drainStats(): TraceStats +} + +export class BamlSpan { + static new(runtime: BamlRuntime, functionName: string, args: any, ctx: RuntimeContextManager): BamlSpan + finish(result: any, ctx: RuntimeContextManager): any +} + +export class ClassBuilder { + field(): FieldType + property(name: string): ClassPropertyBuilder +} + +export class ClassPropertyBuilder { + setType(fieldType: FieldType): ClassPropertyBuilder + alias(alias?: string | undefined | null): ClassPropertyBuilder + description(description?: string | undefined | null): ClassPropertyBuilder +} + +export class EnumBuilder { + value(name: string): EnumValueBuilder + alias(alias?: string | undefined | null): EnumBuilder + field(): FieldType +} + +export class EnumValueBuilder { + alias(alias?: string | undefined | null): EnumValueBuilder + skip(skip?: boolean | undefined | null): EnumValueBuilder + description(description?: string | undefined | null): EnumValueBuilder +} + +export class FieldType { + list(): FieldType + optional(): FieldType +} + +export class FunctionResult { + parsed(): any +} + +export class FunctionResultStream { + onEvent(func: (err: any, param: FunctionResult) => void): void + done(rctx: RuntimeContextManager): Promise +} + +export class RuntimeContextManager { + upsertTags(tags: any): void + deepClone(): RuntimeContextManager +} + +export class TraceStats { + get failed(): number + get started(): number + get finalized(): number + get submitted(): number + get sent(): number + get done(): number + toJson(): string +} + +export class TypeBuilder { + constructor() + getEnum(name: string): EnumBuilder + getClass(name: string): ClassBuilder + list(inner: FieldType): FieldType + optional(inner: FieldType): FieldType + string(): FieldType + int(): FieldType + float(): FieldType + bool(): FieldType + null(): FieldType +} + +export interface BamlLogEvent { + metadata: LogEventMetadata + prompt?: string + rawOutput?: string + parsedOutput?: string + startTime: string +} + +export function invoke_runtime_cli(params: Array): void + +export interface LogEventMetadata { + eventId: string + parentId?: string + rootEventId: string +} + diff --git a/engine/language_client_typescript/native.js b/engine/language_client_typescript/native.js new file mode 100644 index 000000000..ea0bd1193 --- /dev/null +++ b/engine/language_client_typescript/native.js @@ -0,0 +1,378 @@ +// prettier-ignore +/* eslint-disable */ +/* auto-generated by NAPI-RS */ + +const { readFileSync } = require('fs') + +let nativeBinding = null +const loadErrors = [] + +const isMusl = () => { + let musl = false + if (process.platform === 'linux') { + musl = isMuslFromFilesystem() + if (musl === null) { + musl = isMuslFromReport() + } + if (musl === null) { + musl = isMuslFromChildProcess() + } + } + return musl +} + +const isFileMusl = (f) => f.includes('libc.musl-') || f.includes('ld-musl-') + +const isMuslFromFilesystem = () => { + try { + return readFileSync('/usr/bin/ldd', 'utf-8').includes('musl') + } catch { + return null + } +} + +const isMuslFromReport = () => { + const report = typeof process.report.getReport === 'function' ? process.report.getReport() : null + if (!report) { + return null + } + if (report.header && report.header.glibcVersionRuntime) { + return false + } + if (Array.isArray(report.sharedObjects)) { + if (report.sharedObjects.some(isFileMusl)) { + return true + } + } + return false +} + +const isMuslFromChildProcess = () => { + try { + return require('child_process').execSync('ldd --version', { encoding: 'utf8' }).includes('musl') + } catch (e) { + // If we reach this case, we don't know if the system is musl or not, so is better to just fallback to false + return false + } +} + +function requireNative() { + if (process.platform === 'android') { + if (process.arch === 'arm64') { + try { + return require('./baml.android-arm64.node') + } catch (e) { + loadErrors.push(e) + } + try { + return require('@boundaryml/baml-android-arm64') + } catch (e) { + loadErrors.push(e) + } + + } else if (process.arch === 'arm') { + try { + return require('./baml.android-arm-eabi.node') + } catch (e) { + loadErrors.push(e) + } + try { + return require('@boundaryml/baml-android-arm-eabi') + } catch (e) { + loadErrors.push(e) + } + + } else { + loadErrors.push(new Error(`Unsupported architecture on Android ${process.arch}`)) + } + } else if (process.platform === 'win32') { + if (process.arch === 'x64') { + try { + return require('./baml.win32-x64-msvc.node') + } catch (e) { + loadErrors.push(e) + } + try { + return require('@boundaryml/baml-win32-x64-msvc') + } catch (e) { + loadErrors.push(e) + } + + } else if (process.arch === 'ia32') { + try { + return require('./baml.win32-ia32-msvc.node') + } catch (e) { + loadErrors.push(e) + } + try { + return require('@boundaryml/baml-win32-ia32-msvc') + } catch (e) { + loadErrors.push(e) + } + + } else if (process.arch === 'arm64') { + try { + return require('./baml.win32-arm64-msvc.node') + } catch (e) { + loadErrors.push(e) + } + try { + return require('@boundaryml/baml-win32-arm64-msvc') + } catch (e) { + loadErrors.push(e) + } + + } else { + loadErrors.push(new Error(`Unsupported architecture on Windows: ${process.arch}`)) + } + } else if (process.platform === 'darwin') { + try { + return require('./baml.darwin-universal.node') + } catch (e) { + loadErrors.push(e) + } + try { + return require('@boundaryml/baml-darwin-universal') + } catch (e) { + loadErrors.push(e) + } + + if (process.arch === 'x64') { + try { + return require('./baml.darwin-x64.node') + } catch (e) { + loadErrors.push(e) + } + try { + return require('@boundaryml/baml-darwin-x64') + } catch (e) { + loadErrors.push(e) + } + + } else if (process.arch === 'arm64') { + try { + return require('./baml.darwin-arm64.node') + } catch (e) { + loadErrors.push(e) + } + try { + return require('@boundaryml/baml-darwin-arm64') + } catch (e) { + loadErrors.push(e) + } + + } else { + loadErrors.push(new Error(`Unsupported architecture on macOS: ${process.arch}`)) + } + } else if (process.platform === 'freebsd') { + if (process.arch === 'x64') { + try { + return require('./baml.freebsd-x64.node') + } catch (e) { + loadErrors.push(e) + } + try { + return require('@boundaryml/baml-freebsd-x64') + } catch (e) { + loadErrors.push(e) + } + + } else if (process.arch === 'arm64') { + try { + return require('./baml.freebsd-arm64.node') + } catch (e) { + loadErrors.push(e) + } + try { + return require('@boundaryml/baml-freebsd-arm64') + } catch (e) { + loadErrors.push(e) + } + + } else { + loadErrors.push(new Error(`Unsupported architecture on FreeBSD: ${process.arch}`)) + } + } else if (process.platform === 'linux') { + if (process.arch === 'x64') { + if (isMusl()) { + try { + return require('./baml.linux-x64-musl.node') + } catch (e) { + loadErrors.push(e) + } + try { + return require('@boundaryml/baml-linux-x64-musl') + } catch (e) { + loadErrors.push(e) + } + + } else { + try { + return require('./baml.linux-x64-gnu.node') + } catch (e) { + loadErrors.push(e) + } + try { + return require('@boundaryml/baml-linux-x64-gnu') + } catch (e) { + loadErrors.push(e) + } + + } + } else if (process.arch === 'arm64') { + if (isMusl()) { + try { + return require('./baml.linux-arm64-musl.node') + } catch (e) { + loadErrors.push(e) + } + try { + return require('@boundaryml/baml-linux-arm64-musl') + } catch (e) { + loadErrors.push(e) + } + + } else { + try { + return require('./baml.linux-arm64-gnu.node') + } catch (e) { + loadErrors.push(e) + } + try { + return require('@boundaryml/baml-linux-arm64-gnu') + } catch (e) { + loadErrors.push(e) + } + + } + } else if (process.arch === 'arm') { + if (isMusl()) { + try { + return require('./baml.linux-arm-musleabihf.node') + } catch (e) { + loadErrors.push(e) + } + try { + return require('@boundaryml/baml-linux-arm-musleabihf') + } catch (e) { + loadErrors.push(e) + } + + } else { + try { + return require('./baml.linux-arm-gnueabihf.node') + } catch (e) { + loadErrors.push(e) + } + try { + return require('@boundaryml/baml-linux-arm-gnueabihf') + } catch (e) { + loadErrors.push(e) + } + + } + } else if (process.arch === 'riscv64') { + if (isMusl()) { + try { + return require('./baml.linux-riscv64-musl.node') + } catch (e) { + loadErrors.push(e) + } + try { + return require('@boundaryml/baml-linux-riscv64-musl') + } catch (e) { + loadErrors.push(e) + } + + } else { + try { + return require('./baml.linux-riscv64-gnu.node') + } catch (e) { + loadErrors.push(e) + } + try { + return require('@boundaryml/baml-linux-riscv64-gnu') + } catch (e) { + loadErrors.push(e) + } + + } + } else if (process.arch === 'ppc64') { + try { + return require('./baml.linux-ppc64-gnu.node') + } catch (e) { + loadErrors.push(e) + } + try { + return require('@boundaryml/baml-linux-ppc64-gnu') + } catch (e) { + loadErrors.push(e) + } + + } else if (process.arch === 's390x') { + try { + return require('./baml.linux-s390x-gnu.node') + } catch (e) { + loadErrors.push(e) + } + try { + return require('@boundaryml/baml-linux-s390x-gnu') + } catch (e) { + loadErrors.push(e) + } + + } else { + loadErrors.push(new Error(`Unsupported architecture on Linux: ${process.arch}`)) + } + } else { + loadErrors.push(new Error(`Unsupported OS: ${process.platform}, architecture: ${process.arch}`)) + } +} + +nativeBinding = requireNative() + +if (!nativeBinding || process.env.NAPI_RS_FORCE_WASI) { + try { + nativeBinding = require('./baml.wasi.cjs') + } catch (err) { + if (process.env.NAPI_RS_FORCE_WASI) { + console.error(err) + } + } + if (!nativeBinding) { + try { + nativeBinding = require('@boundaryml/baml-wasm32-wasi') + } catch (err) { + if (process.env.NAPI_RS_FORCE_WASI) { + console.error(err) + } + } + } +} + +if (!nativeBinding) { + if (loadErrors.length > 0) { + // TODO Link to documentation with potential fixes + // - The package owner could build/publish bindings for this arch + // - The user may need to bundle the correct files + // - The user may need to re-install node_modules to get new packages + throw new Error('Failed to load native binding', { cause: loadErrors }) + } + throw new Error(`Failed to load native binding`) +} + +module.exports.BamlAudio = nativeBinding.BamlAudio +module.exports.BamlImage = nativeBinding.BamlImage +module.exports.BamlRuntime = nativeBinding.BamlRuntime +module.exports.BamlSpan = nativeBinding.BamlSpan +module.exports.ClassBuilder = nativeBinding.ClassBuilder +module.exports.ClassPropertyBuilder = nativeBinding.ClassPropertyBuilder +module.exports.EnumBuilder = nativeBinding.EnumBuilder +module.exports.EnumValueBuilder = nativeBinding.EnumValueBuilder +module.exports.FieldType = nativeBinding.FieldType +module.exports.FunctionResult = nativeBinding.FunctionResult +module.exports.FunctionResultStream = nativeBinding.FunctionResultStream +module.exports.RuntimeContextManager = nativeBinding.RuntimeContextManager +module.exports.TraceStats = nativeBinding.TraceStats +module.exports.TypeBuilder = nativeBinding.TypeBuilder +module.exports.invoke_runtime_cli = nativeBinding.invoke_runtime_cli diff --git a/engine/language_client_typescript/package.json b/engine/language_client_typescript/package.json index 0b1fb50b7..c8145e10c 100644 --- a/engine/language_client_typescript/package.json +++ b/engine/language_client_typescript/package.json @@ -1,6 +1,6 @@ { "name": "@boundaryml/baml", - "version": "0.47.0", + "version": "0.48.0", "description": "BAML typescript bindings (package.json)", "repository": { "type": "git", diff --git a/engine/language_client_typescript/stream.d.ts b/engine/language_client_typescript/stream.d.ts new file mode 100644 index 000000000..dd7f000cd --- /dev/null +++ b/engine/language_client_typescript/stream.d.ts @@ -0,0 +1,15 @@ +import { FunctionResult, FunctionResultStream, RuntimeContextManager } from './native'; +export declare class BamlStream { + private ffiStream; + private partialCoerce; + private finalCoerce; + private ctxManager; + private task; + private eventQueue; + constructor(ffiStream: FunctionResultStream, partialCoerce: (result: FunctionResult) => PartialOutputType, finalCoerce: (result: FunctionResult) => FinalOutputType, ctxManager: RuntimeContextManager); + private driveToCompletion; + private driveToCompletionInBg; + [Symbol.asyncIterator](): AsyncIterableIterator; + getFinalResponse(): Promise; +} +//# sourceMappingURL=stream.d.ts.map \ No newline at end of file diff --git a/engine/language_client_typescript/stream.d.ts.map b/engine/language_client_typescript/stream.d.ts.map new file mode 100644 index 000000000..7c571df13 --- /dev/null +++ b/engine/language_client_typescript/stream.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"stream.d.ts","sourceRoot":"","sources":["typescript_src/stream.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAA;AAEtF,qBAAa,UAAU,CAAC,iBAAiB,EAAE,eAAe;IAMtD,OAAO,CAAC,SAAS;IACjB,OAAO,CAAC,aAAa;IACrB,OAAO,CAAC,WAAW;IACnB,OAAO,CAAC,UAAU;IARpB,OAAO,CAAC,IAAI,CAAuC;IAEnD,OAAO,CAAC,UAAU,CAAgC;gBAGxC,SAAS,EAAE,oBAAoB,EAC/B,aAAa,EAAE,CAAC,MAAM,EAAE,cAAc,KAAK,iBAAiB,EAC5D,WAAW,EAAE,CAAC,MAAM,EAAE,cAAc,KAAK,eAAe,EACxD,UAAU,EAAE,qBAAqB;YAG7B,iBAAiB;IAiB/B,OAAO,CAAC,qBAAqB;IAQtB,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,qBAAqB,CAAC,iBAAiB,CAAC;IAmBnE,gBAAgB,IAAI,OAAO,CAAC,eAAe,CAAC;CAKnD"} \ No newline at end of file diff --git a/engine/language_client_typescript/stream.js b/engine/language_client_typescript/stream.js new file mode 100644 index 000000000..b7d6ae5f1 --- /dev/null +++ b/engine/language_client_typescript/stream.js @@ -0,0 +1,59 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.BamlStream = void 0; +class BamlStream { + ffiStream; + partialCoerce; + finalCoerce; + ctxManager; + task = null; + eventQueue = []; + constructor(ffiStream, partialCoerce, finalCoerce, ctxManager) { + this.ffiStream = ffiStream; + this.partialCoerce = partialCoerce; + this.finalCoerce = finalCoerce; + this.ctxManager = ctxManager; + } + async driveToCompletion() { + try { + this.ffiStream.onEvent((err, data) => { + if (err) { + return; + } + else { + this.eventQueue.push(data); + } + }); + const retval = await this.ffiStream.done(this.ctxManager); + return retval; + } + finally { + this.eventQueue.push(null); + } + } + driveToCompletionInBg() { + if (this.task === null) { + this.task = this.driveToCompletion(); + } + return this.task; + } + async *[Symbol.asyncIterator]() { + this.driveToCompletionInBg(); + while (true) { + const event = this.eventQueue.shift(); + if (event === undefined) { + await new Promise((resolve) => setTimeout(resolve, 100)); + continue; + } + if (event === null) { + break; + } + yield this.partialCoerce(event.parsed()); + } + } + async getFinalResponse() { + const final = await this.driveToCompletionInBg(); + return this.finalCoerce(final.parsed()); + } +} +exports.BamlStream = BamlStream; diff --git a/engine/language_client_typescript/type_builder.d.ts b/engine/language_client_typescript/type_builder.d.ts new file mode 100644 index 000000000..9a9c70b81 --- /dev/null +++ b/engine/language_client_typescript/type_builder.d.ts @@ -0,0 +1,51 @@ +import { ClassPropertyBuilder as _ClassPropertyBuilder, EnumValueBuilder, FieldType, TypeBuilder as _TypeBuilder } from './native'; +type IsLiteral = string extends T ? false : true; +type NameOf = IsLiteral extends true ? T : 'DynamicType'; +type CheckNever = [T] extends [never] ? `Error: Attempt to add value '${Value}' which is already a part of '${NameOf}'.` : T; +type ExcludeFrom = T extends U ? never : T; +type RestrictNot = IsLiteral extends true ? CheckNever, Name, Value> : Value; +export declare class TypeBuilder { + private tb; + protected classes: Set; + protected enums: Set; + constructor({ classes, enums }: { + classes: Set; + enums: Set; + }); + _tb(): _TypeBuilder; + string(): FieldType; + int(): FieldType; + float(): FieldType; + bool(): FieldType; + list(type: FieldType): FieldType; + classBuilder(name: Name, properties: Properties[]): ClassBuilder; + enumBuilder(name: Name, values: T[]): EnumBuilder; + addClass(name: Name): ClassBuilder; + addEnum(name: Name): EnumBuilder; +} +export declare class ClassBuilder { + private properties; + private bldr; + constructor(tb: _TypeBuilder, name: ClassName, properties?: Set); + type(): FieldType; + listProperties(): Array<[string, ClassPropertyBuilder]>; + addProperty(name: RestrictNot, type: FieldType): ClassPropertyBuilder; + property(name: string): ClassPropertyBuilder; +} +declare class ClassPropertyBuilder { + private bldr; + constructor(bldr: _ClassPropertyBuilder); + alias(alias: string | null): ClassPropertyBuilder; + description(description: string | null): ClassPropertyBuilder; +} +export declare class EnumBuilder { + private values; + private bldr; + constructor(tb: _TypeBuilder, name: EnumName, values?: Set); + type(): FieldType; + value(name: S | T): EnumValueBuilder; + listValues(): Array<[string, EnumValueBuilder]>; + addValue(name: RestrictNot): EnumValueBuilder; +} +export {}; +//# sourceMappingURL=type_builder.d.ts.map \ No newline at end of file diff --git a/engine/language_client_typescript/type_builder.d.ts.map b/engine/language_client_typescript/type_builder.d.ts.map new file mode 100644 index 000000000..c26a52d3a --- /dev/null +++ b/engine/language_client_typescript/type_builder.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"type_builder.d.ts","sourceRoot":"","sources":["typescript_src/type_builder.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/engine/language_client_typescript/type_builder.js b/engine/language_client_typescript/type_builder.js new file mode 100644 index 000000000..bde0e4e18 --- /dev/null +++ b/engine/language_client_typescript/type_builder.js @@ -0,0 +1,129 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.EnumBuilder = exports.ClassBuilder = exports.TypeBuilder = void 0; +const native_1 = require("./native"); +class TypeBuilder { + tb; + classes; + enums; + constructor({ classes, enums }) { + this.classes = classes; + this.enums = enums; + this.tb = new native_1.TypeBuilder(); + } + _tb() { + return this.tb; + } + string() { + return this.tb.string(); + } + int() { + return this.tb.int(); + } + float() { + return this.tb.float(); + } + bool() { + return this.tb.bool(); + } + list(type) { + return this.tb.list(type); + } + classBuilder(name, properties) { + return new ClassBuilder(this.tb, name, new Set(properties)); + } + enumBuilder(name, values) { + return new EnumBuilder(this.tb, name, new Set(values)); + } + addClass(name) { + if (this.classes.has(name)) { + throw new Error(`Class ${name} already exists`); + } + if (this.enums.has(name)) { + throw new Error(`Enum ${name} already exists`); + } + this.classes.add(name); + return new ClassBuilder(this.tb, name); + } + addEnum(name) { + if (this.classes.has(name)) { + throw new Error(`Class ${name} already exists`); + } + if (this.enums.has(name)) { + throw new Error(`Enum ${name} already exists`); + } + this.enums.add(name); + return new EnumBuilder(this.tb, name); + } +} +exports.TypeBuilder = TypeBuilder; +class ClassBuilder { + properties; + bldr; + constructor(tb, name, properties = new Set()) { + this.properties = properties; + this.bldr = tb.getClass(name); + } + type() { + return this.bldr.field(); + } + listProperties() { + return Array.from(this.properties).map((name) => [name, new ClassPropertyBuilder(this.bldr.property(name))]); + } + addProperty(name, type) { + if (this.properties.has(name)) { + throw new Error(`Property ${name} already exists.`); + } + this.properties.add(name); + return new ClassPropertyBuilder(this.bldr.property(name).setType(type)); + } + property(name) { + if (!this.properties.has(name)) { + throw new Error(`Property ${name} not found.`); + } + return new ClassPropertyBuilder(this.bldr.property(name)); + } +} +exports.ClassBuilder = ClassBuilder; +class ClassPropertyBuilder { + bldr; + constructor(bldr) { + this.bldr = bldr; + } + alias(alias) { + this.bldr.alias(alias); + return this; + } + description(description) { + this.bldr.description(description); + return this; + } +} +class EnumBuilder { + values; + bldr; + constructor(tb, name, values = new Set()) { + this.values = values; + this.bldr = tb.getEnum(name); + } + type() { + return this.bldr.field(); + } + value(name) { + if (!this.values.has(name)) { + throw new Error(`Value ${name} not found.`); + } + return this.bldr.value(name); + } + listValues() { + return Array.from(this.values).map((name) => [name, this.bldr.value(name)]); + } + addValue(name) { + if (this.values.has(name)) { + throw new Error(`Value ${name} already exists.`); + } + this.values.add(name); + return this.bldr.value(name); + } +} +exports.EnumBuilder = EnumBuilder; diff --git a/tools/versions/engine.cfg b/tools/versions/engine.cfg index 94bc35dce..f78202871 100644 --- a/tools/versions/engine.cfg +++ b/tools/versions/engine.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 0.47.0 +current_version = 0.48.0 commit = False tag = False parse = ^(?P\d+)\.(?P\d+).(?P\d+)$ diff --git a/tools/versions/python.cfg b/tools/versions/python.cfg index 4ed112094..702b4187c 100644 --- a/tools/versions/python.cfg +++ b/tools/versions/python.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 0.47.0 +current_version = 0.48.0 commit = False tag = False parse = ^(?P\d+)\.(?P\d+).(?P\d+)$ diff --git a/tools/versions/ruby.cfg b/tools/versions/ruby.cfg index 12d7588b6..53c8b1cba 100644 --- a/tools/versions/ruby.cfg +++ b/tools/versions/ruby.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 0.47.0 +current_version = 0.48.0 commit = False tag = False parse = ^(?P\d+)\.(?P\d+).(?P\d+)$ diff --git a/tools/versions/typescript.cfg b/tools/versions/typescript.cfg index 526b2a130..60f32bfc8 100644 --- a/tools/versions/typescript.cfg +++ b/tools/versions/typescript.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 0.47.0 +current_version = 0.48.0 commit = False tag = False parse = ^(?P\d+)\.(?P\d+).(?P\d+)$ diff --git a/tools/versions/vscode.cfg b/tools/versions/vscode.cfg index 66ecbd6d5..11605f006 100644 --- a/tools/versions/vscode.cfg +++ b/tools/versions/vscode.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 0.47.0 +current_version = 0.48.0 commit = False tag = False parse = ^(?P\d+)\.(?P\d+).(?P\d+)$ diff --git a/typescript/vscode-ext/packages/package.json b/typescript/vscode-ext/packages/package.json index 853ea905f..326c99cf6 100644 --- a/typescript/vscode-ext/packages/package.json +++ b/typescript/vscode-ext/packages/package.json @@ -2,7 +2,7 @@ "name": "baml-extension", "displayName": "Baml", "description": "BAML is a DSL for AI applications.", - "version": "0.47.0", + "version": "0.48.0", "publisher": "Boundary", "repository": "https://github.com/BoundaryML/baml", "homepage": "https://www.boundaryml.com",