react-instantsearch-core 7.45.0 → 7.46.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.
@@ -1,4 +1,4 @@
1
- /*! React InstantSearch Core 7.45.0 | © Algolia, Inc. and contributors; MIT License | https://github.com/algolia/instantsearch */
1
+ /*! React InstantSearch Core 7.46.0 | © Algolia, Inc. and contributors; MIT License | https://github.com/algolia/instantsearch */
2
2
  (function (global, factory) {
3
3
  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('react')) :
4
4
  typeof define === 'function' && define.amd ? define(['exports', 'react'], factory) :
@@ -24,7 +24,7 @@
24
24
 
25
25
  var React__namespace = /*#__PURE__*/_interopNamespaceDefault(React);
26
26
 
27
- var version$2 = '7.45.0';
27
+ var version$2 = '7.46.0';
28
28
 
29
29
  function _define_property(obj, key, value) {
30
30
  if (key in obj) {
@@ -9249,7 +9249,7 @@
9249
9249
  });
9250
9250
  }
9251
9251
 
9252
- var version = '4.112.0';
9252
+ var version = '4.113.0';
9253
9253
 
9254
9254
  var ANONYMOUS_TOKEN_COOKIE_KEY = '_ALGOLIA';
9255
9255
  function getCookie(name) {
@@ -12451,6 +12451,31 @@
12451
12451
  var isPartTool = function isPartTool(part) {
12452
12452
  return startsWith(part.type, 'tool-');
12453
12453
  };
12454
+ var TOOL_PART_PREFIX = 'tool-';
12455
+ /**
12456
+ * Resolves the tool a message part belongs to, from either a part type
12457
+ * (`tool-algolia_search_index`) or a bare tool name.
12458
+ *
12459
+ * Generic over the tool shape so the renderer, the loader and the connector —
12460
+ * which hold different subsets of the tool contract — all resolve names the same
12461
+ * way.
12462
+ */ var findTool = function findTool(partType, tools) {
12463
+ var toolName = startsWith(partType, TOOL_PART_PREFIX) ? partType.slice(TOOL_PART_PREFIX.length) : partType;
12464
+ if (tools[toolName]) {
12465
+ return tools[toolName];
12466
+ }
12467
+ // Compatibility shim for tool names suffixed by the index name, as the Algolia
12468
+ // MCP Server does (`algolia_search_index_products`). The longest matching key
12469
+ // wins, so registering both `foo` and `foo_bar` resolves `foo_bar_products` to
12470
+ // `foo_bar` — otherwise the winner would depend on registration order.
12471
+ var match;
12472
+ Object.keys(tools).forEach(function(key) {
12473
+ if (startsWith(toolName, "".concat(key, "_")) && (match === undefined || key.length > match.length)) {
12474
+ match = key;
12475
+ }
12476
+ });
12477
+ return match === undefined ? undefined : tools[match];
12478
+ };
12454
12479
 
12455
12480
  var createRecords = function createRecords() {
12456
12481
  return Object.create(null);
@@ -12506,75 +12531,11 @@
12506
12531
  return store;
12507
12532
  }
12508
12533
 
12509
- var tryParseJson = function tryParseJson(value) {
12510
- try {
12511
- return JSON.parse(value);
12512
- } catch (unused) {
12513
- return undefined;
12514
- }
12515
- };
12516
- var repairPartialJson = function repairPartialJson(value) {
12517
- var repaired = value.trim();
12518
- if (!repaired) {
12519
- return repaired;
12520
- }
12521
- var inString = false;
12522
- var isEscaped = false;
12523
- var stack = [];
12524
- for(var index = 0; index < repaired.length; index++){
12525
- var char = repaired[index];
12526
- if (inString) {
12527
- if (isEscaped) {
12528
- isEscaped = false;
12529
- } else if (char === '\\') {
12530
- isEscaped = true;
12531
- } else if (char === '"') {
12532
- inString = false;
12533
- }
12534
- continue;
12535
- }
12536
- if (char === '"') {
12537
- inString = true;
12538
- continue;
12539
- }
12540
- if (char === '{' || char === '[') {
12541
- stack.push(char);
12542
- continue;
12543
- }
12544
- if (char === '}' && stack[stack.length - 1] === '{') {
12545
- stack.pop();
12546
- continue;
12547
- }
12548
- if (char === ']' && stack[stack.length - 1] === '[') {
12549
- stack.pop();
12550
- }
12551
- }
12552
- if (inString && !isEscaped) {
12553
- repaired += '"';
12554
- }
12555
- repaired = repaired.replace(RegExp(",\\s*$", "u"), '');
12556
- if (stack.length > 0) {
12557
- repaired += stack.reverse().map(function(opening) {
12558
- return opening === '{' ? '}' : ']';
12559
- }).join('');
12560
- }
12561
- return repaired.replace(RegExp(",\\s*([}\\]])", "gu"), '$1');
12562
- };
12563
- var parsePartialJson = function parsePartialJson(accumulatedRawJson, fallbackValue) {
12564
- var normalized = accumulatedRawJson.trim();
12565
- if (!normalized) {
12566
- return fallbackValue;
12567
- }
12568
- var directParsed = tryParseJson(normalized);
12569
- if (directParsed !== undefined) {
12570
- return directParsed;
12571
- }
12572
- var repairedParsed = tryParseJson(repairPartialJson(normalized));
12573
- if (repairedParsed !== undefined) {
12574
- return repairedParsed;
12575
- }
12576
- return fallbackValue;
12577
- };
12534
+ function flat(arr) {
12535
+ return arr.reduce(function(acc, array) {
12536
+ return acc.concat(array);
12537
+ }, []);
12538
+ }
12578
12539
 
12579
12540
  /**
12580
12541
  * Stream parser for parsing SSE (Server-Sent Events) streams.
@@ -12863,8 +12824,268 @@
12863
12824
  } catch (unused) {
12864
12825
  // Not JSON — caller falls back to its own default.
12865
12826
  }
12866
- return undefined;
12867
- }
12827
+ return undefined;
12828
+ }
12829
+
12830
+ /**
12831
+ * Reads a human-readable message from a failed HTTP response body when the
12832
+ * server returns JSON such as `{ "message": "..." }` (the shared
12833
+ * `ErrorResponse` shape used by every status code), falling back to the HTTP
12834
+ * status line when the body is empty or not parseable.
12835
+ */ function getHttpErrorMessage(response) {
12836
+ var fallback = "HTTP error: ".concat(response.status, " ").concat(response.statusText);
12837
+ return response.text().then(function(text) {
12838
+ var _tryParseErrorMessage;
12839
+ return (_tryParseErrorMessage = tryParseErrorMessage(text)) !== null && _tryParseErrorMessage !== void 0 ? _tryParseErrorMessage : fallback;
12840
+ }).catch(function() {
12841
+ return fallback;
12842
+ });
12843
+ }
12844
+ /**
12845
+ * Abstract base class for HTTP-based chat transports.
12846
+ */ var HttpChatTransport = /*#__PURE__*/ function() {
12847
+ function HttpChatTransport(param) {
12848
+ var _param_api = param.api, api = _param_api === void 0 ? '/api/chat' : _param_api, credentials = param.credentials, headers = param.headers, body = param.body, customFetch = param.fetch, prepareSendMessagesRequest = param.prepareSendMessagesRequest, prepareReconnectToStreamRequest = param.prepareReconnectToStreamRequest;
12849
+ _class_call_check(this, HttpChatTransport);
12850
+ _define_property(this, "api", void 0);
12851
+ _define_property(this, "credentials", void 0);
12852
+ _define_property(this, "headers", void 0);
12853
+ _define_property(this, "body", void 0);
12854
+ _define_property(this, "fetch", void 0);
12855
+ _define_property(this, "prepareSendMessagesRequest", void 0);
12856
+ _define_property(this, "prepareReconnectToStreamRequest", void 0);
12857
+ this.api = api;
12858
+ this.credentials = credentials;
12859
+ this.headers = headers;
12860
+ this.body = body;
12861
+ this.fetch = customFetch;
12862
+ this.prepareSendMessagesRequest = prepareSendMessagesRequest;
12863
+ this.prepareReconnectToStreamRequest = prepareReconnectToStreamRequest;
12864
+ }
12865
+ _create_class(HttpChatTransport, [
12866
+ {
12867
+ key: "sendMessages",
12868
+ value: function sendMessages(param) {
12869
+ var _this = this;
12870
+ var abortSignal = param.abortSignal, chatId = param.chatId, messages = param.messages, requestMetadata = param.requestMetadata, trigger = param.trigger, messageId = param.messageId, requestHeaders = param.headers, requestBody = param.body;
12871
+ var _this_fetch;
12872
+ var fetchFn = (_this_fetch = this.fetch) !== null && _this_fetch !== void 0 ? _this_fetch : fetch;
12873
+ // Resolve configurable values
12874
+ return Promise.all([
12875
+ resolveValue(this.credentials),
12876
+ resolveValue(this.headers),
12877
+ resolveValue(this.body)
12878
+ ]).then(function(param) {
12879
+ var _param = _sliced_to_array(param, 3), resolvedCredentials = _param[0], resolvedHeaders = _param[1], resolvedBody = _param[2];
12880
+ // Build default request options
12881
+ var api = _this.api;
12882
+ var body = _object_spread({
12883
+ id: chatId,
12884
+ messages: messages
12885
+ }, resolvedBody, requestBody);
12886
+ var headers = _object_spread({
12887
+ 'Content-Type': 'application/json'
12888
+ }, _instanceof(resolvedHeaders, Headers) ? Object.fromEntries(resolvedHeaders.entries()) : resolvedHeaders, _instanceof(requestHeaders, Headers) ? Object.fromEntries(requestHeaders.entries()) : requestHeaders);
12889
+ var credentials = resolvedCredentials;
12890
+ // Apply custom preparation if provided
12891
+ var prepareRequestBody = _object_spread({}, resolvedBody, requestBody);
12892
+ var preparePromise = _this.prepareSendMessagesRequest ? Promise.resolve(_this.prepareSendMessagesRequest({
12893
+ id: chatId,
12894
+ messages: messages,
12895
+ requestMetadata: requestMetadata,
12896
+ body: prepareRequestBody,
12897
+ credentials: resolvedCredentials,
12898
+ headers: resolvedHeaders,
12899
+ api: _this.api,
12900
+ trigger: trigger,
12901
+ messageId: messageId
12902
+ })) : Promise.resolve(null);
12903
+ return preparePromise.then(function(prepared) {
12904
+ if (prepared) {
12905
+ body = prepared.body;
12906
+ if (prepared.api) api = prepared.api;
12907
+ if (prepared.headers) {
12908
+ headers = _object_spread({
12909
+ 'Content-Type': 'application/json'
12910
+ }, _instanceof(prepared.headers, Headers) ? Object.fromEntries(prepared.headers.entries()) : prepared.headers);
12911
+ }
12912
+ if (prepared.credentials) credentials = prepared.credentials;
12913
+ }
12914
+ return fetchFn(api, {
12915
+ method: 'POST',
12916
+ headers: headers,
12917
+ body: JSON.stringify(body),
12918
+ signal: abortSignal,
12919
+ credentials: credentials
12920
+ }).then(function(response) {
12921
+ if (!response.ok) {
12922
+ return getHttpErrorMessage(response).then(function(message) {
12923
+ throw new Error(message);
12924
+ });
12925
+ }
12926
+ if (!response.body) {
12927
+ throw new Error('Response body is empty');
12928
+ }
12929
+ return _this.processResponseStream(response.body);
12930
+ });
12931
+ });
12932
+ });
12933
+ }
12934
+ },
12935
+ {
12936
+ key: "reconnectToStream",
12937
+ value: function reconnectToStream(param) {
12938
+ var _this = this;
12939
+ var chatId = param.chatId, requestHeaders = param.headers, requestBody = param.body;
12940
+ var _this_fetch;
12941
+ var fetchFn = (_this_fetch = this.fetch) !== null && _this_fetch !== void 0 ? _this_fetch : fetch;
12942
+ // Resolve configurable values
12943
+ return Promise.all([
12944
+ resolveValue(this.credentials),
12945
+ resolveValue(this.headers),
12946
+ resolveValue(this.body)
12947
+ ]).then(function(param) {
12948
+ var _param = _sliced_to_array(param, 3), resolvedCredentials = _param[0], resolvedHeaders = _param[1], resolvedBody = _param[2];
12949
+ // Build default request options
12950
+ var api = _this.api;
12951
+ var headers = _object_spread({}, _instanceof(resolvedHeaders, Headers) ? Object.fromEntries(resolvedHeaders.entries()) : resolvedHeaders, _instanceof(requestHeaders, Headers) ? Object.fromEntries(requestHeaders.entries()) : requestHeaders);
12952
+ var credentials = resolvedCredentials;
12953
+ // Apply custom preparation if provided
12954
+ var prepareRequestBody = _object_spread({}, resolvedBody, requestBody);
12955
+ var preparePromise = _this.prepareReconnectToStreamRequest ? Promise.resolve(_this.prepareReconnectToStreamRequest({
12956
+ id: chatId,
12957
+ requestMetadata: undefined,
12958
+ body: prepareRequestBody,
12959
+ credentials: resolvedCredentials,
12960
+ headers: resolvedHeaders,
12961
+ api: _this.api
12962
+ })) : Promise.resolve(null);
12963
+ return preparePromise.then(function(prepared) {
12964
+ if (prepared) {
12965
+ if (prepared.api) api = prepared.api;
12966
+ if (prepared.headers) {
12967
+ headers = _instanceof(prepared.headers, Headers) ? Object.fromEntries(prepared.headers.entries()) : prepared.headers;
12968
+ }
12969
+ if (prepared.credentials) credentials = prepared.credentials;
12970
+ }
12971
+ // GET request for reconnection
12972
+ return fetchFn("".concat(api, "?chatId=").concat(chatId), {
12973
+ method: 'GET',
12974
+ headers: headers,
12975
+ credentials: credentials
12976
+ }).then(function(response) {
12977
+ if (!response.ok) {
12978
+ // 404 means no stream to reconnect to, which is not an error
12979
+ if (response.status === 404) {
12980
+ return null;
12981
+ }
12982
+ return getHttpErrorMessage(response).then(function(message) {
12983
+ throw new Error(message);
12984
+ });
12985
+ }
12986
+ if (!response.body) {
12987
+ return null;
12988
+ }
12989
+ return _this.processResponseStream(response.body);
12990
+ });
12991
+ });
12992
+ });
12993
+ }
12994
+ }
12995
+ ]);
12996
+ return HttpChatTransport;
12997
+ }();
12998
+ /**
12999
+ * Default chat transport implementation using NDJSON streaming.
13000
+ */ var DefaultChatTransport = /*#__PURE__*/ function(HttpChatTransport) {
13001
+ _inherits(DefaultChatTransport, HttpChatTransport);
13002
+ function DefaultChatTransport() {
13003
+ var options = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {};
13004
+ _class_call_check(this, DefaultChatTransport);
13005
+ return _call_super(this, DefaultChatTransport, [
13006
+ options
13007
+ ]);
13008
+ }
13009
+ _create_class(DefaultChatTransport, [
13010
+ {
13011
+ key: "processResponseStream",
13012
+ value: function processResponseStream(stream) {
13013
+ return parseJsonEventStream(stream);
13014
+ }
13015
+ }
13016
+ ]);
13017
+ return DefaultChatTransport;
13018
+ }(HttpChatTransport);
13019
+
13020
+ var tryParseJson = function tryParseJson(value) {
13021
+ try {
13022
+ return JSON.parse(value);
13023
+ } catch (unused) {
13024
+ return undefined;
13025
+ }
13026
+ };
13027
+ var repairPartialJson = function repairPartialJson(value) {
13028
+ var repaired = value.trim();
13029
+ if (!repaired) {
13030
+ return repaired;
13031
+ }
13032
+ var inString = false;
13033
+ var isEscaped = false;
13034
+ var stack = [];
13035
+ for(var index = 0; index < repaired.length; index++){
13036
+ var char = repaired[index];
13037
+ if (inString) {
13038
+ if (isEscaped) {
13039
+ isEscaped = false;
13040
+ } else if (char === '\\') {
13041
+ isEscaped = true;
13042
+ } else if (char === '"') {
13043
+ inString = false;
13044
+ }
13045
+ continue;
13046
+ }
13047
+ if (char === '"') {
13048
+ inString = true;
13049
+ continue;
13050
+ }
13051
+ if (char === '{' || char === '[') {
13052
+ stack.push(char);
13053
+ continue;
13054
+ }
13055
+ if (char === '}' && stack[stack.length - 1] === '{') {
13056
+ stack.pop();
13057
+ continue;
13058
+ }
13059
+ if (char === ']' && stack[stack.length - 1] === '[') {
13060
+ stack.pop();
13061
+ }
13062
+ }
13063
+ if (inString && !isEscaped) {
13064
+ repaired += '"';
13065
+ }
13066
+ repaired = repaired.replace(RegExp(",\\s*$", "u"), '');
13067
+ if (stack.length > 0) {
13068
+ repaired += stack.reverse().map(function(opening) {
13069
+ return opening === '{' ? '}' : ']';
13070
+ }).join('');
13071
+ }
13072
+ return repaired.replace(RegExp(",\\s*([}\\]])", "gu"), '$1');
13073
+ };
13074
+ var parsePartialJson = function parsePartialJson(accumulatedRawJson, fallbackValue) {
13075
+ var normalized = accumulatedRawJson.trim();
13076
+ if (!normalized) {
13077
+ return fallbackValue;
13078
+ }
13079
+ var directParsed = tryParseJson(normalized);
13080
+ if (directParsed !== undefined) {
13081
+ return directParsed;
13082
+ }
13083
+ var repairedParsed = tryParseJson(repairPartialJson(normalized));
13084
+ if (repairedParsed !== undefined) {
13085
+ return repairedParsed;
13086
+ }
13087
+ return fallbackValue;
13088
+ };
12868
13089
 
12869
13090
  var _computedKey$1;
12870
13091
  var defaultGuardrailFallbackResponse = 'Sorry, we are not able to generate a response at the moment.';
@@ -14327,285 +14548,44 @@
14327
14548
  key: "messages",
14328
14549
  get: function get() {
14329
14550
  return this._messages;
14330
- },
14331
- set: function set(newMessages) {
14332
- this._messages = _to_consumable_array(newMessages);
14333
- this._callMessagesCallbacks();
14334
- }
14335
- }
14336
- ]);
14337
- return ChatState;
14338
- }();
14339
- _computedKey3 = '~registerMessagesCallback', _computedKey4 = '~registerStatusCallback', _computedKey5 = '~registerErrorCallback';
14340
- var _computedKey9 = _computedKey3, _computedKey10 = _computedKey4, _computedKey11 = _computedKey5;
14341
- var Chat = /*#__PURE__*/ function(AbstractChat) {
14342
- _inherits(Chat, AbstractChat);
14343
- function Chat(_0) {
14344
- _class_call_check(this, Chat);
14345
- var _this;
14346
- var messages = _0.messages, agentId = _0.agentId, _0_persistence = _0.persistence, persistence = _0_persistence === void 0 ? true : _0_persistence, init = _object_without_properties(_0, [
14347
- "messages",
14348
- "agentId",
14349
- "persistence"
14350
- ]);
14351
- var state = new ChatState(agentId, messages, persistence);
14352
- _this = _call_super(this, Chat, [
14353
- _object_spread_props(_object_spread({}, init), {
14354
- state: state
14355
- })
14356
- ]), _define_property(_this, "_state", void 0), _define_property(_this, _computedKey9, function(onChange) {
14357
- return _this._state['~registerMessagesCallback'](onChange);
14358
- }), _define_property(_this, _computedKey10, function(onChange) {
14359
- return _this._state['~registerStatusCallback'](onChange);
14360
- }), _define_property(_this, _computedKey11, function(onChange) {
14361
- return _this._state['~registerErrorCallback'](onChange);
14362
- });
14363
- _this._state = state;
14364
- return _this;
14365
- }
14366
- return Chat;
14367
- }(AbstractChat);
14368
-
14369
- // Centralizes the "open the chat from an entry point" behavior shared by the
14370
- // SearchBox AI button, the Autocomplete AI button, prompt suggestions, and any
14371
- // future entry point. The chat is always opened; the message is only sent when
14372
- // it is non-empty and the chat is not already processing a message.
14373
- // Returns true when a message was submitted, so callers can clear their input.
14374
- function openChat(chatRenderState) {
14375
- var _ref = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {}, message = _ref.message, referer = _ref.referer, turnContext = _ref.turnContext;
14376
- var _ref1;
14377
- var _chatRenderState_setOpen;
14378
- if (!chatRenderState) {
14379
- return false;
14380
- }
14381
- var trimmed = (_ref1 = message === null || message === void 0 ? void 0 : message.trim()) !== null && _ref1 !== void 0 ? _ref1 : '';
14382
- if (!trimmed) {
14383
- if (chatRenderState.focusInput) {
14384
- chatRenderState.focusInput();
14385
- } else {
14386
- var _chatRenderState_setOpen1;
14387
- (_chatRenderState_setOpen1 = chatRenderState.setOpen) === null || _chatRenderState_setOpen1 === void 0 ? void 0 : _chatRenderState_setOpen1.call(chatRenderState, true);
14388
- }
14389
- return false;
14390
- }
14391
- (_chatRenderState_setOpen = chatRenderState.setOpen) === null || _chatRenderState_setOpen === void 0 ? void 0 : _chatRenderState_setOpen.call(chatRenderState, true);
14392
- if (isChatBusy(chatRenderState) || !chatRenderState.sendMessage) {
14393
- return false;
14394
- }
14395
- chatRenderState.sendMessage(_object_spread({
14396
- text: trimmed
14397
- }, turnContext ? {
14398
- metadata: {
14399
- turnContext: turnContext
14400
- }
14401
- } : {}), referer ? {
14402
- headers: {
14403
- 'x-algolia-referer': referer
14404
- }
14405
- } : undefined);
14406
- return true;
14407
- }
14408
- function isChatBusy(chatRenderState) {
14409
- return (chatRenderState === null || chatRenderState === void 0 ? void 0 : chatRenderState.status) === 'submitted' || (chatRenderState === null || chatRenderState === void 0 ? void 0 : chatRenderState.status) === 'streaming';
14410
- }
14411
-
14412
- var SearchIndexToolType = 'algolia_search_index';
14413
-
14414
- function flat(arr) {
14415
- return arr.reduce(function(acc, array) {
14416
- return acc.concat(array);
14417
- }, []);
14418
- }
14419
-
14420
- /**
14421
- * Reads a human-readable message from a failed HTTP response body when the
14422
- * server returns JSON such as `{ "message": "..." }` (the shared
14423
- * `ErrorResponse` shape used by every status code), falling back to the HTTP
14424
- * status line when the body is empty or not parseable.
14425
- */ function getHttpErrorMessage(response) {
14426
- var fallback = "HTTP error: ".concat(response.status, " ").concat(response.statusText);
14427
- return response.text().then(function(text) {
14428
- var _tryParseErrorMessage;
14429
- return (_tryParseErrorMessage = tryParseErrorMessage(text)) !== null && _tryParseErrorMessage !== void 0 ? _tryParseErrorMessage : fallback;
14430
- }).catch(function() {
14431
- return fallback;
14432
- });
14433
- }
14434
- /**
14435
- * Abstract base class for HTTP-based chat transports.
14436
- */ var HttpChatTransport = /*#__PURE__*/ function() {
14437
- function HttpChatTransport(param) {
14438
- var _param_api = param.api, api = _param_api === void 0 ? '/api/chat' : _param_api, credentials = param.credentials, headers = param.headers, body = param.body, customFetch = param.fetch, prepareSendMessagesRequest = param.prepareSendMessagesRequest, prepareReconnectToStreamRequest = param.prepareReconnectToStreamRequest;
14439
- _class_call_check(this, HttpChatTransport);
14440
- _define_property(this, "api", void 0);
14441
- _define_property(this, "credentials", void 0);
14442
- _define_property(this, "headers", void 0);
14443
- _define_property(this, "body", void 0);
14444
- _define_property(this, "fetch", void 0);
14445
- _define_property(this, "prepareSendMessagesRequest", void 0);
14446
- _define_property(this, "prepareReconnectToStreamRequest", void 0);
14447
- this.api = api;
14448
- this.credentials = credentials;
14449
- this.headers = headers;
14450
- this.body = body;
14451
- this.fetch = customFetch;
14452
- this.prepareSendMessagesRequest = prepareSendMessagesRequest;
14453
- this.prepareReconnectToStreamRequest = prepareReconnectToStreamRequest;
14454
- }
14455
- _create_class(HttpChatTransport, [
14456
- {
14457
- key: "sendMessages",
14458
- value: function sendMessages(param) {
14459
- var _this = this;
14460
- var abortSignal = param.abortSignal, chatId = param.chatId, messages = param.messages, requestMetadata = param.requestMetadata, trigger = param.trigger, messageId = param.messageId, requestHeaders = param.headers, requestBody = param.body;
14461
- var _this_fetch;
14462
- var fetchFn = (_this_fetch = this.fetch) !== null && _this_fetch !== void 0 ? _this_fetch : fetch;
14463
- // Resolve configurable values
14464
- return Promise.all([
14465
- resolveValue(this.credentials),
14466
- resolveValue(this.headers),
14467
- resolveValue(this.body)
14468
- ]).then(function(param) {
14469
- var _param = _sliced_to_array(param, 3), resolvedCredentials = _param[0], resolvedHeaders = _param[1], resolvedBody = _param[2];
14470
- // Build default request options
14471
- var api = _this.api;
14472
- var body = _object_spread({
14473
- id: chatId,
14474
- messages: messages
14475
- }, resolvedBody, requestBody);
14476
- var headers = _object_spread({
14477
- 'Content-Type': 'application/json'
14478
- }, _instanceof(resolvedHeaders, Headers) ? Object.fromEntries(resolvedHeaders.entries()) : resolvedHeaders, _instanceof(requestHeaders, Headers) ? Object.fromEntries(requestHeaders.entries()) : requestHeaders);
14479
- var credentials = resolvedCredentials;
14480
- // Apply custom preparation if provided
14481
- var prepareRequestBody = _object_spread({}, resolvedBody, requestBody);
14482
- var preparePromise = _this.prepareSendMessagesRequest ? Promise.resolve(_this.prepareSendMessagesRequest({
14483
- id: chatId,
14484
- messages: messages,
14485
- requestMetadata: requestMetadata,
14486
- body: prepareRequestBody,
14487
- credentials: resolvedCredentials,
14488
- headers: resolvedHeaders,
14489
- api: _this.api,
14490
- trigger: trigger,
14491
- messageId: messageId
14492
- })) : Promise.resolve(null);
14493
- return preparePromise.then(function(prepared) {
14494
- if (prepared) {
14495
- body = prepared.body;
14496
- if (prepared.api) api = prepared.api;
14497
- if (prepared.headers) {
14498
- headers = _object_spread({
14499
- 'Content-Type': 'application/json'
14500
- }, _instanceof(prepared.headers, Headers) ? Object.fromEntries(prepared.headers.entries()) : prepared.headers);
14501
- }
14502
- if (prepared.credentials) credentials = prepared.credentials;
14503
- }
14504
- return fetchFn(api, {
14505
- method: 'POST',
14506
- headers: headers,
14507
- body: JSON.stringify(body),
14508
- signal: abortSignal,
14509
- credentials: credentials
14510
- }).then(function(response) {
14511
- if (!response.ok) {
14512
- return getHttpErrorMessage(response).then(function(message) {
14513
- throw new Error(message);
14514
- });
14515
- }
14516
- if (!response.body) {
14517
- throw new Error('Response body is empty');
14518
- }
14519
- return _this.processResponseStream(response.body);
14520
- });
14521
- });
14522
- });
14523
- }
14524
- },
14525
- {
14526
- key: "reconnectToStream",
14527
- value: function reconnectToStream(param) {
14528
- var _this = this;
14529
- var chatId = param.chatId, requestHeaders = param.headers, requestBody = param.body;
14530
- var _this_fetch;
14531
- var fetchFn = (_this_fetch = this.fetch) !== null && _this_fetch !== void 0 ? _this_fetch : fetch;
14532
- // Resolve configurable values
14533
- return Promise.all([
14534
- resolveValue(this.credentials),
14535
- resolveValue(this.headers),
14536
- resolveValue(this.body)
14537
- ]).then(function(param) {
14538
- var _param = _sliced_to_array(param, 3), resolvedCredentials = _param[0], resolvedHeaders = _param[1], resolvedBody = _param[2];
14539
- // Build default request options
14540
- var api = _this.api;
14541
- var headers = _object_spread({}, _instanceof(resolvedHeaders, Headers) ? Object.fromEntries(resolvedHeaders.entries()) : resolvedHeaders, _instanceof(requestHeaders, Headers) ? Object.fromEntries(requestHeaders.entries()) : requestHeaders);
14542
- var credentials = resolvedCredentials;
14543
- // Apply custom preparation if provided
14544
- var prepareRequestBody = _object_spread({}, resolvedBody, requestBody);
14545
- var preparePromise = _this.prepareReconnectToStreamRequest ? Promise.resolve(_this.prepareReconnectToStreamRequest({
14546
- id: chatId,
14547
- requestMetadata: undefined,
14548
- body: prepareRequestBody,
14549
- credentials: resolvedCredentials,
14550
- headers: resolvedHeaders,
14551
- api: _this.api
14552
- })) : Promise.resolve(null);
14553
- return preparePromise.then(function(prepared) {
14554
- if (prepared) {
14555
- if (prepared.api) api = prepared.api;
14556
- if (prepared.headers) {
14557
- headers = _instanceof(prepared.headers, Headers) ? Object.fromEntries(prepared.headers.entries()) : prepared.headers;
14558
- }
14559
- if (prepared.credentials) credentials = prepared.credentials;
14560
- }
14561
- // GET request for reconnection
14562
- return fetchFn("".concat(api, "?chatId=").concat(chatId), {
14563
- method: 'GET',
14564
- headers: headers,
14565
- credentials: credentials
14566
- }).then(function(response) {
14567
- if (!response.ok) {
14568
- // 404 means no stream to reconnect to, which is not an error
14569
- if (response.status === 404) {
14570
- return null;
14571
- }
14572
- return getHttpErrorMessage(response).then(function(message) {
14573
- throw new Error(message);
14574
- });
14575
- }
14576
- if (!response.body) {
14577
- return null;
14578
- }
14579
- return _this.processResponseStream(response.body);
14580
- });
14581
- });
14582
- });
14551
+ },
14552
+ set: function set(newMessages) {
14553
+ this._messages = _to_consumable_array(newMessages);
14554
+ this._callMessagesCallbacks();
14583
14555
  }
14584
14556
  }
14585
14557
  ]);
14586
- return HttpChatTransport;
14558
+ return ChatState;
14587
14559
  }();
