llm-exe 2.2.0 → 2.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -65,20 +65,6 @@ type OpenAIChatModelName = "gpt-3.5-turbo" | "gpt-3.5-turbo-0613" | "gpt-3.5-tur
65
65
  type OpenAIConversationModelName = "davinci" | "text-curie-001" | "text-babbage-001" | "text-ada-001";
66
66
  type OpenAIEmbeddingModelName = "text-embedding-ada-002";
67
67
  type OpenAIModelName = OpenAIChatModelName | OpenAIConversationModelName | OpenAIEmbeddingModelName;
68
- interface LlmExecutorExecuteOptions {
69
- functions?: CallableExecutorCore[];
70
- functionCall?: any;
71
- jsonSchema?: Record<string, any>;
72
- }
73
- type GenericFunctionCall = "auto" | "none" | "any" | {
74
- name: string;
75
- };
76
- interface OpenAiLlmExecutorOptions<T extends GenericFunctionCall = "auto"> extends LlmExecutorExecuteOptions {
77
- functions?: CallableExecutorCore[];
78
- functionCall?: T;
79
- functionCallStrictInput?: boolean;
80
- jsonSchema?: Record<string, any>;
81
- }
82
68
 
83
69
  /**
84
70
  * BaseParser is an abstract class for parsing text and enforcing JSON schema on the parsed data.
@@ -113,21 +99,6 @@ declare abstract class BaseParserWithJson<S extends JSONSchema | undefined = und
113
99
  constructor(name: string, options: BaseParserOptionsWithSchema<S>);
114
100
  }
115
101
 
116
- interface OpenAiFunctionParserOptions<T extends BaseParser<any>> extends BaseParserOptions {
117
- parser: T;
118
- }
119
- declare class OpenAiFunctionParser<T extends BaseParser<any>> extends BaseParser<ParserOutput<T> | {
120
- name: any;
121
- arguments: any;
122
- }> {
123
- parser: T;
124
- constructor(options: OpenAiFunctionParserOptions<T>);
125
- parse(text: OutputResultContent[], _options?: Record<string, any>): ParserOutput<T> | {
126
- name: string;
127
- arguments: any;
128
- };
129
- }
130
-
131
102
  interface StringParserOptions extends BaseParserOptions {
132
103
  }
133
104
  declare class StringParser extends BaseParser<string> {
@@ -330,6 +301,25 @@ declare function createParser<T extends Extract<CreateParserType, "json">, S ext
330
301
  declare function createParser<T extends CreateParserType, S extends JSONSchema | undefined = undefined>(type: T, options?: BaseParserOptionsWithSchema<S> | BaseParserOptions): JsonParser<S> | ListToJsonParser<S> | StringParser | NumberParser | BooleanParser | ListToArrayParser | ListToKeyValueParser | ReplaceStringTemplateParser | MarkdownCodeBlockParser | MarkdownCodeBlocksParser | StringExtractParser;
331
302
  declare function createCustomParser<O>(name: string, parserFn: (text: string, inputValues: ExecutorContext<any, any>) => O): CustomParser<ReturnType<typeof parserFn>>;
332
303
 
304
+ interface LlmNativeFunctionParserOptions<T extends BaseParser<any>> extends BaseParserOptions {
305
+ parser: T;
306
+ }
307
+ declare class LlmNativeFunctionParser<T extends BaseParser<any>> extends BaseParser<ParserOutput<T> | {
308
+ name: any;
309
+ arguments: any;
310
+ }> {
311
+ parser: T;
312
+ constructor(options: LlmNativeFunctionParserOptions<T>);
313
+ parse(text: OutputResultContent[], _options?: Record<string, any>): ParserOutput<T> | {
314
+ name: string;
315
+ arguments: any;
316
+ };
317
+ }
318
+ /**
319
+ * @deprecated Use `LlmExecutorWithFunctions` instead.
320
+ */
321
+ declare const OpenAiFunctionParser: typeof LlmNativeFunctionParser;
322
+
333
323
  declare function replaceTemplateString(templateString?: string, substitutions?: Record<string, any>, configuration?: PromptTemplateOptions): string;
334
324
 
335
325
  declare function replaceTemplateStringAsync(templateString?: string, substitutions?: Record<string, any>, configuration?: PromptTemplateOptions): Promise<string>;
@@ -740,9 +730,14 @@ declare class LlmExecutor<Llm extends BaseLlm<any>, Prompt extends BasePrompt<Re
740
730
  /**
741
731
  * Core Executor With LLM
742
732
  */
