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/dist/index.js CHANGED
@@ -1,14 +1,9 @@
1
- var _ = Object.defineProperty;
2
- var B = (i, t, o) => t in i ? _(i, t, { enumerable: !0, configurable: !0, writable: !0, value: o }) : i[t] = o;
3
- var s = (i, t, o) => B(i, typeof t != "symbol" ? t + "" : t, o);
4
- class R {
5
- constructor() {
6
- /**
7
- * Collection of registered plugins.
8
- * @private
9
- */
10
- s(this, "plugins", []);
11
- }
1
+ class p {
2
+ /**
3
+ * Collection of registered plugins.
4
+ * @private
5
+ */
6
+ plugins = [];
12
7
  /**
13
8
  * Registers a single plugin in the registry.
14
9
  * Throws an error if a plugin with the same ID already exists.
@@ -70,8 +65,8 @@ class R {
70
65
  */
71
66
  async runBeforeInteractionLoopStart(t, o, e) {
72
67
  let r = o;
73
- for (const n of this.plugins)
74
- n.onBeforeInteractionLoopStart && (r = await n.onBeforeInteractionLoopStart(t, r, e));
68
+ for (const s of this.plugins)
69
+ s.onBeforeInteractionLoopStart && (r = await s.onBeforeInteractionLoopStart(t, r, e));
75
70
  return r;
76
71
  }
77
72
  /**
@@ -101,8 +96,8 @@ class R {
101
96
  */
102
97
  async runResponseReceived(t, o, e) {
103
98
  let r = o;
104
- for (const n of this.plugins)
105
- n.onResponseReceived && (r = await n.onResponseReceived(t, r, e));
99
+ for (const s of this.plugins)
100
+ s.onResponseReceived && (r = await s.onResponseReceived(t, r, e));
106
101
  return r;
107
102
  }
108
103
  /**
@@ -150,8 +145,8 @@ class R {
150
145
  */
151
146
  async runBeforeToolCall(t, o, e) {
152
147
  let r = o;
153
- for (const n of this.plugins)
154
- n.onBeforeToolCall && (r = await n.onBeforeToolCall(t, r, e));
148
+ for (const s of this.plugins)
149
+ s.onBeforeToolCall && (r = await s.onBeforeToolCall(t, r, e));
155
150
  return r;
156
151
  }
157
152
  /**
@@ -166,10 +161,10 @@ class R {
166
161
  * @returns Modified result after all plugins have processed it
167
162
  */
168
163
  async runAfterToolCall(t, o, e, r) {
169
- let n = e;
170
- for (const a of this.plugins)
171
- a.onAfterToolCall && (n = await a.onAfterToolCall(t, o, n, r));
172
- return n;
164
+ let s = e;
165
+ for (const l of this.plugins)
166
+ l.onAfterToolCall && (s = await l.onAfterToolCall(t, o, s, r));
167
+ return s;
173
168
  }
174
169
  /**
175
170
  * Sequentially invokes every plugin's onToolCallError hook.
@@ -183,13 +178,48 @@ class R {
183
178
  * @returns Error result or recovery value after all plugins have processed it
184
179
  */
185
180
  async runToolCallError(t, o, e, r) {
186
- let n = `Error: ${e.message}`;
187
- for (const a of this.plugins)
188
- a.onToolCallError && (n = await a.onToolCallError(t, o, e, r));
189
- return n;
181
+ let s = `Error: ${e.message}`;
182
+ for (const l of this.plugins)
183
+ l.onToolCallError && (s = await l.onToolCallError(t, o, e, r));
184
+ return s;
190
185
  }
191
186
  }
192
- class T {
187
+ const u = {
188
+ id: "orchestrator",
189
+ role: `
190
+ This booth serves as the orchestration layer that analyzes user intent and routes
191
+ conversations to the most appropriate specialized booth configuration.
192
+ `,
193
+ description: `
194
+ You are the orchestration layer responsible for determining which booth configuration
195
+ should be active based on user needs. Focus exclusively on routing - do not answer
196
+ questions or provide information directly to users.
197
+
198
+ [ROUTING STRATEGY]
199
+ - Analyze user request and route to the most appropriate specialized booth immediately
200
+ - This booth is only active for initial routing or when explicitly routed back to
201
+ - Once routed, the target booth handles the conversation until completion or re-routing
202
+
203
+ [ROUTING TARGETS]
204
+ - Ambiguous requests → Ask for clarification, then route appropriately
205
+
206
+ [CORE PRINCIPLES]
207
+ - Maintain illusion of single, continuous assistant
208
+ - Never reference booths, tools, or system mechanics to users
209
+ - Silent routing is preferred when intent is clear
210
+ - Only speak to users when clarification is absolutely necessary
211
+
212
+ [ROUTING BEHAVIOR]
213
+ - Clear intent: Route silently using route_to_booth() - do NOT respond to user
214
+ - Ambiguous intent: Ask user for clarification, then route once clarified
215
+ - Never respond to user AND route - it's either respond OR route, not both
216
+
217
+ [BEHAVIOR EXAMPLES]
218
+ - User: "How do I test my number?" → route_to_booth({ targetBooth: 'page-router-booth' })
219
+ - User: "I need help" → "What specifically would you like help with?" → then route based on response
220
+ `
221
+ };
222
+ class R {
193
223
  /**
194
224
  * Creates a new booth registry with a specified base booth configuration.
195
225
  *
@@ -197,18 +227,35 @@ class T {
197
227
  * @param currentContextId - The initial current context booth ID (default is 'orchestrator')
198
228
  */
199
229
  constructor(t, o) {
200
- /**
201
- * Collection of registered booth configurations, indexed by their IDs.
202
- * @private
203
- */
204
- s(this, "booths", {});
205
- /**
206
- * The current context booth ID, defaulting to the orchestrator context.
207
- * @private
208
- */
209
- s(this, "currentContextId");
210
230
  this.baseBooth = t, this.registerBooth(t), this.currentContextId = o || t.id;
211
231
  }
232
+ /**
233
+ * Collection of registered booth configurations, indexed by their IDs.
234
+ * @private
235
+ */
236
+ booths = {};
237
+ /**
238
+ * The current context booth ID, defaulting to the orchestrator context.
239
+ * @private
240
+ */
241
+ currentContextId;
242
+ /**
243
+ * Tracks whether the orchestrator booth is currently registered.
244
+ * @private
245
+ */
246
+ hasOrchestrator = !1;
247
+ /**
248
+ * Optional callback function that gets called when multi-booth mode is enabled.
249
+ * Used to coordinate external actions like tool registration.
250
+ * @private
251
+ */
252
+ onMultiBoothModeEnabled;
253
+ /**
254
+ * Optional callback function that gets called when multi-booth mode is disabled.
255
+ * Used to coordinate external actions like tool unregistration.
256
+ * @private
257
+ */
258
+ onMultiBoothModeDisabled;
212
259
  /**
213
260
  * Gets the current context booth ID.
214
261
  *
@@ -247,7 +294,11 @@ class T {
247
294
  * @param boothConfig - The booth configuration to register
248
295
  */
249
296
  registerBooth(t) {
250
- this.booths[t.id] || (this.booths[t.id] = t);
297
+ if (this.booths[t.id])
298
+ return;
299
+ this.booths[t.id] = t, Object.keys(this.booths).filter(
300
+ (e) => e !== u.id
301
+ ).length > 1 && !this.hasOrchestrator && this.enableMultiBoothMode();
251
302
  }
252
303
  /**
253
304
  * Returns the base booth configuration that was provided during initialization.
@@ -297,12 +348,37 @@ class T {
297
348
  getAllBooths() {
298
349
  return this.booths;
299
350
  }
351
+ toArray() {
352
+ return Object.values(this.booths);
353
+ }
354
+ /**
355
+ * Enables multi-booth mode by registering the orchestrator and setting it as current context.
356
+ * @private
357
+ */
358
+ enableMultiBoothMode() {
359
+ this.hasOrchestrator || (this.booths[u.id] = u, this.hasOrchestrator = !0, this.currentContextId = u.id, this.onMultiBoothModeEnabled?.());
360
+ }
361
+ /**
362
+ * Disables multi-booth mode by unregistering the orchestrator and resetting context to base booth.
363
+ * @private
364
+ */
365
+ disableMultiBoothMode() {
366
+ this.hasOrchestrator && (delete this.booths[u.id], this.hasOrchestrator = !1, this.currentContextId = this.baseBooth.id, this.onMultiBoothModeDisabled?.());
367
+ }
300
368
  /**
301
- * Checks if the registry is operating in a multi-booth configuration.
302
- * @returns {boolean} `true` if there is more than one booth registered, otherwise `false`.
369
+ * Sets callback functions for when multi-booth mode is enabled/disabled.
370
+ * Used to coordinate external actions like tool registration/unregistration.
371
+ *
372
+ * @param onEnabled - Callback for when multi-booth mode is enabled
373
+ * @param onDisabled - Callback for when multi-booth mode is disabled
303
374
  */
375
+ setMultiBoothModeCallbacks(t, o) {
376
+ this.onMultiBoothModeEnabled = t, this.onMultiBoothModeDisabled = o;
377
+ }
304
378
  get isMultiBoothMode() {
305
- return Object.keys(this.booths).length > 1;
379
+ return Object.keys(this.booths).filter(
380
+ (o) => o !== u.id
381
+ ).length > 1;
306
382
  }
307
383
  /**
308
384
  * Removes a booth configuration from the registry by its ID.
@@ -313,10 +389,16 @@ class T {
313
389
  unregisterBooth(t) {
314
390
  if (!this.booths[t])
315
391
  throw new Error(`Booth with ID ${t} does not exist.`);
316
- delete this.booths[t];
392
+ if (t === u.id)
393
+ throw new Error(
394
+ "Cannot unregister orchestrator booth directly. It will be automatically managed based on booth count."
395
+ );
396
+ delete this.booths[t], Object.keys(this.booths).filter(
397
+ (e) => e !== u.id
398
+ ).length <= 1 && this.hasOrchestrator && this.disableMultiBoothMode();
317
399
  }
318
400
  }
319
- class E {
401
+ class B {
320
402
  /**
321
403
  * Creates an instance of InteractionProcessor.
322
404
  * @param boothRegistry - The registry for booth configurations.
@@ -325,9 +407,9 @@ class E {
325
407
  * @param llmAdapter - The adapter for interacting with the LLM.
326
408
  */
327
409
  constructor(t, o, e, r) {
328
- s(this, "loopLimit", 10);
329
410
  this.boothRegistry = t, this.boothPlugins = o, this.toolRegistry = e, this.llmAdapter = r;
330
411
  }
412
+ loopLimit = 10;
331
413
  /**
332
414
  * Creates a synthetic error response with proper structure and error details.
333
415
  * @param error - The error that occurred
@@ -336,17 +418,17 @@ class E {
336
418
  * @private
337
419
  */
338
420
  createErrorResponse(t, o) {
339
- 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", n = {
421
+ 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 = {
340
422
  code: "server_error",
341
423
  message: e
342
424
  };
343
- if (r && (n.code = r), o.model === void 0)
425
+ if (r && (s.code = r), o.model === void 0)
344
426
  throw new Error("Model must be specified in response parameters for error handling.");
345
427
  return {
346
428
  id: `error_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
347
429
  created_at: Math.floor(Date.now() / 1e3),
348
430
  output_text: "An error occurred while communicating with the language model.",
349
- error: n,
431
+ error: s,
350
432
  incomplete_details: null,
351
433
  instructions: null,
352
434
  metadata: null,
@@ -397,8 +479,8 @@ class E {
397
479
  * @private
398
480
  */
399
481
  async runInteractionLoop(t) {
400
- let o = 0, e = t, r, n = !0;
401
- for (; n && o < this.loopLimit; )
482
+ let o = 0, e = t, r, s = !0;
483
+ for (; s && o < this.loopLimit; )
402
484
  o++, e = await this.boothPlugins.runBeforeMessageSend(
403
485
  {
404
486
  toolRegistry: this.toolRegistry,
@@ -425,7 +507,7 @@ class E {
425
507
  },
426
508
  e,
427
509
  r
428
- ) && (n = !1);
510
+ ) && (s = !1);
429
511
  if (!r)
430
512
  throw new Error("No response received from LLM");
431
513
  return r;
@@ -437,53 +519,55 @@ class E {
437
519
  * @returns The processed response from the LLM.
438
520
  */
439
521
  async send(t) {
440
- let o = {
441
- input: [
442
- {
443
- role: "user",
444
- content: t
445
- }
446
- ],
522
+ let o;
523
+ typeof t == "string" ? o = [
524
+ {
525
+ role: "user",
526
+ content: t
527
+ }
528
+ ] : o = t;
529
+ let e = {
530
+ input: o,
447
531
  tools: []
448
532
  };
449
- o = await this.boothPlugins.runBeforeInteractionLoopStart(
533
+ e = await this.boothPlugins.runBeforeInteractionLoopStart(
450
534
  {
451
535
  toolRegistry: this.toolRegistry,
452
536
  boothRegistry: this.boothRegistry,
453
537
  pluginRegistry: this.boothPlugins,
454
538
  llmAdapter: this.llmAdapter
455
539
  },
456
- o,
540
+ e,
457
541
  t
458
542
  );
459
- let e = await this.runInteractionLoop(o);
460
- return e = await this.boothPlugins.runAfterInteractionLoopEnd(
543
+ let r = await this.runInteractionLoop(e);
544
+ return r = await this.boothPlugins.runAfterInteractionLoopEnd(
461
545
  {
462
546
  toolRegistry: this.toolRegistry,
463
547
  boothRegistry: this.boothRegistry,
464
548
  pluginRegistry: this.boothPlugins,
465
549
  llmAdapter: this.llmAdapter
466
550
  },
467
- e
468
- ), e;
551
+ r
552
+ ), r;
469
553
  }
470
554
  }
471
- const C = {
555
+ const T = {
472
556
  id: "summarizer",
473
557
  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:".',
474
558
  description: "A specialized booth for summarizing conversation histories."
475
- }, d = "route_to_booth";
476
- function w(i) {
477
- const t = i.getAllBooths(), o = Object.values(t).map(
559
+ }, f = "route_to_booth";
560
+ function y(n) {
561
+ const t = n.getAllBooths(), o = Object.values(t).map(
478
562
  (r) => `- ${r.id}: ${r.role}
479
563
  Examples:
480
- ${(r.examples || []).map((n) => ` - "${n}"`).join(`
564
+ ${(r.examples || []).map((s) => ` - "${s}"`).join(`
481
565
  `)}`
482
566
  ).join(`
483
567
  `), e = Object.keys(t);
484
568
  return {
485
569
  type: "function",
486
- name: d,
570
+ name: f,
487
571
  description: `
488
572
  Routes the conversation to a specialized booth based on the user's needs. Each booth has a
489
573
  specific role and set of capabilities.
@@ -513,41 +597,68 @@ ${o}
513
597
  */
514
598
  execute: async function({ targetBooth: r }) {
515
599
  try {
516
- return i.setCurrentContextId(r), {
600
+ return n.setCurrentContextId(r), {
517
601
  content: `Routed to booth ${r}`
518
602
  };
519
- } catch (n) {
520
- return console.error("[routeToBoothTool] Error routing to booth:", n), {
603
+ } catch (s) {
604
+ return console.error("[routeToBoothTool] Error routing to booth:", s), {
521
605
  content: `Error: Unable to route to booth ${r}.`
522
606
  };
523
607
  }
524
608
  }
525
609
  };
526
610
  }
527
- let c = [];
528
- class I {
529
- constructor() {
530
- /**
531
- * Unique identifier for this plugin instance.
532
- * @private
533
- */
534
- s(this, "plugin_id", "conversation-history");
535
- /**
536
- * Display name for this plugin.
537
- * @private
538
- */
539
- s(this, "plugin_name", "Conversation History Plugin");
540
- /**
541
- * Brief description of the plugin's purpose and functionality.
542
- * @private
543
- */
544
- s(this, "plugin_description", "A plugin to manage conversation history in booths.");
545
- }
611
+ class v {
612
+ /**
613
+ * The sessionHistory variable stores the conversation history between the user and the booth system.
614
+ * It is initialized as an empty array and will be populated with messages exchanged during the interaction.
615
+ */
616
+ sessionHistory = [];
617
+ /**
618
+ * Unique identifier for this plugin instance.
619
+ * @private
620
+ */
621
+ plugin_id = "conversation-history";
622
+ /**
623
+ * Display name for this plugin.
624
+ * @private
625
+ */
626
+ plugin_name = "Conversation History Plugin";
627
+ /**
628
+ * Brief description of the plugin's purpose and functionality.
629
+ * @private
630
+ */
631
+ plugin_description = "A plugin to manage conversation history in booths.";
632
+ /**
633
+ * Checks if the given response contains a booth change.
634
+ *
635
+ * A booth change is determined by examining the response's output for a specific tool call to 'route_to_booth'.
636
+ * The output can either include a direct function call object or a message containing a list of tool calls.
637
+ *
638
+ * @param response - The response objects to be checked. It is expected to contain an `output` property.
639
+ * @return A boolean indicating whether a booth change is present in the response.
640
+ */
546
641
  responseContainsBoothChange(t) {
547
- return t.output ? t.output.some((o) => o.type === "function_call" ? o.name === d : o.type === "message" && "tool_calls" in o && Array.isArray(o.tool_calls) ? o.tool_calls.some(
548
- (e) => e.type === "function" && e.function.name === d
642
+ return t.output ? t.output.some((o) => o.type === "function_call" ? o.name === f : o.type === "message" && "tool_calls" in o && Array.isArray(o.tool_calls) ? o.tool_calls.some(
643
+ (e) => e.type === "function" && e.function.name === f
549
644
  ) : !1) : !1;
550
645
  }
646
+ /**
647
+ * Constructs a new instance with an optional session history.
648
+ *
649
+ * @param {ResponseInput[]} [sessionHistory=[]] - An array representing the session history. Defaults to an empty array if not provided.
650
+ */
651
+ constructor(t = []) {
652
+ this.sessionHistory = t;
653
+ }
654
+ /**
655
+ * Retrieves the session history.
656
+ *
657
+ * @return {Array} The history of the current session.
658
+ */
659
+ get history() {
660
+ return this.sessionHistory;
661
+ }
551
662
  /**
552
663
  * Returns the plugin's unique identifier.
553
664
  */
@@ -576,37 +687,35 @@ class I {
576
687
  */
577
688
  async onBeforeInteractionLoopStart(t, o) {
578
689
  const { input: e } = o, r = typeof e == "string" ? [{ role: "user", content: e }] : e || [];
579
- return c.push(...r), {
690
+ return this.sessionHistory.push(...r), {
580
691
  ...o,
581
- input: c
692
+ input: this.sessionHistory
582
693
  };
583
694
  }
584
695
  /**
585
696
  * Executes after receiving a response from the LLM, adding the response content
586
697
  * to the conversation history for future reference.
587
698
  *
588
- * @param _
699
+ * @param utilities
589
700
  * @param responseParams - Current parameters for the LLM response creation
590
701
  * @param response
591
702
  * @returns Unmodified response parameters
592
703
  */
593
704
  async onResponseReceived(t, o, e) {
594
- let n = [...o.input, ...(e == null ? void 0 : e.output) ?? []];
705
+ let s = [...o.input, ...e?.output ?? []];
595
706
  if (this.responseContainsBoothChange(e)) {
596
- const l = `Please summarize the following conversation history:
707
+ const i = `Please summarize the following conversation history:
597
708
 
598
- ${JSON.stringify(c)}`, g = (await S(t.llmAdapter, C).callProcessor.send(l)).output_text, y = n.filter((h) => "role" in h && h.role === "user").pop(), f = {
709
+ ${JSON.stringify(this.sessionHistory)}`, d = (await A(t.llmAdapter, T).callProcessor.send(i)).output_text, g = s.filter((h) => "role" in h && h.role === "user").pop(), b = {
599
710
  role: "developer",
600
- content: `A conversation summary up to this point: ${g}`
601
- }, m = n.filter(
602
- (h) => "type" in h && h.type === "function_call" || h.type === "function_call_output"
603
- );
604
- c = y ? [...m, f, y] : [...m, f], n = c;
711
+ content: `A conversation summary up to this point: ${d}`
712
+ }, _ = s.filter((h) => !("role" in h && h.role === "user" || "type" in h && h.type === "message"));
713
+ this.sessionHistory = g ? [..._, b, g] : [..._, b], s = this.sessionHistory;
605
714
  } else
606
- c = n;
715
+ this.sessionHistory = s;
607
716
  return {
608
717
  ...o,
609
- input: n
718
+ input: s
610
719
  };
611
720
  }
612
721
  /**
@@ -619,24 +728,22 @@ ${JSON.stringify(c)}`, g = (await S(t.llmAdapter, C).callProcessor.send(l)).outp
619
728
  return !1;
620
729
  }
621
730
  }
622
- class v {
623
- constructor() {
624
- /**
625
- * Unique identifier for this plugin instance.
626
- * @private
627
- */
628
- s(this, "plugin_id", "context-provider");
629
- /**
630
- * Display the name for this plugin.
631
- * @private
632
- */
633
- s(this, "plugin_name", "Context Provider Plugin");
634
- /**
635
- * Brief description of the plugin's purpose and functionality.
636
- * @private
637
- */
638
- s(this, "plugin_description", "A plugin to provide context to booths.");
639
- }
731
+ class E {
732
+ /**
733
+ * Unique identifier for this plugin instance.
734
+ * @private
735
+ */
736
+ plugin_id = "context-provider";
737
+ /**
738
+ * Display the name for this plugin.
739
+ * @private
740
+ */
741
+ plugin_name = "Context Provider Plugin";
742
+ /**
743
+ * Brief description of the plugin's purpose and functionality.
744
+ * @private
745
+ */
746
+ plugin_description = "A plugin to provide context to booths.";
640
747
  /**
641
748
  * Returns the plugin's unique identifier.
642
749
  */
@@ -665,16 +772,16 @@ class v {
665
772
  */
666
773
  async onBeforeMessageSend(t, o) {
667
774
  const e = t.boothRegistry;
668
- let n = e.baseBoothConfig.description;
775
+ let s = e.baseBoothConfig.description;
669
776
  if (e.isMultiBoothMode) {
670
- const a = e.orchestratorBoothConfig, l = e.currentContextBoothConfig;
671
- n += `
777
+ const l = e.orchestratorBoothConfig, i = e.currentContextBoothConfig;
778
+ s += `
672
779
 
673
- ${a.description}`, l.id !== a.id && (n += `
780
+ ${l.description}`, i.id !== l.id && (s += `
674
781
 
675
- ${l.description}`);
782
+ ${i.description}`);
676
783
  }
677
- return { ...o, instructions: n };
784
+ return { ...o, instructions: s };
678
785
  }
679
786
  /**
680
787
  * Determines whether the interaction loop should end.
@@ -686,12 +793,12 @@ class v {
686
793
  return !1;
687
794
  }
688
795
  }
689
- class A {
796
+ class w {
797
+ tools;
690
798
  /**
691
799
  * Initializes an empty Map to store tools.
692
800
  */
693
801
  constructor() {
694
- s(this, "tools");
695
802
  this.tools = /* @__PURE__ */ new Map();
696
803
  }
697
804
  registerTools(t) {
@@ -705,7 +812,9 @@ class A {
705
812
  */
706
813
  registerTool(t) {
707
814
  if (this.tools.has(t.name)) {
708
- console.warn(`Tool with ID '${t.name}' is already registered. Duplicate registration ignored.`);
815
+ console.warn(
816
+ `Tool with ID '${t.name}' is already registered. Duplicate registration ignored.`
817
+ );
709
818
  return;
710
819
  }
711
820
  this.tools.set(t.name, t);
@@ -722,13 +831,34 @@ class A {
722
831
  throw new Error(`Tool with name ${t} is not registered.`);
723
832
  return o;
724
833
  }
834
+ getGlobalTools() {
835
+ return Array.from(this.tools.values()).filter((t) => t.global);
836
+ }
725
837
  /**
726
838
  * Returns all registered tools as an array.
727
839
  *
728
840
  * @returns Array of all registered Tool instances
729
841
  */
730
- getAllTools() {
731
- return Array.from(this.tools.values());
842
+ getServerTools() {
843
+ return Array.from(this.tools.values()).filter((t) => t.execute !== void 0);
844
+ }
845
+ /**
846
+ * Returns local tools. Local tools are distinguished by not having the execute method.
847
+ */
848
+ getLocalTools() {
849
+ return Array.from(this.tools.values()).filter((t) => t.execute === void 0);
850
+ }
851
+ /**
852
+ * Determines if the specified tool is a local tool.
853
+ *
854
+ * A local tool is identified by the `execute` property being undefined.
855
+ *
856
+ * @param {string} toolName - The name of the tool to be checked.
857
+ * @return {boolean} - Returns true if the specified tool is a local tool, false otherwise.
858
+ */
859
+ isLocalTool(t) {
860
+ const o = this.tools.get(t);
861
+ return o ? o.execute === void 0 : !1;
732
862
  }
733
863
  /**
734
864
  * Removes a tool from the registry by its ID.
@@ -743,12 +873,41 @@ class A {
743
873
  this.tools.delete(t);
744
874
  }
745
875
  }
746
- class P {
747
- constructor() {
748
- s(this, "description", "A plugin to aggregate and provide tools from base and context booths.");
749
- s(this, "id", "tool-provider");
750
- s(this, "name", "Tool Provider Plugin");
876
+ function C(n) {
877
+ switch (n.type) {
878
+ case "function":
879
+ return `function:${n.name}`;
880
+ case "mcp":
881
+ return `mcp:${n.server_label}`;
882
+ case "file_search":
883
+ return `file_search:${n.vector_store_ids.join(",")}`;
884
+ case "web_search_preview":
885
+ case "web_search_preview_2025_03_11":
886
+ return `web_search:${n.type}`;
887
+ case "computer_use_preview":
888
+ return `computer:${n.environment}:${n.display_width}x${n.display_height}`;
889
+ case "code_interpreter":
890
+ return `code_interpreter:${typeof n.container == "string" ? n.container : "auto"}`;
891
+ case "image_generation":
892
+ return `image_generation:${n.model || "gpt-image-1"}`;
893
+ case "local_shell":
894
+ return "local_shell";
895
+ default:
896
+ return `${n.type}:${JSON.stringify(n)}`;
751
897
  }
898
+ }
899
+ function I(n) {
900
+ const t = /* @__PURE__ */ new Set(), o = [];
901
+ for (const e of n) {
902
+ const r = C(e);
903
+ t.has(r) || (t.add(r), o.push(e));
904
+ }
905
+ return o;
906
+ }
907
+ class x {
908
+ description = "A plugin to aggregate and provide tools from base and context booths.";
909
+ id = "tool-provider";
910
+ name = "Tool Provider Plugin";
752
911
  /**
753
912
  * Before a message is sent, this hook gathers the tool keys from both the base and context booths,
754
913
  * retrieves the corresponding tool definitions from the `toolRegistry`, and adds them to the
@@ -758,16 +917,18 @@ class P {
758
917
  * @returns The updated response parameters with the aggregated list of tools.
759
918
  */
760
919
  async onBeforeMessageSend(t, o) {
761
- const e = t.boothRegistry.baseBoothConfig, r = t.boothRegistry.currentContextBoothConfig, n = [...e.tools || [], ...(r == null ? void 0 : r.tools) || []], l = [...new Set(n)].map(
762
- (u) => t.toolRegistry.getTool(u)
920
+ const e = t.boothRegistry.baseBoothConfig, r = t.boothRegistry.currentContextBoothConfig, i = [...e.tools || [], ...r?.tools || []].filter((a, d, g) => g.indexOf(a) === d).map(
921
+ (a) => t.toolRegistry.getTool(a)
763
922
  );
764
- if (e.mcp && l.push(...e.mcp), r != null && r.mcp && l.push(...r.mcp), t.boothRegistry.isMultiBoothMode) {
765
- const u = w(t.boothRegistry);
766
- l.push(u);
923
+ if (e.mcp && i.push(...e.mcp), r?.mcp && i.push(...r.mcp), t.boothRegistry.isMultiBoothMode) {
924
+ const a = y(t.boothRegistry);
925
+ i.push(a);
767
926
  }
927
+ i.push(...t.toolRegistry.getGlobalTools());
928
+ const c = I(i);
768
929
  return {
769
930
  ...o,
770
- tools: l
931
+ tools: c
771
932
  };
772
933
  }
773
934
  /**
@@ -779,12 +940,10 @@ class P {
779
940
  return !1;
780
941
  }
781
942
  }
782
- class x {
783
- constructor() {
784
- s(this, "id", "tool-executor");
785
- s(this, "name", "Tool Executor");
786
- s(this, "description", "Checks for tool calls in the response, executes them, and adds the results to the message history.");
787
- }
943
+ class m {
944
+ id = "tool-executor";
945
+ name = "Tool Executor";
946
+ description = "Checks for tool calls in the response, executes them, and adds the results to the message history.";
788
947
  /**
789
948
  * Executes a single tool call with proper hook integration.
790
949
  * @param utilities - Repository utilities for accessing registries.
@@ -799,27 +958,33 @@ class x {
799
958
  t,
800
959
  o,
801
960
  e
802
- ), n = t.toolRegistry.getTool(r.name);
803
- if (!n)
961
+ ), s = t.toolRegistry.getTool(r.name);
962
+ if (!s)
804
963
  return {
805
964
  type: "function_call_output",
806
965
  call_id: r.call_id,
807
966
  output: `Error: Tool '${r.name}' not found.`
808
967
  };
809
- const a = await n.execute(JSON.parse(r.arguments)), l = await t.pluginRegistry.runAfterToolCall(
968
+ if (!s.execute)
969
+ return {
970
+ type: "function_call_output",
971
+ call_id: r.call_id,
972
+ output: `Error: Tool '${r.name}' does not have an 'execute' method.`
973
+ };
974
+ const l = await s.execute(JSON.parse(r.arguments)), i = await t.pluginRegistry.runAfterToolCall(
810
975
  t,
811
976
  r,
812
- a,
977
+ l,
813
978
  e
814
979
  );
815
980
  return {
816
981
  type: "function_call_output",
817
982
  call_id: r.call_id,
818
- output: JSON.stringify(l)
983
+ output: JSON.stringify(i)
819
984
  };
820
985
  } catch (r) {
821
986
  console.error(`Error executing tool ${o.name}:`, r);
822
- const n = await t.pluginRegistry.runToolCallError(
987
+ const s = await t.pluginRegistry.runToolCallError(
823
988
  t,
824
989
  o,
825
990
  r,
@@ -828,10 +993,15 @@ class x {
828
993
  return {
829
994
  type: "function_call_output",
830
995
  call_id: o.call_id,
831
- output: typeof n == "string" ? n : JSON.stringify(n)
996
+ output: typeof s == "string" ? s : JSON.stringify(s)
832
997
  };
833
998
  }
834
999
  }
1000
+ static extractFunctionCalls(t) {
1001
+ return t.filter(
1002
+ (o) => o.type === "function_call"
1003
+ );
1004
+ }
835
1005
  /**
836
1006
  * After a response is received from the LLM, this hook checks for tool calls. If any are found,
837
1007
  * it executes them using the `toolRegistry` and appends their outputs to the response parameters'
@@ -842,24 +1012,25 @@ class x {
842
1012
  * @returns The updated response parameters, potentially with tool call outputs added to the input.
843
1013
  */
844
1014
  async onResponseReceived(t, o, e) {
845
- const r = (e == null ? void 0 : e.output) ?? [], n = (r == null ? void 0 : r.filter(
846
- (l) => l.type === "function_call"
847
- )) ?? [];
848
- if (!n.length)
1015
+ const r = e?.output ?? [], s = m.extractFunctionCalls(r);
1016
+ if (!s.length)
849
1017
  return o;
850
- const a = [];
851
- for (let l = 0; l < n.length; l++) {
852
- const u = n[l], p = {
1018
+ const l = [];
1019
+ for (let i = 0; i < s.length; i++) {
1020
+ const c = s[i];
1021
+ if (t.toolRegistry.isLocalTool(c.name))
1022
+ continue;
1023
+ const a = {
853
1024
  responseParams: o,
854
1025
  response: e,
855
- toolCallIndex: l,
856
- totalToolCalls: n.length
857
- }, g = await this.executeToolCall(t, u, p);
858
- a.push(g);
1026
+ toolCallIndex: i,
1027
+ totalToolCalls: s.length
1028
+ }, d = await this.executeToolCall(t, c, a);
1029
+ l.push(d);
859
1030
  }
860
1031
  return {
861
1032
  ...o,
862
- input: [...o.input, ...a]
1033
+ input: [...o.input, ...l]
863
1034
  };
864
1035
  }
865
1036
  /**
@@ -871,12 +1042,10 @@ class x {
871
1042
  return !1;
872
1043
  }
873
1044
  }
874
- class L {
875
- constructor() {
876
- s(this, "description", "A plugin to ensure the interaction loop can be finished.");
877
- s(this, "id", "finish-turn-plugin");
878
- s(this, "name", "Finish Turn Plugin");
879
- }
1045
+ class M {
1046
+ description = "A plugin to ensure the interaction loop can be finished.";
1047
+ id = "finish-turn-plugin";
1048
+ name = "Finish Turn Plugin";
880
1049
  /**
881
1050
  * Before sending a message, this hook adds an instruction to the LLM to include a
882
1051
  * specific marker (`__awaiting_user_response__`) when it expects a user response.
@@ -911,8 +1080,8 @@ class L {
911
1080
  async shouldEndInteractionLoop(t, o, e) {
912
1081
  if (!e.output_text)
913
1082
  return !1;
914
- const r = e.output_text.includes("__awaiting_user_response__"), n = e.status === "failed" || e.error !== null;
915
- return r || n;
1083
+ const r = e.output_text.includes("__awaiting_user_response__"), s = e.status === "failed" || e.error !== null;
1084
+ return r || s;
916
1085
  }
917
1086
  /**
918
1087
  * After the interaction loop ends, this hook removes the `__awaiting_user_response__` marker
@@ -930,51 +1099,60 @@ class L {
930
1099
  return o;
931
1100
  }
932
1101
  }
933
- const b = {
934
- id: "orchestrator",
935
- role: `
936
- This booth serves as the orchestration layer that analyzes user intent and routes
937
- conversations to the most appropriate specialized booth configuration.
938
- `,
939
- description: `
940
- You are the orchestration layer responsible for determining which booth configuration
941
- should be active based on user needs. Focus exclusively on routing - do not answer
942
- questions or provide information directly to users.
943
-
944
- [ROUTING STRATEGY]
945
- - Analyze user request and route to the most appropriate specialized booth immediately
946
- - This booth is only active for initial routing or when explicitly routed back to
947
- - Once routed, the target booth handles the conversation until completion or re-routing
948
-
949
- [ROUTING TARGETS]
950
- - Ambiguous requests → Ask for clarification, then route appropriately
951
-
952
- [CORE PRINCIPLES]
953
- - Maintain illusion of single, continuous assistant
954
- - Never reference booths, tools, or system mechanics to users
955
- - Silent routing is preferred when intent is clear
956
- - Only speak to users when clarification is absolutely necessary
957
-
958
- [ROUTING BEHAVIOR]
959
- - Clear intent: Route silently using route_to_booth() - do NOT respond to user
960
- - Ambiguous intent: Ask user for clarification, then route once clarified
961
- - Never respond to user AND route - it's either respond OR route, not both
962
-
963
- [BEHAVIOR EXAMPLES]
964
- - User: "How do I test my number?" → route_to_booth({ targetBooth: 'page-router-booth' })
965
- - User: "I need help" → "What specifically would you like help with?" → then route based on response
966
- `
967
- };
968
- function S(i, t) {
969
- const o = new T(t), e = new A(), r = new R();
970
- return new M({
971
- llmAdapter: i,
1102
+ function A(n, t) {
1103
+ const o = new R(t), e = new w(), r = new p();
1104
+ return new P({
1105
+ llmAdapter: n,
972
1106
  booths: o,
973
1107
  tools: e,
974
1108
  boothPlugins: r
975
1109
  });
976
1110
  }
977
- class M {
1111
+ class P {
1112
+ /**
1113
+ * Represents a registry that maintains a collection of plugins for a booth system.
1114
+ * The boothPluginRegistry is used to manage and access plugins that enhance
1115
+ * or extend the booth's behavior or features.
1116
+ *
1117
+ * This variable is intended to provide a central location for plugin registration,
1118
+ * retrieval, and management.
1119
+ *
1120
+ * @type {BoothPluginRegistry}
1121
+ */
1122
+ boothPluginRegistry;
1123
+ /**
1124
+ * Registry for managing booth configurations across the system.
1125
+ * This registry maintains a collection of booth definitions that can be
1126
+ * accessed by their unique identifiers.
1127
+ *
1128
+ * @type {BoothRegistry}
1129
+ */
1130
+ boothRegistry;
1131
+ /**
1132
+ * Primary processor for handling interactions between users and the booth system.
1133
+ * Responsible for sending messages to the LLM, processing responses, and managing
1134
+ * the interaction loop through plugins.
1135
+ *
1136
+ * @type {InteractionProcessor}
1137
+ */
1138
+ callProcessor;
1139
+ /**
1140
+ * Registry dedicated to system-level plugins that are always available.
1141
+ * This includes core functionality plugins like conversation history and context providers,
1142
+ * as well as any user-defined plugins from the boothPluginRegistry.
1143
+ *
1144
+ * @type {BoothPluginRegistry}
1145
+ */
1146
+ systemPluginsRegistry;
1147
+ /**
1148
+ * A variable that represents a registry for managing and maintaining a collection of tools.
1149
+ * `toolRegistry` is an instance of the `ToolRegistry` class, which provides functionalities
1150
+ * for adding, removing, and retrieving tools.
1151
+ *
1152
+ * The `ToolRegistry` class typically serves as a centralized storage or management
1153
+ * solution for tools that are used in a specific context or application.
1154
+ */
1155
+ toolRegistry;
978
1156
  /**
979
1157
  * Initializes a new instance of the CoreBooth class.
980
1158
  * Sets up the plugin registries, system plugins, and interaction processor.
@@ -985,62 +1163,24 @@ class M {
985
1163
  * @param {ToolRegistry} options.tools - Registry containing tool configurations
986
1164
  */
987
1165
  constructor(t) {
988
- /**
989
- * Represents a registry that maintains a collection of plugins for a booth system.
990
- * The boothPluginRegistry is used to manage and access plugins that enhance
991
- * or extend the booth's behavior or features.
992
- *
993
- * This variable is intended to provide a central location for plugin registration,
994
- * retrieval, and management.
995
- *
996
- * @type {BoothPluginRegistry}
997
- */
998
- s(this, "boothPluginRegistry");
999
- /**
1000
- * Registry for managing booth configurations across the system.
1001
- * This registry maintains a collection of booth definitions that can be
1002
- * accessed by their unique identifiers.
1003
- *
1004
- * @type {BoothRegistry}
1005
- */
1006
- s(this, "boothRegistry");
1007
- /**
1008
- * Primary processor for handling interactions between users and the booth system.
1009
- * Responsible for sending messages to the LLM, processing responses, and managing
1010
- * the interaction loop through plugins.
1011
- *
1012
- * @type {InteractionProcessor}
1013
- */
1014
- s(this, "callProcessor");
1015
- /**
1016
- * Registry dedicated to system-level plugins that are always available.
1017
- * This includes core functionality plugins like conversation history and context providers,
1018
- * as well as any user-defined plugins from the boothPluginRegistry.
1019
- *
1020
- * @type {BoothPluginRegistry}
1021
- */
1022
- s(this, "systemPluginsRegistry");
1023
- /**
1024
- * A variable that represents a registry for managing and maintaining a collection of tools.
1025
- * `toolRegistry` is an instance of the `ToolRegistry` class, which provides functionalities
1026
- * for adding, removing, and retrieving tools.
1027
- *
1028
- * The `ToolRegistry` class typically serves as a centralized storage or management
1029
- * solution for tools that are used in a specific context or application.
1030
- */
1031
- s(this, "toolRegistry");
1032
- if (this.boothPluginRegistry = t.boothPlugins, this.boothRegistry = t.booths, this.toolRegistry = t.tools, this.boothRegistry.isMultiBoothMode) {
1033
- this.boothRegistry.registerBooth(b), this.boothRegistry.setCurrentContextId(b.id);
1034
- const o = w(this.boothRegistry);
1166
+ if (this.boothPluginRegistry = t?.boothPlugins ?? new p(), this.boothRegistry = t.booths, this.toolRegistry = t?.tools ?? new w(), this.boothRegistry.setMultiBoothModeCallbacks(
1167
+ () => {
1168
+ const o = y(this.boothRegistry);
1169
+ this.toolRegistry.registerTools([o]);
1170
+ },
1171
+ () => {
1172
+ }
1173
+ ), this.boothRegistry.isMultiBoothMode) {
1174
+ const o = y(this.boothRegistry);
1035
1175
  this.toolRegistry.registerTools([o]);
1036
1176
  }
1037
- this.systemPluginsRegistry = new R(), this.systemPluginsRegistry.registerPlugins([
1038
- new I(),
1039
- new v(),
1040
- new P(),
1177
+ this.systemPluginsRegistry = new p(), this.systemPluginsRegistry.registerPlugins([
1178
+ new v(t.sessionHistory),
1179
+ new E(),
1041
1180
  new x(),
1042
- new L()
1043
- ]), this.systemPluginsRegistry.registerPlugins(this.boothPluginRegistry.getPlugins()), this.callProcessor = new E(
1181
+ new m(),
1182
+ new M()
1183
+ ]), this.systemPluginsRegistry.registerPlugins(this.boothPluginRegistry.getPlugins()), this.callProcessor = new B(
1044
1184
  this.boothRegistry,
1045
1185
  this.systemPluginsRegistry,
1046
1186
  this.toolRegistry,
@@ -1049,16 +1189,16 @@ class M {
1049
1189
  }
1050
1190
  }
1051
1191
  export {
1052
- R as BoothPluginRegistry,
1053
- T as BoothRegistry,
1054
- v as ContextProviderPlugin,
1055
- I as ConversationHistoryPlugin,
1056
- M as CoreBooth,
1057
- L as FinishTurnPlugin,
1058
- E as InteractionProcessor,
1059
- x as ToolExecutorPlugin,
1060
- P as ToolProviderPlugin,
1061
- A as ToolRegistry,
1062
- S as createCoreBooth,
1063
- w as createRouteToBoothTool
1192
+ p as BoothPluginRegistry,
1193
+ R as BoothRegistry,
1194
+ E as ContextProviderPlugin,
1195
+ v as ConversationHistoryPlugin,
1196
+ P as CoreBooth,
1197
+ M as FinishTurnPlugin,
1198
+ B as InteractionProcessor,
1199
+ m as ToolExecutorPlugin,
1200
+ x as ToolProviderPlugin,
1201
+ w as ToolRegistry,
1202
+ A as createCoreBooth,
1203
+ y as createRouteToBoothTool
1064
1204
  };