@copilotkit/core 1.62.2 → 1.62.3

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.umd.js CHANGED
@@ -1,8 +1,8 @@
1
1
  (function(global, factory) {
2
- typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@tanstack/pacer'), require('@ag-ui/client'), require('@copilotkit/shared'), require('rxjs'), require('rxjs/operators'), require('phoenix'), require('zod-to-json-schema')) :
3
- typeof define === 'function' && define.amd ? define(['exports', '@tanstack/pacer', '@ag-ui/client', '@copilotkit/shared', 'rxjs', 'rxjs/operators', 'phoenix', 'zod-to-json-schema'], factory) :
4
- (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory((global.CopilotKitCore = {}), global._tanstack_pacer,global.AgUIClient,global.CopilotKitShared,global.rxjs,global.rxjs.operators,global.phoenix,global.zodToJsonSchema));
5
- })(this, function(exports, _tanstack_pacer, _ag_ui_client, _copilotkit_shared, rxjs, rxjs_operators, phoenix, zod_to_json_schema) {
2
+ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@tanstack/pacer'), require('@ag-ui/client'), require('@copilotkit/shared'), require('rxjs'), require('rxjs/operators'), require('phoenix'), require('zod-to-json-schema'), require('rxjs/fetch')) :
3
+ typeof define === 'function' && define.amd ? define(['exports', '@tanstack/pacer', '@ag-ui/client', '@copilotkit/shared', 'rxjs', 'rxjs/operators', 'phoenix', 'zod-to-json-schema', 'rxjs/fetch'], factory) :
4
+ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory((global.CopilotKitCore = {}), global._tanstack_pacer,global.AgUIClient,global.CopilotKitShared,global.rxjs,global.rxjs.operators,global.phoenix,global.zodToJsonSchema,global.rxjs_fetch));
5
+ })(this, function(exports, _tanstack_pacer, _ag_ui_client, _copilotkit_shared, rxjs, rxjs_operators, phoenix, zod_to_json_schema, rxjs_fetch) {
6
6
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
7
7
 
8
8
  //#region src/utils/phoenix-observable.ts
@@ -646,12 +646,12 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
646
646
  function isZodError(error) {
647
647
  return error !== null && typeof error === "object" && "name" in error && error.name === "ZodError";
648
648
  }
649
- function isAbortError(error) {
649
+ function isAbortError$1(error) {
650
650
  return (error instanceof DOMException || error instanceof Error) && error.name === "AbortError";
651
651
  }
652
652
  function withAbortErrorHandling(observable) {
653
653
  return observable.pipe((0, rxjs_operators.catchError)((error) => {
654
- if (isZodError(error) || isAbortError(error)) return rxjs.EMPTY;
654
+ if (isZodError(error) || isAbortError$1(error)) return rxjs.EMPTY;
655
655
  throw error;
656
656
  }));
657
657
  }
@@ -1013,6 +1013,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
1013
1013
  _defineProperty(this, "_runtimeMode", _copilotkit_shared.RUNTIME_MODE_SSE);
1014
1014
  _defineProperty(this, "_intelligence", void 0);
1015
1015
  _defineProperty(this, "_threadEndpoints", void 0);
1016
+ _defineProperty(this, "_suggestions", void 0);
1016
1017
  _defineProperty(this, "_a2uiEnabled", false);
1017
1018
  _defineProperty(this, "_a2uiAgents", void 0);
1018
1019
  _defineProperty(this, "_openGenerativeUIEnabled", false);
@@ -1050,6 +1051,9 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
1050
1051
  get threadEndpoints() {
1051
1052
  return this._threadEndpoints;
1052
1053
  }
1054
+ get suggestions() {
1055
+ return this._suggestions;
1056
+ }
1053
1057
  get a2uiEnabled() {
1054
1058
  return this._a2uiEnabled;
1055
1059
  }
@@ -1237,6 +1241,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
1237
1241
  this._runtimeMode = _copilotkit_shared.RUNTIME_MODE_SSE;
1238
1242
  this._intelligence = void 0;
1239
1243
  this._threadEndpoints = void 0;
1244
+ this._suggestions = void 0;
1240
1245
  this._a2uiEnabled = false;
1241
1246
  this._a2uiAgents = void 0;
1242
1247
  this._openGenerativeUIEnabled = false;
@@ -1286,6 +1291,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
1286
1291
  this._runtimeMode = (_runtimeInfoResponse$3 = runtimeInfoResponse.mode) !== null && _runtimeInfoResponse$3 !== void 0 ? _runtimeInfoResponse$3 : _copilotkit_shared.RUNTIME_MODE_SSE;
1287
1292
  this._intelligence = runtimeInfoResponse.intelligence;
1288
1293
  this._threadEndpoints = runtimeInfoResponse.threadEndpoints;
1294
+ this._suggestions = runtimeInfoResponse.suggestions;
1289
1295
  const a2uiInfo = runtimeInfoResponse.a2ui;
1290
1296
  this._a2uiEnabled = (_ref = (_a2uiInfo$enabled = a2uiInfo === null || a2uiInfo === void 0 ? void 0 : a2uiInfo.enabled) !== null && _a2uiInfo$enabled !== void 0 ? _a2uiInfo$enabled : runtimeInfoResponse.a2uiEnabled) !== null && _ref !== void 0 ? _ref : false;
1291
1297
  this._a2uiAgents = (a2uiInfo === null || a2uiInfo === void 0 ? void 0 : a2uiInfo.enabled) ? a2uiInfo.agents : void 0;
@@ -1301,6 +1307,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
1301
1307
  this._runtimeMode = _copilotkit_shared.RUNTIME_MODE_SSE;
1302
1308
  this._intelligence = void 0;
1303
1309
  this._threadEndpoints = void 0;
1310
+ this._suggestions = void 0;
1304
1311
  this._a2uiEnabled = false;
1305
1312
  this._a2uiAgents = void 0;
1306
1313
  this._openGenerativeUIEnabled = false;
@@ -1551,39 +1558,82 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
1551
1558
  };
1552
1559
  }
1553
1560
  /**
1554
- * Generate suggestions using a provider agent
1561
+ * Generate suggestions by running a provider agent and extracting the
1562
+ * `copilotkitSuggest` tool call from its streamed messages.
1563
+ *
1564
+ * Two transports, one set of mechanics: both seed an agent with the
1565
+ * consumer's messages + state and the instruction, then `runAgent` with
1566
+ * forced `copilotkitSuggest` tool choice, parsing suggestions as messages
1567
+ * stream in via `onMessagesChanged`.
1568
+ *
1569
+ * - **Stateless** (runtime advertises `suggestions` and transport isn't
1570
+ * `single`): a stock `HttpAgent` pointed at `/agent/:id/suggest`. That
1571
+ * endpoint runs the provider directly and streams AG-UI SSE **without**
1572
+ * persisting a thread, and a plain `HttpAgent` only ever speaks REST SSE —
1573
+ * it never routes through the Intelligence websocket delegate (which would
1574
+ * persist a thread). This is the path that removes the thread flood.
1575
+ * - **Fallback** (capability absent → old runtime, or `single` transport):
1576
+ * clone the provider agent and run it client-side, as before.
1577
+ *
1578
+ * Gated to non-`single` transports because this client only builds the
1579
+ * multi-route `/agent/:id/suggest` URL; single-route deployments (not the
1580
+ * persisting-thread/Intelligence case) fall through to the clone fallback.
1555
1581
  */
1556
1582
  async generateSuggestions(suggestionId, config, consumerAgentId) {
1557
- let agent = void 0;
1583
+ let runHandle = void 0;
1584
+ let aborted = false;
1558
1585
  try {
1559
- var _config$providerAgent, _this$_runningSuggest3, _config$minSuggestion, _config$maxSuggestion;
1560
- const suggestionsProviderAgent = this.core.getAgent((_config$providerAgent = config.providerAgentId) !== null && _config$providerAgent !== void 0 ? _config$providerAgent : "default");
1561
- if (!suggestionsProviderAgent) throw new Error(`Suggestions provider agent not found: ${config.providerAgentId}`);
1562
- const suggestionsConsumerAgent = this.core.getAgent(consumerAgentId);
1586
+ var _config$providerAgent, _config$minSuggestion, _config$maxSuggestion, _suggestionsConsumerA, _this$_runningSuggest3;
1587
+ const friends = this.core;
1588
+ const resolvedProviderAgentId = (_config$providerAgent = config.providerAgentId) !== null && _config$providerAgent !== void 0 ? _config$providerAgent : "default";
1589
+ const suggestionsProviderAgent = friends.getAgent(resolvedProviderAgentId);
1590
+ if (!suggestionsProviderAgent) throw new Error(`Suggestions provider agent not found: ${resolvedProviderAgentId}`);
1591
+ const suggestionsConsumerAgent = friends.getAgent(consumerAgentId);
1563
1592
  if (!suggestionsConsumerAgent) throw new Error(`Suggestions consumer agent not found: ${consumerAgentId}`);
1564
- agent = suggestionsProviderAgent.clone();
1565
- agent.threadId = suggestionId;
1566
- agent.messages = JSON.parse(JSON.stringify(suggestionsConsumerAgent.messages));
1567
- agent.state = JSON.parse(JSON.stringify(suggestionsConsumerAgent.state));
1593
+ const instructionContent = [
1594
+ `Suggest what the user could say next. Provide clear, highly relevant suggestions by calling the \`copilotkitSuggest\` tool.`,
1595
+ `Provide at least ${(_config$minSuggestion = config.minSuggestions) !== null && _config$minSuggestion !== void 0 ? _config$minSuggestion : 1} and at most ${(_config$maxSuggestion = config.maxSuggestions) !== null && _config$maxSuggestion !== void 0 ? _config$maxSuggestion : 3} suggestions.`,
1596
+ `The user has the following tools available: ${JSON.stringify(friends.buildFrontendTools(consumerAgentId))}.`,
1597
+ ` ${config.instructions}`
1598
+ ].join("\n");
1568
1599
  this._suggestions[consumerAgentId] = {
1569
1600
  ...this._suggestions[consumerAgentId],
1570
1601
  [suggestionId]: []
1571
1602
  };
1572
- this._runningSuggestions[consumerAgentId] = [...(_this$_runningSuggest3 = this._runningSuggestions[consumerAgentId]) !== null && _this$_runningSuggest3 !== void 0 ? _this$_runningSuggest3 : [], agent];
1573
- agent.addMessage({
1603
+ const seededMessages = JSON.parse(JSON.stringify(suggestionsConsumerAgent.messages));
1604
+ const seededState = JSON.parse(JSON.stringify((_suggestionsConsumerA = suggestionsConsumerAgent.state) !== null && _suggestionsConsumerA !== void 0 ? _suggestionsConsumerA : {}));
1605
+ const useStateless = this.core.suggestions === true && this.core.runtimeTransport !== "single";
1606
+ let suggestionAgent;
1607
+ if (useStateless) {
1608
+ const suggestUrl = `${this.core.runtimeUrl}/agent/${encodeURIComponent(resolvedProviderAgentId)}/suggest`;
1609
+ const credentials = this.core.credentials;
1610
+ suggestionAgent = new _ag_ui_client.HttpAgent({
1611
+ agentId: resolvedProviderAgentId,
1612
+ url: suggestUrl,
1613
+ headers: { ...this.core.headers },
1614
+ ...credentials ? { fetch: (url, requestInit) => fetch(url, {
1615
+ ...requestInit,
1616
+ credentials
1617
+ }) } : {}
1618
+ });
1619
+ } else suggestionAgent = suggestionsProviderAgent.clone();
1620
+ suggestionAgent.threadId = suggestionId;
1621
+ suggestionAgent.setMessages(seededMessages);
1622
+ suggestionAgent.setState(seededState);
1623
+ runHandle = { abortRun: () => {
1624
+ aborted = true;
1625
+ suggestionAgent.abortRun();
1626
+ } };
1627
+ this._runningSuggestions[consumerAgentId] = [...(_this$_runningSuggest3 = this._runningSuggestions[consumerAgentId]) !== null && _this$_runningSuggest3 !== void 0 ? _this$_runningSuggest3 : [], runHandle];
1628
+ suggestionAgent.addMessage({
1574
1629
  id: suggestionId,
1575
1630
  role: "user",
1576
- content: [
1577
- `Suggest what the user could say next. Provide clear, highly relevant suggestions by calling the \`copilotkitSuggest\` tool.`,
1578
- `Provide at least ${(_config$minSuggestion = config.minSuggestions) !== null && _config$minSuggestion !== void 0 ? _config$minSuggestion : 1} and at most ${(_config$maxSuggestion = config.maxSuggestions) !== null && _config$maxSuggestion !== void 0 ? _config$maxSuggestion : 3} suggestions.`,
1579
- `The user has the following tools available: ${JSON.stringify(this.core.buildFrontendTools(consumerAgentId))}.`,
1580
- ` ${config.instructions}`
1581
- ].join("\n")
1631
+ content: instructionContent
1582
1632
  });
1583
- await agent.runAgent({
1584
- context: this.core.getContextForAgent(consumerAgentId),
1633
+ await suggestionAgent.runAgent({
1634
+ context: friends.getContextForAgent(consumerAgentId),
1585
1635
  forwardedProps: {
1586
- ...this.core.properties,
1636
+ ...friends.properties,
1587
1637
  toolChoice: {
1588
1638
  type: "function",
1589
1639
  function: { name: "copilotkitSuggest" }
@@ -1594,18 +1644,15 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
1594
1644
  this.extractSuggestions(messages, suggestionId, consumerAgentId, true);
1595
1645
  } });
1596
1646
  } catch (error) {
1597
- console.warn("Error generating suggestions:", error);
1647
+ if (!isAbortError(error) && !aborted) console.warn("Error generating suggestions:", error);
1598
1648
  } finally {
1599
1649
  this.finalizeSuggestions(suggestionId, consumerAgentId);
1600
1650
  const runningAgents = this._runningSuggestions[consumerAgentId];
1601
- if (agent && runningAgents) {
1602
- const filteredAgents = runningAgents.filter((a) => a !== agent);
1603
- this._runningSuggestions[consumerAgentId] = filteredAgents;
1604
- if (filteredAgents.length === 0) {
1605
- delete this._runningSuggestions[consumerAgentId];
1606
- await this.notifySuggestionsFinishedLoading(consumerAgentId);
1607
- }
1608
- }
1651
+ const remaining = runHandle ? (runningAgents !== null && runningAgents !== void 0 ? runningAgents : []).filter((a) => a !== runHandle) : runningAgents !== null && runningAgents !== void 0 ? runningAgents : [];
1652
+ if (remaining.length === 0) {
1653
+ delete this._runningSuggestions[consumerAgentId];
1654
+ await this.notifySuggestionsFinishedLoading(consumerAgentId);
1655
+ } else this._runningSuggestions[consumerAgentId] = remaining;
1609
1656
  }
1610
1657
  }
1611
1658
  /**
@@ -1743,6 +1790,13 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
1743
1790
  }
1744
1791
  };
1745
1792
  /**
1793
+ * Detects an `AbortController`-driven cancellation so the stateless path can
1794
+ * treat it as an expected (non-error) outcome on clear/reload.
1795
+ */
1796
+ function isAbortError(error) {
1797
+ return typeof error === "object" && error !== null && "name" in error && error.name === "AbortError";
1798
+ }
1799
+ /**
1746
1800
  * Type guard for dynamic suggestions config
1747
1801
  */
1748
1802
  function isDynamicSuggestionsConfig(config) {
@@ -2716,161 +2770,1139 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2716
2770
  };
2717
2771
 
2718
2772
  //#endregion
2719
- //#region src/core/core.ts
2720
- let CopilotKitCoreErrorCode = /* @__PURE__ */ function(CopilotKitCoreErrorCode) {
2721
- CopilotKitCoreErrorCode["RUNTIME_INFO_FETCH_FAILED"] = "runtime_info_fetch_failed";
2722
- CopilotKitCoreErrorCode["AGENT_CONNECT_FAILED"] = "agent_connect_failed";
2723
- CopilotKitCoreErrorCode["AGENT_RUN_FAILED"] = "agent_run_failed";
2724
- CopilotKitCoreErrorCode["AGENT_RUN_FAILED_EVENT"] = "agent_run_failed_event";
2725
- CopilotKitCoreErrorCode["AGENT_RUN_ERROR_EVENT"] = "agent_run_error_event";
2726
- CopilotKitCoreErrorCode["TOOL_ARGUMENT_PARSE_FAILED"] = "tool_argument_parse_failed";
2727
- CopilotKitCoreErrorCode["TOOL_HANDLER_FAILED"] = "tool_handler_failed";
2728
- CopilotKitCoreErrorCode["TOOL_NOT_FOUND"] = "tool_not_found";
2729
- CopilotKitCoreErrorCode["AGENT_NOT_FOUND"] = "agent_not_found";
2730
- /**
2731
- * Emitted when an agent run fails because the thread is already locked
2732
- * by another active run.
2733
- *
2734
- * @example
2735
- * ```tsx
2736
- * <CopilotKitProvider
2737
- * onError={({ code, error, context }) => {
2738
- * if (code === "agent_thread_locked") {
2739
- * // Show "Agent is busy, retry?" UI
2740
- * }
2741
- * }}
2742
- * />
2743
- * ```
2744
- */
2745
- CopilotKitCoreErrorCode["AGENT_THREAD_LOCKED"] = "agent_thread_locked";
2746
- CopilotKitCoreErrorCode["TRANSCRIPTION_FAILED"] = "transcription_failed";
2747
- CopilotKitCoreErrorCode["TRANSCRIPTION_SERVICE_NOT_CONFIGURED"] = "transcription_service_not_configured";
2748
- CopilotKitCoreErrorCode["TRANSCRIPTION_INVALID_AUDIO"] = "transcription_invalid_audio";
2749
- CopilotKitCoreErrorCode["TRANSCRIPTION_RATE_LIMITED"] = "transcription_rate_limited";
2750
- CopilotKitCoreErrorCode["TRANSCRIPTION_AUTH_FAILED"] = "transcription_auth_failed";
2751
- CopilotKitCoreErrorCode["TRANSCRIPTION_NETWORK_ERROR"] = "transcription_network_error";
2752
- CopilotKitCoreErrorCode["SUBSCRIBER_CALLBACK_FAILED"] = "subscriber_callback_failed";
2753
- return CopilotKitCoreErrorCode;
2754
- }({});
2773
+ //#region src/utils/micro-redux.ts
2774
+ const INTERNAL_ACTION_TYPES = {
2775
+ boot: "@@micro-redux/boot",
2776
+ init: "@@micro-redux/init",
2777
+ stop: "@@micro-redux/stop"
2778
+ };
2779
+ const INTERNAL_BOOT_ACTION = { type: INTERNAL_ACTION_TYPES.boot };
2755
2780
  /**
2756
- * Runtime allowlist derived from {@link SUBSCRIBE_TO_AGENT_KEYS}. Hoisted
2757
- * to module scope so the Set is allocated once, not per-subscription.
2781
+ * Builds a typed action creator from a type string and payload factory.
2758
2782
  */
2759
- const ALLOWED_KEYS = new Set([
2760
- "onMessagesChanged",
2761
- "onStateChanged",
2762
- "onRunInitialized",
2763
- "onRunFinalized",
2764
- "onRunFailed",
2765
- "onRunErrorEvent"
2766
- ]);
2767
- let CopilotKitCoreRuntimeConnectionStatus = /* @__PURE__ */ function(CopilotKitCoreRuntimeConnectionStatus) {
2768
- CopilotKitCoreRuntimeConnectionStatus["Disconnected"] = "disconnected";
2769
- CopilotKitCoreRuntimeConnectionStatus["Connected"] = "connected";
2770
- CopilotKitCoreRuntimeConnectionStatus["Connecting"] = "connecting";
2771
- CopilotKitCoreRuntimeConnectionStatus["Error"] = "error";
2772
- return CopilotKitCoreRuntimeConnectionStatus;
2773
- }({});
2783
+ function createTypedActionCreator(type, factory) {
2784
+ const creator = ((...args) => ({
2785
+ ...factory(...args),
2786
+ type
2787
+ }));
2788
+ creator.type = type;
2789
+ creator.match = (action) => action.type === type;
2790
+ return creator;
2791
+ }
2774
2792
  /**
2775
- * Normalize a header map to the internal invariant: a `Record<string, string>`
2776
- * with no `null`/`undefined` values. Entries whose value is `null`/`undefined`
2777
- * are dropped (this is how a header is cleared). Shared by the constructor and
2778
- * `setHeaders` so both write paths into `_headers` enforce the same invariant.
2793
+ * Declares a payload-based action config for `createActionGroup`.
2794
+ *
2795
+ * @example
2796
+ * ```ts
2797
+ * const actions = createActionGroup("User", {
2798
+ * loaded: props<{ id: string }>(),
2799
+ * });
2800
+ * ```
2779
2801
  */
2780
- function normalizeHeaders(headers) {
2781
- return Object.fromEntries(Object.entries(headers).filter((entry) => entry[1] != null));
2802
+ function props() {
2803
+ return { kind: "props" };
2782
2804
  }
2783
- var CopilotKitCore = class {
2784
- constructor({ runtimeUrl, runtimeTransport = "auto", headers = {}, credentials, properties = {}, agents__unsafe_dev_only = {}, tools = [], suggestionsConfig = [], debug }) {
2785
- _defineProperty(this, "_headers", void 0);
2786
- _defineProperty(this, "_credentials", void 0);
2787
- _defineProperty(this, "_properties", void 0);
2788
- _defineProperty(this, "_defaultThrottleMs", void 0);
2789
- _defineProperty(this, "_debug", void 0);
2790
- _defineProperty(this, "subscribers", /* @__PURE__ */ new Set());
2791
- _defineProperty(this, "agentRegistry", void 0);
2792
- _defineProperty(this, "contextStore", void 0);
2793
- _defineProperty(this, "suggestionEngine", void 0);
2794
- _defineProperty(this, "runHandler", void 0);
2795
- _defineProperty(this, "stateManager", void 0);
2796
- _defineProperty(this, "threadStoreRegistry", void 0);
2797
- _defineProperty(this, "previousAgentIds", /* @__PURE__ */ new Set());
2798
- this._headers = normalizeHeaders(headers);
2799
- this._credentials = credentials;
2800
- this._properties = properties;
2801
- this._debug = debug;
2802
- this.agentRegistry = new AgentRegistry(this);
2803
- this.contextStore = new ContextStore(this);
2804
- this.suggestionEngine = new SuggestionEngine(this);
2805
- this.runHandler = new RunHandler(this);
2806
- this.stateManager = new StateManager(this);
2807
- this.threadStoreRegistry = new ThreadStoreRegistry(this);
2808
- this.agentRegistry.initialize(agents__unsafe_dev_only);
2809
- this.runHandler.initialize(tools);
2810
- this.suggestionEngine.initialize(suggestionsConfig);
2811
- this.stateManager.initialize();
2812
- this.agentRegistry.setRuntimeTransport(runtimeTransport);
2813
- this.agentRegistry.setRuntimeUrl(runtimeUrl);
2814
- this.previousAgentIds = new Set(Object.keys(agents__unsafe_dev_only));
2815
- this.subscribe({ onAgentsChanged: ({ agents }) => {
2816
- Object.values(agents).forEach((agent) => {
2817
- if (agent.agentId) this.stateManager.subscribeToAgent(agent);
2818
- });
2819
- const currentAgentIds = new Set(Object.keys(agents));
2820
- for (const agentId of Object.keys(this.threadStoreRegistry.getAll())) if (this.previousAgentIds.has(agentId) && !currentAgentIds.has(agentId)) try {
2821
- this.threadStoreRegistry.unregister(agentId);
2822
- } catch (err) {
2823
- console.error(`CopilotKitCore.onAgentsChanged: threadStoreRegistry.unregister failed for "${agentId}":`, err);
2824
- }
2825
- for (const agentId of this.previousAgentIds) if (!currentAgentIds.has(agentId)) try {
2826
- this.stateManager.unsubscribeFromAgent(agentId);
2827
- } catch (err) {
2828
- console.error(`CopilotKitCore.onAgentsChanged: stateManager.unsubscribeFromAgent failed for "${agentId}":`, err);
2829
- }
2830
- this.previousAgentIds = currentAgentIds;
2831
- } });
2832
- }
2833
- /**
2834
- * Internal method used by delegate classes and subclasses to notify subscribers
2835
- */
2836
- async notifySubscribers(handler, errorMessage) {
2837
- await Promise.all(Array.from(this.subscribers).map(async (subscriber) => {
2838
- try {
2839
- await handler(subscriber);
2840
- } catch (error) {
2841
- console.error(errorMessage, error);
2842
- }
2843
- }));
2805
+ /**
2806
+ * Declares a no-payload action config for `createActionGroup`.
2807
+ *
2808
+ * @example
2809
+ * ```ts
2810
+ * const actions = createActionGroup("User", {
2811
+ * reset: empty(),
2812
+ * });
2813
+ * ```
2814
+ */
2815
+ function empty() {
2816
+ return { kind: "empty" };
2817
+ }
2818
+ /**
2819
+ * Creates a namespaced group of typed action creators.
2820
+ *
2821
+ * Action types are formatted as: `[Source] actionName`.
2822
+ */
2823
+ function createActionGroup(source, config) {
2824
+ const group = {};
2825
+ for (const eventName of Object.keys(config)) {
2826
+ const eventConfig = config[eventName];
2827
+ if (!eventConfig) continue;
2828
+ const actionType = `[${source}] ${eventName}`;
2829
+ if (eventConfig.kind === "props") {
2830
+ group[eventName] = createTypedActionCreator(actionType, (payload) => ({ ...payload }));
2831
+ continue;
2832
+ }
2833
+ group[eventName] = createTypedActionCreator(actionType, () => ({}));
2844
2834
  }
2845
- /**
2846
- * Internal method used by delegate classes to emit errors
2847
- */
2848
- async emitError({ error, code, context = {} }) {
2849
- await this.notifySubscribers((subscriber) => {
2850
- var _subscriber$onError;
2851
- return (_subscriber$onError = subscriber.onError) === null || _subscriber$onError === void 0 ? void 0 : _subscriber$onError.call(subscriber, {
2852
- copilotkit: this,
2853
- error,
2854
- code,
2855
- context
2856
- });
2857
- }, "Subscriber onError error:");
2835
+ return group;
2836
+ }
2837
+ /**
2838
+ * Registers one reducer handler for one or more action creators.
2839
+ *
2840
+ * @throws Error when called without at least one action creator and reducer.
2841
+ */
2842
+ function on(...args) {
2843
+ if (args.length < 2) throw new Error("on requires at least one action creator and one reducer");
2844
+ const reducer = args[args.length - 1];
2845
+ return {
2846
+ creators: args.slice(0, -1),
2847
+ reducer
2848
+ };
2849
+ }
2850
+ /**
2851
+ * Creates a reducer from an initial state and `on(...)` handler entries.
2852
+ *
2853
+ * Unknown action types return the current state unchanged.
2854
+ */
2855
+ function createReducer(initialState, ...entries) {
2856
+ const reducerMap = /* @__PURE__ */ new Map();
2857
+ for (const entry of entries) for (const creator of entry.creators) {
2858
+ var _reducerMap$get;
2859
+ const handlers = (_reducerMap$get = reducerMap.get(creator.type)) !== null && _reducerMap$get !== void 0 ? _reducerMap$get : [];
2860
+ handlers.push(entry.reducer);
2861
+ reducerMap.set(creator.type, handlers);
2858
2862
  }
2859
- /**
2860
- * Log a message to the console and emit an error to subscribers.
2861
- * Catches failures from `emitError` itself to prevent unhandled rejections.
2862
- */
2863
- logAndEmitError(message, params, logLevel = "error") {
2864
- console[logLevel](message, params.error);
2865
- this.emitError(params).catch((emitErr) => {
2866
- console.error(message + " — emitError itself failed:", emitErr);
2867
- });
2863
+ return (state, action) => {
2864
+ const currentState = state !== null && state !== void 0 ? state : initialState;
2865
+ const handlers = reducerMap.get(action.type);
2866
+ if (!handlers || handlers.length === 0) return currentState;
2867
+ let nextState = currentState;
2868
+ for (const handler of handlers) nextState = handler(nextState, action);
2869
+ return nextState;
2870
+ };
2871
+ }
2872
+ /**
2873
+ * Creates a selector that caches and reuses the last computed result
2874
+ * when all input references are unchanged.
2875
+ */
2876
+ function createSelector(...args) {
2877
+ if (args.length === 1) {
2878
+ const projector = args[0];
2879
+ let hasCached = false;
2880
+ let lastState;
2881
+ let lastResult;
2882
+ return (state) => {
2883
+ if (hasCached && state === lastState) return lastResult;
2884
+ lastState = state;
2885
+ lastResult = projector(state);
2886
+ hasCached = true;
2887
+ return lastResult;
2888
+ };
2868
2889
  }
2869
- /**
2870
- * Snapshot accessors
2871
- */
2872
- get context() {
2873
- return this.contextStore.context;
2890
+ const projector = args[args.length - 1];
2891
+ const selectors = args.slice(0, -1);
2892
+ let hasCached = false;
2893
+ let lastInputs = [];
2894
+ let lastResult;
2895
+ return (state) => {
2896
+ const inputs = selectors.map((selector) => selector(state));
2897
+ if (hasCached && inputs.length === lastInputs.length && inputs.every((value, index) => value === lastInputs[index])) return lastResult;
2898
+ lastInputs = inputs;
2899
+ lastResult = projector(...inputs);
2900
+ hasCached = true;
2901
+ return lastResult;
2902
+ };
2903
+ }
2904
+ /**
2905
+ * RxJS operator that maps state emissions through a selector and suppresses
2906
+ * unchanged projected values via reference equality.
2907
+ */
2908
+ function select(selector) {
2909
+ return (source$) => source$.pipe((0, rxjs_operators.map)(selector), (0, rxjs_operators.distinctUntilChanged)());
2910
+ }
2911
+ /**
2912
+ * RxJS operator that filters an action stream by action creators and narrows
2913
+ * the output action type to the matched creator union.
2914
+ *
2915
+ * @throws Error when called without at least one action creator.
2916
+ */
2917
+ function ofType(...creators) {
2918
+ if (creators.length === 0) throw new Error("ofType requires at least one action creator");
2919
+ const actionTypes = new Set(creators.map((creator) => creator.type));
2920
+ return (source$) => {
2921
+ return source$.pipe((0, rxjs_operators.filter)((action) => {
2922
+ return actionTypes.has(action.type);
2923
+ }));
2924
+ };
2925
+ }
2926
+ /**
2927
+ * Creates an effect descriptor consumed by `createStore`.
2928
+ */
2929
+ function createEffect(factory, options = {}) {
2930
+ if (options.dispatch === false) return {
2931
+ run: factory,
2932
+ dispatch: false
2933
+ };
2934
+ return {
2935
+ run: factory,
2936
+ dispatch: true
2937
+ };
2938
+ }
2939
+ /**
2940
+ * Creates a small observable store with reducer + effects.
2941
+ *
2942
+ * Behavior:
2943
+ * - `init()` starts effects and dispatches `@@micro-redux/init`.
2944
+ * - `stop()` dispatches `@@micro-redux/stop` and unsubscribes all effects.
2945
+ * - Effect action observation is scheduled on `asapScheduler` to avoid
2946
+ * synchronous re-entrancy in the effect loop.
2947
+ * - Any effect error triggers fail-fast teardown and errors both `actions$`
2948
+ * and `state$`.
2949
+ */
2950
+ function createStore(options) {
2951
+ var _options$effects;
2952
+ const reducer = options.reducer;
2953
+ const effects = (_options$effects = options.effects) !== null && _options$effects !== void 0 ? _options$effects : [];
2954
+ let hasFatalError = false;
2955
+ let isRunning = false;
2956
+ let effectSubscriptions = new rxjs.Subscription();
2957
+ let currentState = reducer(void 0, INTERNAL_BOOT_ACTION);
2958
+ const stateSubject = new rxjs.BehaviorSubject(currentState);
2959
+ const actionsSubject = new rxjs.Subject();
2960
+ const dispatchInternal = (action) => {
2961
+ if (hasFatalError) throw new Error("Store is in a failed state due to an effect error");
2962
+ currentState = reducer(currentState, action);
2963
+ stateSubject.next(currentState);
2964
+ actionsSubject.next(action);
2965
+ };
2966
+ const failFast = (error) => {
2967
+ if (hasFatalError) return;
2968
+ hasFatalError = true;
2969
+ isRunning = false;
2970
+ effectSubscriptions.unsubscribe();
2971
+ effectSubscriptions = new rxjs.Subscription();
2972
+ actionsSubject.error(error);
2973
+ stateSubject.error(error);
2974
+ };
2975
+ const startEffects = () => {
2976
+ for (const effect of effects) {
2977
+ const scheduledActions$ = actionsSubject.asObservable().pipe((0, rxjs_operators.observeOn)(rxjs.asapScheduler));
2978
+ const state$ = stateSubject.asObservable();
2979
+ if (effect.dispatch) {
2980
+ const subscription = effect.run(scheduledActions$, state$).subscribe({
2981
+ next: (effectAction) => {
2982
+ if (hasFatalError) return;
2983
+ dispatchInternal(effectAction);
2984
+ },
2985
+ error: (error) => {
2986
+ failFast(error);
2987
+ }
2988
+ });
2989
+ effectSubscriptions.add(subscription);
2990
+ continue;
2991
+ }
2992
+ const subscription = effect.run(scheduledActions$, state$).subscribe({ error: (error) => {
2993
+ failFast(error);
2994
+ } });
2995
+ effectSubscriptions.add(subscription);
2996
+ }
2997
+ };
2998
+ return {
2999
+ dispatch(action) {
3000
+ dispatchInternal(action);
3001
+ },
3002
+ getState() {
3003
+ return currentState;
3004
+ },
3005
+ get state$() {
3006
+ return stateSubject.asObservable();
3007
+ },
3008
+ get actions$() {
3009
+ return actionsSubject.asObservable();
3010
+ },
3011
+ select(selector) {
3012
+ return stateSubject.asObservable().pipe(select(selector));
3013
+ },
3014
+ init() {
3015
+ if (hasFatalError || isRunning) return;
3016
+ isRunning = true;
3017
+ startEffects();
3018
+ if (hasFatalError) return;
3019
+ dispatchInternal({ type: INTERNAL_ACTION_TYPES.init });
3020
+ },
3021
+ stop() {
3022
+ if (hasFatalError || !isRunning) return;
3023
+ dispatchInternal({ type: INTERNAL_ACTION_TYPES.stop });
3024
+ effectSubscriptions.unsubscribe();
3025
+ effectSubscriptions = new rxjs.Subscription();
3026
+ isRunning = false;
3027
+ }
3028
+ };
3029
+ }
3030
+
3031
+ //#endregion
3032
+ //#region src/memory-errors.ts
3033
+ /**
3034
+ * The memory error registry: the single source of truth for memory error
3035
+ * metadata. Keyed by `code` so a code maps to exactly one category/retryable
3036
+ * default.
3037
+ *
3038
+ * Categories/retryable rationale:
3039
+ * - List/credentials/mutation failures are `dependency` (the runtime/platform
3040
+ * the store calls failed). A 5xx is transient (`retryable: true`); a 4xx is
3041
+ * caller-caused, so the helpers below downgrade those to non-retryable.
3042
+ * - Timeouts are `dependency` and `retryable: true` (the request may simply be
3043
+ * slow).
3044
+ */
3045
+ const MEMORY_ERROR_REGISTRY = Object.freeze({
3046
+ MEMORY_LIST_FAILED: {
3047
+ code: "MEMORY_LIST_FAILED",
3048
+ category: "dependency",
3049
+ retryable: true,
3050
+ message: "Failed to fetch memories",
3051
+ docsPath: "docs/errors/memory.md#memory_list_failed"
3052
+ },
3053
+ MEMORY_CREDENTIALS_FAILED: {
3054
+ code: "MEMORY_CREDENTIALS_FAILED",
3055
+ category: "dependency",
3056
+ retryable: true,
3057
+ message: "Failed to fetch memory subscribe credentials",
3058
+ docsPath: "docs/errors/memory.md#memory_credentials_failed"
3059
+ },
3060
+ MEMORY_MUTATION_FAILED: {
3061
+ code: "MEMORY_MUTATION_FAILED",
3062
+ category: "dependency",
3063
+ retryable: true,
3064
+ message: "Memory mutation request failed",
3065
+ docsPath: "docs/errors/memory.md#memory_mutation_failed"
3066
+ },
3067
+ MEMORY_REQUEST_TIMEOUT: {
3068
+ code: "MEMORY_REQUEST_TIMEOUT",
3069
+ category: "dependency",
3070
+ retryable: true,
3071
+ message: "Request timed out",
3072
+ docsPath: "docs/errors/memory.md#memory_request_timeout"
3073
+ }
3074
+ });
3075
+ /**
3076
+ * An `Error` carrying a stable memory error `code`, `category`, and `retryable`
3077
+ * flag so consumers and observability can branch on it without string-matching
3078
+ * the message.
3079
+ *
3080
+ * It is a real `Error` subclass: `instanceof Error` is true, so the public
3081
+ * `MemoryState.error: Error | null` contract (and the `error: Error | null`
3082
+ * surfaced by `useMemories` / `injectMemories`) holds unchanged. Existing
3083
+ * consumers that only read `.message` keep working; the richer fields are
3084
+ * additive.
3085
+ */
3086
+ var MemoryError = class MemoryError extends Error {
3087
+ /**
3088
+ * @param code - Registry code identifying this error.
3089
+ * @param options - Optional overrides:
3090
+ * - `message`: human-readable message (defaults to the registry message;
3091
+ * callers pass a status-bearing string to preserve prior wording).
3092
+ * - `retryable`: overrides the registry default (e.g. a 4xx list failure is
3093
+ * not retryable even though the code's default is).
3094
+ * - `cause`: the underlying error, preserved for debugging.
3095
+ */
3096
+ constructor(code, options) {
3097
+ var _options$message, _options$retryable;
3098
+ const entry = MEMORY_ERROR_REGISTRY[code];
3099
+ super((_options$message = options === null || options === void 0 ? void 0 : options.message) !== null && _options$message !== void 0 ? _options$message : entry.message, { cause: options === null || options === void 0 ? void 0 : options.cause });
3100
+ _defineProperty(this, "code", void 0);
3101
+ _defineProperty(this, "category", void 0);
3102
+ _defineProperty(this, "retryable", void 0);
3103
+ this.name = "MemoryError";
3104
+ this.code = code;
3105
+ this.category = entry.category;
3106
+ this.retryable = (_options$retryable = options === null || options === void 0 ? void 0 : options.retryable) !== null && _options$retryable !== void 0 ? _options$retryable : entry.retryable;
3107
+ Object.setPrototypeOf(this, MemoryError.prototype);
3108
+ }
3109
+ };
3110
+ /**
3111
+ * Narrows an HTTP status to whether the failure is worth retrying: a 5xx (or a
3112
+ * missing/0 status) is a transient dependency failure and retryable; a 4xx is
3113
+ * caller-caused and not. Used so a `MEMORY_LIST_FAILED`/`MEMORY_MUTATION_FAILED`
3114
+ * carries an accurate `retryable` flag derived from the response status.
3115
+ */
3116
+ function isRetryableStatus(status) {
3117
+ return !(Number.isInteger(status) && status >= 400 && status <= 499);
3118
+ }
3119
+
3120
+ //#endregion
3121
+ //#region src/memory.ts
3122
+ const MEMORIES_PATH = "/memories";
3123
+ const MEMORIES_SUBSCRIBE_PATH = "/memories/subscribe";
3124
+ const REQUEST_TIMEOUT_MS$1 = 15e3;
3125
+ /** Consecutive socket errors tolerated before the realtime stream gives up. */
3126
+ const MAX_SOCKET_RETRIES$1 = 5;
3127
+ /**
3128
+ * HTTP status codes that indicate memory routes are not configured (non-fatal).
3129
+ * 404/501 mean the route is absent/unimplemented; 422 is the runtime's
3130
+ * MISSING_INTELLIGENCE signal (intelligence not configured on the deployment —
3131
+ * see packages/runtime/.../handlers/intelligence/memories.ts). All three map to
3132
+ * the graceful "not available" locked-teaser path, not a hard error.
3133
+ */
3134
+ const ROUTE_UNAVAILABLE_STATUSES = new Set([
3135
+ 404,
3136
+ 422,
3137
+ 501
3138
+ ]);
3139
+ /**
3140
+ * Thrown when a memory route returns a 404/422/501 — treated as "not
3141
+ * configured" (422 is the runtime's MISSING_INTELLIGENCE signal).
3142
+ */
3143
+ var MemoryRouteUnavailableError = class extends Error {};
3144
+ const initialMemoryState = Object.freeze({
3145
+ memories: Object.freeze([]),
3146
+ isLoading: false,
3147
+ inFlightMutationCount: 0,
3148
+ error: null,
3149
+ context: null,
3150
+ sessionId: 0,
3151
+ available: true,
3152
+ realtimeStatus: "connecting"
3153
+ });
3154
+ const memoryAdapterEvents = createActionGroup("Memory Adapter", {
3155
+ started: empty(),
3156
+ stopped: empty(),
3157
+ contextChanged: props(),
3158
+ addRequested: props(),
3159
+ updateRequested: props(),
3160
+ removeRequested: props()
3161
+ });
3162
+ const memoryRestEvents = createActionGroup("Memory REST", {
3163
+ listRequested: props(),
3164
+ listSucceeded: props(),
3165
+ listFailed: props(),
3166
+ listUnavailable: props(),
3167
+ mutationFinished: props(),
3168
+ credentialsRequested: props(),
3169
+ credentialsSucceeded: props(),
3170
+ credentialsFailed: props(),
3171
+ credentialsUnavailable: props()
3172
+ });
3173
+ const memoryDomainEvents = createActionGroup("Memory Domain", {
3174
+ memoryUpserted: props(),
3175
+ memoryInvalidated: props(),
3176
+ realtimeConnecting: props(),
3177
+ realtimeConnected: props(),
3178
+ realtimeUnavailable: props()
3179
+ });
3180
+ /** Projects a wire memory to the public {@link Memory} shape (drops tenant ids). */
3181
+ function toMemory(memory) {
3182
+ return {
3183
+ id: memory.id,
3184
+ kind: memory.kind,
3185
+ scope: memory.scope,
3186
+ content: memory.content,
3187
+ sourceThreadIds: memory.sourceThreadIds,
3188
+ invalidatedAt: memory.invalidatedAt
3189
+ };
3190
+ }
3191
+ /**
3192
+ * Maps a realtime `memory_metadata` event to the domain action that applies it:
3193
+ * `created`/`updated` upsert the projected memory, `invalidated` removes it by
3194
+ * id. Carries the current `sessionId` so the reducer's session guard can drop
3195
+ * deltas left over from a previous context.
3196
+ */
3197
+ function mapMemoryMetadataEvent(event, sessionId) {
3198
+ if (event.operation === "invalidated") return memoryDomainEvents.memoryInvalidated({
3199
+ sessionId,
3200
+ memoryId: event.invalidated.id
3201
+ });
3202
+ return memoryDomainEvents.memoryUpserted({
3203
+ sessionId,
3204
+ memory: toMemory(event.memory)
3205
+ });
3206
+ }
3207
+ /**
3208
+ * Inserts or replaces a memory by id. A new memory is prepended (newest first,
3209
+ * matching the REST list's `created_at DESC` ordering without needing a date
3210
+ * field on the public projection); an existing memory is replaced in place.
3211
+ */
3212
+ function upsertMemory(memories, memory) {
3213
+ const existingIndex = memories.findIndex((item) => item.id === memory.id);
3214
+ if (existingIndex === -1) return [memory, ...memories];
3215
+ const next = [...memories];
3216
+ next[existingIndex] = memory;
3217
+ return next;
3218
+ }
3219
+ const memoryReducer = createReducer(initialMemoryState, on(memoryAdapterEvents.contextChanged, (state, { context }) => ({
3220
+ ...state,
3221
+ context,
3222
+ sessionId: state.sessionId + 1,
3223
+ memories: [],
3224
+ isLoading: Boolean(context),
3225
+ inFlightMutationCount: 0,
3226
+ error: null,
3227
+ available: true,
3228
+ realtimeStatus: "connecting"
3229
+ })), on(memoryAdapterEvents.stopped, (state) => ({
3230
+ ...state,
3231
+ memories: [],
3232
+ isLoading: false,
3233
+ inFlightMutationCount: 0,
3234
+ error: null,
3235
+ available: true,
3236
+ realtimeStatus: "connecting"
3237
+ })), on(memoryRestEvents.listRequested, (state, { sessionId }) => {
3238
+ if (sessionId !== state.sessionId || !state.context) return state;
3239
+ return {
3240
+ ...state,
3241
+ isLoading: true,
3242
+ error: null,
3243
+ available: true
3244
+ };
3245
+ }), on(memoryRestEvents.listFailed, (state, { sessionId, error }) => {
3246
+ if (sessionId !== state.sessionId) return state;
3247
+ return {
3248
+ ...state,
3249
+ isLoading: false,
3250
+ error
3251
+ };
3252
+ }), on(memoryRestEvents.listUnavailable, (state, { sessionId }) => {
3253
+ if (sessionId !== state.sessionId) return state;
3254
+ return {
3255
+ ...state,
3256
+ memories: [],
3257
+ isLoading: false,
3258
+ error: null,
3259
+ available: false
3260
+ };
3261
+ }), on(memoryAdapterEvents.addRequested, memoryAdapterEvents.updateRequested, memoryAdapterEvents.removeRequested, (state) => ({
3262
+ ...state,
3263
+ inFlightMutationCount: state.inFlightMutationCount + 1
3264
+ })), on(memoryRestEvents.mutationFinished, (state, { outcome }) => {
3265
+ if (outcome.sessionId !== state.sessionId) return state;
3266
+ return {
3267
+ ...state,
3268
+ inFlightMutationCount: Math.max(0, state.inFlightMutationCount - 1),
3269
+ error: outcome.ok ? null : outcome.error
3270
+ };
3271
+ }), on(memoryRestEvents.listSucceeded, (state, { sessionId, memories }) => {
3272
+ if (sessionId !== state.sessionId) return state;
3273
+ return {
3274
+ ...state,
3275
+ memories,
3276
+ isLoading: false,
3277
+ error: null,
3278
+ available: true
3279
+ };
3280
+ }), on(memoryDomainEvents.memoryUpserted, (state, { sessionId, memory }) => {
3281
+ if (sessionId !== state.sessionId) return state;
3282
+ return {
3283
+ ...state,
3284
+ memories: upsertMemory(state.memories, memory)
3285
+ };
3286
+ }), on(memoryDomainEvents.memoryInvalidated, (state, { sessionId, memoryId }) => {
3287
+ if (sessionId !== state.sessionId) return state;
3288
+ return {
3289
+ ...state,
3290
+ memories: state.memories.filter((memory) => memory.id !== memoryId)
3291
+ };
3292
+ }), on(memoryDomainEvents.realtimeConnecting, (state, { sessionId }) => {
3293
+ if (sessionId !== state.sessionId) return state;
3294
+ return {
3295
+ ...state,
3296
+ realtimeStatus: "connecting"
3297
+ };
3298
+ }), on(memoryDomainEvents.realtimeConnected, (state, { sessionId }) => {
3299
+ if (sessionId !== state.sessionId) return state;
3300
+ return {
3301
+ ...state,
3302
+ realtimeStatus: "connected"
3303
+ };
3304
+ }), on(memoryDomainEvents.realtimeUnavailable, (state, { sessionId }) => {
3305
+ if (sessionId !== state.sessionId) return state;
3306
+ return {
3307
+ ...state,
3308
+ realtimeStatus: "unavailable"
3309
+ };
3310
+ }));
3311
+ const selectMemories = createSelector((state) => state.memories);
3312
+ const selectMemoriesIsLoading = createSelector((state) => state.isLoading);
3313
+ const selectMemoriesError = createSelector((state) => state.error);
3314
+ /**
3315
+ * Reports whether at least one mutation is in flight. Derived from
3316
+ * `inFlightMutationCount` so concurrent mutations stay correct: the boolean
3317
+ * only clears once every in-flight mutation has settled.
3318
+ */
3319
+ const selectMemoriesIsMutating = createSelector((state) => state.inFlightMutationCount > 0);
3320
+ /**
3321
+ * Reports whether the memory routes are available. Becomes `false` after a
3322
+ * 404, 422 (the runtime's MISSING_INTELLIGENCE signal), or 501 response during
3323
+ * an auto-activation read; defaults to `true`.
3324
+ */
3325
+ const selectMemoriesAvailable = createSelector((state) => state.available);
3326
+ /**
3327
+ * Reports the realtime-connection health (see {@link MemoryRealtimeStatus}).
3328
+ * Distinct from `available`/`error`: it reflects ONLY the live socket/channel,
3329
+ * so the UI can suppress a "live" indicator once realtime permanently dies even
3330
+ * while the REST list route stays healthy. Defaults to `"connecting"`.
3331
+ */
3332
+ const selectMemoriesRealtimeStatus = createSelector((state) => state.realtimeStatus);
3333
+ const MEMORY_METADATA_EVENT = "memory_metadata";
3334
+ function memoryFromFetch(input, init) {
3335
+ return (0, rxjs_fetch.fromFetch)(input, init);
3336
+ }
3337
+ /**
3338
+ * Fetches the memory snapshot and maps it to a success/failure action. Keeps
3339
+ * only user-scoped memories (v1 surfaces user scope only; the realtime stream
3340
+ * is user-scoped too), so project-scoped rows visible to the caller are
3341
+ * dropped from the store.
3342
+ */
3343
+ function createMemoryFetchObservable(environment, context, sessionId) {
3344
+ return (0, rxjs.defer)(() => {
3345
+ const qs = context.includeInvalidated ? "?includeInvalidated=true" : "";
3346
+ return memoryFromFetch(`${context.runtimeUrl}${MEMORIES_PATH}${qs}`, {
3347
+ selector: (response) => {
3348
+ if (!response.ok) {
3349
+ if (ROUTE_UNAVAILABLE_STATUSES.has(response.status)) throw new MemoryRouteUnavailableError(String(response.status));
3350
+ throw new MemoryError("MEMORY_LIST_FAILED", {
3351
+ message: `Failed to fetch memories: ${response.status}`,
3352
+ retryable: isRetryableStatus(response.status)
3353
+ });
3354
+ }
3355
+ return response.json();
3356
+ },
3357
+ fetch: environment.fetch,
3358
+ method: "GET",
3359
+ headers: { ...context.headers }
3360
+ }).pipe((0, rxjs_operators.timeout)({
3361
+ first: REQUEST_TIMEOUT_MS$1,
3362
+ with: () => {
3363
+ throw new MemoryError("MEMORY_REQUEST_TIMEOUT");
3364
+ }
3365
+ }), (0, rxjs_operators.map)((data) => memoryRestEvents.listSucceeded({
3366
+ sessionId,
3367
+ memories: data.memories.filter((memory) => memory.scope === "user")
3368
+ })), (0, rxjs_operators.catchError)((error) => {
3369
+ if (error instanceof MemoryRouteUnavailableError) return (0, rxjs.of)(memoryRestEvents.listUnavailable({ sessionId }));
3370
+ return (0, rxjs.of)(memoryRestEvents.listFailed({
3371
+ sessionId,
3372
+ error: error instanceof Error ? error : new Error(String(error))
3373
+ }));
3374
+ }));
3375
+ });
3376
+ }
3377
+ /**
3378
+ * Fetches join credentials from the `/memories/subscribe` endpoint and maps
3379
+ * the response to a success/failure action. Requires both `joinToken` and
3380
+ * `joinCode` to be non-empty strings; throws otherwise so the `catchError`
3381
+ * path emits `credentialsFailed`.
3382
+ */
3383
+ function createMemoryCredentialsFetchObservable(environment, context, sessionId) {
3384
+ return (0, rxjs.defer)(() => memoryFromFetch(`${context.runtimeUrl}${MEMORIES_SUBSCRIBE_PATH}`, {
3385
+ selector: async (response) => {
3386
+ if (!response.ok) {
3387
+ if (ROUTE_UNAVAILABLE_STATUSES.has(response.status)) throw new MemoryRouteUnavailableError(String(response.status));
3388
+ throw new MemoryError("MEMORY_CREDENTIALS_FAILED", {
3389
+ message: `Failed to fetch memory subscribe credentials: ${response.status}`,
3390
+ retryable: isRetryableStatus(response.status)
3391
+ });
3392
+ }
3393
+ return response.json();
3394
+ },
3395
+ fetch: environment.fetch,
3396
+ method: "POST",
3397
+ headers: {
3398
+ ...context.headers,
3399
+ "Content-Type": "application/json"
3400
+ },
3401
+ body: JSON.stringify({})
3402
+ }).pipe((0, rxjs_operators.timeout)({
3403
+ first: REQUEST_TIMEOUT_MS$1,
3404
+ with: () => {
3405
+ throw new MemoryError("MEMORY_REQUEST_TIMEOUT");
3406
+ }
3407
+ }), (0, rxjs_operators.map)((data) => {
3408
+ if (typeof data.joinToken !== "string" || data.joinToken.length === 0) throw new Error("missing joinToken");
3409
+ if (typeof data.joinCode !== "string" || data.joinCode.length === 0) throw new Error("missing joinCode");
3410
+ return memoryRestEvents.credentialsSucceeded({
3411
+ sessionId,
3412
+ joinToken: data.joinToken,
3413
+ joinCode: data.joinCode
3414
+ });
3415
+ }), (0, rxjs_operators.catchError)((error) => {
3416
+ if (error instanceof MemoryRouteUnavailableError) return (0, rxjs.of)(memoryRestEvents.credentialsUnavailable({ sessionId }));
3417
+ return (0, rxjs.of)(memoryRestEvents.credentialsFailed({
3418
+ sessionId,
3419
+ error: error instanceof Error ? error : new Error(String(error))
3420
+ }));
3421
+ })));
3422
+ }
3423
+ /** Projects a REST mutation response to the public {@link Memory} shape. */
3424
+ function responseToMemory(data) {
3425
+ return {
3426
+ id: data.id,
3427
+ kind: data.kind,
3428
+ scope: data.scope,
3429
+ content: data.content,
3430
+ sourceThreadIds: data.sourceThreadIds,
3431
+ invalidatedAt: data.invalidatedAt
3432
+ };
3433
+ }
3434
+ const MEMORY_KINDS = new Set([
3435
+ "topical",
3436
+ "episodic",
3437
+ "operational"
3438
+ ]);
3439
+ const MEMORY_SCOPES = new Set(["user", "project"]);
3440
+ /**
3441
+ * Validates the required fields of a create/supersede REST response before it is
3442
+ * projected to a {@link Memory}. Returns an `Error` describing the first
3443
+ * missing/invalid field, or `null` when the body is well-formed. Without this a
3444
+ * malformed 200 body yields a Memory with undefined fields that gets upserted.
3445
+ */
3446
+ function validateMutationResponse(data) {
3447
+ if (!data || typeof data !== "object") return /* @__PURE__ */ new Error("memory mutation response missing/invalid body");
3448
+ if (typeof data.id !== "string" || data.id.length === 0) return /* @__PURE__ */ new Error("memory mutation response missing/invalid id");
3449
+ if (typeof data.kind !== "string" || !MEMORY_KINDS.has(data.kind)) return /* @__PURE__ */ new Error("memory mutation response missing/invalid kind");
3450
+ if (typeof data.scope !== "string" || !MEMORY_SCOPES.has(data.scope)) return /* @__PURE__ */ new Error("memory mutation response missing/invalid scope");
3451
+ if (typeof data.content !== "string") return /* @__PURE__ */ new Error("memory mutation response missing/invalid content");
3452
+ if (!Array.isArray(data.sourceThreadIds) || !data.sourceThreadIds.every((id) => typeof id === "string")) return /* @__PURE__ */ new Error("memory mutation response missing/invalid sourceThreadIds");
3453
+ if (data.invalidatedAt !== null && typeof data.invalidatedAt !== "string") return /* @__PURE__ */ new Error("memory mutation response missing/invalid invalidatedAt");
3454
+ return null;
3455
+ }
3456
+ /**
3457
+ * Request body for create/supersede. `scope` is forwarded only when the caller
3458
+ * supplies it: the platform owns the default (`scope` defaults to `"user"` in
3459
+ * the `/api/memories` schema), so the store does not second-guess it here —
3460
+ * one default, at the contract owner. `sourceThreadIds` defaults to `[]`.
3461
+ */
3462
+ function toMutationBody(input) {
3463
+ var _input$sourceThreadId;
3464
+ return {
3465
+ content: input.content,
3466
+ kind: input.kind,
3467
+ ...input.scope !== void 0 ? { scope: input.scope } : {},
3468
+ sourceThreadIds: (_input$sourceThreadId = input.sourceThreadIds) !== null && _input$sourceThreadId !== void 0 ? _input$sourceThreadId : []
3469
+ };
3470
+ }
3471
+ /**
3472
+ * Builds the actions a successful mutation dispatches (server-authoritative):
3473
+ * the REST response is applied to local state immediately, and the realtime
3474
+ * event reconciles idempotently (upsert-by-id). `mutationFinished` resolves the
3475
+ * caller's promise.
3476
+ */
3477
+ function buildMutationSuccessActions(request, data) {
3478
+ const { requestId, sessionId } = request;
3479
+ if (request.kind === "remove") return [memoryDomainEvents.memoryInvalidated({
3480
+ sessionId,
3481
+ memoryId: request.id
3482
+ }), memoryRestEvents.mutationFinished({ outcome: {
3483
+ requestId,
3484
+ sessionId,
3485
+ ok: true,
3486
+ memory: null
3487
+ } })];
3488
+ const validationError = validateMutationResponse(data);
3489
+ if (validationError) return [memoryRestEvents.mutationFinished({ outcome: {
3490
+ requestId,
3491
+ sessionId,
3492
+ ok: false,
3493
+ error: validationError
3494
+ } })];
3495
+ const memory = responseToMemory(data);
3496
+ if (request.kind === "update") {
3497
+ const retiredId = data.retiredId;
3498
+ if (typeof retiredId !== "string" || retiredId.length === 0) return [memoryRestEvents.mutationFinished({ outcome: {
3499
+ requestId,
3500
+ sessionId,
3501
+ ok: false,
3502
+ error: /* @__PURE__ */ new Error("supersede response missing retiredId")
3503
+ } })];
3504
+ return [
3505
+ memoryDomainEvents.memoryInvalidated({
3506
+ sessionId,
3507
+ memoryId: retiredId
3508
+ }),
3509
+ memoryDomainEvents.memoryUpserted({
3510
+ sessionId,
3511
+ memory
3512
+ }),
3513
+ memoryRestEvents.mutationFinished({ outcome: {
3514
+ requestId,
3515
+ sessionId,
3516
+ ok: true,
3517
+ memory
3518
+ } })
3519
+ ];
3520
+ }
3521
+ return [memoryDomainEvents.memoryUpserted({
3522
+ sessionId,
3523
+ memory
3524
+ }), memoryRestEvents.mutationFinished({ outcome: {
3525
+ requestId,
3526
+ sessionId,
3527
+ ok: true,
3528
+ memory
3529
+ } })];
3530
+ }
3531
+ /** Performs a create/supersede/retire HTTP call and emits its resulting actions. */
3532
+ function createMemoryMutationObservable(environment, context, request) {
3533
+ const method = request.kind === "add" ? "POST" : request.kind === "update" ? "PATCH" : "DELETE";
3534
+ const path = request.kind === "add" ? MEMORIES_PATH : `${MEMORIES_PATH}/${encodeURIComponent(request.id)}`;
3535
+ return (0, rxjs.defer)(() => memoryFromFetch(`${context.runtimeUrl}${path}`, {
3536
+ selector: async (response) => {
3537
+ if (!response.ok) throw new MemoryError("MEMORY_MUTATION_FAILED", {
3538
+ message: `Request failed: ${response.status}`,
3539
+ retryable: isRetryableStatus(response.status)
3540
+ });
3541
+ return request.kind === "remove" ? null : await response.json();
3542
+ },
3543
+ fetch: environment.fetch,
3544
+ method,
3545
+ headers: {
3546
+ ...context.headers,
3547
+ "Content-Type": "application/json"
3548
+ },
3549
+ body: request.kind === "remove" ? void 0 : JSON.stringify(request.body)
3550
+ }).pipe((0, rxjs_operators.timeout)({
3551
+ first: REQUEST_TIMEOUT_MS$1,
3552
+ with: () => {
3553
+ throw new MemoryError("MEMORY_REQUEST_TIMEOUT");
3554
+ }
3555
+ }), (0, rxjs_operators.mergeMap)((data) => (0, rxjs.of)(...buildMutationSuccessActions(request, data))), (0, rxjs_operators.catchError)((error) => (0, rxjs.of)(memoryRestEvents.mutationFinished({ outcome: {
3556
+ requestId: request.requestId,
3557
+ sessionId: request.sessionId,
3558
+ ok: false,
3559
+ error: error instanceof Error ? error : new Error(String(error))
3560
+ } })))));
3561
+ }
3562
+ /**
3563
+ * Creates the framework-agnostic memory store: a REST snapshot on `setContext`,
3564
+ * server-authoritative add/update/remove mutations, and realtime
3565
+ * `memory_metadata` deltas off the injected `user_meta` event source — all
3566
+ * reduced into observable state.
3567
+ */
3568
+ function createMemoryStore(environment) {
3569
+ let memoryRequestId = 0;
3570
+ const createMemoryRequestId = () => {
3571
+ memoryRequestId += 1;
3572
+ return `memory-request-${memoryRequestId}`;
3573
+ };
3574
+ const bootstrapEffect = createEffect((actions$, state$) => actions$.pipe(ofType(memoryAdapterEvents.contextChanged), (0, rxjs_operators.withLatestFrom)(state$), (0, rxjs_operators.filter)(([, state]) => Boolean(state.context)), (0, rxjs_operators.map)(([, state]) => memoryRestEvents.listRequested({ sessionId: state.sessionId }))));
3575
+ const credentialsBootstrapEffect = createEffect((actions$, state$) => actions$.pipe(ofType(memoryAdapterEvents.contextChanged), (0, rxjs_operators.withLatestFrom)(state$), (0, rxjs_operators.filter)(([, state]) => Boolean(state.context)), (0, rxjs_operators.map)(([, state]) => memoryRestEvents.credentialsRequested({ sessionId: state.sessionId }))));
3576
+ const credentialsFetchEffect = createEffect((actions$, state$) => actions$.pipe(ofType(memoryRestEvents.credentialsRequested), (0, rxjs_operators.switchMap)((action) => state$.pipe((0, rxjs_operators.map)((state) => state.context), (0, rxjs_operators.filter)((context) => Boolean(context)), (0, rxjs_operators.take)(1), (0, rxjs_operators.map)((context) => ({
3577
+ action,
3578
+ context
3579
+ })), (0, rxjs_operators.takeUntil)(actions$.pipe(ofType(memoryAdapterEvents.contextChanged, memoryAdapterEvents.stopped))), (0, rxjs_operators.switchMap)(({ action: currentAction, context }) => createMemoryCredentialsFetchObservable(environment, context, currentAction.sessionId))))));
3580
+ const store = createStore({
3581
+ reducer: memoryReducer,
3582
+ effects: [
3583
+ bootstrapEffect,
3584
+ credentialsBootstrapEffect,
3585
+ createEffect((actions$, state$) => actions$.pipe(ofType(memoryRestEvents.listRequested), (0, rxjs_operators.switchMap)((action) => state$.pipe((0, rxjs_operators.map)((state) => state.context), (0, rxjs_operators.filter)((context) => Boolean(context)), (0, rxjs_operators.take)(1), (0, rxjs_operators.map)((context) => ({
3586
+ action,
3587
+ context
3588
+ })), (0, rxjs_operators.takeUntil)(actions$.pipe(ofType(memoryAdapterEvents.contextChanged, memoryAdapterEvents.stopped))), (0, rxjs_operators.switchMap)(({ action: currentAction, context }) => createMemoryFetchObservable(environment, context, currentAction.sessionId)))))),
3589
+ credentialsFetchEffect,
3590
+ createEffect((actions$, state$) => actions$.pipe(ofType(memoryAdapterEvents.addRequested, memoryAdapterEvents.updateRequested, memoryAdapterEvents.removeRequested), (0, rxjs_operators.withLatestFrom)(state$), (0, rxjs_operators.mergeMap)(([action, state]) => {
3591
+ const context = state.context;
3592
+ const sessionId = state.sessionId;
3593
+ if (!(context === null || context === void 0 ? void 0 : context.runtimeUrl)) return (0, rxjs.of)(memoryRestEvents.mutationFinished({ outcome: {
3594
+ requestId: action.requestId,
3595
+ sessionId,
3596
+ ok: false,
3597
+ error: /* @__PURE__ */ new Error("Runtime URL is not configured")
3598
+ } }));
3599
+ if (memoryAdapterEvents.addRequested.match(action)) return createMemoryMutationObservable(environment, context, {
3600
+ requestId: action.requestId,
3601
+ sessionId,
3602
+ kind: "add",
3603
+ body: toMutationBody(action.input)
3604
+ });
3605
+ if (memoryAdapterEvents.updateRequested.match(action)) return createMemoryMutationObservable(environment, context, {
3606
+ requestId: action.requestId,
3607
+ sessionId,
3608
+ kind: "update",
3609
+ id: action.id,
3610
+ body: toMutationBody(action.changes)
3611
+ });
3612
+ return createMemoryMutationObservable(environment, context, {
3613
+ requestId: action.requestId,
3614
+ sessionId,
3615
+ kind: "remove",
3616
+ id: action.id
3617
+ });
3618
+ }))),
3619
+ createEffect((actions$, state$) => actions$.pipe(ofType(memoryRestEvents.credentialsSucceeded), (0, rxjs_operators.withLatestFrom)(state$), (0, rxjs_operators.filter)(([action, state]) => {
3620
+ var _state$context;
3621
+ return action.sessionId === state.sessionId && Boolean((_state$context = state.context) === null || _state$context === void 0 ? void 0 : _state$context.wsUrl);
3622
+ }), (0, rxjs_operators.switchMap)(([action, state]) => {
3623
+ const context = state.context;
3624
+ const { joinToken, joinCode } = action;
3625
+ const sessionId = action.sessionId;
3626
+ const shutdown$ = actions$.pipe(ofType(memoryAdapterEvents.contextChanged, memoryAdapterEvents.stopped));
3627
+ return (0, rxjs.defer)(() => {
3628
+ const socket$ = ɵphoenixSocket$({
3629
+ url: context.wsUrl,
3630
+ options: {
3631
+ params: { join_token: joinToken },
3632
+ reconnectAfterMs: (0, _copilotkit_shared.phoenixExponentialBackoff)(100, 1e4),
3633
+ rejoinAfterMs: (0, _copilotkit_shared.phoenixExponentialBackoff)(1e3, 3e4)
3634
+ }
3635
+ }).pipe((0, rxjs_operators.shareReplay)({
3636
+ bufferSize: 1,
3637
+ refCount: true
3638
+ }));
3639
+ const channel$ = ɵphoenixChannel$({
3640
+ socket$,
3641
+ topic: `user_meta:memories:${joinCode}`
3642
+ }).pipe((0, rxjs_operators.shareReplay)({
3643
+ bufferSize: 1,
3644
+ refCount: true
3645
+ }));
3646
+ const fatalSocketShutdown$ = ɵobservePhoenixSocketHealth$(ɵobservePhoenixSocketSignals$(socket$).pipe((0, rxjs_operators.share)()), MAX_SOCKET_RETRIES$1).pipe((0, rxjs_operators.catchError)(() => {
3647
+ console.warn(`[memory] WebSocket failed after ${MAX_SOCKET_RETRIES$1} attempts, giving up`);
3648
+ return (0, rxjs.of)(void 0);
3649
+ }), (0, rxjs_operators.share)());
3650
+ const fatalStatus$ = fatalSocketShutdown$.pipe((0, rxjs_operators.map)(() => memoryDomainEvents.realtimeUnavailable({ sessionId })));
3651
+ const metadata$ = channel$.pipe((0, rxjs_operators.switchMap)(({ channel }) => ɵobservePhoenixEvent$(channel, MEMORY_METADATA_EVENT)), (0, rxjs_operators.map)((event) => mapMemoryMetadataEvent(event, action.sessionId)));
3652
+ const join$ = ɵjoinPhoenixChannel$(channel$).pipe((0, rxjs_operators.concatWith)((0, rxjs.of)(memoryDomainEvents.realtimeConnected({ sessionId }))), (0, rxjs_operators.catchError)((error) => {
3653
+ console.warn(`[memory] failed to join user_meta:memories:${joinCode}`, error);
3654
+ return (0, rxjs.of)(memoryDomainEvents.realtimeUnavailable({ sessionId }));
3655
+ }));
3656
+ return (0, rxjs.merge)((0, rxjs.of)(memoryDomainEvents.realtimeConnecting({ sessionId })), metadata$, join$, fatalStatus$).pipe((0, rxjs_operators.takeUntil)((0, rxjs.merge)(shutdown$, fatalSocketShutdown$.pipe((0, rxjs.observeOn)(rxjs.asapScheduler)))), (0, rxjs_operators.finalize)(() => {}));
3657
+ });
3658
+ })))
3659
+ ]
3660
+ });
3661
+ function trackMutation(dispatchAction, extract) {
3662
+ const { requestId } = dispatchAction;
3663
+ const resultPromise = (0, rxjs.firstValueFrom)((0, rxjs.merge)(store.actions$.pipe(ofType(memoryRestEvents.mutationFinished), (0, rxjs_operators.filter)((action) => action.outcome.requestId === requestId), (0, rxjs_operators.map)((action) => action.outcome)), store.actions$.pipe(ofType(memoryAdapterEvents.stopped), (0, rxjs_operators.map)(() => ({
3664
+ requestId,
3665
+ sessionId: store.getState().sessionId,
3666
+ ok: false,
3667
+ error: /* @__PURE__ */ new Error("Memory store stopped before mutation completed")
3668
+ })))).pipe((0, rxjs_operators.take)(1))).then((outcome) => {
3669
+ if (!outcome.ok) throw outcome.error;
3670
+ return extract(outcome);
3671
+ });
3672
+ store.dispatch(dispatchAction);
3673
+ return resultPromise;
3674
+ }
3675
+ return {
3676
+ start() {
3677
+ store.init();
3678
+ store.dispatch(memoryAdapterEvents.started());
3679
+ },
3680
+ stop() {
3681
+ store.dispatch(memoryAdapterEvents.stopped());
3682
+ store.stop();
3683
+ },
3684
+ setContext(context) {
3685
+ store.dispatch(memoryAdapterEvents.contextChanged({ context }));
3686
+ },
3687
+ refresh() {
3688
+ const { sessionId, context } = store.getState();
3689
+ if (!context) return Promise.resolve();
3690
+ const done = (0, rxjs.firstValueFrom)((0, rxjs.merge)(store.actions$.pipe(ofType(memoryRestEvents.listSucceeded, memoryRestEvents.listFailed, memoryRestEvents.listUnavailable), (0, rxjs_operators.filter)((action) => action.sessionId === sessionId)), store.actions$.pipe(ofType(memoryAdapterEvents.stopped)), store.actions$.pipe(ofType(memoryAdapterEvents.contextChanged))).pipe((0, rxjs_operators.take)(1))).then((action) => {
3691
+ if (memoryRestEvents.listFailed.match(action)) throw action.error;
3692
+ if (memoryAdapterEvents.stopped.match(action)) throw new Error("Memory store stopped before refresh completed");
3693
+ if (memoryAdapterEvents.contextChanged.match(action)) return;
3694
+ });
3695
+ store.dispatch(memoryRestEvents.listRequested({ sessionId }));
3696
+ return done;
3697
+ },
3698
+ addMemory(input) {
3699
+ return trackMutation(memoryAdapterEvents.addRequested({
3700
+ requestId: createMemoryRequestId(),
3701
+ input
3702
+ }), (outcome) => {
3703
+ if (outcome.memory == null) throw new Error("add resolved without a memory");
3704
+ return outcome.memory;
3705
+ });
3706
+ },
3707
+ updateMemory(id, changes) {
3708
+ return trackMutation(memoryAdapterEvents.updateRequested({
3709
+ requestId: createMemoryRequestId(),
3710
+ id,
3711
+ changes
3712
+ }), (outcome) => {
3713
+ if (outcome.memory == null) throw new Error("update resolved without a memory");
3714
+ return outcome.memory;
3715
+ });
3716
+ },
3717
+ removeMemory(id) {
3718
+ return trackMutation(memoryAdapterEvents.removeRequested({
3719
+ requestId: createMemoryRequestId(),
3720
+ id
3721
+ }), () => void 0);
3722
+ },
3723
+ getState() {
3724
+ return store.getState();
3725
+ },
3726
+ getServerState() {
3727
+ return initialMemoryState;
3728
+ },
3729
+ select: store.select.bind(store)
3730
+ };
3731
+ }
3732
+ const ɵmemoryAdapterEvents = memoryAdapterEvents;
3733
+ const ɵmemoryRestEvents = memoryRestEvents;
3734
+ const ɵmemoryDomainEvents = memoryDomainEvents;
3735
+ const ɵmemoryReducer = memoryReducer;
3736
+ const ɵmapMemoryMetadataEvent = mapMemoryMetadataEvent;
3737
+ const ɵselectMemories = selectMemories;
3738
+ const ɵselectMemoriesIsLoading = selectMemoriesIsLoading;
3739
+ const ɵselectMemoriesError = selectMemoriesError;
3740
+ const ɵselectMemoriesIsMutating = selectMemoriesIsMutating;
3741
+ const ɵselectMemoriesAvailable = selectMemoriesAvailable;
3742
+ const ɵselectMemoriesRealtimeStatus = selectMemoriesRealtimeStatus;
3743
+
3744
+ //#endregion
3745
+ //#region src/core/core.ts
3746
+ let CopilotKitCoreErrorCode = /* @__PURE__ */ function(CopilotKitCoreErrorCode) {
3747
+ CopilotKitCoreErrorCode["RUNTIME_INFO_FETCH_FAILED"] = "runtime_info_fetch_failed";
3748
+ CopilotKitCoreErrorCode["AGENT_CONNECT_FAILED"] = "agent_connect_failed";
3749
+ CopilotKitCoreErrorCode["AGENT_RUN_FAILED"] = "agent_run_failed";
3750
+ CopilotKitCoreErrorCode["AGENT_RUN_FAILED_EVENT"] = "agent_run_failed_event";
3751
+ CopilotKitCoreErrorCode["AGENT_RUN_ERROR_EVENT"] = "agent_run_error_event";
3752
+ CopilotKitCoreErrorCode["TOOL_ARGUMENT_PARSE_FAILED"] = "tool_argument_parse_failed";
3753
+ CopilotKitCoreErrorCode["TOOL_HANDLER_FAILED"] = "tool_handler_failed";
3754
+ CopilotKitCoreErrorCode["TOOL_NOT_FOUND"] = "tool_not_found";
3755
+ CopilotKitCoreErrorCode["AGENT_NOT_FOUND"] = "agent_not_found";
3756
+ /**
3757
+ * Emitted when an agent run fails because the thread is already locked
3758
+ * by another active run.
3759
+ *
3760
+ * @example
3761
+ * ```tsx
3762
+ * <CopilotKitProvider
3763
+ * onError={({ code, error, context }) => {
3764
+ * if (code === "agent_thread_locked") {
3765
+ * // Show "Agent is busy, retry?" UI
3766
+ * }
3767
+ * }}
3768
+ * />
3769
+ * ```
3770
+ */
3771
+ CopilotKitCoreErrorCode["AGENT_THREAD_LOCKED"] = "agent_thread_locked";
3772
+ CopilotKitCoreErrorCode["TRANSCRIPTION_FAILED"] = "transcription_failed";
3773
+ CopilotKitCoreErrorCode["TRANSCRIPTION_SERVICE_NOT_CONFIGURED"] = "transcription_service_not_configured";
3774
+ CopilotKitCoreErrorCode["TRANSCRIPTION_INVALID_AUDIO"] = "transcription_invalid_audio";
3775
+ CopilotKitCoreErrorCode["TRANSCRIPTION_RATE_LIMITED"] = "transcription_rate_limited";
3776
+ CopilotKitCoreErrorCode["TRANSCRIPTION_AUTH_FAILED"] = "transcription_auth_failed";
3777
+ CopilotKitCoreErrorCode["TRANSCRIPTION_NETWORK_ERROR"] = "transcription_network_error";
3778
+ CopilotKitCoreErrorCode["SUBSCRIBER_CALLBACK_FAILED"] = "subscriber_callback_failed";
3779
+ return CopilotKitCoreErrorCode;
3780
+ }({});
3781
+ /**
3782
+ * Runtime allowlist derived from {@link SUBSCRIBE_TO_AGENT_KEYS}. Hoisted
3783
+ * to module scope so the Set is allocated once, not per-subscription.
3784
+ */
3785
+ const ALLOWED_KEYS = new Set([
3786
+ "onMessagesChanged",
3787
+ "onStateChanged",
3788
+ "onRunInitialized",
3789
+ "onRunFinalized",
3790
+ "onRunFailed",
3791
+ "onRunErrorEvent"
3792
+ ]);
3793
+ let CopilotKitCoreRuntimeConnectionStatus = /* @__PURE__ */ function(CopilotKitCoreRuntimeConnectionStatus) {
3794
+ CopilotKitCoreRuntimeConnectionStatus["Disconnected"] = "disconnected";
3795
+ CopilotKitCoreRuntimeConnectionStatus["Connected"] = "connected";
3796
+ CopilotKitCoreRuntimeConnectionStatus["Connecting"] = "connecting";
3797
+ CopilotKitCoreRuntimeConnectionStatus["Error"] = "error";
3798
+ return CopilotKitCoreRuntimeConnectionStatus;
3799
+ }({});
3800
+ /**
3801
+ * Normalize a header map to the internal invariant: a `Record<string, string>`
3802
+ * with no `null`/`undefined` values. Entries whose value is `null`/`undefined`
3803
+ * are dropped (this is how a header is cleared). Shared by the constructor and
3804
+ * `setHeaders` so both write paths into `_headers` enforce the same invariant.
3805
+ */
3806
+ function normalizeHeaders(headers) {
3807
+ return Object.fromEntries(Object.entries(headers).filter((entry) => entry[1] != null));
3808
+ }
3809
+ var CopilotKitCore = class {
3810
+ constructor({ runtimeUrl, runtimeTransport = "auto", headers = {}, credentials, properties = {}, agents__unsafe_dev_only = {}, tools = [], suggestionsConfig = [], debug }) {
3811
+ _defineProperty(this, "_headers", void 0);
3812
+ _defineProperty(this, "_credentials", void 0);
3813
+ _defineProperty(this, "_properties", void 0);
3814
+ _defineProperty(this, "_defaultThrottleMs", void 0);
3815
+ _defineProperty(this, "_debug", void 0);
3816
+ _defineProperty(this, "subscribers", /* @__PURE__ */ new Set());
3817
+ _defineProperty(this, "agentRegistry", void 0);
3818
+ _defineProperty(this, "contextStore", void 0);
3819
+ _defineProperty(this, "suggestionEngine", void 0);
3820
+ _defineProperty(this, "runHandler", void 0);
3821
+ _defineProperty(this, "stateManager", void 0);
3822
+ _defineProperty(this, "threadStoreRegistry", void 0);
3823
+ _defineProperty(this, "_memoryStore", void 0);
3824
+ _defineProperty(this, "previousAgentIds", /* @__PURE__ */ new Set());
3825
+ this._headers = normalizeHeaders(headers);
3826
+ this._credentials = credentials;
3827
+ this._properties = properties;
3828
+ this._debug = debug;
3829
+ this.agentRegistry = new AgentRegistry(this);
3830
+ this.contextStore = new ContextStore(this);
3831
+ this.suggestionEngine = new SuggestionEngine(this);
3832
+ this.runHandler = new RunHandler(this);
3833
+ this.stateManager = new StateManager(this);
3834
+ this.threadStoreRegistry = new ThreadStoreRegistry(this);
3835
+ this.agentRegistry.initialize(agents__unsafe_dev_only);
3836
+ this.runHandler.initialize(tools);
3837
+ this.suggestionEngine.initialize(suggestionsConfig);
3838
+ this.stateManager.initialize();
3839
+ this.agentRegistry.setRuntimeTransport(runtimeTransport);
3840
+ this.agentRegistry.setRuntimeUrl(runtimeUrl);
3841
+ this.previousAgentIds = new Set(Object.keys(agents__unsafe_dev_only));
3842
+ this.subscribe({
3843
+ onRuntimeConnectionStatusChanged: () => {
3844
+ if (this._memoryStore) this.syncMemoryContext();
3845
+ },
3846
+ onAgentsChanged: ({ agents }) => {
3847
+ Object.values(agents).forEach((agent) => {
3848
+ if (agent.agentId) this.stateManager.subscribeToAgent(agent);
3849
+ });
3850
+ const currentAgentIds = new Set(Object.keys(agents));
3851
+ for (const agentId of Object.keys(this.threadStoreRegistry.getAll())) if (this.previousAgentIds.has(agentId) && !currentAgentIds.has(agentId)) try {
3852
+ this.threadStoreRegistry.unregister(agentId);
3853
+ } catch (err) {
3854
+ console.error(`CopilotKitCore.onAgentsChanged: threadStoreRegistry.unregister failed for "${agentId}":`, err);
3855
+ }
3856
+ for (const agentId of this.previousAgentIds) if (!currentAgentIds.has(agentId)) try {
3857
+ this.stateManager.unsubscribeFromAgent(agentId);
3858
+ } catch (err) {
3859
+ console.error(`CopilotKitCore.onAgentsChanged: stateManager.unsubscribeFromAgent failed for "${agentId}":`, err);
3860
+ }
3861
+ this.previousAgentIds = currentAgentIds;
3862
+ }
3863
+ });
3864
+ }
3865
+ /**
3866
+ * Internal method used by delegate classes and subclasses to notify subscribers
3867
+ */
3868
+ async notifySubscribers(handler, errorMessage) {
3869
+ await Promise.all(Array.from(this.subscribers).map(async (subscriber) => {
3870
+ try {
3871
+ await handler(subscriber);
3872
+ } catch (error) {
3873
+ console.error(errorMessage, error);
3874
+ }
3875
+ }));
3876
+ }
3877
+ /**
3878
+ * Internal method used by delegate classes to emit errors
3879
+ */
3880
+ async emitError({ error, code, context = {} }) {
3881
+ await this.notifySubscribers((subscriber) => {
3882
+ var _subscriber$onError;
3883
+ return (_subscriber$onError = subscriber.onError) === null || _subscriber$onError === void 0 ? void 0 : _subscriber$onError.call(subscriber, {
3884
+ copilotkit: this,
3885
+ error,
3886
+ code,
3887
+ context
3888
+ });
3889
+ }, "Subscriber onError error:");
3890
+ }
3891
+ /**
3892
+ * Log a message to the console and emit an error to subscribers.
3893
+ * Catches failures from `emitError` itself to prevent unhandled rejections.
3894
+ */
3895
+ logAndEmitError(message, params, logLevel = "error") {
3896
+ console[logLevel](message, params.error);
3897
+ this.emitError(params).catch((emitErr) => {
3898
+ console.error(message + " — emitError itself failed:", emitErr);
3899
+ });
3900
+ }
3901
+ /**
3902
+ * Snapshot accessors
3903
+ */
3904
+ get context() {
3905
+ return this.contextStore.context;
2874
3906
  }
2875
3907
  get agents() {
2876
3908
  return this.agentRegistry.agents;
@@ -2952,6 +3984,9 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2952
3984
  get threadEndpoints() {
2953
3985
  return this.agentRegistry.threadEndpoints;
2954
3986
  }
3987
+ get suggestions() {
3988
+ return this.agentRegistry.suggestions;
3989
+ }
2955
3990
  get a2uiEnabled() {
2956
3991
  return this.agentRegistry.a2uiEnabled;
2957
3992
  }
@@ -3005,6 +4040,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
3005
4040
  */
3006
4041
  setHeaders(headers) {
3007
4042
  this._headers = normalizeHeaders(headers);
4043
+ if (this._memoryStore) this.syncMemoryContext();
3008
4044
  this.agentRegistry.applyHeadersToAgents(this.agentRegistry.agents);
3009
4045
  this.notifySubscribers((subscriber) => {
3010
4046
  var _subscriber$onHeaders;
@@ -3116,6 +4152,47 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
3116
4152
  return this.threadStoreRegistry.getAll();
3117
4153
  }
3118
4154
  /**
4155
+ * Returns the single core-owned, user-scoped memory store, creating and
4156
+ * starting it on first access. Unlike thread stores, memory is not scoped per
4157
+ * agent: there is exactly one store whose runtime context the core wires
4158
+ * itself (see `syncMemoryContext`), so consumers (e.g. a `useMemories`
4159
+ * binding) just read this store rather than registering one.
4160
+ */
4161
+ getMemoryStore() {
4162
+ return this.ensureMemoryStore();
4163
+ }
4164
+ /**
4165
+ * Lazily creates, starts, and context-syncs the core-owned memory store on
4166
+ * first access, then returns it. Subsequent calls return the existing store.
4167
+ * The store is constructed with a bound `globalThis.fetch` and immediately
4168
+ * has its runtime context synced from the current connection state.
4169
+ */
4170
+ ensureMemoryStore() {
4171
+ if (!this._memoryStore) {
4172
+ this._memoryStore = createMemoryStore({ fetch: globalThis.fetch.bind(globalThis) });
4173
+ this._memoryStore.start();
4174
+ this.syncMemoryContext();
4175
+ }
4176
+ return this._memoryStore;
4177
+ }
4178
+ /**
4179
+ * Pushes the current runtime wiring into the memory store. When the runtime
4180
+ * is connected and both the intelligence WebSocket URL and runtime URL are
4181
+ * available, the store receives a context (runtime URL, WebSocket URL, and a
4182
+ * copy of the current headers); otherwise its context is cleared. No-op when
4183
+ * the store has not been created yet.
4184
+ */
4185
+ syncMemoryContext() {
4186
+ var _this$intelligence;
4187
+ if (!this._memoryStore) return;
4188
+ if (this.runtimeConnectionStatus === CopilotKitCoreRuntimeConnectionStatus.Connected && ((_this$intelligence = this.intelligence) === null || _this$intelligence === void 0 ? void 0 : _this$intelligence.wsUrl) && this.runtimeUrl) this._memoryStore.setContext({
4189
+ runtimeUrl: this.runtimeUrl,
4190
+ wsUrl: this.intelligence.wsUrl,
4191
+ headers: { ...this.headers }
4192
+ });
4193
+ else this._memoryStore.setContext(null);
4194
+ }
4195
+ /**
3119
4196
  * Suggestions management (delegated to SuggestionEngine)
3120
4197
  */
3121
4198
  addSuggestionsConfig(config) {
@@ -3284,507 +4361,248 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
3284
4361
  };
3285
4362
  const subscription = agent.subscribe(wrappedSubscriber);
3286
4363
  return { unsubscribe: () => {
3287
- active = false;
3288
- throttler.cancel();
3289
- subscription.unsubscribe();
3290
- } };
3291
- }
3292
- /**
3293
- * Agent connectivity (delegated to RunHandler)
3294
- */
3295
- async connectAgent(params) {
3296
- return this.runHandler.connectAgent(params);
3297
- }
3298
- stopAgent(params) {
3299
- this.runHandler.abortCurrentRun();
3300
- params.agent.abortRun();
3301
- }
3302
- async runAgent(params) {
3303
- return this.runHandler.runAgent(params);
3304
- }
3305
- /**
3306
- * Programmatically execute a registered frontend tool without going through an LLM turn.
3307
- * The handler runs, render components show up in the UI, and both the tool call and
3308
- * result messages are added to `agent.messages`.
3309
- */
3310
- async runTool(params) {
3311
- return this.runHandler.runTool(params);
3312
- }
3313
- /**
3314
- * State management (delegated to StateManager)
3315
- */
3316
- getStateByRun(agentId, threadId, runId) {
3317
- return this.stateManager.getStateByRun(agentId, threadId, runId);
3318
- }
3319
- getRunIdForMessage(agentId, threadId, messageId) {
3320
- return this.stateManager.getRunIdForMessage(agentId, threadId, messageId);
3321
- }
3322
- getRunIdsForThread(agentId, threadId) {
3323
- return this.stateManager.getRunIdsForThread(agentId, threadId);
3324
- }
3325
- /**
3326
- * Internal method used by RunHandler to build frontend tools
3327
- */
3328
- buildFrontendTools(agentId) {
3329
- return this.runHandler.buildFrontendTools(agentId);
3330
- }
3331
- /**
3332
- * Called before each follow-up agent run (after tool execution).
3333
- *
3334
- * When a frontend tool handler calls framework state setters (e.g. React's
3335
- * setState), those updates are batched and deferred — they do not take effect
3336
- * until the framework's scheduler runs (React uses MessageChannel).
3337
- * useAgentContext registers context via useLayoutEffect, which runs
3338
- * synchronously after React commits that deferred batch.
3339
- *
3340
- * Without yielding here, the follow-up runAgent reads the context store
3341
- * synchronously while the deferred updates are still pending, producing stale
3342
- * context for the next agent turn.
3343
- *
3344
- * Override in framework-specific subclasses to yield to the framework
3345
- * scheduler before the follow-up run. The base implementation is a no-op
3346
- * because non-React environments have no deferred state to flush.
3347
- */
3348
- async waitForPendingFrameworkUpdates() {}
3349
- };
3350
-
3351
- //#endregion
3352
- //#region src/types.ts
3353
- /**
3354
- * Status of a tool call execution
3355
- */
3356
- let ToolCallStatus = /* @__PURE__ */ function(ToolCallStatus) {
3357
- ToolCallStatus["InProgress"] = "inProgress";
3358
- ToolCallStatus["Executing"] = "executing";
3359
- ToolCallStatus["Complete"] = "complete";
3360
- return ToolCallStatus;
3361
- }({});
3362
-
3363
- //#endregion
3364
- //#region src/utils/markdown.ts
3365
- function completePartialMarkdown(input) {
3366
- let s = input;
3367
- const fenceMatches = Array.from(s.matchAll(/^(\s*)(`{3,}|~{3,})/gm));
3368
- if (fenceMatches.length % 2 === 1) {
3369
- const [, indent, fence] = fenceMatches[0];
3370
- s += `\n${indent}${fence}`;
3371
- }
3372
- if (s.match(/\[([^\]]*)\]\(([^)]*)$/)) s += ")";
3373
- const openElements = [];
3374
- const chars = Array.from(s);
3375
- const codeBlockRanges = [];
3376
- const inlineCodeRanges = [];
3377
- let tempCodeFenceCount = 0;
3378
- let currentCodeBlockStart = -1;
3379
- for (let i = 0; i < chars.length; i++) if (i === 0 || chars[i - 1] === "\n") {
3380
- const lineMatch = s.substring(i).match(/^(\s*)(`{3,}|~{3,})/);
3381
- if (lineMatch) {
3382
- tempCodeFenceCount++;
3383
- if (tempCodeFenceCount % 2 === 1) currentCodeBlockStart = i;
3384
- else if (currentCodeBlockStart !== -1) {
3385
- codeBlockRanges.push({
3386
- start: currentCodeBlockStart,
3387
- end: i + lineMatch[0].length
3388
- });
3389
- currentCodeBlockStart = -1;
3390
- }
3391
- i += lineMatch[0].length - 1;
3392
- }
3393
- }
3394
- for (let i = 0; i < chars.length; i++) if (chars[i] === "`") {
3395
- let backslashCount = 0;
3396
- for (let j = i - 1; j >= 0 && chars[j] === "\\"; j--) backslashCount++;
3397
- if (backslashCount % 2 === 0) {
3398
- for (let j = i + 1; j < chars.length; j++) if (chars[j] === "`") {
3399
- let closingBackslashCount = 0;
3400
- for (let k = j - 1; k >= 0 && chars[k] === "\\"; k--) closingBackslashCount++;
3401
- if (closingBackslashCount % 2 === 0) {
3402
- inlineCodeRanges.push({
3403
- start: i,
3404
- end: j + 1
3405
- });
3406
- i = j;
3407
- break;
3408
- }
3409
- }
3410
- }
3411
- }
3412
- const isInCode = (pos) => {
3413
- return codeBlockRanges.some((range) => pos >= range.start && pos < range.end) || inlineCodeRanges.some((range) => pos >= range.start && pos < range.end);
3414
- };
3415
- for (let i = 0; i < chars.length; i++) {
3416
- const char = chars[i];
3417
- const nextChar = chars[i + 1];
3418
- const prevChar = chars[i - 1];
3419
- if (isInCode(i)) continue;
3420
- if (char === "[") {
3421
- let isCompleteLink = false;
3422
- let bracketDepth = 1;
3423
- let j = i + 1;
3424
- while (j < chars.length && bracketDepth > 0) {
3425
- if (chars[j] === "[" && !isInCode(j)) bracketDepth++;
3426
- if (chars[j] === "]" && !isInCode(j)) bracketDepth--;
3427
- j++;
3428
- }
3429
- if (bracketDepth === 0 && chars[j] === "(") {
3430
- let parenDepth = 1;
3431
- j++;
3432
- while (j < chars.length && parenDepth > 0) {
3433
- if (chars[j] === "(" && !isInCode(j)) parenDepth++;
3434
- if (chars[j] === ")" && !isInCode(j)) parenDepth--;
3435
- j++;
3436
- }
3437
- if (parenDepth === 0) {
3438
- isCompleteLink = true;
3439
- i = j - 1;
3440
- continue;
3441
- }
3442
- }
3443
- if (!isCompleteLink) {
3444
- const existingIndex = openElements.findIndex((el) => el.type === "bracket");
3445
- if (existingIndex !== -1) openElements.splice(existingIndex, 1);
3446
- else openElements.push({
3447
- type: "bracket",
3448
- marker: "[",
3449
- position: i
3450
- });
3451
- }
3452
- } else if (char === "*" && nextChar === "*") {
3453
- const existingIndex = openElements.findIndex((el) => el.type === "bold_star");
3454
- if (existingIndex !== -1) openElements.splice(existingIndex, 1);
3455
- else openElements.push({
3456
- type: "bold_star",
3457
- marker: "**",
3458
- position: i
3459
- });
3460
- i++;
3461
- } else if (char === "_" && nextChar === "_") {
3462
- const existingIndex = openElements.findIndex((el) => el.type === "bold_underscore");
3463
- if (existingIndex !== -1) openElements.splice(existingIndex, 1);
3464
- else openElements.push({
3465
- type: "bold_underscore",
3466
- marker: "__",
3467
- position: i
3468
- });
3469
- i++;
3470
- } else if (char === "~" && nextChar === "~") {
3471
- const existingIndex = openElements.findIndex((el) => el.type === "strike");
3472
- if (existingIndex !== -1) openElements.splice(existingIndex, 1);
3473
- else openElements.push({
3474
- type: "strike",
3475
- marker: "~~",
3476
- position: i
3477
- });
3478
- i++;
3479
- } else if (char === "*" && prevChar !== "*" && nextChar !== "*") {
3480
- const existingIndex = openElements.findIndex((el) => el.type === "italic_star");
3481
- if (existingIndex !== -1) openElements.splice(existingIndex, 1);
3482
- else openElements.push({
3483
- type: "italic_star",
3484
- marker: "*",
3485
- position: i
3486
- });
3487
- } else if (char === "_" && prevChar !== "_" && nextChar !== "_") {
3488
- const existingIndex = openElements.findIndex((el) => el.type === "italic_underscore");
3489
- if (existingIndex !== -1) openElements.splice(existingIndex, 1);
3490
- else openElements.push({
3491
- type: "italic_underscore",
3492
- marker: "_",
3493
- position: i
3494
- });
3495
- }
4364
+ active = false;
4365
+ throttler.cancel();
4366
+ subscription.unsubscribe();
4367
+ } };
3496
4368
  }
3497
- let backtickCount = 0;
3498
- for (let i = 0; i < chars.length; i++) if (chars[i] === "`" && !isInCode(i)) backtickCount++;
3499
- if (backtickCount % 2 === 1) s += "`";
3500
- openElements.sort((a, b) => b.position - a.position);
3501
- const closers = openElements.map((el) => {
3502
- switch (el.type) {
3503
- case "bracket": return "]";
3504
- case "bold_star": return "**";
3505
- case "bold_underscore": return "__";
3506
- case "strike": return "~~";
3507
- case "italic_star": return "*";
3508
- case "italic_underscore": return "_";
3509
- default: return "";
3510
- }
3511
- });
3512
- let result = s + closers.join("");
3513
- const finalFenceMatches = Array.from(result.matchAll(/^(\s*)(`{3,}|~{3,})/gm));
3514
- const hasUnclosedBacktick = (result.match(/`/g) || []).length % 2 === 1;
3515
- const hasUnclosedCodeFence = finalFenceMatches.length % 2 === 1;
3516
- let shouldCloseParens = !hasUnclosedBacktick && !hasUnclosedCodeFence;
3517
- if (shouldCloseParens) {
3518
- const lastOpenParen = result.lastIndexOf("(");
3519
- if (lastOpenParen !== -1) {
3520
- if ((result.substring(0, lastOpenParen).match(/`/g) || []).length % 2 === 1) shouldCloseParens = false;
3521
- }
4369
+ /**
4370
+ * Agent connectivity (delegated to RunHandler)
4371
+ */
4372
+ async connectAgent(params) {
4373
+ return this.runHandler.connectAgent(params);
3522
4374
  }
3523
- if (shouldCloseParens) {
3524
- const openParens = (result.match(/\(/g) || []).length;
3525
- const closeParens = (result.match(/\)/g) || []).length;
3526
- if (openParens > closeParens) result += ")".repeat(openParens - closeParens);
4375
+ stopAgent(params) {
4376
+ this.runHandler.abortCurrentRun();
4377
+ params.agent.abortRun();
3527
4378
  }
3528
- return result;
3529
- }
3530
-
3531
- //#endregion
3532
- //#region src/utils/micro-redux.ts
3533
- const INTERNAL_ACTION_TYPES = {
3534
- boot: "@@micro-redux/boot",
3535
- init: "@@micro-redux/init",
3536
- stop: "@@micro-redux/stop"
3537
- };
3538
- const INTERNAL_BOOT_ACTION = { type: INTERNAL_ACTION_TYPES.boot };
3539
- /**
3540
- * Builds a typed action creator from a type string and payload factory.
3541
- */
3542
- function createTypedActionCreator(type, factory) {
3543
- const creator = ((...args) => ({
3544
- ...factory(...args),
3545
- type
3546
- }));
3547
- creator.type = type;
3548
- creator.match = (action) => action.type === type;
3549
- return creator;
3550
- }
3551
- /**
3552
- * Declares a payload-based action config for `createActionGroup`.
3553
- *
3554
- * @example
3555
- * ```ts
3556
- * const actions = createActionGroup("User", {
3557
- * loaded: props<{ id: string }>(),
3558
- * });
3559
- * ```
3560
- */
3561
- function props() {
3562
- return { kind: "props" };
3563
- }
3564
- /**
3565
- * Declares a no-payload action config for `createActionGroup`.
3566
- *
3567
- * @example
3568
- * ```ts
3569
- * const actions = createActionGroup("User", {
3570
- * reset: empty(),
3571
- * });
3572
- * ```
3573
- */
3574
- function empty() {
3575
- return { kind: "empty" };
3576
- }
3577
- /**
3578
- * Creates a namespaced group of typed action creators.
3579
- *
3580
- * Action types are formatted as: `[Source] actionName`.
3581
- */
3582
- function createActionGroup(source, config) {
3583
- const group = {};
3584
- for (const eventName of Object.keys(config)) {
3585
- const eventConfig = config[eventName];
3586
- if (!eventConfig) continue;
3587
- const actionType = `[${source}] ${eventName}`;
3588
- if (eventConfig.kind === "props") {
3589
- group[eventName] = createTypedActionCreator(actionType, (payload) => ({ ...payload }));
3590
- continue;
3591
- }
3592
- group[eventName] = createTypedActionCreator(actionType, () => ({}));
4379
+ async runAgent(params) {
4380
+ return this.runHandler.runAgent(params);
3593
4381
  }
3594
- return group;
3595
- }
3596
- /**
3597
- * Registers one reducer handler for one or more action creators.
3598
- *
3599
- * @throws Error when called without at least one action creator and reducer.
3600
- */
3601
- function on(...args) {
3602
- if (args.length < 2) throw new Error("on requires at least one action creator and one reducer");
3603
- const reducer = args[args.length - 1];
3604
- return {
3605
- creators: args.slice(0, -1),
3606
- reducer
3607
- };
3608
- }
3609
- /**
3610
- * Creates a reducer from an initial state and `on(...)` handler entries.
3611
- *
3612
- * Unknown action types return the current state unchanged.
3613
- */
3614
- function createReducer(initialState, ...entries) {
3615
- const reducerMap = /* @__PURE__ */ new Map();
3616
- for (const entry of entries) for (const creator of entry.creators) {
3617
- var _reducerMap$get;
3618
- const handlers = (_reducerMap$get = reducerMap.get(creator.type)) !== null && _reducerMap$get !== void 0 ? _reducerMap$get : [];
3619
- handlers.push(entry.reducer);
3620
- reducerMap.set(creator.type, handlers);
4382
+ /**
4383
+ * Programmatically execute a registered frontend tool without going through an LLM turn.
4384
+ * The handler runs, render components show up in the UI, and both the tool call and
4385
+ * result messages are added to `agent.messages`.
4386
+ */
4387
+ async runTool(params) {
4388
+ return this.runHandler.runTool(params);
3621
4389
  }
3622
- return (state, action) => {
3623
- const currentState = state !== null && state !== void 0 ? state : initialState;
3624
- const handlers = reducerMap.get(action.type);
3625
- if (!handlers || handlers.length === 0) return currentState;
3626
- let nextState = currentState;
3627
- for (const handler of handlers) nextState = handler(nextState, action);
3628
- return nextState;
3629
- };
3630
- }
3631
- /**
3632
- * Creates a selector that caches and reuses the last computed result
3633
- * when all input references are unchanged.
3634
- */
3635
- function createSelector(...args) {
3636
- if (args.length === 1) {
3637
- const projector = args[0];
3638
- let hasCached = false;
3639
- let lastState;
3640
- let lastResult;
3641
- return (state) => {
3642
- if (hasCached && state === lastState) return lastResult;
3643
- lastState = state;
3644
- lastResult = projector(state);
3645
- hasCached = true;
3646
- return lastResult;
3647
- };
4390
+ /**
4391
+ * State management (delegated to StateManager)
4392
+ */
4393
+ getStateByRun(agentId, threadId, runId) {
4394
+ return this.stateManager.getStateByRun(agentId, threadId, runId);
3648
4395
  }
3649
- const projector = args[args.length - 1];
3650
- const selectors = args.slice(0, -1);
3651
- let hasCached = false;
3652
- let lastInputs = [];
3653
- let lastResult;
3654
- return (state) => {
3655
- const inputs = selectors.map((selector) => selector(state));
3656
- if (hasCached && inputs.length === lastInputs.length && inputs.every((value, index) => value === lastInputs[index])) return lastResult;
3657
- lastInputs = inputs;
3658
- lastResult = projector(...inputs);
3659
- hasCached = true;
3660
- return lastResult;
3661
- };
3662
- }
3663
- /**
3664
- * RxJS operator that maps state emissions through a selector and suppresses
3665
- * unchanged projected values via reference equality.
3666
- */
3667
- function select(selector) {
3668
- return (source$) => source$.pipe((0, rxjs_operators.map)(selector), (0, rxjs_operators.distinctUntilChanged)());
3669
- }
3670
- /**
3671
- * RxJS operator that filters an action stream by action creators and narrows
3672
- * the output action type to the matched creator union.
3673
- *
3674
- * @throws Error when called without at least one action creator.
3675
- */
3676
- function ofType(...creators) {
3677
- if (creators.length === 0) throw new Error("ofType requires at least one action creator");
3678
- const actionTypes = new Set(creators.map((creator) => creator.type));
3679
- return (source$) => {
3680
- return source$.pipe((0, rxjs_operators.filter)((action) => {
3681
- return actionTypes.has(action.type);
3682
- }));
3683
- };
3684
- }
3685
- /**
3686
- * Creates an effect descriptor consumed by `createStore`.
3687
- */
3688
- function createEffect(factory, options = {}) {
3689
- if (options.dispatch === false) return {
3690
- run: factory,
3691
- dispatch: false
3692
- };
3693
- return {
3694
- run: factory,
3695
- dispatch: true
3696
- };
3697
- }
3698
- /**
3699
- * Creates a small observable store with reducer + effects.
3700
- *
3701
- * Behavior:
3702
- * - `init()` starts effects and dispatches `@@micro-redux/init`.
3703
- * - `stop()` dispatches `@@micro-redux/stop` and unsubscribes all effects.
3704
- * - Effect action observation is scheduled on `asapScheduler` to avoid
3705
- * synchronous re-entrancy in the effect loop.
3706
- * - Any effect error triggers fail-fast teardown and errors both `actions$`
3707
- * and `state$`.
4396
+ getRunIdForMessage(agentId, threadId, messageId) {
4397
+ return this.stateManager.getRunIdForMessage(agentId, threadId, messageId);
4398
+ }
4399
+ getRunIdsForThread(agentId, threadId) {
4400
+ return this.stateManager.getRunIdsForThread(agentId, threadId);
4401
+ }
4402
+ /**
4403
+ * Internal method used by RunHandler to build frontend tools
4404
+ */
4405
+ buildFrontendTools(agentId) {
4406
+ return this.runHandler.buildFrontendTools(agentId);
4407
+ }
4408
+ /**
4409
+ * Called before each follow-up agent run (after tool execution).
4410
+ *
4411
+ * When a frontend tool handler calls framework state setters (e.g. React's
4412
+ * setState), those updates are batched and deferred — they do not take effect
4413
+ * until the framework's scheduler runs (React uses MessageChannel).
4414
+ * useAgentContext registers context via useLayoutEffect, which runs
4415
+ * synchronously after React commits that deferred batch.
4416
+ *
4417
+ * Without yielding here, the follow-up runAgent reads the context store
4418
+ * synchronously while the deferred updates are still pending, producing stale
4419
+ * context for the next agent turn.
4420
+ *
4421
+ * Override in framework-specific subclasses to yield to the framework
4422
+ * scheduler before the follow-up run. The base implementation is a no-op
4423
+ * because non-React environments have no deferred state to flush.
4424
+ */
4425
+ async waitForPendingFrameworkUpdates() {}
4426
+ };
4427
+
4428
+ //#endregion
4429
+ //#region src/types.ts
4430
+ /**
4431
+ * Status of a tool call execution
3708
4432
  */
3709
- function createStore(options) {
3710
- var _options$effects;
3711
- const reducer = options.reducer;
3712
- const effects = (_options$effects = options.effects) !== null && _options$effects !== void 0 ? _options$effects : [];
3713
- let hasFatalError = false;
3714
- let isRunning = false;
3715
- let effectSubscriptions = new rxjs.Subscription();
3716
- let currentState = reducer(void 0, INTERNAL_BOOT_ACTION);
3717
- const stateSubject = new rxjs.BehaviorSubject(currentState);
3718
- const actionsSubject = new rxjs.Subject();
3719
- const dispatchInternal = (action) => {
3720
- if (hasFatalError) throw new Error("Store is in a failed state due to an effect error");
3721
- currentState = reducer(currentState, action);
3722
- stateSubject.next(currentState);
3723
- actionsSubject.next(action);
3724
- };
3725
- const failFast = (error) => {
3726
- if (hasFatalError) return;
3727
- hasFatalError = true;
3728
- isRunning = false;
3729
- effectSubscriptions.unsubscribe();
3730
- effectSubscriptions = new rxjs.Subscription();
3731
- actionsSubject.error(error);
3732
- stateSubject.error(error);
3733
- };
3734
- const startEffects = () => {
3735
- for (const effect of effects) {
3736
- const scheduledActions$ = actionsSubject.asObservable().pipe((0, rxjs_operators.observeOn)(rxjs.asapScheduler));
3737
- const state$ = stateSubject.asObservable();
3738
- if (effect.dispatch) {
3739
- const subscription = effect.run(scheduledActions$, state$).subscribe({
3740
- next: (effectAction) => {
3741
- if (hasFatalError) return;
3742
- dispatchInternal(effectAction);
3743
- },
3744
- error: (error) => {
3745
- failFast(error);
3746
- }
4433
+ let ToolCallStatus = /* @__PURE__ */ function(ToolCallStatus) {
4434
+ ToolCallStatus["InProgress"] = "inProgress";
4435
+ ToolCallStatus["Executing"] = "executing";
4436
+ ToolCallStatus["Complete"] = "complete";
4437
+ return ToolCallStatus;
4438
+ }({});
4439
+
4440
+ //#endregion
4441
+ //#region src/utils/markdown.ts
4442
+ function completePartialMarkdown(input) {
4443
+ let s = input;
4444
+ const fenceMatches = Array.from(s.matchAll(/^(\s*)(`{3,}|~{3,})/gm));
4445
+ if (fenceMatches.length % 2 === 1) {
4446
+ const [, indent, fence] = fenceMatches[0];
4447
+ s += `\n${indent}${fence}`;
4448
+ }
4449
+ if (s.match(/\[([^\]]*)\]\(([^)]*)$/)) s += ")";
4450
+ const openElements = [];
4451
+ const chars = Array.from(s);
4452
+ const codeBlockRanges = [];
4453
+ const inlineCodeRanges = [];
4454
+ let tempCodeFenceCount = 0;
4455
+ let currentCodeBlockStart = -1;
4456
+ for (let i = 0; i < chars.length; i++) if (i === 0 || chars[i - 1] === "\n") {
4457
+ const lineMatch = s.substring(i).match(/^(\s*)(`{3,}|~{3,})/);
4458
+ if (lineMatch) {
4459
+ tempCodeFenceCount++;
4460
+ if (tempCodeFenceCount % 2 === 1) currentCodeBlockStart = i;
4461
+ else if (currentCodeBlockStart !== -1) {
4462
+ codeBlockRanges.push({
4463
+ start: currentCodeBlockStart,
4464
+ end: i + lineMatch[0].length
3747
4465
  });
3748
- effectSubscriptions.add(subscription);
3749
- continue;
4466
+ currentCodeBlockStart = -1;
3750
4467
  }
3751
- const subscription = effect.run(scheduledActions$, state$).subscribe({ error: (error) => {
3752
- failFast(error);
3753
- } });
3754
- effectSubscriptions.add(subscription);
4468
+ i += lineMatch[0].length - 1;
3755
4469
  }
3756
- };
3757
- return {
3758
- dispatch(action) {
3759
- dispatchInternal(action);
3760
- },
3761
- getState() {
3762
- return currentState;
3763
- },
3764
- get state$() {
3765
- return stateSubject.asObservable();
3766
- },
3767
- get actions$() {
3768
- return actionsSubject.asObservable();
3769
- },
3770
- select(selector) {
3771
- return stateSubject.asObservable().pipe(select(selector));
3772
- },
3773
- init() {
3774
- if (hasFatalError || isRunning) return;
3775
- isRunning = true;
3776
- startEffects();
3777
- if (hasFatalError) return;
3778
- dispatchInternal({ type: INTERNAL_ACTION_TYPES.init });
3779
- },
3780
- stop() {
3781
- if (hasFatalError || !isRunning) return;
3782
- dispatchInternal({ type: INTERNAL_ACTION_TYPES.stop });
3783
- effectSubscriptions.unsubscribe();
3784
- effectSubscriptions = new rxjs.Subscription();
3785
- isRunning = false;
4470
+ }
4471
+ for (let i = 0; i < chars.length; i++) if (chars[i] === "`") {
4472
+ let backslashCount = 0;
4473
+ for (let j = i - 1; j >= 0 && chars[j] === "\\"; j--) backslashCount++;
4474
+ if (backslashCount % 2 === 0) {
4475
+ for (let j = i + 1; j < chars.length; j++) if (chars[j] === "`") {
4476
+ let closingBackslashCount = 0;
4477
+ for (let k = j - 1; k >= 0 && chars[k] === "\\"; k--) closingBackslashCount++;
4478
+ if (closingBackslashCount % 2 === 0) {
4479
+ inlineCodeRanges.push({
4480
+ start: i,
4481
+ end: j + 1
4482
+ });
4483
+ i = j;
4484
+ break;
4485
+ }
4486
+ }
3786
4487
  }
4488
+ }
4489
+ const isInCode = (pos) => {
4490
+ return codeBlockRanges.some((range) => pos >= range.start && pos < range.end) || inlineCodeRanges.some((range) => pos >= range.start && pos < range.end);
3787
4491
  };
4492
+ for (let i = 0; i < chars.length; i++) {
4493
+ const char = chars[i];
4494
+ const nextChar = chars[i + 1];
4495
+ const prevChar = chars[i - 1];
4496
+ if (isInCode(i)) continue;
4497
+ if (char === "[") {
4498
+ let isCompleteLink = false;
4499
+ let bracketDepth = 1;
4500
+ let j = i + 1;
4501
+ while (j < chars.length && bracketDepth > 0) {
4502
+ if (chars[j] === "[" && !isInCode(j)) bracketDepth++;
4503
+ if (chars[j] === "]" && !isInCode(j)) bracketDepth--;
4504
+ j++;
4505
+ }
4506
+ if (bracketDepth === 0 && chars[j] === "(") {
4507
+ let parenDepth = 1;
4508
+ j++;
4509
+ while (j < chars.length && parenDepth > 0) {
4510
+ if (chars[j] === "(" && !isInCode(j)) parenDepth++;
4511
+ if (chars[j] === ")" && !isInCode(j)) parenDepth--;
4512
+ j++;
4513
+ }
4514
+ if (parenDepth === 0) {
4515
+ isCompleteLink = true;
4516
+ i = j - 1;
4517
+ continue;
4518
+ }
4519
+ }
4520
+ if (!isCompleteLink) {
4521
+ const existingIndex = openElements.findIndex((el) => el.type === "bracket");
4522
+ if (existingIndex !== -1) openElements.splice(existingIndex, 1);
4523
+ else openElements.push({
4524
+ type: "bracket",
4525
+ marker: "[",
4526
+ position: i
4527
+ });
4528
+ }
4529
+ } else if (char === "*" && nextChar === "*") {
4530
+ const existingIndex = openElements.findIndex((el) => el.type === "bold_star");
4531
+ if (existingIndex !== -1) openElements.splice(existingIndex, 1);
4532
+ else openElements.push({
4533
+ type: "bold_star",
4534
+ marker: "**",
4535
+ position: i
4536
+ });
4537
+ i++;
4538
+ } else if (char === "_" && nextChar === "_") {
4539
+ const existingIndex = openElements.findIndex((el) => el.type === "bold_underscore");
4540
+ if (existingIndex !== -1) openElements.splice(existingIndex, 1);
4541
+ else openElements.push({
4542
+ type: "bold_underscore",
4543
+ marker: "__",
4544
+ position: i
4545
+ });
4546
+ i++;
4547
+ } else if (char === "~" && nextChar === "~") {
4548
+ const existingIndex = openElements.findIndex((el) => el.type === "strike");
4549
+ if (existingIndex !== -1) openElements.splice(existingIndex, 1);
4550
+ else openElements.push({
4551
+ type: "strike",
4552
+ marker: "~~",
4553
+ position: i
4554
+ });
4555
+ i++;
4556
+ } else if (char === "*" && prevChar !== "*" && nextChar !== "*") {
4557
+ const existingIndex = openElements.findIndex((el) => el.type === "italic_star");
4558
+ if (existingIndex !== -1) openElements.splice(existingIndex, 1);
4559
+ else openElements.push({
4560
+ type: "italic_star",
4561
+ marker: "*",
4562
+ position: i
4563
+ });
4564
+ } else if (char === "_" && prevChar !== "_" && nextChar !== "_") {
4565
+ const existingIndex = openElements.findIndex((el) => el.type === "italic_underscore");
4566
+ if (existingIndex !== -1) openElements.splice(existingIndex, 1);
4567
+ else openElements.push({
4568
+ type: "italic_underscore",
4569
+ marker: "_",
4570
+ position: i
4571
+ });
4572
+ }
4573
+ }
4574
+ let backtickCount = 0;
4575
+ for (let i = 0; i < chars.length; i++) if (chars[i] === "`" && !isInCode(i)) backtickCount++;
4576
+ if (backtickCount % 2 === 1) s += "`";
4577
+ openElements.sort((a, b) => b.position - a.position);
4578
+ const closers = openElements.map((el) => {
4579
+ switch (el.type) {
4580
+ case "bracket": return "]";
4581
+ case "bold_star": return "**";
4582
+ case "bold_underscore": return "__";
4583
+ case "strike": return "~~";
4584
+ case "italic_star": return "*";
4585
+ case "italic_underscore": return "_";
4586
+ default: return "";
4587
+ }
4588
+ });
4589
+ let result = s + closers.join("");
4590
+ const finalFenceMatches = Array.from(result.matchAll(/^(\s*)(`{3,}|~{3,})/gm));
4591
+ const hasUnclosedBacktick = (result.match(/`/g) || []).length % 2 === 1;
4592
+ const hasUnclosedCodeFence = finalFenceMatches.length % 2 === 1;
4593
+ let shouldCloseParens = !hasUnclosedBacktick && !hasUnclosedCodeFence;
4594
+ if (shouldCloseParens) {
4595
+ const lastOpenParen = result.lastIndexOf("(");
4596
+ if (lastOpenParen !== -1) {
4597
+ if ((result.substring(0, lastOpenParen).match(/`/g) || []).length % 2 === 1) shouldCloseParens = false;
4598
+ }
4599
+ }
4600
+ if (shouldCloseParens) {
4601
+ const openParens = (result.match(/\(/g) || []).length;
4602
+ const closeParens = (result.match(/\)/g) || []).length;
4603
+ if (openParens > closeParens) result += ")".repeat(openParens - closeParens);
4604
+ }
4605
+ return result;
3788
4606
  }
3789
4607
 
3790
4608
  //#endregion
@@ -3799,6 +4617,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
3799
4617
  isLoading: false,
3800
4618
  isFetchingNextPage: false,
3801
4619
  error: null,
4620
+ fetchMoreError: null,
3802
4621
  context: null,
3803
4622
  sessionId: 0,
3804
4623
  metadataCredentialsRequested: false,
@@ -3886,6 +4705,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
3886
4705
  isLoading: Boolean(context),
3887
4706
  isFetchingNextPage: false,
3888
4707
  error: null,
4708
+ fetchMoreError: null,
3889
4709
  metadataCredentialsRequested: false,
3890
4710
  metadataJoinCode: null,
3891
4711
  nextCursor: null,
@@ -3897,6 +4717,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
3897
4717
  isLoading: false,
3898
4718
  isFetchingNextPage: false,
3899
4719
  error: null,
4720
+ fetchMoreError: null,
3900
4721
  metadataCredentialsRequested: false,
3901
4722
  metadataJoinCode: null,
3902
4723
  nextCursor: null,
@@ -3907,7 +4728,8 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
3907
4728
  return {
3908
4729
  ...state,
3909
4730
  isLoading: true,
3910
- error: null
4731
+ error: null,
4732
+ fetchMoreError: null
3911
4733
  };
3912
4734
  }), on(threadRestEvents.listSucceeded, (state, { sessionId, threads, joinCode, nextCursor }) => {
3913
4735
  if (sessionId !== state.sessionId) return state;
@@ -3917,6 +4739,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
3917
4739
  threads: sortThreadsByRecency(threads),
3918
4740
  isLoading: false,
3919
4741
  error: null,
4742
+ fetchMoreError: null,
3920
4743
  metadataJoinCode: joinCode,
3921
4744
  metadataCredentialsRequested: joinCodeChanged ? false : state.metadataCredentialsRequested,
3922
4745
  nextCursor
@@ -3936,6 +4759,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
3936
4759
  ...state,
3937
4760
  threads: merged,
3938
4761
  isFetchingNextPage: false,
4762
+ fetchMoreError: null,
3939
4763
  nextCursor
3940
4764
  };
3941
4765
  }), on(threadRestEvents.nextPageFailed, (state, { sessionId, error }) => {
@@ -3943,7 +4767,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
3943
4767
  return {
3944
4768
  ...state,
3945
4769
  isFetchingNextPage: false,
3946
- error
4770
+ fetchMoreError: error
3947
4771
  };
3948
4772
  }), on(threadRestEvents.metadataCredentialsFailed, (state, { sessionId }) => {
3949
4773
  if (sessionId !== state.sessionId) return state;
@@ -3961,7 +4785,8 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
3961
4785
  if (!state.nextCursor || state.isFetchingNextPage) return state;
3962
4786
  return {
3963
4787
  ...state,
3964
- isFetchingNextPage: true
4788
+ isFetchingNextPage: true,
4789
+ fetchMoreError: null
3965
4790
  };
3966
4791
  }), on(threadAdapterEvents.renameRequested, (state, { threadId, name }) => {
3967
4792
  const existing = state.threads.find((thread) => thread.id === threadId);
@@ -4091,6 +4916,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
4091
4916
  threads: createSelector((state) => state.threads),
4092
4917
  isLoading: createSelector((state) => state.isLoading),
4093
4918
  error: createSelector((state) => state.error),
4919
+ fetchMoreError: createSelector((state) => state.fetchMoreError),
4094
4920
  hasNextPage: createSelector((state) => state.nextCursor != null),
4095
4921
  isFetchingNextPage: createSelector((state) => state.isFetchingNextPage),
4096
4922
  isMutating: createSelector((state) => state.inFlightMutationCount > 0)
@@ -4100,6 +4926,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
4100
4926
  const selectThreads = standaloneSelectors.threads;
4101
4927
  const selectThreadsIsLoading = standaloneSelectors.isLoading;
4102
4928
  const selectThreadsError = standaloneSelectors.error;
4929
+ const selectFetchMoreError = standaloneSelectors.fetchMoreError;
4103
4930
  const selectHasNextPage = standaloneSelectors.hasNextPage;
4104
4931
  const selectIsFetchingNextPage = standaloneSelectors.isFetchingNextPage;
4105
4932
  const selectIsMutating = standaloneSelectors.isMutating;
@@ -4485,6 +5312,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
4485
5312
  const ɵselectThreads = selectThreads;
4486
5313
  const ɵselectThreadsIsLoading = selectThreadsIsLoading;
4487
5314
  const ɵselectThreadsError = selectThreadsError;
5315
+ const ɵselectFetchMoreError = selectFetchMoreError;
4488
5316
  const ɵselectHasNextPage = selectHasNextPage;
4489
5317
  const ɵselectIsFetchingNextPage = selectIsFetchingNextPage;
4490
5318
  const ɵselectIsMutating = selectIsMutating;
@@ -4549,6 +5377,8 @@ exports.CopilotKitCore = CopilotKitCore;
4549
5377
  exports.CopilotKitCoreErrorCode = CopilotKitCoreErrorCode;
4550
5378
  exports.CopilotKitCoreRuntimeConnectionStatus = CopilotKitCoreRuntimeConnectionStatus;
4551
5379
  exports.IntelligenceAgent = IntelligenceAgent;
5380
+ exports.MEMORY_ERROR_REGISTRY = MEMORY_ERROR_REGISTRY;
5381
+ exports.MemoryError = MemoryError;
4552
5382
  exports.ProxiedCopilotRuntimeAgent = ProxiedCopilotRuntimeAgent;
4553
5383
  exports.RunHandler = RunHandler;
4554
5384
  exports.StateManager = StateManager;
@@ -4562,6 +5392,7 @@ exports.createSelector = createSelector;
4562
5392
  exports.createStore = createStore;
4563
5393
  exports.empty = empty;
4564
5394
  exports.ensureObjectArgs = ensureObjectArgs;
5395
+ exports.isAbortError = isAbortError;
4565
5396
  exports.isRunCompletionAware = isRunCompletionAware;
4566
5397
  exports.ofType = ofType;
4567
5398
  exports.on = on;
@@ -4570,19 +5401,33 @@ exports.props = props;
4570
5401
  exports.select = select;
4571
5402
  exports.ɵCOPILOTKIT_FEATURES = ɵCOPILOTKIT_FEATURES;
4572
5403
  exports.ɵMAX_SOCKET_RETRIES = ɵMAX_SOCKET_RETRIES;
5404
+ exports.ɵcreateMemoryStore = createMemoryStore;
4573
5405
  exports.ɵcreateThreadSelectors = ɵcreateThreadSelectors;
4574
5406
  exports.ɵcreateThreadStore = createThreadStore;
4575
5407
  exports.ɵisCopilotKitFeature = ɵisCopilotKitFeature;
5408
+ exports.ɵisRetryableMemoryStatus = isRetryableStatus;
4576
5409
  exports.ɵjoinPhoenixChannel$ = ɵjoinPhoenixChannel$;
5410
+ exports.ɵmapMemoryMetadataEvent = ɵmapMemoryMetadataEvent;
5411
+ exports.ɵmemoryAdapterEvents = ɵmemoryAdapterEvents;
5412
+ exports.ɵmemoryDomainEvents = ɵmemoryDomainEvents;
5413
+ exports.ɵmemoryReducer = ɵmemoryReducer;
5414
+ exports.ɵmemoryRestEvents = ɵmemoryRestEvents;
4577
5415
  exports.ɵobservePhoenixEvent$ = ɵobservePhoenixEvent$;
4578
5416
  exports.ɵobservePhoenixJoinOutcome$ = ɵobservePhoenixJoinOutcome$;
4579
5417
  exports.ɵobservePhoenixSocketHealth$ = ɵobservePhoenixSocketHealth$;
4580
5418
  exports.ɵobservePhoenixSocketSignals$ = ɵobservePhoenixSocketSignals$;
4581
5419
  exports.ɵphoenixChannel$ = ɵphoenixChannel$;
4582
5420
  exports.ɵphoenixSocket$ = ɵphoenixSocket$;
5421
+ exports.ɵselectFetchMoreError = ɵselectFetchMoreError;
4583
5422
  exports.ɵselectHasNextPage = ɵselectHasNextPage;
4584
5423
  exports.ɵselectIsFetchingNextPage = ɵselectIsFetchingNextPage;
4585
5424
  exports.ɵselectIsMutating = ɵselectIsMutating;
5425
+ exports.ɵselectMemories = ɵselectMemories;
5426
+ exports.ɵselectMemoriesAvailable = ɵselectMemoriesAvailable;
5427
+ exports.ɵselectMemoriesError = ɵselectMemoriesError;
5428
+ exports.ɵselectMemoriesIsLoading = ɵselectMemoriesIsLoading;
5429
+ exports.ɵselectMemoriesIsMutating = ɵselectMemoriesIsMutating;
5430
+ exports.ɵselectMemoriesRealtimeStatus = ɵselectMemoriesRealtimeStatus;
4586
5431
  exports.ɵselectThreads = ɵselectThreads;
4587
5432
  exports.ɵselectThreadsError = ɵselectThreadsError;
4588
5433
  exports.ɵselectThreadsIsLoading = ɵselectThreadsIsLoading;