booths 0.1.3 → 1.1.0

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/README.md CHANGED
@@ -10,12 +10,11 @@ The Booths framework is built around a few key concepts that work together to cr
10
10
 
11
11
  ```mermaid
12
12
  graph TD
13
- subgraph User Interface
14
- A[Vue.js Component]
13
+ subgraph Application Layer
14
+ A[Your Application]
15
15
  end
16
16
 
17
17
  subgraph Booth Service Layer
18
- B(useLLMService)
19
18
  C(CoreBooth)
20
19
  end
21
20
 
@@ -26,8 +25,7 @@ graph TD
26
25
  G[Plugins]
27
26
  end
28
27
 
29
- A -- "sends user input" --> B
30
- B -- "initializes and calls" --> C
28
+ A -- "initializes and calls" --> C
31
29
  C -- "delegates to" --> D
32
30
  D -- "uses" --> E
33
31
  D -- "uses" --> F
@@ -38,57 +36,47 @@ graph TD
38
36
  F -- "manages" --> K{Plugins}
39
37
  G -- "hook into" --> D
40
38
 
41
- style B fill:#f9f,stroke:#333,stroke-width:2px
42
39
  style C fill:#f9f,stroke:#333,stroke-width:2px
43
40
  ```
44
41
 
45
- 1. **User Interface**: A frontend application (e.g., a Vue component) captures user input and displays the conversation.
46
- 2. **Service Layer (`useLLMService.ts`)**: This layer acts as a bridge between the UI and the Booths engine. It initializes the `CoreBooth`, manages the conversational state, and exposes methods for sending messages.
47
- 3. **`CoreBooth`**: The central orchestrator of the system. It is configured with an `LLMAdapter`, and a set of registries for booths, tools, and plugins.
48
- 4. **`InteractionProcessor`**: The engine that drives the conversation. It takes user input, runs it through the plugin lifecycle, sends it to the LLM (via the adapter), and processes the response.
49
- 5. **`LLMAdapter`**: A component that handles communication with the specific LLM provider (e.g., OpenAI). It translates requests and responses between the Booths system and the LLM's API.
50
- 6. **Registries**: These are responsible for managing the different components of the system:
42
+ 1. **Application Layer**: Your application integrates the Booths framework to handle conversational AI interactions.
43
+ 2. **`CoreBooth`**: The framework foundation that provides global functionality, instructions, and infrastructure that applies to all booths. It manages the overall system configuration and coordinates the interaction flow.
44
+ 3. **`InteractionProcessor`**: The engine that drives the conversation. It takes user input, runs it through the plugin lifecycle, sends it to the LLM (via the adapter), and processes the response.
45
+ 4. **`LLMAdapter`**: A component that handles communication with the specific LLM provider (e.g., OpenAI). It translates requests and responses between the Booths system and the LLM's API.
46
+ 5. **Registries**: These are responsible for managing the different components of the system:
51
47
  * `BoothRegistry`: Manages `BoothConfig` objects that define the behavior of different AI agents.
52
48
  * `ToolRegistry`: Manages the tools (functions) that booths can use.
53
49
  * `BoothPluginRegistry`: Manages the plugins that hook into the conversational lifecycle.
54
- 7. **Plugins**: These are modules that add functionality to the system by hooking into the `InteractionProcessor`'s lifecycle (e.g., managing conversation history, providing context to the LLM, executing tools).
50
+ 6. **Plugins**: These are modules that add functionality to the system by hooking into the `InteractionProcessor`'s lifecycle (e.g., managing conversation history, providing context to the LLM, executing tools).
55
51
 
56
- ## Running the Examples
52
+ ## Getting Started
57
53
 
58
- The best way to understand the Booths framework is to run the example application provided in the `src/examples` directory.
54
+ The Booths framework is designed as a TypeScript library for building conversational AI systems. This repository contains the core framework implementation.
59
55
 