14588
- /**
14589
- * Default chat transport implementation using NDJSON streaming.
14590
- */ var DefaultChatTransport = /*#__PURE__*/ function(HttpChatTransport) {
14591
- _inherits(DefaultChatTransport, HttpChatTransport);
14592
- function DefaultChatTransport() {
14593
- var options = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {};
14594
- _class_call_check(this, DefaultChatTransport);
14595
- return _call_super(this, DefaultChatTransport, [
14596
- options
14560
+ _computedKey3 = '~registerMessagesCallback', _computedKey4 = '~registerStatusCallback', _computedKey5 = '~registerErrorCallback';
14561
+ var _computedKey9 = _computedKey3, _computedKey10 = _computedKey4, _computedKey11 = _computedKey5;
14562
+ var Chat = /*#__PURE__*/ function(AbstractChat) {
14563
+ _inherits(Chat, AbstractChat);
14564
+ function Chat(_0) {
14565
+ _class_call_check(this, Chat);
14566
+ var _this;
14567
+ var messages = _0.messages, agentId = _0.agentId, _0_persistence = _0.persistence, persistence = _0_persistence === void 0 ? true : _0_persistence, init = _object_without_properties(_0, [
14568
+ "messages",
14569
+ "agentId",
14570
+ "persistence"
14597
14571
  ]);
14572
+ var state = new ChatState(agentId, messages, persistence);
14573
+ _this = _call_super(this, Chat, [
14574
+ _object_spread_props(_object_spread({}, init), {
14575
+ state: state
14576
+ })
14577
+ ]), _define_property(_this, "_state", void 0), _define_property(_this, _computedKey9, function(onChange) {
14578
+ return _this._state['~registerMessagesCallback'](onChange);
14579
+ }), _define_property(_this, _computedKey10, function(onChange) {
14580
+ return _this._state['~registerStatusCallback'](onChange);
14581
+ }), _define_property(_this, _computedKey11, function(onChange) {
14582
+ return _this._state['~registerErrorCallback'](onChange);
14583
+ });
14584
+ _this._state = state;
14585
+ return _this;
14598
14586
  }
14599
- _create_class(DefaultChatTransport, [
14600
- {
14601
- key: "processResponseStream",
14602
- value: function processResponseStream(stream) {
14603
- return parseJsonEventStream(stream);
14604
- }
14605
- }
14606
- ]);
14607
- return DefaultChatTransport;
14608
- }(HttpChatTransport);
14587
+ return Chat;
14588
+ }(AbstractChat);
14609
14589
 
14610
14590
  var withUsage$q = createDocumentationMessageGenerator({
14611
14591
  name: 'chat',
@@ -14735,11 +14715,6 @@
14735
14715
  "requiresSearch"
14736
14716
  ]);
14737
14717
  var normalizedPersistence = normalizePersistence(persistence, 'chat' in options);
14738
- // Compatibility shim with Algolia MCP Server search tool, which suffixes
14739
- // the tool name with the index name (`searchIndex_products`).
14740
- var resolveTool = function resolveTool(toolName) {
14741
- return tools[toolName] || (toolName.startsWith("".concat(SearchIndexToolType, "_")) ? tools[SearchIndexToolType] : undefined);
14742
- };
14743
14718
  var _chatInstance;
14744
14719
  var input = '';
14745
14720
  var open = false;
@@ -14767,21 +14742,44 @@
14767
14742
  return unsubscribe();
14768
14743
  });
14769
14744
  };
