@copilotkit/core 1.77.2 → 1.79.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.umd.js CHANGED
@@ -1158,7 +1158,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
1158
1158
  ...this.headers,
1159
1159
  "Content-Type": "application/json"
1160
1160
  });
1161
- fetch(this.singleEndpointUrl, {
1161
+ this.fetch(this.singleEndpointUrl, {
1162
1162
  method: "POST",
1163
1163
  headers,
1164
1164
  body: JSON.stringify({
@@ -1169,7 +1169,8 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
1169
1169
  },
1170
1170
  ...runId === void 0 ? {} : { body: { runId } }
1171
1171
  }),
1172
- ...this.credentials ? { credentials: this.credentials } : {}
1172
+ ...this.credentials ? { credentials: this.credentials } : {},
1173
+ ɵruntimeRequest: { nonCritical: true }
1173
1174
  }).catch((error) => {
1174
1175
  console.error("ProxiedCopilotRuntimeAgent: stop request failed", error);
1175
1176
  });
@@ -1180,14 +1181,15 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
1180
1181
  const origin = typeof window !== "undefined" && window.location ? window.location.origin : "http://localhost";
1181
1182
  const base = new URL(this.runtimeUrl, origin);
1182
1183
  const stopUrl = new URL(stopPath, base);
1183
- fetch(stopUrl.toString(), {
1184
+ this.fetch(stopUrl.toString(), {
1184
1185
  method: "POST",
1185
1186
  headers: {
1186
1187
  "Content-Type": "application/json",
1187
1188
  ...this.headers
1188
1189
  },
1189
1190
  ...runId === void 0 ? {} : { body: JSON.stringify({ runId }) },
1190
- ...this.credentials ? { credentials: this.credentials } : {}
1191
+ ...this.credentials ? { credentials: this.credentials } : {},
1192
+ ɵruntimeRequest: { nonCritical: true }
1191
1193
  }).catch((error) => {
1192
1194
  console.error("ProxiedCopilotRuntimeAgent: stop request failed", error);
1193
1195
  });
@@ -1663,6 +1665,185 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
1663
1665
  };
1664
1666
  }
1665
1667
 
1668
+ //#endregion
1669
+ //#region src/core/header-source.ts
1670
+ var CopilotKitHeaderResolutionError = class extends Error {
1671
+ constructor(cause) {
1672
+ super("[CopilotKit] Failed to resolve request headers", { cause });
1673
+ _defineProperty(this, "name", "CopilotKitHeaderResolutionError");
1674
+ }
1675
+ };
1676
+ function isHeaderResolutionError(error) {
1677
+ let current = error;
1678
+ for (let depth = 0; depth < 5 && current; depth++) {
1679
+ if (current instanceof CopilotKitHeaderResolutionError) return true;
1680
+ current = current.cause;
1681
+ }
1682
+ return false;
1683
+ }
1684
+ function isPromiseLike(value) {
1685
+ return typeof value === "object" && value !== null && typeof value.then === "function";
1686
+ }
1687
+ /**
1688
+ * Normalize a header map to a `Record<string, string>` with no `null` or
1689
+ * `undefined` values. Dropping an entry is how a header is cleared.
1690
+ */
1691
+ function normalizeHeaders(headers) {
1692
+ return Object.fromEntries(Object.entries(headers).filter((entry) => entry[1] != null));
1693
+ }
1694
+ /** Same keys, same values (order-independent). */
1695
+ function shallowEqualRecord(a, b) {
1696
+ const aKeys = Object.keys(a);
1697
+ const bKeys = Object.keys(b);
1698
+ if (aKeys.length !== bKeys.length) return false;
1699
+ return aKeys.every((key) => a[key] === b[key]);
1700
+ }
1701
+ function isHeaderRecordInput(value) {
1702
+ return typeof value === "object" && value !== null && !Array.isArray(value);
1703
+ }
1704
+ /**
1705
+ * Owns the headers source for one core. Resolution is synchronous for a
1706
+ * record or a sync builder, so those callers never pay an extra await.
1707
+ */
1708
+ var HeaderSourceResolver = class {
1709
+ constructor(onFailure) {
1710
+ this.onFailure = onFailure;
1711
+ _defineProperty(this, "source", {});
1712
+ _defineProperty(this, "sourceGeneration", 0);
1713
+ _defineProperty(this, "snapshot", {});
1714
+ _defineProperty(this, "inFlight", void 0);
1715
+ }
1716
+ /** The last resolved headers. Not necessarily current for a builder. */
1717
+ get headers() {
1718
+ return this.snapshot;
1719
+ }
1720
+ /** Bumped on every accepted `setSource`, never by a new token. */
1721
+ get generation() {
1722
+ return this.sourceGeneration;
1723
+ }
1724
+ /**
1725
+ * Returns false when a builder with the same identity is set again, or
1726
+ * when a record replaces another record with equal normalized values (a
1727
+ * caller re-passing an equivalent literal on every re-render must not
1728
+ * bump the generation). A record replacing a builder, a builder replacing
1729
+ * a record, and a new builder function all still count as a change.
1730
+ */
1731
+ setSource(source) {
1732
+ if (typeof source === "function" && source === this.source) return false;
1733
+ const nextSnapshot = typeof source === "function" ? {} : normalizeHeaders(source);
1734
+ if (typeof source !== "function" && typeof this.source !== "function" && shallowEqualRecord(nextSnapshot, this.snapshot)) return false;
1735
+ this.source = source;
1736
+ this.sourceGeneration += 1;
1737
+ this.inFlight = void 0;
1738
+ this.snapshot = nextSnapshot;
1739
+ return true;
1740
+ }
1741
+ resolve() {
1742
+ var _this$inFlight;
1743
+ const source = this.source;
1744
+ if (typeof source !== "function") return this.snapshot;
1745
+ const generation = this.sourceGeneration;
1746
+ if (((_this$inFlight = this.inFlight) === null || _this$inFlight === void 0 ? void 0 : _this$inFlight.generation) === generation) return this.inFlight.promise;
1747
+ let value;
1748
+ try {
1749
+ value = source();
1750
+ } catch (error) {
1751
+ throw this.fail(error);
1752
+ }
1753
+ if (!isPromiseLike(value)) return this.accept(value, generation);
1754
+ const promise = Promise.resolve(value).then((resolved) => this.accept(resolved, generation), (error) => {
1755
+ throw this.fail(error);
1756
+ }).finally(() => {
1757
+ var _this$inFlight2;
1758
+ if (((_this$inFlight2 = this.inFlight) === null || _this$inFlight2 === void 0 ? void 0 : _this$inFlight2.promise) === promise) this.inFlight = void 0;
1759
+ });
1760
+ this.inFlight = {
1761
+ generation,
1762
+ promise
1763
+ };
1764
+ return promise;
1765
+ }
1766
+ accept(value, generation) {
1767
+ if (!isHeaderRecordInput(value)) throw this.fail(/* @__PURE__ */ new TypeError("headers builder must return an object of header values"));
1768
+ const normalized = normalizeHeaders(value);
1769
+ if (generation === this.sourceGeneration) {
1770
+ if (!shallowEqualRecord(normalized, this.snapshot)) this.snapshot = normalized;
1771
+ return this.snapshot;
1772
+ }
1773
+ return normalized;
1774
+ }
1775
+ fail(cause) {
1776
+ if (cause instanceof CopilotKitHeaderResolutionError) return cause;
1777
+ const error = new CopilotKitHeaderResolutionError(cause);
1778
+ this.onFailure(error);
1779
+ return error;
1780
+ }
1781
+ };
1782
+ const PROTOCOL_HEADERS = new Set(["content-type", "accept"]);
1783
+ /**
1784
+ * Put fresh core headers on top of a request's headers, keeping the input's
1785
+ * shape. Core beats an agent's own headers (#5635). A site's Content-Type and
1786
+ * Accept are never overridden, matching every site's existing spread order.
1787
+ */
1788
+ function ɵoverlayCoreHeaders(existing, core) {
1789
+ if (existing instanceof Headers) {
1790
+ const headers = new Headers(existing);
1791
+ for (const [key, value] of Object.entries(core)) {
1792
+ if (PROTOCOL_HEADERS.has(key.toLowerCase()) && headers.has(key)) continue;
1793
+ headers.set(key, value);
1794
+ }
1795
+ return headers;
1796
+ }
1797
+ const base = Array.isArray(existing) ? Object.fromEntries(existing) : { ...existing };
1798
+ const keyByLower = new Map(Object.keys(base).map((k) => [k.toLowerCase(), k]));
1799
+ for (const [key, value] of Object.entries(core)) {
1800
+ const existingKey = keyByLower.get(key.toLowerCase());
1801
+ if (existingKey !== void 0) {
1802
+ if (PROTOCOL_HEADERS.has(key.toLowerCase())) continue;
1803
+ delete base[existingKey];
1804
+ }
1805
+ base[key] = value;
1806
+ }
1807
+ return base;
1808
+ }
1809
+ /** Reject with the signal's AbortError if it aborts before `value` settles. */
1810
+ async function abortable(value, signal) {
1811
+ if (!signal || !isPromiseLike(value)) return value;
1812
+ if (signal.aborted) throw abortError(signal);
1813
+ return new Promise((resolve, reject) => {
1814
+ const onAbort = () => reject(abortError(signal));
1815
+ signal.addEventListener("abort", onAbort, { once: true });
1816
+ Promise.resolve(value).then((v) => {
1817
+ signal.removeEventListener("abort", onAbort);
1818
+ resolve(v);
1819
+ }, (e) => {
1820
+ signal.removeEventListener("abort", onAbort);
1821
+ reject(e);
1822
+ });
1823
+ });
1824
+ }
1825
+ function abortError(signal) {
1826
+ return signal.reason instanceof Error ? signal.reason : new DOMException("The operation was aborted.", "AbortError");
1827
+ }
1828
+ /**
1829
+ * Add default headers (e.g. the public API key) to a source, only where the
1830
+ * source left the key unset or empty. The single shared replacement for the
1831
+ * React, Vue and Angular providers' own merges.
1832
+ */
1833
+ function ɵwithHeaderDefaults(source, defaults) {
1834
+ if (Object.keys(defaults).length === 0) return source;
1835
+ const fill = (headers) => {
1836
+ const out = { ...headers };
1837
+ for (const [key, value] of Object.entries(defaults)) if (!out[key]) out[key] = value;
1838
+ return out;
1839
+ };
1840
+ if (typeof source !== "function") return fill(source);
1841
+ return (() => {
1842
+ const value = source();
1843
+ return isPromiseLike(value) ? Promise.resolve(value).then((resolved) => isHeaderRecordInput(resolved) ? fill(resolved) : resolved) : isHeaderRecordInput(value) ? fill(value) : value;
1844
+ });
1845
+ }
1846
+
1666
1847
  //#endregion
1667
1848
  //#region src/core/agent-registry.ts
1668
1849
  /** Maximum wait for optional Inspector metadata before degrading to absence. */
@@ -1988,29 +2169,85 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
1988
2169
  console.warn(`Agent ${id} not found`);
1989
2170
  }
