booths 1.4.1 → 1.5.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
@@ -103,6 +103,7 @@ import type {
103
103
  LLMAdapter,
104
104
  ResponseCreateParamsNonStreaming,
105
105
  Response,
106
+ ResponseInput,
106
107
  } from 'booths';
107
108
  import OpenAI from 'openai';
108
109
 
@@ -120,6 +121,8 @@ export class OpenAIAdapter implements LLMAdapter<Response> {
120
121
  }
121
122
  ```
122
123
 
124
+ > **Note**: All necessary types including `ResponseInput` and `ResponseInputItem` can be imported directly from `booths`, eliminating the need to import from the OpenAI library.
125
+
123
126
  ### 4) Initialize and talk to the booth
124
127
 
125
128
  ```ts
package/dist/index.cjs ADDED
@@ -0,0 +1,60 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});class f{plugins=[];registerPlugin(t){if(this.plugins.some(o=>o.id===t.id))throw new Error(`Plugin with ID ${t.id} is already registered.`);this.plugins.push(t)}getPlugins(){return this.plugins}registerPlugins(t){for(const o of t)this.registerPlugin(o)}getPluginById(t){return this.plugins.find(o=>o.id===t)}getPluginsByIds(t){const o=[];for(const e of t){const r=this.getPluginById(e);if(!r)throw new Error(`Plugin with ID ${e} is not registered.`);o.push(r)}return o}unregisterPlugin(t){const o=this.plugins.findIndex(e=>e.id===t);if(o===-1)throw new Error(`Plugin with ID ${t} does not exist.`);this.plugins.splice(o,1)}async runBeforeInteractionLoopStart(t,o,e){let r=o;for(const s of this.plugins)s.onBeforeInteractionLoopStart&&(r=await s.onBeforeInteractionLoopStart(t,r,e));return r}async runBeforeMessageSend(t,o){let e=o;for(const r of this.plugins)r.onBeforeMessageSend&&(e=await r.onBeforeMessageSend(t,e));return e}async runResponseReceived(t,o,e){let r=o;for(const s of this.plugins)s.onResponseReceived&&(r=await s.onResponseReceived(t,r,e));return r}async runShouldEndInteractionLoop(t,o,e){for(const r of this.plugins)if(await r.shouldEndInteractionLoop(t,o,e))return console.log(`BoothPluginRegistry: Plugin ${r.id} indicated loop should end.`),!0;return!1}async runAfterInteractionLoopEnd(t,o){let e=o;for(const r of this.plugins)r.onAfterInteractionLoopEnd&&(e=await r.onAfterInteractionLoopEnd(t,o));return e}async runBeforeToolCall(t,o,e){let r=o;for(const s of this.plugins)s.onBeforeToolCall&&(r=await s.onBeforeToolCall(t,r,e));return r}async runAfterToolCall(t,o,e,r){let s=e;for(const i of this.plugins)i.onAfterToolCall&&(s=await i.onAfterToolCall(t,o,s,r));return s}async runToolCallError(t,o,e,r){let s=`Error: ${e.message}`;for(const i of this.plugins)i.onToolCallError&&(s=await i.onToolCallError(t,o,e,r));return s}}const u={id:"orchestrator",role:`
2
+ This booth serves as the orchestration layer that analyzes user intent and routes
3
+ conversations to the most appropriate specialized booth configuration.
4
+ `,description:`
5
+ You are the orchestration layer responsible for determining which booth configuration
6
+ should be active based on user needs. Focus exclusively on routing - do not answer
7
+ questions or provide information directly to users.
8
+
9
+ [ROUTING STRATEGY]
10
+ - Analyze user request and route to the most appropriate specialized booth immediately
11
+ - This booth is only active for initial routing or when explicitly routed back to
12
+ - Once routed, the target booth handles the conversation until completion or re-routing
13
+
14
+ [ROUTING TARGETS]
15
+ - Ambiguous requests → Ask for clarification, then route appropriately
16
+
17
+ [CORE PRINCIPLES]
18
+ - Maintain illusion of single, continuous assistant
19
+ - Never reference booths, tools, or system mechanics to users
20
+ - Silent routing is preferred when intent is clear
21
+ - Only speak to users when clarification is absolutely necessary
22
+
23
+ [ROUTING BEHAVIOR]
24
+ - Clear intent: Route silently using route_to_booth() - do NOT respond to user
25
+ - Ambiguous intent: Ask user for clarification, then route once clarified
26
+ - Never respond to user AND route - it's either respond OR route, not both
27
+
28
+ [BEHAVIOR EXAMPLES]
29
+ - User: "How do I test my number?" → route_to_booth({ targetBooth: 'page-router-booth' })
30
+ - User: "I need help" → "What specifically would you like help with?" → then route based on response
31
+ `};class _{constructor(t,o){this.baseBooth=t,this.registerBooth(t),this.currentContextId=o||t.id}booths={};currentContextId;hasOrchestrator=!1;onMultiBoothModeEnabled;onMultiBoothModeDisabled;getCurrentContextId(){return this.currentContextId}setCurrentContextId(t){if(!this.booths[t])throw new Error(`Booth with ID ${t} is not registered.`);this.currentContextId=t}get currentContextBoothConfig(){const t=this.getBoothById(this.currentContextId);if(!t)throw new Error(`Booth with ID ${this.currentContextId} is not registered.`);return t}registerBooth(t){if(this.booths[t.id])return;this.booths[t.id]=t,Object.keys(this.booths).filter(e=>e!==u.id).length>1&&!this.hasOrchestrator&&this.enableMultiBoothMode()}get baseBoothConfig(){return this.baseBooth}get orchestratorBoothConfig(){const t=this.getBoothById("orchestrator");if(!t)throw new Error("Base booth does not have an orchestrator configuration.");return t}registerBooths(t){for(const o of t)this.registerBooth(o)}getBoothById(t){return this.booths[t]}getBoothsByIds(t){const o=[];for(const e of t){const r=this.getBoothById(e);if(!r)throw new Error(`Booth with ID ${e} is not registered.`);o.push(r)}return o}getAllBooths(){return this.booths}getSelectableBooths(){const t={};for(const[o,e]of Object.entries(this.booths))o!==this.baseBooth.id&&o!==u.id&&(t[o]=e);return t}toArray(){return Object.values(this.booths)}enableMultiBoothMode(){this.hasOrchestrator||(this.booths[u.id]=u,this.hasOrchestrator=!0,this.currentContextId=u.id,this.onMultiBoothModeEnabled?.())}disableMultiBoothMode(){this.hasOrchestrator&&(delete this.booths[u.id],this.hasOrchestrator=!1,this.currentContextId=this.baseBooth.id,this.onMultiBoothModeDisabled?.())}setMultiBoothModeCallbacks(t,o){this.onMultiBoothModeEnabled=t,this.onMultiBoothModeDisabled=o}get isMultiBoothMode(){return Object.keys(this.booths).filter(o=>o!==u.id).length>1}unregisterBooth(t){if(!this.booths[t])throw new Error(`Booth with ID ${t} does not exist.`);if(t===u.id)throw new Error("Cannot unregister orchestrator booth directly. It will be automatically managed based on booth count.");delete this.booths[t],Object.keys(this.booths).filter(e=>e!==u.id).length<=1&&this.hasOrchestrator&&this.disableMultiBoothMode()}}class v{constructor(t,o,e,r){this.boothRegistry=t,this.boothPlugins=o,this.toolRegistry=e,this.llmAdapter=r}loopLimit=10;createErrorResponse(t,o){const e=t instanceof Error?t.message:"Unknown error occurred while calling LLM",r=t instanceof Error&&"code"in t&&typeof t.code=="string"?t.code:"server_error",s={code:"server_error",message:e};if(r&&(s.code=r),o.model===void 0)throw new Error("Model must be specified in response parameters for error handling.");return{id:`error_${Date.now()}_${Math.random().toString(36).substr(2,9)}`,created_at:Math.floor(Date.now()/1e3),output_text:"An error occurred while communicating with the language model.",error:s,incomplete_details:null,instructions:null,metadata:null,model:o.model,object:"response",output:[{id:`msg_${Date.now()}_${Math.random().toString(36).substr(2,9)}`,content:[{type:"output_text",text:`Error: ${e}. Please try again or contact support if the issue persists.`,annotations:[]}],role:"assistant",status:"completed",type:"message"}],parallel_tool_calls:o.parallel_tool_calls||!1,temperature:o.temperature||null,tool_choice:o.tool_choice||"auto",tools:o.tools||[],top_p:o.top_p||null,status:"failed"}}async callLLM(t,o){try{const e=await this.llmAdapter.invoke(t,o);return await this.llmAdapter.interpret(e)}catch(e){return console.log("Error calling LLM:",e),this.createErrorResponse(e,t)}}async runInteractionLoop(t){let o=0,e=t,r,s=!0;for(;s&&o<this.loopLimit;){o++;const i={toolRegistry:this.toolRegistry,boothRegistry:this.boothRegistry,pluginRegistry:this.boothPlugins,llmAdapter:this.llmAdapter};e=await this.boothPlugins.runBeforeMessageSend(i,e),r=await this.callLLM(e,i),e=await this.boothPlugins.runResponseReceived(i,e,r),await this.boothPlugins.runShouldEndInteractionLoop(i,e,r)&&(console.log("Ending interaction loop because 'shouldEndInteractionLoop' returned true."),s=!1)}if(!r)throw new Error("No response received from LLM");return r}async send(t){let o;typeof t=="string"?o=[{role:"user",content:t}]:o=t;let e={input:o,tools:[]};const r=this.boothPlugins;e=await this.boothPlugins.runBeforeInteractionLoopStart({toolRegistry:this.toolRegistry,boothRegistry:this.boothRegistry,pluginRegistry:r,llmAdapter:this.llmAdapter},e,t);let s=await this.runInteractionLoop(e);return s=await this.boothPlugins.runAfterInteractionLoopEnd({toolRegistry:this.toolRegistry,boothRegistry:this.boothRegistry,pluginRegistry:r,llmAdapter:this.llmAdapter},s),s}}const L={id:"summarizer",role:'You are a highly skilled summarization AI. Your task is to read a conversation history and provide a concise, neutral, and objective summary. The summary should capture the key points, decisions made, and any unresolved questions. It must be written from a third-person perspective and should be clear enough for another AI assistant to understand the full context and continue the conversation seamlessly without needing the original transcript. Do not add any conversational fluff or introductory phrases like "Here is the summary:".',description:"A specialized booth for summarizing conversation histories."},w="route_to_booth";function y(n){const t=n.getSelectableBooths(),o=Object.values(t).map(r=>`- ${r.id}: ${r.role}
32
+ Examples:
33
+ ${(r.examples||[]).map(s=>` - "${s}"`).join(`
34
+ `)}`).join(`
35
+ `),e=Object.keys(t);return{type:"function",name:w,description:`
36
+ Routes the conversation to a specialized booth based on the user's needs. Each booth has a
37
+ specific role and set of capabilities.
38
+ `,parameters:{type:"object",properties:{targetBooth:{type:"string",description:`
39
+ The ID of the booth to route the conversation to. Must be one of the following available
40
+ booths:
41
+ ${o}
42
+ `,enum:e}},required:["targetBooth"],additionalProperties:!1},strict:!0,execute:async function({targetBooth:r}){try{return n.setCurrentContextId(r),{content:`Routed to booth ${r}`}}catch(s){return console.log("[routeToBoothTool] Error routing to booth:",s),{content:`Error: Unable to route to booth ${r}.`}}}}}class E{sessionHistory=[];plugin_id="conversation-history";plugin_name="Conversation History Plugin";plugin_description="A plugin to manage conversation history in booths.";responseContainsBoothChange(t){return t.output?t.output.some(o=>o.type==="function_call"?o.name===w:o.type==="message"&&"tool_calls"in o&&Array.isArray(o.tool_calls)?o.tool_calls.some(e=>e.type==="function"&&e.function.name===w):!1):!1}constructor(t=[]){this.sessionHistory=t}get history(){return this.sessionHistory}get id(){return this.plugin_id}get name(){return this.plugin_name}get description(){return this.plugin_description}async onBeforeInteractionLoopStart(t,o){const{input:e}=o,r=typeof e=="string"?[{role:"user",content:e}]:e||[];return this.sessionHistory.push(...r),{...o,input:this.sessionHistory}}async onResponseReceived(t,o,e){let s=[...o.input,...e?.output??[]];if(this.responseContainsBoothChange(e)){const l=`Please compact the following LLM conversation history. Take key points and make it useful for
43
+ an LLM that may need to look back for references. Conclude the summary with any next steps or
44
+ actions needed to complete the conversation.
45
+
46
+ The conversation History:
47
+ ${JSON.stringify(this.sessionHistory)}`.trim(),c=(await P(t.llmAdapter,L).callProcessor.send(l)).output,g=s.filter(a=>"role"in a&&a.role==="user").pop();console.log("LastUserMessage: ",g),console.log("Summary: ",c),console.log("Summary: ",c.join(""));let b="";const p=c.find(a=>a.type==="message");console.log("summaryMessages",p),p&&"type"in p&&p.type=="message"&&p.content.forEach(a=>{a.type==="output_text"&&(b+=a.text)}),console.log("summaryText",b);const R={role:"developer",content:`A conversation summary up to this point: ${b}`},T=s.filter(a=>!("role"in a&&a.role==="user"||"type"in a&&a.type==="message"));this.sessionHistory=g?[...T,R,g]:[...T,R],s=this.sessionHistory}else this.sessionHistory=s;return{...o,input:s}}async shouldEndInteractionLoop(){return!1}}class I{plugin_id="context-provider";plugin_name="Context Provider Plugin";plugin_description="A plugin to provide context to booths.";get id(){return this.plugin_id}get name(){return this.plugin_name}get description(){return this.plugin_description}async onBeforeMessageSend(t,o){const e=t.boothRegistry;let s=e.baseBoothConfig.description;if(e.isMultiBoothMode){const i=e.orchestratorBoothConfig,l=e.currentContextBoothConfig;s+=`
48
+
49
+ ${i.description}`,l.id!==i.id&&(s+=`
50
+
51
+ ${l.description}`)}return{...o,instructions:s}}async shouldEndInteractionLoop(){return!1}}class B{tools;constructor(){this.tools=new Map}registerTools(t){t.forEach(o=>this.registerTool(o))}registerTool(t){if(this.tools.has(t.name)){console.warn(`Tool with ID '${t.name}' is already registered. Duplicate registration ignored.`);return}this.tools.set(t.name,t)}getTool(t){const o=this.tools.get(t);if(!o)throw new Error(`Tool with name ${t} is not registered.`);return o}getToolsByNames(t){const o=[];for(const e of t){const r=this.getTool(e);o.push(r)}return o}getGlobalTools(){return Array.from(this.tools.values()).filter(t=>t.global)}getServerTools(){return Array.from(this.tools.values()).filter(t=>t.execute!==void 0)}getLocalTools(){return Array.from(this.tools.values()).filter(t=>t.execute===void 0)}isLocalTool(t){const o=this.tools.get(t);return o?o.execute===void 0:!1}unregisterTool(t){if(!this.tools.has(t))throw new Error(`Tool with ID ${t} is not registered.`);this.tools.delete(t)}}function $(n){switch(n.type){case"function":return`function:${n.name}`;case"mcp":return`mcp:${n.server_label}`;case"file_search":return`file_search:${n.vector_store_ids.join(",")}`;case"web_search_preview":case"web_search_preview_2025_03_11":return`web_search:${n.type}`;case"computer_use_preview":return`computer:${n.environment}:${n.display_width}x${n.display_height}`;case"code_interpreter":return`code_interpreter:${typeof n.container=="string"?n.container:"auto"}`;case"image_generation":return`image_generation:${n.model||"gpt-image-1"}`;case"local_shell":return"local_shell";default:return`${n.type}:${JSON.stringify(n)}`}}function A(n){const t=new Set,o=[];for(const e of n){const r=$(e);t.has(r)||(t.add(r),o.push(e))}return o}class C{description="A plugin to aggregate and provide tools from base and context booths.";id="tool-provider";name="Tool Provider Plugin";async onBeforeMessageSend(t,o){const e=t.boothRegistry.baseBoothConfig,r=t.boothRegistry.currentContextBoothConfig,l=[...e.tools||[],...r?.tools||[]].filter((h,c,g)=>g.indexOf(h)===c).map(h=>t.toolRegistry.getTool(h));if(e.mcp&&l.push(...e.mcp),r?.mcp&&l.push(...r.mcp),t.boothRegistry.isMultiBoothMode){const h=y(t.boothRegistry);l.push(h)}l.push(...t.toolRegistry.getGlobalTools());const d=A(l);return{...o,tools:d}}async shouldEndInteractionLoop(){return!1}}class m{id="tool-executor";name="Tool Executor";description="Checks for tool calls in the response, executes them, and adds the results to the message history.";async executeToolCall(t,o,e){try{const r=await t.pluginRegistry.runBeforeToolCall(t,o,e),s=t.toolRegistry.getTool(r.name);if(!s)return{type:"function_call_output",call_id:r.call_id,output:`Error: Tool '${r.name}' not found.`};if(!s.execute)return{type:"function_call_output",call_id:r.call_id,output:`Error: Tool '${r.name}' does not have an 'execute' method.`};const i=await s.execute(JSON.parse(r.arguments)),l=await t.pluginRegistry.runAfterToolCall(t,r,i,e);return l||console.log(`Booths.ToolExecutorPlugin: Tool execution returned an empty results for ${s.name}. This may result in 400 responses from the LLM.`),{type:"function_call_output",call_id:r.call_id,output:JSON.stringify(l)}}catch(r){console.log(`Error executing tool ${o.name}:`,r);const s=await t.pluginRegistry.runToolCallError(t,o,r,e);return{type:"function_call_output",call_id:o.call_id,output:typeof s=="string"?s:JSON.stringify(s)}}}static extractFunctionCalls(t){return t.filter(o=>o.type==="function_call")}async onResponseReceived(t,o,e){const r=e?.output??[],s=m.extractFunctionCalls(r);if(!s.length)return o;const i=[];for(let l=0;l<s.length;l++){const d=s[l];if(t.toolRegistry.isLocalTool(d.name))continue;const h={responseParams:o,response:e,toolCallIndex:l,totalToolCalls:s.length},c=await this.executeToolCall(t,d,h);i.push(c)}return{...o,input:[...o.input,...i]}}async shouldEndInteractionLoop(){return!1}}class M{constructor(t="__awaiting_user_response__"){this.marker=t}description="A plugin to ensure the interaction loop can be finished.";id="finish-turn-plugin";name="Finish Turn Plugin";async onBeforeMessageSend(t,o){let e=o.instructions||"";return e=`
52
+
53
+
54
+
55
+ [MUST]
56
+ - Always add the marker "${this.marker}" at the end of your output when you have finished your part
57
+ - This marker indicates that the interaction loop should end.
58
+
59
+ ${e}
60
+ `,{...o,instructions:e}}async shouldEndInteractionLoop(t,o,e){const s=JSON.stringify(e.output).includes(this.marker),i=e.status==="failed"||e.error!==null;return s||i}async onAfterInteractionLoopEnd(t,o){const e=JSON.stringify(o);if(e.includes(this.marker)){const r=e.replace(new RegExp(this.marker,"g"),"");return JSON.parse(r)}return o}}function P(n,t){const o=new _(t),e=new B,r=new f;return new x({llmAdapter:n,booths:o,tools:e,boothPlugins:r})}class x{boothPluginRegistry;boothRegistry;callProcessor;systemPluginsRegistry;toolRegistry;constructor(t){if(this.boothPluginRegistry=t?.boothPlugins??new f,this.boothRegistry=t.booths,this.toolRegistry=t?.tools??new B,this.boothRegistry.setMultiBoothModeCallbacks(()=>{const o=y(this.boothRegistry);this.toolRegistry.registerTools([o])},()=>{}),this.boothRegistry.isMultiBoothMode){const o=y(this.boothRegistry);this.toolRegistry.registerTools([o])}this.systemPluginsRegistry=new f,this.systemPluginsRegistry.registerPlugins([new E(t.sessionHistory),new I,new C,new m,new M(t.endInteractionLoopMarker)]),this.systemPluginsRegistry.registerPlugins(this.boothPluginRegistry.getPlugins()),this.callProcessor=new v(this.boothRegistry,this.systemPluginsRegistry,this.toolRegistry,t.llmAdapter)}}exports.BoothPluginRegistry=f;exports.BoothRegistry=_;exports.ContextProviderPlugin=I;exports.ConversationHistoryPlugin=E;exports.CoreBooth=x;exports.FinishTurnPlugin=M;exports.InteractionProcessor=v;exports.ToolExecutorPlugin=m;exports.ToolProviderPlugin=C;exports.ToolRegistry=B;exports.createCoreBooth=P;exports.createRouteToBoothTool=y;
package/dist/index.d.ts CHANGED
@@ -855,6 +855,10 @@ export declare type RepositoryUtilities = {
855
855
 
856
856
  export { ResponseCreateParamsNonStreaming }
857
857
 
858
+ export { ResponseInput }
859
+
860
+ export { ResponseInputItem }
861
+
858
862
  /**
859
863
  * Represents the result of processing a single tool call.
860
864
  */
package/dist/index.js CHANGED
@@ -534,36 +534,18 @@ class E {
534
534
  let o = 0, e = t, r, s = !0;
535
535
  for (; s && o < this.loopLimit; ) {
536
536
  o++;
537
- const i = this.boothPlugins;
538
- e = await this.boothPlugins.runBeforeMessageSend(
539
- {
540
- toolRegistry: this.toolRegistry,
541
- boothRegistry: this.boothRegistry,
542
- pluginRegistry: i,
543
- llmAdapter: this.llmAdapter
544
- },
545
- e
546
- ), r = await this.callLLM(e, {
537
+ const i = {
547
538
  toolRegistry: this.toolRegistry,
548
539
  boothRegistry: this.boothRegistry,
549
- pluginRegistry: i,
540
+ pluginRegistry: this.boothPlugins,
550
541
  llmAdapter: this.llmAdapter
551
- }), e = await this.boothPlugins.runResponseReceived(
552
- {
553
- toolRegistry: this.toolRegistry,
554
- boothRegistry: this.boothRegistry,
555
- pluginRegistry: i,
556
- llmAdapter: this.llmAdapter
557
- },
542
+ };
543
+ e = await this.boothPlugins.runBeforeMessageSend(i, e), r = await this.callLLM(e, i), e = await this.boothPlugins.runResponseReceived(
544
+ i,
558
545
  e,
559
546
  r
560
547
  ), await this.boothPlugins.runShouldEndInteractionLoop(
561
- {
562
- toolRegistry: this.toolRegistry,
563
- boothRegistry: this.boothRegistry,
564
- pluginRegistry: i,
565
- llmAdapter: this.llmAdapter
566
- },
548
+ i,
567
549
  e,
568
550
  r
569
551
  ) && (console.log("Ending interaction loop because 'shouldEndInteractionLoop' returned true."), s = !1);
@@ -765,20 +747,23 @@ class I {
765
747
  async onResponseReceived(t, o, e) {
766
748
  let s = [...o.input, ...e?.output ?? []];
767
749
  if (this.responseContainsBoothChange(e)) {
768
- const l = `Please summarize the following conversation history:
750
+ const l = `Please compact the following LLM conversation history. Take key points and make it useful for
751
+ an LLM that may need to look back for references. Conclude the summary with any next steps or
752
+ actions needed to complete the conversation.
769
753
 
770
- ${JSON.stringify(this.sessionHistory)}`, c = (await $(t.llmAdapter, v).callProcessor.send(l)).output, g = s.filter((a) => "role" in a && a.role === "user").pop();
754
+ The conversation History:
755
+ ${JSON.stringify(this.sessionHistory)}`.trim(), c = (await $(t.llmAdapter, v).callProcessor.send(l)).output, g = s.filter((a) => "role" in a && a.role === "user").pop();
771
756
  console.log("LastUserMessage: ", g), console.log("Summary: ", c), console.log("Summary: ", c.join(""));
772
757
  let f = "";
773
758
  const p = c.find((a) => a.type === "message");
774
759
  console.log("summaryMessages", p), p && "type" in p && p.type == "message" && p.content.forEach((a) => {
775
760
  a.type === "output_text" && (f += a.text);
776
761
  }), console.log("summaryText", f);
777
- const R = {
762
+ const B = {
778
763
  role: "developer",
779
764
  content: `A conversation summary up to this point: ${f}`
780
- }, B = s.filter((a) => !("role" in a && a.role === "user" || "type" in a && a.type === "message"));
781
- this.sessionHistory = g ? [...B, R, g] : [...B, R], s = this.sessionHistory;
765
+ }, R = s.filter((a) => !("role" in a && a.role === "user" || "type" in a && a.type === "message"));
766
+ this.sessionHistory = g ? [...R, B, g] : [...R, B], s = this.sessionHistory;
782
767
  } else
783
768
  this.sessionHistory = s;
784
769
  return {
@@ -957,7 +942,7 @@ class _ {
957
942
  this.tools.delete(t);
958
943
  }
959
944
  }
960
- function x(n) {
945
+ function M(n) {
961
946
  switch (n.type) {
962
947
  case "function":
963
948
  return `function:${n.name}`;
@@ -980,15 +965,15 @@ function x(n) {
980
965
  return `${n.type}:${JSON.stringify(n)}`;
981
966
  }
982
967
  }
983
- function M(n) {
968
+ function x(n) {
984
969
  const t = /* @__PURE__ */ new Set(), o = [];
985
970
  for (const e of n) {
986
- const r = x(e);
971
+ const r = M(e);
987
972
  t.has(r) || (t.add(r), o.push(e));
988
973
  }
989
974
  return o;
990
975
  }
991
- class A {
976
+ class P {
992
977
  description = "A plugin to aggregate and provide tools from base and context booths.";
993
978
  id = "tool-provider";
994
979
  name = "Tool Provider Plugin";
@@ -1009,7 +994,7 @@ class A {
1009
994
  l.push(h);
1010
995
  }
1011
996
  l.push(...t.toolRegistry.getGlobalTools());
1012
- const d = M(l);
997
+ const d = x(l);
1013
998
  return {
1014
999
  ...o,
1015
1000
  tools: d
@@ -1134,7 +1119,7 @@ class w {
1134
1119
  return !1;
1135
1120
  }
1136
1121
  }
1137
- class P {
1122
+ class L {
1138
1123
  constructor(t = "__awaiting_user_response__") {
1139
1124
  this.marker = t;
1140
1125
  }
@@ -1194,14 +1179,14 @@ class P {
1194
1179
  }
1195
1180
  function $(n, t) {
1196
1181
  const o = new T(t), e = new _(), r = new y();
1197
- return new L({
1182
+ return new A({
1198
1183
  llmAdapter: n,
1199
1184
  booths: o,
1200
1185
  tools: e,
1201
1186
  boothPlugins: r
1202
1187
  });
1203
1188
  }
1204
- class L {
1189
+ class A {
1205
1190
  /**
1206
1191
  * Represents a registry that maintains a collection of plugins for a booth system.
1207
1192
  * The boothPluginRegistry is used to manage and access plugins that enhance
@@ -1270,9 +1255,9 @@ class L {
1270
1255
  this.systemPluginsRegistry = new y(), this.systemPluginsRegistry.registerPlugins([
1271
1256
  new I(t.sessionHistory),
1272
1257
  new C(),
1273
- new A(),
1258
+ new P(),
1274
1259
  new w(),
1275
- new P(t.endInteractionLoopMarker)
1260
+ new L(t.endInteractionLoopMarker)
1276
1261
  ]), this.systemPluginsRegistry.registerPlugins(this.boothPluginRegistry.getPlugins()), this.callProcessor = new E(
1277
1262
  this.boothRegistry,
1278
1263
  this.systemPluginsRegistry,
@@ -1286,11 +1271,11 @@ export {
1286
1271
  T as BoothRegistry,
1287
1272
  C as ContextProviderPlugin,
1288
1273
  I as ConversationHistoryPlugin,
1289
- L as CoreBooth,
1290
- P as FinishTurnPlugin,
1274
+ A as CoreBooth,
1275
+ L as FinishTurnPlugin,
1291
1276
  E as InteractionProcessor,
1292
1277
  w as ToolExecutorPlugin,
1293
- A as ToolProviderPlugin,
1278
+ P as ToolProviderPlugin,
1294
1279
  _ as ToolRegistry,
1295
1280
  $ as createCoreBooth,
1296
1281
  b as createRouteToBoothTool
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "booths",
3
3
  "private": false,
4
- "version": "1.4.1",
4
+ "version": "1.5.0",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
7
7
  "module": "./dist/index.js",
@@ -12,7 +12,8 @@
12
12
  "exports": {
13
13
  ".": {
14
14
  "types": "./dist/index.d.ts",
15
- "import": "./dist/index.js"
15
+ "import": "./dist/index.js",
16
+ "require": "./dist/index.cjs"
16
17
  }
17
18
  },
18
19
  "scripts": {