14770
- // Extract suggestions from the last assistant message's data-suggestions part
14771
- var getSuggestionsFromMessages = function getSuggestionsFromMessages(messages) {
14772
- // Find the last assistant message (iterate from end)
14773
- var lastAssistantMessage = _to_consumable_array(messages).reverse().find(function(message) {
14745
+ var findSuggestionsPart = function findSuggestionsPart(message) {
14746
+ var _message_parts;
14747
+ return message === null || message === void 0 ? void 0 : (_message_parts = message.parts) === null || _message_parts === void 0 ? void 0 : _message_parts.find(function(part) {
14748
+ var _part_data;
14749
+ return 'type' in part && part.type === 'data-suggestions' && 'data' in part && Array.isArray((_part_data = part.data) === null || _part_data === void 0 ? void 0 : _part_data.suggestions);
14750
+ });
14751
+ };
14752
+ var findLastAssistantMessage = function findLastAssistantMessage(messages) {
14753
+ return _to_consumable_array(messages).reverse().find(function(message) {
14774
14754
  return message.role === 'assistant' && message.parts;
14775
14755
  });
14776
- if (!(lastAssistantMessage === null || lastAssistantMessage === void 0 ? void 0 : lastAssistantMessage.parts)) {
14777
- return undefined;
14756
+ };
14757
+ // Extract suggestions from the last assistant message's data-suggestions part
14758
+ var getSuggestionsFromMessages = function getSuggestionsFromMessages(messages) {
14759
+ var _findSuggestionsPart;
14760
+ return (_findSuggestionsPart = findSuggestionsPart(findLastAssistantMessage(messages))) === null || _findSuggestionsPart === void 0 ? void 0 : _findSuggestionsPart.data.suggestions;
14761
+ };
14762
+ // "Still coming" has to be inferred: the turn is running and has no
14763
+ // `data-suggestions` part yet. Expecting any at all needs evidence, or an
14764
+ // agent that never sends them would sit under a placeholder forever.
14765
+ var getSuggestionsStatus = function getSuggestionsStatus(messages) {
14766
+ var _lastAssistantMessage_metadata;
14767
+ var status = _chatInstance.status;
14768
+ if (status !== 'submitted' && status !== 'streaming') {
14769
+ return 'idle';
14778
14770
  }
14779
- // Find the data-suggestions part
14780
- var suggestionsPart = lastAssistantMessage.parts.find(function(part) {
14781
- var _part_data;
14782
- return 'type' in part && part.type === 'data-suggestions' && 'data' in part && Array.isArray((_part_data = part.data) === null || _part_data === void 0 ? void 0 : _part_data.suggestions);
14771
+ var lastAssistantMessage = findLastAssistantMessage(messages);
14772
+ if (findSuggestionsPart(lastAssistantMessage)) {
14773
+ return 'idle';
14774
+ }
14775
+ var declaresSuggestions = (lastAssistantMessage === null || lastAssistantMessage === void 0 ? void 0 : (_lastAssistantMessage_metadata = lastAssistantMessage.metadata) === null || _lastAssistantMessage_metadata === void 0 ? void 0 : _lastAssistantMessage_metadata.suggestionsEnabled) === true;
14776
+ if (declaresSuggestions) {
14777
+ return 'loading';
14778
+ }
14779
+ var hasSuggestionsHistory = messages.some(function(message) {
14780
+ return message !== lastAssistantMessage && message.role === 'assistant' && Boolean(findSuggestionsPart(message));
14783
14781
  });
14784
- return suggestionsPart === null || suggestionsPart === void 0 ? void 0 : suggestionsPart.data.suggestions;
14782
+ return hasSuggestionsHistory ? 'loading' : 'idle';
14785
14783
  };
14786
14784
  var setMessages = function setMessages(messagesParam) {
14787
14785
  if (typeof messagesParam === 'function') {
@@ -14924,14 +14922,14 @@
14924
14922
  sendAutomaticallyWhen: sendAutomaticallyWhen,
14925
14923
  transport: transport,
14926
14924
  shouldRepairToolInput: function shouldRepairToolInput(toolName) {
14927
- var tool = resolveTool(toolName);
14925
+ var tool = findTool(toolName, tools);
14928
14926
  if (!tool) return true;
14929
14927
  return Boolean(tool.streamInput);
14930
14928
  },
14931
14929
  resolveCancelledToolOutput: function resolveCancelledToolOutput(param) {
14932
14930
  var toolName = param.toolName, toolCallId = param.toolCallId, input = param.input;
14933
- var _resolveTool;
14934
- var cancelOutput = (_resolveTool = resolveTool(toolName)) === null || _resolveTool === void 0 ? void 0 : _resolveTool.cancelOutput;
14931
+ var _findTool;
14932
+ var cancelOutput = (_findTool = findTool(toolName, tools)) === null || _findTool === void 0 ? void 0 : _findTool.cancelOutput;
14935
14933
  if (!cancelOutput) return undefined;
14936
14934
  try {
14937
14935
  var output = cancelOutput({
@@ -14948,7 +14946,7 @@
14948
14946
  },
14949
14947
  onToolCall: function onToolCall(param, submitToolResult) {
14950
14948
  var toolCall = param.toolCall;
14951
- var tool = resolveTool(toolCall.toolName);
14949
+ var tool = findTool(toolCall.toolName, tools);
14952
14950
  if (!tool) {
14953
14951
  return submitToolResult({
14954
14952
  output: 'No tool implemented for "'.concat(toolCall.toolName, '".'),
@@ -15178,6 +15176,7 @@
15178
15176
  '~isOpenStatePersistenceEnabled': normalizedPersistence.open,
15179
15177
  setMessages: setMessages,
15180
15178
  suggestions: getSuggestionsFromMessages(_chatInstance.messages),
15179
+ suggestionsStatus: getSuggestionsStatus(_chatInstance.messages),
15181
15180
  clearMessages: clearMessages,
15182
15181
  tools: toolsWithAddToolResult,
15183
15182
  records: records,
@@ -15281,44 +15280,30 @@
15281
15280
  });
15282
15281
  }
15283
15282
 
15284
- function buildEndpoint(param) {
15285
- var appId = param.appId, agentId = param.agentId;
15286
- return "https://".concat(appId, ".algolia.net/agent-studio/1/agents/").concat(agentId, "/tasks");
15283
+ function isHeaders$1(headers) {
15284
+ return !Array.isArray(headers) && 'entries' in headers && typeof headers.entries === 'function';
15287
15285
  }
15288
- function resolveEndpoint(params) {
15289
- if (params.transport) {
15290
- return {
15291
- endpoint: params.transport.api,
15292
- headers: params.transport.headers || {},
15293
- prepareSendMessagesRequest: params.transport.prepareSendMessagesRequest
15294
- };
15286
+ function headersToRecord$1(headers) {
15287
+ if (!headers) {
15288
+ return {};
15295
15289
  }
15296
- if (!params.appId || !params.apiKey || !params.agentId) {
15297
- throw new Error('[tasks] Either `transport` or `{ appId, apiKey, agentId }` is required.');
15290
+ if (isHeaders$1(headers)) {
15291
+ return Object.fromEntries(headers.entries());
15298
15292
  }
15299
- var headers = {
15300
- 'x-algolia-application-id': params.appId,
15301
- 'x-algolia-api-key': params.apiKey
15302
- };
15303
- if (params.algoliaAgent) {
15304
- headers['x-algolia-agent'] = "".concat(params.algoliaAgent, "; tasks");
15293
+ if (Array.isArray(headers)) {
15294
+ return Object.fromEntries(headers);
15305
15295
  }
15306
- return {
15307
- endpoint: buildEndpoint({
15308
- appId: params.appId,
15309
- agentId: params.agentId
15310
- }),
15311
- headers: headers
15312
- };
15296
+ return headers;
15313
15297
  }
15314
-
15315
- function buildTaskPayload(param) {
15316
- var task = param.task, input = param.input, prepareRequest = param.prepareRequest;
15317
- var payload = {
15318
- task: task,
15319
- input: input
15320
- };
15321
- return prepareRequest ? prepareRequest(payload).body : payload;
15298
+ function withJsonContentType(headers) {
15299
+ var merged = _object_spread({}, headersToRecord$1(headers));
15300
+ Object.keys(merged).forEach(function(name) {
15301
+ if (name.toLowerCase() === 'content-type') {
15302
+ delete merged[name];
15303
+ }
15304
+ });
15305
+ merged['Content-Type'] = 'application/json';
15306
+ return merged;
15322
15307
  }
15323
15308
  function withStreamParam(url) {
15324
15309
  return url.includes('?') ? "".concat(url, "&stream=true") : "".concat(url, "?stream=true");
@@ -15326,6 +15311,40 @@
15326
15311
  function resolveStreamedOutput(data, previous) {
15327
15312
  return typeof data === 'string' ? parsePartialJson(data, previous) : data;
15328
15313
  }
15314
+ function createTaskPreparationContext(context) {
15315
+ function hideProperty(key) {
15316
+ var value = context[key];
15317
+ Object.defineProperty(context, key, {
15318
+ configurable: true,
15319
+ enumerable: false,
15320
+ get: function get() {
15321
+ return value;
15322
+ },
15323
+ set: function set(nextValue) {
15324
+ Reflect.deleteProperty(context, key);
15325
+ Object.defineProperty(context, key, {
15326
+ configurable: true,
15327
+ enumerable: true,
15328
+ value: nextValue,
15329
+ writable: true
15330
+ });
15331
+ }
15332
+ });
15333
+ }
15334
+ // Rich metadata stays out of legacy body spreads until assigned as payload.
15335
+ hideProperty('stream');
15336
+ hideProperty('body');
15337
+ hideProperty('credentials');
15338
+ hideProperty('headers');
15339
+ hideProperty('api');
15340
+ return context;
15341
+ }
15342
+ function unwrap(envelope) {
15343
+ if ((typeof envelope === "undefined" ? "undefined" : _type_of(envelope)) === 'object' && envelope !== null && 'output' in envelope) {
15344
+ return envelope.output;
15345
+ }
15346
+ return undefined;
15347
+ }
15329
15348
  function consumeTaskStream(body, onData) {
15330
15349
  return new Promise(function(resolve, reject) {
15331
15350
  var chunkStream = parseJsonEventStream(body);
@@ -15334,10 +15353,6 @@
15334
15353
  if (!chunk) {
15335
15354
  return;
15336
15355
  }
15337
- // A terminal `error` event aborts the task: reject rather than let the
15338
- // stream close and resolve the last partial snapshot as a success.
15339
- // Throwing here lets `processStream` release the reader and stop
15340
- // consuming; the rejection propagates to the caller's `.catch`.
15341
15356
  if (chunk.type === 'error') {
15342
15357
  throw new Error(chunk.errorText || 'Task stream error');
15343
15358
  }
@@ -15353,48 +15368,207 @@
15353
15368
  }, reject);
15354
15369
  });
15355
15370
  }
15356
- function fetchTask(param) {
15357
- var endpoint = param.endpoint, headers = param.headers, payload = param.payload, onData = param.onData, _param_stream = param.stream, stream = _param_stream === void 0 ? true : _param_stream;
15358
- return fetch(stream ? withStreamParam(endpoint) : endpoint, {
15359
- method: 'POST',
15360
- headers: _object_spread_props(_object_spread({}, headers), {
15361
- 'Content-Type': 'application/json'
15362
- }),
15363
- body: JSON.stringify(payload)
15364
- }).then(function(response) {
15365
- var _response_headers_get, _response_headers;
15366
- if (!response.ok) {
15367
- throw new Error("HTTP error ".concat(response.status));
15368
- }
15369
- var contentType = ((_response_headers = response.headers) === null || _response_headers === void 0 ? void 0 : (_response_headers_get = _response_headers.get) === null || _response_headers_get === void 0 ? void 0 : _response_headers_get.call(_response_headers, 'content-type')) || '';
15370
- if (stream && response.body && contentType.includes('text/event-stream')) {
15371
- return consumeTaskStream(response.body, onData);
15371
+ /** Default HTTP transport for named Tasks requests and task-output streams. */ var DefaultTaskTransport = /*#__PURE__*/ function() {
15372
+ function DefaultTaskTransport() {
15373
+ var _ref = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {}, _ref_api = _ref.api, api = _ref_api === void 0 ? '/api/tasks' : _ref_api, credentials = _ref.credentials, headers = _ref.headers, body = _ref.body, customFetch = _ref.fetch, prepareSendMessagesRequest = _ref.prepareSendMessagesRequest;
15374
+ _class_call_check(this, DefaultTaskTransport);
15375
+ _define_property(this, "api", void 0);
15376
+ _define_property(this, "credentials", void 0);
15377
+ _define_property(this, "headers", void 0);
15378
+ _define_property(this, "body", void 0);
15379
+ _define_property(this, "fetch", void 0);
15380
+ _define_property(this, "prepareSendMessagesRequest", void 0);
15381
+ this.api = api;
15382
+ this.credentials = credentials;
15383
+ this.headers = headers;
15384
+ this.body = body;
15385
+ this.fetch = customFetch;
15386
+ this.prepareSendMessagesRequest = prepareSendMessagesRequest;
15387
+ }
15388
+ _create_class(DefaultTaskTransport, [
15389
+ {
15390
+ key: "sendTask",
15391
+ value: function sendTask(param) {
15392
+ var task = param.task, input = param.input, stream = param.stream, onData = param.onData;
15393
+ return this.sendTaskRequest({
15394
+ task: task,
15395
+ input: input,
15396
+ stream: stream,
15397
+ onData: onData ? function(data) {
15398
+ return onData(unwrap(data));
15399
+ } : undefined
15400
+ }).then(unwrap);
15401
+ }
15402
+ },
15403
+ {
15404
+ /** @internal */ key: "sendTaskRequest",
15405
+ value: function sendTaskRequest(param) {
15406
+ var _this = this;
15407
+ var task = param.task, input = param.input, stream = param.stream, onData = param.onData;
15408
+ var _this_fetch;
15409
+ var fetchFn = (_this_fetch = this.fetch) !== null && _this_fetch !== void 0 ? _this_fetch : fetch;
15410
+ return Promise.all([
15411
+ resolveValue(this.credentials),
15412
+ resolveValue(this.headers),
15413
+ resolveValue(this.body)
15414
+ ]).then(function(param) {
15415
+ var _param = _sliced_to_array(param, 3), resolvedCredentials = _param[0], resolvedHeaders = _param[1], resolvedBody = _param[2];
15416
+ var api = _this.api;
15417
+ var credentials = resolvedCredentials;
15418
+ var headers = withJsonContentType(resolvedHeaders);
15419
+ var body = _object_spread({
15420
+ task: task,
15421
+ input: input
15422
+ }, resolvedBody);
15423
+ var preparedBody = resolvedBody ? _object_spread({}, resolvedBody) : undefined;
15424
+ var preparePromise = _this.prepareSendMessagesRequest ? Promise.resolve(_this.prepareSendMessagesRequest(createTaskPreparationContext({
15425
+ task: task,
15426
+ input: input,
15427
+ stream: stream,
15428
+ body: preparedBody,
15429
+ credentials: resolvedCredentials,
15430
+ headers: resolvedHeaders,
15431
+ api: _this.api
15432
+ }))) : Promise.resolve(null);
15433
+ return preparePromise.then(function(prepared) {
15434
+ if (prepared) {
15435
+ body = prepared.body;
15436
+ if (prepared.api) {
15437
+ api = prepared.api;
15438
+ }
15439
+ if (prepared.credentials) {
15440
+ credentials = prepared.credentials;
15441
+ }
15442
+ if (prepared.headers) {
15443
+ headers = withJsonContentType(prepared.headers);
15444
+ }
15445
+ }
15446
+ var request = {
15447
+ method: 'POST',
15448
+ headers: headers,
15449
+ body: JSON.stringify(body)
15450
+ };
15451
+ if (credentials !== undefined) {
15452
+ request.credentials = credentials;
15453
+ }
15454
+ return fetchFn(stream ? withStreamParam(api) : api, request).then(function(response) {
15455
+ var _response_headers_get, _response_headers;
15456
+ if (!response.ok) {
15457
+ throw new Error("HTTP error ".concat(response.status));
15458
+ }
15459
+ var contentType = ((_response_headers = response.headers) === null || _response_headers === void 0 ? void 0 : (_response_headers_get = _response_headers.get) === null || _response_headers_get === void 0 ? void 0 : _response_headers_get.call(_response_headers, 'content-type')) || '';
15460
+ if (stream && response.body && contentType.includes('text/event-stream')) {
15461
+ return consumeTaskStream(response.body, onData);
15462
+ }
15463
+ return response.json();
15464
+ });
15465
+ });
15466
+ });
15467
+ }
15372
15468
  }
15373
- return response.json();
15469
+ ]);
15470
+ return DefaultTaskTransport;
15471
+ }();
15472
+
15473
+ function buildEndpoint(param) {
15474
+ var appId = param.appId, agentId = param.agentId;
15475
+ return "https://".concat(appId, ".algolia.net/agent-studio/1/agents/").concat(agentId, "/tasks");
15476
+ }
15477
+ function isHeaders(headers) {
15478
+ return !Array.isArray(headers) && 'entries' in headers && typeof headers.entries === 'function';
15479
+ }
15480
+ function headersToRecord(headers) {
15481
+ if (!headers) {
15482
+ return {};
15483
+ }
15484
+ if (isHeaders(headers)) {
15485
+ return Object.fromEntries(headers.entries());
15486
+ }
15487
+ if (Array.isArray(headers)) {
15488
+ return Object.fromEntries(headers);
15489
+ }
15490
+ return _object_spread({}, headers);
15491
+ }
15492
+ function mergeProtectedHeaders(headers, protectedHeaders) {
15493
+ var merged = headersToRecord(headers);
15494
+ Object.entries(protectedHeaders).forEach(function(param) {
15495
+ var _param = _sliced_to_array(param, 2), protectedName = _param[0], value = _param[1];
15496
+ Object.keys(merged).forEach(function(name) {
15497
+ if (name.toLowerCase() === protectedName.toLowerCase()) {
15498
+ delete merged[name];
15499
+ }
15500
+ });
15501
+ merged[protectedName] = value;
15374
15502
  });
15503
+ return merged;
15375
15504
  }
15376
- function unwrap(envelope) {
15377
- return envelope === null || envelope === void 0 ? void 0 : envelope.output;
15505
+ /** @internal */ function createTaskTransport(param) {
15506
+ var _param_transport = param.transport, transport = _param_transport === void 0 ? {} : _param_transport, appId = param.appId, apiKey = param.apiKey, agentId = param.agentId, algoliaAgent = param.algoliaAgent;
15507
+ var _transport_api;
15508
+ if (!agentId) {
15509
+ return new DefaultTaskTransport(transport);
15510
+ }
15511
+ if (!appId || !apiKey) {
15512
+ throw new Error('[tasks] `appId` and `apiKey` are required when `agentId` is provided.');
15513
+ }
15514
+ var protectedHeaders = {
15515
+ 'x-algolia-application-id': appId,
15516
+ 'x-algolia-api-key': apiKey
15517
+ };
15518
+ if (algoliaAgent) {
15519
+ protectedHeaders['x-algolia-agent'] = "".concat(algoliaAgent, "; tasks");
15520
+ }
15521
+ var originalPrepare = transport.prepareSendMessagesRequest;
15522
+ var prepareSendMessagesRequest = originalPrepare ? function(request) {
15523
+ return Promise.resolve(originalPrepare(request)).then(function(prepared) {
15524
+ return _object_spread_props(_object_spread({}, prepared), {
15525
+ headers: prepared.headers ? mergeProtectedHeaders(prepared.headers, protectedHeaders) : undefined
15526
+ });
15527
+ });
15528
+ } : undefined;
15529
+ return new DefaultTaskTransport(_object_spread_props(_object_spread({}, transport), {
15530
+ api: (_transport_api = transport.api) !== null && _transport_api !== void 0 ? _transport_api : buildEndpoint({
15531
+ appId: appId,
15532
+ agentId: agentId
15533
+ }),
15534
+ headers: function headers() {
15535
+ return Promise.resolve(resolveValue(transport.headers)).then(function(headers) {
15536
+ return mergeProtectedHeaders(headers, protectedHeaders);
15537
+ });
15538
+ },
15539
+ prepareSendMessagesRequest: prepareSendMessagesRequest
15540
+ }));
15378
15541
  }
15379
- function createTaskRunner(param) {
15380
- var endpoint = param.endpoint, headers = param.headers, task = param.task, _param_stream = param.stream, stream = _param_stream === void 0 ? true : _param_stream, prepareRequest = param.prepareRequest;
15542
+
15543
+ function createTaskRunner(options) {
15544
+ var task = options.task, _options_stream = options.stream, stream = _options_stream === void 0 ? true : _options_stream;
15545
+ var transport;
15546
+ if (options.transport !== undefined) {
15547
+ transport = options.transport;
15548
+ } else {
15549
+ var prepareRequest = options.prepareRequest;
15550
+ transport = new DefaultTaskTransport({
15551
+ api: options.endpoint,
15552
+ headers: options.headers,
15553
+ fetch: options.fetch,
15554
+ prepareSendMessagesRequest: prepareRequest ? function(param) {
15555
+ var requestTask = param.task, input = param.input;
15556
+ return prepareRequest({
15557
+ task: requestTask,
15558
+ input: input
15559
+ });
15560
+ } : undefined
15561
+ });
15562
+ }
15381
15563
  return {
15382
- submit: function submit(variables) {
15564
+ submit: function submit(input) {
15383
15565
  var onData = (arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {}).onData;
15384
- var payload = buildTaskPayload({
15566
+ return transport.sendTask({
15385
15567
  task: task,
15386
- input: variables,
15387
- prepareRequest: prepareRequest
15388
- });
15389
- return fetchTask({
15390
- endpoint: endpoint,
15391
- headers: headers,
15392
- payload: payload,
15568
+ input: input,
15393
15569
  stream: stream,
15394
- onData: onData ? function(partial) {
15395
- return onData(unwrap(partial));
15396
- } : undefined
15397
- }).then(unwrap);
15570
+ onData: onData
15571
+ });
15398
15572
  }
15399
15573
  };
15400
15574
  }
@@ -15481,31 +15655,28 @@
15481
15655
  $$type: 'ais.tasks',
15482
15656
  init: function init(initOptions) {
15483
15657
  var instantSearchInstance = initOptions.instantSearchInstance;
15484
- if (transport) {
15485
- var resolved = resolveEndpoint({
15486
- transport: transport
15487
- });
15488
- runner = createTaskRunner({
15489
- endpoint: resolved.endpoint,
15490
- headers: resolved.headers,
15491
- task: task,
15492
- stream: stream,
15493
- prepareRequest: resolved.prepareSendMessagesRequest
15494
- });
15495
- } else {
15658
+ if (agentId) {
15496
15659
  var _getAppIdAndApiKey = _sliced_to_array(getAppIdAndApiKey(instantSearchInstance.client), 2), appId = _getAppIdAndApiKey[0], apiKey = _getAppIdAndApiKey[1];
15497
15660
  if (!appId || !apiKey) {
15498
15661
  throw new Error(withUsage$p('Could not extract Algolia credentials from the search client.'));
15499
15662
  }
15500
- var resolved1 = resolveEndpoint({
15663
+ var taskTransport = createTaskTransport({
15664
+ transport: transport,
15501
15665
  appId: appId,
15502
15666
  apiKey: apiKey,
15503
15667
  agentId: agentId,
15504
15668
  algoliaAgent: getAlgoliaAgent(instantSearchInstance.client)
15505
15669
  });
15506
15670
  runner = createTaskRunner({
15507
- endpoint: resolved1.endpoint,
15508
- headers: resolved1.headers,
15671
+ transport: taskTransport,
15672
+ task: task,
15673
+ stream: stream
15674
+ });
15675
+ } else {
15676
+ runner = createTaskRunner({
15677
+ transport: createTaskTransport({
15678
+ transport: transport
15679
+ }),
15509
15680
  task: task,
15510
15681
  stream: stream
15511
15682
  });
@@ -15532,6 +15703,49 @@
15532
15703
  };
15533
15704
  };
15534
15705
 
15706
+ // Centralizes the "open the chat from an entry point" behavior shared by the
15707
+ // SearchBox AI button, the Autocomplete AI button, prompt suggestions, and any
15708
+ // future entry point. The chat is always opened; the message is only sent when
15709
+ // it is non-empty and the chat is not already processing a message.
15710
+ // Returns true when a message was submitted, so callers can clear their input.
15711
+ function openChat(chatRenderState) {
15712
+ var _ref = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {}, message = _ref.message, referer = _ref.referer, turnContext = _ref.turnContext;
15713
+ var _ref1;
15714
+ var _chatRenderState_setOpen;
15715
+ if (!chatRenderState) {
15716
+ return false;
15717
+ }
15718
+ var trimmed = (_ref1 = message === null || message === void 0 ? void 0 : message.trim()) !== null && _ref1 !== void 0 ? _ref1 : '';
15719
+ if (!trimmed) {
15720
+ if (chatRenderState.focusInput) {
15721
+ chatRenderState.focusInput();
15722
+ } else {
15723
+ var _chatRenderState_setOpen1;
15724
+ (_chatRenderState_setOpen1 = chatRenderState.setOpen) === null || _chatRenderState_setOpen1 === void 0 ? void 0 : _chatRenderState_setOpen1.call(chatRenderState, true);
15725
+ }
15726
+ return false;
15727
+ }
15728
+ (_chatRenderState_setOpen = chatRenderState.setOpen) === null || _chatRenderState_setOpen === void 0 ? void 0 : _chatRenderState_setOpen.call(chatRenderState, true);
15729
+ if (isChatBusy(chatRenderState) || !chatRenderState.sendMessage) {
15730
+ return false;
15731
+ }
15732
+ chatRenderState.sendMessage(_object_spread({
15733
+ text: trimmed
15734
+ }, turnContext ? {
15735
+ metadata: {
15736
+ turnContext: turnContext
15737
+ }
15738
+ } : {}), referer ? {
15739
+ headers: {
15740
+ 'x-algolia-referer': referer
15741
+ }
15742
+ } : undefined);
15743
+ return true;
15744
+ }
15745
+ function isChatBusy(chatRenderState) {
15746
+ return (chatRenderState === null || chatRenderState === void 0 ? void 0 : chatRenderState.status) === 'submitted' || (chatRenderState === null || chatRenderState === void 0 ? void 0 : chatRenderState.status) === 'streaming';
15747
+ }
15748
+
15535
15749
  var withUsage$o = createDocumentationMessageGenerator({
15536
15750
  name: 'prompt-suggestions',
15537
15751
  connector: true
@@ -15773,14 +15987,24 @@
15773
15987
  if (!latestRenderOptions) return;
15774
15988
  renderOutward(latestRenderOptions);
15775
15989
  };
15776
- var tasksWidget = connectTasks(handleInnerRender, noop)(_object_spread_props(_object_spread({}, transport ? {
15777
- transport: transport
15778
- } : {
15779
- agentId: agentId
15780
- }), {
15781
- task: configurationId,
15782
- stream: true
15783
- }));
15990
+ var tasksParams;
15991
+ if (agentId) {
15992
+ tasksParams = {
15993
+ agentId: agentId,
15994
+ transport: transport,
15995
+ task: configurationId,
15996
+ stream: true
15997
+ };
15998
+ } else if (transport) {
15999
+ tasksParams = {
16000
+ transport: transport,
16001
+ task: configurationId,
16002
+ stream: true
16003
+ };
16004
+ } else {
16005
+ throw new Error(withUsage$o('The `agentId` option is required unless a custom `transport` is provided.'));
16006
+ }
16007
+ var tasksWidget = connectTasks(handleInnerRender, noop)(tasksParams);
15784
16008
  return {
15785
16009
  $$type: 'ais.promptSuggestions',
15786
16010
  init: function init(initOptions) {