@copilotkit/core 1.62.2 → 1.63.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -6,6 +6,7 @@ let rxjs = require("rxjs");
6
6
  let rxjs_operators = require("rxjs/operators");
7
7
  let phoenix = require("phoenix");
8
8
  let zod_to_json_schema = require("zod-to-json-schema");
9
+ let rxjs_fetch = require("rxjs/fetch");
9
10
 
10
11
  //#region src/utils/phoenix-observable.ts
11
12
  /**
@@ -543,12 +544,12 @@ function hasCredentials(agent) {
543
544
  function isZodError(error) {
544
545
  return error !== null && typeof error === "object" && "name" in error && error.name === "ZodError";
545
546
  }
546
- function isAbortError(error) {
547
+ function isAbortError$1(error) {
547
548
  return (error instanceof DOMException || error instanceof Error) && error.name === "AbortError";
548
549
  }
549
550
  function withAbortErrorHandling(observable) {
550
551
  return observable.pipe((0, rxjs_operators.catchError)((error) => {
551
- if (isZodError(error) || isAbortError(error)) return rxjs.EMPTY;
552
+ if (isZodError(error) || isAbortError$1(error)) return rxjs.EMPTY;
552
553
  throw error;
553
554
  }));
554
555
  }
@@ -888,6 +889,7 @@ var AgentRegistry = class {
888
889
  localAgents = {};
889
890
  remoteAgents = {};
890
891
  _runtimeUrl;
892
+ _connectionInFlight;
891
893
  _runtimeVersion;
892
894
  _runtimeConnectionStatus = CopilotKitCoreRuntimeConnectionStatus.Disconnected;
893
895
  _runtimeTransport = "auto";
@@ -896,6 +898,7 @@ var AgentRegistry = class {
896
898
  _runtimeMode = _copilotkit_shared.RUNTIME_MODE_SSE;
897
899
  _intelligence;
898
900
  _threadEndpoints;
901
+ _suggestions;
899
902
  _a2uiEnabled = false;
900
903
  _a2uiAgents;
901
904
  _openGenerativeUIEnabled = false;
@@ -945,6 +948,9 @@ var AgentRegistry = class {
945
948
  get threadEndpoints() {
946
949
  return this._threadEndpoints;
947
950
  }
951
+ get suggestions() {
952
+ return this._suggestions;
953
+ }
948
954
  get a2uiEnabled() {
949
955
  return this._a2uiEnabled;
950
956
  }
@@ -976,10 +982,28 @@ var AgentRegistry = class {
976
982
  /**
977
983
  * Set the runtime URL and update connection
978
984
  */