60
- ### Prerequisites
56
+ ### Installation
61
57
 
62
- - Node.js and npm installed.
63
- - An OpenAI API key.
58
+ ```bash
59
+ npm install booths
60
+ ```
64
61
 
65
- ### Setup
62
+ ### Prerequisites
66
63
 
67
- 1. **Clone the repository:**
68
- ```bash
69
- git clone <repository-url>
70
- cd booths
71
- ```
64
+ - Node.js and npm installed
65
+ - An LLM provider API key (e.g., OpenAI)
72
66
 
73
- 2. **Install dependencies:**
74
- ```bash
75
- npm install
76
- ```
67
+ ### Development
77
68
 
78
- 3. **Set up your environment variables:**
79
- Create a `.env.local` file in the root of the project and add your OpenAI API key:
80
- ```
81
- VITE_OPENAI_API_KEY=your-openai-api-key
82
- ```
69
+ To build the library:
83
70
 
84
- 4. **Run the application:**
85
- ```bash
86
- npm run dev
87
- ```
71
+ ```bash
72
+ npm run build
73
+ ```
88
74
 
89
- This will start a local development server. Open your browser to the specified address (usually `http://localhost:5173`) to see the chat application in action.
75
+ To check types:
90
76
 
91
- The example application features a collection of pirate-themed booths that demonstrate how to create and manage different conversational agents. You can interact with a "Sea Lore" booth, a "Shipwright" booth, and even a "Duel" booth.
77
+ ```bash
78
+ npm run typecheck
79
+ ```
92
80
 
93
81
  ## Quick Start Guide
94
82
 