1990
2171
  /**
1991
- * Apply current core headers to an agent, merged ON TOP of the agent's own
1992
- * construction-time headers (the per-agent baseline in `agentOwnHeaders`).
1993
- * Core wins on a key conflict. Non-`HttpAgent` agents are left untouched
1994
- * because only `HttpAgent` carries a `headers` field. See #5635.
2172
+ * Shared core-and-own-header merge for a single agent. Captures the
2173
+ * agent's construction-time headers once (the per-agent baseline in
2174
+ * `agentOwnHeaders`), then either keeps only that baseline — a
2175
+ * `ProxiedCopilotRuntimeAgent`, whose core headers are added by
2176
+ * `ɵruntimeFetch` when each request is actually sent instead, so a key the
2177
+ * builder stops returning can never ride along from a stale copy baked
2178
+ * onto the agent (see #1937) — or merges `coreHeaders` on top of it (any
2179
+ * other `HttpAgent`; core wins on a key conflict, see #5635).
1995
2180
  */
1996
- applyHeadersToAgent(agent) {
1997
- if (ɵisHttpAgent(agent)) {
1998
- if (!this.agentOwnHeaders.has(agent)) this.agentOwnHeaders.set(agent, { ...agent.headers });
1999
- agent.headers = {
2000
- ...this.agentOwnHeaders.get(agent),
2001
- ...this.core.headers
2002
- };
2181
+ applyHeaderRecordToAgent(agent, coreHeaders) {
2182
+ if (!this.agentOwnHeaders.has(agent)) this.agentOwnHeaders.set(agent, { ...agent.headers });
2183
+ const own = this.agentOwnHeaders.get(agent);
2184
+ if (agent instanceof ProxiedCopilotRuntimeAgent) {
2185
+ agent.headers = { ...own };
2186
+ this.applyRuntimeFetchToAgent(agent);
2187
+ return;
2003
2188
  }
2189
+ agent.headers = {
2190
+ ...own,
2191
+ ...coreHeaders
2192
+ };
2004
2193
  }
2005
2194
  /**
2006
- * Apply current headers to all agents
2195
+ * Apply the last resolved header snapshot to an agent, merged ON TOP of
2196
+ * the agent's own construction-time headers. Non-`HttpAgent` agents are
2197
+ * left untouched because only `HttpAgent` carries a `headers` field. See
2198
+ * #5635.
2199
+ *
2200
+ * Never invokes the headers builder — safe to call from anywhere (dev-only
2201
+ * registration helpers, a React effect that re-runs on every render)
2202
+ * without risking a synchronous throw or an unhandled async rejection from
2203
+ * a user-supplied builder. Use `prepareAgentHeadersForRun` (friends-only)
2204
+ * on the run/connect path, where a builder failure can be awaited and
2205
+ * reported once.
2206
+ */
2207
+ applyHeadersToAgent(agent) {
2208
+ if (!ɵisHttpAgent(agent)) return;
2209
+ const friends = this.core;
2210
+ this.applyHeaderRecordToAgent(agent, friends.headers);
2211
+ }
2212
+ /**
2213
+ * Apply the last resolved header snapshot to every agent, without
2214
+ * triggering a builder call per agent. Used by `initialize` and
2215
+ * `setHeaders`; a run re-applies with fresh headers anyway (see
2216
+ * `prepareAgentHeadersForRun`).
2007
2217
  */
2008
2218
  applyHeadersToAgents(agents) {
2219
+ const friends = this.core;
2009
2220
  Object.values(agents).forEach((agent) => {
2010
- this.applyHeadersToAgent(agent);
2221
+ if (ɵisHttpAgent(agent)) this.applyHeaderRecordToAgent(agent, friends.headers);
2011
2222
  });
2012
2223
  }
2013
2224
  /**
2225
+ * Resolve headers fresh and apply them to `agent` right before a run or
2226
+ * connect actually sends (#1937) — the resolving counterpart to
2227
+ * `applyHeadersToAgent`. Friends-only: only the run handler should call
2228
+ * this, since resolving can invoke a user-supplied builder that throws
2229
+ * synchronously or returns a rejecting promise. Resolution is synchronous
2230
+ * for a record or a sync builder; this returns a promise only when an
2231
+ * async builder must be awaited first, and callers that need the write to
2232
+ * have landed before continuing must await a returned promise.
2233
+ *
2234
+ * A `ProxiedCopilotRuntimeAgent` never invokes the builder here: its core
2235
+ * headers are added by `ɵruntimeFetch` at send time instead, so only its
2236
+ * own headers are (re)applied.
2237
+ */
2238
+ prepareAgentHeadersForRun(agent) {
2239
+ if (!ɵisHttpAgent(agent)) return;
2240
+ if (agent instanceof ProxiedCopilotRuntimeAgent) {
2241
+ this.applyHeaderRecordToAgent(agent, {});
2242
+ return;
2243
+ }
2244
+ const resolved = this.core.resolveHeaders();
2245
+ if (isPromiseLike(resolved)) return Promise.resolve(resolved).then((headers) => {
2246
+ this.applyHeaderRecordToAgent(agent, headers);
2247
+ });
2248
+ this.applyHeaderRecordToAgent(agent, resolved);
2249
+ }
2250
+ /**
2014
2251
  * Apply current credentials to an agent
2015
2252
  */
2016
2253
  applyCredentialsToAgent(agent) {
@@ -2072,6 +2309,14 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2072
2309
  }
2073
2310
  createRuntimeFetch() {
2074
2311
  if (!this.runtimeFetch) this.runtimeFetch = (async (input, init) => {
2312
+ var _init$headers;
2313
+ const friends = this.core;
2314
+ const coreHeaders = await abortable(friends.resolveHeaders(), init === null || init === void 0 ? void 0 : init.signal);
2315
+ const requestHeaders = ɵoverlayCoreHeaders((_init$headers = init === null || init === void 0 ? void 0 : init.headers) !== null && _init$headers !== void 0 ? _init$headers : input instanceof Request ? input.headers : void 0, coreHeaders);
2316
+ init = {
2317
+ ...init,
2318
+ headers: requestHeaders
2319
+ };
2075
2320
  const meta = () => runtimeRequestMeta(init);
2076
2321
  const watchdog = this.armRuntimeRequestWatchdog(meta());
2077
2322
  try {
@@ -2143,7 +2388,15 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2143
2388
  const headersGeneration = this.inspectorMetadataHeadersGeneration;
2144
2389
  const credentialsGeneration = this.inspectorMetadataCredentialsGeneration;
2145
2390
  const friends = this.core;
2146
- const headers = { ...friends.headers };
2391
+ let headers;
2392
+ try {
2393
+ const resolved = friends.resolveHeaders();
2394
+ headers = { ...isPromiseLike(resolved) ? await resolved : resolved };
2395
+ } catch (_unused) {
2396
+ if (generation === this.inspectorMetadataGeneration) this.setInspectorMetadata(void 0);
2397
+ return;
2398
+ }
2399
+ if (generation !== this.inspectorMetadataGeneration) return;
2147
2400
  const credentials = friends.credentials;
2148
2401
  const abortController = new AbortController();
2149
2402
  this.inspectorMetadataAbortController = abortController;
@@ -2186,7 +2439,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2186
2439
  aborted,
2187
2440
  timeout
2188
2441
  ]);
2189
- } catch (_unused) {
2442
+ } catch (_unused2) {
2190
2443
  nextMetadata = void 0;
2191
2444
  } finally {
2192
2445
  if (timeoutId !== void 0) clearTimeout(timeoutId);
@@ -2305,6 +2558,10 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2305
2558
  async markRuntimeUnreachable(error) {
2306
2559
  this.setRuntimeConnectionStatus(CopilotKitCoreRuntimeConnectionStatus.Error);
2307
2560
  await this.notifyRuntimeStatusChanged(CopilotKitCoreRuntimeConnectionStatus.Error);
2561
+ if (isHeaderResolutionError(error)) {
2562
+ _copilotkit_shared.logger.warn(`Could not resolve request headers for the identification request (${this._runtimeUrl}/info). Check the headers builder passed to CopilotKit.`);
2563
+ return;
2564
+ }
2308
2565
  const runtimeStatus = isRuntimeInfoRequestError(error) ? error.runtimeInfoStatus : void 0;
2309
2566
  _copilotkit_shared.logger.warn(runtimeStatus === void 0 ? `Runtime did not answer the identification request (${this._runtimeUrl}/info): ${error.message}. The runtime appears to be unreachable.` : `Runtime answered the identification request with status ${runtimeStatus} (${this._runtimeUrl}/info): ${error.message}. The runtime is reachable but refused the request — check credentials and authorisation before addresses and ports.`);
2310
2567
  await this.core.emitError({
@@ -2570,9 +2827,10 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2570
2827
  }
2571
2828
  }
2572
2829
  async fetchRuntimeInfo(runtimeUrl, runtimeTransport, signal) {
2573
- const baseHeaders = this.core.headers;
2574
- const credentials = this.core.credentials;
2575
- const headers = { ...baseHeaders };
2830
+ const friends = this.core;
2831
+ const credentials = friends.credentials;
2832
+ const resolved = friends.resolveHeaders();
2833
+ const headers = { ...isPromiseLike(resolved) ? await abortable(resolved, signal) : resolved };
2576
2834
  if (runtimeTransport === "single") return {
2577
2835
  runtimeInfo: await this.fetchRuntimeInfoSingle(this.singleEndpointUrlFor(runtimeUrl), headers, credentials, signal),
2578
2836
  resolvedTransport: "single"
@@ -2625,7 +2883,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2625
2883
  runtimeInfo: await response.json(),
2626
2884
  resolvedTransport: "rest"
2627
2885
  };
2628
- } catch (_unused2) {}
2886
+ } catch (_unused3) {}
2629
2887
  return {
2630
2888
  runtimeInfo: await this.fetchRuntimeInfoSingle(this.singleEndpointUrlFor(runtimeUrl), { ...headers }, credentials, signal),
2631
2889
  resolvedTransport: "single"
@@ -2875,18 +3133,19 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2875
3133
  const seededState = JSON.parse(JSON.stringify((_suggestionsConsumerA = suggestionsConsumerAgent.state) !== null && _suggestionsConsumerA !== void 0 ? _suggestionsConsumerA : {}));
2876
3134
  const useStateless = this.core.suggestions === true && this.core.runtimeTransport !== "single";
2877
3135
  let suggestionAgent;
3136
+ let statelessAgent;
2878
3137
  if (useStateless) {
2879
3138
  const suggestUrl = `${this.core.runtimeUrl}/agent/${encodeURIComponent(resolvedProviderAgentId)}/suggest`;
2880
3139
  const credentials = this.core.credentials;
2881
- suggestionAgent = new _ag_ui_client.HttpAgent({
3140
+ statelessAgent = new _ag_ui_client.HttpAgent({
2882
3141
  agentId: resolvedProviderAgentId,
2883
3142
  url: suggestUrl,
2884
- headers: { ...this.core.headers },
2885
3143
  ...credentials ? { fetch: (url, requestInit) => fetch(url, {
2886
3144
  ...requestInit,
2887
3145
  credentials
2888
3146
  }) } : {}
2889
3147
  });
3148
+ suggestionAgent = statelessAgent;
2890
3149
  } else {
2891
3150
  suggestionAgent = suggestionsProviderAgent.clone();
2892
3151
  if (suggestionAgent instanceof ProxiedCopilotRuntimeAgent) suggestionAgent.messageFilter = void 0;
@@ -2899,6 +3158,9 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2899
3158
  suggestionAgent.abortRun();
2900
3159
  } };
2901
3160
  this._runningSuggestions[consumerAgentId] = [...(_this$_runningSuggest3 = this._runningSuggestions[consumerAgentId]) !== null && _this$_runningSuggest3 !== void 0 ? _this$_runningSuggest3 : [], runHandle];
3161
+ if (statelessAgent) statelessAgent.headers = { ...await this.core.resolveHeaders() };
3162
+ else await this.core.prepareAgentHeadersForRun(suggestionAgent);
3163
+ if (aborted) return;
2902
3164
  suggestionAgent.addMessage({
2903
3165
  id: suggestionId,
2904
3166
  role: "user",
@@ -3594,7 +3856,8 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
3594
3856
  if (typeof cursorAware.clearReconnectCursor === "function") cursorAware.clearReconnectCursor(incomingThreadId);
3595
3857
  }
3596
3858
  }
3597
- this._internal.applyHeadersToAgent(agent);
3859
+ const headersApplied = this._internal.prepareAgentHeadersForRun(agent);
3860
+ if (headersApplied) await headersApplied;
3598
3861
  await this._internal.notifySubscribers((subscriber) => {
3599
3862
  var _subscriber$onAgentRu;
3600
3863
  return (_subscriber$onAgentRu = subscriber.onAgentRunStarted) === null || _subscriber$onAgentRu === void 0 ? void 0 : _subscriber$onAgentRu.call(subscriber, {
@@ -3661,7 +3924,16 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
3661
3924
  */
3662
3925
  async runAgent({ agent, forwardedProps, resume, runId }, continuationHandoff) {
3663
3926
  if (agent.agentId) this._internal.suggestionEngine.clearSuggestions(agent.agentId);
3664
- this._internal.applyHeadersToAgent(agent);
3927
+ try {
3928
+ const headersApplied = this._internal.prepareAgentHeadersForRun(agent);
3929
+ if (headersApplied) await headersApplied;
3930
+ } catch (_unused) {
3931
+ continuationHandoff === null || continuationHandoff === void 0 || continuationHandoff.cancel();
3932
+ return {
3933
+ result: void 0,
3934
+ newMessages: []
3935
+ };
3936
+ }
3665
3937
  if (agent.detachActiveRun) try {
3666
3938
  await agent.detachActiveRun();
3667
3939
  } catch (error) {
@@ -4911,6 +5183,9 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
4911
5183
  stop() {
4912
5184
  const session = this.session;
4913
5185
  if (!session) return;
5186
+ const collector = session.collector;
5187
+ session.collector = void 0;
5188
+ collector === null || collector === void 0 || collector.stop();
4914
5189
  if (session.ready && session.connection) this.flush(session, session.connection);
4915
5190
  this.end(session, {
4916
5191
  status: "error",
@@ -5013,6 +5288,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
5013
5288
  } finally {
5014
5289
  if (socket) {
5015
5290
  socket.off(connection.socketRefs);
5291
+ socket.connect = () => void 0;
5016
5292
  socket.disconnect();
5017
5293
  }
5018
5294
  }
@@ -5020,12 +5296,12 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
5020
5296
  fail(session, connection, code, retryable = true) {
5021
5297
  var _session$collector3;
5022
5298
  if (!this.current(session, connection)) return;
5023
- (_session$collector3 = session.collector) === null || _session$collector3 === void 0 || _session$collector3.stop();
5024
- session.collector = void 0;
5025
5299
  if (session.ready && session.started) session.promise = new Promise((resolve) => {
5026
5300
  session.resolve = resolve;
5027
5301
  });
5028
5302
  session.ready = false;
5303
+ (_session$collector3 = session.collector) === null || _session$collector3 === void 0 || _session$collector3.stop();
5304
+ session.collector = void 0;
5029
5305
  this.discardQueue(session);
5030
5306
  session.linkedThreads.clear();
5031
5307
  for (const pending of connection.pending) pending.finish("PERSISTENCE_UNKNOWN");
@@ -5070,12 +5346,15 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
5070
5346
  if (!this.current(session, connection)) return;
5071
5347
  }
5072
5348
  const rest = transport === "rest";
5349
+ const resolved = this.core.resolveHeaders();
5350
+ const coreHeaders = isPromiseLike(resolved) ? await abortable(resolved, connection.abort.signal) : resolved;
5351
+ if (!this.current(session, connection)) return;
5073
5352
  const response = await fetch(rest ? `${runtimeUrl}/trajectory/${encodeURIComponent(session.trajectoryId)}/connect` : (_this$core$ɵruntimeE = this.core.ɵruntimeEndpointUrl) !== null && _this$core$ɵruntimeE !== void 0 ? _this$core$ɵruntimeE : runtimeUrl, {
5074
5353
  method: "POST",
5075
5354
  redirect: "error",
5076
5355
  signal: connection.abort.signal,
5077
5356
  headers: {
5078
- ...this.core.headers,
5357
+ ...coreHeaders,
5079
5358
  "Content-Type": "application/json"
5080
5359
  },
5081
5360
  credentials: this.core.credentials,
@@ -5187,7 +5466,11 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
5187
5466
  return ((_connection$socket = connection.socket) === null || _connection$socket === void 0 ? void 0 : _connection$socket.isConnected()) === true && ((_connection$channel = connection.channel) === null || _connection$channel === void 0 ? void 0 : _connection$channel.state) === "joined";
5188
5467
  }
5189
5468
  send(session, connection, event) {
5190
- if (!this.current(session, connection) || !session.ready) return;
5469
+ if (!this.current(session, connection)) return;
5470
+ if (!session.ready) {
5471
+ this.addDropped(session, 1, false);
5472
+ return;
5473
+ }
5191
5474
  if (!this.connected(connection)) {
5192
5475
  this.addDropped(session, 1);
5193
5476
  this.fail(session, connection, "CONNECTION_LOST");
@@ -6714,6 +6997,11 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
6714
6997
  CopilotKitCoreErrorCode["TRANSCRIPTION_AUTH_FAILED"] = "transcription_auth_failed";
6715
6998
  CopilotKitCoreErrorCode["TRANSCRIPTION_NETWORK_ERROR"] = "transcription_network_error";
6716
6999
  CopilotKitCoreErrorCode["SUBSCRIBER_CALLBACK_FAILED"] = "subscriber_callback_failed";
7000
+ /**
7001
+ * The `headers` builder threw, rejected, or returned something other than
7002
+ * an object. The request was not sent. `error.cause` is the builder's error.
7003
+ */
7004
+ CopilotKitCoreErrorCode["HEADER_RESOLUTION_FAILED"] = "header_resolution_failed";
6717
7005
  return CopilotKitCoreErrorCode;
6718
7006
  }({});
6719
7007
  /**
@@ -6736,18 +7024,9 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
6736
7024
  CopilotKitCoreRuntimeConnectionStatus["Error"] = "error";
6737
7025
  return CopilotKitCoreRuntimeConnectionStatus;
6738
7026
  }({});
6739
- /**
6740
- * Normalize a header map to the internal invariant: a `Record<string, string>`
6741
- * with no `null`/`undefined` values. Entries whose value is `null`/`undefined`
6742
- * are dropped (this is how a header is cleared). Shared by the constructor and
6743
- * `setHeaders` so both write paths into `_headers` enforce the same invariant.
6744
- */
6745
- function normalizeHeaders(headers) {
6746
- return Object.fromEntries(Object.entries(headers).filter((entry) => entry[1] != null));
6747
- }
6748
7027
  var CopilotKitCore = class {
6749
7028
  constructor({ runtimeUrl, runtimeTransport = "auto", deferInitialConnection = false, headers = {}, credentials, messageFilter, properties = {}, agents__unsafe_dev_only = {}, tools = [], suggestionsConfig = [], debug, learning }) {
6750
- _defineProperty(this, "_headers", void 0);
7029
+ _defineProperty(this, "headerSource", void 0);
6751
7030
  _defineProperty(this, "_credentials", void 0);
6752
7031
  _defineProperty(this, "_messageFilter", void 0);
6753
7032
  _defineProperty(this, "_properties", void 0);
@@ -6765,7 +7044,14 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
6765
7044
  _defineProperty(this, "learningConfiguredListeners", /* @__PURE__ */ new Set());
6766
7045
  _defineProperty(this, "_memoryStore", void 0);
6767
7046
  _defineProperty(this, "previousAgentIds", /* @__PURE__ */ new Set());
6768
- this._headers = normalizeHeaders(headers);
7047
+ this.headerSource = new HeaderSourceResolver((error) => {
7048
+ this.emitError({
7049
+ error,
7050
+ code: CopilotKitCoreErrorCode.HEADER_RESOLUTION_FAILED,
7051
+ context: { source: "headers" }
7052
+ });
7053
+ });
7054
+ this.headerSource.setSource(headers);
6769
7055
  this._credentials = credentials;
6770
7056
  this._messageFilter = messageFilter;
6771
7057
  this._properties = properties;
@@ -6823,6 +7109,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
6823
7109
  * Internal method used by delegate classes to emit errors
6824
7110
  */
6825
7111
  async emitError({ error, code, context = {} }) {
7112
+ if (code !== CopilotKitCoreErrorCode.HEADER_RESOLUTION_FAILED && isHeaderResolutionError(error)) return;
6826
7113
  await this.notifySubscribers((subscriber) => {
6827
7114
  var _subscriber$onError;
6828
7115
  return (_subscriber$onError = subscriber.onError) === null || _subscriber$onError === void 0 ? void 0 : _subscriber$onError.call(subscriber, {
@@ -6885,8 +7172,24 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
6885
7172
  get runtimeVersion() {
6886
7173
  return this.agentRegistry.runtimeVersion;
6887
7174
  }
7175
+ /**
7176
+ * The last resolved headers. With a builder this is the value from the most
7177
+ * recent request, not necessarily current; call `resolveHeaders()` for that.
7178
+ */
6888
7179
  get headers() {
6889
- return this._headers;
7180
+ return this.headerSource.headers;
7181
+ }
7182
+ /**
7183
+ * Resolve the current headers. Synchronous for a record or a sync builder,
7184
+ * a promise for an async builder. Concurrent calls share one builder call.
7185
+ * The returned object is shared; copy it before modifying.
7186
+ */
7187
+ resolveHeaders() {
7188
+ return this.headerSource.resolve();
7189
+ }
7190
+ /** Changes only on `setHeaders` or a new source, never on a new token. */
7191
+ get ɵheadersGeneration() {
7192
+ return this.headerSource.generation;
6890
7193
  }
6891
7194
  get credentials() {
6892
7195
  return this._credentials;
@@ -7027,9 +7330,17 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
7027
7330
  * with, set it at the provider/core level instead of on the agent, or update
7028
7331
  * it on the agent directly. The clear-on-logout pattern above is for
7029
7332
  * core-level headers.
7333
+ *
7334
+ * Pass a function to have headers evaluated when each request is sent
7335
+ * (sync or async). Setting the same function again is a no-op. A new token
7336
+ * from the builder doesn't notify `onHeadersChanged`. On a user switch,
7337
+ * call `setHeaders` with a NEW function (or a record), or remount.
7338
+ *
7339
+ * Passing a record equal (by value) to the currently applied record is
7340
+ * also a no-op — safe to call on every render with a fresh object literal.
7030
7341
  */
7031
7342
  setHeaders(headers) {
7032
- this._headers = normalizeHeaders(headers);
7343
+ if (!this.headerSource.setSource(headers)) return;
7033
7344
  if (this._memoryStore) this.syncMemoryContext();
7034
7345
  this.agentRegistry.applyHeadersToAgents(this.agentRegistry.agents);
7035
7346
  this.agentRegistry.handleHeadersChanged();
@@ -7185,8 +7496,8 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
7185
7496
  return this.learningBridge.registerOpenThread(params);
7186
7497
  }
7187
7498
  /**
7188
- * Re-apply the current headers to a single agent (delegated to
7189
- * AgentRegistry). Core headers are merged on top of the agent's own
7499
+ * Re-apply the last resolved header snapshot to a single agent (delegated
7500
+ * to AgentRegistry). Core headers are merged on top of the agent's own
7190
7501
  * construction-time headers rather than replacing them, so headers
7191
7502
  * configured directly on an `HttpAgent` (e.g. an `Authorization` for a
7192
7503
  * self-hosted backend) survive header updates instead of being silently
@@ -7197,11 +7508,31 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
7197
7508
  * afterwards is `setHeaders` (which re-applies to every agent), not mutating
7198
7509
  * `agent.headers` directly — a direct mutation is overwritten on the next
7199
7510
  * re-apply.
7511
+ *
7512
+ * A `ProxiedCopilotRuntimeAgent` keeps only its own construction-time
7513
+ * headers here — core headers are added by `ɵruntimeFetch` when each
7514
+ * request is sent (see #1937), so `agent.headers` never carries a stale
7515
+ * copy of a core header the builder has since stopped returning.
7516
+ *
7517
+ * Never invokes the headers builder (unlike the run/connect path's
7518
+ * internal `prepareAgentHeadersForRun`): safe to call from a dev-only
7519
+ * registration helper or a React effect that re-runs on every render
7520
+ * without risking a synchronous throw or an unhandled async rejection from
7521
+ * a user-supplied builder.
7200
7522
  */
7201
7523
  applyHeadersToAgent(agent) {
7202
7524
  this.agentRegistry.applyHeadersToAgent(agent);
7203
7525
  }
7204
7526
  /**
7527
+ * Resolve headers fresh and apply them to `agent` right before a run or
7528
+ * connect actually sends (#1937). Friends-only (delegated to
7529
+ * AgentRegistry) — the run handler is the sole caller, since resolving can
7530
+ * invoke a user-supplied builder that throws or rejects.
7531
+ */
7532
+ prepareAgentHeadersForRun(agent) {
7533
+ return this.agentRegistry.prepareAgentHeadersForRun(agent);
7534
+ }
7535
+ /**
7205
7536
  * Context management (delegated to ContextStore).
7206
7537
  * Pass `agentIds` to restrict the entry to runs of specific agents;
7207
7538
  * omit it for context every agent should receive.
@@ -7261,17 +7592,21 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
7261
7592
  /**
7262
7593
  * Pushes the current runtime wiring into the memory store. When the runtime
7263
7594
  * is connected and both the intelligence WebSocket URL and runtime URL are
7264
- * available, the store receives a context (runtime URL, WebSocket URL, and a
7265
- * copy of the current headers); otherwise its context is cleared. No-op when
7266
- * the store has not been created yet.
7595
+ * available, the store receives a context (runtime URL, WebSocket URL);
7596
+ * otherwise its context is cleared. No-op when the store has not been
7597
+ * created yet.
7598
+ *
7599
+ * Headers are deliberately NOT part of this context: the store's `fetch` is
7600
+ * `ɵruntimeFetch` (see `ensureMemoryStore`), which already resolves and
7601
+ * overlays the current core headers at send time (#1937) — a header
7602
+ * snapshot copied here would go stale between context syncs.
7267
7603
  */
7268
7604
  syncMemoryContext() {
7269
7605
  var _this$intelligence;
7270
7606
  if (!this._memoryStore) return;
7271
7607
  if (this.runtimeConnectionStatus === CopilotKitCoreRuntimeConnectionStatus.Connected && ((_this$intelligence = this.intelligence) === null || _this$intelligence === void 0 ? void 0 : _this$intelligence.wsUrl) && this.runtimeUrl) this._memoryStore.setContext({
7272
7608
  runtimeUrl: this.runtimeUrl,
7273
- wsUrl: this.intelligence.wsUrl,
7274
- headers: { ...this.headers }
7609
+ wsUrl: this.intelligence.wsUrl
7275
7610
  });
7276
7611
  else this._memoryStore.setContext(null);
7277
7612
  }
@@ -8755,6 +9090,7 @@ exports.ContextStore = ContextStore;
8755
9090
  exports.CopilotKitCore = CopilotKitCore;
8756
9091
  exports.CopilotKitCoreErrorCode = CopilotKitCoreErrorCode;
8757
9092
  exports.CopilotKitCoreRuntimeConnectionStatus = CopilotKitCoreRuntimeConnectionStatus;
9093
+ exports.CopilotKitHeaderResolutionError = CopilotKitHeaderResolutionError;
8758
9094
  exports.INSPECTOR_THREAD_BRIDGE_PLUGIN_ID = INSPECTOR_THREAD_BRIDGE_PLUGIN_ID;
8759
9095
  exports.IntelligenceAgent = IntelligenceAgent;
8760
9096
  exports.MEMORY_ERROR_REGISTRY = MEMORY_ERROR_REGISTRY;
@@ -8828,5 +9164,6 @@ exports.ɵselectThreads = ɵselectThreads;
8828
9164
  exports.ɵselectThreadsError = ɵselectThreadsError;
8829
9165
  exports.ɵselectThreadsIsLoading = ɵselectThreadsIsLoading;
8830
9166
  exports.ɵthreadAdapterEvents = ɵthreadAdapterEvents;
9167
+ exports.ɵwithHeaderDefaults = ɵwithHeaderDefaults;
8831
9168
  });
8832
9169
  //# sourceMappingURL=index.umd.js.map