mirror of
https://github.com/humanlayer/12-factor-agents.git
synced 2025-08-20 18:59:53 +03:00
wip
This commit is contained in:
@@ -1,125 +0,0 @@
|
||||
# Chapter 0 - Hello World
|
||||
|
||||
Let's start with a basic TypeScript setup and a hello world program.
|
||||
|
||||
Copy initial package.json
|
||||
|
||||
cp ./walkthrough/00-package.json package.json
|
||||
|
||||
<details>
|
||||
<summary>show file</summary>
|
||||
|
||||
```json
|
||||
// ./walkthrough/00-package.json
|
||||
{
|
||||
"name": "my-agent",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "tsx src/index.ts",
|
||||
"build": "tsc"
|
||||
},
|
||||
"dependencies": {
|
||||
"tsx": "^4.15.0",
|
||||
"typescript": "^5.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^20.0.0",
|
||||
"@typescript-eslint/eslint-plugin": "^6.0.0",
|
||||
"@typescript-eslint/parser": "^6.0.0",
|
||||
"eslint": "^8.0.0"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
Install dependencies
|
||||
|
||||
npm install
|
||||
|
||||
Copy tsconfig.json
|
||||
|
||||
cp ./walkthrough/00-tsconfig.json tsconfig.json
|
||||
|
||||
<details>
|
||||
<summary>show file</summary>
|
||||
|
||||
```json
|
||||
// ./walkthrough/00-tsconfig.json
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2017",
|
||||
"lib": ["esnext"],
|
||||
"allowJs": true,
|
||||
"skipLibCheck": true,
|
||||
"strict": true,
|
||||
"noEmit": true,
|
||||
"esModuleInterop": true,
|
||||
"module": "esnext",
|
||||
"moduleResolution": "bundler",
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"jsx": "preserve",
|
||||
"incremental": true,
|
||||
"plugins": [],
|
||||
"paths": {
|
||||
"@/*": ["./*"]
|
||||
}
|
||||
},
|
||||
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
|
||||
"exclude": ["node_modules", "walkthrough"]
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
add .gitignore
|
||||
|
||||
cp ./walkthrough/00-.gitignore .gitignore
|
||||
|
||||
<details>
|
||||
<summary>show file</summary>
|
||||
|
||||
```gitignore
|
||||
// ./walkthrough/00-.gitignore
|
||||
baml_src/
|
||||
node_modules/
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
Create src folder
|
||||
|
||||
mkdir -p src
|
||||
|
||||
Add a simple hello world index.ts
|
||||
|
||||
cp ./walkthrough/00-index.ts src/index.ts
|
||||
|
||||
<details>
|
||||
<summary>show file</summary>
|
||||
|
||||
```ts
|
||||
// ./walkthrough/00-index.ts
|
||||
async function hello(): Promise<void> {
|
||||
console.log('hello, world!')
|
||||
}
|
||||
|
||||
async function main() {
|
||||
await hello()
|
||||
}
|
||||
|
||||
main().catch(console.error)
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
Run it to verify
|
||||
|
||||
npx tsx src/index.ts
|
||||
|
||||
You should see:
|
||||
|
||||
hello, world!
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
baml_src/
|
||||
node_modules/
|
||||
@@ -1,9 +0,0 @@
|
||||
async function hello(): Promise<void> {
|
||||
console.log('hello, world!')
|
||||
}
|
||||
|
||||
async function main() {
|
||||
await hello()
|
||||
}
|
||||
|
||||
main().catch(console.error)
|
||||
@@ -1,20 +0,0 @@
|
||||
{
|
||||
"name": "my-agent",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "tsx src/index.ts",
|
||||
"build": "tsc"
|
||||
},
|
||||
"dependencies": {
|
||||
"tsx": "^4.15.0",
|
||||
"typescript": "^5.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^20.0.0",
|
||||
"@typescript-eslint/eslint-plugin": "^6.0.0",
|
||||
"@typescript-eslint/parser": "^6.0.0",
|
||||
"eslint": "^8.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2017",
|
||||
"lib": ["esnext"],
|
||||
"allowJs": true,
|
||||
"skipLibCheck": true,
|
||||
"strict": true,
|
||||
"noEmit": true,
|
||||
"esModuleInterop": true,
|
||||
"module": "esnext",
|
||||
"moduleResolution": "bundler",
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"jsx": "preserve",
|
||||
"incremental": true,
|
||||
"plugins": [],
|
||||
"paths": {
|
||||
"@/*": ["./*"]
|
||||
}
|
||||
},
|
||||
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
|
||||
"exclude": ["node_modules", "walkthrough"]
|
||||
}
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
baml_src/
|
||||
node_modules/
|
||||
@@ -1,181 +0,0 @@
|
||||
# Chapter 1 - CLI and Agent Loop
|
||||
|
||||
Now let's add BAML and create our first agent with a CLI interface.
|
||||
|
||||
Install BAML
|
||||
|
||||
npm i baml
|
||||
|
||||
Initialize BAML
|
||||
|
||||
npx baml-cli init
|
||||
|
||||
Remove default resume.baml
|
||||
|
||||
rm baml_src/resume.baml
|
||||
|
||||
Add our starter agent
|
||||
|
||||
cp ./walkthrough/01-agent.baml baml_src/agent.baml
|
||||
|
||||
<details>
|
||||
<summary>show file</summary>
|
||||
|
||||
```rust
|
||||
// ./walkthrough/01-agent.baml
|
||||
class DoneForNow {
|
||||
intent "done_for_now"
|
||||
message string
|
||||
}
|
||||
|
||||
function DetermineNextStep(
|
||||
thread: string
|
||||
) -> DoneForNow {
|
||||
client "openai/gpt-4o"
|
||||
|
||||
prompt #"
|
||||
{{ _.role("system") }}
|
||||
|
||||
You are a helpful assistant that can help with tasks.
|
||||
|
||||
{{ _.role("user") }}
|
||||
|
||||
You are working on the following thread:
|
||||
|
||||
{{ thread }}
|
||||
|
||||
What should the next step be?
|
||||
|
||||
{{ ctx.output_format }}
|
||||
"#
|
||||
}
|
||||
|
||||
test HelloWorld {
|
||||
functions [DetermineNextStep]
|
||||
args {
|
||||
thread #"
|
||||
{
|
||||
"type": "user_input",
|
||||
"data": "hello!"
|
||||
}
|
||||
"#
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
Generate BAML client code
|
||||
|
||||
npx baml-cli generate
|
||||
|
||||
Enable BAML logging for development
|
||||
|
||||
export BAML_LOG=debug
|
||||
|
||||
Add the CLI interface
|
||||
|
||||
cp ./walkthrough/01-cli.ts src/cli.ts
|
||||
|
||||
<details>
|
||||
<summary>show file</summary>
|
||||
|
||||
```ts
|
||||
// ./walkthrough/01-cli.ts
|
||||
// cli.ts lets you invoke the agent loop from the command line
|
||||
|
||||
import { agentLoop, Thread, Event } from "./agent";
|
||||
|
||||
export async function cli() {
|
||||
// Get command line arguments, skipping the first two (node and script name)
|
||||
const args = process.argv.slice(2);
|
||||
|
||||
if (args.length === 0) {
|
||||
console.error("Error: Please provide a message as a command line argument");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// Join all arguments into a single message
|
||||
const message = args.join(" ");
|
||||
|
||||
// Create a new thread with the user's message as the initial event
|
||||
const thread = new Thread([{ type: "user_input", data: message }]);
|
||||
|
||||
// Run the agent loop with the thread
|
||||
const result = await agentLoop(thread);
|
||||
console.log(result);
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
Update index.ts to use the CLI
|
||||
|
||||
```diff
|
||||
src/index.ts
|
||||
+import { cli } from "./cli"
|
||||
+
|
||||
async function hello(): Promise<void> {
|
||||
console.log('hello, world!')
|
||||
|
||||
async function main() {
|
||||
- await hello()
|
||||
+ await cli()
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>skip this step</summary>
|
||||
|
||||
cp ./walkthrough/01-index.ts src/index.ts
|
||||
|
||||
</details>
|
||||
|
||||
Add the agent implementation
|
||||
|
||||
cp ./walkthrough/01-agent.ts src/agent.ts
|
||||
|
||||
<details>
|
||||
<summary>show file</summary>
|
||||
|
||||
```ts
|
||||
// ./walkthrough/01-agent.ts
|
||||
import { b } from "../baml_client";
|
||||
|
||||
// tool call or a respond to human tool
|
||||
type AgentResponse = Awaited<ReturnType<typeof b.DetermineNextStep>>;
|
||||
|
||||
export interface Event {
|
||||
type: string
|
||||
data: any;
|
||||
}
|
||||
|
||||
export class Thread {
|
||||
events: Event[] = [];
|
||||
|
||||
constructor(events: Event[]) {
|
||||
this.events = events;
|
||||
}
|
||||
|
||||
serializeForLLM() {
|
||||
// can change this to whatever custom serialization you want to do, XML, etc
|
||||
// e.g. https://github.com/got-agents/agents/blob/59ebbfa236fc376618f16ee08eb0f3bf7b698892/linear-assistant-ts/src/agent.ts#L66-L105
|
||||
return JSON.stringify(this.events);
|
||||
}
|
||||
}
|
||||
|
||||
// right now this just runs one turn with the LLM, but
|
||||
// we'll update this function to handle all the agent logic
|
||||
export async function agentLoop(thread: Thread): Promise<AgentResponse> {
|
||||
const nextStep = await b.DetermineNextStep(thread.serializeForLLM());
|
||||
return nextStep;
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
Try it out
|
||||
|
||||
npx tsx src/index.ts hello
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,20 +0,0 @@
|
||||
{
|
||||
"name": "my-agent",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "tsx src/index.ts",
|
||||
"build": "tsc"
|
||||
},
|
||||
"dependencies": {
|
||||
"tsx": "^4.15.0",
|
||||
"typescript": "^5.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^20.0.0",
|
||||
"@typescript-eslint/eslint-plugin": "^6.0.0",
|
||||
"@typescript-eslint/parser": "^6.0.0",
|
||||
"eslint": "^8.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
async function hello(): Promise<void> {
|
||||
console.log('hello, world!')
|
||||
}
|
||||
|
||||
async function main() {
|
||||
await hello()
|
||||
}
|
||||
|
||||
main().catch(console.error)
|
||||
@@ -1,24 +0,0 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2017",
|
||||
"lib": ["esnext"],
|
||||
"allowJs": true,
|
||||
"skipLibCheck": true,
|
||||
"strict": true,
|
||||
"noEmit": true,
|
||||
"esModuleInterop": true,
|
||||
"module": "esnext",
|
||||
"moduleResolution": "bundler",
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"jsx": "preserve",
|
||||
"incremental": true,
|
||||
"plugins": [],
|
||||
"paths": {
|
||||
"@/*": ["./*"]
|
||||
}
|
||||
},
|
||||
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
|
||||
"exclude": ["node_modules", "walkthrough"]
|
||||
}
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
class DoneForNow {
|
||||
intent "done_for_now"
|
||||
message string
|
||||
}
|
||||
|
||||
function DetermineNextStep(
|
||||
thread: string
|
||||
) -> DoneForNow {
|
||||
client "openai/gpt-4o"
|
||||
|
||||
prompt #"
|
||||
{{ _.role("system") }}
|
||||
|
||||
You are a helpful assistant that can help with tasks.
|
||||
|
||||
{{ _.role("user") }}
|
||||
|
||||
You are working on the following thread:
|
||||
|
||||
{{ thread }}
|
||||
|
||||
What should the next step be?
|
||||
|
||||
{{ ctx.output_format }}
|
||||
"#
|
||||
}
|
||||
|
||||
test HelloWorld {
|
||||
functions [DetermineNextStep]
|
||||
args {
|
||||
thread #"
|
||||
{
|
||||
"type": "user_input",
|
||||
"data": "hello!"
|
||||
}
|
||||
"#
|
||||
}
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
import { b } from "../baml_client";
|
||||
|
||||
// tool call or a respond to human tool
|
||||
type AgentResponse = Awaited<ReturnType<typeof b.DetermineNextStep>>;
|
||||
|
||||
export interface Event {
|
||||
type: string
|
||||
data: any;
|
||||
}
|
||||
|
||||
export class Thread {
|
||||
events: Event[] = [];
|
||||
|
||||
constructor(events: Event[]) {
|
||||
this.events = events;
|
||||
}
|
||||
|
||||
serializeForLLM() {
|
||||
// can change this to whatever custom serialization you want to do, XML, etc
|
||||
// e.g. https://github.com/got-agents/agents/blob/59ebbfa236fc376618f16ee08eb0f3bf7b698892/linear-assistant-ts/src/agent.ts#L66-L105
|
||||
return JSON.stringify(this.events);
|
||||
}
|
||||
}
|
||||
|
||||
// right now this just runs one turn with the LLM, but
|
||||
// we'll update this function to handle all the agent logic
|
||||
export async function agentLoop(thread: Thread): Promise<AgentResponse> {
|
||||
const nextStep = await b.DetermineNextStep(thread.serializeForLLM());
|
||||
return nextStep;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
// cli.ts lets you invoke the agent loop from the command line
|
||||
|
||||
import { agentLoop, Thread, Event } from "./agent";
|
||||
|
||||
export async function cli() {
|
||||
// Get command line arguments, skipping the first two (node and script name)
|
||||
const args = process.argv.slice(2);
|
||||
|
||||
if (args.length === 0) {
|
||||
console.error("Error: Please provide a message as a command line argument");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// Join all arguments into a single message
|
||||
const message = args.join(" ");
|
||||
|
||||
// Create a new thread with the user's message as the initial event
|
||||
const thread = new Thread([{ type: "user_input", data: message }]);
|
||||
|
||||
// Run the agent loop with the thread
|
||||
const result = await agentLoop(thread);
|
||||
console.log(result);
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
import { cli } from "./cli"
|
||||
|
||||
async function hello(): Promise<void> {
|
||||
console.log('hello, world!')
|
||||
}
|
||||
|
||||
async function main() {
|
||||
await cli()
|
||||
}
|
||||
|
||||
main().catch(console.error)
|
||||
@@ -1,2 +0,0 @@
|
||||
baml_src/
|
||||
node_modules/
|
||||
@@ -1,70 +0,0 @@
|
||||
# Chapter 2 - Add Calculator Tools
|
||||
|
||||
Let's add some calculator tools to our agent.
|
||||
|
||||
Add calculator tools definition
|
||||
|
||||
cp ./walkthrough/02-tool_calculator.baml baml_src/tool_calculator.baml
|
||||
|
||||
<details>
|
||||
<summary>show file</summary>
|
||||
|
||||
```rust
|
||||
// ./walkthrough/02-tool_calculator.baml
|
||||
type CalculatorTools = AddTool | SubtractTool | MultiplyTool | DivideTool
|
||||
|
||||
|
||||
class AddTool {
|
||||
intent "add"
|
||||
a int | float
|
||||
b int | float
|
||||
}
|
||||
|
||||
class SubtractTool {
|
||||
intent "subtract"
|
||||
a int | float
|
||||
b int | float
|
||||
}
|
||||
|
||||
class MultiplyTool {
|
||||
intent "multiply"
|
||||
a int | float
|
||||
b int | float
|
||||
}
|
||||
|
||||
class DivideTool {
|
||||
intent "divide"
|
||||
a int | float
|
||||
b int | float
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
Update agent to use calculator tools
|
||||
|
||||
```diff
|
||||
baml_src/agent.baml
|
||||
function DetermineNextStep(
|
||||
thread: string
|
||||
-) -> DoneForNow {
|
||||
+) -> CalculatorTools | DoneForNow {
|
||||
client "openai/gpt-4o"
|
||||
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>skip this step</summary>
|
||||
|
||||
cp ./walkthrough/02-agent.baml baml_src/agent.baml
|
||||
|
||||
</details>
|
||||
|
||||
Generate updated BAML client
|
||||
|
||||
npx baml-cli generate
|
||||
|
||||
Try out the calculator
|
||||
|
||||
npx tsx src/index.ts 'can you add 3 and 4'
|
||||
|
||||
@@ -1,154 +0,0 @@
|
||||
/*************************************************************************************************
|
||||
|
||||
Welcome to Baml! To use this generated code, please run one of the following:
|
||||
|
||||
$ npm install @boundaryml/baml
|
||||
$ yarn add @boundaryml/baml
|
||||
$ pnpm add @boundaryml/baml
|
||||
|
||||
*************************************************************************************************/
|
||||
|
||||
// This file was generated by BAML: do not edit it. Instead, edit the BAML
|
||||
// files and re-generate this code.
|
||||
//
|
||||
/* eslint-disable */
|
||||
// tslint:disable
|
||||
// @ts-nocheck
|
||||
// biome-ignore format: autogenerated code
|
||||
import type { BamlRuntime, FunctionResult, BamlCtxManager, ClientRegistry, Image, Audio, Collector } from "@boundaryml/baml"
|
||||
import { toBamlError, BamlStream, type HTTPRequest } from "@boundaryml/baml"
|
||||
import type { Checked, Check, RecursivePartialNull as MovedRecursivePartialNull } from "./types"
|
||||
import type { partial_types } from "./partial_types"
|
||||
import type * as types from "./types"
|
||||
import type {DoneForNow} from "./types"
|
||||
import type TypeBuilder from "./type_builder"
|
||||
import { AsyncHttpRequest, AsyncHttpStreamRequest } from "./async_request"
|
||||
import { LlmResponseParser, LlmStreamParser } from "./parser"
|
||||
import { DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_CTX, DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_RUNTIME } from "./globals"
|
||||
|
||||
/**
|
||||
* @deprecated Use RecursivePartialNull from 'baml_client/types' instead.
|
||||
*/
|
||||
export type RecursivePartialNull<T> = MovedRecursivePartialNull<T>
|
||||
|
||||
type BamlCallOptions = {
|
||||
tb?: TypeBuilder
|
||||
clientRegistry?: ClientRegistry
|
||||
collector?: Collector | Collector[]
|
||||
}
|
||||
|
||||
export class BamlAsyncClient {
|
||||
private runtime: BamlRuntime
|
||||
private ctxManager: BamlCtxManager
|
||||
private streamClient: BamlStreamClient
|
||||
private httpRequest: AsyncHttpRequest
|
||||
private httpStreamRequest: AsyncHttpStreamRequest
|
||||
private llmResponseParser: LlmResponseParser
|
||||
private llmStreamParser: LlmStreamParser
|
||||
private bamlOptions: BamlCallOptions
|
||||
|
||||
constructor(runtime: BamlRuntime, ctxManager: BamlCtxManager, bamlOptions?: BamlCallOptions) {
|
||||
this.runtime = runtime
|
||||
this.ctxManager = ctxManager
|
||||
this.streamClient = new BamlStreamClient(runtime, ctxManager, bamlOptions)
|
||||
this.httpRequest = new AsyncHttpRequest(runtime, ctxManager)
|
||||
this.httpStreamRequest = new AsyncHttpStreamRequest(runtime, ctxManager)
|
||||
this.llmResponseParser = new LlmResponseParser(runtime, ctxManager)
|
||||
this.llmStreamParser = new LlmStreamParser(runtime, ctxManager)
|
||||
this.bamlOptions = bamlOptions || {}
|
||||
}
|
||||
|
||||
withOptions(bamlOptions: BamlCallOptions) {
|
||||
return new BamlAsyncClient(this.runtime, this.ctxManager, bamlOptions)
|
||||
}
|
||||
|
||||
get stream() {
|
||||
return this.streamClient
|
||||
}
|
||||
|
||||
get request() {
|
||||
return this.httpRequest
|
||||
}
|
||||
|
||||
get streamRequest() {
|
||||
return this.httpStreamRequest
|
||||
}
|
||||
|
||||
get parse() {
|
||||
return this.llmResponseParser
|
||||
}
|
||||
|
||||
get parseStream() {
|
||||
return this.llmStreamParser
|
||||
}
|
||||
|
||||
|
||||
async DetermineNextStep(
|
||||
thread: string,
|
||||
__baml_options__?: BamlCallOptions
|
||||
): Promise<DoneForNow> {
|
||||
try {
|
||||
const options = { ...this.bamlOptions, ...(__baml_options__ || {}) }
|
||||
const collector = options.collector ? (Array.isArray(options.collector) ? options.collector : [options.collector]) : [];
|
||||
const raw = await this.runtime.callFunction(
|
||||
"DetermineNextStep",
|
||||
{
|
||||
"thread": thread
|
||||
},
|
||||
this.ctxManager.cloneContext(),
|
||||
options.tb?.__tb(),
|
||||
options.clientRegistry,
|
||||
collector,
|
||||
)
|
||||
return raw.parsed(false) as DoneForNow
|
||||
} catch (error) {
|
||||
throw toBamlError(error);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class BamlStreamClient {
|
||||
private runtime: BamlRuntime
|
||||
private ctxManager: BamlCtxManager
|
||||
private bamlOptions: BamlCallOptions
|
||||
|
||||
constructor(runtime: BamlRuntime, ctxManager: BamlCtxManager, bamlOptions?: BamlCallOptions) {
|
||||
this.runtime = runtime
|
||||
this.ctxManager = ctxManager
|
||||
this.bamlOptions = bamlOptions || {}
|
||||
}
|
||||
|
||||
|
||||
DetermineNextStep(
|
||||
thread: string,
|
||||
__baml_options__?: { tb?: TypeBuilder, clientRegistry?: ClientRegistry, collector?: Collector | Collector[] }
|
||||
): BamlStream<partial_types.DoneForNow, DoneForNow> {
|
||||
try {
|
||||
const options = { ...this.bamlOptions, ...(__baml_options__ || {}) }
|
||||
const collector = options.collector ? (Array.isArray(options.collector) ? options.collector : [options.collector]) : [];
|
||||
const raw = this.runtime.streamFunction(
|
||||
"DetermineNextStep",
|
||||
{
|
||||
"thread": thread
|
||||
},
|
||||
undefined,
|
||||
this.ctxManager.cloneContext(),
|
||||
options.tb?.__tb(),
|
||||
options.clientRegistry,
|
||||
collector,
|
||||
)
|
||||
return new BamlStream<partial_types.DoneForNow, DoneForNow>(
|
||||
raw,
|
||||
(a): partial_types.DoneForNow => a,
|
||||
(a): DoneForNow => a,
|
||||
this.ctxManager.cloneContext(),
|
||||
)
|
||||
} catch (error) {
|
||||
throw toBamlError(error);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export const b = new BamlAsyncClient(DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_RUNTIME, DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_CTX)
|
||||
@@ -1,80 +0,0 @@
|
||||
/*************************************************************************************************
|
||||
|
||||
Welcome to Baml! To use this generated code, please run one of the following:
|
||||
|
||||
$ npm install @boundaryml/baml
|
||||
$ yarn add @boundaryml/baml
|
||||
$ pnpm add @boundaryml/baml
|
||||
|
||||
*************************************************************************************************/
|
||||
|
||||
// This file was generated by BAML: do not edit it. Instead, edit the BAML
|
||||
// files and re-generate this code.
|
||||
//
|
||||
/* eslint-disable */
|
||||
// tslint:disable
|
||||
// @ts-nocheck
|
||||
// biome-ignore format: autogenerated code
|
||||
import type { BamlRuntime, BamlCtxManager, ClientRegistry, Image, Audio } from "@boundaryml/baml"
|
||||
import { toBamlError, HTTPRequest } from "@boundaryml/baml"
|
||||
import type { Checked, Check } from "./types"
|
||||
import type * as types from "./types"
|
||||
import type {DoneForNow} from "./types"
|
||||
import type TypeBuilder from "./type_builder"
|
||||
|
||||
type BamlCallOptions = {
|
||||
tb?: TypeBuilder
|
||||
clientRegistry?: ClientRegistry
|
||||
}
|
||||
|
||||
export class AsyncHttpRequest {
|
||||
constructor(private runtime: BamlRuntime, private ctxManager: BamlCtxManager) {}
|
||||
|
||||
|
||||
async DetermineNextStep(
|
||||
thread: string,
|
||||
__baml_options__?: BamlCallOptions
|
||||
): Promise<HTTPRequest> {
|
||||
try {
|
||||
return await this.runtime.buildRequest(
|
||||
"DetermineNextStep",
|
||||
{
|
||||
"thread": thread
|
||||
},
|
||||
this.ctxManager.cloneContext(),
|
||||
__baml_options__?.tb?.__tb(),
|
||||
__baml_options__?.clientRegistry,
|
||||
false,
|
||||
)
|
||||
} catch (error) {
|
||||
throw toBamlError(error);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export class AsyncHttpStreamRequest {
|
||||
constructor(private runtime: BamlRuntime, private ctxManager: BamlCtxManager) {}
|
||||
|
||||
|
||||
async DetermineNextStep(
|
||||
thread: string,
|
||||
__baml_options__?: BamlCallOptions
|
||||
): Promise<HTTPRequest> {
|
||||
try {
|
||||
return await this.runtime.buildRequest(
|
||||
"DetermineNextStep",
|
||||
{
|
||||
"thread": thread
|
||||
},
|
||||
this.ctxManager.cloneContext(),
|
||||
__baml_options__?.tb?.__tb(),
|
||||
__baml_options__?.clientRegistry,
|
||||
true,
|
||||
)
|
||||
} catch (error) {
|
||||
throw toBamlError(error);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
/*************************************************************************************************
|
||||
|
||||
Welcome to Baml! To use this generated code, please run one of the following:
|
||||
|
||||
$ npm install @boundaryml/baml
|
||||
$ yarn add @boundaryml/baml
|
||||
$ pnpm add @boundaryml/baml
|
||||
|
||||
*************************************************************************************************/
|
||||
|
||||
// This file was generated by BAML: do not edit it. Instead, edit the BAML
|
||||
// files and re-generate this code.
|
||||
//
|
||||
/* eslint-disable */
|
||||
// tslint:disable
|
||||
// @ts-nocheck
|
||||
// biome-ignore format: autogenerated code
|
||||
export { setLogLevel, getLogLevel, setLogJson } from "@boundaryml/baml/logging";
|
||||
export { resetBamlEnvVars } from "./globals";
|
||||
@@ -1,67 +0,0 @@
|
||||
/*************************************************************************************************
|
||||
|
||||
Welcome to Baml! To use this generated code, please run one of the following:
|
||||
|
||||
$ npm install @boundaryml/baml
|
||||
$ yarn add @boundaryml/baml
|
||||
$ pnpm add @boundaryml/baml
|
||||
|
||||
*************************************************************************************************/
|
||||
|
||||
// This file was generated by BAML: do not edit it. Instead, edit the BAML
|
||||
// files and re-generate this code.
|
||||
//
|
||||
/* eslint-disable */
|
||||
// tslint:disable
|
||||
// @ts-nocheck
|
||||
// biome-ignore format: autogenerated code
|
||||
import { BamlRuntime, BamlCtxManager } from '@boundaryml/baml'
|
||||
import { getBamlFiles } from './inlinedbaml'
|
||||
|
||||
|
||||
export const DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_RUNTIME = BamlRuntime.fromFiles(
|
||||
'baml_src',
|
||||
getBamlFiles(),
|
||||
process.env
|
||||
)
|
||||
export const DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_CTX = new BamlCtxManager(DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_RUNTIME)
|
||||
|
||||
|
||||
export function resetBamlEnvVars(envVars: Record<string, string | undefined>) {
|
||||
if (DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_CTX.allowResets()) {
|
||||
const envVarsToReset = Object.fromEntries(Object.entries(envVars).filter((kv): kv is [string, string] => kv[1] !== undefined));
|
||||
DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_RUNTIME.reset('baml_src', getBamlFiles(), envVarsToReset)
|
||||
DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_CTX.reset()
|
||||
} else {
|
||||
throw new Error('BamlError: Cannot reset BAML environment variables while there are active BAML contexts.')
|
||||
}
|
||||
}
|
||||
|
||||
const patchedLoad = (originalFn: any) => (...args: any[]) => {
|
||||
const result = originalFn(...args);
|
||||
try {
|
||||
// Dont fail if env vars fail to reset
|
||||
resetBamlEnvVars(process.env);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
try {
|
||||
const dotenv = require('dotenv');
|
||||
// Monkeypatch load function to call resetBamlEnvVars after execution
|
||||
|
||||
|
||||
// Apply the patch
|
||||
dotenv.config = patchedLoad(dotenv.config);
|
||||
dotenv.configDotenv = patchedLoad(dotenv.configDotenv);
|
||||
dotenv.populate = patchedLoad(dotenv.populate);
|
||||
} catch (error) {
|
||||
// dotenv is not installed, so we do nothing
|
||||
}
|
||||
|
||||
// also patch process.loadEnvFile
|
||||
if (process.loadEnvFile) {
|
||||
process.loadEnvFile = patchedLoad(process.loadEnvFile);
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
/*************************************************************************************************
|
||||
|
||||
Welcome to Baml! To use this generated code, please run one of the following:
|
||||
|
||||
$ npm install @boundaryml/baml
|
||||
$ yarn add @boundaryml/baml
|
||||
$ pnpm add @boundaryml/baml
|
||||
|
||||
*************************************************************************************************/
|
||||
|
||||
// This file was generated by BAML: do not edit it. Instead, edit the BAML
|
||||
// files and re-generate this code.
|
||||
//
|
||||
/* eslint-disable */
|
||||
// tslint:disable
|
||||
// @ts-nocheck
|
||||
// biome-ignore format: autogenerated code
|
||||
/**
|
||||
* If this import fails, you may need to upgrade @boundaryml/baml.
|
||||
*
|
||||
* Please upgrade @boundaryml/baml to 0.85.0.
|
||||
*
|
||||
* $ npm install @boundaryml/baml@0.85.0
|
||||
* $ yarn add @boundaryml/baml@0.85.0
|
||||
* $ pnpm add @boundaryml/baml@0.85.0
|
||||
*
|
||||
* If nothing else works, please ask for help:
|
||||
*
|
||||
* https://github.com/boundaryml/baml/issues
|
||||
* https://boundaryml.com/discord
|
||||
*
|
||||
**/
|
||||
import { ThrowIfVersionMismatch } from "@boundaryml/baml";
|
||||
|
||||
export const version = "0.85.0";
|
||||
|
||||
ThrowIfVersionMismatch(version);
|
||||
|
||||
|
||||
|
||||
export { b } from "./async_client"
|
||||
|
||||
export * from "./types"
|
||||
export type { partial_types } from "./partial_types"
|
||||
export * from "./tracing"
|
||||
export { resetBamlEnvVars } from "./globals"
|
||||
export { BamlClientHttpError, BamlValidationError, BamlClientFinishReasonError } from "@boundaryml/baml"
|
||||
@@ -1,26 +0,0 @@
|
||||
/*************************************************************************************************
|
||||
|
||||
Welcome to Baml! To use this generated code, please run one of the following:
|
||||
|
||||
$ npm install @boundaryml/baml
|
||||
$ yarn add @boundaryml/baml
|
||||
$ pnpm add @boundaryml/baml
|
||||
|
||||
*************************************************************************************************/
|
||||
|
||||
// This file was generated by BAML: do not edit it. Instead, edit the BAML
|
||||
// files and re-generate this code.
|
||||
//
|
||||
/* eslint-disable */
|
||||
// tslint:disable
|
||||
// @ts-nocheck
|
||||
// biome-ignore format: autogenerated code
|
||||
const fileMap = {
|
||||
|
||||
"agent.baml": "class DoneForNow {\n intent \"done_for_now\"\n message string \n}\n\nfunction DetermineNextStep(\n thread: string \n) -> DoneForNow {\n client \"openai/gpt-4o\"\n\n prompt #\"\n {{ _.role(\"system\") }}\n\n You are a helpful assistant that can help with tasks.\n\n {{ _.role(\"user\") }}\n\n You are working on the following thread:\n\n {{ thread }}\n\n What should the next step be?\n\n {{ ctx.output_format }}\n \"#\n}\n\ntest HelloWorld {\n functions [DetermineNextStep]\n args {\n thread #\"\n {\n \"type\": \"user_input\",\n \"data\": \"hello!\"\n }\n \"#\n }\n}",
|
||||
"clients.baml": "// Learn more about clients at https://docs.boundaryml.com/docs/snippets/clients/overview\n\nclient<llm> CustomGPT4o {\n provider openai\n options {\n model \"gpt-4o\"\n api_key env.OPENAI_API_KEY\n }\n}\n\nclient<llm> CustomGPT4oMini {\n provider openai\n retry_policy Exponential\n options {\n model \"gpt-4o-mini\"\n api_key env.OPENAI_API_KEY\n }\n}\n\nclient<llm> CustomSonnet {\n provider anthropic\n options {\n model \"claude-3-5-sonnet-20241022\"\n api_key env.ANTHROPIC_API_KEY\n }\n}\n\n\nclient<llm> CustomHaiku {\n provider anthropic\n retry_policy Constant\n options {\n model \"claude-3-haiku-20240307\"\n api_key env.ANTHROPIC_API_KEY\n }\n}\n\n// https://docs.boundaryml.com/docs/snippets/clients/round-robin\nclient<llm> CustomFast {\n provider round-robin\n options {\n // This will alternate between the two clients\n strategy [CustomGPT4oMini, CustomHaiku]\n }\n}\n\n// https://docs.boundaryml.com/docs/snippets/clients/fallback\nclient<llm> OpenaiFallback {\n provider fallback\n options {\n // This will try the clients in order until one succeeds\n strategy [CustomGPT4oMini, CustomGPT4oMini]\n }\n}\n\n// https://docs.boundaryml.com/docs/snippets/clients/retry\nretry_policy Constant {\n max_retries 3\n // Strategy is optional\n strategy {\n type constant_delay\n delay_ms 200\n }\n}\n\nretry_policy Exponential {\n max_retries 2\n // Strategy is optional\n strategy {\n type exponential_backoff\n delay_ms 300\n multiplier 1.5\n max_delay_ms 10000\n }\n}",
|
||||
"generators.baml": "// This helps use auto generate libraries you can use in the language of\n// your choice. You can have multiple generators if you use multiple languages.\n// Just ensure that the output_dir is different for each generator.\ngenerator target {\n // Valid values: \"python/pydantic\", \"typescript\", \"ruby/sorbet\", \"rest/openapi\"\n output_type \"typescript\"\n\n // Where the generated code will be saved (relative to baml_src/)\n output_dir \"../\"\n\n // The version of the BAML package you have installed (e.g. same version as your baml-py or @boundaryml/baml).\n // The BAML VSCode extension version should also match this version.\n version \"0.85.0\"\n\n // Valid values: \"sync\", \"async\"\n // This controls what `b.FunctionName()` will be (sync or async).\n default_client_mode async\n}\n",
|
||||
}
|
||||
export const getBamlFiles = () => {
|
||||
return fileMap;
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
/*************************************************************************************************
|
||||
|
||||
Welcome to Baml! To use this generated code, please run one of the following:
|
||||
|
||||
$ npm install @boundaryml/baml
|
||||
$ yarn add @boundaryml/baml
|
||||
$ pnpm add @boundaryml/baml
|
||||
|
||||
*************************************************************************************************/
|
||||
|
||||
// This file was generated by BAML: do not edit it. Instead, edit the BAML
|
||||
// files and re-generate this code.
|
||||
//
|
||||
/* eslint-disable */
|
||||
// tslint:disable
|
||||
// @ts-nocheck
|
||||
// biome-ignore format: autogenerated code
|
||||
import type { BamlRuntime, BamlCtxManager, ClientRegistry, Image, Audio, Collector } from "@boundaryml/baml"
|
||||
import { toBamlError } from "@boundaryml/baml"
|
||||
import type { Checked, Check } from "./types"
|
||||
import type { partial_types } from "./partial_types"
|
||||
import type * as types from "./types"
|
||||
import type {DoneForNow} from "./types"
|
||||
import type TypeBuilder from "./type_builder"
|
||||
|
||||
export class LlmResponseParser {
|
||||
constructor(private runtime: BamlRuntime, private ctxManager: BamlCtxManager) {}
|
||||
|
||||
|
||||
DetermineNextStep(
|
||||
llmResponse: string,
|
||||
__baml_options__?: { tb?: TypeBuilder, clientRegistry?: ClientRegistry }
|
||||
): DoneForNow {
|
||||
try {
|
||||
return this.runtime.parseLlmResponse(
|
||||
"DetermineNextStep",
|
||||
llmResponse,
|
||||
false,
|
||||
this.ctxManager.cloneContext(),
|
||||
__baml_options__?.tb?.__tb(),
|
||||
__baml_options__?.clientRegistry,
|
||||
) as DoneForNow
|
||||
} catch (error) {
|
||||
throw toBamlError(error);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export class LlmStreamParser {
|
||||
constructor(private runtime: BamlRuntime, private ctxManager: BamlCtxManager) {}
|
||||
|
||||
|
||||
DetermineNextStep(
|
||||
llmResponse: string,
|
||||
__baml_options__?: { tb?: TypeBuilder, clientRegistry?: ClientRegistry }
|
||||
): partial_types.DoneForNow {
|
||||
try {
|
||||
return this.runtime.parseLlmResponse(
|
||||
"DetermineNextStep",
|
||||
llmResponse,
|
||||
true,
|
||||
this.ctxManager.cloneContext(),
|
||||
__baml_options__?.tb?.__tb(),
|
||||
__baml_options__?.clientRegistry,
|
||||
) as partial_types.DoneForNow
|
||||
} catch (error) {
|
||||
throw toBamlError(error);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
/*************************************************************************************************
|
||||
|
||||
Welcome to Baml! To use this generated code, please run one of the following:
|
||||
|
||||
$ npm install @boundaryml/baml
|
||||
$ yarn add @boundaryml/baml
|
||||
$ pnpm add @boundaryml/baml
|
||||
|
||||
*************************************************************************************************/
|
||||
|
||||
// This file was generated by BAML: do not edit it. Instead, edit the BAML
|
||||
// files and re-generate this code.
|
||||
//
|
||||
/* eslint-disable */
|
||||
// tslint:disable
|
||||
// @ts-nocheck
|
||||
// biome-ignore format: autogenerated code
|
||||
import type { Image, Audio } from "@boundaryml/baml"
|
||||
import type { Checked, Check } from "./types"
|
||||
import type { DoneForNow } from "./types"
|
||||
import type * as types from "./types"
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* These types are used for streaming, for when an instance of a type
|
||||
* is still being built up and any of its fields is not yet fully available.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
export interface StreamState<T> {
|
||||
value: T
|
||||
state: "Pending" | "Incomplete" | "Complete"
|
||||
}
|
||||
|
||||
export namespace partial_types {
|
||||
|
||||
export interface DoneForNow {
|
||||
intent: "done_for_now"
|
||||
message?: (string | null)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,113 +0,0 @@
|
||||
/*************************************************************************************************
|
||||
|
||||
Welcome to Baml! To use this generated code, please run one of the following:
|
||||
|
||||
$ npm install @boundaryml/baml
|
||||
$ yarn add @boundaryml/baml
|
||||
$ pnpm add @boundaryml/baml
|
||||
|
||||
*************************************************************************************************/
|
||||
|
||||
// This file was generated by BAML: do not edit it. Instead, edit the BAML
|
||||
// files and re-generate this code.
|
||||
//
|
||||
/* eslint-disable */
|
||||
// tslint:disable
|
||||
// @ts-nocheck
|
||||
// biome-ignore format: autogenerated code
|
||||
import type { BamlRuntime, FunctionResult, BamlCtxManager, Image, Audio, ClientRegistry, Collector } from "@boundaryml/baml"
|
||||
import { toBamlError, type HTTPRequest } from "@boundaryml/baml"
|
||||
import type { Checked, Check, RecursivePartialNull as MovedRecursivePartialNull } from "./types"
|
||||
import type * as types from "./types"
|
||||
import type {DoneForNow} from "./types"
|
||||
import type TypeBuilder from "./type_builder"
|
||||
import { HttpRequest, HttpStreamRequest } from "./sync_request"
|
||||
import { LlmResponseParser, LlmStreamParser } from "./parser"
|
||||
import { DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_CTX, DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_RUNTIME } from "./globals"
|
||||
|
||||
/**
|
||||
* @deprecated Use RecursivePartialNull from 'baml_client/types' instead.
|
||||
* Example:
|
||||
* ```ts
|
||||
* import { RecursivePartialNull } from './baml_client/types'
|
||||
* ```
|
||||
*/
|
||||
export type RecursivePartialNull<T> = MovedRecursivePartialNull<T>;
|
||||
|
||||
type BamlCallOptions = {
|
||||
tb?: TypeBuilder
|
||||
clientRegistry?: ClientRegistry
|
||||
collector?: Collector | Collector[]
|
||||
}
|
||||
|
||||
export class BamlSyncClient {
|
||||
private httpRequest: HttpRequest
|
||||
private httpStreamRequest: HttpStreamRequest
|
||||
private llmResponseParser: LlmResponseParser
|
||||
private llmStreamParser: LlmStreamParser
|
||||
private bamlOptions: BamlCallOptions
|
||||
|
||||
constructor(private runtime: BamlRuntime, private ctxManager: BamlCtxManager, private bamlOptions?: BamlCallOptions) {
|
||||
this.httpRequest = new HttpRequest(runtime, ctxManager)
|
||||
this.httpStreamRequest = new HttpStreamRequest(runtime, ctxManager)
|
||||
this.llmResponseParser = new LlmResponseParser(runtime, ctxManager)
|
||||
this.llmStreamParser = new LlmStreamParser(runtime, ctxManager)
|
||||
this.bamlOptions = bamlOptions || {}
|
||||
}
|
||||
|
||||
withOptions(bamlOptions: BamlCallOptions) {
|
||||
return new BamlSyncClient(this.runtime, this.ctxManager, bamlOptions)
|
||||
}
|
||||
|
||||
/*
|
||||
* @deprecated NOT IMPLEMENTED as streaming must by async. We
|
||||
* are not providing an async version as we want to reserve the
|
||||
* right to provide a sync version in the future.
|
||||
*/
|
||||
get stream() {
|
||||
throw new Error("stream is not available in BamlSyncClient. Use `import { b } from 'baml_client/async_client")
|
||||
}
|
||||
|
||||
get request() {
|
||||
return this.httpRequest
|
||||
}
|
||||
|
||||
get streamRequest() {
|
||||
return this.httpStreamRequest
|
||||
}
|
||||
|
||||
get parse() {
|
||||
return this.llmResponseParser
|
||||
}
|
||||
|
||||
get parseStream() {
|
||||
return this.llmStreamParser
|
||||
}
|
||||
|
||||
|
||||
DetermineNextStep(
|
||||
thread: string,
|
||||
__baml_options__?: BamlCallOptions
|
||||
): DoneForNow {
|
||||
try {
|
||||
const options = { ...this.bamlOptions, ...(__baml_options__ || {}) }
|
||||
const collector = options.collector ? (Array.isArray(options.collector) ? options.collector : [options.collector]) : [];
|
||||
const raw = this.runtime.callFunctionSync(
|
||||
"DetermineNextStep",
|
||||
{
|
||||
"thread": thread
|
||||
},
|
||||
this.ctxManager.cloneContext(),
|
||||
options.tb?.__tb(),
|
||||
options.clientRegistry,
|
||||
collector,
|
||||
)
|
||||
return raw.parsed(false) as DoneForNow
|
||||
} catch (error: any) {
|
||||
throw toBamlError(error);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export const b = new BamlSyncClient(DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_RUNTIME, DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_CTX)
|
||||
@@ -1,80 +0,0 @@
|
||||
/*************************************************************************************************
|
||||
|
||||
Welcome to Baml! To use this generated code, please run one of the following:
|
||||
|
||||
$ npm install @boundaryml/baml
|
||||
$ yarn add @boundaryml/baml
|
||||
$ pnpm add @boundaryml/baml
|
||||
|
||||
*************************************************************************************************/
|
||||
|
||||
// This file was generated by BAML: do not edit it. Instead, edit the BAML
|
||||
// files and re-generate this code.
|
||||
//
|
||||
/* eslint-disable */
|
||||
// tslint:disable
|
||||
// @ts-nocheck
|
||||
// biome-ignore format: autogenerated code
|
||||
import type { BamlRuntime, BamlCtxManager, ClientRegistry, Image, Audio } from "@boundaryml/baml"
|
||||
import { toBamlError, HTTPRequest } from "@boundaryml/baml"
|
||||
import type { Checked, Check } from "./types"
|
||||
import type * as types from "./types"
|
||||
import type {DoneForNow} from "./types"
|
||||
import type TypeBuilder from "./type_builder"
|
||||
|
||||
type BamlCallOptions = {
|
||||
tb?: TypeBuilder
|
||||
clientRegistry?: ClientRegistry
|
||||
}
|
||||
|
||||
export class HttpRequest {
|
||||
constructor(private runtime: BamlRuntime, private ctxManager: BamlCtxManager) {}
|
||||
|
||||
|
||||
DetermineNextStep(
|
||||
thread: string,
|
||||
__baml_options__?: BamlCallOptions
|
||||
): HTTPRequest {
|
||||
try {
|
||||
return this.runtime.buildRequestSync(
|
||||
"DetermineNextStep",
|
||||
{
|
||||
"thread": thread
|
||||
},
|
||||
this.ctxManager.cloneContext(),
|
||||
__baml_options__?.tb?.__tb(),
|
||||
__baml_options__?.clientRegistry,
|
||||
false,
|
||||
)
|
||||
} catch (error) {
|
||||
throw toBamlError(error);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export class HttpStreamRequest {
|
||||
constructor(private runtime: BamlRuntime, private ctxManager: BamlCtxManager) {}
|
||||
|
||||
|
||||
DetermineNextStep(
|
||||
thread: string,
|
||||
__baml_options__?: BamlCallOptions
|
||||
): HTTPRequest {
|
||||
try {
|
||||
return this.runtime.buildRequestSync(
|
||||
"DetermineNextStep",
|
||||
{
|
||||
"thread": thread
|
||||
},
|
||||
this.ctxManager.cloneContext(),
|
||||
__baml_options__?.tb?.__tb(),
|
||||
__baml_options__?.clientRegistry,
|
||||
true,
|
||||
)
|
||||
} catch (error) {
|
||||
throw toBamlError(error);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
/*************************************************************************************************
|
||||
|
||||
Welcome to Baml! To use this generated code, please run one of the following:
|
||||
|
||||
$ npm install @boundaryml/baml
|
||||
$ yarn add @boundaryml/baml
|
||||
$ pnpm add @boundaryml/baml
|
||||
|
||||
*************************************************************************************************/
|
||||
|
||||
// This file was generated by BAML: do not edit it. Instead, edit the BAML
|
||||
// files and re-generate this code.
|
||||
//
|
||||
/* eslint-disable */
|
||||
// tslint:disable
|
||||
// @ts-nocheck
|
||||
// biome-ignore format: autogenerated code
|
||||
import type { BamlLogEvent } from '@boundaryml/baml';
|
||||
import { DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_CTX } from './globals';
|
||||
|
||||
const traceAsync =
|
||||
DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_CTX.traceFnAsync.bind(DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_CTX)
|
||||
const traceSync =
|
||||
DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_CTX.traceFnSync.bind(DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_CTX)
|
||||
const setTags =
|
||||
DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_CTX.upsertTags.bind(DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_CTX)
|
||||
const flush = () => {
|
||||
DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_CTX.flush.bind(DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_CTX)()
|
||||
}
|
||||
const onLogEvent = (callback: undefined | ((event: BamlLogEvent) => void)) =>
|
||||
DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_CTX.onLogEvent(callback)
|
||||
|
||||
export { traceAsync, traceSync, setTags, flush, onLogEvent }
|
||||
@@ -1,100 +0,0 @@
|
||||
/*************************************************************************************************
|
||||
|
||||
Welcome to Baml! To use this generated code, please run one of the following:
|
||||
|
||||
$ npm install @boundaryml/baml
|
||||
$ yarn add @boundaryml/baml
|
||||
$ pnpm add @boundaryml/baml
|
||||
|
||||
*************************************************************************************************/
|
||||
|
||||
// This file was generated by BAML: do not edit it. Instead, edit the BAML
|
||||
// files and re-generate this code.
|
||||
//
|
||||
/* eslint-disable */
|
||||
// tslint:disable
|
||||
// @ts-nocheck
|
||||
// biome-ignore format: autogenerated code
|
||||
import { FieldType } from '@boundaryml/baml/native'
|
||||
import { TypeBuilder as _TypeBuilder, EnumBuilder, ClassBuilder } from '@boundaryml/baml/type_builder'
|
||||
import { DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_RUNTIME } from "./globals"
|
||||
|
||||
export default class TypeBuilder {
|
||||
private tb: _TypeBuilder;
|
||||
|
||||
|
||||
|
||||
constructor() {
|
||||
this.tb = new _TypeBuilder({
|
||||
classes: new Set([
|
||||
"DoneForNow",
|
||||
]),
|
||||
enums: new Set([
|
||||
|
||||
]),
|
||||
runtime: DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_RUNTIME
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
|
||||
__tb() {
|
||||
return this.tb._tb();
|
||||
}
|
||||
|
||||
string(): FieldType {
|
||||
return this.tb.string()
|
||||
}
|
||||
|
||||
literalString(value: string): FieldType {
|
||||
return this.tb.literalString(value)
|
||||
}
|
||||
|
||||
literalInt(value: number): FieldType {
|
||||
return this.tb.literalInt(value)
|
||||
}
|
||||
|
||||
literalBool(value: boolean): FieldType {
|
||||
return this.tb.literalBool(value)
|
||||
}
|
||||
|
||||
int(): FieldType {
|
||||
return this.tb.int()
|
||||
}
|
||||
|
||||
float(): FieldType {
|
||||
return this.tb.float()
|
||||
}
|
||||
|
||||
bool(): FieldType {
|
||||
return this.tb.bool()
|
||||
}
|
||||
|
||||
list(type: FieldType): FieldType {
|
||||
return this.tb.list(type)
|
||||
}
|
||||
|
||||
null(): FieldType {
|
||||
return this.tb.null()
|
||||
}
|
||||
|
||||
map(key: FieldType, value: FieldType): FieldType {
|
||||
return this.tb.map(key, value)
|
||||
}
|
||||
|
||||
union(types: FieldType[]): FieldType {
|
||||
return this.tb.union(types)
|
||||
}
|
||||
|
||||
addClass<Name extends string>(name: Name): ClassBuilder<Name> {
|
||||
return this.tb.addClass(name);
|
||||
}
|
||||
|
||||
addEnum<Name extends string>(name: Name): EnumBuilder<Name> {
|
||||
return this.tb.addEnum(name);
|
||||
}
|
||||
|
||||
addBaml(baml: string): void {
|
||||
this.tb.addBaml(baml, this.runtime);
|
||||
}
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
/*************************************************************************************************
|
||||
|
||||
Welcome to Baml! To use this generated code, please run one of the following:
|
||||
|
||||
$ npm install @boundaryml/baml
|
||||
$ yarn add @boundaryml/baml
|
||||
$ pnpm add @boundaryml/baml
|
||||
|
||||
*************************************************************************************************/
|
||||
|
||||
// This file was generated by BAML: do not edit it. Instead, edit the BAML
|
||||
// files and re-generate this code.
|
||||
//
|
||||
/* eslint-disable */
|
||||
// tslint:disable
|
||||
// @ts-nocheck
|
||||
// biome-ignore format: autogenerated code
|
||||
import type { Image, Audio } from "@boundaryml/baml"
|
||||
|
||||
/**
|
||||
* Recursively partial type that can be null.
|
||||
*
|
||||
* @deprecated Use types from the `partial_types` namespace instead, which provides type-safe partial implementations
|
||||
* @template T The type to make recursively partial.
|
||||
*/
|
||||
export type RecursivePartialNull<T> = T extends object
|
||||
? { [P in keyof T]?: RecursivePartialNull<T[P]> }
|
||||
: T | null;
|
||||
|
||||
export interface Checked<T,CheckName extends string = string> {
|
||||
value: T,
|
||||
checks: Record<CheckName, Check>,
|
||||
}
|
||||
|
||||
|
||||
export interface Check {
|
||||
name: string,
|
||||
expr: string
|
||||
status: "succeeded" | "failed"
|
||||
}
|
||||
|
||||
export function all_succeeded<CheckName extends string>(checks: Record<CheckName, Check>): boolean {
|
||||
return get_checks(checks).every(check => check.status === "succeeded")
|
||||
}
|
||||
|
||||
export function get_checks<CheckName extends string>(checks: Record<CheckName, Check>): Check[] {
|
||||
return Object.values(checks)
|
||||
}
|
||||
export interface DoneForNow {
|
||||
intent: "done_for_now"
|
||||
message: string
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,20 +0,0 @@
|
||||
{
|
||||
"name": "my-agent",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "tsx src/index.ts",
|
||||
"build": "tsc"
|
||||
},
|
||||
"dependencies": {
|
||||
"baml": "^0.0.0",
|
||||
"tsx": "^4.15.0",
|
||||
"typescript": "^5.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^20.0.0",
|
||||
"@typescript-eslint/eslint-plugin": "^6.0.0",
|
||||
"@typescript-eslint/parser": "^6.0.0",
|
||||
"eslint": "^8.0.0"
|
||||
}
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
import { b } from "../baml_client";
|
||||
|
||||
// tool call or a respond to human tool
|
||||
type AgentResponse = Awaited<ReturnType<typeof b.DetermineNextStep>>;
|
||||
|
||||
export interface Event {
|
||||
type: string
|
||||
data: any;
|
||||
}
|
||||
|
||||
export class Thread {
|
||||
events: Event[] = [];
|
||||
|
||||
constructor(events: Event[]) {
|
||||
this.events = events;
|
||||
}
|
||||
|
||||
serializeForLLM() {
|
||||
// can change this to whatever custom serialization you want to do, XML, etc
|
||||
// e.g. https://github.com/got-agents/agents/blob/59ebbfa236fc376618f16ee08eb0f3bf7b698892/linear-assistant-ts/src/agent.ts#L66-L105
|
||||
return JSON.stringify(this.events);
|
||||
}
|
||||
}
|
||||
|
||||
// right now this just runs one turn with the LLM, but
|
||||
// we'll update this function to handle all the agent logic
|
||||
export async function agentLoop(thread: Thread): Promise<AgentResponse> {
|
||||
const nextStep = await b.DetermineNextStep(thread.serializeForLLM());
|
||||
return nextStep;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
// cli.ts lets you invoke the agent loop from the command line
|
||||
|
||||
import { agentLoop, Thread, Event } from "./agent";
|
||||
|
||||
export async function cli() {
|
||||
// Get command line arguments, skipping the first two (node and script name)
|
||||
const args = process.argv.slice(2);
|
||||
|
||||
if (args.length === 0) {
|
||||
console.error("Error: Please provide a message as a command line argument");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// Join all arguments into a single message
|
||||
const message = args.join(" ");
|
||||
|
||||
// Create a new thread with the user's message as the initial event
|
||||
const thread = new Thread([{ type: "user_input", data: message }]);
|
||||
|
||||
// Run the agent loop with the thread
|
||||
const result = await agentLoop(thread);
|
||||
console.log(result);
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
import { cli } from "./cli"
|
||||
|
||||
async function hello(): Promise<void> {
|
||||
console.log('hello, world!')
|
||||
}
|
||||
|
||||
async function main() {
|
||||
await cli()
|
||||
}
|
||||
|
||||
main().catch(console.error)
|
||||
@@ -1,24 +0,0 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2017",
|
||||
"lib": ["esnext"],
|
||||
"allowJs": true,
|
||||
"skipLibCheck": true,
|
||||
"strict": true,
|
||||
"noEmit": true,
|
||||
"esModuleInterop": true,
|
||||
"module": "esnext",
|
||||
"moduleResolution": "bundler",
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"jsx": "preserve",
|
||||
"incremental": true,
|
||||
"plugins": [],
|
||||
"paths": {
|
||||
"@/*": ["./*"]
|
||||
}
|
||||
},
|
||||
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
|
||||
"exclude": ["node_modules", "walkthrough"]
|
||||
}
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
class DoneForNow {
|
||||
intent "done_for_now"
|
||||
message string
|
||||
}
|
||||
|
||||
function DetermineNextStep(
|
||||
thread: string
|
||||
) -> CalculatorTools | DoneForNow {
|
||||
client "openai/gpt-4o"
|
||||
|
||||
prompt #"
|
||||
{{ _.role("system") }}
|
||||
|
||||
You are a helpful assistant that can help with tasks.
|
||||
|
||||
{{ _.role("user") }}
|
||||
|
||||
You are working on the following thread:
|
||||
|
||||
{{ thread }}
|
||||
|
||||
What should the next step be?
|
||||
|
||||
{{ ctx.output_format }}
|
||||
"#
|
||||
}
|
||||
|
||||
test HelloWorld {
|
||||
functions [DetermineNextStep]
|
||||
args {
|
||||
thread #"
|
||||
{
|
||||
"type": "user_input",
|
||||
"data": "hello!"
|
||||
}
|
||||
"#
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
type CalculatorTools = AddTool | SubtractTool | MultiplyTool | DivideTool
|
||||
|
||||
|
||||
class AddTool {
|
||||
intent "add"
|
||||
a int | float
|
||||
b int | float
|
||||
}
|
||||
|
||||
class SubtractTool {
|
||||
intent "subtract"
|
||||
a int | float
|
||||
b int | float
|
||||
}
|
||||
|
||||
class MultiplyTool {
|
||||
intent "multiply"
|
||||
a int | float
|
||||
b int | float
|
||||
}
|
||||
|
||||
class DivideTool {
|
||||
intent "divide"
|
||||
a int | float
|
||||
b int | float
|
||||
}
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
baml_src/
|
||||
node_modules/
|
||||
@@ -1,172 +0,0 @@
|
||||
# Chapter 3 - Process Tool Calls in a Loop
|
||||
|
||||
Now let's add a real agentic loop that can run the tools and get a final answer from the LLM.
|
||||
|
||||
Update agent with tool handling
|
||||
|
||||
```diff
|
||||
src/agent.ts
|
||||
}
|
||||
|
||||
-// right now this just runs one turn with the LLM, but
|
||||
-// we'll update this function to handle all the agent logic
|
||||
-export async function agentLoop(thread: Thread): Promise<AgentResponse> {
|
||||
- const nextStep = await b.DetermineNextStep(thread.serializeForLLM());
|
||||
- return nextStep;
|
||||
+
|
||||
+
|
||||
+export async function agentLoop(thread: Thread): Promise<string> {
|
||||
+
|
||||
+ while (true) {
|
||||
+ const nextStep = await b.DetermineNextStep(thread.serializeForLLM());
|
||||
+ console.log("nextStep", nextStep);
|
||||
+
|
||||
+ switch (nextStep.intent) {
|
||||
+ case "done_for_now":
|
||||
+ // response to human, return the next step object
|
||||
+ return nextStep.message;
|
||||
+ case "add":
|
||||
+ thread.events.push({
|
||||
+ "type": "tool_call",
|
||||
+ "data": nextStep
|
||||
+ });
|
||||
+ const result = nextStep.a + nextStep.b;
|
||||
+ console.log("tool_response", result);
|
||||
+ thread.events.push({
|
||||
+ "type": "tool_response",
|
||||
+ "data": result
|
||||
+ });
|
||||
+ continue;
|
||||
+ default:
|
||||
+ throw new Error(`Unknown intent: ${nextStep.intent}`);
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>skip this step</summary>
|
||||
|
||||
cp ./walkthrough/03-agent.ts src/agent.ts
|
||||
|
||||
</details>
|
||||
|
||||
Try a simple calculation
|
||||
|
||||
npx tsx src/index.ts 'can you add 3 and 4'
|
||||
|
||||
Turn off BAML logs for cleaner output
|
||||
|
||||
export BAML_LOG=off
|
||||
|
||||
Try a multi-step calculation
|
||||
|
||||
npx tsx src/index.ts 'can you add 3 and 4, then add 6 to that result'
|
||||
|
||||
Add handlers for all calculator tools
|
||||
|
||||
```diff
|
||||
src/agent.ts
|
||||
-import { b } from "../baml_client";
|
||||
+import { AddTool, SubtractTool, DivideTool, MultiplyTool, b } from "../baml_client";
|
||||
|
||||
-// tool call or a respond to human tool
|
||||
-type AgentResponse = Awaited<ReturnType<typeof b.DetermineNextStep>>;
|
||||
-
|
||||
export interface Event {
|
||||
type: string
|
||||
}
|
||||
|
||||
+export type CalculatorTool = AddTool | SubtractTool | MultiplyTool | DivideTool;
|
||||
|
||||
+export async function handleNextStep(nextStep: CalculatorTool, thread: Thread): Promise<Thread> {
|
||||
+ let result: number;
|
||||
+ switch (nextStep.intent) {
|
||||
+ case "add":
|
||||
+ result = nextStep.a + nextStep.b;
|
||||
+ console.log("tool_response", result);
|
||||
+ thread.events.push({
|
||||
+ "type": "tool_response",
|
||||
+ "data": result
|
||||
+ });
|
||||
+ return thread;
|
||||
+ case "subtract":
|
||||
+ result = nextStep.a - nextStep.b;
|
||||
+ console.log("tool_response", result);
|
||||
+ thread.events.push({
|
||||
+ "type": "tool_response",
|
||||
+ "data": result
|
||||
+ });
|
||||
+ return thread;
|
||||
+ case "multiply":
|
||||
+ result = nextStep.a * nextStep.b;
|
||||
+ console.log("tool_response", result);
|
||||
+ thread.events.push({
|
||||
+ "type": "tool_response",
|
||||
+ "data": result
|
||||
+ });
|
||||
+ return thread;
|
||||
+ case "divide":
|
||||
+ result = nextStep.a / nextStep.b;
|
||||
+ console.log("tool_response", result);
|
||||
+ thread.events.push({
|
||||
+ "type": "tool_response",
|
||||
+ "data": result
|
||||
+ });
|
||||
+ return thread;
|
||||
+ }
|
||||
+}
|
||||
|
||||
export async function agentLoop(thread: Thread): Promise<string> {
|
||||
console.log("nextStep", nextStep);
|
||||
|
||||
+ thread.events.push({
|
||||
+ "type": "tool_call",
|
||||
+ "data": nextStep
|
||||
+ });
|
||||
+
|
||||
switch (nextStep.intent) {
|
||||
case "done_for_now":
|
||||
return nextStep.message;
|
||||
case "add":
|
||||
- thread.events.push({
|
||||
- "type": "tool_call",
|
||||
- "data": nextStep
|
||||
- });
|
||||
- const result = nextStep.a + nextStep.b;
|
||||
- console.log("tool_response", result);
|
||||
- thread.events.push({
|
||||
- "type": "tool_response",
|
||||
- "data": result
|
||||
- });
|
||||
- continue;
|
||||
- default:
|
||||
- throw new Error(`Unknown intent: ${nextStep.intent}`);
|
||||
+ case "subtract":
|
||||
+ case "multiply":
|
||||
+ case "divide":
|
||||
+ thread = await handleNextStep(nextStep, thread);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>skip this step</summary>
|
||||
|
||||
cp ./walkthrough/03b-agent.ts src/agent.ts
|
||||
|
||||
</details>
|
||||
|
||||
Test subtraction
|
||||
|
||||
npx tsx src/index.ts 'can you subtract 3 from 4'
|
||||
|
||||
Test multiplication
|
||||
|
||||
npx tsx src/index.ts 'can you multiply 3 and 4'
|
||||
|
||||
Test a complex calculation
|
||||
|
||||
npx tsx src/index.ts 'can you multiply 3 and 4, then divide the result by 2 and then add 12 to that result'
|
||||
|
||||
@@ -1,154 +0,0 @@
|
||||
/*************************************************************************************************
|
||||
|
||||
Welcome to Baml! To use this generated code, please run one of the following:
|
||||
|
||||
$ npm install @boundaryml/baml
|
||||
$ yarn add @boundaryml/baml
|
||||
$ pnpm add @boundaryml/baml
|
||||
|
||||
*************************************************************************************************/
|
||||
|
||||
// This file was generated by BAML: do not edit it. Instead, edit the BAML
|
||||
// files and re-generate this code.
|
||||
//
|
||||
/* eslint-disable */
|
||||
// tslint:disable
|
||||
// @ts-nocheck
|
||||
// biome-ignore format: autogenerated code
|
||||
import type { BamlRuntime, FunctionResult, BamlCtxManager, ClientRegistry, Image, Audio, Collector } from "@boundaryml/baml"
|
||||
import { toBamlError, BamlStream, type HTTPRequest } from "@boundaryml/baml"
|
||||
import type { Checked, Check, RecursivePartialNull as MovedRecursivePartialNull } from "./types"
|
||||
import type { partial_types } from "./partial_types"
|
||||
import type * as types from "./types"
|
||||
import type {AddTool, DivideTool, DoneForNow, MultiplyTool, SubtractTool} from "./types"
|
||||
import type TypeBuilder from "./type_builder"
|
||||
import { AsyncHttpRequest, AsyncHttpStreamRequest } from "./async_request"
|
||||
import { LlmResponseParser, LlmStreamParser } from "./parser"
|
||||
import { DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_CTX, DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_RUNTIME } from "./globals"
|
||||
|
||||
/**
|
||||
* @deprecated Use RecursivePartialNull from 'baml_client/types' instead.
|
||||
*/
|
||||
export type RecursivePartialNull<T> = MovedRecursivePartialNull<T>
|
||||
|
||||
type BamlCallOptions = {
|
||||
tb?: TypeBuilder
|
||||
clientRegistry?: ClientRegistry
|
||||
collector?: Collector | Collector[]
|
||||
}
|
||||
|
||||
export class BamlAsyncClient {
|
||||
private runtime: BamlRuntime
|
||||
private ctxManager: BamlCtxManager
|
||||
private streamClient: BamlStreamClient
|
||||
private httpRequest: AsyncHttpRequest
|
||||
private httpStreamRequest: AsyncHttpStreamRequest
|
||||
private llmResponseParser: LlmResponseParser
|
||||
private llmStreamParser: LlmStreamParser
|
||||
private bamlOptions: BamlCallOptions
|
||||
|
||||
constructor(runtime: BamlRuntime, ctxManager: BamlCtxManager, bamlOptions?: BamlCallOptions) {
|
||||
this.runtime = runtime
|
||||
this.ctxManager = ctxManager
|
||||
this.streamClient = new BamlStreamClient(runtime, ctxManager, bamlOptions)
|
||||
this.httpRequest = new AsyncHttpRequest(runtime, ctxManager)
|
||||
this.httpStreamRequest = new AsyncHttpStreamRequest(runtime, ctxManager)
|
||||
this.llmResponseParser = new LlmResponseParser(runtime, ctxManager)
|
||||
this.llmStreamParser = new LlmStreamParser(runtime, ctxManager)
|
||||
this.bamlOptions = bamlOptions || {}
|
||||
}
|
||||
|
||||
withOptions(bamlOptions: BamlCallOptions) {
|
||||
return new BamlAsyncClient(this.runtime, this.ctxManager, bamlOptions)
|
||||
}
|
||||
|
||||
get stream() {
|
||||
return this.streamClient
|
||||
}
|
||||
|
||||
get request() {
|
||||
return this.httpRequest
|
||||
}
|
||||
|
||||
get streamRequest() {
|
||||
return this.httpStreamRequest
|
||||
}
|
||||
|
||||
get parse() {
|
||||
return this.llmResponseParser
|
||||
}
|
||||
|
||||
get parseStream() {
|
||||
return this.llmStreamParser
|
||||
}
|
||||
|
||||
|
||||
async DetermineNextStep(
|
||||
thread: string,
|
||||
__baml_options__?: BamlCallOptions
|
||||
): Promise<AddTool | SubtractTool | MultiplyTool | DivideTool | DoneForNow> {
|
||||
try {
|
||||
const options = { ...this.bamlOptions, ...(__baml_options__ || {}) }
|
||||
const collector = options.collector ? (Array.isArray(options.collector) ? options.collector : [options.collector]) : [];
|
||||
const raw = await this.runtime.callFunction(
|
||||
"DetermineNextStep",
|
||||
{
|
||||
"thread": thread
|
||||
},
|
||||
this.ctxManager.cloneContext(),
|
||||
options.tb?.__tb(),
|
||||
options.clientRegistry,
|
||||
collector,
|
||||
)
|
||||
return raw.parsed(false) as AddTool | SubtractTool | MultiplyTool | DivideTool | DoneForNow
|
||||
} catch (error) {
|
||||
throw toBamlError(error);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class BamlStreamClient {
|
||||
private runtime: BamlRuntime
|
||||
private ctxManager: BamlCtxManager
|
||||
private bamlOptions: BamlCallOptions
|
||||
|
||||
constructor(runtime: BamlRuntime, ctxManager: BamlCtxManager, bamlOptions?: BamlCallOptions) {
|
||||
this.runtime = runtime
|
||||
this.ctxManager = ctxManager
|
||||
this.bamlOptions = bamlOptions || {}
|
||||
}
|
||||
|
||||
|
||||
DetermineNextStep(
|
||||
thread: string,
|
||||
__baml_options__?: { tb?: TypeBuilder, clientRegistry?: ClientRegistry, collector?: Collector | Collector[] }
|
||||
): BamlStream<(((partial_types.AddTool | null) | (partial_types.SubtractTool | null) | (partial_types.MultiplyTool | null) | (partial_types.DivideTool | null) | null) | (partial_types.DoneForNow | null)), AddTool | SubtractTool | MultiplyTool | DivideTool | DoneForNow> {
|
||||
try {
|
||||
const options = { ...this.bamlOptions, ...(__baml_options__ || {}) }
|
||||
const collector = options.collector ? (Array.isArray(options.collector) ? options.collector : [options.collector]) : [];
|
||||
const raw = this.runtime.streamFunction(
|
||||
"DetermineNextStep",
|
||||
{
|
||||
"thread": thread
|
||||
},
|
||||
undefined,
|
||||
this.ctxManager.cloneContext(),
|
||||
options.tb?.__tb(),
|
||||
options.clientRegistry,
|
||||
collector,
|
||||
)
|
||||
return new BamlStream<(((partial_types.AddTool | null) | (partial_types.SubtractTool | null) | (partial_types.MultiplyTool | null) | (partial_types.DivideTool | null) | null) | (partial_types.DoneForNow | null)), AddTool | SubtractTool | MultiplyTool | DivideTool | DoneForNow>(
|
||||
raw,
|
||||
(a): (((partial_types.AddTool | null) | (partial_types.SubtractTool | null) | (partial_types.MultiplyTool | null) | (partial_types.DivideTool | null) | null) | (partial_types.DoneForNow | null)) => a,
|
||||
(a): AddTool | SubtractTool | MultiplyTool | DivideTool | DoneForNow => a,
|
||||
this.ctxManager.cloneContext(),
|
||||
)
|
||||
} catch (error) {
|
||||
throw toBamlError(error);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export const b = new BamlAsyncClient(DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_RUNTIME, DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_CTX)
|
||||
@@ -1,80 +0,0 @@
|
||||
/*************************************************************************************************
|
||||
|
||||
Welcome to Baml! To use this generated code, please run one of the following:
|
||||
|
||||
$ npm install @boundaryml/baml
|
||||
$ yarn add @boundaryml/baml
|
||||
$ pnpm add @boundaryml/baml
|
||||
|
||||
*************************************************************************************************/
|
||||
|
||||
// This file was generated by BAML: do not edit it. Instead, edit the BAML
|
||||
// files and re-generate this code.
|
||||
//
|
||||
/* eslint-disable */
|
||||
// tslint:disable
|
||||
// @ts-nocheck
|
||||
// biome-ignore format: autogenerated code
|
||||
import type { BamlRuntime, BamlCtxManager, ClientRegistry, Image, Audio } from "@boundaryml/baml"
|
||||
import { toBamlError, HTTPRequest } from "@boundaryml/baml"
|
||||
import type { Checked, Check } from "./types"
|
||||
import type * as types from "./types"
|
||||
import type {AddTool, DivideTool, DoneForNow, MultiplyTool, SubtractTool} from "./types"
|
||||
import type TypeBuilder from "./type_builder"
|
||||
|
||||
type BamlCallOptions = {
|
||||
tb?: TypeBuilder
|
||||
clientRegistry?: ClientRegistry
|
||||
}
|
||||
|
||||
export class AsyncHttpRequest {
|
||||
constructor(private runtime: BamlRuntime, private ctxManager: BamlCtxManager) {}
|
||||
|
||||
|
||||
async DetermineNextStep(
|
||||
thread: string,
|
||||
__baml_options__?: BamlCallOptions
|
||||
): Promise<HTTPRequest> {
|
||||
try {
|
||||
return await this.runtime.buildRequest(
|
||||
"DetermineNextStep",
|
||||
{
|
||||
"thread": thread
|
||||
},
|
||||
this.ctxManager.cloneContext(),
|
||||
__baml_options__?.tb?.__tb(),
|
||||
__baml_options__?.clientRegistry,
|
||||
false,
|
||||
)
|
||||
} catch (error) {
|
||||
throw toBamlError(error);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export class AsyncHttpStreamRequest {
|
||||
constructor(private runtime: BamlRuntime, private ctxManager: BamlCtxManager) {}
|
||||
|
||||
|
||||
async DetermineNextStep(
|
||||
thread: string,
|
||||
__baml_options__?: BamlCallOptions
|
||||
): Promise<HTTPRequest> {
|
||||
try {
|
||||
return await this.runtime.buildRequest(
|
||||
"DetermineNextStep",
|
||||
{
|
||||
"thread": thread
|
||||
},
|
||||
this.ctxManager.cloneContext(),
|
||||
__baml_options__?.tb?.__tb(),
|
||||
__baml_options__?.clientRegistry,
|
||||
true,
|
||||
)
|
||||
} catch (error) {
|
||||
throw toBamlError(error);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
/*************************************************************************************************
|
||||
|
||||
Welcome to Baml! To use this generated code, please run one of the following:
|
||||
|
||||
$ npm install @boundaryml/baml
|
||||
$ yarn add @boundaryml/baml
|
||||
$ pnpm add @boundaryml/baml
|
||||
|
||||
*************************************************************************************************/
|
||||
|
||||
// This file was generated by BAML: do not edit it. Instead, edit the BAML
|
||||
// files and re-generate this code.
|
||||
//
|
||||
/* eslint-disable */
|
||||
// tslint:disable
|
||||
// @ts-nocheck
|
||||
// biome-ignore format: autogenerated code
|
||||
export { setLogLevel, getLogLevel, setLogJson } from "@boundaryml/baml/logging";
|
||||
export { resetBamlEnvVars } from "./globals";
|
||||
@@ -1,67 +0,0 @@
|
||||
/*************************************************************************************************
|
||||
|
||||
Welcome to Baml! To use this generated code, please run one of the following:
|
||||
|
||||
$ npm install @boundaryml/baml
|
||||
$ yarn add @boundaryml/baml
|
||||
$ pnpm add @boundaryml/baml
|
||||
|
||||
*************************************************************************************************/
|
||||
|
||||
// This file was generated by BAML: do not edit it. Instead, edit the BAML
|
||||
// files and re-generate this code.
|
||||
//
|
||||
/* eslint-disable */
|
||||
// tslint:disable
|
||||
// @ts-nocheck
|
||||
// biome-ignore format: autogenerated code
|
||||
import { BamlRuntime, BamlCtxManager } from '@boundaryml/baml'
|
||||
import { getBamlFiles } from './inlinedbaml'
|
||||
|
||||
|
||||
export const DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_RUNTIME = BamlRuntime.fromFiles(
|
||||
'baml_src',
|
||||
getBamlFiles(),
|
||||
process.env
|
||||
)
|
||||
export const DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_CTX = new BamlCtxManager(DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_RUNTIME)
|
||||
|
||||
|
||||
export function resetBamlEnvVars(envVars: Record<string, string | undefined>) {
|
||||
if (DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_CTX.allowResets()) {
|
||||
const envVarsToReset = Object.fromEntries(Object.entries(envVars).filter((kv): kv is [string, string] => kv[1] !== undefined));
|
||||
DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_RUNTIME.reset('baml_src', getBamlFiles(), envVarsToReset)
|
||||
DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_CTX.reset()
|
||||
} else {
|
||||
throw new Error('BamlError: Cannot reset BAML environment variables while there are active BAML contexts.')
|
||||
}
|
||||
}
|
||||
|
||||
const patchedLoad = (originalFn: any) => (...args: any[]) => {
|
||||
const result = originalFn(...args);
|
||||
try {
|
||||
// Dont fail if env vars fail to reset
|
||||
resetBamlEnvVars(process.env);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
try {
|
||||
const dotenv = require('dotenv');
|
||||
// Monkeypatch load function to call resetBamlEnvVars after execution
|
||||
|
||||
|
||||
// Apply the patch
|
||||
dotenv.config = patchedLoad(dotenv.config);
|
||||
dotenv.configDotenv = patchedLoad(dotenv.configDotenv);
|
||||
dotenv.populate = patchedLoad(dotenv.populate);
|
||||
} catch (error) {
|
||||
// dotenv is not installed, so we do nothing
|
||||
}
|
||||
|
||||
// also patch process.loadEnvFile
|
||||
if (process.loadEnvFile) {
|
||||
process.loadEnvFile = patchedLoad(process.loadEnvFile);
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
/*************************************************************************************************
|
||||
|
||||
Welcome to Baml! To use this generated code, please run one of the following:
|
||||
|
||||
$ npm install @boundaryml/baml
|
||||
$ yarn add @boundaryml/baml
|
||||
$ pnpm add @boundaryml/baml
|
||||
|
||||
*************************************************************************************************/
|
||||
|
||||
// This file was generated by BAML: do not edit it. Instead, edit the BAML
|
||||
// files and re-generate this code.
|
||||
//
|
||||
/* eslint-disable */
|
||||
// tslint:disable
|
||||
// @ts-nocheck
|
||||
// biome-ignore format: autogenerated code
|
||||
/**
|
||||
* If this import fails, you may need to upgrade @boundaryml/baml.
|
||||
*
|
||||
* Please upgrade @boundaryml/baml to 0.85.0.
|
||||
*
|
||||
* $ npm install @boundaryml/baml@0.85.0
|
||||
* $ yarn add @boundaryml/baml@0.85.0
|
||||
* $ pnpm add @boundaryml/baml@0.85.0
|
||||
*
|
||||
* If nothing else works, please ask for help:
|
||||
*
|
||||
* https://github.com/boundaryml/baml/issues
|
||||
* https://boundaryml.com/discord
|
||||
*
|
||||
**/
|
||||
import { ThrowIfVersionMismatch } from "@boundaryml/baml";
|
||||
|
||||
export const version = "0.85.0";
|
||||
|
||||
ThrowIfVersionMismatch(version);
|
||||
|
||||
|
||||
|
||||
export { b } from "./async_client"
|
||||
|
||||
export * from "./types"
|
||||
export type { partial_types } from "./partial_types"
|
||||
export * from "./tracing"
|
||||
export { resetBamlEnvVars } from "./globals"
|
||||
export { BamlClientHttpError, BamlValidationError, BamlClientFinishReasonError } from "@boundaryml/baml"
|
||||
@@ -1,27 +0,0 @@
|
||||
/*************************************************************************************************
|
||||
|
||||
Welcome to Baml! To use this generated code, please run one of the following:
|
||||
|
||||
$ npm install @boundaryml/baml
|
||||
$ yarn add @boundaryml/baml
|
||||
$ pnpm add @boundaryml/baml
|
||||
|
||||
*************************************************************************************************/
|
||||
|
||||
// This file was generated by BAML: do not edit it. Instead, edit the BAML
|
||||
// files and re-generate this code.
|
||||
//
|
||||
/* eslint-disable */
|
||||
// tslint:disable
|
||||
// @ts-nocheck
|
||||
// biome-ignore format: autogenerated code
|
||||
const fileMap = {
|
||||
|
||||
"agent.baml": "class DoneForNow {\n intent \"done_for_now\"\n message string \n}\n\nfunction DetermineNextStep(\n thread: string \n) -> CalculatorTools | DoneForNow {\n client \"openai/gpt-4o\"\n\n prompt #\"\n {{ _.role(\"system\") }}\n\n You are a helpful assistant that can help with tasks.\n\n {{ _.role(\"user\") }}\n\n You are working on the following thread:\n\n {{ thread }}\n\n What should the next step be?\n\n {{ ctx.output_format }}\n \"#\n}\n\ntest HelloWorld {\n functions [DetermineNextStep]\n args {\n thread #\"\n {\n \"type\": \"user_input\",\n \"data\": \"hello!\"\n }\n \"#\n }\n}",
|
||||
"clients.baml": "// Learn more about clients at https://docs.boundaryml.com/docs/snippets/clients/overview\n\nclient<llm> CustomGPT4o {\n provider openai\n options {\n model \"gpt-4o\"\n api_key env.OPENAI_API_KEY\n }\n}\n\nclient<llm> CustomGPT4oMini {\n provider openai\n retry_policy Exponential\n options {\n model \"gpt-4o-mini\"\n api_key env.OPENAI_API_KEY\n }\n}\n\nclient<llm> CustomSonnet {\n provider anthropic\n options {\n model \"claude-3-5-sonnet-20241022\"\n api_key env.ANTHROPIC_API_KEY\n }\n}\n\n\nclient<llm> CustomHaiku {\n provider anthropic\n retry_policy Constant\n options {\n model \"claude-3-haiku-20240307\"\n api_key env.ANTHROPIC_API_KEY\n }\n}\n\n// https://docs.boundaryml.com/docs/snippets/clients/round-robin\nclient<llm> CustomFast {\n provider round-robin\n options {\n // This will alternate between the two clients\n strategy [CustomGPT4oMini, CustomHaiku]\n }\n}\n\n// https://docs.boundaryml.com/docs/snippets/clients/fallback\nclient<llm> OpenaiFallback {\n provider fallback\n options {\n // This will try the clients in order until one succeeds\n strategy [CustomGPT4oMini, CustomGPT4oMini]\n }\n}\n\n// https://docs.boundaryml.com/docs/snippets/clients/retry\nretry_policy Constant {\n max_retries 3\n // Strategy is optional\n strategy {\n type constant_delay\n delay_ms 200\n }\n}\n\nretry_policy Exponential {\n max_retries 2\n // Strategy is optional\n strategy {\n type exponential_backoff\n delay_ms 300\n multiplier 1.5\n max_delay_ms 10000\n }\n}",
|
||||
"generators.baml": "// This helps use auto generate libraries you can use in the language of\n// your choice. You can have multiple generators if you use multiple languages.\n// Just ensure that the output_dir is different for each generator.\ngenerator target {\n // Valid values: \"python/pydantic\", \"typescript\", \"ruby/sorbet\", \"rest/openapi\"\n output_type \"typescript\"\n\n // Where the generated code will be saved (relative to baml_src/)\n output_dir \"../\"\n\n // The version of the BAML package you have installed (e.g. same version as your baml-py or @boundaryml/baml).\n // The BAML VSCode extension version should also match this version.\n version \"0.85.0\"\n\n // Valid values: \"sync\", \"async\"\n // This controls what `b.FunctionName()` will be (sync or async).\n default_client_mode async\n}\n",
|
||||
"tool_calculator.baml": "type CalculatorTools = AddTool | SubtractTool | MultiplyTool | DivideTool\n\n\nclass AddTool {\n intent \"add\"\n a int | float\n b int | float\n}\n\nclass SubtractTool {\n intent \"subtract\"\n a int | float\n b int | float\n}\n\nclass MultiplyTool {\n intent \"multiply\"\n a int | float\n b int | float\n}\n\nclass DivideTool {\n intent \"divide\"\n a int | float\n b int | float\n}\n\n",
|
||||
}
|
||||
export const getBamlFiles = () => {
|
||||
return fileMap;
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
/*************************************************************************************************
|
||||
|
||||
Welcome to Baml! To use this generated code, please run one of the following:
|
||||
|
||||
$ npm install @boundaryml/baml
|
||||
$ yarn add @boundaryml/baml
|
||||
$ pnpm add @boundaryml/baml
|
||||
|
||||
*************************************************************************************************/
|
||||
|
||||
// This file was generated by BAML: do not edit it. Instead, edit the BAML
|
||||
// files and re-generate this code.
|
||||
//
|
||||
/* eslint-disable */
|
||||
// tslint:disable
|
||||
// @ts-nocheck
|
||||
// biome-ignore format: autogenerated code
|
||||
import type { BamlRuntime, BamlCtxManager, ClientRegistry, Image, Audio, Collector } from "@boundaryml/baml"
|
||||
import { toBamlError } from "@boundaryml/baml"
|
||||
import type { Checked, Check } from "./types"
|
||||
import type { partial_types } from "./partial_types"
|
||||
import type * as types from "./types"
|
||||
import type {AddTool, DivideTool, DoneForNow, MultiplyTool, SubtractTool} from "./types"
|
||||
import type TypeBuilder from "./type_builder"
|
||||
|
||||
export class LlmResponseParser {
|
||||
constructor(private runtime: BamlRuntime, private ctxManager: BamlCtxManager) {}
|
||||
|
||||
|
||||
DetermineNextStep(
|
||||
llmResponse: string,
|
||||
__baml_options__?: { tb?: TypeBuilder, clientRegistry?: ClientRegistry }
|
||||
): AddTool | SubtractTool | MultiplyTool | DivideTool | DoneForNow {
|
||||
try {
|
||||
return this.runtime.parseLlmResponse(
|
||||
"DetermineNextStep",
|
||||
llmResponse,
|
||||
false,
|
||||
this.ctxManager.cloneContext(),
|
||||
__baml_options__?.tb?.__tb(),
|
||||
__baml_options__?.clientRegistry,
|
||||
) as AddTool | SubtractTool | MultiplyTool | DivideTool | DoneForNow
|
||||
} catch (error) {
|
||||
throw toBamlError(error);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export class LlmStreamParser {
|
||||
constructor(private runtime: BamlRuntime, private ctxManager: BamlCtxManager) {}
|
||||
|
||||
|
||||
DetermineNextStep(
|
||||
llmResponse: string,
|
||||
__baml_options__?: { tb?: TypeBuilder, clientRegistry?: ClientRegistry }
|
||||
): (((partial_types.AddTool | null) | (partial_types.SubtractTool | null) | (partial_types.MultiplyTool | null) | (partial_types.DivideTool | null) | null) | (partial_types.DoneForNow | null)) {
|
||||
try {
|
||||
return this.runtime.parseLlmResponse(
|
||||
"DetermineNextStep",
|
||||
llmResponse,
|
||||
true,
|
||||
this.ctxManager.cloneContext(),
|
||||
__baml_options__?.tb?.__tb(),
|
||||
__baml_options__?.clientRegistry,
|
||||
) as (((partial_types.AddTool | null) | (partial_types.SubtractTool | null) | (partial_types.MultiplyTool | null) | (partial_types.DivideTool | null) | null) | (partial_types.DoneForNow | null))
|
||||
} catch (error) {
|
||||
throw toBamlError(error);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,66 +0,0 @@
|
||||
/*************************************************************************************************
|
||||
|
||||
Welcome to Baml! To use this generated code, please run one of the following:
|
||||
|
||||
$ npm install @boundaryml/baml
|
||||
$ yarn add @boundaryml/baml
|
||||
$ pnpm add @boundaryml/baml
|
||||
|
||||
*************************************************************************************************/
|
||||
|
||||
// This file was generated by BAML: do not edit it. Instead, edit the BAML
|
||||
// files and re-generate this code.
|
||||
//
|
||||
/* eslint-disable */
|
||||
// tslint:disable
|
||||
// @ts-nocheck
|
||||
// biome-ignore format: autogenerated code
|
||||
import type { Image, Audio } from "@boundaryml/baml"
|
||||
import type { Checked, Check } from "./types"
|
||||
import type { AddTool, DivideTool, DoneForNow, MultiplyTool, SubtractTool } from "./types"
|
||||
import type * as types from "./types"
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* These types are used for streaming, for when an instance of a type
|
||||
* is still being built up and any of its fields is not yet fully available.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
export interface StreamState<T> {
|
||||
value: T
|
||||
state: "Pending" | "Incomplete" | "Complete"
|
||||
}
|
||||
|
||||
export namespace partial_types {
|
||||
|
||||
export interface AddTool {
|
||||
intent: "add"
|
||||
a?: ((number | null) | (number | null) | null)
|
||||
b?: ((number | null) | (number | null) | null)
|
||||
}
|
||||
|
||||
export interface DivideTool {
|
||||
intent: "divide"
|
||||
a?: ((number | null) | (number | null) | null)
|
||||
b?: ((number | null) | (number | null) | null)
|
||||
}
|
||||
|
||||
export interface DoneForNow {
|
||||
intent: "done_for_now"
|
||||
message?: (string | null)
|
||||
}
|
||||
|
||||
export interface MultiplyTool {
|
||||
intent: "multiply"
|
||||
a?: ((number | null) | (number | null) | null)
|
||||
b?: ((number | null) | (number | null) | null)
|
||||
}
|
||||
|
||||
export interface SubtractTool {
|
||||
intent: "subtract"
|
||||
a?: ((number | null) | (number | null) | null)
|
||||
b?: ((number | null) | (number | null) | null)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,113 +0,0 @@
|
||||
/*************************************************************************************************
|
||||
|
||||
Welcome to Baml! To use this generated code, please run one of the following:
|
||||
|
||||
$ npm install @boundaryml/baml
|
||||
$ yarn add @boundaryml/baml
|
||||
$ pnpm add @boundaryml/baml
|
||||
|
||||
*************************************************************************************************/
|
||||
|
||||
// This file was generated by BAML: do not edit it. Instead, edit the BAML
|
||||
// files and re-generate this code.
|
||||
//
|
||||
/* eslint-disable */
|
||||
// tslint:disable
|
||||
// @ts-nocheck
|
||||
// biome-ignore format: autogenerated code
|
||||
import type { BamlRuntime, FunctionResult, BamlCtxManager, Image, Audio, ClientRegistry, Collector } from "@boundaryml/baml"
|
||||
import { toBamlError, type HTTPRequest } from "@boundaryml/baml"
|
||||
import type { Checked, Check, RecursivePartialNull as MovedRecursivePartialNull } from "./types"
|
||||
import type * as types from "./types"
|
||||
import type {AddTool, DivideTool, DoneForNow, MultiplyTool, SubtractTool} from "./types"
|
||||
import type TypeBuilder from "./type_builder"
|
||||
import { HttpRequest, HttpStreamRequest } from "./sync_request"
|
||||
import { LlmResponseParser, LlmStreamParser } from "./parser"
|
||||
import { DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_CTX, DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_RUNTIME } from "./globals"
|
||||
|
||||
/**
|
||||
* @deprecated Use RecursivePartialNull from 'baml_client/types' instead.
|
||||
* Example:
|
||||
* ```ts
|
||||
* import { RecursivePartialNull } from './baml_client/types'
|
||||
* ```
|
||||
*/
|
||||
export type RecursivePartialNull<T> = MovedRecursivePartialNull<T>;
|
||||
|
||||
type BamlCallOptions = {
|
||||
tb?: TypeBuilder
|
||||
clientRegistry?: ClientRegistry
|
||||
collector?: Collector | Collector[]
|
||||
}
|
||||
|
||||
export class BamlSyncClient {
|
||||
private httpRequest: HttpRequest
|
||||
private httpStreamRequest: HttpStreamRequest
|
||||
private llmResponseParser: LlmResponseParser
|
||||
private llmStreamParser: LlmStreamParser
|
||||
private bamlOptions: BamlCallOptions
|
||||
|
||||
constructor(private runtime: BamlRuntime, private ctxManager: BamlCtxManager, private bamlOptions?: BamlCallOptions) {
|
||||
this.httpRequest = new HttpRequest(runtime, ctxManager)
|
||||
this.httpStreamRequest = new HttpStreamRequest(runtime, ctxManager)
|
||||
this.llmResponseParser = new LlmResponseParser(runtime, ctxManager)
|
||||
this.llmStreamParser = new LlmStreamParser(runtime, ctxManager)
|
||||
this.bamlOptions = bamlOptions || {}
|
||||
}
|
||||
|
||||
withOptions(bamlOptions: BamlCallOptions) {
|
||||
return new BamlSyncClient(this.runtime, this.ctxManager, bamlOptions)
|
||||
}
|
||||
|
||||
/*
|
||||
* @deprecated NOT IMPLEMENTED as streaming must by async. We
|
||||
* are not providing an async version as we want to reserve the
|
||||
* right to provide a sync version in the future.
|
||||
*/
|
||||
get stream() {
|
||||
throw new Error("stream is not available in BamlSyncClient. Use `import { b } from 'baml_client/async_client")
|
||||
}
|
||||
|
||||
get request() {
|
||||
return this.httpRequest
|
||||
}
|
||||
|
||||
get streamRequest() {
|
||||
return this.httpStreamRequest
|
||||
}
|
||||
|
||||
get parse() {
|
||||
return this.llmResponseParser
|
||||
}
|
||||
|
||||
get parseStream() {
|
||||
return this.llmStreamParser
|
||||
}
|
||||
|
||||
|
||||
DetermineNextStep(
|
||||
thread: string,
|
||||
__baml_options__?: BamlCallOptions
|
||||
): AddTool | SubtractTool | MultiplyTool | DivideTool | DoneForNow {
|
||||
try {
|
||||
const options = { ...this.bamlOptions, ...(__baml_options__ || {}) }
|
||||
const collector = options.collector ? (Array.isArray(options.collector) ? options.collector : [options.collector]) : [];
|
||||
const raw = this.runtime.callFunctionSync(
|
||||
"DetermineNextStep",
|
||||
{
|
||||
"thread": thread
|
||||
},
|
||||
this.ctxManager.cloneContext(),
|
||||
options.tb?.__tb(),
|
||||
options.clientRegistry,
|
||||
collector,
|
||||
)
|
||||
return raw.parsed(false) as AddTool | SubtractTool | MultiplyTool | DivideTool | DoneForNow
|
||||
} catch (error: any) {
|
||||
throw toBamlError(error);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export const b = new BamlSyncClient(DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_RUNTIME, DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_CTX)
|
||||
@@ -1,80 +0,0 @@
|
||||
/*************************************************************************************************
|
||||
|
||||
Welcome to Baml! To use this generated code, please run one of the following:
|
||||
|
||||
$ npm install @boundaryml/baml
|
||||
$ yarn add @boundaryml/baml
|
||||
$ pnpm add @boundaryml/baml
|
||||
|
||||
*************************************************************************************************/
|
||||
|
||||
// This file was generated by BAML: do not edit it. Instead, edit the BAML
|
||||
// files and re-generate this code.
|
||||
//
|
||||
/* eslint-disable */
|
||||
// tslint:disable
|
||||
// @ts-nocheck
|
||||
// biome-ignore format: autogenerated code
|
||||
import type { BamlRuntime, BamlCtxManager, ClientRegistry, Image, Audio } from "@boundaryml/baml"
|
||||
import { toBamlError, HTTPRequest } from "@boundaryml/baml"
|
||||
import type { Checked, Check } from "./types"
|
||||
import type * as types from "./types"
|
||||
import type {AddTool, DivideTool, DoneForNow, MultiplyTool, SubtractTool} from "./types"
|
||||
import type TypeBuilder from "./type_builder"
|
||||
|
||||
type BamlCallOptions = {
|
||||
tb?: TypeBuilder
|
||||
clientRegistry?: ClientRegistry
|
||||
}
|
||||
|
||||
export class HttpRequest {
|
||||
constructor(private runtime: BamlRuntime, private ctxManager: BamlCtxManager) {}
|
||||
|
||||
|
||||
DetermineNextStep(
|
||||
thread: string,
|
||||
__baml_options__?: BamlCallOptions
|
||||
): HTTPRequest {
|
||||
try {
|
||||
return this.runtime.buildRequestSync(
|
||||
"DetermineNextStep",
|
||||
{
|
||||
"thread": thread
|
||||
},
|
||||
this.ctxManager.cloneContext(),
|
||||
__baml_options__?.tb?.__tb(),
|
||||
__baml_options__?.clientRegistry,
|
||||
false,
|
||||
)
|
||||
} catch (error) {
|
||||
throw toBamlError(error);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export class HttpStreamRequest {
|
||||
constructor(private runtime: BamlRuntime, private ctxManager: BamlCtxManager) {}
|
||||
|
||||
|
||||
DetermineNextStep(
|
||||
thread: string,
|
||||
__baml_options__?: BamlCallOptions
|
||||
): HTTPRequest {
|
||||
try {
|
||||
return this.runtime.buildRequestSync(
|
||||
"DetermineNextStep",
|
||||
{
|
||||
"thread": thread
|
||||
},
|
||||
this.ctxManager.cloneContext(),
|
||||
__baml_options__?.tb?.__tb(),
|
||||
__baml_options__?.clientRegistry,
|
||||
true,
|
||||
)
|
||||
} catch (error) {
|
||||
throw toBamlError(error);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
/*************************************************************************************************
|
||||
|
||||
Welcome to Baml! To use this generated code, please run one of the following:
|
||||
|
||||
$ npm install @boundaryml/baml
|
||||
$ yarn add @boundaryml/baml
|
||||
$ pnpm add @boundaryml/baml
|
||||
|
||||
*************************************************************************************************/
|
||||
|
||||
// This file was generated by BAML: do not edit it. Instead, edit the BAML
|
||||
// files and re-generate this code.
|
||||
//
|
||||
/* eslint-disable */
|
||||
// tslint:disable
|
||||
// @ts-nocheck
|
||||
// biome-ignore format: autogenerated code
|
||||
import type { BamlLogEvent } from '@boundaryml/baml';
|
||||
import { DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_CTX } from './globals';
|
||||
|
||||
const traceAsync =
|
||||
DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_CTX.traceFnAsync.bind(DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_CTX)
|
||||
const traceSync =
|
||||
DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_CTX.traceFnSync.bind(DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_CTX)
|
||||
const setTags =
|
||||
DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_CTX.upsertTags.bind(DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_CTX)
|
||||
const flush = () => {
|
||||
DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_CTX.flush.bind(DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_CTX)()
|
||||
}
|
||||
const onLogEvent = (callback: undefined | ((event: BamlLogEvent) => void)) =>
|
||||
DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_CTX.onLogEvent(callback)
|
||||
|
||||
export { traceAsync, traceSync, setTags, flush, onLogEvent }
|
||||
@@ -1,100 +0,0 @@
|
||||
/*************************************************************************************************
|
||||
|
||||
Welcome to Baml! To use this generated code, please run one of the following:
|
||||
|
||||
$ npm install @boundaryml/baml
|
||||
$ yarn add @boundaryml/baml
|
||||
$ pnpm add @boundaryml/baml
|
||||
|
||||
*************************************************************************************************/
|
||||
|
||||
// This file was generated by BAML: do not edit it. Instead, edit the BAML
|
||||
// files and re-generate this code.
|
||||
//
|
||||
/* eslint-disable */
|
||||
// tslint:disable
|
||||
// @ts-nocheck
|
||||
// biome-ignore format: autogenerated code
|
||||
import { FieldType } from '@boundaryml/baml/native'
|
||||
import { TypeBuilder as _TypeBuilder, EnumBuilder, ClassBuilder } from '@boundaryml/baml/type_builder'
|
||||
import { DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_RUNTIME } from "./globals"
|
||||
|
||||
export default class TypeBuilder {
|
||||
private tb: _TypeBuilder;
|
||||
|
||||
|
||||
|
||||
constructor() {
|
||||
this.tb = new _TypeBuilder({
|
||||
classes: new Set([
|
||||
"AddTool","DivideTool","DoneForNow","MultiplyTool","SubtractTool",
|
||||
]),
|
||||
enums: new Set([
|
||||
|
||||
]),
|
||||
runtime: DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_RUNTIME
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
|
||||
__tb() {
|
||||
return this.tb._tb();
|
||||
}
|
||||
|
||||
string(): FieldType {
|
||||
return this.tb.string()
|
||||
}
|
||||
|
||||
literalString(value: string): FieldType {
|
||||
return this.tb.literalString(value)
|
||||
}
|
||||
|
||||
literalInt(value: number): FieldType {
|
||||
return this.tb.literalInt(value)
|
||||
}
|
||||
|
||||
literalBool(value: boolean): FieldType {
|
||||
return this.tb.literalBool(value)
|
||||
}
|
||||
|
||||
int(): FieldType {
|
||||
return this.tb.int()
|
||||
}
|
||||
|
||||
float(): FieldType {
|
||||
return this.tb.float()
|
||||
}
|
||||
|
||||
bool(): FieldType {
|
||||
return this.tb.bool()
|
||||
}
|
||||
|
||||
list(type: FieldType): FieldType {
|
||||
return this.tb.list(type)
|
||||
}
|
||||
|
||||
null(): FieldType {
|
||||
return this.tb.null()
|
||||
}
|
||||
|
||||
map(key: FieldType, value: FieldType): FieldType {
|
||||
return this.tb.map(key, value)
|
||||
}
|
||||
|
||||
union(types: FieldType[]): FieldType {
|
||||
return this.tb.union(types)
|
||||
}
|
||||
|
||||
addClass<Name extends string>(name: Name): ClassBuilder<Name> {
|
||||
return this.tb.addClass(name);
|
||||
}
|
||||
|
||||
addEnum<Name extends string>(name: Name): EnumBuilder<Name> {
|
||||
return this.tb.addEnum(name);
|
||||
}
|
||||
|
||||
addBaml(baml: string): void {
|
||||
this.tb.addBaml(baml, this.runtime);
|
||||
}
|
||||
}
|
||||
@@ -1,81 +0,0 @@
|
||||
/*************************************************************************************************
|
||||
|
||||
Welcome to Baml! To use this generated code, please run one of the following:
|
||||
|
||||
$ npm install @boundaryml/baml
|
||||
$ yarn add @boundaryml/baml
|
||||
$ pnpm add @boundaryml/baml
|
||||
|
||||
*************************************************************************************************/
|
||||
|
||||
// This file was generated by BAML: do not edit it. Instead, edit the BAML
|
||||
// files and re-generate this code.
|
||||
//
|
||||
/* eslint-disable */
|
||||
// tslint:disable
|
||||
// @ts-nocheck
|
||||
// biome-ignore format: autogenerated code
|
||||
import type { Image, Audio } from "@boundaryml/baml"
|
||||
|
||||
/**
|
||||
* Recursively partial type that can be null.
|
||||
*
|
||||
* @deprecated Use types from the `partial_types` namespace instead, which provides type-safe partial implementations
|
||||
* @template T The type to make recursively partial.
|
||||
*/
|
||||
export type RecursivePartialNull<T> = T extends object
|
||||
? { [P in keyof T]?: RecursivePartialNull<T[P]> }
|
||||
: T | null;
|
||||
|
||||
export interface Checked<T,CheckName extends string = string> {
|
||||
value: T,
|
||||
checks: Record<CheckName, Check>,
|
||||
}
|
||||
|
||||
|
||||
export interface Check {
|
||||
name: string,
|
||||
expr: string
|
||||
status: "succeeded" | "failed"
|
||||
}
|
||||
|
||||
export function all_succeeded<CheckName extends string>(checks: Record<CheckName, Check>): boolean {
|
||||
return get_checks(checks).every(check => check.status === "succeeded")
|
||||
}
|
||||
|
||||
export function get_checks<CheckName extends string>(checks: Record<CheckName, Check>): Check[] {
|
||||
return Object.values(checks)
|
||||
}
|
||||
export interface AddTool {
|
||||
intent: "add"
|
||||
a: number | number
|
||||
b: number | number
|
||||
|
||||
}
|
||||
|
||||
export interface DivideTool {
|
||||
intent: "divide"
|
||||
a: number | number
|
||||
b: number | number
|
||||
|
||||
}
|
||||
|
||||
export interface DoneForNow {
|
||||
intent: "done_for_now"
|
||||
message: string
|
||||
|
||||
}
|
||||
|
||||
export interface MultiplyTool {
|
||||
intent: "multiply"
|
||||
a: number | number
|
||||
b: number | number
|
||||
|
||||
}
|
||||
|
||||
export interface SubtractTool {
|
||||
intent: "subtract"
|
||||
a: number | number
|
||||
b: number | number
|
||||
|
||||
}
|
||||
2295
workshops/2025-05/sections/03-tool-loop/package-lock.json
generated
2295
workshops/2025-05/sections/03-tool-loop/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -1,20 +0,0 @@
|
||||
{
|
||||
"name": "my-agent",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "tsx src/index.ts",
|
||||
"build": "tsc"
|
||||
},
|
||||
"dependencies": {
|
||||
"baml": "^0.0.0",
|
||||
"tsx": "^4.15.0",
|
||||
"typescript": "^5.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^20.0.0",
|
||||
"@typescript-eslint/eslint-plugin": "^6.0.0",
|
||||
"@typescript-eslint/parser": "^6.0.0",
|
||||
"eslint": "^8.0.0"
|
||||
}
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
import { b } from "../baml_client";
|
||||
|
||||
// tool call or a respond to human tool
|
||||
type AgentResponse = Awaited<ReturnType<typeof b.DetermineNextStep>>;
|
||||
|
||||
export interface Event {
|
||||
type: string
|
||||
data: any;
|
||||
}
|
||||
|
||||
export class Thread {
|
||||
events: Event[] = [];
|
||||
|
||||
constructor(events: Event[]) {
|
||||
this.events = events;
|
||||
}
|
||||
|
||||
serializeForLLM() {
|
||||
// can change this to whatever custom serialization you want to do, XML, etc
|
||||
// e.g. https://github.com/got-agents/agents/blob/59ebbfa236fc376618f16ee08eb0f3bf7b698892/linear-assistant-ts/src/agent.ts#L66-L105
|
||||
return JSON.stringify(this.events);
|
||||
}
|
||||
}
|
||||
|
||||
// right now this just runs one turn with the LLM, but
|
||||
// we'll update this function to handle all the agent logic
|
||||
export async function agentLoop(thread: Thread): Promise<AgentResponse> {
|
||||
const nextStep = await b.DetermineNextStep(thread.serializeForLLM());
|
||||
return nextStep;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
// cli.ts lets you invoke the agent loop from the command line
|
||||
|
||||
import { agentLoop, Thread, Event } from "./agent";
|
||||
|
||||
export async function cli() {
|
||||
// Get command line arguments, skipping the first two (node and script name)
|
||||
const args = process.argv.slice(2);
|
||||
|
||||
if (args.length === 0) {
|
||||
console.error("Error: Please provide a message as a command line argument");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// Join all arguments into a single message
|
||||
const message = args.join(" ");
|
||||
|
||||
// Create a new thread with the user's message as the initial event
|
||||
const thread = new Thread([{ type: "user_input", data: message }]);
|
||||
|
||||
// Run the agent loop with the thread
|
||||
const result = await agentLoop(thread);
|
||||
console.log(result);
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
import { cli } from "./cli"
|
||||
|
||||
async function hello(): Promise<void> {
|
||||
console.log('hello, world!')
|
||||
}
|
||||
|
||||
async function main() {
|
||||
await cli()
|
||||
}
|
||||
|
||||
main().catch(console.error)
|
||||
@@ -1,24 +0,0 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2017",
|
||||
"lib": ["esnext"],
|
||||
"allowJs": true,
|
||||
"skipLibCheck": true,
|
||||
"strict": true,
|
||||
"noEmit": true,
|
||||
"esModuleInterop": true,
|
||||
"module": "esnext",
|
||||
"moduleResolution": "bundler",
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"jsx": "preserve",
|
||||
"incremental": true,
|
||||
"plugins": [],
|
||||
"paths": {
|
||||
"@/*": ["./*"]
|
||||
}
|
||||
},
|
||||
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
|
||||
"exclude": ["node_modules", "walkthrough"]
|
||||
}
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
import { b } from "../baml_client";
|
||||
|
||||
// tool call or a respond to human tool
|
||||
type AgentResponse = Awaited<ReturnType<typeof b.DetermineNextStep>>;
|
||||
|
||||
export interface Event {
|
||||
type: string
|
||||
data: any;
|
||||
}
|
||||
|
||||
export class Thread {
|
||||
events: Event[] = [];
|
||||
|
||||
constructor(events: Event[]) {
|
||||
this.events = events;
|
||||
}
|
||||
|
||||
serializeForLLM() {
|
||||
// can change this to whatever custom serialization you want to do, XML, etc
|
||||
// e.g. https://github.com/got-agents/agents/blob/59ebbfa236fc376618f16ee08eb0f3bf7b698892/linear-assistant-ts/src/agent.ts#L66-L105
|
||||
return JSON.stringify(this.events);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
export async function agentLoop(thread: Thread): Promise<string> {
|
||||
|
||||
while (true) {
|
||||
const nextStep = await b.DetermineNextStep(thread.serializeForLLM());
|
||||
console.log("nextStep", nextStep);
|
||||
|
||||
switch (nextStep.intent) {
|
||||
case "done_for_now":
|
||||
// response to human, return the next step object
|
||||
return nextStep.message;
|
||||
case "add":
|
||||
thread.events.push({
|
||||
"type": "tool_call",
|
||||
"data": nextStep
|
||||
});
|
||||
const result = nextStep.a + nextStep.b;
|
||||
console.log("tool_response", result);
|
||||
thread.events.push({
|
||||
"type": "tool_response",
|
||||
"data": result
|
||||
});
|
||||
continue;
|
||||
default:
|
||||
throw new Error(`Unknown intent: ${nextStep.intent}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,86 +0,0 @@
|
||||
import { AddTool, SubtractTool, DivideTool, MultiplyTool, b } from "../baml_client";
|
||||
|
||||
export interface Event {
|
||||
type: string
|
||||
data: any;
|
||||
}
|
||||
|
||||
export class Thread {
|
||||
events: Event[] = [];
|
||||
|
||||
constructor(events: Event[]) {
|
||||
this.events = events;
|
||||
}
|
||||
|
||||
serializeForLLM() {
|
||||
// can change this to whatever custom serialization you want to do, XML, etc
|
||||
// e.g. https://github.com/got-agents/agents/blob/59ebbfa236fc376618f16ee08eb0f3bf7b698892/linear-assistant-ts/src/agent.ts#L66-L105
|
||||
return JSON.stringify(this.events);
|
||||
}
|
||||
}
|
||||
|
||||
export type CalculatorTool = AddTool | SubtractTool | MultiplyTool | DivideTool;
|
||||
|
||||
export async function handleNextStep(nextStep: CalculatorTool, thread: Thread): Promise<Thread> {
|
||||
let result: number;
|
||||
switch (nextStep.intent) {
|
||||
case "add":
|
||||
result = nextStep.a + nextStep.b;
|
||||
console.log("tool_response", result);
|
||||
thread.events.push({
|
||||
"type": "tool_response",
|
||||
"data": result
|
||||
});
|
||||
return thread;
|
||||
case "subtract":
|
||||
result = nextStep.a - nextStep.b;
|
||||
console.log("tool_response", result);
|
||||
thread.events.push({
|
||||
"type": "tool_response",
|
||||
"data": result
|
||||
});
|
||||
return thread;
|
||||
case "multiply":
|
||||
result = nextStep.a * nextStep.b;
|
||||
console.log("tool_response", result);
|
||||
thread.events.push({
|
||||
"type": "tool_response",
|
||||
"data": result
|
||||
});
|
||||
return thread;
|
||||
case "divide":
|
||||
result = nextStep.a / nextStep.b;
|
||||
console.log("tool_response", result);
|
||||
thread.events.push({
|
||||
"type": "tool_response",
|
||||
"data": result
|
||||
});
|
||||
return thread;
|
||||
}
|
||||
}
|
||||
|
||||
export async function agentLoop(thread: Thread): Promise<string> {
|
||||
|
||||
while (true) {
|
||||
const nextStep = await b.DetermineNextStep(thread.serializeForLLM());
|
||||
console.log("nextStep", nextStep);
|
||||
|
||||
thread.events.push({
|
||||
"type": "tool_call",
|
||||
"data": nextStep
|
||||
});
|
||||
|
||||
switch (nextStep.intent) {
|
||||
case "done_for_now":
|
||||
// response to human, return the next step object
|
||||
return nextStep.message;
|
||||
case "add":
|
||||
case "subtract":
|
||||
case "multiply":
|
||||
case "divide":
|
||||
thread = await handleNextStep(nextStep, thread);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
baml_src/
|
||||
node_modules/
|
||||
@@ -1,144 +0,0 @@
|
||||
# Chapter 4 - Add Tests to agent.baml
|
||||
|
||||
Let's add some tests to our BAML agent.
|
||||
|
||||
Update agent with tests
|
||||
|
||||
```diff
|
||||
baml_src/agent.baml
|
||||
"#
|
||||
}
|
||||
+
|
||||
+test MathOperation {
|
||||
+ functions [DetermineNextStep]
|
||||
+ args {
|
||||
+ thread #"
|
||||
+ {
|
||||
+ "type": "user_input",
|
||||
+ "data": "can you multiply 3 and 4?"
|
||||
+ }
|
||||
+ "#
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>skip this step</summary>
|
||||
|
||||
cp ./walkthrough/04-agent.baml baml_src/agent.baml
|
||||
|
||||
</details>
|
||||
|
||||
Run the tests
|
||||
|
||||
npx baml-cli test
|
||||
|
||||
Add more complex test cases
|
||||
|
||||
```diff
|
||||
baml_src/agent.baml
|
||||
"#
|
||||
}
|
||||
+ @@assert(hello, {{this.intent == "done_for_now"}})
|
||||
}
|
||||
|
||||
"#
|
||||
}
|
||||
+ @@assert(math_operation, {{this.intent == "multiply"}})
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>skip this step</summary>
|
||||
|
||||
cp ./walkthrough/04b-agent.baml baml_src/agent.baml
|
||||
|
||||
</details>
|
||||
|
||||
Run the tests
|
||||
|
||||
npx baml-cli test
|
||||
|
||||
Add more complex test cases
|
||||
|
||||
```diff
|
||||
baml_src/agent.baml
|
||||
"#
|
||||
}
|
||||
- @@assert(hello, {{this.intent == "done_for_now"}})
|
||||
+ @@assert(intent, {{this.intent == "done_for_now"}})
|
||||
}
|
||||
|
||||
"#
|
||||
}
|
||||
- @@assert(math_operation, {{this.intent == "multiply"}})
|
||||
+ @@assert(intent, {{this.intent == "multiply"}})
|
||||
}
|
||||
|
||||
+test LongMath {
|
||||
+ functions [DetermineNextStep]
|
||||
+ args {
|
||||
+ thread #"
|
||||
+ [
|
||||
+ {
|
||||
+ "type": "user_input",
|
||||
+ "data": "can you multiply 3 and 4, then divide the result by 2 and then add 12 to that result?"
|
||||
+ },
|
||||
+ {
|
||||
+ "type": "tool_call",
|
||||
+ "data": {
|
||||
+ "intent": "multiply",
|
||||
+ "a": 3,
|
||||
+ "b": 4
|
||||
+ }
|
||||
+ },
|
||||
+ {
|
||||
+ "type": "tool_response",
|
||||
+ "data": 12
|
||||
+ },
|
||||
+ {
|
||||
+ "type": "tool_call",
|
||||
+ "data": {
|
||||
+ "intent": "divide",
|
||||
+ "a": 12,
|
||||
+ "b": 2
|
||||
+ }
|
||||
+ },
|
||||
+ {
|
||||
+ "type": "tool_response",
|
||||
+ "data": 6
|
||||
+ },
|
||||
+ {
|
||||
+ "type": "tool_call",
|
||||
+ "data": {
|
||||
+ "intent": "add",
|
||||
+ "a": 6,
|
||||
+ "b": 12
|
||||
+ }
|
||||
+ },
|
||||
+ {
|
||||
+ "type": "tool_response",
|
||||
+ "data": 18
|
||||
+ }
|
||||
+ ]
|
||||
+ "#
|
||||
+ }
|
||||
+ @@assert(intent, {{this.intent == "done_for_now"}})
|
||||
+ @@assert(answer, {{"18" in this.message}})
|
||||
+}
|
||||
+
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>skip this step</summary>
|
||||
|
||||
cp ./walkthrough/04c-agent.baml baml_src/agent.baml
|
||||
|
||||
</details>
|
||||
|
||||
Run the expanded test suite
|
||||
|
||||
npx baml-cli test
|
||||
|
||||
@@ -1,154 +0,0 @@
|
||||
/*************************************************************************************************
|
||||
|
||||
Welcome to Baml! To use this generated code, please run one of the following:
|
||||
|
||||
$ npm install @boundaryml/baml
|
||||
$ yarn add @boundaryml/baml
|
||||
$ pnpm add @boundaryml/baml
|
||||
|
||||
*************************************************************************************************/
|
||||
|
||||
// This file was generated by BAML: do not edit it. Instead, edit the BAML
|
||||
// files and re-generate this code.
|
||||
//
|
||||
/* eslint-disable */
|
||||
// tslint:disable
|
||||
// @ts-nocheck
|
||||
// biome-ignore format: autogenerated code
|
||||
import type { BamlRuntime, FunctionResult, BamlCtxManager, ClientRegistry, Image, Audio, Collector } from "@boundaryml/baml"
|
||||
import { toBamlError, BamlStream, type HTTPRequest } from "@boundaryml/baml"
|
||||
import type { Checked, Check, RecursivePartialNull as MovedRecursivePartialNull } from "./types"
|
||||
import type { partial_types } from "./partial_types"
|
||||
import type * as types from "./types"
|
||||
import type {AddTool, DivideTool, DoneForNow, MultiplyTool, SubtractTool} from "./types"
|
||||
import type TypeBuilder from "./type_builder"
|
||||
import { AsyncHttpRequest, AsyncHttpStreamRequest } from "./async_request"
|
||||
import { LlmResponseParser, LlmStreamParser } from "./parser"
|
||||
import { DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_CTX, DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_RUNTIME } from "./globals"
|
||||
|
||||
/**
|
||||
* @deprecated Use RecursivePartialNull from 'baml_client/types' instead.
|
||||
*/
|
||||
export type RecursivePartialNull<T> = MovedRecursivePartialNull<T>
|
||||
|
||||
type BamlCallOptions = {
|
||||
tb?: TypeBuilder
|
||||
clientRegistry?: ClientRegistry
|
||||
collector?: Collector | Collector[]
|
||||
}
|
||||
|
||||
export class BamlAsyncClient {
|
||||
private runtime: BamlRuntime
|
||||
private ctxManager: BamlCtxManager
|
||||
private streamClient: BamlStreamClient
|
||||
private httpRequest: AsyncHttpRequest
|
||||
private httpStreamRequest: AsyncHttpStreamRequest
|
||||
private llmResponseParser: LlmResponseParser
|
||||
private llmStreamParser: LlmStreamParser
|
||||
private bamlOptions: BamlCallOptions
|
||||
|
||||
constructor(runtime: BamlRuntime, ctxManager: BamlCtxManager, bamlOptions?: BamlCallOptions) {
|
||||
this.runtime = runtime
|
||||
this.ctxManager = ctxManager
|
||||
this.streamClient = new BamlStreamClient(runtime, ctxManager, bamlOptions)
|
||||
this.httpRequest = new AsyncHttpRequest(runtime, ctxManager)
|
||||
this.httpStreamRequest = new AsyncHttpStreamRequest(runtime, ctxManager)
|
||||
this.llmResponseParser = new LlmResponseParser(runtime, ctxManager)
|
||||
this.llmStreamParser = new LlmStreamParser(runtime, ctxManager)
|
||||
this.bamlOptions = bamlOptions || {}
|
||||
}
|
||||
|
||||
withOptions(bamlOptions: BamlCallOptions) {
|
||||
return new BamlAsyncClient(this.runtime, this.ctxManager, bamlOptions)
|
||||
}
|
||||
|
||||
get stream() {
|
||||
return this.streamClient
|
||||
}
|
||||
|
||||
get request() {
|
||||
return this.httpRequest
|
||||
}
|
||||
|
||||
get streamRequest() {
|
||||
return this.httpStreamRequest
|
||||
}
|
||||
|
||||
get parse() {
|
||||
return this.llmResponseParser
|
||||
}
|
||||
|
||||
get parseStream() {
|
||||
return this.llmStreamParser
|
||||
}
|
||||
|
||||
|
||||
async DetermineNextStep(
|
||||
thread: string,
|
||||
__baml_options__?: BamlCallOptions
|
||||
): Promise<AddTool | SubtractTool | MultiplyTool | DivideTool | DoneForNow> {
|
||||
try {
|
||||
const options = { ...this.bamlOptions, ...(__baml_options__ || {}) }
|
||||
const collector = options.collector ? (Array.isArray(options.collector) ? options.collector : [options.collector]) : [];
|
||||
const raw = await this.runtime.callFunction(
|
||||
"DetermineNextStep",
|
||||
{
|
||||
"thread": thread
|
||||
},
|
||||
this.ctxManager.cloneContext(),
|
||||
options.tb?.__tb(),
|
||||
options.clientRegistry,
|
||||
collector,
|
||||
)
|
||||
return raw.parsed(false) as AddTool | SubtractTool | MultiplyTool | DivideTool | DoneForNow
|
||||
} catch (error) {
|
||||
throw toBamlError(error);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class BamlStreamClient {
|
||||
private runtime: BamlRuntime
|
||||
private ctxManager: BamlCtxManager
|
||||
private bamlOptions: BamlCallOptions
|
||||
|
||||
constructor(runtime: BamlRuntime, ctxManager: BamlCtxManager, bamlOptions?: BamlCallOptions) {
|
||||
this.runtime = runtime
|
||||
this.ctxManager = ctxManager
|
||||
this.bamlOptions = bamlOptions || {}
|
||||
}
|
||||
|
||||
|
||||
DetermineNextStep(
|
||||
thread: string,
|
||||
__baml_options__?: { tb?: TypeBuilder, clientRegistry?: ClientRegistry, collector?: Collector | Collector[] }
|
||||
): BamlStream<(((partial_types.AddTool | null) | (partial_types.SubtractTool | null) | (partial_types.MultiplyTool | null) | (partial_types.DivideTool | null) | null) | (partial_types.DoneForNow | null)), AddTool | SubtractTool | MultiplyTool | DivideTool | DoneForNow> {
|
||||
try {
|
||||
const options = { ...this.bamlOptions, ...(__baml_options__ || {}) }
|
||||
const collector = options.collector ? (Array.isArray(options.collector) ? options.collector : [options.collector]) : [];
|
||||
const raw = this.runtime.streamFunction(
|
||||
"DetermineNextStep",
|
||||
{
|
||||
"thread": thread
|
||||
},
|
||||
undefined,
|
||||
this.ctxManager.cloneContext(),
|
||||
options.tb?.__tb(),
|
||||
options.clientRegistry,
|
||||
collector,
|
||||
)
|
||||
return new BamlStream<(((partial_types.AddTool | null) | (partial_types.SubtractTool | null) | (partial_types.MultiplyTool | null) | (partial_types.DivideTool | null) | null) | (partial_types.DoneForNow | null)), AddTool | SubtractTool | MultiplyTool | DivideTool | DoneForNow>(
|
||||
raw,
|
||||
(a): (((partial_types.AddTool | null) | (partial_types.SubtractTool | null) | (partial_types.MultiplyTool | null) | (partial_types.DivideTool | null) | null) | (partial_types.DoneForNow | null)) => a,
|
||||
(a): AddTool | SubtractTool | MultiplyTool | DivideTool | DoneForNow => a,
|
||||
this.ctxManager.cloneContext(),
|
||||
)
|
||||
} catch (error) {
|
||||
throw toBamlError(error);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export const b = new BamlAsyncClient(DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_RUNTIME, DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_CTX)
|
||||
@@ -1,80 +0,0 @@
|
||||
/*************************************************************************************************
|
||||
|
||||
Welcome to Baml! To use this generated code, please run one of the following:
|
||||
|
||||
$ npm install @boundaryml/baml
|
||||
$ yarn add @boundaryml/baml
|
||||
$ pnpm add @boundaryml/baml
|
||||
|
||||
*************************************************************************************************/
|
||||
|
||||
// This file was generated by BAML: do not edit it. Instead, edit the BAML
|
||||
// files and re-generate this code.
|
||||
//
|
||||
/* eslint-disable */
|
||||
// tslint:disable
|
||||
// @ts-nocheck
|
||||
// biome-ignore format: autogenerated code
|
||||
import type { BamlRuntime, BamlCtxManager, ClientRegistry, Image, Audio } from "@boundaryml/baml"
|
||||
import { toBamlError, HTTPRequest } from "@boundaryml/baml"
|
||||
import type { Checked, Check } from "./types"
|
||||
import type * as types from "./types"
|
||||
import type {AddTool, DivideTool, DoneForNow, MultiplyTool, SubtractTool} from "./types"
|
||||
import type TypeBuilder from "./type_builder"
|
||||
|
||||
type BamlCallOptions = {
|
||||
tb?: TypeBuilder
|
||||
clientRegistry?: ClientRegistry
|
||||
}
|
||||
|
||||
export class AsyncHttpRequest {
|
||||
constructor(private runtime: BamlRuntime, private ctxManager: BamlCtxManager) {}
|
||||
|
||||
|
||||
async DetermineNextStep(
|
||||
thread: string,
|
||||
__baml_options__?: BamlCallOptions
|
||||
): Promise<HTTPRequest> {
|
||||
try {
|
||||
return await this.runtime.buildRequest(
|
||||
"DetermineNextStep",
|
||||
{
|
||||
"thread": thread
|
||||
},
|
||||
this.ctxManager.cloneContext(),
|
||||
__baml_options__?.tb?.__tb(),
|
||||
__baml_options__?.clientRegistry,
|
||||
false,
|
||||
)
|
||||
} catch (error) {
|
||||
throw toBamlError(error);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export class AsyncHttpStreamRequest {
|
||||
constructor(private runtime: BamlRuntime, private ctxManager: BamlCtxManager) {}
|
||||
|
||||
|
||||
async DetermineNextStep(
|
||||
thread: string,
|
||||
__baml_options__?: BamlCallOptions
|
||||
): Promise<HTTPRequest> {
|
||||
try {
|
||||
return await this.runtime.buildRequest(
|
||||
"DetermineNextStep",
|
||||
{
|
||||
"thread": thread
|
||||
},
|
||||
this.ctxManager.cloneContext(),
|
||||
__baml_options__?.tb?.__tb(),
|
||||
__baml_options__?.clientRegistry,
|
||||
true,
|
||||
)
|
||||
} catch (error) {
|
||||
throw toBamlError(error);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
/*************************************************************************************************
|
||||
|
||||
Welcome to Baml! To use this generated code, please run one of the following:
|
||||
|
||||
$ npm install @boundaryml/baml
|
||||
$ yarn add @boundaryml/baml
|
||||
$ pnpm add @boundaryml/baml
|
||||
|
||||
*************************************************************************************************/
|
||||
|
||||
// This file was generated by BAML: do not edit it. Instead, edit the BAML
|
||||
// files and re-generate this code.
|
||||
//
|
||||
/* eslint-disable */
|
||||
// tslint:disable
|
||||
// @ts-nocheck
|
||||
// biome-ignore format: autogenerated code
|
||||
export { setLogLevel, getLogLevel, setLogJson } from "@boundaryml/baml/logging";
|
||||
export { resetBamlEnvVars } from "./globals";
|
||||
@@ -1,67 +0,0 @@
|
||||
/*************************************************************************************************
|
||||
|
||||
Welcome to Baml! To use this generated code, please run one of the following:
|
||||
|
||||
$ npm install @boundaryml/baml
|
||||
$ yarn add @boundaryml/baml
|
||||
$ pnpm add @boundaryml/baml
|
||||
|
||||
*************************************************************************************************/
|
||||
|
||||
// This file was generated by BAML: do not edit it. Instead, edit the BAML
|
||||
// files and re-generate this code.
|
||||
//
|
||||
/* eslint-disable */
|
||||
// tslint:disable
|
||||
// @ts-nocheck
|
||||
// biome-ignore format: autogenerated code
|
||||
import { BamlRuntime, BamlCtxManager } from '@boundaryml/baml'
|
||||
import { getBamlFiles } from './inlinedbaml'
|
||||
|
||||
|
||||
export const DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_RUNTIME = BamlRuntime.fromFiles(
|
||||
'baml_src',
|
||||
getBamlFiles(),
|
||||
process.env
|
||||
)
|
||||
export const DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_CTX = new BamlCtxManager(DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_RUNTIME)
|
||||
|
||||
|
||||
export function resetBamlEnvVars(envVars: Record<string, string | undefined>) {
|
||||
if (DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_CTX.allowResets()) {
|
||||
const envVarsToReset = Object.fromEntries(Object.entries(envVars).filter((kv): kv is [string, string] => kv[1] !== undefined));
|
||||
DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_RUNTIME.reset('baml_src', getBamlFiles(), envVarsToReset)
|
||||
DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_CTX.reset()
|
||||
} else {
|
||||
throw new Error('BamlError: Cannot reset BAML environment variables while there are active BAML contexts.')
|
||||
}
|
||||
}
|
||||
|
||||
const patchedLoad = (originalFn: any) => (...args: any[]) => {
|
||||
const result = originalFn(...args);
|
||||
try {
|
||||
// Dont fail if env vars fail to reset
|
||||
resetBamlEnvVars(process.env);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
try {
|
||||
const dotenv = require('dotenv');
|
||||
// Monkeypatch load function to call resetBamlEnvVars after execution
|
||||
|
||||
|
||||
// Apply the patch
|
||||
dotenv.config = patchedLoad(dotenv.config);
|
||||
dotenv.configDotenv = patchedLoad(dotenv.configDotenv);
|
||||
dotenv.populate = patchedLoad(dotenv.populate);
|
||||
} catch (error) {
|
||||
// dotenv is not installed, so we do nothing
|
||||
}
|
||||
|
||||
// also patch process.loadEnvFile
|
||||
if (process.loadEnvFile) {
|
||||
process.loadEnvFile = patchedLoad(process.loadEnvFile);
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
/*************************************************************************************************
|
||||
|
||||
Welcome to Baml! To use this generated code, please run one of the following:
|
||||
|
||||
$ npm install @boundaryml/baml
|
||||
$ yarn add @boundaryml/baml
|
||||
$ pnpm add @boundaryml/baml
|
||||
|
||||
*************************************************************************************************/
|
||||
|
||||
// This file was generated by BAML: do not edit it. Instead, edit the BAML
|
||||
// files and re-generate this code.
|
||||
//
|
||||
/* eslint-disable */
|
||||
// tslint:disable
|
||||
// @ts-nocheck
|
||||
// biome-ignore format: autogenerated code
|
||||
/**
|
||||
* If this import fails, you may need to upgrade @boundaryml/baml.
|
||||
*
|
||||
* Please upgrade @boundaryml/baml to 0.85.0.
|
||||
*
|
||||
* $ npm install @boundaryml/baml@0.85.0
|
||||
* $ yarn add @boundaryml/baml@0.85.0
|
||||
* $ pnpm add @boundaryml/baml@0.85.0
|
||||
*
|
||||
* If nothing else works, please ask for help:
|
||||
*
|
||||
* https://github.com/boundaryml/baml/issues
|
||||
* https://boundaryml.com/discord
|
||||
*
|
||||
**/
|
||||
import { ThrowIfVersionMismatch } from "@boundaryml/baml";
|
||||
|
||||
export const version = "0.85.0";
|
||||
|
||||
ThrowIfVersionMismatch(version);
|
||||
|
||||
|
||||
|
||||
export { b } from "./async_client"
|
||||
|
||||
export * from "./types"
|
||||
export type { partial_types } from "./partial_types"
|
||||
export * from "./tracing"
|
||||
export { resetBamlEnvVars } from "./globals"
|
||||
export { BamlClientHttpError, BamlValidationError, BamlClientFinishReasonError } from "@boundaryml/baml"
|
||||
@@ -1,27 +0,0 @@
|
||||
/*************************************************************************************************
|
||||
|
||||
Welcome to Baml! To use this generated code, please run one of the following:
|
||||
|
||||
$ npm install @boundaryml/baml
|
||||
$ yarn add @boundaryml/baml
|
||||
$ pnpm add @boundaryml/baml
|
||||
|
||||
*************************************************************************************************/
|
||||
|
||||
// This file was generated by BAML: do not edit it. Instead, edit the BAML
|
||||
// files and re-generate this code.
|
||||
//
|
||||
/* eslint-disable */
|
||||
// tslint:disable
|
||||
// @ts-nocheck
|
||||
// biome-ignore format: autogenerated code
|
||||
const fileMap = {
|
||||
|
||||
"agent.baml": "class DoneForNow {\n intent \"done_for_now\"\n message string \n}\n\nfunction DetermineNextStep(\n thread: string \n) -> CalculatorTools | DoneForNow {\n client \"openai/gpt-4o\"\n\n prompt #\"\n {{ _.role(\"system\") }}\n\n You are a helpful assistant that can help with tasks.\n\n {{ _.role(\"user\") }}\n\n You are working on the following thread:\n\n {{ thread }}\n\n What should the next step be?\n\n {{ ctx.output_format }}\n \"#\n}\n\ntest HelloWorld {\n functions [DetermineNextStep]\n args {\n thread #\"\n {\n \"type\": \"user_input\",\n \"data\": \"hello!\"\n }\n \"#\n }\n}",
|
||||
"clients.baml": "// Learn more about clients at https://docs.boundaryml.com/docs/snippets/clients/overview\n\nclient<llm> CustomGPT4o {\n provider openai\n options {\n model \"gpt-4o\"\n api_key env.OPENAI_API_KEY\n }\n}\n\nclient<llm> CustomGPT4oMini {\n provider openai\n retry_policy Exponential\n options {\n model \"gpt-4o-mini\"\n api_key env.OPENAI_API_KEY\n }\n}\n\nclient<llm> CustomSonnet {\n provider anthropic\n options {\n model \"claude-3-5-sonnet-20241022\"\n api_key env.ANTHROPIC_API_KEY\n }\n}\n\n\nclient<llm> CustomHaiku {\n provider anthropic\n retry_policy Constant\n options {\n model \"claude-3-haiku-20240307\"\n api_key env.ANTHROPIC_API_KEY\n }\n}\n\n// https://docs.boundaryml.com/docs/snippets/clients/round-robin\nclient<llm> CustomFast {\n provider round-robin\n options {\n // This will alternate between the two clients\n strategy [CustomGPT4oMini, CustomHaiku]\n }\n}\n\n// https://docs.boundaryml.com/docs/snippets/clients/fallback\nclient<llm> OpenaiFallback {\n provider fallback\n options {\n // This will try the clients in order until one succeeds\n strategy [CustomGPT4oMini, CustomGPT4oMini]\n }\n}\n\n// https://docs.boundaryml.com/docs/snippets/clients/retry\nretry_policy Constant {\n max_retries 3\n // Strategy is optional\n strategy {\n type constant_delay\n delay_ms 200\n }\n}\n\nretry_policy Exponential {\n max_retries 2\n // Strategy is optional\n strategy {\n type exponential_backoff\n delay_ms 300\n multiplier 1.5\n max_delay_ms 10000\n }\n}",
|
||||
"generators.baml": "// This helps use auto generate libraries you can use in the language of\n// your choice. You can have multiple generators if you use multiple languages.\n// Just ensure that the output_dir is different for each generator.\ngenerator target {\n // Valid values: \"python/pydantic\", \"typescript\", \"ruby/sorbet\", \"rest/openapi\"\n output_type \"typescript\"\n\n // Where the generated code will be saved (relative to baml_src/)\n output_dir \"../\"\n\n // The version of the BAML package you have installed (e.g. same version as your baml-py or @boundaryml/baml).\n // The BAML VSCode extension version should also match this version.\n version \"0.85.0\"\n\n // Valid values: \"sync\", \"async\"\n // This controls what `b.FunctionName()` will be (sync or async).\n default_client_mode async\n}\n",
|
||||
"tool_calculator.baml": "type CalculatorTools = AddTool | SubtractTool | MultiplyTool | DivideTool\n\n\nclass AddTool {\n intent \"add\"\n a int | float\n b int | float\n}\n\nclass SubtractTool {\n intent \"subtract\"\n a int | float\n b int | float\n}\n\nclass MultiplyTool {\n intent \"multiply\"\n a int | float\n b int | float\n}\n\nclass DivideTool {\n intent \"divide\"\n a int | float\n b int | float\n}\n\n",
|
||||
}
|
||||
export const getBamlFiles = () => {
|
||||
return fileMap;
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
/*************************************************************************************************
|
||||
|
||||
Welcome to Baml! To use this generated code, please run one of the following:
|
||||
|
||||
$ npm install @boundaryml/baml
|
||||
$ yarn add @boundaryml/baml
|
||||
$ pnpm add @boundaryml/baml
|
||||
|
||||
*************************************************************************************************/
|
||||
|
||||
// This file was generated by BAML: do not edit it. Instead, edit the BAML
|
||||
// files and re-generate this code.
|
||||
//
|
||||
/* eslint-disable */
|
||||
// tslint:disable
|
||||
// @ts-nocheck
|
||||
// biome-ignore format: autogenerated code
|
||||
import type { BamlRuntime, BamlCtxManager, ClientRegistry, Image, Audio, Collector } from "@boundaryml/baml"
|
||||
import { toBamlError } from "@boundaryml/baml"
|
||||
import type { Checked, Check } from "./types"
|
||||
import type { partial_types } from "./partial_types"
|
||||
import type * as types from "./types"
|
||||
import type {AddTool, DivideTool, DoneForNow, MultiplyTool, SubtractTool} from "./types"
|
||||
import type TypeBuilder from "./type_builder"
|
||||
|
||||
export class LlmResponseParser {
|
||||
constructor(private runtime: BamlRuntime, private ctxManager: BamlCtxManager) {}
|
||||
|
||||
|
||||
DetermineNextStep(
|
||||
llmResponse: string,
|
||||
__baml_options__?: { tb?: TypeBuilder, clientRegistry?: ClientRegistry }
|
||||
): AddTool | SubtractTool | MultiplyTool | DivideTool | DoneForNow {
|
||||
try {
|
||||
return this.runtime.parseLlmResponse(
|
||||
"DetermineNextStep",
|
||||
llmResponse,
|
||||
false,
|
||||
this.ctxManager.cloneContext(),
|
||||
__baml_options__?.tb?.__tb(),
|
||||
__baml_options__?.clientRegistry,
|
||||
) as AddTool | SubtractTool | MultiplyTool | DivideTool | DoneForNow
|
||||
} catch (error) {
|
||||
throw toBamlError(error);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export class LlmStreamParser {
|
||||
constructor(private runtime: BamlRuntime, private ctxManager: BamlCtxManager) {}
|
||||
|
||||
|
||||
DetermineNextStep(
|
||||
llmResponse: string,
|
||||
__baml_options__?: { tb?: TypeBuilder, clientRegistry?: ClientRegistry }
|
||||
): (((partial_types.AddTool | null) | (partial_types.SubtractTool | null) | (partial_types.MultiplyTool | null) | (partial_types.DivideTool | null) | null) | (partial_types.DoneForNow | null)) {
|
||||
try {
|
||||
return this.runtime.parseLlmResponse(
|
||||
"DetermineNextStep",
|
||||
llmResponse,
|
||||
true,
|
||||
this.ctxManager.cloneContext(),
|
||||
__baml_options__?.tb?.__tb(),
|
||||
__baml_options__?.clientRegistry,
|
||||
) as (((partial_types.AddTool | null) | (partial_types.SubtractTool | null) | (partial_types.MultiplyTool | null) | (partial_types.DivideTool | null) | null) | (partial_types.DoneForNow | null))
|
||||
} catch (error) {
|
||||
throw toBamlError(error);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,66 +0,0 @@
|
||||
/*************************************************************************************************
|
||||
|
||||
Welcome to Baml! To use this generated code, please run one of the following:
|
||||
|
||||
$ npm install @boundaryml/baml
|
||||
$ yarn add @boundaryml/baml
|
||||
$ pnpm add @boundaryml/baml
|
||||
|
||||
*************************************************************************************************/
|
||||
|
||||
// This file was generated by BAML: do not edit it. Instead, edit the BAML
|
||||
// files and re-generate this code.
|
||||
//
|
||||
/* eslint-disable */
|
||||
// tslint:disable
|
||||
// @ts-nocheck
|
||||
// biome-ignore format: autogenerated code
|
||||
import type { Image, Audio } from "@boundaryml/baml"
|
||||
import type { Checked, Check } from "./types"
|
||||
import type { AddTool, DivideTool, DoneForNow, MultiplyTool, SubtractTool } from "./types"
|
||||
import type * as types from "./types"
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* These types are used for streaming, for when an instance of a type
|
||||
* is still being built up and any of its fields is not yet fully available.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
export interface StreamState<T> {
|
||||
value: T
|
||||
state: "Pending" | "Incomplete" | "Complete"
|
||||
}
|
||||
|
||||
export namespace partial_types {
|
||||
|
||||
export interface AddTool {
|
||||
intent: "add"
|
||||
a?: ((number | null) | (number | null) | null)
|
||||
b?: ((number | null) | (number | null) | null)
|
||||
}
|
||||
|
||||
export interface DivideTool {
|
||||
intent: "divide"
|
||||
a?: ((number | null) | (number | null) | null)
|
||||
b?: ((number | null) | (number | null) | null)
|
||||
}
|
||||
|
||||
export interface DoneForNow {
|
||||
intent: "done_for_now"
|
||||
message?: (string | null)
|
||||
}
|
||||
|
||||
export interface MultiplyTool {
|
||||
intent: "multiply"
|
||||
a?: ((number | null) | (number | null) | null)
|
||||
b?: ((number | null) | (number | null) | null)
|
||||
}
|
||||
|
||||
export interface SubtractTool {
|
||||
intent: "subtract"
|
||||
a?: ((number | null) | (number | null) | null)
|
||||
b?: ((number | null) | (number | null) | null)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,113 +0,0 @@
|
||||
/*************************************************************************************************
|
||||
|
||||
Welcome to Baml! To use this generated code, please run one of the following:
|
||||
|
||||
$ npm install @boundaryml/baml
|
||||
$ yarn add @boundaryml/baml
|
||||
$ pnpm add @boundaryml/baml
|
||||
|
||||
*************************************************************************************************/
|
||||
|
||||
// This file was generated by BAML: do not edit it. Instead, edit the BAML
|
||||
// files and re-generate this code.
|
||||
//
|
||||
/* eslint-disable */
|
||||
// tslint:disable
|
||||
// @ts-nocheck
|
||||
// biome-ignore format: autogenerated code
|
||||
import type { BamlRuntime, FunctionResult, BamlCtxManager, Image, Audio, ClientRegistry, Collector } from "@boundaryml/baml"
|
||||
import { toBamlError, type HTTPRequest } from "@boundaryml/baml"
|
||||
import type { Checked, Check, RecursivePartialNull as MovedRecursivePartialNull } from "./types"
|
||||
import type * as types from "./types"
|
||||
import type {AddTool, DivideTool, DoneForNow, MultiplyTool, SubtractTool} from "./types"
|
||||
import type TypeBuilder from "./type_builder"
|
||||
import { HttpRequest, HttpStreamRequest } from "./sync_request"
|
||||
import { LlmResponseParser, LlmStreamParser } from "./parser"
|
||||
import { DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_CTX, DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_RUNTIME } from "./globals"
|
||||
|
||||
/**
|
||||
* @deprecated Use RecursivePartialNull from 'baml_client/types' instead.
|
||||
* Example:
|
||||
* ```ts
|
||||
* import { RecursivePartialNull } from './baml_client/types'
|
||||
* ```
|
||||
*/
|
||||
export type RecursivePartialNull<T> = MovedRecursivePartialNull<T>;
|
||||
|
||||
type BamlCallOptions = {
|
||||
tb?: TypeBuilder
|
||||
clientRegistry?: ClientRegistry
|
||||
collector?: Collector | Collector[]
|
||||
}
|
||||
|
||||
export class BamlSyncClient {
|
||||
private httpRequest: HttpRequest
|
||||
private httpStreamRequest: HttpStreamRequest
|
||||
private llmResponseParser: LlmResponseParser
|
||||
private llmStreamParser: LlmStreamParser
|
||||
private bamlOptions: BamlCallOptions
|
||||
|
||||
constructor(private runtime: BamlRuntime, private ctxManager: BamlCtxManager, private bamlOptions?: BamlCallOptions) {
|
||||
this.httpRequest = new HttpRequest(runtime, ctxManager)
|
||||
this.httpStreamRequest = new HttpStreamRequest(runtime, ctxManager)
|
||||
this.llmResponseParser = new LlmResponseParser(runtime, ctxManager)
|
||||
this.llmStreamParser = new LlmStreamParser(runtime, ctxManager)
|
||||
this.bamlOptions = bamlOptions || {}
|
||||
}
|
||||
|
||||
withOptions(bamlOptions: BamlCallOptions) {
|
||||
return new BamlSyncClient(this.runtime, this.ctxManager, bamlOptions)
|
||||
}
|
||||
|
||||
/*
|
||||
* @deprecated NOT IMPLEMENTED as streaming must by async. We
|
||||
* are not providing an async version as we want to reserve the
|
||||
* right to provide a sync version in the future.
|
||||
*/
|
||||
get stream() {
|
||||
throw new Error("stream is not available in BamlSyncClient. Use `import { b } from 'baml_client/async_client")
|
||||
}
|
||||
|
||||
get request() {
|
||||
return this.httpRequest
|
||||
}
|
||||
|
||||
get streamRequest() {
|
||||
return this.httpStreamRequest
|
||||
}
|
||||
|
||||
get parse() {
|
||||
return this.llmResponseParser
|
||||
}
|
||||
|
||||
get parseStream() {
|
||||
return this.llmStreamParser
|
||||
}
|
||||
|
||||
|
||||
DetermineNextStep(
|
||||
thread: string,
|
||||
__baml_options__?: BamlCallOptions
|
||||
): AddTool | SubtractTool | MultiplyTool | DivideTool | DoneForNow {
|
||||
try {
|
||||
const options = { ...this.bamlOptions, ...(__baml_options__ || {}) }
|
||||
const collector = options.collector ? (Array.isArray(options.collector) ? options.collector : [options.collector]) : [];
|
||||
const raw = this.runtime.callFunctionSync(
|
||||
"DetermineNextStep",
|
||||
{
|
||||
"thread": thread
|
||||
},
|
||||
this.ctxManager.cloneContext(),
|
||||
options.tb?.__tb(),
|
||||
options.clientRegistry,
|
||||
collector,
|
||||
)
|
||||
return raw.parsed(false) as AddTool | SubtractTool | MultiplyTool | DivideTool | DoneForNow
|
||||
} catch (error: any) {
|
||||
throw toBamlError(error);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export const b = new BamlSyncClient(DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_RUNTIME, DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_CTX)
|
||||
@@ -1,80 +0,0 @@
|
||||
/*************************************************************************************************
|
||||
|
||||
Welcome to Baml! To use this generated code, please run one of the following:
|
||||
|
||||
$ npm install @boundaryml/baml
|
||||
$ yarn add @boundaryml/baml
|
||||
$ pnpm add @boundaryml/baml
|
||||
|
||||
*************************************************************************************************/
|
||||
|
||||
// This file was generated by BAML: do not edit it. Instead, edit the BAML
|
||||
// files and re-generate this code.
|
||||
//
|
||||
/* eslint-disable */
|
||||
// tslint:disable
|
||||
// @ts-nocheck
|
||||
// biome-ignore format: autogenerated code
|
||||
import type { BamlRuntime, BamlCtxManager, ClientRegistry, Image, Audio } from "@boundaryml/baml"
|
||||
import { toBamlError, HTTPRequest } from "@boundaryml/baml"
|
||||
import type { Checked, Check } from "./types"
|
||||
import type * as types from "./types"
|
||||
import type {AddTool, DivideTool, DoneForNow, MultiplyTool, SubtractTool} from "./types"
|
||||
import type TypeBuilder from "./type_builder"
|
||||
|
||||
type BamlCallOptions = {
|
||||
tb?: TypeBuilder
|
||||
clientRegistry?: ClientRegistry
|
||||
}
|
||||
|
||||
export class HttpRequest {
|
||||
constructor(private runtime: BamlRuntime, private ctxManager: BamlCtxManager) {}
|
||||
|
||||
|
||||
DetermineNextStep(
|
||||
thread: string,
|
||||
__baml_options__?: BamlCallOptions
|
||||
): HTTPRequest {
|
||||
try {
|
||||
return this.runtime.buildRequestSync(
|
||||
"DetermineNextStep",
|
||||
{
|
||||
"thread": thread
|
||||
},
|
||||
this.ctxManager.cloneContext(),
|
||||
__baml_options__?.tb?.__tb(),
|
||||
__baml_options__?.clientRegistry,
|
||||
false,
|
||||
)
|
||||
} catch (error) {
|
||||
throw toBamlError(error);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export class HttpStreamRequest {
|
||||
constructor(private runtime: BamlRuntime, private ctxManager: BamlCtxManager) {}
|
||||
|
||||
|
||||
DetermineNextStep(
|
||||
thread: string,
|
||||
__baml_options__?: BamlCallOptions
|
||||
): HTTPRequest {
|
||||
try {
|
||||
return this.runtime.buildRequestSync(
|
||||
"DetermineNextStep",
|
||||
{
|
||||
"thread": thread
|
||||
},
|
||||
this.ctxManager.cloneContext(),
|
||||
__baml_options__?.tb?.__tb(),
|
||||
__baml_options__?.clientRegistry,
|
||||
true,
|
||||
)
|
||||
} catch (error) {
|
||||
throw toBamlError(error);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
/*************************************************************************************************
|
||||
|
||||
Welcome to Baml! To use this generated code, please run one of the following:
|
||||
|
||||
$ npm install @boundaryml/baml
|
||||
$ yarn add @boundaryml/baml
|
||||
$ pnpm add @boundaryml/baml
|
||||
|
||||
*************************************************************************************************/
|
||||
|
||||
// This file was generated by BAML: do not edit it. Instead, edit the BAML
|
||||
// files and re-generate this code.
|
||||
//
|
||||
/* eslint-disable */
|
||||
// tslint:disable
|
||||
// @ts-nocheck
|
||||
// biome-ignore format: autogenerated code
|
||||
import type { BamlLogEvent } from '@boundaryml/baml';
|
||||
import { DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_CTX } from './globals';
|
||||
|
||||
const traceAsync =
|
||||
DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_CTX.traceFnAsync.bind(DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_CTX)
|
||||
const traceSync =
|
||||
DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_CTX.traceFnSync.bind(DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_CTX)
|
||||
const setTags =
|
||||
DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_CTX.upsertTags.bind(DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_CTX)
|
||||
const flush = () => {
|
||||
DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_CTX.flush.bind(DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_CTX)()
|
||||
}
|
||||
const onLogEvent = (callback: undefined | ((event: BamlLogEvent) => void)) =>
|
||||
DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_CTX.onLogEvent(callback)
|
||||
|
||||
export { traceAsync, traceSync, setTags, flush, onLogEvent }
|
||||
@@ -1,100 +0,0 @@
|
||||
/*************************************************************************************************
|
||||
|
||||
Welcome to Baml! To use this generated code, please run one of the following:
|
||||
|
||||
$ npm install @boundaryml/baml
|
||||
$ yarn add @boundaryml/baml
|
||||
$ pnpm add @boundaryml/baml
|
||||
|
||||
*************************************************************************************************/
|
||||
|
||||
// This file was generated by BAML: do not edit it. Instead, edit the BAML
|
||||
// files and re-generate this code.
|
||||
//
|
||||
/* eslint-disable */
|
||||
// tslint:disable
|
||||
// @ts-nocheck
|
||||
// biome-ignore format: autogenerated code
|
||||
import { FieldType } from '@boundaryml/baml/native'
|
||||
import { TypeBuilder as _TypeBuilder, EnumBuilder, ClassBuilder } from '@boundaryml/baml/type_builder'
|
||||
import { DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_RUNTIME } from "./globals"
|
||||
|
||||
export default class TypeBuilder {
|
||||
private tb: _TypeBuilder;
|
||||
|
||||
|
||||
|
||||
constructor() {
|
||||
this.tb = new _TypeBuilder({
|
||||
classes: new Set([
|
||||
"AddTool","DivideTool","DoneForNow","MultiplyTool","SubtractTool",
|
||||
]),
|
||||
enums: new Set([
|
||||
|
||||
]),
|
||||
runtime: DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_RUNTIME
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
|
||||
__tb() {
|
||||
return this.tb._tb();
|
||||
}
|
||||
|
||||
string(): FieldType {
|
||||
return this.tb.string()
|
||||
}
|
||||
|
||||
literalString(value: string): FieldType {
|
||||
return this.tb.literalString(value)
|
||||
}
|
||||
|
||||
literalInt(value: number): FieldType {
|
||||
return this.tb.literalInt(value)
|
||||
}
|
||||
|
||||
literalBool(value: boolean): FieldType {
|
||||
return this.tb.literalBool(value)
|
||||
}
|
||||
|
||||
int(): FieldType {
|
||||
return this.tb.int()
|
||||
}
|
||||
|
||||
float(): FieldType {
|
||||
return this.tb.float()
|
||||
}
|
||||
|
||||
bool(): FieldType {
|
||||
return this.tb.bool()
|
||||
}
|
||||
|
||||
list(type: FieldType): FieldType {
|
||||
return this.tb.list(type)
|
||||
}
|
||||
|
||||
null(): FieldType {
|
||||
return this.tb.null()
|
||||
}
|
||||
|
||||
map(key: FieldType, value: FieldType): FieldType {
|
||||
return this.tb.map(key, value)
|
||||
}
|
||||
|
||||
union(types: FieldType[]): FieldType {
|
||||
return this.tb.union(types)
|
||||
}
|
||||
|
||||
addClass<Name extends string>(name: Name): ClassBuilder<Name> {
|
||||
return this.tb.addClass(name);
|
||||
}
|
||||
|
||||
addEnum<Name extends string>(name: Name): EnumBuilder<Name> {
|
||||
return this.tb.addEnum(name);
|
||||
}
|
||||
|
||||
addBaml(baml: string): void {
|
||||
this.tb.addBaml(baml, this.runtime);
|
||||
}
|
||||
}
|
||||
@@ -1,81 +0,0 @@
|
||||
/*************************************************************************************************
|
||||
|
||||
Welcome to Baml! To use this generated code, please run one of the following:
|
||||
|
||||
$ npm install @boundaryml/baml
|
||||
$ yarn add @boundaryml/baml
|
||||
$ pnpm add @boundaryml/baml
|
||||
|
||||
*************************************************************************************************/
|
||||
|
||||
// This file was generated by BAML: do not edit it. Instead, edit the BAML
|
||||
// files and re-generate this code.
|
||||
//
|
||||
/* eslint-disable */
|
||||
// tslint:disable
|
||||
// @ts-nocheck
|
||||
// biome-ignore format: autogenerated code
|
||||
import type { Image, Audio } from "@boundaryml/baml"
|
||||
|
||||
/**
|
||||
* Recursively partial type that can be null.
|
||||
*
|
||||
* @deprecated Use types from the `partial_types` namespace instead, which provides type-safe partial implementations
|
||||
* @template T The type to make recursively partial.
|
||||
*/
|
||||
export type RecursivePartialNull<T> = T extends object
|
||||
? { [P in keyof T]?: RecursivePartialNull<T[P]> }
|
||||
: T | null;
|
||||
|
||||
export interface Checked<T,CheckName extends string = string> {
|
||||
value: T,
|
||||
checks: Record<CheckName, Check>,
|
||||
}
|
||||
|
||||
|
||||
export interface Check {
|
||||
name: string,
|
||||
expr: string
|
||||
status: "succeeded" | "failed"
|
||||
}
|
||||
|
||||
export function all_succeeded<CheckName extends string>(checks: Record<CheckName, Check>): boolean {
|
||||
return get_checks(checks).every(check => check.status === "succeeded")
|
||||
}
|
||||
|
||||
export function get_checks<CheckName extends string>(checks: Record<CheckName, Check>): Check[] {
|
||||
return Object.values(checks)
|
||||
}
|
||||
export interface AddTool {
|
||||
intent: "add"
|
||||
a: number | number
|
||||
b: number | number
|
||||
|
||||
}
|
||||
|
||||
export interface DivideTool {
|
||||
intent: "divide"
|
||||
a: number | number
|
||||
b: number | number
|
||||
|
||||
}
|
||||
|
||||
export interface DoneForNow {
|
||||
intent: "done_for_now"
|
||||
message: string
|
||||
|
||||
}
|
||||
|
||||
export interface MultiplyTool {
|
||||
intent: "multiply"
|
||||
a: number | number
|
||||
b: number | number
|
||||
|
||||
}
|
||||
|
||||
export interface SubtractTool {
|
||||
intent: "subtract"
|
||||
a: number | number
|
||||
b: number | number
|
||||
|
||||
}
|
||||
2295
workshops/2025-05/sections/04-baml-tests/package-lock.json
generated
2295
workshops/2025-05/sections/04-baml-tests/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -1,20 +0,0 @@
|
||||
{
|
||||
"name": "my-agent",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "tsx src/index.ts",
|
||||
"build": "tsc"
|
||||
},
|
||||
"dependencies": {
|
||||
"baml": "^0.0.0",
|
||||
"tsx": "^4.15.0",
|
||||
"typescript": "^5.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^20.0.0",
|
||||
"@typescript-eslint/eslint-plugin": "^6.0.0",
|
||||
"@typescript-eslint/parser": "^6.0.0",
|
||||
"eslint": "^8.0.0"
|
||||
}
|
||||
}
|
||||
@@ -1,86 +0,0 @@
|
||||
import { AddTool, SubtractTool, DivideTool, MultiplyTool, b } from "../baml_client";
|
||||
|
||||
export interface Event {
|
||||
type: string
|
||||
data: any;
|
||||
}
|
||||
|
||||
export class Thread {
|
||||
events: Event[] = [];
|
||||
|
||||
constructor(events: Event[]) {
|
||||
this.events = events;
|
||||
}
|
||||
|
||||
serializeForLLM() {
|
||||
// can change this to whatever custom serialization you want to do, XML, etc
|
||||
// e.g. https://github.com/got-agents/agents/blob/59ebbfa236fc376618f16ee08eb0f3bf7b698892/linear-assistant-ts/src/agent.ts#L66-L105
|
||||
return JSON.stringify(this.events);
|
||||
}
|
||||
}
|
||||
|
||||
export type CalculatorTool = AddTool | SubtractTool | MultiplyTool | DivideTool;
|
||||
|
||||
export async function handleNextStep(nextStep: CalculatorTool, thread: Thread): Promise<Thread> {
|
||||
let result: number;
|
||||
switch (nextStep.intent) {
|
||||
case "add":
|
||||
result = nextStep.a + nextStep.b;
|
||||
console.log("tool_response", result);
|
||||
thread.events.push({
|
||||
"type": "tool_response",
|
||||
"data": result
|
||||
});
|
||||
return thread;
|
||||
case "subtract":
|
||||
result = nextStep.a - nextStep.b;
|
||||
console.log("tool_response", result);
|
||||
thread.events.push({
|
||||
"type": "tool_response",
|
||||
"data": result
|
||||
});
|
||||
return thread;
|
||||
case "multiply":
|
||||
result = nextStep.a * nextStep.b;
|
||||
console.log("tool_response", result);
|
||||
thread.events.push({
|
||||
"type": "tool_response",
|
||||
"data": result
|
||||
});
|
||||
return thread;
|
||||
case "divide":
|
||||
result = nextStep.a / nextStep.b;
|
||||
console.log("tool_response", result);
|
||||
thread.events.push({
|
||||
"type": "tool_response",
|
||||
"data": result
|
||||
});
|
||||
return thread;
|
||||
}
|
||||
}
|
||||
|
||||
export async function agentLoop(thread: Thread): Promise<string> {
|
||||
|
||||
while (true) {
|
||||
const nextStep = await b.DetermineNextStep(thread.serializeForLLM());
|
||||
console.log("nextStep", nextStep);
|
||||
|
||||
thread.events.push({
|
||||
"type": "tool_call",
|
||||
"data": nextStep
|
||||
});
|
||||
|
||||
switch (nextStep.intent) {
|
||||
case "done_for_now":
|
||||
// response to human, return the next step object
|
||||
return nextStep.message;
|
||||
case "add":
|
||||
case "subtract":
|
||||
case "multiply":
|
||||
case "divide":
|
||||
thread = await handleNextStep(nextStep, thread);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
// cli.ts lets you invoke the agent loop from the command line
|
||||
|
||||
import { agentLoop, Thread, Event } from "./agent";
|
||||
|
||||
export async function cli() {
|
||||
// Get command line arguments, skipping the first two (node and script name)
|
||||
const args = process.argv.slice(2);
|
||||
|
||||
if (args.length === 0) {
|
||||
console.error("Error: Please provide a message as a command line argument");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// Join all arguments into a single message
|
||||
const message = args.join(" ");
|
||||
|
||||
// Create a new thread with the user's message as the initial event
|
||||
const thread = new Thread([{ type: "user_input", data: message }]);
|
||||
|
||||
// Run the agent loop with the thread
|
||||
const result = await agentLoop(thread);
|
||||
console.log(result);
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
import { cli } from "./cli"
|
||||
|
||||
async function hello(): Promise<void> {
|
||||
console.log('hello, world!')
|
||||
}
|
||||
|
||||
async function main() {
|
||||
await cli()
|
||||
}
|
||||
|
||||
main().catch(console.error)
|
||||
@@ -1,24 +0,0 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2017",
|
||||
"lib": ["esnext"],
|
||||
"allowJs": true,
|
||||
"skipLibCheck": true,
|
||||
"strict": true,
|
||||
"noEmit": true,
|
||||
"esModuleInterop": true,
|
||||
"module": "esnext",
|
||||
"moduleResolution": "bundler",
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"jsx": "preserve",
|
||||
"incremental": true,
|
||||
"plugins": [],
|
||||
"paths": {
|
||||
"@/*": ["./*"]
|
||||
}
|
||||
},
|
||||
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
|
||||
"exclude": ["node_modules", "walkthrough"]
|
||||
}
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
class DoneForNow {
|
||||
intent "done_for_now"
|
||||
message string
|
||||
}
|
||||
|
||||
function DetermineNextStep(
|
||||
thread: string
|
||||
) -> CalculatorTools | DoneForNow {
|
||||
client "openai/gpt-4o"
|
||||
|
||||
prompt #"
|
||||
{{ _.role("system") }}
|
||||
|
||||
You are a helpful assistant that can help with tasks.
|
||||
|
||||
{{ _.role("user") }}
|
||||
|
||||
You are working on the following thread:
|
||||
|
||||
{{ thread }}
|
||||
|
||||
What should the next step be?
|
||||
|
||||
{{ ctx.output_format }}
|
||||
"#
|
||||
}
|
||||
|
||||
test HelloWorld {
|
||||
functions [DetermineNextStep]
|
||||
args {
|
||||
thread #"
|
||||
{
|
||||
"type": "user_input",
|
||||
"data": "hello!"
|
||||
}
|
||||
"#
|
||||
}
|
||||
}
|
||||
|
||||
test MathOperation {
|
||||
functions [DetermineNextStep]
|
||||
args {
|
||||
thread #"
|
||||
{
|
||||
"type": "user_input",
|
||||
"data": "can you multiply 3 and 4?"
|
||||
}
|
||||
"#
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,53 +0,0 @@
|
||||
class DoneForNow {
|
||||
intent "done_for_now"
|
||||
message string
|
||||
}
|
||||
|
||||
function DetermineNextStep(
|
||||
thread: string
|
||||
) -> CalculatorTools | DoneForNow {
|
||||
client "openai/gpt-4o"
|
||||
|
||||
prompt #"
|
||||
{{ _.role("system") }}
|
||||
|
||||
You are a helpful assistant that can help with tasks.
|
||||
|
||||
{{ _.role("user") }}
|
||||
|
||||
You are working on the following thread:
|
||||
|
||||
{{ thread }}
|
||||
|
||||
What should the next step be?
|
||||
|
||||
{{ ctx.output_format }}
|
||||
"#
|
||||
}
|
||||
|
||||
test HelloWorld {
|
||||
functions [DetermineNextStep]
|
||||
args {
|
||||
thread #"
|
||||
{
|
||||
"type": "user_input",
|
||||
"data": "hello!"
|
||||
}
|
||||
"#
|
||||
}
|
||||
@@assert(hello, {{this.intent == "done_for_now"}})
|
||||
}
|
||||
|
||||
test MathOperation {
|
||||
functions [DetermineNextStep]
|
||||
args {
|
||||
thread #"
|
||||
{
|
||||
"type": "user_input",
|
||||
"data": "can you multiply 3 and 4?"
|
||||
}
|
||||
"#
|
||||
}
|
||||
@@assert(math_operation, {{this.intent == "multiply"}})
|
||||
}
|
||||
|
||||
@@ -1,105 +0,0 @@
|
||||
class DoneForNow {
|
||||
intent "done_for_now"
|
||||
message string
|
||||
}
|
||||
|
||||
function DetermineNextStep(
|
||||
thread: string
|
||||
) -> CalculatorTools | DoneForNow {
|
||||
client "openai/gpt-4o"
|
||||
|
||||
prompt #"
|
||||
{{ _.role("system") }}
|
||||
|
||||
You are a helpful assistant that can help with tasks.
|
||||
|
||||
{{ _.role("user") }}
|
||||
|
||||
You are working on the following thread:
|
||||
|
||||
{{ thread }}
|
||||
|
||||
What should the next step be?
|
||||
|
||||
{{ ctx.output_format }}
|
||||
"#
|
||||
}
|
||||
|
||||
test HelloWorld {
|
||||
functions [DetermineNextStep]
|
||||
args {
|
||||
thread #"
|
||||
{
|
||||
"type": "user_input",
|
||||
"data": "hello!"
|
||||
}
|
||||
"#
|
||||
}
|
||||
@@assert(intent, {{this.intent == "done_for_now"}})
|
||||
}
|
||||
|
||||
test MathOperation {
|
||||
functions [DetermineNextStep]
|
||||
args {
|
||||
thread #"
|
||||
{
|
||||
"type": "user_input",
|
||||
"data": "can you multiply 3 and 4?"
|
||||
}
|
||||
"#
|
||||
}
|
||||
@@assert(intent, {{this.intent == "multiply"}})
|
||||
}
|
||||
|
||||
test LongMath {
|
||||
functions [DetermineNextStep]
|
||||
args {
|
||||
thread #"
|
||||
[
|
||||
{
|
||||
"type": "user_input",
|
||||
"data": "can you multiply 3 and 4, then divide the result by 2 and then add 12 to that result?"
|
||||
},
|
||||
{
|
||||
"type": "tool_call",
|
||||
"data": {
|
||||
"intent": "multiply",
|
||||
"a": 3,
|
||||
"b": 4
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "tool_response",
|
||||
"data": 12
|
||||
},
|
||||
{
|
||||
"type": "tool_call",
|
||||
"data": {
|
||||
"intent": "divide",
|
||||
"a": 12,
|
||||
"b": 2
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "tool_response",
|
||||
"data": 6
|
||||
},
|
||||
{
|
||||
"type": "tool_call",
|
||||
"data": {
|
||||
"intent": "add",
|
||||
"a": 6,
|
||||
"b": 12
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "tool_response",
|
||||
"data": 18
|
||||
}
|
||||
]
|
||||
"#
|
||||
}
|
||||
@@assert(intent, {{this.intent == "done_for_now"}})
|
||||
@@assert(answer, {{"18" in this.message}})
|
||||
}
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
baml_src/
|
||||
node_modules/
|
||||
@@ -1,202 +0,0 @@
|
||||
# Chapter 5 - Multiple Human Tools
|
||||
|
||||
Add support for requesting clarification from humans.
|
||||
|
||||
Update agent with clarification support
|
||||
|
||||
```diff
|
||||
baml_src/agent.baml
|
||||
+// human tools are async requests to a human
|
||||
+type HumanTools = ClarificationRequest | DoneForNow
|
||||
+
|
||||
+class ClarificationRequest {
|
||||
+ intent "request_more_information" @description("you can request more information from me")
|
||||
+ message string
|
||||
+}
|
||||
+
|
||||
class DoneForNow {
|
||||
intent "done_for_now"
|
||||
- message string
|
||||
+
|
||||
+ message string @description(#"
|
||||
+ message to send to the user about the work that was done.
|
||||
+ "#)
|
||||
}
|
||||
|
||||
function DetermineNextStep(
|
||||
thread: string
|
||||
-) -> CalculatorTools | DoneForNow {
|
||||
+) -> HumanTools | CalculatorTools {
|
||||
client "openai/gpt-4o"
|
||||
|
||||
}
|
||||
|
||||
+
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>skip this step</summary>
|
||||
|
||||
cp ./walkthrough/05-agent.baml baml_src/agent.baml
|
||||
|
||||
</details>
|
||||
|
||||
Generate updated client
|
||||
|
||||
npx baml-cli generate
|
||||
|
||||
Update agent implementation
|
||||
|
||||
```diff
|
||||
src/agent.ts
|
||||
}
|
||||
|
||||
-export async function agentLoop(thread: Thread): Promise<string> {
|
||||
+export async function agentLoop(thread: Thread): Promise<Thread> {
|
||||
|
||||
while (true) {
|
||||
switch (nextStep.intent) {
|
||||
case "done_for_now":
|
||||
- // response to human, return the next step object
|
||||
- return nextStep.message;
|
||||
+ case "request_more_information":
|
||||
+ // response to human, return the thread
|
||||
+ return thread;
|
||||
case "add":
|
||||
case "subtract":
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>skip this step</summary>
|
||||
|
||||
cp ./walkthrough/05-agent.ts src/agent.ts
|
||||
|
||||
</details>
|
||||
|
||||
Update CLI to handle clarification requests
|
||||
|
||||
```diff
|
||||
src/cli.ts
|
||||
// cli.ts lets you invoke the agent loop from the command line
|
||||
|
||||
-import { agentLoop, Thread, Event } from "./agent";
|
||||
+import { agentLoop, Thread, Event } from "../src/agent";
|
||||
|
||||
+
|
||||
+
|
||||
export async function cli() {
|
||||
// Get command line arguments, skipping the first two (node and script name)
|
||||
// Run the agent loop with the thread
|
||||
const result = await agentLoop(thread);
|
||||
- console.log(result);
|
||||
+ let lastEvent = result.events.slice(-1)[0];
|
||||
+
|
||||
+ while (lastEvent.data.intent === "request_more_information") {
|
||||
+ const message = await askHuman(lastEvent.data.message);
|
||||
+ thread.events.push({ type: "human_response", data: message });
|
||||
+ const result = await agentLoop(thread);
|
||||
+ lastEvent = result.events.slice(-1)[0];
|
||||
+ }
|
||||
+
|
||||
+ // print the final result
|
||||
+ // optional - you could loop here too
|
||||
+ console.log(lastEvent.data.message);
|
||||
+ process.exit(0);
|
||||
}
|
||||
+
|
||||
+async function askHuman(message: string) {
|
||||
+ const readline = require('readline').createInterface({
|
||||
+ input: process.stdin,
|
||||
+ output: process.stdout
|
||||
+ });
|
||||
+
|
||||
+ return new Promise((resolve) => {
|
||||
+ readline.question(`${message}\n> `, (answer: string) => {
|
||||
+ resolve(answer);
|
||||
+ });
|
||||
+ });
|
||||
+}
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>skip this step</summary>
|
||||
|
||||
cp ./walkthrough/05-cli.ts src/cli.ts
|
||||
|
||||
</details>
|
||||
|
||||
Test clarification flow
|
||||
|
||||
npx tsx src/index.ts 'can you multiply 3 and FD*(#F&& '
|
||||
|
||||
Add tests for clarification
|
||||
|
||||
```diff
|
||||
baml_src/agent.baml
|
||||
|
||||
|
||||
+
|
||||
+test MathOperationWithClarification {
|
||||
+ functions [DetermineNextStep]
|
||||
+ args {
|
||||
+ thread #"
|
||||
+ [{"type":"user_input","data":"can you multiply 3 and feee9ff10"}]
|
||||
+ "#
|
||||
+ }
|
||||
+ @@assert(intent, {{this.intent == "request_more_information"}})
|
||||
+}
|
||||
+
|
||||
+test MathOperationPostClarification {
|
||||
+ functions [DetermineNextStep]
|
||||
+ args {
|
||||
+ thread #"
|
||||
+ [
|
||||
+ {"type":"user_input","data":"can you multiply 3 and FD*(#F&& ?"},
|
||||
+ {"type":"tool_call","data":{"intent":"request_more_information","message":"It seems like there was a typo or mistake in your request. Could you please clarify or provide the correct numbers you would like to multiply?"}},
|
||||
+ {"type":"human_response","data":"lets try 12 instead"},
|
||||
+ ]
|
||||
+ "#
|
||||
+ }
|
||||
+ @@assert(intent, {{this.intent == "multiply"}})
|
||||
+ @@assert(a, {{this.b == 12}})
|
||||
+ @@assert(b, {{this.a == 3}})
|
||||
+}
|
||||
+
|
||||
+
|
||||
+
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>skip this step</summary>
|
||||
|
||||
cp ./walkthrough/05b-agent.baml baml_src/agent.baml
|
||||
|
||||
</details>
|
||||
|
||||
Run the tests
|
||||
|
||||
npx baml-cli test
|
||||
|
||||
Fix hello world test
|
||||
|
||||
```diff
|
||||
baml_src/agent.baml
|
||||
"#
|
||||
}
|
||||
- @@assert(intent, {{this.intent == "done_for_now"}})
|
||||
+ @@assert(intent, {{this.intent == "request_more_information"}})
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>skip this step</summary>
|
||||
|
||||
cp ./walkthrough/05c-agent.baml baml_src/agent.baml
|
||||
|
||||
</details>
|
||||
|
||||
Verify tests pass
|
||||
|
||||
npx baml-cli test
|
||||
|
||||
@@ -1,154 +0,0 @@
|
||||
/*************************************************************************************************
|
||||
|
||||
Welcome to Baml! To use this generated code, please run one of the following:
|
||||
|
||||
$ npm install @boundaryml/baml
|
||||
$ yarn add @boundaryml/baml
|
||||
$ pnpm add @boundaryml/baml
|
||||
|
||||
*************************************************************************************************/
|
||||
|
||||
// This file was generated by BAML: do not edit it. Instead, edit the BAML
|
||||
// files and re-generate this code.
|
||||
//
|
||||
/* eslint-disable */
|
||||
// tslint:disable
|
||||
// @ts-nocheck
|
||||
// biome-ignore format: autogenerated code
|
||||
import type { BamlRuntime, FunctionResult, BamlCtxManager, ClientRegistry, Image, Audio, Collector } from "@boundaryml/baml"
|
||||
import { toBamlError, BamlStream, type HTTPRequest } from "@boundaryml/baml"
|
||||
import type { Checked, Check, RecursivePartialNull as MovedRecursivePartialNull } from "./types"
|
||||
import type { partial_types } from "./partial_types"
|
||||
import type * as types from "./types"
|
||||
import type {AddTool, DivideTool, DoneForNow, MultiplyTool, SubtractTool} from "./types"
|
||||
import type TypeBuilder from "./type_builder"
|
||||
import { AsyncHttpRequest, AsyncHttpStreamRequest } from "./async_request"
|
||||
import { LlmResponseParser, LlmStreamParser } from "./parser"
|
||||
import { DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_CTX, DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_RUNTIME } from "./globals"
|
||||
|
||||
/**
|
||||
* @deprecated Use RecursivePartialNull from 'baml_client/types' instead.
|
||||
*/
|
||||
export type RecursivePartialNull<T> = MovedRecursivePartialNull<T>
|
||||
|
||||
type BamlCallOptions = {
|
||||
tb?: TypeBuilder
|
||||
clientRegistry?: ClientRegistry
|
||||
collector?: Collector | Collector[]
|
||||
}
|
||||
|
||||
export class BamlAsyncClient {
|
||||
private runtime: BamlRuntime
|
||||
private ctxManager: BamlCtxManager
|
||||
private streamClient: BamlStreamClient
|
||||
private httpRequest: AsyncHttpRequest
|
||||
private httpStreamRequest: AsyncHttpStreamRequest
|
||||
private llmResponseParser: LlmResponseParser
|
||||
private llmStreamParser: LlmStreamParser
|
||||
private bamlOptions: BamlCallOptions
|
||||
|
||||
constructor(runtime: BamlRuntime, ctxManager: BamlCtxManager, bamlOptions?: BamlCallOptions) {
|
||||
this.runtime = runtime
|
||||
this.ctxManager = ctxManager
|
||||
this.streamClient = new BamlStreamClient(runtime, ctxManager, bamlOptions)
|
||||
this.httpRequest = new AsyncHttpRequest(runtime, ctxManager)
|
||||
this.httpStreamRequest = new AsyncHttpStreamRequest(runtime, ctxManager)
|
||||
this.llmResponseParser = new LlmResponseParser(runtime, ctxManager)
|
||||
this.llmStreamParser = new LlmStreamParser(runtime, ctxManager)
|
||||
this.bamlOptions = bamlOptions || {}
|
||||
}
|
||||
|
||||
withOptions(bamlOptions: BamlCallOptions) {
|
||||
return new BamlAsyncClient(this.runtime, this.ctxManager, bamlOptions)
|
||||
}
|
||||
|
||||
get stream() {
|
||||
return this.streamClient
|
||||
}
|
||||
|
||||
get request() {
|
||||
return this.httpRequest
|
||||
}
|
||||
|
||||
get streamRequest() {
|
||||
return this.httpStreamRequest
|
||||
}
|
||||
|
||||
get parse() {
|
||||
return this.llmResponseParser
|
||||
}
|
||||
|
||||
get parseStream() {
|
||||
return this.llmStreamParser
|
||||
}
|
||||
|
||||
|
||||
async DetermineNextStep(
|
||||
thread: string,
|
||||
__baml_options__?: BamlCallOptions
|
||||
): Promise<AddTool | SubtractTool | MultiplyTool | DivideTool | DoneForNow> {
|
||||
try {
|
||||
const options = { ...this.bamlOptions, ...(__baml_options__ || {}) }
|
||||
const collector = options.collector ? (Array.isArray(options.collector) ? options.collector : [options.collector]) : [];
|
||||
const raw = await this.runtime.callFunction(
|
||||
"DetermineNextStep",
|
||||
{
|
||||
"thread": thread
|
||||
},
|
||||
this.ctxManager.cloneContext(),
|
||||
options.tb?.__tb(),
|
||||
options.clientRegistry,
|
||||
collector,
|
||||
)
|
||||
return raw.parsed(false) as AddTool | SubtractTool | MultiplyTool | DivideTool | DoneForNow
|
||||
} catch (error) {
|
||||
throw toBamlError(error);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class BamlStreamClient {
|
||||
private runtime: BamlRuntime
|
||||
private ctxManager: BamlCtxManager
|
||||
private bamlOptions: BamlCallOptions
|
||||
|
||||
constructor(runtime: BamlRuntime, ctxManager: BamlCtxManager, bamlOptions?: BamlCallOptions) {
|
||||
this.runtime = runtime
|
||||
this.ctxManager = ctxManager
|
||||
this.bamlOptions = bamlOptions || {}
|
||||
}
|
||||
|
||||
|
||||
DetermineNextStep(
|
||||
thread: string,
|
||||
__baml_options__?: { tb?: TypeBuilder, clientRegistry?: ClientRegistry, collector?: Collector | Collector[] }
|
||||
): BamlStream<(((partial_types.AddTool | null) | (partial_types.SubtractTool | null) | (partial_types.MultiplyTool | null) | (partial_types.DivideTool | null) | null) | (partial_types.DoneForNow | null)), AddTool | SubtractTool | MultiplyTool | DivideTool | DoneForNow> {
|
||||
try {
|
||||
const options = { ...this.bamlOptions, ...(__baml_options__ || {}) }
|
||||
const collector = options.collector ? (Array.isArray(options.collector) ? options.collector : [options.collector]) : [];
|
||||
const raw = this.runtime.streamFunction(
|
||||
"DetermineNextStep",
|
||||
{
|
||||
"thread": thread
|
||||
},
|
||||
undefined,
|
||||
this.ctxManager.cloneContext(),
|
||||
options.tb?.__tb(),
|
||||
options.clientRegistry,
|
||||
collector,
|
||||
)
|
||||
return new BamlStream<(((partial_types.AddTool | null) | (partial_types.SubtractTool | null) | (partial_types.MultiplyTool | null) | (partial_types.DivideTool | null) | null) | (partial_types.DoneForNow | null)), AddTool | SubtractTool | MultiplyTool | DivideTool | DoneForNow>(
|
||||
raw,
|
||||
(a): (((partial_types.AddTool | null) | (partial_types.SubtractTool | null) | (partial_types.MultiplyTool | null) | (partial_types.DivideTool | null) | null) | (partial_types.DoneForNow | null)) => a,
|
||||
(a): AddTool | SubtractTool | MultiplyTool | DivideTool | DoneForNow => a,
|
||||
this.ctxManager.cloneContext(),
|
||||
)
|
||||
} catch (error) {
|
||||
throw toBamlError(error);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export const b = new BamlAsyncClient(DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_RUNTIME, DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_CTX)
|
||||
@@ -1,80 +0,0 @@
|
||||
/*************************************************************************************************
|
||||
|
||||
Welcome to Baml! To use this generated code, please run one of the following:
|
||||
|
||||
$ npm install @boundaryml/baml
|
||||
$ yarn add @boundaryml/baml
|
||||
$ pnpm add @boundaryml/baml
|
||||
|
||||
*************************************************************************************************/
|
||||
|
||||
// This file was generated by BAML: do not edit it. Instead, edit the BAML
|
||||
// files and re-generate this code.
|
||||
//
|
||||
/* eslint-disable */
|
||||
// tslint:disable
|
||||
// @ts-nocheck
|
||||
// biome-ignore format: autogenerated code
|
||||
import type { BamlRuntime, BamlCtxManager, ClientRegistry, Image, Audio } from "@boundaryml/baml"
|
||||
import { toBamlError, HTTPRequest } from "@boundaryml/baml"
|
||||
import type { Checked, Check } from "./types"
|
||||
import type * as types from "./types"
|
||||
import type {AddTool, DivideTool, DoneForNow, MultiplyTool, SubtractTool} from "./types"
|
||||
import type TypeBuilder from "./type_builder"
|
||||
|
||||
type BamlCallOptions = {
|
||||
tb?: TypeBuilder
|
||||
clientRegistry?: ClientRegistry
|
||||
}
|
||||
|
||||
export class AsyncHttpRequest {
|
||||
constructor(private runtime: BamlRuntime, private ctxManager: BamlCtxManager) {}
|
||||
|
||||
|
||||
async DetermineNextStep(
|
||||
thread: string,
|
||||
__baml_options__?: BamlCallOptions
|
||||
): Promise<HTTPRequest> {
|
||||
try {
|
||||
return await this.runtime.buildRequest(
|
||||
"DetermineNextStep",
|
||||
{
|
||||
"thread": thread
|
||||
},
|
||||
this.ctxManager.cloneContext(),
|
||||
__baml_options__?.tb?.__tb(),
|
||||
__baml_options__?.clientRegistry,
|
||||
false,
|
||||
)
|
||||
} catch (error) {
|
||||
throw toBamlError(error);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export class AsyncHttpStreamRequest {
|
||||
constructor(private runtime: BamlRuntime, private ctxManager: BamlCtxManager) {}
|
||||
|
||||
|
||||
async DetermineNextStep(
|
||||
thread: string,
|
||||
__baml_options__?: BamlCallOptions
|
||||
): Promise<HTTPRequest> {
|
||||
try {
|
||||
return await this.runtime.buildRequest(
|
||||
"DetermineNextStep",
|
||||
{
|
||||
"thread": thread
|
||||
},
|
||||
this.ctxManager.cloneContext(),
|
||||
__baml_options__?.tb?.__tb(),
|
||||
__baml_options__?.clientRegistry,
|
||||
true,
|
||||
)
|
||||
} catch (error) {
|
||||
throw toBamlError(error);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
/*************************************************************************************************
|
||||
|
||||
Welcome to Baml! To use this generated code, please run one of the following:
|
||||
|
||||
$ npm install @boundaryml/baml
|
||||
$ yarn add @boundaryml/baml
|
||||
$ pnpm add @boundaryml/baml
|
||||
|
||||
*************************************************************************************************/
|
||||
|
||||
// This file was generated by BAML: do not edit it. Instead, edit the BAML
|
||||
// files and re-generate this code.
|
||||
//
|
||||
/* eslint-disable */
|
||||
// tslint:disable
|
||||
// @ts-nocheck
|
||||
// biome-ignore format: autogenerated code
|
||||
export { setLogLevel, getLogLevel, setLogJson } from "@boundaryml/baml/logging";
|
||||
export { resetBamlEnvVars } from "./globals";
|
||||
@@ -1,67 +0,0 @@
|
||||
/*************************************************************************************************
|
||||
|
||||
Welcome to Baml! To use this generated code, please run one of the following:
|
||||
|
||||
$ npm install @boundaryml/baml
|
||||
$ yarn add @boundaryml/baml
|
||||
$ pnpm add @boundaryml/baml
|
||||
|
||||
*************************************************************************************************/
|
||||
|
||||
// This file was generated by BAML: do not edit it. Instead, edit the BAML
|
||||
// files and re-generate this code.
|
||||
//
|
||||
/* eslint-disable */
|
||||
// tslint:disable
|
||||
// @ts-nocheck
|
||||
// biome-ignore format: autogenerated code
|
||||
import { BamlRuntime, BamlCtxManager } from '@boundaryml/baml'
|
||||
import { getBamlFiles } from './inlinedbaml'
|
||||
|
||||
|
||||
export const DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_RUNTIME = BamlRuntime.fromFiles(
|
||||
'baml_src',
|
||||
getBamlFiles(),
|
||||
process.env
|
||||
)
|
||||
export const DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_CTX = new BamlCtxManager(DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_RUNTIME)
|
||||
|
||||
|
||||
export function resetBamlEnvVars(envVars: Record<string, string | undefined>) {
|
||||
if (DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_CTX.allowResets()) {
|
||||
const envVarsToReset = Object.fromEntries(Object.entries(envVars).filter((kv): kv is [string, string] => kv[1] !== undefined));
|
||||
DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_RUNTIME.reset('baml_src', getBamlFiles(), envVarsToReset)
|
||||
DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_CTX.reset()
|
||||
} else {
|
||||
throw new Error('BamlError: Cannot reset BAML environment variables while there are active BAML contexts.')
|
||||
}
|
||||
}
|
||||
|
||||
const patchedLoad = (originalFn: any) => (...args: any[]) => {
|
||||
const result = originalFn(...args);
|
||||
try {
|
||||
// Dont fail if env vars fail to reset
|
||||
resetBamlEnvVars(process.env);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
try {
|
||||
const dotenv = require('dotenv');
|
||||
// Monkeypatch load function to call resetBamlEnvVars after execution
|
||||
|
||||
|
||||
// Apply the patch
|
||||
dotenv.config = patchedLoad(dotenv.config);
|
||||
dotenv.configDotenv = patchedLoad(dotenv.configDotenv);
|
||||
dotenv.populate = patchedLoad(dotenv.populate);
|
||||
} catch (error) {
|
||||
// dotenv is not installed, so we do nothing
|
||||
}
|
||||
|
||||
// also patch process.loadEnvFile
|
||||
if (process.loadEnvFile) {
|
||||
process.loadEnvFile = patchedLoad(process.loadEnvFile);
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
/*************************************************************************************************
|
||||
|
||||
Welcome to Baml! To use this generated code, please run one of the following:
|
||||
|
||||
$ npm install @boundaryml/baml
|
||||
$ yarn add @boundaryml/baml
|
||||
$ pnpm add @boundaryml/baml
|
||||
|
||||
*************************************************************************************************/
|
||||
|
||||
// This file was generated by BAML: do not edit it. Instead, edit the BAML
|
||||
// files and re-generate this code.
|
||||
//
|
||||
/* eslint-disable */
|
||||
// tslint:disable
|
||||
// @ts-nocheck
|
||||
// biome-ignore format: autogenerated code
|
||||
/**
|
||||
* If this import fails, you may need to upgrade @boundaryml/baml.
|
||||
*
|
||||
* Please upgrade @boundaryml/baml to 0.85.0.
|
||||
*
|
||||
* $ npm install @boundaryml/baml@0.85.0
|
||||
* $ yarn add @boundaryml/baml@0.85.0
|
||||
* $ pnpm add @boundaryml/baml@0.85.0
|
||||
*
|
||||
* If nothing else works, please ask for help:
|
||||
*
|
||||
* https://github.com/boundaryml/baml/issues
|
||||
* https://boundaryml.com/discord
|
||||
*
|
||||
**/
|
||||
import { ThrowIfVersionMismatch } from "@boundaryml/baml";
|
||||
|
||||
export const version = "0.85.0";
|
||||
|
||||
ThrowIfVersionMismatch(version);
|
||||
|
||||
|
||||
|
||||
export { b } from "./async_client"
|
||||
|
||||
export * from "./types"
|
||||
export type { partial_types } from "./partial_types"
|
||||
export * from "./tracing"
|
||||
export { resetBamlEnvVars } from "./globals"
|
||||
export { BamlClientHttpError, BamlValidationError, BamlClientFinishReasonError } from "@boundaryml/baml"
|
||||
@@ -1,27 +0,0 @@
|
||||
/*************************************************************************************************
|
||||
|
||||
Welcome to Baml! To use this generated code, please run one of the following:
|
||||
|
||||
$ npm install @boundaryml/baml
|
||||
$ yarn add @boundaryml/baml
|
||||
$ pnpm add @boundaryml/baml
|
||||
|
||||
*************************************************************************************************/
|
||||
|
||||
// This file was generated by BAML: do not edit it. Instead, edit the BAML
|
||||
// files and re-generate this code.
|
||||
//
|
||||
/* eslint-disable */
|
||||
// tslint:disable
|
||||
// @ts-nocheck
|
||||
// biome-ignore format: autogenerated code
|
||||
const fileMap = {
|
||||
|
||||
"agent.baml": "class DoneForNow {\n intent \"done_for_now\"\n message string \n}\n\nfunction DetermineNextStep(\n thread: string \n) -> CalculatorTools | DoneForNow {\n client \"openai/gpt-4o\"\n\n prompt #\"\n {{ _.role(\"system\") }}\n\n You are a helpful assistant that can help with tasks.\n\n {{ _.role(\"user\") }}\n\n You are working on the following thread:\n\n {{ thread }}\n\n What should the next step be?\n\n {{ ctx.output_format }}\n \"#\n}\n\ntest HelloWorld {\n functions [DetermineNextStep]\n args {\n thread #\"\n {\n \"type\": \"user_input\",\n \"data\": \"hello!\"\n }\n \"#\n }\n}",
|
||||
"clients.baml": "// Learn more about clients at https://docs.boundaryml.com/docs/snippets/clients/overview\n\nclient<llm> CustomGPT4o {\n provider openai\n options {\n model \"gpt-4o\"\n api_key env.OPENAI_API_KEY\n }\n}\n\nclient<llm> CustomGPT4oMini {\n provider openai\n retry_policy Exponential\n options {\n model \"gpt-4o-mini\"\n api_key env.OPENAI_API_KEY\n }\n}\n\nclient<llm> CustomSonnet {\n provider anthropic\n options {\n model \"claude-3-5-sonnet-20241022\"\n api_key env.ANTHROPIC_API_KEY\n }\n}\n\n\nclient<llm> CustomHaiku {\n provider anthropic\n retry_policy Constant\n options {\n model \"claude-3-haiku-20240307\"\n api_key env.ANTHROPIC_API_KEY\n }\n}\n\n// https://docs.boundaryml.com/docs/snippets/clients/round-robin\nclient<llm> CustomFast {\n provider round-robin\n options {\n // This will alternate between the two clients\n strategy [CustomGPT4oMini, CustomHaiku]\n }\n}\n\n// https://docs.boundaryml.com/docs/snippets/clients/fallback\nclient<llm> OpenaiFallback {\n provider fallback\n options {\n // This will try the clients in order until one succeeds\n strategy [CustomGPT4oMini, CustomGPT4oMini]\n }\n}\n\n// https://docs.boundaryml.com/docs/snippets/clients/retry\nretry_policy Constant {\n max_retries 3\n // Strategy is optional\n strategy {\n type constant_delay\n delay_ms 200\n }\n}\n\nretry_policy Exponential {\n max_retries 2\n // Strategy is optional\n strategy {\n type exponential_backoff\n delay_ms 300\n multiplier 1.5\n max_delay_ms 10000\n }\n}",
|
||||
"generators.baml": "// This helps use auto generate libraries you can use in the language of\n// your choice. You can have multiple generators if you use multiple languages.\n// Just ensure that the output_dir is different for each generator.\ngenerator target {\n // Valid values: \"python/pydantic\", \"typescript\", \"ruby/sorbet\", \"rest/openapi\"\n output_type \"typescript\"\n\n // Where the generated code will be saved (relative to baml_src/)\n output_dir \"../\"\n\n // The version of the BAML package you have installed (e.g. same version as your baml-py or @boundaryml/baml).\n // The BAML VSCode extension version should also match this version.\n version \"0.85.0\"\n\n // Valid values: \"sync\", \"async\"\n // This controls what `b.FunctionName()` will be (sync or async).\n default_client_mode async\n}\n",
|
||||
"tool_calculator.baml": "type CalculatorTools = AddTool | SubtractTool | MultiplyTool | DivideTool\n\n\nclass AddTool {\n intent \"add\"\n a int | float\n b int | float\n}\n\nclass SubtractTool {\n intent \"subtract\"\n a int | float\n b int | float\n}\n\nclass MultiplyTool {\n intent \"multiply\"\n a int | float\n b int | float\n}\n\nclass DivideTool {\n intent \"divide\"\n a int | float\n b int | float\n}\n\n",
|
||||
}
|
||||
export const getBamlFiles = () => {
|
||||
return fileMap;
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
/*************************************************************************************************
|
||||
|
||||
Welcome to Baml! To use this generated code, please run one of the following:
|
||||
|
||||
$ npm install @boundaryml/baml
|
||||
$ yarn add @boundaryml/baml
|
||||
$ pnpm add @boundaryml/baml
|
||||
|
||||
*************************************************************************************************/
|
||||
|
||||
// This file was generated by BAML: do not edit it. Instead, edit the BAML
|
||||
// files and re-generate this code.
|
||||
//
|
||||
/* eslint-disable */
|
||||
// tslint:disable
|
||||
// @ts-nocheck
|
||||
// biome-ignore format: autogenerated code
|
||||
import type { BamlRuntime, BamlCtxManager, ClientRegistry, Image, Audio, Collector } from "@boundaryml/baml"
|
||||
import { toBamlError } from "@boundaryml/baml"
|
||||
import type { Checked, Check } from "./types"
|
||||
import type { partial_types } from "./partial_types"
|
||||
import type * as types from "./types"
|
||||
import type {AddTool, DivideTool, DoneForNow, MultiplyTool, SubtractTool} from "./types"
|
||||
import type TypeBuilder from "./type_builder"
|
||||
|
||||
export class LlmResponseParser {
|
||||
constructor(private runtime: BamlRuntime, private ctxManager: BamlCtxManager) {}
|
||||
|
||||
|
||||
DetermineNextStep(
|
||||
llmResponse: string,
|
||||
__baml_options__?: { tb?: TypeBuilder, clientRegistry?: ClientRegistry }
|
||||
): AddTool | SubtractTool | MultiplyTool | DivideTool | DoneForNow {
|
||||
try {
|
||||
return this.runtime.parseLlmResponse(
|
||||
"DetermineNextStep",
|
||||
llmResponse,
|
||||
false,
|
||||
this.ctxManager.cloneContext(),
|
||||
__baml_options__?.tb?.__tb(),
|
||||
__baml_options__?.clientRegistry,
|
||||
) as AddTool | SubtractTool | MultiplyTool | DivideTool | DoneForNow
|
||||
} catch (error) {
|
||||
throw toBamlError(error);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export class LlmStreamParser {
|
||||
constructor(private runtime: BamlRuntime, private ctxManager: BamlCtxManager) {}
|
||||
|
||||
|
||||
DetermineNextStep(
|
||||
llmResponse: string,
|
||||
__baml_options__?: { tb?: TypeBuilder, clientRegistry?: ClientRegistry }
|
||||
): (((partial_types.AddTool | null) | (partial_types.SubtractTool | null) | (partial_types.MultiplyTool | null) | (partial_types.DivideTool | null) | null) | (partial_types.DoneForNow | null)) {
|
||||
try {
|
||||
return this.runtime.parseLlmResponse(
|
||||
"DetermineNextStep",
|
||||
llmResponse,
|
||||
true,
|
||||
this.ctxManager.cloneContext(),
|
||||
__baml_options__?.tb?.__tb(),
|
||||
__baml_options__?.clientRegistry,
|
||||
) as (((partial_types.AddTool | null) | (partial_types.SubtractTool | null) | (partial_types.MultiplyTool | null) | (partial_types.DivideTool | null) | null) | (partial_types.DoneForNow | null))
|
||||
} catch (error) {
|
||||
throw toBamlError(error);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,66 +0,0 @@
|
||||
/*************************************************************************************************
|
||||
|
||||
Welcome to Baml! To use this generated code, please run one of the following:
|
||||
|
||||
$ npm install @boundaryml/baml
|
||||
$ yarn add @boundaryml/baml
|
||||
$ pnpm add @boundaryml/baml
|
||||
|
||||
*************************************************************************************************/
|
||||
|
||||
// This file was generated by BAML: do not edit it. Instead, edit the BAML
|
||||
// files and re-generate this code.
|
||||
//
|
||||
/* eslint-disable */
|
||||
// tslint:disable
|
||||
// @ts-nocheck
|
||||
// biome-ignore format: autogenerated code
|
||||
import type { Image, Audio } from "@boundaryml/baml"
|
||||
import type { Checked, Check } from "./types"
|
||||
import type { AddTool, DivideTool, DoneForNow, MultiplyTool, SubtractTool } from "./types"
|
||||
import type * as types from "./types"
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* These types are used for streaming, for when an instance of a type
|
||||
* is still being built up and any of its fields is not yet fully available.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
export interface StreamState<T> {
|
||||
value: T
|
||||
state: "Pending" | "Incomplete" | "Complete"
|
||||
}
|
||||
|
||||
export namespace partial_types {
|
||||
|
||||
export interface AddTool {
|
||||
intent: "add"
|
||||
a?: ((number | null) | (number | null) | null)
|
||||
b?: ((number | null) | (number | null) | null)
|
||||
}
|
||||
|
||||
export interface DivideTool {
|
||||
intent: "divide"
|
||||
a?: ((number | null) | (number | null) | null)
|
||||
b?: ((number | null) | (number | null) | null)
|
||||
}
|
||||
|
||||
export interface DoneForNow {
|
||||
intent: "done_for_now"
|
||||
message?: (string | null)
|
||||
}
|
||||
|
||||
export interface MultiplyTool {
|
||||
intent: "multiply"
|
||||
a?: ((number | null) | (number | null) | null)
|
||||
b?: ((number | null) | (number | null) | null)
|
||||
}
|
||||
|
||||
export interface SubtractTool {
|
||||
intent: "subtract"
|
||||
a?: ((number | null) | (number | null) | null)
|
||||
b?: ((number | null) | (number | null) | null)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,113 +0,0 @@
|
||||
/*************************************************************************************************
|
||||
|
||||
Welcome to Baml! To use this generated code, please run one of the following:
|
||||
|
||||
$ npm install @boundaryml/baml
|
||||
$ yarn add @boundaryml/baml
|
||||
$ pnpm add @boundaryml/baml
|
||||
|
||||
*************************************************************************************************/
|
||||
|
||||
// This file was generated by BAML: do not edit it. Instead, edit the BAML
|
||||
// files and re-generate this code.
|
||||
//
|
||||
/* eslint-disable */
|
||||
// tslint:disable
|
||||
// @ts-nocheck
|
||||
// biome-ignore format: autogenerated code
|
||||
import type { BamlRuntime, FunctionResult, BamlCtxManager, Image, Audio, ClientRegistry, Collector } from "@boundaryml/baml"
|
||||
import { toBamlError, type HTTPRequest } from "@boundaryml/baml"
|
||||
import type { Checked, Check, RecursivePartialNull as MovedRecursivePartialNull } from "./types"
|
||||
import type * as types from "./types"
|
||||
import type {AddTool, DivideTool, DoneForNow, MultiplyTool, SubtractTool} from "./types"
|
||||
import type TypeBuilder from "./type_builder"
|
||||
import { HttpRequest, HttpStreamRequest } from "./sync_request"
|
||||
import { LlmResponseParser, LlmStreamParser } from "./parser"
|
||||
import { DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_CTX, DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_RUNTIME } from "./globals"
|
||||
|
||||
/**
|
||||
* @deprecated Use RecursivePartialNull from 'baml_client/types' instead.
|
||||
* Example:
|
||||
* ```ts
|
||||
* import { RecursivePartialNull } from './baml_client/types'
|
||||
* ```
|
||||
*/
|
||||
export type RecursivePartialNull<T> = MovedRecursivePartialNull<T>;
|
||||
|
||||
type BamlCallOptions = {
|
||||
tb?: TypeBuilder
|
||||
clientRegistry?: ClientRegistry
|
||||
collector?: Collector | Collector[]
|
||||
}
|
||||
|
||||
export class BamlSyncClient {
|
||||
private httpRequest: HttpRequest
|
||||
private httpStreamRequest: HttpStreamRequest
|
||||
private llmResponseParser: LlmResponseParser
|
||||
private llmStreamParser: LlmStreamParser
|
||||
private bamlOptions: BamlCallOptions
|
||||
|
||||
constructor(private runtime: BamlRuntime, private ctxManager: BamlCtxManager, private bamlOptions?: BamlCallOptions) {
|
||||
this.httpRequest = new HttpRequest(runtime, ctxManager)
|
||||
this.httpStreamRequest = new HttpStreamRequest(runtime, ctxManager)
|
||||
this.llmResponseParser = new LlmResponseParser(runtime, ctxManager)
|
||||
this.llmStreamParser = new LlmStreamParser(runtime, ctxManager)
|
||||
this.bamlOptions = bamlOptions || {}
|
||||
}
|
||||
|
||||
withOptions(bamlOptions: BamlCallOptions) {
|
||||
return new BamlSyncClient(this.runtime, this.ctxManager, bamlOptions)
|
||||
}
|
||||
|
||||
/*
|
||||
* @deprecated NOT IMPLEMENTED as streaming must by async. We
|
||||
* are not providing an async version as we want to reserve the
|
||||
* right to provide a sync version in the future.
|
||||
*/
|
||||
get stream() {
|
||||
throw new Error("stream is not available in BamlSyncClient. Use `import { b } from 'baml_client/async_client")
|
||||
}
|
||||
|
||||
get request() {
|
||||
return this.httpRequest
|
||||
}
|
||||
|
||||
get streamRequest() {
|
||||
return this.httpStreamRequest
|
||||
}
|
||||
|
||||
get parse() {
|
||||
return this.llmResponseParser
|
||||
}
|
||||
|
||||
get parseStream() {
|
||||
return this.llmStreamParser
|
||||
}
|
||||
|
||||
|
||||
DetermineNextStep(
|
||||
thread: string,
|
||||
__baml_options__?: BamlCallOptions
|
||||
): AddTool | SubtractTool | MultiplyTool | DivideTool | DoneForNow {
|
||||
try {
|
||||
const options = { ...this.bamlOptions, ...(__baml_options__ || {}) }
|
||||
const collector = options.collector ? (Array.isArray(options.collector) ? options.collector : [options.collector]) : [];
|
||||
const raw = this.runtime.callFunctionSync(
|
||||
"DetermineNextStep",
|
||||
{
|
||||
"thread": thread
|
||||
},
|
||||
this.ctxManager.cloneContext(),
|
||||
options.tb?.__tb(),
|
||||
options.clientRegistry,
|
||||
collector,
|
||||
)
|
||||
return raw.parsed(false) as AddTool | SubtractTool | MultiplyTool | DivideTool | DoneForNow
|
||||
} catch (error: any) {
|
||||
throw toBamlError(error);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export const b = new BamlSyncClient(DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_RUNTIME, DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_CTX)
|
||||
@@ -1,80 +0,0 @@
|
||||
/*************************************************************************************************
|
||||
|
||||
Welcome to Baml! To use this generated code, please run one of the following:
|
||||
|
||||
$ npm install @boundaryml/baml
|
||||
$ yarn add @boundaryml/baml
|
||||
$ pnpm add @boundaryml/baml
|
||||
|
||||
*************************************************************************************************/
|
||||
|
||||
// This file was generated by BAML: do not edit it. Instead, edit the BAML
|
||||
// files and re-generate this code.
|
||||
//
|
||||
/* eslint-disable */
|
||||
// tslint:disable
|
||||
// @ts-nocheck
|
||||
// biome-ignore format: autogenerated code
|
||||
import type { BamlRuntime, BamlCtxManager, ClientRegistry, Image, Audio } from "@boundaryml/baml"
|
||||
import { toBamlError, HTTPRequest } from "@boundaryml/baml"
|
||||
import type { Checked, Check } from "./types"
|
||||
import type * as types from "./types"
|
||||
import type {AddTool, DivideTool, DoneForNow, MultiplyTool, SubtractTool} from "./types"
|
||||
import type TypeBuilder from "./type_builder"
|
||||
|
||||
type BamlCallOptions = {
|
||||
tb?: TypeBuilder
|
||||
clientRegistry?: ClientRegistry
|
||||
}
|
||||
|
||||
export class HttpRequest {
|
||||
constructor(private runtime: BamlRuntime, private ctxManager: BamlCtxManager) {}
|
||||
|
||||
|
||||
DetermineNextStep(
|
||||
thread: string,
|
||||
__baml_options__?: BamlCallOptions
|
||||
): HTTPRequest {
|
||||
try {
|
||||
return this.runtime.buildRequestSync(
|
||||
"DetermineNextStep",
|
||||
{
|
||||
"thread": thread
|
||||
},
|
||||
this.ctxManager.cloneContext(),
|
||||
__baml_options__?.tb?.__tb(),
|
||||
__baml_options__?.clientRegistry,
|
||||
false,
|
||||
)
|
||||
} catch (error) {
|
||||
throw toBamlError(error);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export class HttpStreamRequest {
|
||||
constructor(private runtime: BamlRuntime, private ctxManager: BamlCtxManager) {}
|
||||
|
||||
|
||||
DetermineNextStep(
|
||||
thread: string,
|
||||
__baml_options__?: BamlCallOptions
|
||||
): HTTPRequest {
|
||||
try {
|
||||
return this.runtime.buildRequestSync(
|
||||
"DetermineNextStep",
|
||||
{
|
||||
"thread": thread
|
||||
},
|
||||
this.ctxManager.cloneContext(),
|
||||
__baml_options__?.tb?.__tb(),
|
||||
__baml_options__?.clientRegistry,
|
||||
true,
|
||||
)
|
||||
} catch (error) {
|
||||
throw toBamlError(error);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
/*************************************************************************************************
|
||||
|
||||
Welcome to Baml! To use this generated code, please run one of the following:
|
||||
|
||||
$ npm install @boundaryml/baml
|
||||
$ yarn add @boundaryml/baml
|
||||
$ pnpm add @boundaryml/baml
|
||||
|
||||
*************************************************************************************************/
|
||||
|
||||
// This file was generated by BAML: do not edit it. Instead, edit the BAML
|
||||
// files and re-generate this code.
|
||||
//
|
||||
/* eslint-disable */
|
||||
// tslint:disable
|
||||
// @ts-nocheck
|
||||
// biome-ignore format: autogenerated code
|
||||
import type { BamlLogEvent } from '@boundaryml/baml';
|
||||
import { DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_CTX } from './globals';
|
||||
|
||||
const traceAsync =
|
||||
DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_CTX.traceFnAsync.bind(DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_CTX)
|
||||
const traceSync =
|
||||
DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_CTX.traceFnSync.bind(DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_CTX)
|
||||
const setTags =
|
||||
DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_CTX.upsertTags.bind(DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_CTX)
|
||||
const flush = () => {
|
||||
DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_CTX.flush.bind(DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_CTX)()
|
||||
}
|
||||
const onLogEvent = (callback: undefined | ((event: BamlLogEvent) => void)) =>
|
||||
DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_CTX.onLogEvent(callback)
|
||||
|
||||
export { traceAsync, traceSync, setTags, flush, onLogEvent }
|
||||
@@ -1,100 +0,0 @@
|
||||
/*************************************************************************************************
|
||||
|
||||
Welcome to Baml! To use this generated code, please run one of the following:
|
||||
|
||||
$ npm install @boundaryml/baml
|
||||
$ yarn add @boundaryml/baml
|
||||
$ pnpm add @boundaryml/baml
|
||||
|
||||
*************************************************************************************************/
|
||||
|
||||
// This file was generated by BAML: do not edit it. Instead, edit the BAML
|
||||
// files and re-generate this code.
|
||||
//
|
||||
/* eslint-disable */
|
||||
// tslint:disable
|
||||
// @ts-nocheck
|
||||
// biome-ignore format: autogenerated code
|
||||
import { FieldType } from '@boundaryml/baml/native'
|
||||
import { TypeBuilder as _TypeBuilder, EnumBuilder, ClassBuilder } from '@boundaryml/baml/type_builder'
|
||||
import { DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_RUNTIME } from "./globals"
|
||||
|
||||
export default class TypeBuilder {
|
||||
private tb: _TypeBuilder;
|
||||
|
||||
|
||||
|
||||
constructor() {
|
||||
this.tb = new _TypeBuilder({
|
||||
classes: new Set([
|
||||
"AddTool","DivideTool","DoneForNow","MultiplyTool","SubtractTool",
|
||||
]),
|
||||
enums: new Set([
|
||||
|
||||
]),
|
||||
runtime: DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_RUNTIME
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
|
||||
__tb() {
|
||||
return this.tb._tb();
|
||||
}
|
||||
|
||||
string(): FieldType {
|
||||
return this.tb.string()
|
||||
}
|
||||
|
||||
literalString(value: string): FieldType {
|
||||
return this.tb.literalString(value)
|
||||
}
|
||||
|
||||
literalInt(value: number): FieldType {
|
||||
return this.tb.literalInt(value)
|
||||
}
|
||||
|
||||
literalBool(value: boolean): FieldType {
|
||||
return this.tb.literalBool(value)
|
||||
}
|
||||
|
||||
int(): FieldType {
|
||||
return this.tb.int()
|
||||
}
|
||||
|
||||
float(): FieldType {
|
||||
return this.tb.float()
|
||||
}
|
||||
|
||||
bool(): FieldType {
|
||||
return this.tb.bool()
|
||||
}
|
||||
|
||||
list(type: FieldType): FieldType {
|
||||
return this.tb.list(type)
|
||||
}
|
||||
|
||||
null(): FieldType {
|
||||
return this.tb.null()
|
||||
}
|
||||
|
||||
map(key: FieldType, value: FieldType): FieldType {
|
||||
return this.tb.map(key, value)
|
||||
}
|
||||
|
||||
union(types: FieldType[]): FieldType {
|
||||
return this.tb.union(types)
|
||||
}
|
||||
|
||||
addClass<Name extends string>(name: Name): ClassBuilder<Name> {
|
||||
return this.tb.addClass(name);
|
||||
}
|
||||
|
||||
addEnum<Name extends string>(name: Name): EnumBuilder<Name> {
|
||||
return this.tb.addEnum(name);
|
||||
}
|
||||
|
||||
addBaml(baml: string): void {
|
||||
this.tb.addBaml(baml, this.runtime);
|
||||
}
|
||||
}
|
||||
@@ -1,81 +0,0 @@
|
||||
/*************************************************************************************************
|
||||
|
||||
Welcome to Baml! To use this generated code, please run one of the following:
|
||||
|
||||
$ npm install @boundaryml/baml
|
||||
$ yarn add @boundaryml/baml
|
||||
$ pnpm add @boundaryml/baml
|
||||
|
||||
*************************************************************************************************/
|
||||
|
||||
// This file was generated by BAML: do not edit it. Instead, edit the BAML
|
||||
// files and re-generate this code.
|
||||
//
|
||||
/* eslint-disable */
|
||||
// tslint:disable
|
||||
// @ts-nocheck
|
||||
// biome-ignore format: autogenerated code
|
||||
import type { Image, Audio } from "@boundaryml/baml"
|
||||
|
||||
/**
|
||||
* Recursively partial type that can be null.
|
||||
*
|
||||
* @deprecated Use types from the `partial_types` namespace instead, which provides type-safe partial implementations
|
||||
* @template T The type to make recursively partial.
|
||||
*/
|
||||
export type RecursivePartialNull<T> = T extends object
|
||||
? { [P in keyof T]?: RecursivePartialNull<T[P]> }
|
||||
: T | null;
|
||||
|
||||
export interface Checked<T,CheckName extends string = string> {
|
||||
value: T,
|
||||
checks: Record<CheckName, Check>,
|
||||
}
|
||||
|
||||
|
||||
export interface Check {
|
||||
name: string,
|
||||
expr: string
|
||||
status: "succeeded" | "failed"
|
||||
}
|
||||
|
||||
export function all_succeeded<CheckName extends string>(checks: Record<CheckName, Check>): boolean {
|
||||
return get_checks(checks).every(check => check.status === "succeeded")
|
||||
}
|
||||
|
||||
export function get_checks<CheckName extends string>(checks: Record<CheckName, Check>): Check[] {
|
||||
return Object.values(checks)
|
||||
}
|
||||
export interface AddTool {
|
||||
intent: "add"
|
||||
a: number | number
|
||||
b: number | number
|
||||
|
||||
}
|
||||
|
||||
export interface DivideTool {
|
||||
intent: "divide"
|
||||
a: number | number
|
||||
b: number | number
|
||||
|
||||
}
|
||||
|
||||
export interface DoneForNow {
|
||||
intent: "done_for_now"
|
||||
message: string
|
||||
|
||||
}
|
||||
|
||||
export interface MultiplyTool {
|
||||
intent: "multiply"
|
||||
a: number | number
|
||||
b: number | number
|
||||
|
||||
}
|
||||
|
||||
export interface SubtractTool {
|
||||
intent: "subtract"
|
||||
a: number | number
|
||||
b: number | number
|
||||
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user