@@ -135,18 +123,18 @@ export const tellPirateJokeTool: ToolModule = {
135
123
  The `CoreBooth` requires an `LLMAdapter` to communicate with your chosen language model. Here is a minimal example for OpenAI.
136
124
 
137
125
  ```typescript
138
- // in openAIAdapter.ts
126
+ // in OpenAIAdapter.ts
139
127
  import type { LLMAdapter, ResponseCreateParamsNonStreaming, Response } from 'booths';
140
- import openai from 'openai';
128
+ import OpenAI from 'openai';
141
129
 
142
- export class OpenAIAdapter implements LLMAdapter<any> {
143
- openai: openai;
130
+ export class OpenAIAdapter implements LLMAdapter<Response> {
131
+ private openai: OpenAI;
144
132
 
145
133
  constructor(apiKey: string) {
146
- this.openai = new openai({ apiKey, dangerouslyAllowBrowser: true });
134
+ this.openai = new OpenAI({ apiKey });
147
135
  }
148
136
 
149
- invoke(params: ResponseCreateParamsNonStreaming) {
137
+ async invoke(params: ResponseCreateParamsNonStreaming): Promise<Response> {
150
138
  return this.openai.responses.create({ ...params, model: 'gpt-4o' });
151
139
  }
152
140
 
package/dist/index.d.ts CHANGED
@@ -13,6 +13,7 @@ import { ResponseFunctionWebSearch } from 'openai/resources/responses/responses'
13
13
  import { ResponseIncludable } from 'openai/resources/responses/responses';
14
14
  import { ResponseInput } from 'openai/resources/responses/responses';
15
15
  import { ResponseInputItem } from 'openai/resources/responses/responses';
16
+ import { ResponseOutputItem } from 'openai/resources/responses/responses';
16
17
  import { ResponseOutputMessage } from 'openai/resources/responses/responses';
17
18
  import { ResponsePrompt } from 'openai/resources/responses/responses';
18
19
  import { ResponseReasoningItem } from 'openai/resources/responses/responses';
@@ -85,7 +86,7 @@ export declare interface BoothPlugin {
85
86
  * @param responseParams - The initial parameters for the response creation.
86
87
  * @returns The potentially modified response parameters.
87
88
  */
88
- onBeforeInteractionLoopStart?: (prepareInitialMessagesArgs: RepositoryUtilities, responseParams: ResponseCreateParamsNonStreaming, initialInput: string) => Promise<ResponseCreateParamsNonStreaming>;
89
+ onBeforeInteractionLoopStart?: (prepareInitialMessagesArgs: RepositoryUtilities, responseParams: ResponseCreateParamsNonStreaming, initialInput: string | ResponseInput) => Promise<ResponseCreateParamsNonStreaming>;
89
90
  /**
90
91
  * Called before a message is sent to the AI. This allows for modification
91
92
  * of the message or its parameters.
@@ -207,7 +208,7 @@ export declare class BoothPluginRegistry {
207
208
  * @param initialInput
208
209
  * @returns Modified response parameters after all plugins have processed them
209
210
  */
210
- runBeforeInteractionLoopStart(prepareArgs: RepositoryUtilities, initialParams: ResponseCreateParamsNonStreaming, initialInput: string): Promise<ResponseCreateParamsNonStreaming>;
211
+ runBeforeInteractionLoopStart(prepareArgs: RepositoryUtilities, initialParams: ResponseCreateParamsNonStreaming, initialInput: string | ResponseInput): Promise<ResponseCreateParamsNonStreaming>;
211
212
  /**
212
213
  * Sequentially invokes every plugin's onBeforeMessageSend hook.
213
214
  * This is called immediately before sending a message to the LLM,
@@ -304,6 +305,23 @@ export declare class BoothRegistry {
304
305
  * @private
305
306
  */
306
307
  private currentContextId;
308
+ /**
309
+ * Tracks whether the orchestrator booth is currently registered.
310
+ * @private
311
+ */
312
+ private hasOrchestrator;
313
+ /**
314
+ * Optional callback function that gets called when multi-booth mode is enabled.
315
+ * Used to coordinate external actions like tool registration.
316
+ * @private
317
+ */
318
+ private onMultiBoothModeEnabled?;
319
+ /**
320
+ * Optional callback function that gets called when multi-booth mode is disabled.
321
+ * Used to coordinate external actions like tool unregistration.
322
+ * @private
323
+ */
324
+ private onMultiBoothModeDisabled?;
307
325
  /**
308
326
  * Creates a new booth registry with a specified base booth configuration.
309
327
  *
@@ -372,10 +390,25 @@ export declare class BoothRegistry {
372
390
  * @returns Record of all booth configurations indexed by their IDs
373
391
  */
374
392
  getAllBooths(): Record<string, BoothConfig>;
393
+ toArray(): BoothConfig[];
375
394
  /**
376
- * Checks if the registry is operating in a multi-booth configuration.
377
- * @returns {boolean} `true` if there is more than one booth registered, otherwise `false`.
395
+ * Enables multi-booth mode by registering the orchestrator and setting it as current context.
396
+ * @private
378
397
  */
398
+ private enableMultiBoothMode;
399
+ /**
400
+ * Disables multi-booth mode by unregistering the orchestrator and resetting context to base booth.
401
+ * @private
402
+ */
403
+ private disableMultiBoothMode;
404
+ /**
405
+ * Sets callback functions for when multi-booth mode is enabled/disabled.
406
+ * Used to coordinate external actions like tool registration/unregistration.
407
+ *
408
+ * @param onEnabled - Callback for when multi-booth mode is enabled
409
+ * @param onDisabled - Callback for when multi-booth mode is disabled
410
+ */
411
+ setMultiBoothModeCallbacks(onEnabled?: () => void, onDisabled?: () => void): void;
379
412
  get isMultiBoothMode(): boolean;
380
413
  /**
381
414
  * Removes a booth configuration from the registry by its ID.
@@ -386,6 +419,12 @@ export declare class BoothRegistry {
386
419
  unregisterBooth(boothId: string): void;
387
420
  }
388
421
 
422
+ export declare type BoothResponseInput = BoothResponseInputItem[];
423
+
424
+ export declare type BoothResponseInputItem = (ResponseInputItem & {
425
+ bmId: string;
426
+ }) | string;
427
+
389
428
  /**
390
429
  * The ContextProviderPlugin provides contextual information to booths during interaction loops.
391
430
  *
@@ -447,6 +486,11 @@ export declare class ContextProviderPlugin implements BoothPlugin {
447
486
  * interaction has access to the full conversation history, enabling contextual responses.
448
487
  */
449
488
  export declare class ConversationHistoryPlugin implements BoothPlugin {
489
+ /**
490
+ * The sessionHistory variable stores the conversation history between the user and the booth system.
491
+ * It is initialized as an empty array and will be populated with messages exchanged during the interaction.
492
+ */
493
+ private sessionHistory;
450
494
  /**
451
495
  * Unique identifier for this plugin instance.
452
496
  * @private
@@ -462,7 +506,30 @@ export declare class ConversationHistoryPlugin implements BoothPlugin {
462
506
  * @private
463
507
  */
464
508
  private readonly plugin_description;
509
+ /**
510
+ * Checks if the given response contains a booth change.
511
+ *
512
+ * A booth change is determined by examining the response's output for a specific tool call to 'route_to_booth'.
513
+ * The output can either include a direct function call object or a message containing a list of tool calls.
514
+ *
515
+ * @param response - The response objects to be checked. It is expected to contain an `output` property.
516
+ * @return A boolean indicating whether a booth change is present in the response.
517
+ */
465
518
  private responseContainsBoothChange;
519
+ /**
520
+ * Constructs a new instance with an optional session history.
521
+ *
522
+ * @param {ResponseInput[]} [sessionHistory=[]] - An array representing the session history. Defaults to an empty array if not provided.
523
+ */
524
+ constructor(sessionHistory?: ResponseInput);
525
+ /**
526
+ * Retrieves the session history.
527
+ *
528
+ * @return {Array} The history of the current session.
529
+ */
530
+ get history(): (ResponseInputItem & {
531
+ bmId?: string;
532
+ })[];
466
533
  /**
467
534
  * Returns the plugin's unique identifier.
468
535
  */
@@ -488,13 +555,13 @@ export declare class ConversationHistoryPlugin implements BoothPlugin {
488
555
  * Executes after receiving a response from the LLM, adding the response content
489
556
  * to the conversation history for future reference.
490
557
  *
491
- * @param _
558
+ * @param utilities
492
559
  * @param responseParams - Current parameters for the LLM response creation
493
560
  * @param response
494
561
  * @returns Unmodified response parameters
495
562
  */
496
563
  onResponseReceived(utilities: RepositoryUtilities, responseParams: ResponseCreateParamsNonStreaming, response: Response_2): Promise<{
497
- input: ( ResponseFunctionToolCall | EasyInputMessage | ResponseOutputMessage | ResponseFileSearchToolCall | ResponseComputerToolCall | ResponseInputItem.ComputerCallOutput | ResponseFunctionWebSearch | ResponseInputItem.FunctionCallOutput | ResponseReasoningItem | ResponseInputItem.ImageGenerationCall | ResponseCodeInterpreterToolCall | ResponseInputItem.LocalShellCall | ResponseInputItem.LocalShellCallOutput | ResponseInputItem.McpListTools | ResponseInputItem.McpApprovalRequest | ResponseInputItem.McpApprovalResponse | ResponseInputItem.McpCall | ResponseInputItem.ItemReference)[];
564
+ input: ( EasyInputMessage | ResponseOutputMessage | ResponseFileSearchToolCall | ResponseComputerToolCall | ResponseInputItem.ComputerCallOutput | ResponseFunctionWebSearch | ResponseFunctionToolCall | ResponseInputItem.FunctionCallOutput | ResponseReasoningItem | ResponseInputItem.ImageGenerationCall | ResponseCodeInterpreterToolCall | ResponseInputItem.LocalShellCall | ResponseInputItem.LocalShellCallOutput | ResponseInputItem.McpListTools | ResponseInputItem.McpApprovalRequest | ResponseInputItem.McpApprovalResponse | ResponseInputItem.McpCall | ResponseInputItem.ItemReference)[];
498
565
  stream?: false | null;
499
566
  background?: boolean | null;
500
567
  include?: Array< ResponseIncludable> | null;
@@ -585,10 +652,11 @@ export declare class CoreBooth<T> {
585
652
  * @param {ToolRegistry} options.tools - Registry containing tool configurations
586
653
  */
587
654
  constructor(options: {
588
- boothPlugins: BoothPluginRegistry;
655
+ boothPlugins?: BoothPluginRegistry;
589
656
  booths: BoothRegistry;
590
- tools: ToolRegistry;
657
+ tools?: ToolRegistry;
591
658
  llmAdapter: LLMAdapter<T>;
659
+ sessionHistory?: ResponseInput;
592
660
  });
593
661
  }
594
662
 
@@ -717,10 +785,10 @@ export declare class InteractionProcessor<T> {
717
785
  * @param input The input message to send.
718
786
  * @returns The processed response from the LLM.
719
787
  */
720
- send(input: string): Promise<Response_2>;
788
+ send(input: string | ResponseInput): Promise<Response_2>;
721
789
  }
722
790
 
723
- export declare interface LLMAdapter<LLMResponse> {
791
+ export declare interface LLMAdapter<LLMResponse = any> {
724
792
  invoke: (responseParams: ResponseCreateParamsNonStreaming) => Promise<LLMResponse>;
725
793
  interpret: (response: LLMResponse) => Promise<Response_2>;
726
794
  }
@@ -799,6 +867,7 @@ export declare class ToolExecutorPlugin implements BoothPlugin {
799
867
  * @private
800
868
  */
801
869
  private executeToolCall;
870
+ static extractFunctionCalls(output: ResponseOutputItem[]): ResponseFunctionToolCall[];
802
871
  /**
803
872
  * After a response is received from the LLM, this hook checks for tool calls. If any are found,
804
873
  * it executes them using the `toolRegistry` and appends their outputs to the response parameters'
@@ -827,7 +896,8 @@ export declare type ToolModule = FunctionTool & {
827
896
  * @param input - The input parameters for the tool, typically parsed from a JSON string.
828
897
  * @returns A promise that resolves with the result of the tool's execution.
829
898
  */
830
- execute: (input: any) => Promise<any>;
899
+ execute?: (input?: any) => Promise<any>;
900
+ global?: boolean;
831
901
  };
832
902
 
833
903
  /**
@@ -916,12 +986,26 @@ export declare class ToolRegistry {
916
986
  * @returns The tool instance if found, undefined otherwise
917
987
  */
918
988
  getTool(toolName: string): ToolModule;
989
+ getGlobalTools(): ToolModule[];
919
990
  /**
920
991
  * Returns all registered tools as an array.
921
992
  *
922
993
  * @returns Array of all registered Tool instances
923
994
  */
924
- getAllTools(): ToolModule[];
995
+ getServerTools(): ToolModule[];
996
+ /**
997
+ * Returns local tools. Local tools are distinguished by not having the execute method.
998
+ */
999
+ getLocalTools(): ToolModule[];
1000
+ /**
1001
+ * Determines if the specified tool is a local tool.
1002
+ *
1003
+ * A local tool is identified by the `execute` property being undefined.
1004
+ *
1005
+ * @param {string} toolName - The name of the tool to be checked.
1006
+ * @return {boolean} - Returns true if the specified tool is a local tool, false otherwise.
1007
+ */
1008
+ isLocalTool(toolName: string): boolean;
925
1009
  /**
926
1010
  * Removes a tool from the registry by its ID.
927
1011
  * Throws an error if the tool doesn't exist.