979
- setRuntimeUrl(runtimeUrl) {
985
+ setRuntimeUrl(runtimeUrl, options) {
980
986
  const normalizedRuntimeUrl = runtimeUrl ? runtimeUrl.replace(/\/$/, "") : void 0;
981
987
  if (this._runtimeUrl === normalizedRuntimeUrl) return;
982
988
  this._runtimeUrl = normalizedRuntimeUrl;
989
+ if (options?.deferConnection) return;
990
+ this.updateRuntimeConnection();
991
+ }
992
+ /**
993
+ * Start the initial runtime connection if it has not been started yet.
994
+ *
995
+ * Backs {@link CopilotKitCore.connect}. Idempotent: it only kicks off a fetch
996
+ * when a `runtimeUrl` is set and the connection is still `Disconnected` (its
997
+ * state before any connect attempt). `updateRuntimeConnection` flips the
998
+ * status to `Connecting` synchronously, so a second call — e.g. React
999
+ * StrictMode double-invoking the mount effect — bails here. A genuine config
1000
+ * change still reconnects through `setRuntimeUrl`/`setRuntimeTransport`. See
1001
+ * #5801.
1002
+ */
1003
+ connectRuntime() {
1004
+ if (typeof window === "undefined") return;
1005
+ if (!this._runtimeUrl) return;
1006
+ if (this._runtimeConnectionStatus !== CopilotKitCoreRuntimeConnectionStatus.Disconnected) return;
983
1007
  this.updateRuntimeConnection();
984
1008
  }
985
1009
  setRuntimeTransport(runtimeTransport) {
@@ -1125,6 +1149,20 @@ var AgentRegistry = class {
1125
1149
  */
1126
1150
  async updateRuntimeConnection() {
1127
1151
  if (typeof window === "undefined") return;
1152
+ const key = `${this._runtimeUrl ?? ""}::${this._requestedTransport}`;
1153
+ const inFlight = this._connectionInFlight;
1154
+ if (inFlight && inFlight.key === key) return inFlight.promise;
1155
+ const promise = this.performRuntimeConnection();
1156
+ this._connectionInFlight = {
1157
+ key,
1158
+ promise
1159
+ };
1160
+ promise.finally(() => {
1161
+ if (this._connectionInFlight?.promise === promise) this._connectionInFlight = void 0;
1162
+ });
1163
+ return promise;
1164
+ }
1165
+ async performRuntimeConnection() {
1128
1166
  if (!this.runtimeUrl) {
1129
1167
  this._runtimeConnectionStatus = CopilotKitCoreRuntimeConnectionStatus.Disconnected;
1130
1168
  this._runtimeVersion = void 0;
@@ -1132,6 +1170,7 @@ var AgentRegistry = class {
1132
1170
  this._runtimeMode = _copilotkit_shared.RUNTIME_MODE_SSE;
1133
1171
  this._intelligence = void 0;
1134
1172
  this._threadEndpoints = void 0;
1173
+ this._suggestions = void 0;
1135
1174
  this._a2uiEnabled = false;
1136
1175
  this._a2uiAgents = void 0;
1137
1176
  this._openGenerativeUIEnabled = false;
@@ -1179,6 +1218,7 @@ var AgentRegistry = class {
1179
1218
  this._runtimeMode = runtimeInfoResponse.mode ?? _copilotkit_shared.RUNTIME_MODE_SSE;
1180
1219
  this._intelligence = runtimeInfoResponse.intelligence;
1181
1220
  this._threadEndpoints = runtimeInfoResponse.threadEndpoints;
1221
+ this._suggestions = runtimeInfoResponse.suggestions;
1182
1222
  const a2uiInfo = runtimeInfoResponse.a2ui;
1183
1223
  this._a2uiEnabled = a2uiInfo?.enabled ?? runtimeInfoResponse.a2uiEnabled ?? false;
1184
1224
  this._a2uiAgents = a2uiInfo?.enabled ? a2uiInfo.agents : void 0;
@@ -1194,6 +1234,7 @@ var AgentRegistry = class {
1194
1234
  this._runtimeMode = _copilotkit_shared.RUNTIME_MODE_SSE;
1195
1235
  this._intelligence = void 0;
1196
1236
  this._threadEndpoints = void 0;
1237
+ this._suggestions = void 0;
1197
1238
  this._a2uiEnabled = false;
1198
1239
  this._a2uiAgents = void 0;
1199
1240
  this._openGenerativeUIEnabled = false;
@@ -1433,38 +1474,81 @@ var SuggestionEngine = class {
1433
1474
  };
1434
1475
  }
1435
1476
  /**
1436
- * Generate suggestions using a provider agent
1477
+ * Generate suggestions by running a provider agent and extracting the
1478
+ * `copilotkitSuggest` tool call from its streamed messages.
1479
+ *
1480
+ * Two transports, one set of mechanics: both seed an agent with the
1481
+ * consumer's messages + state and the instruction, then `runAgent` with
1482
+ * forced `copilotkitSuggest` tool choice, parsing suggestions as messages
1483
+ * stream in via `onMessagesChanged`.
1484
+ *
1485
+ * - **Stateless** (runtime advertises `suggestions` and transport isn't
1486
+ * `single`): a stock `HttpAgent` pointed at `/agent/:id/suggest`. That
1487
+ * endpoint runs the provider directly and streams AG-UI SSE **without**
1488
+ * persisting a thread, and a plain `HttpAgent` only ever speaks REST SSE —
1489
+ * it never routes through the Intelligence websocket delegate (which would
1490
+ * persist a thread). This is the path that removes the thread flood.
1491
+ * - **Fallback** (capability absent → old runtime, or `single` transport):
1492
+ * clone the provider agent and run it client-side, as before.
1493
+ *
1494
+ * Gated to non-`single` transports because this client only builds the
1495
+ * multi-route `/agent/:id/suggest` URL; single-route deployments (not the
1496
+ * persisting-thread/Intelligence case) fall through to the clone fallback.
1437
1497
  */
1438
1498
  async generateSuggestions(suggestionId, config, consumerAgentId) {
1439
- let agent = void 0;
1499
+ let runHandle = void 0;
1500
+ let aborted = false;
1440
1501
  try {
1441
- const suggestionsProviderAgent = this.core.getAgent(config.providerAgentId ?? "default");
1442
- if (!suggestionsProviderAgent) throw new Error(`Suggestions provider agent not found: ${config.providerAgentId}`);
1443
- const suggestionsConsumerAgent = this.core.getAgent(consumerAgentId);
1502
+ const friends = this.core;
1503
+ const resolvedProviderAgentId = config.providerAgentId ?? "default";
1504
+ const suggestionsProviderAgent = friends.getAgent(resolvedProviderAgentId);
1505
+ if (!suggestionsProviderAgent) throw new Error(`Suggestions provider agent not found: ${resolvedProviderAgentId}`);
1506
+ const suggestionsConsumerAgent = friends.getAgent(consumerAgentId);
1444
1507
  if (!suggestionsConsumerAgent) throw new Error(`Suggestions consumer agent not found: ${consumerAgentId}`);
1445
- agent = suggestionsProviderAgent.clone();
1446
- agent.threadId = suggestionId;
1447
- agent.messages = JSON.parse(JSON.stringify(suggestionsConsumerAgent.messages));
1448
- agent.state = JSON.parse(JSON.stringify(suggestionsConsumerAgent.state));
1508
+ const instructionContent = [
1509
+ `Suggest what the user could say next. Provide clear, highly relevant suggestions by calling the \`copilotkitSuggest\` tool.`,
1510
+ `Provide at least ${config.minSuggestions ?? 1} and at most ${config.maxSuggestions ?? 3} suggestions.`,
1511
+ `The user has the following tools available: ${JSON.stringify(friends.buildFrontendTools(consumerAgentId))}.`,
1512
+ ` ${config.instructions}`
1513
+ ].join("\n");
1449
1514
  this._suggestions[consumerAgentId] = {
1450
1515
  ...this._suggestions[consumerAgentId],
1451
1516
  [suggestionId]: []
1452
1517
  };
1453
- this._runningSuggestions[consumerAgentId] = [...this._runningSuggestions[consumerAgentId] ?? [], agent];
1454
- agent.addMessage({
1518
+ const seededMessages = JSON.parse(JSON.stringify(suggestionsConsumerAgent.messages));
1519
+ const seededState = JSON.parse(JSON.stringify(suggestionsConsumerAgent.state ?? {}));
1520
+ const useStateless = this.core.suggestions === true && this.core.runtimeTransport !== "single";
1521
+ let suggestionAgent;
1522
+ if (useStateless) {
1523
+ const suggestUrl = `${this.core.runtimeUrl}/agent/${encodeURIComponent(resolvedProviderAgentId)}/suggest`;
1524
+ const credentials = this.core.credentials;
1525
+ suggestionAgent = new _ag_ui_client.HttpAgent({
1526
+ agentId: resolvedProviderAgentId,
1527
+ url: suggestUrl,
1528
+ headers: { ...this.core.headers },
1529
+ ...credentials ? { fetch: (url, requestInit) => fetch(url, {
1530
+ ...requestInit,
1531
+ credentials
1532
+ }) } : {}
1533
+ });
1534
+ } else suggestionAgent = suggestionsProviderAgent.clone();
1535
+ suggestionAgent.threadId = suggestionId;
1536
+ suggestionAgent.setMessages(seededMessages);
1537
+ suggestionAgent.setState(seededState);
1538
+ runHandle = { abortRun: () => {
1539
+ aborted = true;
1540
+ suggestionAgent.abortRun();
1541
+ } };
1542
+ this._runningSuggestions[consumerAgentId] = [...this._runningSuggestions[consumerAgentId] ?? [], runHandle];
1543
+ suggestionAgent.addMessage({
1455
1544
  id: suggestionId,
1456
1545
  role: "user",
1457
- content: [
1458
- `Suggest what the user could say next. Provide clear, highly relevant suggestions by calling the \`copilotkitSuggest\` tool.`,
1459
- `Provide at least ${config.minSuggestions ?? 1} and at most ${config.maxSuggestions ?? 3} suggestions.`,
1460
- `The user has the following tools available: ${JSON.stringify(this.core.buildFrontendTools(consumerAgentId))}.`,
1461
- ` ${config.instructions}`
1462
- ].join("\n")
1546
+ content: instructionContent
1463
1547
  });
1464
- await agent.runAgent({
1465
- context: this.core.getContextForAgent(consumerAgentId),
1548
+ await suggestionAgent.runAgent({
1549
+ context: friends.getContextForAgent(consumerAgentId),
1466
1550
  forwardedProps: {
1467
- ...this.core.properties,
1551
+ ...friends.properties,
1468
1552
  toolChoice: {
1469
1553
  type: "function",
1470
1554
  function: { name: "copilotkitSuggest" }
@@ -1475,18 +1559,15 @@ var SuggestionEngine = class {
1475
1559
  this.extractSuggestions(messages, suggestionId, consumerAgentId, true);
1476
1560
  } });
1477
1561
  } catch (error) {
1478
- console.warn("Error generating suggestions:", error);
1562
+ if (!isAbortError(error) && !aborted) console.warn("Error generating suggestions:", error);
1479
1563
  } finally {
1480
1564
  this.finalizeSuggestions(suggestionId, consumerAgentId);
1481
1565
  const runningAgents = this._runningSuggestions[consumerAgentId];
1482
- if (agent && runningAgents) {
1483
- const filteredAgents = runningAgents.filter((a) => a !== agent);
1484
- this._runningSuggestions[consumerAgentId] = filteredAgents;
1485
- if (filteredAgents.length === 0) {
1486
- delete this._runningSuggestions[consumerAgentId];
1487
- await this.notifySuggestionsFinishedLoading(consumerAgentId);
1488
- }
1489
- }
1566
+ const remaining = runHandle ? (runningAgents ?? []).filter((a) => a !== runHandle) : runningAgents ?? [];
1567
+ if (remaining.length === 0) {
1568
+ delete this._runningSuggestions[consumerAgentId];
1569
+ await this.notifySuggestionsFinishedLoading(consumerAgentId);
1570
+ } else this._runningSuggestions[consumerAgentId] = remaining;
1490
1571
  }
1491
1572
  }
1492
1573
  /**
@@ -1606,6 +1687,13 @@ var SuggestionEngine = class {
1606
1687
  }
1607
1688
  };
1608
1689
  /**
1690
+ * Detects an `AbortController`-driven cancellation so the stateless path can
1691
+ * treat it as an expected (non-error) outcome on clear/reload.
1692
+ */
1693
+ function isAbortError(error) {
1694
+ return typeof error === "object" && error !== null && "name" in error && error.name === "AbortError";
1695
+ }
1696
+ /**
1609
1697
  * Type guard for dynamic suggestions config
1610
1698
  */
1611
1699
  function isDynamicSuggestionsConfig(config) {
@@ -2565,153 +2653,1135 @@ var ThreadStoreRegistry = class {
2565
2653
  };
2566
2654
 
2567
2655
  //#endregion
2568
- //#region src/core/core.ts
2569
- let CopilotKitCoreErrorCode = /* @__PURE__ */ function(CopilotKitCoreErrorCode) {
2570
- CopilotKitCoreErrorCode["RUNTIME_INFO_FETCH_FAILED"] = "runtime_info_fetch_failed";
2571
- CopilotKitCoreErrorCode["AGENT_CONNECT_FAILED"] = "agent_connect_failed";
2572
- CopilotKitCoreErrorCode["AGENT_RUN_FAILED"] = "agent_run_failed";
2573
- CopilotKitCoreErrorCode["AGENT_RUN_FAILED_EVENT"] = "agent_run_failed_event";
2574
- CopilotKitCoreErrorCode["AGENT_RUN_ERROR_EVENT"] = "agent_run_error_event";
2575
- CopilotKitCoreErrorCode["TOOL_ARGUMENT_PARSE_FAILED"] = "tool_argument_parse_failed";
2576
- CopilotKitCoreErrorCode["TOOL_HANDLER_FAILED"] = "tool_handler_failed";
2577
- CopilotKitCoreErrorCode["TOOL_NOT_FOUND"] = "tool_not_found";
2578
- CopilotKitCoreErrorCode["AGENT_NOT_FOUND"] = "agent_not_found";
2579
- /**
2580
- * Emitted when an agent run fails because the thread is already locked
2581
- * by another active run.
2582
- *
2583
- * @example
2584
- * ```tsx
2585
- * <CopilotKitProvider
2586
- * onError={({ code, error, context }) => {
2587
- * if (code === "agent_thread_locked") {
2588
- * // Show "Agent is busy, retry?" UI
2589
- * }
2590
- * }}
2591
- * />
2592
- * ```
2593
- */
2594
- CopilotKitCoreErrorCode["AGENT_THREAD_LOCKED"] = "agent_thread_locked";
2595
- CopilotKitCoreErrorCode["TRANSCRIPTION_FAILED"] = "transcription_failed";
2596
- CopilotKitCoreErrorCode["TRANSCRIPTION_SERVICE_NOT_CONFIGURED"] = "transcription_service_not_configured";
2597
- CopilotKitCoreErrorCode["TRANSCRIPTION_INVALID_AUDIO"] = "transcription_invalid_audio";
2598
- CopilotKitCoreErrorCode["TRANSCRIPTION_RATE_LIMITED"] = "transcription_rate_limited";
2599
- CopilotKitCoreErrorCode["TRANSCRIPTION_AUTH_FAILED"] = "transcription_auth_failed";
2600
- CopilotKitCoreErrorCode["TRANSCRIPTION_NETWORK_ERROR"] = "transcription_network_error";
2601
- CopilotKitCoreErrorCode["SUBSCRIBER_CALLBACK_FAILED"] = "subscriber_callback_failed";
2602
- return CopilotKitCoreErrorCode;
2603
- }({});
2656
+ //#region src/utils/micro-redux.ts
2657
+ const INTERNAL_ACTION_TYPES = {
2658
+ boot: "@@micro-redux/boot",
2659
+ init: "@@micro-redux/init",
2660
+ stop: "@@micro-redux/stop"
2661
+ };
2662
+ const INTERNAL_BOOT_ACTION = { type: INTERNAL_ACTION_TYPES.boot };
2604
2663
  /**
2605
- * Runtime allowlist derived from {@link SUBSCRIBE_TO_AGENT_KEYS}. Hoisted
2606
- * to module scope so the Set is allocated once, not per-subscription.
2664
+ * Builds a typed action creator from a type string and payload factory.
2607
2665
  */
2608
- const ALLOWED_KEYS = new Set([
2609
- "onMessagesChanged",
2610
- "onStateChanged",
2611
- "onRunInitialized",
2612
- "onRunFinalized",
2613
- "onRunFailed",
2614
- "onRunErrorEvent"
2615
- ]);
2616
- let CopilotKitCoreRuntimeConnectionStatus = /* @__PURE__ */ function(CopilotKitCoreRuntimeConnectionStatus) {
2617
- CopilotKitCoreRuntimeConnectionStatus["Disconnected"] = "disconnected";
2618
- CopilotKitCoreRuntimeConnectionStatus["Connected"] = "connected";
2619
- CopilotKitCoreRuntimeConnectionStatus["Connecting"] = "connecting";
2620
- CopilotKitCoreRuntimeConnectionStatus["Error"] = "error";
2621
- return CopilotKitCoreRuntimeConnectionStatus;
2622
- }({});
2666
+ function createTypedActionCreator(type, factory) {
2667
+ const creator = ((...args) => ({
2668
+ ...factory(...args),
2669
+ type
2670
+ }));
2671
+ creator.type = type;
2672
+ creator.match = (action) => action.type === type;
2673
+ return creator;
2674
+ }
2623
2675
  /**
2624
- * Normalize a header map to the internal invariant: a `Record<string, string>`
2625
- * with no `null`/`undefined` values. Entries whose value is `null`/`undefined`
2626
- * are dropped (this is how a header is cleared). Shared by the constructor and
2627
- * `setHeaders` so both write paths into `_headers` enforce the same invariant.
2676
+ * Declares a payload-based action config for `createActionGroup`.
2677
+ *
2678
+ * @example
2679
+ * ```ts
2680
+ * const actions = createActionGroup("User", {
2681
+ * loaded: props<{ id: string }>(),
2682
+ * });
2683
+ * ```
2628
2684
  */
2629
- function normalizeHeaders(headers) {
2630
- return Object.fromEntries(Object.entries(headers).filter((entry) => entry[1] != null));
2685
+ function props() {
2686
+ return { kind: "props" };
2631
2687
  }
2632
- var CopilotKitCore = class {
2633
- _headers;
2634
- _credentials;
2635
- _properties;
2636
- _defaultThrottleMs;
2637
- _debug;
2638
- subscribers = /* @__PURE__ */ new Set();
2639
- agentRegistry;
2640
- contextStore;
2641
- suggestionEngine;
2642
- runHandler;
2643
- stateManager;
2644
- threadStoreRegistry;
2645
- /**
2646
- * Tracks the agent IDs from the most recent `onAgentsChanged` notification.
2647
- * Used to gate thread-store auto-unregister so the FIRST empty-agents
2648
- * notification (before published agents are merged in) does not rip out a
2649
- * store that was registered prior to that initial notification.
2650
- */
2651
- previousAgentIds = /* @__PURE__ */ new Set();
2652
- constructor({ runtimeUrl, runtimeTransport = "auto", headers = {}, credentials, properties = {}, agents__unsafe_dev_only = {}, tools = [], suggestionsConfig = [], debug }) {
2653
- this._headers = normalizeHeaders(headers);
2654
- this._credentials = credentials;
2655
- this._properties = properties;
2656
- this._debug = debug;
2657
- this.agentRegistry = new AgentRegistry(this);
2658
- this.contextStore = new ContextStore(this);
2659
- this.suggestionEngine = new SuggestionEngine(this);
2660
- this.runHandler = new RunHandler(this);
2661
- this.stateManager = new StateManager(this);
2662
- this.threadStoreRegistry = new ThreadStoreRegistry(this);
2663
- this.agentRegistry.initialize(agents__unsafe_dev_only);
2664
- this.runHandler.initialize(tools);
2665
- this.suggestionEngine.initialize(suggestionsConfig);
2666
- this.stateManager.initialize();
2667
- this.agentRegistry.setRuntimeTransport(runtimeTransport);
2668
- this.agentRegistry.setRuntimeUrl(runtimeUrl);
2669
- this.previousAgentIds = new Set(Object.keys(agents__unsafe_dev_only));
2670
- this.subscribe({ onAgentsChanged: ({ agents }) => {
2671
- Object.values(agents).forEach((agent) => {
2672
- if (agent.agentId) this.stateManager.subscribeToAgent(agent);
2673
- });
2674
- const currentAgentIds = new Set(Object.keys(agents));
2675
- for (const agentId of Object.keys(this.threadStoreRegistry.getAll())) if (this.previousAgentIds.has(agentId) && !currentAgentIds.has(agentId)) try {
2676
- this.threadStoreRegistry.unregister(agentId);
2677
- } catch (err) {
2678
- console.error(`CopilotKitCore.onAgentsChanged: threadStoreRegistry.unregister failed for "${agentId}":`, err);
2679
- }
2680
- for (const agentId of this.previousAgentIds) if (!currentAgentIds.has(agentId)) try {
2681
- this.stateManager.unsubscribeFromAgent(agentId);
2682
- } catch (err) {
2683
- console.error(`CopilotKitCore.onAgentsChanged: stateManager.unsubscribeFromAgent failed for "${agentId}":`, err);
2684
- }
2685
- this.previousAgentIds = currentAgentIds;
2686
- } });
2688
+ /**
2689
+ * Declares a no-payload action config for `createActionGroup`.
2690
+ *
2691
+ * @example
2692
+ * ```ts
2693
+ * const actions = createActionGroup("User", {
2694
+ * reset: empty(),
2695
+ * });
2696
+ * ```
2697
+ */
2698
+ function empty() {
2699
+ return { kind: "empty" };
2700
+ }
2701
+ /**
2702
+ * Creates a namespaced group of typed action creators.
2703
+ *
2704
+ * Action types are formatted as: `[Source] actionName`.
2705
+ */
2706
+ function createActionGroup(source, config) {
2707
+ const group = {};
2708
+ for (const eventName of Object.keys(config)) {
2709
+ const eventConfig = config[eventName];
2710
+ if (!eventConfig) continue;
2711
+ const actionType = `[${source}] ${eventName}`;
2712
+ if (eventConfig.kind === "props") {
2713
+ group[eventName] = createTypedActionCreator(actionType, (payload) => ({ ...payload }));
2714
+ continue;
2715
+ }
2716
+ group[eventName] = createTypedActionCreator(actionType, () => ({}));
2687
2717
  }
2688
- /**
2689
- * Internal method used by delegate classes and subclasses to notify subscribers
2690
- */
2691
- async notifySubscribers(handler, errorMessage) {
2692
- await Promise.all(Array.from(this.subscribers).map(async (subscriber) => {
2693
- try {
2694
- await handler(subscriber);
2695
- } catch (error) {
2696
- console.error(errorMessage, error);
2697
- }
2698
- }));
2718
+ return group;
2719
+ }
2720
+ /**
2721
+ * Registers one reducer handler for one or more action creators.
2722
+ *
2723
+ * @throws Error when called without at least one action creator and reducer.
2724
+ */
2725
+ function on(...args) {
2726
+ if (args.length < 2) throw new Error("on requires at least one action creator and one reducer");
2727
+ const reducer = args[args.length - 1];
2728
+ return {
2729
+ creators: args.slice(0, -1),
2730
+ reducer
2731
+ };
2732
+ }
2733
+ /**
2734
+ * Creates a reducer from an initial state and `on(...)` handler entries.
2735
+ *
2736
+ * Unknown action types return the current state unchanged.
2737
+ */
2738
+ function createReducer(initialState, ...entries) {
2739
+ const reducerMap = /* @__PURE__ */ new Map();
2740
+ for (const entry of entries) for (const creator of entry.creators) {
2741
+ const handlers = reducerMap.get(creator.type) ?? [];
2742
+ handlers.push(entry.reducer);
2743
+ reducerMap.set(creator.type, handlers);
2699
2744
  }
2700
- /**
2701
- * Internal method used by delegate classes to emit errors
2702
- */
2703
- async emitError({ error, code, context = {} }) {
2704
- await this.notifySubscribers((subscriber) => subscriber.onError?.({
2705
- copilotkit: this,
2706
- error,
2707
- code,
2708
- context
2709
- }), "Subscriber onError error:");
2745
+ return (state, action) => {
2746
+ const currentState = state ?? initialState;
2747
+ const handlers = reducerMap.get(action.type);
2748
+ if (!handlers || handlers.length === 0) return currentState;
2749
+ let nextState = currentState;
2750
+ for (const handler of handlers) nextState = handler(nextState, action);
2751
+ return nextState;
2752
+ };
2753
+ }
2754
+ /**
2755
+ * Creates a selector that caches and reuses the last computed result
2756
+ * when all input references are unchanged.
2757
+ */
2758
+ function createSelector(...args) {
2759
+ if (args.length === 1) {
2760
+ const projector = args[0];
2761
+ let hasCached = false;
2762
+ let lastState;
2763
+ let lastResult;
2764
+ return (state) => {
2765
+ if (hasCached && state === lastState) return lastResult;
2766
+ lastState = state;
2767
+ lastResult = projector(state);
2768
+ hasCached = true;
2769
+ return lastResult;
2770
+ };
2710
2771
  }
2711
- /**
2712
- * Log a message to the console and emit an error to subscribers.
2713
- * Catches failures from `emitError` itself to prevent unhandled rejections.
2714
- */
2772
+ const projector = args[args.length - 1];
2773
+ const selectors = args.slice(0, -1);
2774
+ let hasCached = false;
2775
+ let lastInputs = [];
2776
+ let lastResult;
2777
+ return (state) => {
2778
+ const inputs = selectors.map((selector) => selector(state));
2779
+ if (hasCached && inputs.length === lastInputs.length && inputs.every((value, index) => value === lastInputs[index])) return lastResult;
2780
+ lastInputs = inputs;
2781
+ lastResult = projector(...inputs);
2782
+ hasCached = true;
2783
+ return lastResult;
2784
+ };
2785
+ }
2786
+ /**
2787
+ * RxJS operator that maps state emissions through a selector and suppresses
2788
+ * unchanged projected values via reference equality.
2789
+ */
2790
+ function select(selector) {
2791
+ return (source$) => source$.pipe((0, rxjs_operators.map)(selector), (0, rxjs_operators.distinctUntilChanged)());
2792
+ }
2793
+ /**
2794
+ * RxJS operator that filters an action stream by action creators and narrows
2795
+ * the output action type to the matched creator union.
2796
+ *
2797
+ * @throws Error when called without at least one action creator.
2798
+ */
2799
+ function ofType(...creators) {
2800
+ if (creators.length === 0) throw new Error("ofType requires at least one action creator");
2801
+ const actionTypes = new Set(creators.map((creator) => creator.type));
2802
+ return (source$) => {
2803
+ return source$.pipe((0, rxjs_operators.filter)((action) => {
2804
+ return actionTypes.has(action.type);
2805
+ }));
2806
+ };
2807
+ }
2808
+ /**
2809
+ * Creates an effect descriptor consumed by `createStore`.
2810
+ */
2811
+ function createEffect(factory, options = {}) {
2812
+ if (options.dispatch === false) return {
2813
+ run: factory,
2814
+ dispatch: false
2815
+ };
2816
+ return {
2817
+ run: factory,
2818
+ dispatch: true
2819
+ };
2820
+ }
2821
+ /**
2822
+ * Creates a small observable store with reducer + effects.
2823
+ *
2824
+ * Behavior:
2825
+ * - `init()` starts effects and dispatches `@@micro-redux/init`.
2826
+ * - `stop()` dispatches `@@micro-redux/stop` and unsubscribes all effects.
2827
+ * - Effect action observation is scheduled on `asapScheduler` to avoid
2828
+ * synchronous re-entrancy in the effect loop.
2829
+ * - Any effect error triggers fail-fast teardown and errors both `actions$`
2830
+ * and `state$`.
2831
+ */
2832
+ function createStore(options) {
2833
+ const reducer = options.reducer;
2834
+ const effects = options.effects ?? [];
2835
+ let hasFatalError = false;
2836
+ let isRunning = false;
2837
+ let effectSubscriptions = new rxjs.Subscription();
2838
+ let currentState = reducer(void 0, INTERNAL_BOOT_ACTION);
2839
+ const stateSubject = new rxjs.BehaviorSubject(currentState);
2840
+ const actionsSubject = new rxjs.Subject();
2841
+ const dispatchInternal = (action) => {
2842
+ if (hasFatalError) throw new Error("Store is in a failed state due to an effect error");
2843
+ currentState = reducer(currentState, action);
2844
+ stateSubject.next(currentState);
2845
+ actionsSubject.next(action);
2846
+ };
2847
+ const failFast = (error) => {
2848
+ if (hasFatalError) return;
2849
+ hasFatalError = true;
2850
+ isRunning = false;
2851
+ effectSubscriptions.unsubscribe();
2852
+ effectSubscriptions = new rxjs.Subscription();
2853
+ actionsSubject.error(error);
2854
+ stateSubject.error(error);
2855
+ };
2856
+ const startEffects = () => {
2857
+ for (const effect of effects) {
2858
+ const scheduledActions$ = actionsSubject.asObservable().pipe((0, rxjs_operators.observeOn)(rxjs.asapScheduler));
2859
+ const state$ = stateSubject.asObservable();
2860
+ if (effect.dispatch) {
2861
+ const subscription = effect.run(scheduledActions$, state$).subscribe({
2862
+ next: (effectAction) => {
2863
+ if (hasFatalError) return;
2864
+ dispatchInternal(effectAction);
2865
+ },
2866
+ error: (error) => {
2867
+ failFast(error);
2868
+ }
2869
+ });
2870
+ effectSubscriptions.add(subscription);
2871
+ continue;
2872
+ }
2873
+ const subscription = effect.run(scheduledActions$, state$).subscribe({ error: (error) => {
2874
+ failFast(error);
2875
+ } });
2876
+ effectSubscriptions.add(subscription);
2877
+ }
2878
+ };
2879
+ return {
2880
+ dispatch(action) {
2881
+ dispatchInternal(action);
2882
+ },
2883
+ getState() {
2884
+ return currentState;
2885
+ },
2886
+ get state$() {
2887
+ return stateSubject.asObservable();
2888
+ },
2889
+ get actions$() {
2890
+ return actionsSubject.asObservable();
2891
+ },
2892
+ select(selector) {
2893
+ return stateSubject.asObservable().pipe(select(selector));
2894
+ },
2895
+ init() {
2896
+ if (hasFatalError || isRunning) return;
2897
+ isRunning = true;
2898
+ startEffects();
2899
+ if (hasFatalError) return;
2900
+ dispatchInternal({ type: INTERNAL_ACTION_TYPES.init });
2901
+ },
2902
+ stop() {
2903
+ if (hasFatalError || !isRunning) return;
2904
+ dispatchInternal({ type: INTERNAL_ACTION_TYPES.stop });
2905
+ effectSubscriptions.unsubscribe();
2906
+ effectSubscriptions = new rxjs.Subscription();
2907
+ isRunning = false;
2908
+ }
2909
+ };
2910
+ }
2911
+
2912
+ //#endregion
2913
+ //#region src/memory-errors.ts
2914
+ /**
2915
+ * The memory error registry: the single source of truth for memory error
2916
+ * metadata. Keyed by `code` so a code maps to exactly one category/retryable
2917
+ * default.
2918
+ *
2919
+ * Categories/retryable rationale:
2920
+ * - List/credentials/mutation failures are `dependency` (the runtime/platform
2921
+ * the store calls failed). A 5xx is transient (`retryable: true`); a 4xx is
2922
+ * caller-caused, so the helpers below downgrade those to non-retryable.
2923
+ * - Timeouts are `dependency` and `retryable: true` (the request may simply be
2924
+ * slow).
2925
+ */
2926
+ const MEMORY_ERROR_REGISTRY = Object.freeze({
2927
+ MEMORY_LIST_FAILED: {
2928
+ code: "MEMORY_LIST_FAILED",
2929
+ category: "dependency",
2930
+ retryable: true,
2931
+ message: "Failed to fetch memories",
2932
+ docsPath: "docs/errors/memory.md#memory_list_failed"
2933
+ },
2934
+ MEMORY_CREDENTIALS_FAILED: {
2935
+ code: "MEMORY_CREDENTIALS_FAILED",
2936
+ category: "dependency",
2937
+ retryable: true,
2938
+ message: "Failed to fetch memory subscribe credentials",
2939
+ docsPath: "docs/errors/memory.md#memory_credentials_failed"
2940
+ },
2941
+ MEMORY_MUTATION_FAILED: {
2942
+ code: "MEMORY_MUTATION_FAILED",
2943
+ category: "dependency",
2944
+ retryable: true,
2945
+ message: "Memory mutation request failed",
2946
+ docsPath: "docs/errors/memory.md#memory_mutation_failed"
2947
+ },
2948
+ MEMORY_REQUEST_TIMEOUT: {
2949
+ code: "MEMORY_REQUEST_TIMEOUT",
2950
+ category: "dependency",
2951
+ retryable: true,
2952
+ message: "Request timed out",
2953
+ docsPath: "docs/errors/memory.md#memory_request_timeout"
2954
+ }
2955
+ });
2956
+ /**
2957
+ * An `Error` carrying a stable memory error `code`, `category`, and `retryable`
2958
+ * flag so consumers and observability can branch on it without string-matching
2959
+ * the message.
2960
+ *
2961
+ * It is a real `Error` subclass: `instanceof Error` is true, so the public
2962
+ * `MemoryState.error: Error | null` contract (and the `error: Error | null`
2963
+ * surfaced by `useMemories` / `injectMemories`) holds unchanged. Existing
2964
+ * consumers that only read `.message` keep working; the richer fields are
2965
+ * additive.
2966
+ */
2967
+ var MemoryError = class MemoryError extends Error {
2968
+ /** Stable, machine-readable error identifier. */
2969
+ code;
2970
+ /** Coarse error category for grouping/observability. */
2971
+ category;
2972
+ /** Whether retrying the operation could plausibly succeed. */
2973
+ retryable;
2974
+ /**
2975
+ * @param code - Registry code identifying this error.
2976
+ * @param options - Optional overrides:
2977
+ * - `message`: human-readable message (defaults to the registry message;
2978
+ * callers pass a status-bearing string to preserve prior wording).
2979
+ * - `retryable`: overrides the registry default (e.g. a 4xx list failure is
2980
+ * not retryable even though the code's default is).
2981
+ * - `cause`: the underlying error, preserved for debugging.
2982
+ */
2983
+ constructor(code, options) {
2984
+ const entry = MEMORY_ERROR_REGISTRY[code];
2985
+ super(options?.message ?? entry.message, { cause: options?.cause });
2986
+ this.name = "MemoryError";
2987
+ this.code = code;
2988
+ this.category = entry.category;
2989
+ this.retryable = options?.retryable ?? entry.retryable;
2990
+ Object.setPrototypeOf(this, MemoryError.prototype);
2991
+ }
2992
+ };
2993
+ /**
2994
+ * Narrows an HTTP status to whether the failure is worth retrying: a 5xx (or a
2995
+ * missing/0 status) is a transient dependency failure and retryable; a 4xx is
2996
+ * caller-caused and not. Used so a `MEMORY_LIST_FAILED`/`MEMORY_MUTATION_FAILED`
2997
+ * carries an accurate `retryable` flag derived from the response status.
2998
+ */
2999
+ function isRetryableStatus(status) {
3000
+ return !(Number.isInteger(status) && status >= 400 && status <= 499);
3001
+ }
3002
+
3003
+ //#endregion
3004
+ //#region src/memory.ts
3005
+ const MEMORIES_PATH = "/memories";
3006
+ const MEMORIES_SUBSCRIBE_PATH = "/memories/subscribe";
3007
+ const REQUEST_TIMEOUT_MS$1 = 15e3;
3008
+ /** Consecutive socket errors tolerated before the realtime stream gives up. */
3009
+ const MAX_SOCKET_RETRIES$1 = 5;
3010
+ /**
3011
+ * HTTP status codes that indicate memory routes are not configured (non-fatal).
3012
+ * 404/501 mean the route is absent/unimplemented; 422 is the runtime's
3013
+ * MISSING_INTELLIGENCE signal (intelligence not configured on the deployment —
3014
+ * see packages/runtime/.../handlers/intelligence/memories.ts). All three map to
3015
+ * the graceful "not available" locked-teaser path, not a hard error.
3016
+ */
3017
+ const ROUTE_UNAVAILABLE_STATUSES = new Set([
3018
+ 404,
3019
+ 422,
3020
+ 501
3021
+ ]);
3022
+ /**
3023
+ * Thrown when a memory route returns a 404/422/501 — treated as "not
3024
+ * configured" (422 is the runtime's MISSING_INTELLIGENCE signal).
3025
+ */
3026
+ var MemoryRouteUnavailableError = class extends Error {};
3027
+ const initialMemoryState = Object.freeze({
3028
+ memories: Object.freeze([]),
3029
+ isLoading: false,
3030
+ inFlightMutationCount: 0,
3031
+ error: null,
3032
+ context: null,
3033
+ sessionId: 0,
3034
+ available: true,
3035
+ realtimeStatus: "connecting"
3036
+ });
3037
+ const memoryAdapterEvents = createActionGroup("Memory Adapter", {
3038
+ started: empty(),
3039
+ stopped: empty(),
3040
+ contextChanged: props(),
3041
+ addRequested: props(),
3042
+ updateRequested: props(),
3043
+ removeRequested: props()
3044
+ });
3045
+ const memoryRestEvents = createActionGroup("Memory REST", {
3046
+ listRequested: props(),
3047
+ listSucceeded: props(),
3048
+ listFailed: props(),
3049
+ listUnavailable: props(),
3050
+ mutationFinished: props(),
3051
+ credentialsRequested: props(),
3052
+ credentialsSucceeded: props(),
3053
+ credentialsFailed: props(),
3054
+ credentialsUnavailable: props()
3055
+ });
3056
+ const memoryDomainEvents = createActionGroup("Memory Domain", {
3057
+ memoryUpserted: props(),
3058
+ memoryInvalidated: props(),
3059
+ realtimeConnecting: props(),
3060
+ realtimeConnected: props(),
3061
+ realtimeUnavailable: props()
3062
+ });
3063
+ /** Projects a wire memory to the public {@link Memory} shape (drops tenant ids). */
3064
+ function toMemory(memory) {
3065
+ return {
3066
+ id: memory.id,
3067
+ kind: memory.kind,
3068
+ scope: memory.scope,
3069
+ content: memory.content,
3070
+ sourceThreadIds: memory.sourceThreadIds,
3071
+ invalidatedAt: memory.invalidatedAt
3072
+ };
3073
+ }
3074
+ /**
3075
+ * Maps a realtime `memory_metadata` event to the domain action that applies it:
3076
+ * `created`/`updated` upsert the projected memory, `invalidated` removes it by
3077
+ * id. Carries the current `sessionId` so the reducer's session guard can drop
3078
+ * deltas left over from a previous context.
3079
+ */
3080
+ function mapMemoryMetadataEvent(event, sessionId) {
3081
+ if (event.operation === "invalidated") return memoryDomainEvents.memoryInvalidated({
3082
+ sessionId,
3083
+ memoryId: event.invalidated.id
3084
+ });
3085
+ return memoryDomainEvents.memoryUpserted({
3086
+ sessionId,
3087
+ memory: toMemory(event.memory)
3088
+ });
3089
+ }
3090
+ /**
3091
+ * Inserts or replaces a memory by id. A new memory is prepended (newest first,
3092
+ * matching the REST list's `created_at DESC` ordering without needing a date
3093
+ * field on the public projection); an existing memory is replaced in place.
3094
+ */
3095
+ function upsertMemory(memories, memory) {
3096
+ const existingIndex = memories.findIndex((item) => item.id === memory.id);
3097
+ if (existingIndex === -1) return [memory, ...memories];
3098
+ const next = [...memories];
3099
+ next[existingIndex] = memory;
3100
+ return next;
3101
+ }
3102
+ const memoryReducer = createReducer(initialMemoryState, on(memoryAdapterEvents.contextChanged, (state, { context }) => ({
3103
+ ...state,
3104
+ context,
3105
+ sessionId: state.sessionId + 1,
3106
+ memories: [],
3107
+ isLoading: Boolean(context),
3108
+ inFlightMutationCount: 0,
3109
+ error: null,
3110
+ available: true,
3111
+ realtimeStatus: "connecting"
3112
+ })), on(memoryAdapterEvents.stopped, (state) => ({
3113
+ ...state,
3114
+ memories: [],
3115
+ isLoading: false,
3116
+ inFlightMutationCount: 0,
3117
+ error: null,
3118
+ available: true,
3119
+ realtimeStatus: "connecting"
3120
+ })), on(memoryRestEvents.listRequested, (state, { sessionId }) => {
3121
+ if (sessionId !== state.sessionId || !state.context) return state;
3122
+ return {
3123
+ ...state,
3124
+ isLoading: true,
3125
+ error: null,
3126
+ available: true
3127
+ };
3128
+ }), on(memoryRestEvents.listFailed, (state, { sessionId, error }) => {
3129
+ if (sessionId !== state.sessionId) return state;
3130
+ return {
3131
+ ...state,
3132
+ isLoading: false,
3133
+ error
3134
+ };
3135
+ }), on(memoryRestEvents.listUnavailable, (state, { sessionId }) => {
3136
+ if (sessionId !== state.sessionId) return state;
3137
+ return {
3138
+ ...state,
3139
+ memories: [],
3140
+ isLoading: false,
3141
+ error: null,
3142
+ available: false
3143
+ };
3144
+ }), on(memoryAdapterEvents.addRequested, memoryAdapterEvents.updateRequested, memoryAdapterEvents.removeRequested, (state) => ({
3145
+ ...state,
3146
+ inFlightMutationCount: state.inFlightMutationCount + 1
3147
+ })), on(memoryRestEvents.mutationFinished, (state, { outcome }) => {
3148
+ if (outcome.sessionId !== state.sessionId) return state;
3149
+ return {
3150
+ ...state,
3151
+ inFlightMutationCount: Math.max(0, state.inFlightMutationCount - 1),
3152
+ error: outcome.ok ? null : outcome.error
3153
+ };
3154
+ }), on(memoryRestEvents.listSucceeded, (state, { sessionId, memories }) => {
3155
+ if (sessionId !== state.sessionId) return state;
3156
+ return {
3157
+ ...state,
3158
+ memories,
3159
+ isLoading: false,
3160
+ error: null,
3161
+ available: true
3162
+ };
3163
+ }), on(memoryDomainEvents.memoryUpserted, (state, { sessionId, memory }) => {
3164
+ if (sessionId !== state.sessionId) return state;
3165
+ return {
3166
+ ...state,
3167
+ memories: upsertMemory(state.memories, memory)
3168
+ };
3169
+ }), on(memoryDomainEvents.memoryInvalidated, (state, { sessionId, memoryId }) => {
3170
+ if (sessionId !== state.sessionId) return state;
3171
+ return {
3172
+ ...state,
3173
+ memories: state.memories.filter((memory) => memory.id !== memoryId)
3174
+ };
3175
+ }), on(memoryDomainEvents.realtimeConnecting, (state, { sessionId }) => {
3176
+ if (sessionId !== state.sessionId) return state;
3177
+ return {
3178
+ ...state,
3179
+ realtimeStatus: "connecting"
3180
+ };
3181
+ }), on(memoryDomainEvents.realtimeConnected, (state, { sessionId }) => {
3182
+ if (sessionId !== state.sessionId) return state;
3183
+ return {
3184
+ ...state,
3185
+ realtimeStatus: "connected"
3186
+ };
3187
+ }), on(memoryDomainEvents.realtimeUnavailable, (state, { sessionId }) => {
3188
+ if (sessionId !== state.sessionId) return state;
3189
+ return {
3190
+ ...state,
3191
+ realtimeStatus: "unavailable"
3192
+ };
3193
+ }));
3194
+ const selectMemories = createSelector((state) => state.memories);
3195
+ const selectMemoriesIsLoading = createSelector((state) => state.isLoading);
3196
+ const selectMemoriesError = createSelector((state) => state.error);
3197
+ /**
3198
+ * Reports whether at least one mutation is in flight. Derived from
3199
+ * `inFlightMutationCount` so concurrent mutations stay correct: the boolean
3200
+ * only clears once every in-flight mutation has settled.
3201
+ */
3202
+ const selectMemoriesIsMutating = createSelector((state) => state.inFlightMutationCount > 0);
3203
+ /**
3204
+ * Reports whether the memory routes are available. Becomes `false` after a
3205
+ * 404, 422 (the runtime's MISSING_INTELLIGENCE signal), or 501 response during
3206
+ * an auto-activation read; defaults to `true`.
3207
+ */
3208
+ const selectMemoriesAvailable = createSelector((state) => state.available);
3209
+ /**
3210
+ * Reports the realtime-connection health (see {@link MemoryRealtimeStatus}).
3211
+ * Distinct from `available`/`error`: it reflects ONLY the live socket/channel,
3212
+ * so the UI can suppress a "live" indicator once realtime permanently dies even
3213
+ * while the REST list route stays healthy. Defaults to `"connecting"`.
3214
+ */
3215
+ const selectMemoriesRealtimeStatus = createSelector((state) => state.realtimeStatus);
3216
+ const MEMORY_METADATA_EVENT = "memory_metadata";
3217
+ function memoryFromFetch(input, init) {
3218
+ return (0, rxjs_fetch.fromFetch)(input, init);
3219
+ }
3220
+ /**
3221
+ * Fetches the memory snapshot and maps it to a success/failure action. Keeps
3222
+ * only user-scoped memories (v1 surfaces user scope only; the realtime stream
3223
+ * is user-scoped too), so project-scoped rows visible to the caller are
3224
+ * dropped from the store.
3225
+ */
3226
+ function createMemoryFetchObservable(environment, context, sessionId) {
3227
+ return (0, rxjs.defer)(() => {
3228
+ const qs = context.includeInvalidated ? "?includeInvalidated=true" : "";
3229
+ return memoryFromFetch(`${context.runtimeUrl}${MEMORIES_PATH}${qs}`, {
3230
+ selector: (response) => {
3231
+ if (!response.ok) {
3232
+ if (ROUTE_UNAVAILABLE_STATUSES.has(response.status)) throw new MemoryRouteUnavailableError(String(response.status));
3233
+ throw new MemoryError("MEMORY_LIST_FAILED", {
3234
+ message: `Failed to fetch memories: ${response.status}`,
3235
+ retryable: isRetryableStatus(response.status)
3236
+ });
3237
+ }
3238
+ return response.json();
3239
+ },
3240
+ fetch: environment.fetch,
3241
+ method: "GET",
3242
+ headers: { ...context.headers }
3243
+ }).pipe((0, rxjs_operators.timeout)({
3244
+ first: REQUEST_TIMEOUT_MS$1,
3245
+ with: () => {
3246
+ throw new MemoryError("MEMORY_REQUEST_TIMEOUT");
3247
+ }
3248
+ }), (0, rxjs_operators.map)((data) => memoryRestEvents.listSucceeded({
3249
+ sessionId,
3250
+ memories: data.memories.filter((memory) => memory.scope === "user")
3251
+ })), (0, rxjs_operators.catchError)((error) => {
3252
+ if (error instanceof MemoryRouteUnavailableError) return (0, rxjs.of)(memoryRestEvents.listUnavailable({ sessionId }));
3253
+ return (0, rxjs.of)(memoryRestEvents.listFailed({
3254
+ sessionId,
3255
+ error: error instanceof Error ? error : new Error(String(error))
3256
+ }));
3257
+ }));
3258
+ });
3259
+ }
3260
+ /**
3261
+ * Fetches join credentials from the `/memories/subscribe` endpoint and maps
3262
+ * the response to a success/failure action. Requires both `joinToken` and
3263
+ * `joinCode` to be non-empty strings; throws otherwise so the `catchError`
3264
+ * path emits `credentialsFailed`.
3265
+ */
3266
+ function createMemoryCredentialsFetchObservable(environment, context, sessionId) {
3267
+ return (0, rxjs.defer)(() => memoryFromFetch(`${context.runtimeUrl}${MEMORIES_SUBSCRIBE_PATH}`, {
3268
+ selector: async (response) => {
3269
+ if (!response.ok) {
3270
+ if (ROUTE_UNAVAILABLE_STATUSES.has(response.status)) throw new MemoryRouteUnavailableError(String(response.status));
3271
+ throw new MemoryError("MEMORY_CREDENTIALS_FAILED", {
3272
+ message: `Failed to fetch memory subscribe credentials: ${response.status}`,
3273
+ retryable: isRetryableStatus(response.status)
3274
+ });
3275
+ }
3276
+ return response.json();
3277
+ },
3278
+ fetch: environment.fetch,
3279
+ method: "POST",
3280
+ headers: {
3281
+ ...context.headers,
3282
+ "Content-Type": "application/json"
3283
+ },
3284
+ body: JSON.stringify({})
3285
+ }).pipe((0, rxjs_operators.timeout)({
3286
+ first: REQUEST_TIMEOUT_MS$1,
3287
+ with: () => {
3288
+ throw new MemoryError("MEMORY_REQUEST_TIMEOUT");
3289
+ }
3290
+ }), (0, rxjs_operators.map)((data) => {
3291
+ if (typeof data.joinToken !== "string" || data.joinToken.length === 0) throw new Error("missing joinToken");
3292
+ if (typeof data.joinCode !== "string" || data.joinCode.length === 0) throw new Error("missing joinCode");
3293
+ return memoryRestEvents.credentialsSucceeded({
3294
+ sessionId,
3295
+ joinToken: data.joinToken,
3296
+ joinCode: data.joinCode
3297
+ });
3298
+ }), (0, rxjs_operators.catchError)((error) => {
3299
+ if (error instanceof MemoryRouteUnavailableError) return (0, rxjs.of)(memoryRestEvents.credentialsUnavailable({ sessionId }));
3300
+ return (0, rxjs.of)(memoryRestEvents.credentialsFailed({
3301
+ sessionId,
3302
+ error: error instanceof Error ? error : new Error(String(error))
3303
+ }));
3304
+ })));
3305
+ }
3306
+ /** Projects a REST mutation response to the public {@link Memory} shape. */
3307
+ function responseToMemory(data) {
3308
+ return {
3309
+ id: data.id,
3310
+ kind: data.kind,
3311
+ scope: data.scope,
3312
+ content: data.content,
3313
+ sourceThreadIds: data.sourceThreadIds,
3314
+ invalidatedAt: data.invalidatedAt
3315
+ };
3316
+ }
3317
+ const MEMORY_KINDS = new Set([
3318
+ "topical",
3319
+ "episodic",
3320
+ "operational"
3321
+ ]);
3322
+ const MEMORY_SCOPES = new Set(["user", "project"]);
3323
+ /**
3324
+ * Validates the required fields of a create/supersede REST response before it is
3325
+ * projected to a {@link Memory}. Returns an `Error` describing the first
3326
+ * missing/invalid field, or `null` when the body is well-formed. Without this a
3327
+ * malformed 200 body yields a Memory with undefined fields that gets upserted.
3328
+ */
3329
+ function validateMutationResponse(data) {
3330
+ if (!data || typeof data !== "object") return /* @__PURE__ */ new Error("memory mutation response missing/invalid body");
3331
+ if (typeof data.id !== "string" || data.id.length === 0) return /* @__PURE__ */ new Error("memory mutation response missing/invalid id");
3332
+ if (typeof data.kind !== "string" || !MEMORY_KINDS.has(data.kind)) return /* @__PURE__ */ new Error("memory mutation response missing/invalid kind");
3333
+ if (typeof data.scope !== "string" || !MEMORY_SCOPES.has(data.scope)) return /* @__PURE__ */ new Error("memory mutation response missing/invalid scope");
3334
+ if (typeof data.content !== "string") return /* @__PURE__ */ new Error("memory mutation response missing/invalid content");
3335
+ if (!Array.isArray(data.sourceThreadIds) || !data.sourceThreadIds.every((id) => typeof id === "string")) return /* @__PURE__ */ new Error("memory mutation response missing/invalid sourceThreadIds");
3336
+ if (data.invalidatedAt !== null && typeof data.invalidatedAt !== "string") return /* @__PURE__ */ new Error("memory mutation response missing/invalid invalidatedAt");
3337
+ return null;
3338
+ }
3339
+ /**
3340
+ * Request body for create/supersede. `scope` is forwarded only when the caller
3341
+ * supplies it: the platform owns the default (`scope` defaults to `"user"` in
3342
+ * the `/api/memories` schema), so the store does not second-guess it here —
3343
+ * one default, at the contract owner. `sourceThreadIds` defaults to `[]`.
3344
+ */
3345
+ function toMutationBody(input) {
3346
+ return {
3347
+ content: input.content,
3348
+ kind: input.kind,
3349
+ ...input.scope !== void 0 ? { scope: input.scope } : {},
3350
+ sourceThreadIds: input.sourceThreadIds ?? []
3351
+ };
3352
+ }
3353
+ /**
3354
+ * Builds the actions a successful mutation dispatches (server-authoritative):
3355
+ * the REST response is applied to local state immediately, and the realtime
3356
+ * event reconciles idempotently (upsert-by-id). `mutationFinished` resolves the
3357
+ * caller's promise.
3358
+ */
3359
+ function buildMutationSuccessActions(request, data) {
3360
+ const { requestId, sessionId } = request;
3361
+ if (request.kind === "remove") return [memoryDomainEvents.memoryInvalidated({
3362
+ sessionId,
3363
+ memoryId: request.id
3364
+ }), memoryRestEvents.mutationFinished({ outcome: {
3365
+ requestId,
3366
+ sessionId,
3367
+ ok: true,
3368
+ memory: null
3369
+ } })];
3370
+ const validationError = validateMutationResponse(data);
3371
+ if (validationError) return [memoryRestEvents.mutationFinished({ outcome: {
3372
+ requestId,
3373
+ sessionId,
3374
+ ok: false,
3375
+ error: validationError
3376
+ } })];
3377
+ const memory = responseToMemory(data);
3378
+ if (request.kind === "update") {
3379
+ const retiredId = data.retiredId;
3380
+ if (typeof retiredId !== "string" || retiredId.length === 0) return [memoryRestEvents.mutationFinished({ outcome: {
3381
+ requestId,
3382
+ sessionId,
3383
+ ok: false,
3384
+ error: /* @__PURE__ */ new Error("supersede response missing retiredId")
3385
+ } })];
3386
+ return [
3387
+ memoryDomainEvents.memoryInvalidated({
3388
+ sessionId,
3389
+ memoryId: retiredId
3390
+ }),
3391
+ memoryDomainEvents.memoryUpserted({
3392
+ sessionId,
3393
+ memory
3394
+ }),
3395
+ memoryRestEvents.mutationFinished({ outcome: {
3396
+ requestId,
3397
+ sessionId,
3398
+ ok: true,
3399
+ memory
3400
+ } })
3401
+ ];
3402
+ }
3403
+ return [memoryDomainEvents.memoryUpserted({
3404
+ sessionId,
3405
+ memory
3406
+ }), memoryRestEvents.mutationFinished({ outcome: {
3407
+ requestId,
3408
+ sessionId,
3409
+ ok: true,
3410
+ memory
3411
+ } })];
3412
+ }
3413
+ /** Performs a create/supersede/retire HTTP call and emits its resulting actions. */
3414
+ function createMemoryMutationObservable(environment, context, request) {
3415
+ const method = request.kind === "add" ? "POST" : request.kind === "update" ? "PATCH" : "DELETE";
3416
+ const path = request.kind === "add" ? MEMORIES_PATH : `${MEMORIES_PATH}/${encodeURIComponent(request.id)}`;
3417
+ return (0, rxjs.defer)(() => memoryFromFetch(`${context.runtimeUrl}${path}`, {
3418
+ selector: async (response) => {
3419
+ if (!response.ok) throw new MemoryError("MEMORY_MUTATION_FAILED", {
3420
+ message: `Request failed: ${response.status}`,
3421
+ retryable: isRetryableStatus(response.status)
3422
+ });
3423
+ return request.kind === "remove" ? null : await response.json();
3424
+ },
3425
+ fetch: environment.fetch,
3426
+ method,
3427
+ headers: {
3428
+ ...context.headers,
3429
+ "Content-Type": "application/json"
3430
+ },
3431
+ body: request.kind === "remove" ? void 0 : JSON.stringify(request.body)
3432
+ }).pipe((0, rxjs_operators.timeout)({
3433
+ first: REQUEST_TIMEOUT_MS$1,
3434
+ with: () => {
3435
+ throw new MemoryError("MEMORY_REQUEST_TIMEOUT");
3436
+ }
3437
+ }), (0, rxjs_operators.mergeMap)((data) => (0, rxjs.of)(...buildMutationSuccessActions(request, data))), (0, rxjs_operators.catchError)((error) => (0, rxjs.of)(memoryRestEvents.mutationFinished({ outcome: {
3438
+ requestId: request.requestId,
3439
+ sessionId: request.sessionId,
3440
+ ok: false,
3441
+ error: error instanceof Error ? error : new Error(String(error))
3442
+ } })))));
3443
+ }
3444
+ /**
3445
+ * Creates the framework-agnostic memory store: a REST snapshot on `setContext`,
3446
+ * server-authoritative add/update/remove mutations, and realtime
3447
+ * `memory_metadata` deltas off the injected `user_meta` event source — all
3448
+ * reduced into observable state.
3449
+ */
3450
+ function createMemoryStore(environment) {
3451
+ let memoryRequestId = 0;
3452
+ const createMemoryRequestId = () => {
3453
+ memoryRequestId += 1;
3454
+ return `memory-request-${memoryRequestId}`;
3455
+ };
3456
+ 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 }))));
3457
+ 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 }))));
3458
+ 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) => ({
3459
+ action,
3460
+ context
3461
+ })), (0, rxjs_operators.takeUntil)(actions$.pipe(ofType(memoryAdapterEvents.contextChanged, memoryAdapterEvents.stopped))), (0, rxjs_operators.switchMap)(({ action: currentAction, context }) => createMemoryCredentialsFetchObservable(environment, context, currentAction.sessionId))))));
3462
+ const store = createStore({
3463
+ reducer: memoryReducer,
3464
+ effects: [
3465
+ bootstrapEffect,
3466
+ credentialsBootstrapEffect,
3467
+ 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) => ({
3468
+ action,
3469
+ context
3470
+ })), (0, rxjs_operators.takeUntil)(actions$.pipe(ofType(memoryAdapterEvents.contextChanged, memoryAdapterEvents.stopped))), (0, rxjs_operators.switchMap)(({ action: currentAction, context }) => createMemoryFetchObservable(environment, context, currentAction.sessionId)))))),
3471
+ credentialsFetchEffect,
3472
+ createEffect((actions$, state$) => actions$.pipe(ofType(memoryAdapterEvents.addRequested, memoryAdapterEvents.updateRequested, memoryAdapterEvents.removeRequested), (0, rxjs_operators.withLatestFrom)(state$), (0, rxjs_operators.mergeMap)(([action, state]) => {
3473
+ const context = state.context;
3474
+ const sessionId = state.sessionId;
3475
+ if (!context?.runtimeUrl) return (0, rxjs.of)(memoryRestEvents.mutationFinished({ outcome: {
3476
+ requestId: action.requestId,
3477
+ sessionId,
3478
+ ok: false,
3479
+ error: /* @__PURE__ */ new Error("Runtime URL is not configured")
3480
+ } }));
3481
+ if (memoryAdapterEvents.addRequested.match(action)) return createMemoryMutationObservable(environment, context, {
3482
+ requestId: action.requestId,
3483
+ sessionId,
3484
+ kind: "add",
3485
+ body: toMutationBody(action.input)
3486
+ });
3487
+ if (memoryAdapterEvents.updateRequested.match(action)) return createMemoryMutationObservable(environment, context, {
3488
+ requestId: action.requestId,
3489
+ sessionId,
3490
+ kind: "update",
3491
+ id: action.id,
3492
+ body: toMutationBody(action.changes)
3493
+ });
3494
+ return createMemoryMutationObservable(environment, context, {
3495
+ requestId: action.requestId,
3496
+ sessionId,
3497
+ kind: "remove",
3498
+ id: action.id
3499
+ });
3500
+ }))),
3501
+ createEffect((actions$, state$) => actions$.pipe(ofType(memoryRestEvents.credentialsSucceeded), (0, rxjs_operators.withLatestFrom)(state$), (0, rxjs_operators.filter)(([action, state]) => {
3502
+ return action.sessionId === state.sessionId && Boolean(state.context?.wsUrl);
3503
+ }), (0, rxjs_operators.switchMap)(([action, state]) => {
3504
+ const context = state.context;
3505
+ const { joinToken, joinCode } = action;
3506
+ const sessionId = action.sessionId;
3507
+ const shutdown$ = actions$.pipe(ofType(memoryAdapterEvents.contextChanged, memoryAdapterEvents.stopped));
3508
+ return (0, rxjs.defer)(() => {
3509
+ const socket$ = ɵphoenixSocket$({
3510
+ url: context.wsUrl,
3511
+ options: {
3512
+ params: { join_token: joinToken },
3513
+ reconnectAfterMs: (0, _copilotkit_shared.phoenixExponentialBackoff)(100, 1e4),
3514
+ rejoinAfterMs: (0, _copilotkit_shared.phoenixExponentialBackoff)(1e3, 3e4)
3515
+ }
3516
+ }).pipe((0, rxjs_operators.shareReplay)({
3517
+ bufferSize: 1,
3518
+ refCount: true
3519
+ }));
3520
+ const channel$ = ɵphoenixChannel$({
3521
+ socket$,
3522
+ topic: `user_meta:memories:${joinCode}`
3523
+ }).pipe((0, rxjs_operators.shareReplay)({
3524
+ bufferSize: 1,
3525
+ refCount: true
3526
+ }));
3527
+ const fatalSocketShutdown$ = ɵobservePhoenixSocketHealth$(ɵobservePhoenixSocketSignals$(socket$).pipe((0, rxjs_operators.share)()), MAX_SOCKET_RETRIES$1).pipe((0, rxjs_operators.catchError)(() => {
3528
+ console.warn(`[memory] WebSocket failed after ${MAX_SOCKET_RETRIES$1} attempts, giving up`);
3529
+ return (0, rxjs.of)(void 0);
3530
+ }), (0, rxjs_operators.share)());
3531
+ const fatalStatus$ = fatalSocketShutdown$.pipe((0, rxjs_operators.map)(() => memoryDomainEvents.realtimeUnavailable({ sessionId })));
3532
+ const metadata$ = channel$.pipe((0, rxjs_operators.switchMap)(({ channel }) => ɵobservePhoenixEvent$(channel, MEMORY_METADATA_EVENT)), (0, rxjs_operators.map)((event) => mapMemoryMetadataEvent(event, action.sessionId)));
3533
+ const join$ = ɵjoinPhoenixChannel$(channel$).pipe((0, rxjs_operators.concatWith)((0, rxjs.of)(memoryDomainEvents.realtimeConnected({ sessionId }))), (0, rxjs_operators.catchError)((error) => {
3534
+ console.warn(`[memory] failed to join user_meta:memories:${joinCode}`, error);
3535
+ return (0, rxjs.of)(memoryDomainEvents.realtimeUnavailable({ sessionId }));
3536
+ }));
3537
+ 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)(() => {}));
3538
+ });
3539
+ })))
3540
+ ]
3541
+ });
3542
+ function trackMutation(dispatchAction, extract) {
3543
+ const { requestId } = dispatchAction;
3544
+ 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)(() => ({
3545
+ requestId,
3546
+ sessionId: store.getState().sessionId,
3547
+ ok: false,
3548
+ error: /* @__PURE__ */ new Error("Memory store stopped before mutation completed")
3549
+ })))).pipe((0, rxjs_operators.take)(1))).then((outcome) => {
3550
+ if (!outcome.ok) throw outcome.error;
3551
+ return extract(outcome);
3552
+ });
3553
+ store.dispatch(dispatchAction);
3554
+ return resultPromise;
3555
+ }
3556
+ return {
3557
+ start() {
3558
+ store.init();
3559
+ store.dispatch(memoryAdapterEvents.started());
3560
+ },
3561
+ stop() {
3562
+ store.dispatch(memoryAdapterEvents.stopped());
3563
+ store.stop();
3564
+ },
3565
+ setContext(context) {
3566
+ store.dispatch(memoryAdapterEvents.contextChanged({ context }));
3567
+ },
3568
+ refresh() {
3569
+ const { sessionId, context } = store.getState();
3570
+ if (!context) return Promise.resolve();
3571
+ 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) => {
3572
+ if (memoryRestEvents.listFailed.match(action)) throw action.error;
3573
+ if (memoryAdapterEvents.stopped.match(action)) throw new Error("Memory store stopped before refresh completed");
3574
+ if (memoryAdapterEvents.contextChanged.match(action)) return;
3575
+ });
3576
+ store.dispatch(memoryRestEvents.listRequested({ sessionId }));
3577
+ return done;
3578
+ },
3579
+ addMemory(input) {
3580
+ return trackMutation(memoryAdapterEvents.addRequested({
3581
+ requestId: createMemoryRequestId(),
3582
+ input
3583
+ }), (outcome) => {
3584
+ if (outcome.memory == null) throw new Error("add resolved without a memory");
3585
+ return outcome.memory;
3586
+ });
3587
+ },
3588
+ updateMemory(id, changes) {
3589
+ return trackMutation(memoryAdapterEvents.updateRequested({
3590
+ requestId: createMemoryRequestId(),
3591
+ id,
3592
+ changes
3593
+ }), (outcome) => {
3594
+ if (outcome.memory == null) throw new Error("update resolved without a memory");
3595
+ return outcome.memory;
3596
+ });
3597
+ },
3598
+ removeMemory(id) {
3599
+ return trackMutation(memoryAdapterEvents.removeRequested({
3600
+ requestId: createMemoryRequestId(),
3601
+ id
3602
+ }), () => void 0);
3603
+ },
3604
+ getState() {
3605
+ return store.getState();
3606
+ },
3607
+ getServerState() {
3608
+ return initialMemoryState;
3609
+ },
3610
+ select: store.select.bind(store)
3611
+ };
3612
+ }
3613
+ const ɵmemoryAdapterEvents = memoryAdapterEvents;
3614
+ const ɵmemoryRestEvents = memoryRestEvents;
3615
+ const ɵmemoryDomainEvents = memoryDomainEvents;
3616
+ const ɵmemoryReducer = memoryReducer;
3617
+ const ɵmapMemoryMetadataEvent = mapMemoryMetadataEvent;
3618
+ const ɵselectMemories = selectMemories;
3619
+ const ɵselectMemoriesIsLoading = selectMemoriesIsLoading;
3620
+ const ɵselectMemoriesError = selectMemoriesError;
3621
+ const ɵselectMemoriesIsMutating = selectMemoriesIsMutating;
3622
+ const ɵselectMemoriesAvailable = selectMemoriesAvailable;
3623
+ const ɵselectMemoriesRealtimeStatus = selectMemoriesRealtimeStatus;
3624
+
3625
+ //#endregion
3626
+ //#region src/core/core.ts
3627
+ let CopilotKitCoreErrorCode = /* @__PURE__ */ function(CopilotKitCoreErrorCode) {
3628
+ CopilotKitCoreErrorCode["RUNTIME_INFO_FETCH_FAILED"] = "runtime_info_fetch_failed";
3629
+ CopilotKitCoreErrorCode["AGENT_CONNECT_FAILED"] = "agent_connect_failed";
3630
+ CopilotKitCoreErrorCode["AGENT_RUN_FAILED"] = "agent_run_failed";
3631
+ CopilotKitCoreErrorCode["AGENT_RUN_FAILED_EVENT"] = "agent_run_failed_event";
3632
+ CopilotKitCoreErrorCode["AGENT_RUN_ERROR_EVENT"] = "agent_run_error_event";
3633
+ CopilotKitCoreErrorCode["TOOL_ARGUMENT_PARSE_FAILED"] = "tool_argument_parse_failed";
3634
+ CopilotKitCoreErrorCode["TOOL_HANDLER_FAILED"] = "tool_handler_failed";
3635
+ CopilotKitCoreErrorCode["TOOL_NOT_FOUND"] = "tool_not_found";
3636
+ CopilotKitCoreErrorCode["AGENT_NOT_FOUND"] = "agent_not_found";
3637
+ /**
3638
+ * Emitted when an agent run fails because the thread is already locked
3639
+ * by another active run.
3640
+ *
3641
+ * @example
3642
+ * ```tsx
3643
+ * <CopilotKitProvider
3644
+ * onError={({ code, error, context }) => {
3645
+ * if (code === "agent_thread_locked") {
3646
+ * // Show "Agent is busy, retry?" UI
3647
+ * }
3648
+ * }}
3649
+ * />
3650
+ * ```
3651
+ */
3652
+ CopilotKitCoreErrorCode["AGENT_THREAD_LOCKED"] = "agent_thread_locked";
3653
+ CopilotKitCoreErrorCode["TRANSCRIPTION_FAILED"] = "transcription_failed";
3654
+ CopilotKitCoreErrorCode["TRANSCRIPTION_SERVICE_NOT_CONFIGURED"] = "transcription_service_not_configured";
3655
+ CopilotKitCoreErrorCode["TRANSCRIPTION_INVALID_AUDIO"] = "transcription_invalid_audio";
3656
+ CopilotKitCoreErrorCode["TRANSCRIPTION_RATE_LIMITED"] = "transcription_rate_limited";
3657
+ CopilotKitCoreErrorCode["TRANSCRIPTION_AUTH_FAILED"] = "transcription_auth_failed";
3658
+ CopilotKitCoreErrorCode["TRANSCRIPTION_NETWORK_ERROR"] = "transcription_network_error";
3659
+ CopilotKitCoreErrorCode["SUBSCRIBER_CALLBACK_FAILED"] = "subscriber_callback_failed";
3660
+ return CopilotKitCoreErrorCode;
3661
+ }({});
3662
+ /**
3663
+ * Runtime allowlist derived from {@link SUBSCRIBE_TO_AGENT_KEYS}. Hoisted
3664
+ * to module scope so the Set is allocated once, not per-subscription.
3665
+ */
3666
+ const ALLOWED_KEYS = new Set([
3667
+ "onMessagesChanged",
3668
+ "onStateChanged",
3669
+ "onRunInitialized",
3670
+ "onRunFinalized",
3671
+ "onRunFailed",
3672
+ "onRunErrorEvent"
3673
+ ]);
3674
+ let CopilotKitCoreRuntimeConnectionStatus = /* @__PURE__ */ function(CopilotKitCoreRuntimeConnectionStatus) {
3675
+ CopilotKitCoreRuntimeConnectionStatus["Disconnected"] = "disconnected";
3676
+ CopilotKitCoreRuntimeConnectionStatus["Connected"] = "connected";
3677
+ CopilotKitCoreRuntimeConnectionStatus["Connecting"] = "connecting";
3678
+ CopilotKitCoreRuntimeConnectionStatus["Error"] = "error";
3679
+ return CopilotKitCoreRuntimeConnectionStatus;
3680
+ }({});
3681
+ /**
3682
+ * Normalize a header map to the internal invariant: a `Record<string, string>`
3683
+ * with no `null`/`undefined` values. Entries whose value is `null`/`undefined`
3684
+ * are dropped (this is how a header is cleared). Shared by the constructor and
3685
+ * `setHeaders` so both write paths into `_headers` enforce the same invariant.
3686
+ */
3687
+ function normalizeHeaders(headers) {
3688
+ return Object.fromEntries(Object.entries(headers).filter((entry) => entry[1] != null));
3689
+ }
3690
+ var CopilotKitCore = class {
3691
+ _headers;
3692
+ _credentials;
3693
+ _properties;
3694
+ _defaultThrottleMs;
3695
+ _debug;
3696
+ subscribers = /* @__PURE__ */ new Set();
3697
+ agentRegistry;
3698
+ contextStore;
3699
+ suggestionEngine;
3700
+ runHandler;
3701
+ stateManager;
3702
+ threadStoreRegistry;
3703
+ /**
3704
+ * The single core-owned memory store, created lazily on first
3705
+ * `getMemoryStore()` and kept user-scoped for the lifetime of the core.
3706
+ * Its runtime context is wired by the core itself (see `syncMemoryContext`),
3707
+ * so callers never register or look it up by `agentId`.
3708
+ */
3709
+ _memoryStore;
3710
+ /**
3711
+ * Tracks the agent IDs from the most recent `onAgentsChanged` notification.
3712
+ * Used to gate thread-store auto-unregister so the FIRST empty-agents
3713
+ * notification (before published agents are merged in) does not rip out a
3714
+ * store that was registered prior to that initial notification.
3715
+ */
3716
+ previousAgentIds = /* @__PURE__ */ new Set();
3717
+ constructor({ runtimeUrl, runtimeTransport = "auto", deferInitialConnection = false, headers = {}, credentials, properties = {}, agents__unsafe_dev_only = {}, tools = [], suggestionsConfig = [], debug }) {
3718
+ this._headers = normalizeHeaders(headers);
3719
+ this._credentials = credentials;
3720
+ this._properties = properties;
3721
+ this._debug = debug;
3722
+ this.agentRegistry = new AgentRegistry(this);
3723
+ this.contextStore = new ContextStore(this);
3724
+ this.suggestionEngine = new SuggestionEngine(this);
3725
+ this.runHandler = new RunHandler(this);
3726
+ this.stateManager = new StateManager(this);
3727
+ this.threadStoreRegistry = new ThreadStoreRegistry(this);
3728
+ this.agentRegistry.initialize(agents__unsafe_dev_only);
3729
+ this.runHandler.initialize(tools);
3730
+ this.suggestionEngine.initialize(suggestionsConfig);
3731
+ this.stateManager.initialize();
3732
+ this.agentRegistry.setRuntimeTransport(runtimeTransport);
3733
+ this.agentRegistry.setRuntimeUrl(runtimeUrl, { deferConnection: deferInitialConnection });
3734
+ this.previousAgentIds = new Set(Object.keys(agents__unsafe_dev_only));
3735
+ this.subscribe({
3736
+ onRuntimeConnectionStatusChanged: () => {
3737
+ if (this._memoryStore) this.syncMemoryContext();
3738
+ },
3739
+ onAgentsChanged: ({ agents }) => {
3740
+ Object.values(agents).forEach((agent) => {
3741
+ if (agent.agentId) this.stateManager.subscribeToAgent(agent);
3742
+ });
3743
+ const currentAgentIds = new Set(Object.keys(agents));
3744
+ for (const agentId of Object.keys(this.threadStoreRegistry.getAll())) if (this.previousAgentIds.has(agentId) && !currentAgentIds.has(agentId)) try {
3745
+ this.threadStoreRegistry.unregister(agentId);
3746
+ } catch (err) {
3747
+ console.error(`CopilotKitCore.onAgentsChanged: threadStoreRegistry.unregister failed for "${agentId}":`, err);
3748
+ }
3749
+ for (const agentId of this.previousAgentIds) if (!currentAgentIds.has(agentId)) try {
3750
+ this.stateManager.unsubscribeFromAgent(agentId);
3751
+ } catch (err) {
3752
+ console.error(`CopilotKitCore.onAgentsChanged: stateManager.unsubscribeFromAgent failed for "${agentId}":`, err);
3753
+ }
3754
+ this.previousAgentIds = currentAgentIds;
3755
+ }
3756
+ });
3757
+ }
3758
+ /**
3759
+ * Internal method used by delegate classes and subclasses to notify subscribers
3760
+ */
3761
+ async notifySubscribers(handler, errorMessage) {
3762
+ await Promise.all(Array.from(this.subscribers).map(async (subscriber) => {
3763
+ try {
3764
+ await handler(subscriber);
3765
+ } catch (error) {
3766
+ console.error(errorMessage, error);
3767
+ }
3768
+ }));
3769
+ }
3770
+ /**
3771
+ * Internal method used by delegate classes to emit errors
3772
+ */
3773
+ async emitError({ error, code, context = {} }) {
3774
+ await this.notifySubscribers((subscriber) => subscriber.onError?.({
3775
+ copilotkit: this,
3776
+ error,
3777
+ code,
3778
+ context
3779
+ }), "Subscriber onError error:");
3780
+ }
3781
+ /**
3782
+ * Log a message to the console and emit an error to subscribers.
3783
+ * Catches failures from `emitError` itself to prevent unhandled rejections.
3784
+ */
2715
3785
  logAndEmitError(message, params, logLevel = "error") {
2716
3786
  console[logLevel](message, params.error);
2717
3787
  this.emitError(params).catch((emitErr) => {
@@ -2736,6 +3806,18 @@ var CopilotKitCore = class {
2736
3806
  setRuntimeUrl(runtimeUrl) {
2737
3807
  this.agentRegistry.setRuntimeUrl(runtimeUrl);
2738
3808
  }
3809
+ /**
3810
+ * Start the runtime `/info` connection if it has not been started yet.
3811
+ *
3812
+ * Intended to be driven from a host's commit-phase effect when the core was
3813
+ * constructed with {@link CopilotKitCoreConfig.deferInitialConnection}. Safe
3814
+ * to call repeatedly — it is a no-op once a connection is in progress or
3815
+ * settled, so a double-invoked mount effect (React StrictMode) collapses to a
3816
+ * single request. See #5801.
3817
+ */
3818
+ connect() {
3819
+ this.agentRegistry.connectRuntime();
3820
+ }
2739
3821
  get runtimeTransport() {
2740
3822
  return this.agentRegistry.runtimeTransport;
2741
3823
  }
@@ -2804,6 +3886,9 @@ var CopilotKitCore = class {
2804
3886
  get threadEndpoints() {
2805
3887
  return this.agentRegistry.threadEndpoints;
2806
3888
  }
3889
+ get suggestions() {
3890
+ return this.agentRegistry.suggestions;
3891
+ }
2807
3892
  get a2uiEnabled() {
2808
3893
  return this.agentRegistry.a2uiEnabled;
2809
3894
  }
@@ -2857,6 +3942,7 @@ var CopilotKitCore = class {
2857
3942
  */
2858
3943
  setHeaders(headers) {
2859
3944
  this._headers = normalizeHeaders(headers);
3945
+ if (this._memoryStore) this.syncMemoryContext();
2860
3946
  this.agentRegistry.applyHeadersToAgents(this.agentRegistry.agents);
2861
3947
  this.notifySubscribers((subscriber) => subscriber.onHeadersChanged?.({
2862
3948
  copilotkit: this,
@@ -2962,6 +4048,46 @@ var CopilotKitCore = class {
2962
4048
  return this.threadStoreRegistry.getAll();
2963
4049
  }
2964
4050
  /**
4051
+ * Returns the single core-owned, user-scoped memory store, creating and
4052
+ * starting it on first access. Unlike thread stores, memory is not scoped per
4053
+ * agent: there is exactly one store whose runtime context the core wires
4054
+ * itself (see `syncMemoryContext`), so consumers (e.g. a `useMemories`
4055
+ * binding) just read this store rather than registering one.
4056
+ */
4057
+ getMemoryStore() {
4058
+ return this.ensureMemoryStore();
4059
+ }
4060
+ /**
4061
+ * Lazily creates, starts, and context-syncs the core-owned memory store on
4062
+ * first access, then returns it. Subsequent calls return the existing store.
4063
+ * The store is constructed with a bound `globalThis.fetch` and immediately
4064
+ * has its runtime context synced from the current connection state.
4065
+ */
4066
+ ensureMemoryStore() {
4067
+ if (!this._memoryStore) {
4068
+ this._memoryStore = createMemoryStore({ fetch: globalThis.fetch.bind(globalThis) });
4069
+ this._memoryStore.start();
4070
+ this.syncMemoryContext();
4071
+ }
4072
+ return this._memoryStore;
4073
+ }
4074
+ /**
4075
+ * Pushes the current runtime wiring into the memory store. When the runtime
4076
+ * is connected and both the intelligence WebSocket URL and runtime URL are
4077
+ * available, the store receives a context (runtime URL, WebSocket URL, and a
4078
+ * copy of the current headers); otherwise its context is cleared. No-op when
4079
+ * the store has not been created yet.
4080
+ */
4081
+ syncMemoryContext() {
4082
+ if (!this._memoryStore) return;
4083
+ if (this.runtimeConnectionStatus === CopilotKitCoreRuntimeConnectionStatus.Connected && this.intelligence?.wsUrl && this.runtimeUrl) this._memoryStore.setContext({
4084
+ runtimeUrl: this.runtimeUrl,
4085
+ wsUrl: this.intelligence.wsUrl,
4086
+ headers: { ...this.headers }
4087
+ });
4088
+ else this._memoryStore.setContext(null);
4089
+ }
4090
+ /**
2965
4091
  * Suggestions management (delegated to SuggestionEngine)
2966
4092
  */
2967
4093
  addSuggestionsConfig(config) {
@@ -3125,509 +4251,252 @@ var CopilotKitCore = class {
3125
4251
  };
3126
4252
  if (subscriber.onStateChanged) wrappedSubscriber.onStateChanged = (params) => {
3127
4253
  latestStateParams = params;
3128
- throttler.maybeExecute();
3129
- };
3130
- const subscription = agent.subscribe(wrappedSubscriber);
3131
- return { unsubscribe: () => {
3132
- active = false;
3133
- throttler.cancel();
3134
- subscription.unsubscribe();
3135
- } };
3136
- }
3137
- /**
3138
- * Agent connectivity (delegated to RunHandler)
3139
- */
3140
- async connectAgent(params) {
3141
- return this.runHandler.connectAgent(params);
3142
- }
3143
- stopAgent(params) {
3144
- this.runHandler.abortCurrentRun();
3145
- params.agent.abortRun();
3146
- }
3147
- async runAgent(params) {
3148
- return this.runHandler.runAgent(params);
3149
- }
3150
- /**
3151
- * Programmatically execute a registered frontend tool without going through an LLM turn.
3152
- * The handler runs, render components show up in the UI, and both the tool call and
3153
- * result messages are added to `agent.messages`.
3154
- */
3155
- async runTool(params) {
3156
- return this.runHandler.runTool(params);
3157
- }
3158
- /**
3159
- * State management (delegated to StateManager)
3160
- */
3161
- getStateByRun(agentId, threadId, runId) {
3162
- return this.stateManager.getStateByRun(agentId, threadId, runId);
3163
- }
3164
- getRunIdForMessage(agentId, threadId, messageId) {
3165
- return this.stateManager.getRunIdForMessage(agentId, threadId, messageId);
3166
- }
3167
- getRunIdsForThread(agentId, threadId) {
3168
- return this.stateManager.getRunIdsForThread(agentId, threadId);
3169
- }
3170
- /**
3171
- * Internal method used by RunHandler to build frontend tools
3172
- */
3173
- buildFrontendTools(agentId) {
3174
- return this.runHandler.buildFrontendTools(agentId);
3175
- }
3176
- /**
3177
- * Called before each follow-up agent run (after tool execution).
3178
- *
3179
- * When a frontend tool handler calls framework state setters (e.g. React's
3180
- * setState), those updates are batched and deferred — they do not take effect
3181
- * until the framework's scheduler runs (React uses MessageChannel).
3182
- * useAgentContext registers context via useLayoutEffect, which runs
3183
- * synchronously after React commits that deferred batch.
3184
- *
3185
- * Without yielding here, the follow-up runAgent reads the context store
3186
- * synchronously while the deferred updates are still pending, producing stale
3187
- * context for the next agent turn.
3188
- *
3189
- * Override in framework-specific subclasses to yield to the framework
3190
- * scheduler before the follow-up run. The base implementation is a no-op
3191
- * because non-React environments have no deferred state to flush.
3192
- */
3193
- async waitForPendingFrameworkUpdates() {}
3194
- };
3195
-
3196
- //#endregion
3197
- //#region src/types.ts
3198
- /**
3199
- * Status of a tool call execution
3200
- */
3201
- let ToolCallStatus = /* @__PURE__ */ function(ToolCallStatus) {
3202
- ToolCallStatus["InProgress"] = "inProgress";
3203
- ToolCallStatus["Executing"] = "executing";
3204
- ToolCallStatus["Complete"] = "complete";
3205
- return ToolCallStatus;
3206
- }({});
3207
-
3208
- //#endregion
3209
- //#region src/utils/markdown.ts
3210
- function completePartialMarkdown(input) {
3211
- let s = input;
3212
- const fenceMatches = Array.from(s.matchAll(/^(\s*)(`{3,}|~{3,})/gm));
3213
- if (fenceMatches.length % 2 === 1) {
3214
- const [, indent, fence] = fenceMatches[0];
3215
- s += `\n${indent}${fence}`;
3216
- }
3217
- if (s.match(/\[([^\]]*)\]\(([^)]*)$/)) s += ")";
3218
- const openElements = [];
3219
- const chars = Array.from(s);
3220
- const codeBlockRanges = [];
3221
- const inlineCodeRanges = [];
3222
- let tempCodeFenceCount = 0;
3223
- let currentCodeBlockStart = -1;
3224
- for (let i = 0; i < chars.length; i++) if (i === 0 || chars[i - 1] === "\n") {
3225
- const lineMatch = s.substring(i).match(/^(\s*)(`{3,}|~{3,})/);
3226
- if (lineMatch) {
3227
- tempCodeFenceCount++;
3228
- if (tempCodeFenceCount % 2 === 1) currentCodeBlockStart = i;
3229
- else if (currentCodeBlockStart !== -1) {
3230
- codeBlockRanges.push({
3231
- start: currentCodeBlockStart,
3232
- end: i + lineMatch[0].length
3233
- });
3234
- currentCodeBlockStart = -1;
3235
- }
3236
- i += lineMatch[0].length - 1;
3237
- }
3238
- }
3239
- for (let i = 0; i < chars.length; i++) if (chars[i] === "`") {
3240
- let backslashCount = 0;
3241
- for (let j = i - 1; j >= 0 && chars[j] === "\\"; j--) backslashCount++;
3242
- if (backslashCount % 2 === 0) {
3243
- for (let j = i + 1; j < chars.length; j++) if (chars[j] === "`") {
3244
- let closingBackslashCount = 0;
3245
- for (let k = j - 1; k >= 0 && chars[k] === "\\"; k--) closingBackslashCount++;
3246
- if (closingBackslashCount % 2 === 0) {
3247
- inlineCodeRanges.push({
3248
- start: i,
3249
- end: j + 1
3250
- });
3251
- i = j;
3252
- break;
3253
- }
3254
- }
3255
- }
3256
- }
3257
- const isInCode = (pos) => {
3258
- return codeBlockRanges.some((range) => pos >= range.start && pos < range.end) || inlineCodeRanges.some((range) => pos >= range.start && pos < range.end);
3259
- };
3260
- for (let i = 0; i < chars.length; i++) {
3261
- const char = chars[i];
3262
- const nextChar = chars[i + 1];
3263
- const prevChar = chars[i - 1];
3264
- if (isInCode(i)) continue;
3265
- if (char === "[") {
3266
- let isCompleteLink = false;
3267
- let bracketDepth = 1;
3268
- let j = i + 1;
3269
- while (j < chars.length && bracketDepth > 0) {
3270
- if (chars[j] === "[" && !isInCode(j)) bracketDepth++;
3271
- if (chars[j] === "]" && !isInCode(j)) bracketDepth--;
3272
- j++;
3273
- }
3274
- if (bracketDepth === 0 && chars[j] === "(") {
3275
- let parenDepth = 1;
3276
- j++;
3277
- while (j < chars.length && parenDepth > 0) {
3278
- if (chars[j] === "(" && !isInCode(j)) parenDepth++;
3279
- if (chars[j] === ")" && !isInCode(j)) parenDepth--;
3280
- j++;
3281
- }
3282
- if (parenDepth === 0) {
3283
- isCompleteLink = true;
3284
- i = j - 1;
3285
- continue;
3286
- }
3287
- }
3288
- if (!isCompleteLink) {
3289
- const existingIndex = openElements.findIndex((el) => el.type === "bracket");
3290
- if (existingIndex !== -1) openElements.splice(existingIndex, 1);
3291
- else openElements.push({
3292
- type: "bracket",
3293
- marker: "[",
3294
- position: i
3295
- });
3296
- }
3297
- } else if (char === "*" && nextChar === "*") {
3298
- const existingIndex = openElements.findIndex((el) => el.type === "bold_star");
3299
- if (existingIndex !== -1) openElements.splice(existingIndex, 1);
3300
- else openElements.push({
3301
- type: "bold_star",
3302
- marker: "**",
3303
- position: i
3304
- });
3305
- i++;
3306
- } else if (char === "_" && nextChar === "_") {
3307
- const existingIndex = openElements.findIndex((el) => el.type === "bold_underscore");
3308
- if (existingIndex !== -1) openElements.splice(existingIndex, 1);
3309
- else openElements.push({
3310
- type: "bold_underscore",
3311
- marker: "__",
3312
- position: i
3313
- });
3314
- i++;
3315
- } else if (char === "~" && nextChar === "~") {
3316
- const existingIndex = openElements.findIndex((el) => el.type === "strike");
3317
- if (existingIndex !== -1) openElements.splice(existingIndex, 1);
3318
- else openElements.push({
3319
- type: "strike",
3320
- marker: "~~",
3321
- position: i
3322
- });
3323
- i++;
3324
- } else if (char === "*" && prevChar !== "*" && nextChar !== "*") {
3325
- const existingIndex = openElements.findIndex((el) => el.type === "italic_star");
3326
- if (existingIndex !== -1) openElements.splice(existingIndex, 1);
3327
- else openElements.push({
3328
- type: "italic_star",
3329
- marker: "*",
3330
- position: i
3331
- });
3332
- } else if (char === "_" && prevChar !== "_" && nextChar !== "_") {
3333
- const existingIndex = openElements.findIndex((el) => el.type === "italic_underscore");
3334
- if (existingIndex !== -1) openElements.splice(existingIndex, 1);
3335
- else openElements.push({
3336
- type: "italic_underscore",
3337
- marker: "_",
3338
- position: i
3339
- });
3340
- }
4254
+ throttler.maybeExecute();
4255
+ };
4256
+ const subscription = agent.subscribe(wrappedSubscriber);
4257
+ return { unsubscribe: () => {
4258
+ active = false;
4259
+ throttler.cancel();
4260
+ subscription.unsubscribe();
4261
+ } };
3341
4262
  }
3342
- let backtickCount = 0;
3343
- for (let i = 0; i < chars.length; i++) if (chars[i] === "`" && !isInCode(i)) backtickCount++;
3344
- if (backtickCount % 2 === 1) s += "`";
3345
- openElements.sort((a, b) => b.position - a.position);
3346
- const closers = openElements.map((el) => {
3347
- switch (el.type) {
3348
- case "bracket": return "]";
3349
- case "bold_star": return "**";
3350
- case "bold_underscore": return "__";
3351
- case "strike": return "~~";
3352
- case "italic_star": return "*";
3353
- case "italic_underscore": return "_";
3354
- default: return "";
3355
- }
3356
- });
3357
- let result = s + closers.join("");
3358
- const finalFenceMatches = Array.from(result.matchAll(/^(\s*)(`{3,}|~{3,})/gm));
3359
- const hasUnclosedBacktick = (result.match(/`/g) || []).length % 2 === 1;
3360
- const hasUnclosedCodeFence = finalFenceMatches.length % 2 === 1;
3361
- let shouldCloseParens = !hasUnclosedBacktick && !hasUnclosedCodeFence;
3362
- if (shouldCloseParens) {
3363
- const lastOpenParen = result.lastIndexOf("(");
3364
- if (lastOpenParen !== -1) {
3365
- if ((result.substring(0, lastOpenParen).match(/`/g) || []).length % 2 === 1) shouldCloseParens = false;
3366
- }
4263
+ /**
4264
+ * Agent connectivity (delegated to RunHandler)
4265
+ */
4266
+ async connectAgent(params) {
4267
+ return this.runHandler.connectAgent(params);
3367
4268
  }
3368
- if (shouldCloseParens) {
3369
- const openParens = (result.match(/\(/g) || []).length;
3370
- const closeParens = (result.match(/\)/g) || []).length;
3371
- if (openParens > closeParens) result += ")".repeat(openParens - closeParens);
4269
+ stopAgent(params) {
4270
+ this.runHandler.abortCurrentRun();
4271
+ params.agent.abortRun();
3372
4272
  }
3373
- return result;
3374
- }
3375
-
3376
- //#endregion
3377
- //#region src/utils/micro-redux.ts
3378
- const INTERNAL_ACTION_TYPES = {
3379
- boot: "@@micro-redux/boot",
3380
- init: "@@micro-redux/init",
3381
- stop: "@@micro-redux/stop"
3382
- };
3383
- const INTERNAL_BOOT_ACTION = { type: INTERNAL_ACTION_TYPES.boot };
3384
- /**
3385
- * Builds a typed action creator from a type string and payload factory.
3386
- */
3387
- function createTypedActionCreator(type, factory) {
3388
- const creator = ((...args) => ({
3389
- ...factory(...args),
3390
- type
3391
- }));
3392
- creator.type = type;
3393
- creator.match = (action) => action.type === type;
3394
- return creator;
3395
- }
3396
- /**
3397
- * Declares a payload-based action config for `createActionGroup`.
3398
- *
3399
- * @example
3400
- * ```ts
3401
- * const actions = createActionGroup("User", {
3402
- * loaded: props<{ id: string }>(),
3403
- * });
3404
- * ```
3405
- */
3406
- function props() {
3407
- return { kind: "props" };
3408
- }
3409
- /**
3410
- * Declares a no-payload action config for `createActionGroup`.
3411
- *
3412
- * @example
3413
- * ```ts
3414
- * const actions = createActionGroup("User", {
3415
- * reset: empty(),
3416
- * });
3417
- * ```
3418
- */
3419
- function empty() {
3420
- return { kind: "empty" };
3421
- }
3422
- /**
3423
- * Creates a namespaced group of typed action creators.
3424
- *
3425
- * Action types are formatted as: `[Source] actionName`.
3426
- */
3427
- function createActionGroup(source, config) {
3428
- const group = {};
3429
- for (const eventName of Object.keys(config)) {
3430
- const eventConfig = config[eventName];
3431
- if (!eventConfig) continue;
3432
- const actionType = `[${source}] ${eventName}`;
3433
- if (eventConfig.kind === "props") {
3434
- group[eventName] = createTypedActionCreator(actionType, (payload) => ({ ...payload }));
3435
- continue;
3436
- }
3437
- group[eventName] = createTypedActionCreator(actionType, () => ({}));
4273
+ async runAgent(params) {
4274
+ return this.runHandler.runAgent(params);
3438
4275
  }
3439
- return group;
3440
- }
3441
- /**
3442
- * Registers one reducer handler for one or more action creators.
3443
- *
3444
- * @throws Error when called without at least one action creator and reducer.
3445
- */
3446
- function on(...args) {
3447
- if (args.length < 2) throw new Error("on requires at least one action creator and one reducer");
3448
- const reducer = args[args.length - 1];
3449
- return {
3450
- creators: args.slice(0, -1),
3451
- reducer
3452
- };
3453
- }
3454
- /**
3455
- * Creates a reducer from an initial state and `on(...)` handler entries.
3456
- *
3457
- * Unknown action types return the current state unchanged.
3458
- */
3459
- function createReducer(initialState, ...entries) {
3460
- const reducerMap = /* @__PURE__ */ new Map();
3461
- for (const entry of entries) for (const creator of entry.creators) {
3462
- const handlers = reducerMap.get(creator.type) ?? [];
3463
- handlers.push(entry.reducer);
3464
- reducerMap.set(creator.type, handlers);
4276
+ /**
4277
+ * Programmatically execute a registered frontend tool without going through an LLM turn.
4278
+ * The handler runs, render components show up in the UI, and both the tool call and
4279
+ * result messages are added to `agent.messages`.
4280
+ */
4281
+ async runTool(params) {
4282
+ return this.runHandler.runTool(params);
3465
4283
  }
3466
- return (state, action) => {
3467
- const currentState = state ?? initialState;
3468
- const handlers = reducerMap.get(action.type);
3469
- if (!handlers || handlers.length === 0) return currentState;
3470
- let nextState = currentState;
3471
- for (const handler of handlers) nextState = handler(nextState, action);
3472
- return nextState;
3473
- };
3474
- }
3475
- /**
3476
- * Creates a selector that caches and reuses the last computed result
3477
- * when all input references are unchanged.
3478
- */
3479
- function createSelector(...args) {
3480
- if (args.length === 1) {
3481
- const projector = args[0];
3482
- let hasCached = false;
3483
- let lastState;
3484
- let lastResult;
3485
- return (state) => {
3486
- if (hasCached && state === lastState) return lastResult;
3487
- lastState = state;
3488
- lastResult = projector(state);
3489
- hasCached = true;
3490
- return lastResult;
3491
- };
4284
+ /**
4285
+ * State management (delegated to StateManager)
4286
+ */
4287
+ getStateByRun(agentId, threadId, runId) {
4288
+ return this.stateManager.getStateByRun(agentId, threadId, runId);
3492
4289
  }
3493
- const projector = args[args.length - 1];
3494
- const selectors = args.slice(0, -1);
3495
- let hasCached = false;
3496
- let lastInputs = [];
3497
- let lastResult;
3498
- return (state) => {
3499
- const inputs = selectors.map((selector) => selector(state));
3500
- if (hasCached && inputs.length === lastInputs.length && inputs.every((value, index) => value === lastInputs[index])) return lastResult;
3501
- lastInputs = inputs;
3502
- lastResult = projector(...inputs);
3503
- hasCached = true;
3504
- return lastResult;
3505
- };
3506
- }
3507
- /**
3508
- * RxJS operator that maps state emissions through a selector and suppresses
3509
- * unchanged projected values via reference equality.
3510
- */
3511
- function select(selector) {
3512
- return (source$) => source$.pipe((0, rxjs_operators.map)(selector), (0, rxjs_operators.distinctUntilChanged)());
3513
- }
3514
- /**
3515
- * RxJS operator that filters an action stream by action creators and narrows
3516
- * the output action type to the matched creator union.
3517
- *
3518
- * @throws Error when called without at least one action creator.
3519
- */
3520
- function ofType(...creators) {
3521
- if (creators.length === 0) throw new Error("ofType requires at least one action creator");
3522
- const actionTypes = new Set(creators.map((creator) => creator.type));
3523
- return (source$) => {
3524
- return source$.pipe((0, rxjs_operators.filter)((action) => {
3525
- return actionTypes.has(action.type);
3526
- }));
3527
- };
3528
- }
3529
- /**
3530
- * Creates an effect descriptor consumed by `createStore`.
3531
- */
3532
- function createEffect(factory, options = {}) {
3533
- if (options.dispatch === false) return {
3534
- run: factory,
3535
- dispatch: false
3536
- };
3537
- return {
3538
- run: factory,
3539
- dispatch: true
3540
- };
3541
- }
4290
+ getRunIdForMessage(agentId, threadId, messageId) {
4291
+ return this.stateManager.getRunIdForMessage(agentId, threadId, messageId);
4292
+ }
4293
+ getRunIdsForThread(agentId, threadId) {
4294
+ return this.stateManager.getRunIdsForThread(agentId, threadId);
4295
+ }
4296
+ /**
4297
+ * Internal method used by RunHandler to build frontend tools
4298
+ */
4299
+ buildFrontendTools(agentId) {
4300
+ return this.runHandler.buildFrontendTools(agentId);
4301
+ }
4302
+ /**
4303
+ * Called before each follow-up agent run (after tool execution).
4304
+ *
4305
+ * When a frontend tool handler calls framework state setters (e.g. React's
4306
+ * setState), those updates are batched and deferred — they do not take effect
4307
+ * until the framework's scheduler runs (React uses MessageChannel).
4308
+ * useAgentContext registers context via useLayoutEffect, which runs
4309
+ * synchronously after React commits that deferred batch.
4310
+ *
4311
+ * Without yielding here, the follow-up runAgent reads the context store
4312
+ * synchronously while the deferred updates are still pending, producing stale
4313
+ * context for the next agent turn.
4314
+ *
4315
+ * Override in framework-specific subclasses to yield to the framework
4316
+ * scheduler before the follow-up run. The base implementation is a no-op
4317
+ * because non-React environments have no deferred state to flush.
4318
+ */
4319
+ async waitForPendingFrameworkUpdates() {}
4320
+ };
4321
+
4322
+ //#endregion
4323
+ //#region src/types.ts
3542
4324
  /**
3543
- * Creates a small observable store with reducer + effects.
3544
- *
3545
- * Behavior:
3546
- * - `init()` starts effects and dispatches `@@micro-redux/init`.
3547
- * - `stop()` dispatches `@@micro-redux/stop` and unsubscribes all effects.
3548
- * - Effect action observation is scheduled on `asapScheduler` to avoid
3549
- * synchronous re-entrancy in the effect loop.
3550
- * - Any effect error triggers fail-fast teardown and errors both `actions$`
3551
- * and `state$`.
4325
+ * Status of a tool call execution
3552
4326
  */
3553
- function createStore(options) {
3554
- const reducer = options.reducer;
3555
- const effects = options.effects ?? [];
3556
- let hasFatalError = false;
3557
- let isRunning = false;
3558
- let effectSubscriptions = new rxjs.Subscription();
3559
- let currentState = reducer(void 0, INTERNAL_BOOT_ACTION);
3560
- const stateSubject = new rxjs.BehaviorSubject(currentState);
3561
- const actionsSubject = new rxjs.Subject();
3562
- const dispatchInternal = (action) => {
3563
- if (hasFatalError) throw new Error("Store is in a failed state due to an effect error");
3564
- currentState = reducer(currentState, action);
3565
- stateSubject.next(currentState);
3566
- actionsSubject.next(action);
3567
- };
3568
- const failFast = (error) => {
3569
- if (hasFatalError) return;
3570
- hasFatalError = true;
3571
- isRunning = false;
3572
- effectSubscriptions.unsubscribe();
3573
- effectSubscriptions = new rxjs.Subscription();
3574
- actionsSubject.error(error);
3575
- stateSubject.error(error);
3576
- };
3577
- const startEffects = () => {
3578
- for (const effect of effects) {
3579
- const scheduledActions$ = actionsSubject.asObservable().pipe((0, rxjs_operators.observeOn)(rxjs.asapScheduler));
3580
- const state$ = stateSubject.asObservable();
3581
- if (effect.dispatch) {
3582
- const subscription = effect.run(scheduledActions$, state$).subscribe({
3583
- next: (effectAction) => {
3584
- if (hasFatalError) return;
3585
- dispatchInternal(effectAction);
3586
- },
3587
- error: (error) => {
3588
- failFast(error);
3589
- }
4327
+ let ToolCallStatus = /* @__PURE__ */ function(ToolCallStatus) {
4328
+ ToolCallStatus["InProgress"] = "inProgress";
4329
+ ToolCallStatus["Executing"] = "executing";
4330
+ ToolCallStatus["Complete"] = "complete";
4331
+ return ToolCallStatus;
4332
+ }({});
4333
+
4334
+ //#endregion
4335
+ //#region src/utils/markdown.ts
4336
+ function completePartialMarkdown(input) {
4337
+ let s = input;
4338
+ const fenceMatches = Array.from(s.matchAll(/^(\s*)(`{3,}|~{3,})/gm));
4339
+ if (fenceMatches.length % 2 === 1) {
4340
+ const [, indent, fence] = fenceMatches[0];
4341
+ s += `\n${indent}${fence}`;
4342
+ }
4343
+ if (s.match(/\[([^\]]*)\]\(([^)]*)$/)) s += ")";
4344
+ const openElements = [];
4345
+ const chars = Array.from(s);
4346
+ const codeBlockRanges = [];
4347
+ const inlineCodeRanges = [];
4348
+ let tempCodeFenceCount = 0;
4349
+ let currentCodeBlockStart = -1;
4350
+ for (let i = 0; i < chars.length; i++) if (i === 0 || chars[i - 1] === "\n") {
4351
+ const lineMatch = s.substring(i).match(/^(\s*)(`{3,}|~{3,})/);
4352
+ if (lineMatch) {
4353
+ tempCodeFenceCount++;
4354
+ if (tempCodeFenceCount % 2 === 1) currentCodeBlockStart = i;
4355
+ else if (currentCodeBlockStart !== -1) {
4356
+ codeBlockRanges.push({
4357
+ start: currentCodeBlockStart,
4358
+ end: i + lineMatch[0].length
3590
4359
  });
3591
- effectSubscriptions.add(subscription);
3592
- continue;
4360
+ currentCodeBlockStart = -1;
3593
4361
  }
3594
- const subscription = effect.run(scheduledActions$, state$).subscribe({ error: (error) => {
3595
- failFast(error);
3596
- } });
3597
- effectSubscriptions.add(subscription);
4362
+ i += lineMatch[0].length - 1;
3598
4363
  }
3599
- };
3600
- return {
3601
- dispatch(action) {
3602
- dispatchInternal(action);
3603
- },
3604
- getState() {
3605
- return currentState;
3606
- },
3607
- get state$() {
3608
- return stateSubject.asObservable();
3609
- },
3610
- get actions$() {
3611
- return actionsSubject.asObservable();
3612
- },
3613
- select(selector) {
3614
- return stateSubject.asObservable().pipe(select(selector));
3615
- },
3616
- init() {
3617
- if (hasFatalError || isRunning) return;
3618
- isRunning = true;
3619
- startEffects();
3620
- if (hasFatalError) return;
3621
- dispatchInternal({ type: INTERNAL_ACTION_TYPES.init });
3622
- },
3623
- stop() {
3624
- if (hasFatalError || !isRunning) return;
3625
- dispatchInternal({ type: INTERNAL_ACTION_TYPES.stop });
3626
- effectSubscriptions.unsubscribe();
3627
- effectSubscriptions = new rxjs.Subscription();
3628
- isRunning = false;
4364
+ }
4365
+ for (let i = 0; i < chars.length; i++) if (chars[i] === "`") {
4366
+ let backslashCount = 0;
4367
+ for (let j = i - 1; j >= 0 && chars[j] === "\\"; j--) backslashCount++;
4368
+ if (backslashCount % 2 === 0) {
4369
+ for (let j = i + 1; j < chars.length; j++) if (chars[j] === "`") {
4370
+ let closingBackslashCount = 0;
4371
+ for (let k = j - 1; k >= 0 && chars[k] === "\\"; k--) closingBackslashCount++;
4372
+ if (closingBackslashCount % 2 === 0) {
4373
+ inlineCodeRanges.push({
4374
+ start: i,
4375
+ end: j + 1
4376
+ });
4377
+ i = j;
4378
+ break;
4379
+ }
4380
+ }
3629
4381
  }
4382
+ }
4383
+ const isInCode = (pos) => {
4384
+ return codeBlockRanges.some((range) => pos >= range.start && pos < range.end) || inlineCodeRanges.some((range) => pos >= range.start && pos < range.end);
3630
4385
  };
4386
+ for (let i = 0; i < chars.length; i++) {
4387
+ const char = chars[i];
4388
+ const nextChar = chars[i + 1];
4389
+ const prevChar = chars[i - 1];
4390
+ if (isInCode(i)) continue;
4391
+ if (char === "[") {
4392
+ let isCompleteLink = false;
4393
+ let bracketDepth = 1;
4394
+ let j = i + 1;
4395
+ while (j < chars.length && bracketDepth > 0) {
4396
+ if (chars[j] === "[" && !isInCode(j)) bracketDepth++;
4397
+ if (chars[j] === "]" && !isInCode(j)) bracketDepth--;
4398
+ j++;
4399
+ }
4400
+ if (bracketDepth === 0 && chars[j] === "(") {
4401
+ let parenDepth = 1;
4402
+ j++;
4403
+ while (j < chars.length && parenDepth > 0) {
4404
+ if (chars[j] === "(" && !isInCode(j)) parenDepth++;
4405
+ if (chars[j] === ")" && !isInCode(j)) parenDepth--;
4406
+ j++;
4407
+ }
4408
+ if (parenDepth === 0) {
4409
+ isCompleteLink = true;
4410
+ i = j - 1;
4411
+ continue;
4412
+ }
4413
+ }
4414
+ if (!isCompleteLink) {
4415
+ const existingIndex = openElements.findIndex((el) => el.type === "bracket");
4416
+ if (existingIndex !== -1) openElements.splice(existingIndex, 1);
4417
+ else openElements.push({
4418
+ type: "bracket",
4419
+ marker: "[",
4420
+ position: i
4421
+ });
4422
+ }
4423
+ } else if (char === "*" && nextChar === "*") {
4424
+ const existingIndex = openElements.findIndex((el) => el.type === "bold_star");
4425
+ if (existingIndex !== -1) openElements.splice(existingIndex, 1);
4426
+ else openElements.push({
4427
+ type: "bold_star",
4428
+ marker: "**",
4429
+ position: i
4430
+ });
4431
+ i++;
4432
+ } else if (char === "_" && nextChar === "_") {
4433
+ const existingIndex = openElements.findIndex((el) => el.type === "bold_underscore");
4434
+ if (existingIndex !== -1) openElements.splice(existingIndex, 1);
4435
+ else openElements.push({
4436
+ type: "bold_underscore",
4437
+ marker: "__",
4438
+ position: i
4439
+ });
4440
+ i++;
4441
+ } else if (char === "~" && nextChar === "~") {
4442
+ const existingIndex = openElements.findIndex((el) => el.type === "strike");
4443
+ if (existingIndex !== -1) openElements.splice(existingIndex, 1);
4444
+ else openElements.push({
4445
+ type: "strike",
4446
+ marker: "~~",
4447
+ position: i
4448
+ });
4449
+ i++;
4450
+ } else if (char === "*" && prevChar !== "*" && nextChar !== "*") {
4451
+ const existingIndex = openElements.findIndex((el) => el.type === "italic_star");
4452
+ if (existingIndex !== -1) openElements.splice(existingIndex, 1);
4453
+ else openElements.push({
4454
+ type: "italic_star",
4455
+ marker: "*",
4456
+ position: i
4457
+ });
4458
+ } else if (char === "_" && prevChar !== "_" && nextChar !== "_") {
4459
+ const existingIndex = openElements.findIndex((el) => el.type === "italic_underscore");
4460
+ if (existingIndex !== -1) openElements.splice(existingIndex, 1);
4461
+ else openElements.push({
4462
+ type: "italic_underscore",
4463
+ marker: "_",
4464
+ position: i
4465
+ });
4466
+ }
4467
+ }
4468
+ let backtickCount = 0;
4469
+ for (let i = 0; i < chars.length; i++) if (chars[i] === "`" && !isInCode(i)) backtickCount++;
4470
+ if (backtickCount % 2 === 1) s += "`";
4471
+ openElements.sort((a, b) => b.position - a.position);
4472
+ const closers = openElements.map((el) => {
4473
+ switch (el.type) {
4474
+ case "bracket": return "]";
4475
+ case "bold_star": return "**";
4476
+ case "bold_underscore": return "__";
4477
+ case "strike": return "~~";
4478
+ case "italic_star": return "*";
4479
+ case "italic_underscore": return "_";
4480
+ default: return "";
4481
+ }
4482
+ });
4483
+ let result = s + closers.join("");
4484
+ const finalFenceMatches = Array.from(result.matchAll(/^(\s*)(`{3,}|~{3,})/gm));
4485
+ const hasUnclosedBacktick = (result.match(/`/g) || []).length % 2 === 1;
4486
+ const hasUnclosedCodeFence = finalFenceMatches.length % 2 === 1;
4487
+ let shouldCloseParens = !hasUnclosedBacktick && !hasUnclosedCodeFence;
4488
+ if (shouldCloseParens) {
4489
+ const lastOpenParen = result.lastIndexOf("(");
4490
+ if (lastOpenParen !== -1) {
4491
+ if ((result.substring(0, lastOpenParen).match(/`/g) || []).length % 2 === 1) shouldCloseParens = false;
4492
+ }
4493
+ }
4494
+ if (shouldCloseParens) {
4495
+ const openParens = (result.match(/\(/g) || []).length;
4496
+ const closeParens = (result.match(/\)/g) || []).length;
4497
+ if (openParens > closeParens) result += ")".repeat(openParens - closeParens);
4498
+ }
4499
+ return result;
3631
4500
  }
3632
4501
 
3633
4502
  //#endregion
@@ -3642,6 +4511,7 @@ const initialThreadState = {
3642
4511
  isLoading: false,
3643
4512
  isFetchingNextPage: false,
3644
4513
  error: null,
4514
+ fetchMoreError: null,
3645
4515
  context: null,
3646
4516
  sessionId: 0,
3647
4517
  metadataCredentialsRequested: false,
@@ -3727,6 +4597,7 @@ const threadReducer = createReducer(initialThreadState, on(threadAdapterEvents.c
3727
4597
  isLoading: Boolean(context),
3728
4598
  isFetchingNextPage: false,
3729
4599
  error: null,
4600
+ fetchMoreError: null,
3730
4601
  metadataCredentialsRequested: false,
3731
4602
  metadataJoinCode: null,
3732
4603
  nextCursor: null,
@@ -3738,6 +4609,7 @@ const threadReducer = createReducer(initialThreadState, on(threadAdapterEvents.c
3738
4609
  isLoading: false,
3739
4610
  isFetchingNextPage: false,
3740
4611
  error: null,
4612
+ fetchMoreError: null,
3741
4613
  metadataCredentialsRequested: false,
3742
4614
  metadataJoinCode: null,
3743
4615
  nextCursor: null,
@@ -3748,7 +4620,8 @@ const threadReducer = createReducer(initialThreadState, on(threadAdapterEvents.c
3748
4620
  return {
3749
4621
  ...state,
3750
4622
  isLoading: true,
3751
- error: null
4623
+ error: null,
4624
+ fetchMoreError: null
3752
4625
  };
3753
4626
  }), on(threadRestEvents.listSucceeded, (state, { sessionId, threads, joinCode, nextCursor }) => {
3754
4627
  if (sessionId !== state.sessionId) return state;
@@ -3758,6 +4631,7 @@ const threadReducer = createReducer(initialThreadState, on(threadAdapterEvents.c
3758
4631
  threads: sortThreadsByRecency(threads),
3759
4632
  isLoading: false,
3760
4633
  error: null,
4634
+ fetchMoreError: null,
3761
4635
  metadataJoinCode: joinCode,
3762
4636
  metadataCredentialsRequested: joinCodeChanged ? false : state.metadataCredentialsRequested,
3763
4637
  nextCursor
@@ -3777,6 +4651,7 @@ const threadReducer = createReducer(initialThreadState, on(threadAdapterEvents.c
3777
4651
  ...state,
3778
4652
  threads: merged,
3779
4653
  isFetchingNextPage: false,
4654
+ fetchMoreError: null,
3780
4655
  nextCursor
3781
4656
  };
3782
4657
  }), on(threadRestEvents.nextPageFailed, (state, { sessionId, error }) => {
@@ -3784,7 +4659,7 @@ const threadReducer = createReducer(initialThreadState, on(threadAdapterEvents.c
3784
4659
  return {
3785
4660
  ...state,
3786
4661
  isFetchingNextPage: false,
3787
- error
4662
+ fetchMoreError: error
3788
4663
  };
3789
4664
  }), on(threadRestEvents.metadataCredentialsFailed, (state, { sessionId }) => {
3790
4665
  if (sessionId !== state.sessionId) return state;
@@ -3802,7 +4677,8 @@ const threadReducer = createReducer(initialThreadState, on(threadAdapterEvents.c
3802
4677
  if (!state.nextCursor || state.isFetchingNextPage) return state;
3803
4678
  return {
3804
4679
  ...state,
3805
- isFetchingNextPage: true
4680
+ isFetchingNextPage: true,
4681
+ fetchMoreError: null
3806
4682
  };
3807
4683
  }), on(threadAdapterEvents.renameRequested, (state, { threadId, name }) => {
3808
4684
  const existing = state.threads.find((thread) => thread.id === threadId);
@@ -3931,6 +4807,7 @@ function createThreadSelectors() {
3931
4807
  threads: createSelector((state) => state.threads),
3932
4808
  isLoading: createSelector((state) => state.isLoading),
3933
4809
  error: createSelector((state) => state.error),
4810
+ fetchMoreError: createSelector((state) => state.fetchMoreError),
3934
4811
  hasNextPage: createSelector((state) => state.nextCursor != null),
3935
4812
  isFetchingNextPage: createSelector((state) => state.isFetchingNextPage),
3936
4813
  isMutating: createSelector((state) => state.inFlightMutationCount > 0)
@@ -3940,6 +4817,7 @@ const standaloneSelectors = createThreadSelectors();
3940
4817
  const selectThreads = standaloneSelectors.threads;
3941
4818
  const selectThreadsIsLoading = standaloneSelectors.isLoading;
3942
4819
  const selectThreadsError = standaloneSelectors.error;
4820
+ const selectFetchMoreError = standaloneSelectors.fetchMoreError;
3943
4821
  const selectHasNextPage = standaloneSelectors.hasNextPage;
3944
4822
  const selectIsFetchingNextPage = standaloneSelectors.isFetchingNextPage;
3945
4823
  const selectIsMutating = standaloneSelectors.isMutating;
@@ -4313,6 +5191,7 @@ const ɵcreateThreadSelectors = createThreadSelectors;
4313
5191
  const ɵselectThreads = selectThreads;
4314
5192
  const ɵselectThreadsIsLoading = selectThreadsIsLoading;
4315
5193
  const ɵselectThreadsError = selectThreadsError;
5194
+ const ɵselectFetchMoreError = selectFetchMoreError;
4316
5195
  const ɵselectHasNextPage = selectHasNextPage;
4317
5196
  const ɵselectIsFetchingNextPage = selectIsFetchingNextPage;
4318
5197
  const ɵselectIsMutating = selectIsMutating;
@@ -4377,6 +5256,8 @@ exports.CopilotKitCore = CopilotKitCore;
4377
5256
  exports.CopilotKitCoreErrorCode = CopilotKitCoreErrorCode;
4378
5257
  exports.CopilotKitCoreRuntimeConnectionStatus = CopilotKitCoreRuntimeConnectionStatus;
4379
5258
  exports.IntelligenceAgent = IntelligenceAgent;
5259
+ exports.MEMORY_ERROR_REGISTRY = MEMORY_ERROR_REGISTRY;
5260
+ exports.MemoryError = MemoryError;
4380
5261
  exports.ProxiedCopilotRuntimeAgent = ProxiedCopilotRuntimeAgent;
4381
5262
  exports.RunHandler = RunHandler;
4382
5263
  exports.StateManager = StateManager;
@@ -4390,6 +5271,7 @@ exports.createSelector = createSelector;
4390
5271
  exports.createStore = createStore;
4391
5272
  exports.empty = empty;
4392
5273
  exports.ensureObjectArgs = ensureObjectArgs;
5274
+ exports.isAbortError = isAbortError;
4393
5275
  exports.isRunCompletionAware = isRunCompletionAware;
4394
5276
  exports.ofType = ofType;
4395
5277
  exports.on = on;
@@ -4398,19 +5280,33 @@ exports.props = props;
4398
5280
  exports.select = select;
4399
5281
  exports.ɵCOPILOTKIT_FEATURES = ɵCOPILOTKIT_FEATURES;
4400
5282
  exports.ɵMAX_SOCKET_RETRIES = ɵMAX_SOCKET_RETRIES;
5283
+ exports.ɵcreateMemoryStore = createMemoryStore;
4401
5284
  exports.ɵcreateThreadSelectors = ɵcreateThreadSelectors;
4402
5285
  exports.ɵcreateThreadStore = createThreadStore;
4403
5286
  exports.ɵisCopilotKitFeature = ɵisCopilotKitFeature;
5287
+ exports.ɵisRetryableMemoryStatus = isRetryableStatus;
4404
5288
  exports.ɵjoinPhoenixChannel$ = ɵjoinPhoenixChannel$;
5289
+ exports.ɵmapMemoryMetadataEvent = ɵmapMemoryMetadataEvent;
5290
+ exports.ɵmemoryAdapterEvents = ɵmemoryAdapterEvents;
5291
+ exports.ɵmemoryDomainEvents = ɵmemoryDomainEvents;
5292
+ exports.ɵmemoryReducer = ɵmemoryReducer;
5293
+ exports.ɵmemoryRestEvents = ɵmemoryRestEvents;
4405
5294
  exports.ɵobservePhoenixEvent$ = ɵobservePhoenixEvent$;
4406
5295
  exports.ɵobservePhoenixJoinOutcome$ = ɵobservePhoenixJoinOutcome$;
4407
5296
  exports.ɵobservePhoenixSocketHealth$ = ɵobservePhoenixSocketHealth$;
4408
5297
  exports.ɵobservePhoenixSocketSignals$ = ɵobservePhoenixSocketSignals$;
4409
5298
  exports.ɵphoenixChannel$ = ɵphoenixChannel$;
4410
5299
  exports.ɵphoenixSocket$ = ɵphoenixSocket$;
5300
+ exports.ɵselectFetchMoreError = ɵselectFetchMoreError;
4411
5301
  exports.ɵselectHasNextPage = ɵselectHasNextPage;
4412
5302
  exports.ɵselectIsFetchingNextPage = ɵselectIsFetchingNextPage;
4413
5303
  exports.ɵselectIsMutating = ɵselectIsMutating;
5304
+ exports.ɵselectMemories = ɵselectMemories;
5305
+ exports.ɵselectMemoriesAvailable = ɵselectMemoriesAvailable;
5306
+ exports.ɵselectMemoriesError = ɵselectMemoriesError;
5307
+ exports.ɵselectMemoriesIsLoading = ɵselectMemoriesIsLoading;
5308
+ exports.ɵselectMemoriesIsMutating = ɵselectMemoriesIsMutating;
5309
+ exports.ɵselectMemoriesRealtimeStatus = ɵselectMemoriesRealtimeStatus;
4414
5310
  exports.ɵselectThreads = ɵselectThreads;
4415
5311
  exports.ɵselectThreadsError = ɵselectThreadsError;
4416
5312
  exports.ɵselectThreadsIsLoading = ɵselectThreadsIsLoading;