743
- declare class LlmExecutorOpenAiFunctions<Llm extends BaseLlm, Prompt extends BasePrompt<Record<string, any>>, Parser extends BaseParser, State extends BaseState> extends LlmExecutor<Llm, Prompt, Parser, State> {
733
+ declare class LlmExecutorWithFunctions<Llm extends BaseLlm, Prompt extends BasePrompt<Record<string, any>>, Parser extends BaseParser, State extends BaseState> extends LlmExecutor<Llm, Prompt, Parser, State> {
744
734
  constructor(llmConfiguration: ExecutorWithLlmOptions<Llm, Prompt, Parser, State>, options?: CoreExecutorExecuteOptions<LlmExecutorHooks>);
745
- execute<T extends GenericFunctionCall>(_input: PromptInput<Prompt>, _options: OpenAiLlmExecutorOptions<T>): Promise<ParserOutput<Parser>>;
735
+ execute<T extends GenericFunctionCall>(_input: PromptInput<Prompt>, _options: LlmExecutorWithFunctionsOptions<T>): Promise<ParserOutput<Parser>>;
736
+ }
737
+ /**
738
+ * @deprecated Use `LlmExecutorWithFunctions` instead.
739
+ */
740
+ declare class LlmExecutorOpenAiFunctions<Llm extends BaseLlm, Prompt extends BasePrompt<Record<string, any>>, Parser extends BaseParser, State extends BaseState> extends LlmExecutorWithFunctions<Llm, Prompt, Parser, State> {
746
741
  }
747
742
 
748
743
  /**
@@ -763,6 +758,7 @@ declare function createCoreExecutor<I extends PlainObject, O>(handler: (input: I
763
758
  * @returns - A new LlmExecutor instance.
764
759
  */
765
760
  declare function createLlmExecutor<Llm extends BaseLlm<any>, Prompt extends BasePrompt<any>, Parser extends BaseParser, State extends BaseState>(llmConfiguration: ExecutorWithLlmOptions<Llm, Prompt, Parser, State>, options?: CoreExecutorExecuteOptions<LlmExecutorHooks>): LlmExecutor<Llm, Prompt, Parser, State>;
761
+ declare function createLlmFunctionExecutor<Llm extends BaseLlm, Prompt extends BasePrompt<Record<string, any>>, Parser extends BaseParser, State extends BaseState>(llmConfiguration: ExecutorWithLlmOptions<Llm, Prompt, Parser, State>, options?: CoreExecutorExecuteOptions<LlmExecutorHooks>): LlmExecutorWithFunctions<Llm, Prompt, Parser, State>;
766
762
 
767
763
  declare const hookOnComplete = "onComplete";
768
764
  declare const hookOnError = "onError";
@@ -829,6 +825,20 @@ interface CallableExecutorCore {
829
825
  description: string;
830
826
  parameters?: Record<string, any>;
831
827
  }
828
+ interface LlmExecutorExecuteOptions {
829
+ functions?: CallableExecutorCore[];
830
+ functionCall?: any;
831
+ jsonSchema?: Record<string, any>;
832
+ }
833
+ type GenericFunctionCall = "auto" | "none" | "any" | {
834
+ name: string;
835
+ };
836
+ interface LlmExecutorWithFunctionsOptions<T extends GenericFunctionCall = "auto"> extends LlmExecutorExecuteOptions {
837
+ functions?: CallableExecutorCore[];
838
+ functionCall?: T;
839
+ functionCallStrictInput?: boolean;
840
+ jsonSchema?: Record<string, any>;
841
+ }
832
842
 
833
843
  type CreateParserType = "json" | "string" | "boolean" | "number" | "stringExtract" | "listToArray" | "listToJson" | "listToKeyValue" | "replaceStringTemplate" | "markdownCodeBlocks" | "markdownCodeBlock";
834
844
  interface BaseParserOptions {
@@ -1260,7 +1270,7 @@ declare const configs: {
1260
1270
  };
1261
1271
 
1262
1272
  declare function useLlm<T extends keyof typeof configs>(provider: T, options?: AllUseLlmOptions[T]["input"]): {
1263
- call: (messages: string | IChatMessages, options?: OpenAiLlmExecutorOptions) => Promise<{
1273
+ call: (messages: string | IChatMessages, options?: LlmExecutorWithFunctionsOptions) => Promise<{
1264
1274
  getResultContent: (index?: number) => OutputResultContent[];
1265
1275
  getResultText: () => string;
1266
1276
  getResult: () => OutputResult;
@@ -1280,7 +1290,7 @@ declare function useLlm<T extends keyof typeof configs>(provider: T, options?: A
1280
1290
  };
1281
1291
 
1282
1292
  declare function createEmbedding<T extends EmbeddingProviderKey>(provider: T, options: AllEmbedding[T]["input"]): {
1283
- call: (messages: string | string[], options?: OpenAiLlmExecutorOptions) => Promise<{
1293
+ call: (messages: string | string[], options?: LlmExecutorWithFunctionsOptions) => Promise<{
1284
1294
  getEmbedding: (index?: number) => number[];
1285
1295
  getResult: () => EmbeddingOutputResult;
1286
1296
  }>;
@@ -1298,4 +1308,4 @@ declare function createEmbedding<T extends EmbeddingProviderKey>(provider: T, op
1298
1308
  };
1299
1309
  };
1300
1310
 
1301
- export { BaseExecutor, type BaseLlm, BaseParser, BasePrompt, BaseStateItem, ChatPrompt, CustomParser, DefaultState, DefaultStateItem, type EmbeddingProviderKey, type ExecutorContext, type IChatMessages, LlmExecutorOpenAiFunctions, type LlmProvider, type LlmProviderKey, type OpenAIModelName, OpenAiFunctionParser, TextPrompt, type UseLlmKey, createCallableExecutor, createChatPrompt, createCoreExecutor, createCustomParser, createDialogue, createEmbedding, createLlmExecutor, createParser, createPrompt, createState, createStateItem, defineSchema, registerHelpers, registerPartials, useExecutors, useLlm, index as utils };
1311
+ export { BaseExecutor, type BaseLlm, BaseParser, BasePrompt, BaseStateItem, ChatPrompt, CustomParser, DefaultState, DefaultStateItem, type EmbeddingProviderKey, type ExecutorContext, type IChatMessages, LlmExecutorOpenAiFunctions, LlmExecutorWithFunctions, LlmNativeFunctionParser, type LlmProvider, type LlmProviderKey, type OpenAIModelName, OpenAiFunctionParser, TextPrompt, type UseLlmKey, createCallableExecutor, createChatPrompt, createCoreExecutor, createCustomParser, createDialogue, createEmbedding, createLlmExecutor, createLlmFunctionExecutor, createParser, createPrompt, createState, createStateItem, defineSchema, registerHelpers, registerPartials, useExecutors, useLlm, index as utils };
package/dist/index.d.ts CHANGED
@@ -65,20 +65,6 @@ type OpenAIChatModelName = "gpt-3.5-turbo" | "gpt-3.5-turbo-0613" | "gpt-3.5-tur
65
65
  type OpenAIConversationModelName = "davinci" | "text-curie-001" | "text-babbage-001" | "text-ada-001";
66
66
  type OpenAIEmbeddingModelName = "text-embedding-ada-002";
67
67
  type OpenAIModelName = OpenAIChatModelName | OpenAIConversationModelName | OpenAIEmbeddingModelName;
68
- interface LlmExecutorExecuteOptions {
69
- functions?: CallableExecutorCore[];
70
- functionCall?: any;
71
- jsonSchema?: Record<string, any>;
72
- }
73
- type GenericFunctionCall = "auto" | "none" | "any" | {
74
- name: string;
75
- };
76
- interface OpenAiLlmExecutorOptions<T extends GenericFunctionCall = "auto"> extends LlmExecutorExecuteOptions {
77
- functions?: CallableExecutorCore[];
78
- functionCall?: T;
79
- functionCallStrictInput?: boolean;
80
- jsonSchema?: Record<string, any>;
81
- }
82
68
 
83
69
  /**
84
70
  * BaseParser is an abstract class for parsing text and enforcing JSON schema on the parsed data.
@@ -113,21 +99,6 @@ declare abstract class BaseParserWithJson<S extends JSONSchema | undefined = und
113
99
  constructor(name: string, options: BaseParserOptionsWithSchema<S>);
114
100
  }
115
101
 
116
- interface OpenAiFunctionParserOptions<T extends BaseParser<any>> extends BaseParserOptions {
117
- parser: T;
118
- }
119
- declare class OpenAiFunctionParser<T extends BaseParser<any>> extends BaseParser<ParserOutput<T> | {
120
- name: any;
121
- arguments: any;
122
- }> {
123
- parser: T;
124
- constructor(options: OpenAiFunctionParserOptions<T>);
125
- parse(text: OutputResultContent[], _options?: Record<string, any>): ParserOutput<T> | {
126
- name: string;
127
- arguments: any;
128
- };
129
- }
130
-
131
102
  interface StringParserOptions extends BaseParserOptions {
132
103
  }
133
104
  declare class StringParser extends BaseParser<string> {
@@ -330,6 +301,25 @@ declare function createParser<T extends Extract<CreateParserType, "json">, S ext
330
301
  declare function createParser<T extends CreateParserType, S extends JSONSchema | undefined = undefined>(type: T, options?: BaseParserOptionsWithSchema<S> | BaseParserOptions): JsonParser<S> | ListToJsonParser<S> | StringParser | NumberParser | BooleanParser | ListToArrayParser | ListToKeyValueParser | ReplaceStringTemplateParser | MarkdownCodeBlockParser | MarkdownCodeBlocksParser | StringExtractParser;
331
302
  declare function createCustomParser<O>(name: string, parserFn: (text: string, inputValues: ExecutorContext<any, any>) => O): CustomParser<ReturnType<typeof parserFn>>;
332
303
 
304
+ interface LlmNativeFunctionParserOptions<T extends BaseParser<any>> extends BaseParserOptions {
305
+ parser: T;
306
+ }
307
+ declare class LlmNativeFunctionParser<T extends BaseParser<any>> extends BaseParser<ParserOutput<T> | {
308
+ name: any;
309
+ arguments: any;
310
+ }> {
311
+ parser: T;
312
+ constructor(options: LlmNativeFunctionParserOptions<T>);
313
+ parse(text: OutputResultContent[], _options?: Record<string, any>): ParserOutput<T> | {
314
+ name: string;
315
+ arguments: any;
316
+ };
317
+ }
318
+ /**
319
+ * @deprecated Use `LlmExecutorWithFunctions` instead.
320
+ */
321
+ declare const OpenAiFunctionParser: typeof LlmNativeFunctionParser;
322
+
333
323
  declare function replaceTemplateString(templateString?: string, substitutions?: Record<string, any>, configuration?: PromptTemplateOptions): string;
334
324
 
335
325
  declare function replaceTemplateStringAsync(templateString?: string, substitutions?: Record<string, any>, configuration?: PromptTemplateOptions): Promise<string>;
@@ -740,9 +730,14 @@ declare class LlmExecutor<Llm extends BaseLlm<any>, Prompt extends BasePrompt<Re
740
730
  /**
741
731
  * Core Executor With LLM
742
732
  */
743
- declare class LlmExecutorOpenAiFunctions<Llm extends BaseLlm, Prompt extends BasePrompt<Record<string, any>>, Parser extends BaseParser, State extends BaseState> extends LlmExecutor<Llm, Prompt, Parser, State> {
733
+ declare class LlmExecutorWithFunctions<Llm extends BaseLlm, Prompt extends BasePrompt<Record<string, any>>, Parser extends BaseParser, State extends BaseState> extends LlmExecutor<Llm, Prompt, Parser, State> {
744
734
  constructor(llmConfiguration: ExecutorWithLlmOptions<Llm, Prompt, Parser, State>, options?: CoreExecutorExecuteOptions<LlmExecutorHooks>);
745
- execute<T extends GenericFunctionCall>(_input: PromptInput<Prompt>, _options: OpenAiLlmExecutorOptions<T>): Promise<ParserOutput<Parser>>;
735
+ execute<T extends GenericFunctionCall>(_input: PromptInput<Prompt>, _options: LlmExecutorWithFunctionsOptions<T>): Promise<ParserOutput<Parser>>;
736
+ }
737
+ /**
738
+ * @deprecated Use `LlmExecutorWithFunctions` instead.
739
+ */
740
+ declare class LlmExecutorOpenAiFunctions<Llm extends BaseLlm, Prompt extends BasePrompt<Record<string, any>>, Parser extends BaseParser, State extends BaseState> extends LlmExecutorWithFunctions<Llm, Prompt, Parser, State> {
746
741
  }
747
742
 
748
743
  /**
@@ -763,6 +758,7 @@ declare function createCoreExecutor<I extends PlainObject, O>(handler: (input: I
763
758
  * @returns - A new LlmExecutor instance.
764
759
  */
765
760
  declare function createLlmExecutor<Llm extends BaseLlm<any>, Prompt extends BasePrompt<any>, Parser extends BaseParser, State extends BaseState>(llmConfiguration: ExecutorWithLlmOptions<Llm, Prompt, Parser, State>, options?: CoreExecutorExecuteOptions<LlmExecutorHooks>): LlmExecutor<Llm, Prompt, Parser, State>;
761
+ declare function createLlmFunctionExecutor<Llm extends BaseLlm, Prompt extends BasePrompt<Record<string, any>>, Parser extends BaseParser, State extends BaseState>(llmConfiguration: ExecutorWithLlmOptions<Llm, Prompt, Parser, State>, options?: CoreExecutorExecuteOptions<LlmExecutorHooks>): LlmExecutorWithFunctions<Llm, Prompt, Parser, State>;
766
762
 
767
763
  declare const hookOnComplete = "onComplete";
768
764
  declare const hookOnError = "onError";
@@ -829,6 +825,20 @@ interface CallableExecutorCore {
829
825
  description: string;
830
826
  parameters?: Record<string, any>;
831
827
  }
828
+ interface LlmExecutorExecuteOptions {
829
+ functions?: CallableExecutorCore[];
830
+ functionCall?: any;
831
+ jsonSchema?: Record<string, any>;
832
+ }
833
+ type GenericFunctionCall = "auto" | "none" | "any" | {
834
+ name: string;
835
+ };
836
+ interface LlmExecutorWithFunctionsOptions<T extends GenericFunctionCall = "auto"> extends LlmExecutorExecuteOptions {
837
+ functions?: CallableExecutorCore[];
838
+ functionCall?: T;
839
+ functionCallStrictInput?: boolean;
840
+ jsonSchema?: Record<string, any>;
841
+ }
832
842
 
833
843
  type CreateParserType = "json" | "string" | "boolean" | "number" | "stringExtract" | "listToArray" | "listToJson" | "listToKeyValue" | "replaceStringTemplate" | "markdownCodeBlocks" | "markdownCodeBlock";
834
844
  interface BaseParserOptions {
@@ -1260,7 +1270,7 @@ declare const configs: {
1260
1270
  };
1261
1271
 
1262
1272
  declare function useLlm<T extends keyof typeof configs>(provider: T, options?: AllUseLlmOptions[T]["input"]): {
1263
- call: (messages: string | IChatMessages, options?: OpenAiLlmExecutorOptions) => Promise<{
1273
+ call: (messages: string | IChatMessages, options?: LlmExecutorWithFunctionsOptions) => Promise<{
1264
1274
  getResultContent: (index?: number) => OutputResultContent[];
1265
1275
  getResultText: () => string;
1266
1276
  getResult: () => OutputResult;
@@ -1280,7 +1290,7 @@ declare function useLlm<T extends keyof typeof configs>(provider: T, options?: A
1280
1290
  };
1281
1291
 
1282
1292
  declare function createEmbedding<T extends EmbeddingProviderKey>(provider: T, options: AllEmbedding[T]["input"]): {
1283
- call: (messages: string | string[], options?: OpenAiLlmExecutorOptions) => Promise<{
1293
+ call: (messages: string | string[], options?: LlmExecutorWithFunctionsOptions) => Promise<{
1284
1294
  getEmbedding: (index?: number) => number[];
1285
1295
  getResult: () => EmbeddingOutputResult;
1286
1296
  }>;
@@ -1298,4 +1308,4 @@ declare function createEmbedding<T extends EmbeddingProviderKey>(provider: T, op
1298
1308
  };
1299
1309
  };
1300
1310
 
1301
- export { BaseExecutor, type BaseLlm, BaseParser, BasePrompt, BaseStateItem, ChatPrompt, CustomParser, DefaultState, DefaultStateItem, type EmbeddingProviderKey, type ExecutorContext, type IChatMessages, LlmExecutorOpenAiFunctions, type LlmProvider, type LlmProviderKey, type OpenAIModelName, OpenAiFunctionParser, TextPrompt, type UseLlmKey, createCallableExecutor, createChatPrompt, createCoreExecutor, createCustomParser, createDialogue, createEmbedding, createLlmExecutor, createParser, createPrompt, createState, createStateItem, defineSchema, registerHelpers, registerPartials, useExecutors, useLlm, index as utils };
1311
+ export { BaseExecutor, type BaseLlm, BaseParser, BasePrompt, BaseStateItem, ChatPrompt, CustomParser, DefaultState, DefaultStateItem, type EmbeddingProviderKey, type ExecutorContext, type IChatMessages, LlmExecutorOpenAiFunctions, LlmExecutorWithFunctions, LlmNativeFunctionParser, type LlmProvider, type LlmProviderKey, type OpenAIModelName, OpenAiFunctionParser, TextPrompt, type UseLlmKey, createCallableExecutor, createChatPrompt, createCoreExecutor, createCustomParser, createDialogue, createEmbedding, createLlmExecutor, createLlmFunctionExecutor, createParser, createPrompt, createState, createStateItem, defineSchema, registerHelpers, registerPartials, useExecutors, useLlm, index as utils };
package/dist/index.js CHANGED
@@ -47,6 +47,8 @@ __export(index_exports, {
47
47
  DefaultState: () => DefaultState,
48
48
  DefaultStateItem: () => DefaultStateItem,
49
49
  LlmExecutorOpenAiFunctions: () => LlmExecutorOpenAiFunctions,
50
+ LlmExecutorWithFunctions: () => LlmExecutorWithFunctions,
51
+ LlmNativeFunctionParser: () => LlmNativeFunctionParser,
50
52
  OpenAiFunctionParser: () => OpenAiFunctionParser,
51
53
  TextPrompt: () => TextPrompt,
52
54
  createCallableExecutor: () => createCallableExecutor,
@@ -56,6 +58,7 @@ __export(index_exports, {
56
58
  createDialogue: () => createDialogue,
57
59
  createEmbedding: () => createEmbedding,
58
60
  createLlmExecutor: () => createLlmExecutor,
61
+ createLlmFunctionExecutor: () => createLlmFunctionExecutor,
59
62
  createParser: () => createParser,
60
63
  createPrompt: () => createPrompt,
61
64
  createState: () => createState,
@@ -390,6 +393,79 @@ var BaseParserWithJson = class extends BaseParser {
390
393
  }
391
394
  };
392
395
 
396
+ // src/utils/modules/assert.ts
397
+ function assert(condition, message) {
398
+ if (condition === void 0 || condition === null || condition === false) {
399
+ if (typeof message === "string") {
400
+ throw new Error(message);
401
+ } else if (message instanceof Error) {
402
+ throw message;
403
+ } else {
404
+ throw new Error(`Assertion error`);
405
+ }
406
+ }
407
+ }
408
+
409
+ // src/parser/parsers/StringParser.ts
410
+ var StringParser = class extends BaseParser {
411
+ constructor(options) {
412
+ super("string", options);
413
+ }
414
+ parse(text, _options) {
415
+ assert(
416
+ typeof text === "string",
417
+ `Invalid input. Expected string. Received ${typeof text}.`
418
+ );
419
+ const parsed = text.toString();
420
+ return parsed;
421
+ }
422
+ };
423
+
424
+ // src/parser/parsers/BooleanParser.ts
425
+ var BooleanParser = class extends BaseParser {
426
+ constructor(options) {
427
+ super("boolean", options);
428
+ }
429
+ parse(text) {
430
+ assert(
431
+ typeof text === "string",
432
+ `Invalid input. Expected string. Received ${typeof text}.`
433
+ );
434
+ const clean = text.toLowerCase().trim();
435
+ if (clean === "true") {
436
+ return true;
437
+ }
438
+ return false;
439
+ }
440
+ };
441
+
442
+ // src/utils/modules/isFinite.ts
443
+ function isFinite(value) {
444
+ return typeof value === "number" && Number.isFinite(value);
445
+ }
446
+
447
+ // src/utils/modules/toNumber.ts
448
+ function toNumber(value) {
449
+ if (typeof value === "number") {
450
+ return value;
451
+ }
452
+ if (typeof value === "string" && value.trim() !== "") {
453
+ return Number(value);
454
+ }
455
+ return NaN;
456
+ }
457
+
458
+ // src/parser/parsers/NumberParser.ts
459
+ var NumberParser = class extends BaseParser {
460
+ constructor(options) {
461
+ super("number", options);
462
+ }
463
+ parse(text) {
464
+ const match = text.match(/\d/g);
465
+ return match && isFinite(toNumber(match[0])) ? toNumber(match[0]) : -1;
466
+ }
467
+ };
468
+
393
469
  // src/utils/index.ts
394
470
  var utils_exports = {};
395
471
  __export(utils_exports, {
@@ -409,19 +485,6 @@ __export(utils_exports, {
409
485
  replaceTemplateStringAsync: () => replaceTemplateStringAsync
410
486
  });
411
487
 
412
- // src/utils/modules/assert.ts
413
- function assert(condition, message) {
414
- if (condition === void 0 || condition === null || condition === false) {
415
- if (typeof message === "string") {
416
- throw new Error(message);
417
- } else if (message instanceof Error) {
418
- throw message;
419
- } else {
420
- throw new Error(`Assertion error`);
421
- }
422
- }
423
- }
424
-
425
488
  // src/utils/modules/defineSchema.ts
426
489
  var import_json_schema_to_ts = require("json-schema-to-ts");
427
490
  function defineSchema(obj) {
@@ -467,17 +530,6 @@ function importHelpers(_helpers) {
467
530
  return helpers;
468
531
  }
469
532
 
470
- // src/utils/modules/toNumber.ts
471
- function toNumber(value) {
472
- if (typeof value === "number") {
473
- return value;
474
- }
475
- if (typeof value === "string" && value.trim() !== "") {
476
- return Number(value);
477
- }
478
- return NaN;
479
- }
480
-
481
533
  // src/utils/modules/get.ts
482
534
  function get(obj, path, defaultValue) {
483
535
  if (obj == null || path === "" || Array.isArray(path) && path.length === 0) {
@@ -1377,82 +1429,6 @@ function registerPartials(partials2) {
1377
1429
  hbsAsync.registerPartials(partials2);
1378
1430
  }
1379
1431
 
1380
- // src/llm/output/_utils/getResultText.ts
1381
- function getResultText(content) {
1382
- if (content.length === 1 && content.every((a) => a.type === "text")) {
1383
- return content[0]?.text || "";
1384
- }
1385
- return "";
1386
- }
1387
-
1388
- // src/parser/parsers/OpenAiFunctionParser.ts
1389
- var OpenAiFunctionParser = class extends BaseParser {
1390
- constructor(options) {
1391
- super("openAiFunction", options, "function_call");
1392
- __publicField(this, "parser");
1393
- this.parser = options.parser;
1394
- }
1395
- parse(text, _options) {
1396
- const functionUse = text?.find((a) => a.type === "function_use");
1397
- if (functionUse && "name" in functionUse && "input" in functionUse) {
1398
- return {
1399
- name: functionUse.name,
1400
- arguments: maybeParseJSON(functionUse.input)
1401
- };
1402
- }
1403
- return this.parser.parse(getResultText(text));
1404
- }
1405
- };
1406
-
1407
- // src/parser/parsers/StringParser.ts
1408
- var StringParser = class extends BaseParser {
1409
- constructor(options) {
1410
- super("string", options);
1411
- }
1412
- parse(text, _options) {
1413
- assert(
1414
- typeof text === "string",
1415
- `Invalid input. Expected string. Received ${typeof text}.`
1416
- );
1417
- const parsed = text.toString();
1418
- return parsed;
1419
- }
1420
- };
1421
-
1422
- // src/parser/parsers/BooleanParser.ts
1423
- var BooleanParser = class extends BaseParser {
1424
- constructor(options) {
1425
- super("boolean", options);
1426
- }
1427
- parse(text) {
1428
- assert(
1429
- typeof text === "string",
1430
- `Invalid input. Expected string. Received ${typeof text}.`
1431
- );
1432
- const clean = text.toLowerCase().trim();
1433
- if (clean === "true") {
1434
- return true;
1435
- }
1436
- return false;
1437
- }
1438
- };
1439
-
1440
- // src/utils/modules/isFinite.ts
1441
- function isFinite(value) {
1442
- return typeof value === "number" && Number.isFinite(value);
1443
- }
1444
-
1445
- // src/parser/parsers/NumberParser.ts
1446
- var NumberParser = class extends BaseParser {
1447
- constructor(options) {
1448
- super("number", options);
1449
- }
1450
- parse(text) {
1451
- const match = text.match(/\d/g);
1452
- return match && isFinite(toNumber(match[0])) ? toNumber(match[0]) : -1;
1453
- }
1454
- };
1455
-
1456
1432
  // src/parser/_utils.ts
1457
1433
  var import_jsonschema = require("jsonschema");
1458
1434
  function enforceParserSchema(schema, parsed) {
@@ -1745,6 +1721,34 @@ function createCustomParser(name, parserFn) {
1745
1721
  return new CustomParser(name, parserFn);
1746
1722
  }
1747
1723
 
1724
+ // src/llm/output/_utils/getResultText.ts
1725
+ function getResultText(content) {
1726
+ if (content.length === 1 && content.every((a) => a.type === "text")) {
1727
+ return content[0]?.text || "";
1728
+ }
1729
+ return "";
1730
+ }
1731
+
1732
+ // src/parser/parsers/LlmNativeFunctionParser.ts
1733
+ var LlmNativeFunctionParser = class extends BaseParser {
1734
+ constructor(options) {
1735
+ super("openAiFunction", options, "function_call");
1736
+ __publicField(this, "parser");
1737
+ this.parser = options.parser;
1738
+ }
1739
+ parse(text, _options) {
1740
+ const functionUse = text?.find((a) => a.type === "function_use");
1741
+ if (functionUse && "name" in functionUse && "input" in functionUse) {
1742
+ return {
1743
+ name: functionUse.name,
1744
+ arguments: maybeParseJSON(functionUse.input)
1745
+ };
1746
+ }
1747
+ return this.parser.parse(getResultText(text));
1748
+ }
1749
+ };
1750
+ var OpenAiFunctionParser = LlmNativeFunctionParser;
1751
+
1748
1752
  // src/executor/llm.ts
1749
1753
  var LlmExecutor = class extends BaseExecutor {
1750
1754
  constructor(llmConfiguration, options) {
@@ -1820,20 +1824,12 @@ var LlmExecutor = class extends BaseExecutor {
1820
1824
  }
1821
1825
  };
1822
1826
 
1823
- // src/executor/_functions.ts
1824
- function createCoreExecutor(handler, options) {
1825
- return new CoreExecutor({ handler }, options);
1826
- }
1827
- function createLlmExecutor(llmConfiguration, options) {
1828
- return new LlmExecutor(llmConfiguration, options);
1829
- }
1830
-
1831
1827
  // src/executor/llm-openai-function.ts
1832
- var LlmExecutorOpenAiFunctions = class extends LlmExecutor {
1828
+ var LlmExecutorWithFunctions = class extends LlmExecutor {
1833
1829
  constructor(llmConfiguration, options) {
1834
1830
  super(
1835
1831
  Object.assign({}, llmConfiguration, {
1836
- parser: new OpenAiFunctionParser({
1832
+ parser: new LlmNativeFunctionParser({
1837
1833
  parser: llmConfiguration.parser || new StringParser()
1838
1834
  })
1839
1835
  }),
@@ -1844,6 +1840,22 @@ var LlmExecutorOpenAiFunctions = class extends LlmExecutor {
1844
1840
  return super.execute(_input, _options);
1845
1841
  }
1846
1842
  };
1843
+ var LlmExecutorOpenAiFunctions = class extends LlmExecutorWithFunctions {
1844
+ };
1845
+
1846
+ // src/executor/_functions.ts
1847
+ function createCoreExecutor(handler, options) {
1848
+ return new CoreExecutor({ handler }, options);
1849
+ }
1850
+ function createLlmExecutor(llmConfiguration, options) {
1851
+ return new LlmExecutor(llmConfiguration, options);
1852
+ }
1853
+ function createLlmFunctionExecutor(llmConfiguration, options) {
1854
+ return new LlmExecutorWithFunctions(
1855
+ llmConfiguration,
1856
+ options
1857
+ );
1858
+ }
1847
1859
 
1848
1860
  // src/utils/modules/enforceResultAttributes.ts
1849
1861
  function enforceResultAttributes(input) {
@@ -3134,11 +3146,20 @@ async function parseHeaders(config, replacements, payload) {
3134
3146
 
3135
3147
  // src/llm/output/_utils/cleanJsonSchemaFor.ts
3136
3148
  var providerFieldExclusions = {
3137
- "openai.chat": ["default"]
3149
+ "openai.chat": ["default"],
3150
+ // fields to exclude for openai.chat
3151
+ "anthropic.chat": []
3138
3152
  // fields to exclude for openai.chat
3139
3153
  };
3140
3154
  function cleanJsonSchemaFor(schema = {}, provider) {
3141
3155
  const clone = deepClone(schema);
3156
+ if (Object.keys(clone).length === 0) {
3157
+ return {
3158
+ type: "object",
3159
+ properties: {},
3160
+ required: []
3161
+ };
3162
+ }
3142
3163
  const exclusions = providerFieldExclusions[provider] || [];
3143
3164
  function removeDisallowedFields(obj) {
3144
3165
  if (Array.isArray(obj)) {
@@ -3167,7 +3188,7 @@ async function useLlm_call(state, messages, _options) {
3167
3188
  })
3168
3189
  );
3169
3190
  if (_options && _options?.jsonSchema) {
3170
- if (state.provider === "openai.chat") {
3191
+ if (state.provider.startsWith("openai")) {
3171
3192
  const curr = input["response_format"] || {};
3172
3193
  input["response_format"] = Object.assign(curr, {
3173
3194
  type: "json_schema",
@@ -3180,7 +3201,7 @@ async function useLlm_call(state, messages, _options) {
3180
3201
  }
3181
3202
  }
3182
3203
  if (_options && _options?.functionCall) {
3183
- if (state.provider === "anthropic.chat") {
3204
+ if (state.provider.startsWith("anthropic")) {
3184
3205
  if (_options?.functionCall === "none") {
3185
3206
  _options.functions = [];
3186
3207
  } else if (_options?.functionCall === "auto" || _options?.functionCall === "any") {
@@ -3188,7 +3209,7 @@ async function useLlm_call(state, messages, _options) {
3188
3209
  } else {
3189
3210
  input["tool_choice"] = _options?.functionCall;
3190
3211
  }
3191
- } else if (state.provider === "openai.chat") {
3212
+ } else if (state.provider.startsWith("openai")) {
3192
3213
  input["tool_choice"] = normalizeFunctionCall(
3193
3214
  _options?.functionCall,
3194
3215
  "openai"
@@ -3196,13 +3217,13 @@ async function useLlm_call(state, messages, _options) {
3196
3217
  }
3197
3218
  }
3198
3219
  if (_options && _options?.functions?.length) {
3199
- if (state.provider === "anthropic.chat") {
3220
+ if (state.provider.startsWith("anthropic")) {
3200
3221
  input["tools"] = _options.functions.map((f) => ({
3201
3222
  name: f.name,
3202
3223
  description: f.description,
3203
- input_schema: f.parameters
3224
+ input_schema: cleanJsonSchemaFor(f.parameters, "anthropic.chat")
3204
3225
  }));
3205
- } else if (state.provider === "openai.chat") {
3226
+ } else if (state.provider.startsWith("openai")) {
3206
3227
  input["tools"] = _options.functions.map((f) => {
3207
3228
  const props = {
3208
3229
  name: f?.name,
@@ -4448,6 +4469,12 @@ var Dialogue = class extends BaseStateItem {
4448
4469
  return this;
4449
4470
  }
4450
4471
  setFunctionCallMessage(input) {
4472
+ if (!input?.function_call) {
4473
+ throw new LlmExeError(`Invalid arguments`, "state", {
4474
+ error: `Invalid arguments: missing required function_call`,
4475
+ module: "dialogue"
4476
+ });
4477
+ }
4451
4478
  this.value.push({
4452
4479
  role: "assistant",
4453
4480
  function_call: {
@@ -4607,6 +4634,8 @@ function createStateItem(name, defaultValue) {
4607
4634
  DefaultState,
4608
4635
  DefaultStateItem,
4609
4636
  LlmExecutorOpenAiFunctions,
4637
+ LlmExecutorWithFunctions,
4638
+ LlmNativeFunctionParser,
4610
4639
  OpenAiFunctionParser,
4611
4640
  TextPrompt,
4612
4641
  createCallableExecutor,
@@ -4616,6 +4645,7 @@ function createStateItem(name, defaultValue) {
4616
4645
  createDialogue,
4617
4646
  createEmbedding,
4618
4647
  createLlmExecutor,
4648
+ createLlmFunctionExecutor,
4619
4649
  createParser,
4620
4650
  createPrompt,
4621
4651
  createState,
package/dist/index.mjs CHANGED
@@ -333,6 +333,79 @@ var BaseParserWithJson = class extends BaseParser {
333
333
  }
334
334
  };
335
335
 
336
+ // src/utils/modules/assert.ts
337
+ function assert(condition, message) {
338
+ if (condition === void 0 || condition === null || condition === false) {
339
+ if (typeof message === "string") {
340
+ throw new Error(message);
341
+ } else if (message instanceof Error) {
342
+ throw message;
343
+ } else {
344
+ throw new Error(`Assertion error`);
345
+ }
346
+ }
347
+ }
348
+
349
+ // src/parser/parsers/StringParser.ts
350
+ var StringParser = class extends BaseParser {
351
+ constructor(options) {
352
+ super("string", options);
353
+ }
354
+ parse(text, _options) {
355
+ assert(
356
+ typeof text === "string",
357
+ `Invalid input. Expected string. Received ${typeof text}.`
358
+ );
359
+ const parsed = text.toString();
360
+ return parsed;
361
+ }
362
+ };
363
+
364
+ // src/parser/parsers/BooleanParser.ts
365
+ var BooleanParser = class extends BaseParser {
366
+ constructor(options) {
367
+ super("boolean", options);
368
+ }
369
+ parse(text) {
370
+ assert(
371
+ typeof text === "string",
372
+ `Invalid input. Expected string. Received ${typeof text}.`
373
+ );
374
+ const clean = text.toLowerCase().trim();
375
+ if (clean === "true") {
376
+ return true;
377
+ }
378
+ return false;
379
+ }
380
+ };
381
+
382
+ // src/utils/modules/isFinite.ts
383
+ function isFinite(value) {
384
+ return typeof value === "number" && Number.isFinite(value);
385
+ }
386
+
387
+ // src/utils/modules/toNumber.ts
388
+ function toNumber(value) {
389
+ if (typeof value === "number") {
390
+ return value;
391
+ }
392
+ if (typeof value === "string" && value.trim() !== "") {
393
+ return Number(value);
394
+ }
395
+ return NaN;
396
+ }
397
+
398
+ // src/parser/parsers/NumberParser.ts
399
+ var NumberParser = class extends BaseParser {
400
+ constructor(options) {
401
+ super("number", options);
402
+ }
403
+ parse(text) {
404
+ const match = text.match(/\d/g);
405
+ return match && isFinite(toNumber(match[0])) ? toNumber(match[0]) : -1;
406
+ }
407
+ };
408
+
336
409
  // src/utils/index.ts
337
410
  var utils_exports = {};
338
411
  __export(utils_exports, {
@@ -352,19 +425,6 @@ __export(utils_exports, {
352
425
  replaceTemplateStringAsync: () => replaceTemplateStringAsync
353
426
  });
354
427
 
355
- // src/utils/modules/assert.ts
356
- function assert(condition, message) {
357
- if (condition === void 0 || condition === null || condition === false) {
358
- if (typeof message === "string") {
359
- throw new Error(message);
360
- } else if (message instanceof Error) {
361
- throw message;
362
- } else {
363
- throw new Error(`Assertion error`);
364
- }
365
- }
366
- }
367
-
368
428
  // src/utils/modules/defineSchema.ts
369
429
  import { asConst } from "json-schema-to-ts";
370
430
  function defineSchema(obj) {
@@ -410,17 +470,6 @@ function importHelpers(_helpers) {
410
470
  return helpers;
411
471
  }
412
472
 
413
- // src/utils/modules/toNumber.ts
414
- function toNumber(value) {
415
- if (typeof value === "number") {
416
- return value;
417
- }
418
- if (typeof value === "string" && value.trim() !== "") {
419
- return Number(value);
420
- }
421
- return NaN;
422
- }
423
-
424
473
  // src/utils/modules/get.ts
425
474
  function get(obj, path, defaultValue) {
426
475
  if (obj == null || path === "" || Array.isArray(path) && path.length === 0) {
@@ -1320,82 +1369,6 @@ function registerPartials(partials2) {
1320
1369
  hbsAsync.registerPartials(partials2);
1321
1370
  }
1322
1371
 
1323
- // src/llm/output/_utils/getResultText.ts
1324
- function getResultText(content) {
1325
- if (content.length === 1 && content.every((a) => a.type === "text")) {
1326
- return content[0]?.text || "";
1327
- }
1328
- return "";
1329
- }
1330
-
1331
- // src/parser/parsers/OpenAiFunctionParser.ts
1332
- var OpenAiFunctionParser = class extends BaseParser {
1333
- constructor(options) {
1334
- super("openAiFunction", options, "function_call");
1335
- __publicField(this, "parser");
1336
- this.parser = options.parser;
1337
- }
1338
- parse(text, _options) {
1339
- const functionUse = text?.find((a) => a.type === "function_use");
1340
- if (functionUse && "name" in functionUse && "input" in functionUse) {
1341
- return {
1342
- name: functionUse.name,
1343
- arguments: maybeParseJSON(functionUse.input)
1344
- };
1345
- }
1346
- return this.parser.parse(getResultText(text));
1347
- }
1348
- };
1349
-
1350
- // src/parser/parsers/StringParser.ts
1351
- var StringParser = class extends BaseParser {
1352
- constructor(options) {
1353
- super("string", options);
1354
- }
1355
- parse(text, _options) {
1356
- assert(
1357
- typeof text === "string",
1358
- `Invalid input. Expected string. Received ${typeof text}.`
1359
- );
1360
- const parsed = text.toString();
1361
- return parsed;
1362
- }
1363
- };
1364
-
1365
- // src/parser/parsers/BooleanParser.ts
1366
- var BooleanParser = class extends BaseParser {
1367
- constructor(options) {
1368
- super("boolean", options);
1369
- }
1370
- parse(text) {
1371
- assert(
1372
- typeof text === "string",
1373
- `Invalid input. Expected string. Received ${typeof text}.`
1374
- );
1375
- const clean = text.toLowerCase().trim();
1376
- if (clean === "true") {
1377
- return true;
1378
- }
1379
- return false;
1380
- }
1381
- };
1382
-
1383
- // src/utils/modules/isFinite.ts
1384
- function isFinite(value) {
1385
- return typeof value === "number" && Number.isFinite(value);
1386
- }
1387
-
1388
- // src/parser/parsers/NumberParser.ts
1389
- var NumberParser = class extends BaseParser {
1390
- constructor(options) {
1391
- super("number", options);
1392
- }
1393
- parse(text) {
1394
- const match = text.match(/\d/g);
1395
- return match && isFinite(toNumber(match[0])) ? toNumber(match[0]) : -1;
1396
- }
1397
- };
1398
-
1399
1372
  // src/parser/_utils.ts
1400
1373
  import { validate as validateSchema } from "jsonschema";
1401
1374
  function enforceParserSchema(schema, parsed) {
@@ -1688,6 +1661,34 @@ function createCustomParser(name, parserFn) {
1688
1661
  return new CustomParser(name, parserFn);
1689
1662
  }
1690
1663
 
1664
+ // src/llm/output/_utils/getResultText.ts
1665
+ function getResultText(content) {
1666
+ if (content.length === 1 && content.every((a) => a.type === "text")) {
1667
+ return content[0]?.text || "";
1668
+ }
1669
+ return "";
1670
+ }
1671
+
1672
+ // src/parser/parsers/LlmNativeFunctionParser.ts
1673
+ var LlmNativeFunctionParser = class extends BaseParser {
1674
+ constructor(options) {
1675
+ super("openAiFunction", options, "function_call");
1676
+ __publicField(this, "parser");
1677
+ this.parser = options.parser;
1678
+ }
1679
+ parse(text, _options) {
1680
+ const functionUse = text?.find((a) => a.type === "function_use");
1681
+ if (functionUse && "name" in functionUse && "input" in functionUse) {
1682
+ return {
1683
+ name: functionUse.name,
1684
+ arguments: maybeParseJSON(functionUse.input)
1685
+ };
1686
+ }
1687
+ return this.parser.parse(getResultText(text));
1688
+ }
1689
+ };
1690
+ var OpenAiFunctionParser = LlmNativeFunctionParser;
1691
+
1691
1692
  // src/executor/llm.ts
1692
1693
  var LlmExecutor = class extends BaseExecutor {
1693
1694
  constructor(llmConfiguration, options) {
@@ -1763,20 +1764,12 @@ var LlmExecutor = class extends BaseExecutor {
1763
1764
  }
1764
1765
  };
1765
1766
 
1766
- // src/executor/_functions.ts
1767
- function createCoreExecutor(handler, options) {
1768
- return new CoreExecutor({ handler }, options);
1769
- }
1770
- function createLlmExecutor(llmConfiguration, options) {
1771
- return new LlmExecutor(llmConfiguration, options);
1772
- }
1773
-
1774
1767
  // src/executor/llm-openai-function.ts
1775
- var LlmExecutorOpenAiFunctions = class extends LlmExecutor {
1768
+ var LlmExecutorWithFunctions = class extends LlmExecutor {
1776
1769
  constructor(llmConfiguration, options) {
1777
1770
  super(
1778
1771
  Object.assign({}, llmConfiguration, {
1779
- parser: new OpenAiFunctionParser({
1772
+ parser: new LlmNativeFunctionParser({
1780
1773
  parser: llmConfiguration.parser || new StringParser()
1781
1774
  })
1782
1775
  }),
@@ -1787,6 +1780,22 @@ var LlmExecutorOpenAiFunctions = class extends LlmExecutor {
1787
1780
  return super.execute(_input, _options);
1788
1781
  }
1789
1782
  };
1783
+ var LlmExecutorOpenAiFunctions = class extends LlmExecutorWithFunctions {
1784
+ };
1785
+
1786
+ // src/executor/_functions.ts
1787
+ function createCoreExecutor(handler, options) {
1788
+ return new CoreExecutor({ handler }, options);
1789
+ }
1790
+ function createLlmExecutor(llmConfiguration, options) {
1791
+ return new LlmExecutor(llmConfiguration, options);
1792
+ }
1793
+ function createLlmFunctionExecutor(llmConfiguration, options) {
1794
+ return new LlmExecutorWithFunctions(
1795
+ llmConfiguration,
1796
+ options
1797
+ );
1798
+ }
1790
1799
 
1791
1800
  // src/utils/modules/enforceResultAttributes.ts
1792
1801
  function enforceResultAttributes(input) {
@@ -3077,11 +3086,20 @@ async function parseHeaders(config, replacements, payload) {
3077
3086
 
3078
3087
  // src/llm/output/_utils/cleanJsonSchemaFor.ts
3079
3088
  var providerFieldExclusions = {
3080
- "openai.chat": ["default"]
3089
+ "openai.chat": ["default"],
3090
+ // fields to exclude for openai.chat
3091
+ "anthropic.chat": []
3081
3092
  // fields to exclude for openai.chat
3082
3093
  };
3083
3094
  function cleanJsonSchemaFor(schema = {}, provider) {
3084
3095
  const clone = deepClone(schema);
3096
+ if (Object.keys(clone).length === 0) {
3097
+ return {
3098
+ type: "object",
3099
+ properties: {},
3100
+ required: []
3101
+ };
3102
+ }
3085
3103
  const exclusions = providerFieldExclusions[provider] || [];
3086
3104
  function removeDisallowedFields(obj) {
3087
3105
  if (Array.isArray(obj)) {
@@ -3110,7 +3128,7 @@ async function useLlm_call(state, messages, _options) {
3110
3128
  })
3111
3129
  );
3112
3130
  if (_options && _options?.jsonSchema) {
3113
- if (state.provider === "openai.chat") {
3131
+ if (state.provider.startsWith("openai")) {
3114
3132
  const curr = input["response_format"] || {};
3115
3133
  input["response_format"] = Object.assign(curr, {
3116
3134
  type: "json_schema",
@@ -3123,7 +3141,7 @@ async function useLlm_call(state, messages, _options) {
3123
3141
  }
3124
3142
  }
3125
3143
  if (_options && _options?.functionCall) {
3126
- if (state.provider === "anthropic.chat") {
3144
+ if (state.provider.startsWith("anthropic")) {
3127
3145
  if (_options?.functionCall === "none") {
3128
3146
  _options.functions = [];
3129
3147
  } else if (_options?.functionCall === "auto" || _options?.functionCall === "any") {
@@ -3131,7 +3149,7 @@ async function useLlm_call(state, messages, _options) {
3131
3149
  } else {
3132
3150
  input["tool_choice"] = _options?.functionCall;
3133
3151
  }
3134
- } else if (state.provider === "openai.chat") {
3152
+ } else if (state.provider.startsWith("openai")) {
3135
3153
  input["tool_choice"] = normalizeFunctionCall(
3136
3154
  _options?.functionCall,
3137
3155
  "openai"
@@ -3139,13 +3157,13 @@ async function useLlm_call(state, messages, _options) {
3139
3157
  }
3140
3158
  }
3141
3159
  if (_options && _options?.functions?.length) {
3142
- if (state.provider === "anthropic.chat") {
3160
+ if (state.provider.startsWith("anthropic")) {
3143
3161
  input["tools"] = _options.functions.map((f) => ({
3144
3162
  name: f.name,
3145
3163
  description: f.description,
3146
- input_schema: f.parameters
3164
+ input_schema: cleanJsonSchemaFor(f.parameters, "anthropic.chat")
3147
3165
  }));
3148
- } else if (state.provider === "openai.chat") {
3166
+ } else if (state.provider.startsWith("openai")) {
3149
3167
  input["tools"] = _options.functions.map((f) => {
3150
3168
  const props = {
3151
3169
  name: f?.name,
@@ -4391,6 +4409,12 @@ var Dialogue = class extends BaseStateItem {
4391
4409
  return this;
4392
4410
  }
4393
4411
  setFunctionCallMessage(input) {
4412
+ if (!input?.function_call) {
4413
+ throw new LlmExeError(`Invalid arguments`, "state", {
4414
+ error: `Invalid arguments: missing required function_call`,
4415
+ module: "dialogue"
4416
+ });
4417
+ }
4394
4418
  this.value.push({
4395
4419
  role: "assistant",
4396
4420
  function_call: {
@@ -4549,6 +4573,8 @@ export {
4549
4573
  DefaultState,
4550
4574
  DefaultStateItem,
4551
4575
  LlmExecutorOpenAiFunctions,
4576
+ LlmExecutorWithFunctions,
4577
+ LlmNativeFunctionParser,
4552
4578
  OpenAiFunctionParser,
4553
4579
  TextPrompt,
4554
4580
  createCallableExecutor,
@@ -4558,6 +4584,7 @@ export {
4558
4584
  createDialogue,
4559
4585
  createEmbedding,
4560
4586
  createLlmExecutor,
4587
+ createLlmFunctionExecutor,
4561
4588
  createParser,
4562
4589
  createPrompt,
4563
4590
  createState,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "llm-exe",
3
- "version": "2.2.0",
3
+ "version": "2.2.1",
4
4
  "description": "Simplify building LLM-powered apps with easy-to-use base components, supporting text and chat-based prompts with handlebars template engine, output parsers, and flexible function calling capabilities.",
5
5
  "keywords": [
6
6
  "ai",
@@ -38,7 +38,8 @@
38
38
  "typecheck": "tsc --noEmit",
39
39
  "test": "NODE_OPTIONS=--experimental-vm-modules jest --config jest.config.ts --detectOpenHandles --coverage --forceExit",
40
40
  "test-examples": "eval $(cat .env) NODE_OPTIONS=--experimental-vm-modules jest --config jest.config.examples.ts --detectOpenHandles --coverage --forceExit",
41
- "test-one": "eval $(cat .env) NODE_OPTIONS=--experimental-vm-modules jest --detectOpenHandles --coverage --forceExit --config jest.config.examples.ts examples/helloWorldReasoning.test.ts",
41
+ "test-one": "eval $(cat .env) NODE_OPTIONS=--experimental-vm-modules jest --detectOpenHandles --coverage --forceExit --config jest.config.examples.ts examples/intentBot.test.ts",
42
+ "run-one": "eval $(cat .env) ts-node ./examples/chains/self-refinement/usage.ts",
42
43
  "build": "(concurrently \"tsc --p ./tsconfig.json -w\" \"tsc-alias -p tsconfig.json -w\")",
43
44
  "build:ci": "tsup src/index.ts --format cjs,esm --dts --clean",
44
45
  "build:browser": "tsup src/script.ts --format iife --platform browser --target es6 --sourcemap --clean --external '**'",
@@ -46,8 +47,8 @@
46
47
  "build:docs-examples": "./node_modules/.bin/esbuild examples/prompt/index.ts examples/state/index.ts --bundle --outdir=docs/.vitepress/components/examples --platform=node --target=es6 --format=esm",
47
48
  "build:watch:docs-examples": "./node_modules/.bin/esbuild examples/prompt/index.ts examples/state/index.ts --watch --bundle --outdir=docs/.vitepress/components/examples --platform=node --target=es6 --format=esm",
48
49
  "predocs:build": "npm run build:docs-examples",
49
- "docs:dev": "(concurrently \"vitepress dev docs\" \"npm run build:watch:docs-examples\")",
50
- "docs:build": "vitepress build docs",
50
+ "docs:dev": "eval $(cat docs/.env) && concurrently \"vitepress dev docs\" \"npm run build:watch:docs-examples\"",
51
+ "docs:build": "eval $(cat docs/.env) && vitepress build docs",
51
52
  "lint": "eslint .",
52
53
  "format:check": "prettier --check \"src\"",
53
54
  "format:write": "prettier --write \"src\"",
@@ -88,7 +89,7 @@
88
89
  "tsconfig-paths": "4.2.0",
89
90
  "tsup": "^8.4.0",
90
91
  "typescript": "5.8.3",
91
- "vitepress": "^1.3.2"
92
+ "vitepress": "^1.6.3"
92
93
  },
93
94
  "repository": {
94
95
  "type": "git",
package/readme.md CHANGED
@@ -6,81 +6,151 @@ A package that provides simplified base components to make building and maintain
6
6
 
7
7
  - Write functions powered by LLM's with easy to use building blocks.
8
8
  - Pure Javascript and Typescript. Allows you to pass and infer types.
9
+ - Supercharge your prompts by using handlebars within prompt template.
9
10
  - Support for text-based (llama-3) and chat-based prompts. (gpt-4o, claude-3.5, grok-3, Gemini, Bedrock, Ollama, etc)
10
11
  - Call LLM's from different providers without changing your code. (OpenAi/Anthropic/xAI/Google/AWS Bedrock/Ollama/Deepseek)
11
- - Supercharge your prompts by using handlebars within prompt template.
12
12
  - Allow LLM's to call functions (or call other LLM executors).
13
13
  - Not very opinionated. You have control on how you use it.
14
14
 
15
- ![llm-exe](https://assets.llm-exe.com/llm-exe-featured.jpg)
16
-
15
+ ![llm-exe](https://assets.llm-exe.com/llm-exe-featured-2025.png)
17
16
 
18
17
  See full docs here: [https://llm-exe.com](https://llm-exe.com)
19
18
 
20
-
21
19
  ---
20
+
22
21
  # Install
23
22
 
24
23
  Install llm-exe using npm.
24
+
25
25
  ```
26
26
  npm i llm-exe
27
27
  ```
28
28
 
29
+ ESM-first. CommonJS works too.
30
+
29
31
  ```typescript
32
+ // ESM
30
33
  import * as llmExe from "llm-exe";
34
+ // or specific modules
35
+ import { useLlm, createChatPrompt, createParser } from "llm-exe";
36
+
37
+ // CommonJS
38
+ const llmExe = require("llm-exe");
39
+ ```
31
40
 
32
- // or
41
+ ## Overview
33
42
 
34
- import { /* specific modules */ } from from "llm-exe"
43
+ ```ts
44
+ // Prompt
45
+ const prompt = createChatPrompt("You are a support agent. Help the user.");
46
+ prompt.addUserMessage("I need help with my order.");
47
+
48
+ // LLM
49
+ const llm = useLlm("openai.gpt-4o");
50
+
51
+ // Parser
52
+ const parser = createParser("json", { schema: mySchema });
53
+
54
+ // Executor
55
+ const executor = createLlmExecutor({ llm, prompt, parser });
56
+ await executor.execute({ input: "..." });
57
+ ```
58
+
59
+ #### Prompt Helpers
60
+
61
+ ```ts
62
+ const prompt = createChatPrompt(`
63
+ {{#if user.isFirstTime}}
64
+ Welcome!
65
+ {{else}}
66
+ Welcome back!
67
+ {{/if}}
68
+ `);
69
+ ```
70
+
71
+ #### Built-In Parsers
72
+
73
+ ```ts
74
+ createParser("stringExtract", { enum: ["yes", "no"] });
75
+ createParser("listToJson");
76
+ createParser("listToArray");
77
+ createParser("markdownCodeBlock");
78
+ // ...etc
79
+ ```
80
+
81
+ #### Custom Parsers
82
+
83
+ ```ts
84
+ const parser = createCustomParser("MyUppercaseParser", (output, input) => {
85
+ return output.toUpperCase();
86
+ });
87
+ ```
88
+
89
+ #### State
90
+
91
+ ```ts
92
+ const dialogue = createDialogue("chat");
93
+ dialogue.setUserMessage("Hi");
94
+ dialogue.setAssistantMessage("Hello!");
95
+ dialogue.getHistory(); // returns chat array
96
+ ```
97
+
98
+ #### Hooks
99
+
100
+ ```ts
101
+ executor.on("onSuccess", console.log);
102
+ executor.on("onError", console.error);
35
103
  ```
36
104
 
37
105
  ## Basic Example
106
+
38
107
  Below is simple example:
108
+
39
109
  ```typescript
40
- import * as llmExe from "llm-exe";
110
+ // 1. Use the model you want
111
+ const llm = useLlm("openai.gpt-4o");
112
+
113
+ // 2. Create a parameterized prompt
114
+ const instruction = `
115
+ You are a classifier. Given a user message, reply with the category it belongs to.
116
+ Pick from only the following options:
117
+
118
+ {{#each options}}- {{this}}
119
+ {{/each}}
120
+
121
+ Respond with only one of the options.`;
122
+
123
+ const prompt = createChatPrompt<{ options: string[]; input: string }>(
124
+ instruction
125
+ ).addUserMessage("{{input}}"); // placeholder for message content
126
+
127
+ // 3. Create a parser that ensures a clean match
128
+ const parser = createParser("stringExtract", {
129
+ enum: ["billing", "support", "cancel", "unknown"],
130
+ });
131
+
132
+ // 4. Create the executor
133
+ const classifyMessage = createLlmExecutor({
134
+ llm,
135
+ prompt,
136
+ parser,
137
+ });
138
+
139
+ // 5. Pass in options and a message — like a real function!
140
+ // classifyMessage.execute is typed based on the prompt/parser!
141
+ const result = await classifyMessage.execute({
142
+ input: "Hi, I'm moving and no longer need this service.",
143
+ options: ["billing", "support", "cancel", "unknown"],
144
+ });
145
+
146
+ console.log(result); // => "cancel"
147
+ ```
148
+
149
+ ### Further Reading
150
+
151
+ [Find llm-exe on Medium](https://medium.com/llm-exe)
41
152
 
42
- /**
43
- * Define a yes/no llm-powered function
44
- */
45
- export async function YesOrNoBot<I extends string>(input: I) {
46
- const llm = llmExe.useLlm("openai.gpt-4o-mini");
47
-
48
- const instruction = `You are not an assistant, I need you to reply with only
49
- 'yes' or 'no' as an answer to the question below. Do not explain yourself
50
- or ask questions. Answer with only yes or no.`;
51
-
52
- const prompt = llmExe
53
- .createChatPrompt(instruction)
54
- .addUserMessage(input)
55
- .addUserMessage(`yes or no:`);
56
-
57
- const parser = llmExe.createParser("stringExtract", { enum: ["yes", "no"] });
58
- return llmExe.createLlmExecutor({ llm, prompt, parser }).execute({ input });
59
- }
60
-
61
- const isTheSkyBlue = await YesOrNoBot(`Is AI cool?`)
62
-
63
- /**
64
- *
65
- * The prompt sent to the LLM would be:
66
- * (line breaks added for readability)
67
- *
68
- * [{
69
- * role: 'system',
70
- * content: 'You are not an assistant, I need you to reply with only
71
- 'yes' or 'no' as an answer to the question asked by the user. Do not explain yourself
72
- or ask questions. Answer only with yes or no.'
73
- * },
74
- * {
75
- * role: 'user',
76
- * content: 'Is AI cool?'
77
- * }]
78
- *
79
- */
80
-
81
- /**
82
- *
83
- * console.log(isTheSkyBlue)
84
- * yes
85
- * /
86
- ```
153
+ - [Prompt: Create Typed, Modular Prompt Templates in TypeScript](https://medium.com/llm-exe/llm-exe-intro-prompt-3d9d40dc923d)
154
+ - [LLM: Keep Your Code Clean While Switching Models](https://medium.com/llm-exe/llm-exe-intro-llm-2f5f35e60caf)
155
+ - [Parser: Parse, Validate, and Structure AI Responses](https://medium.com/llm-exe/llm-exe-intro-parser-aed787f81082)
156
+ - [Executor: Prompt, Parse, and Execute with Type Safety](https://medium.com/llm-exe/llm-exe-intro-llm-executor-52bb95c76c84)