@copilotkit/core 1.71.2 → 1.72.1-canary.sp-longthread-perf

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.mjs CHANGED
@@ -647,6 +647,13 @@ var ProxiedCopilotRuntimeAgent = class ProxiedCopilotRuntimeAgent extends HttpAg
647
647
  credentials;
648
648
  runtimeAgentId;
649
649
  transport;
650
+ /**
651
+ * The runtime URL exactly as the caller supplied it. `runtimeUrl` is the
652
+ * slash-stripped form used for path joins; the single-route endpoint (run,
653
+ * connect, stop, info envelopes) is this verbatim value, because a trailing
654
+ * slash can select a different proxy location.
655
+ */
656
+ runtimeEndpointUrl;
650
657
  singleEndpointUrl;
651
658
  runtimeMode;
652
659
  intelligence;
@@ -657,13 +664,14 @@ var ProxiedCopilotRuntimeAgent = class ProxiedCopilotRuntimeAgent extends HttpAg
657
664
  const normalizedRuntimeUrl = config.runtimeUrl ? config.runtimeUrl.replace(/\/$/, "") : void 0;
658
665
  const transport = config.transport ?? "auto";
659
666
  const routedId = config.runtimeAgentId ?? config.agentId ?? "";
660
- const runUrl = transport === "single" ? normalizedRuntimeUrl ?? config.runtimeUrl ?? "" : `${normalizedRuntimeUrl ?? config.runtimeUrl}/agent/${encodeURIComponent(routedId)}/run`;
667
+ const runUrl = transport === "single" ? config.runtimeUrl ?? "" : `${normalizedRuntimeUrl ?? config.runtimeUrl}/agent/${encodeURIComponent(routedId)}/run`;
661
668
  if (!runUrl) throw new Error("ProxiedCopilotRuntimeAgent requires a runtimeUrl when transport is set to 'single'.");
662
669
  super({
663
670
  ...config,
664
671
  url: runUrl
665
672
  });
666
673
  this.runtimeUrl = normalizedRuntimeUrl ?? config.runtimeUrl;
674
+ this.runtimeEndpointUrl = config.runtimeUrl;
667
675
  this.credentials = config.credentials;
668
676
  this.runtimeAgentId = config.runtimeAgentId;
669
677
  this.transport = transport;
@@ -671,7 +679,7 @@ var ProxiedCopilotRuntimeAgent = class ProxiedCopilotRuntimeAgent extends HttpAg
671
679
  this.intelligence = config.intelligence;
672
680
  this._capabilities = config.capabilities;
673
681
  if (config.debug) this.debug = config.debug;
674
- if (this.transport === "single") this.singleEndpointUrl = this.runtimeUrl;
682
+ if (this.transport === "single") this.singleEndpointUrl = this.runtimeEndpointUrl;
675
683
  }
676
684
  /**
677
685
  * The agent id used for outbound runtime requests — `runtimeAgentId` when
@@ -826,7 +834,7 @@ var ProxiedCopilotRuntimeAgent = class ProxiedCopilotRuntimeAgent extends HttpAg
826
834
  }
827
835
  clone() {
828
836
  const cloned = new ProxiedCopilotRuntimeAgent({
829
- runtimeUrl: this.runtimeUrl,
837
+ runtimeUrl: this.runtimeEndpointUrl ?? this.runtimeUrl,
830
838
  agentId: this.agentId,
831
839
  runtimeAgentId: this.runtimeAgentId,
832
840
  description: this.description,
@@ -898,7 +906,7 @@ var ProxiedCopilotRuntimeAgent = class ProxiedCopilotRuntimeAgent extends HttpAg
898
906
  if (this.transport === "single") {
899
907
  if (!this.singleEndpointUrl) throw new Error("Single endpoint transport requires a runtimeUrl");
900
908
  if (!headers["Content-Type"]) headers["Content-Type"] = "application/json";
901
- url = this.runtimeUrl;
909
+ url = this.singleEndpointUrl;
902
910
  init = {
903
911
  method: "POST",
904
912
  body: JSON.stringify({ method: "info" })
@@ -928,7 +936,8 @@ var ProxiedCopilotRuntimeAgent = class ProxiedCopilotRuntimeAgent extends HttpAg
928
936
  } catch {}
929
937
  const singleHeaders = { ...headers };
930
938
  if (!singleHeaders["Content-Type"]) singleHeaders["Content-Type"] = "application/json";
931
- const response = await this.fetch(this.runtimeUrl, {
939
+ const endpointUrl = this.runtimeEndpointUrl ?? this.runtimeUrl;
940
+ const response = await this.fetch(endpointUrl, {
932
941
  method: "POST",
933
942
  headers: singleHeaders,
934
943
  body: JSON.stringify({ method: "info" }),
@@ -936,7 +945,7 @@ var ProxiedCopilotRuntimeAgent = class ProxiedCopilotRuntimeAgent extends HttpAg
936
945
  });
937
946
  if (!response.ok) throw await runtimeInfoError(response);
938
947
  this.transport = "single";
939
- this.singleEndpointUrl = this.runtimeUrl;
948
+ this.singleEndpointUrl = endpointUrl;
940
949
  return await response.json();
941
950
  }
942
951
  createSingleRouteRequestInit(input, method, params) {
@@ -1101,6 +1110,8 @@ var AgentRegistry = class {
1101
1110
  remoteAgents = {};
1102
1111
  mintedThreadIds = /* @__PURE__ */ new WeakMap();
1103
1112
  _runtimeUrl;
1113
+ /** The runtime URL as the caller supplied it; the single-route endpoint uses it verbatim. */
1114
+ _runtimeEndpointUrl;
1104
1115
  _connectionInFlight;
1105
1116
  _runtimeConnectionGeneration = 0;
1106
1117
  _activeRuntimeConnectionAttempt;
@@ -1235,7 +1246,8 @@ var AgentRegistry = class {
1235
1246
  */
1236
1247
  setRuntimeUrl(runtimeUrl, options) {
1237
1248
  const normalizedRuntimeUrl = runtimeUrl ? runtimeUrl.replace(/\/$/, "") : void 0;
1238
- if (this._runtimeUrl === normalizedRuntimeUrl) return;
1249
+ const runtimeEndpointUrl = runtimeUrl || void 0;
1250
+ if (this._runtimeUrl === normalizedRuntimeUrl && this._runtimeEndpointUrl === runtimeEndpointUrl) return;
1239
1251
  this.invalidateInspectorMetadataConnection();
1240
1252
  this.abandonRuntimeHealthProbe();
1241
1253
  this.resetRuntimeEntitlementRetry();
@@ -1243,6 +1255,7 @@ var AgentRegistry = class {
1243
1255
  this._runtimeEntitlements = void 0;
1244
1256
  this._singleRouteResourceOperations = false;
1245
1257
  this._runtimeUrl = normalizedRuntimeUrl;
1258
+ this._runtimeEndpointUrl = runtimeEndpointUrl;
1246
1259
  if (options?.deferConnection) return;
1247
1260
  this.updateRuntimeConnection({ preserveOnFailure: this.hasLiveRuntimeKnowledgeToProtect() });
1248
1261
  }
@@ -1361,7 +1374,7 @@ var AgentRegistry = class {
1361
1374
  const friends = this.core;
1362
1375
  const debug = friends.debug;
1363
1376
  const agent = new ProxiedCopilotRuntimeAgent({
1364
- runtimeUrl: this._runtimeUrl,
1377
+ runtimeUrl: this._runtimeEndpointUrl ?? this._runtimeUrl,
1365
1378
  agentId,
1366
1379
  runtimeAgentId,
1367
1380
  transport: this._runtimeTransport,
@@ -1442,7 +1455,7 @@ var AgentRegistry = class {
1442
1455
  const meta = () => runtimeRequestMeta(init);
1443
1456
  const watchdog = this.armRuntimeRequestWatchdog(meta());
1444
1457
  try {
1445
- const singleRouteRequest = this._runtimeTransport === "single" && this._singleRouteResourceOperations && this._runtimeUrl ? await createSingleRouteResourceRequest(input, init, this._runtimeUrl) : null;
1458
+ const singleRouteRequest = this._runtimeTransport === "single" && this._singleRouteResourceOperations && this._runtimeUrl ? await createSingleRouteResourceRequest(input, init, this._runtimeEndpointUrl ?? this._runtimeUrl) : null;
1446
1459
  const response = singleRouteRequest ? await fetch(singleRouteRequest.input, singleRouteRequest.init) : await fetch(input, init);
1447
1460
  watchdog.clear();
1448
1461
  this.handleRuntimeRequestOutcome(response.ok ? "ok" : meta()?.nonCritical ? "ignored" : "failed", watchdog.checked);
@@ -1533,7 +1546,7 @@ var AgentRegistry = class {
1533
1546
  try {
1534
1547
  const request = (async () => {
1535
1548
  const response = resolvedTransport === "single" ? await this.fetchInspectorMetadataSingle({
1536
- runtimeUrl,
1549
+ runtimeUrl: this.singleEndpointUrlFor(runtimeUrl),
1537
1550
  headers,
1538
1551
  credentials,
1539
1552
  signal: abortController.signal
@@ -1730,13 +1743,13 @@ var AgentRegistry = class {
1730
1743
  }
1731
1744
  /** Return the stable key that scopes connection and entitlement retries. */
1732
1745
  runtimeConnectionKey() {
1733
- return `${this._runtimeUrl ?? ""}::${this._requestedTransport}`;
1746
+ return `${this._runtimeEndpointUrl ?? this._runtimeUrl ?? ""}::${this._requestedTransport}`;
1734
1747
  }
1735
1748
  /** Return whether a proxy still targets this Runtime connection. */
1736
1749
  canReuseRuntimeAgent(agent, runtimeUrl, transport) {
1737
1750
  if (!runtimeUrl) return false;
1738
1751
  const connection = this.remoteAgentConnections.get(agent);
1739
- return connection?.runtimeUrl === runtimeUrl.replace(/\/$/, "") && connection.transport === transport;
1752
+ return connection?.runtimeUrl === runtimeUrl.replace(/\/$/, "") && connection.endpointUrl === this._runtimeEndpointUrl && connection.transport === transport;
1740
1753
  }
1741
1754
  /** Return whether an async attempt still owns the active Runtime state. */
1742
1755
  isCurrentRuntimeConnection(attempt) {
@@ -1828,7 +1841,7 @@ var AgentRegistry = class {
1828
1841
  return [id, existing];
1829
1842
  }
1830
1843
  const agent = new ProxiedCopilotRuntimeAgent({
1831
- runtimeUrl,
1844
+ runtimeUrl: this._runtimeEndpointUrl ?? runtimeUrl,
1832
1845
  agentId: id,
1833
1846
  description,
1834
1847
  transport: this._runtimeTransport,
@@ -1848,6 +1861,7 @@ var AgentRegistry = class {
1848
1861
  }
1849
1862
  this.remoteAgentConnections.set(agent, {
1850
1863
  runtimeUrl,
1864
+ endpointUrl: this._runtimeEndpointUrl,
1851
1865
  transport: this._runtimeTransport
1852
1866
  });
1853
1867
  return [id, agent];
@@ -1929,7 +1943,7 @@ var AgentRegistry = class {
1929
1943
  const credentials = this.core.credentials;
1930
1944
  const headers = { ...baseHeaders };
1931
1945
  if (runtimeTransport === "single") return {
1932
- runtimeInfo: await this.fetchRuntimeInfoSingle(runtimeUrl, headers, credentials, signal),
1946
+ runtimeInfo: await this.fetchRuntimeInfoSingle(this.singleEndpointUrlFor(runtimeUrl), headers, credentials, signal),
1933
1947
  resolvedTransport: "single"
1934
1948
  };
1935
1949
  if (runtimeTransport === "auto") return this.fetchRuntimeInfoAutoDetect(runtimeUrl, headers, credentials, signal);
@@ -1944,6 +1958,15 @@ var AgentRegistry = class {
1944
1958
  resolvedTransport: "rest"
1945
1959
  };
1946
1960
  }
1961
+ /**
1962
+ * The URL a single-route request targets: the runtime URL as the caller
1963
+ * supplied it. `runtimeUrl` is the slash-stripped form used for path joins;
1964
+ * a trailing slash can select a different proxy location, so the endpoint
1965
+ * itself keeps it.
1966
+ */
1967
+ singleEndpointUrlFor(runtimeUrl) {
1968
+ return this._runtimeEndpointUrl !== void 0 && this._runtimeUrl === runtimeUrl ? this._runtimeEndpointUrl : runtimeUrl;
1969
+ }
1947
1970
  async fetchRuntimeInfoSingle(runtimeUrl, headers, credentials, signal) {
1948
1971
  const response = await fetch(runtimeUrl, {
1949
1972
  method: "POST",
@@ -1973,7 +1996,7 @@ var AgentRegistry = class {
1973
1996
  };
1974
1997
  } catch {}
1975
1998
  return {
1976
- runtimeInfo: await this.fetchRuntimeInfoSingle(runtimeUrl, { ...headers }, credentials, signal),
1999
+ runtimeInfo: await this.fetchRuntimeInfoSingle(this.singleEndpointUrlFor(runtimeUrl), { ...headers }, credentials, signal),
1977
2000
  resolvedTransport: "single"
1978
2001
  };
1979
2002
  }
@@ -2646,6 +2669,15 @@ var RunHandler = class {
2646
2669
  */
2647
2670
  _disabledToolKeys = /* @__PURE__ */ new Set();
2648
2671
  /**
2672
+ * Registry keys already reported by {@link warnOnMissingToolParameters}.
2673
+ * Development only, and per instance rather than per module so tests and
2674
+ * multiple cores stay independent. Deliberately NOT cleared by
2675
+ * {@link removeTool}: `useFrontendTool` tears down and re-registers on every
2676
+ * dependency change, so clearing it would turn one warning into one per
2677
+ * render. Key = `capabilityKey(name, agentId)`.
2678
+ */
2679
+ _warnedMissingToolParameters = /* @__PURE__ */ new Set();
2680
+ /**
2649
2681
  * Tracks whether the current run (including in-flight tool execution)
2650
2682
  * has been aborted via `stopAgent()` or `agent.abortRun()`. Created
2651
2683
  * fresh in `runAgent()`, aborted by `abortCurrentRun()`.
@@ -2735,6 +2767,7 @@ var RunHandler = class {
2735
2767
  initialize(tools) {
2736
2768
  this._propTools = [...tools];
2737
2769
  this._cachedMergedTools = null;
2770
+ this.warnOnMissingToolParameters(this._propTools);
2738
2771
  this.syncWebMCP();
2739
2772
  }
2740
2773
  /**
@@ -2749,9 +2782,39 @@ var RunHandler = class {
2749
2782
  }
2750
2783
  this._hookTools.set(key, tool);
2751
2784
  this._cachedMergedTools = null;
2785
+ this.warnOnMissingToolParameters([tool]);
2752
2786
  this.syncWebMCP();
2753
2787
  }
2754
2788
  /**
2789
+ * Report, once per tool and at development time only, a tool registered with
2790
+ * no `parameters` schema.
2791
+ *
2792
+ * `createToolSchema` substitutes `{ type: "object", properties: {} }` for a
2793
+ * missing `parameters` and returns silently, and `parameters` is optional on
2794
+ * `FrontendTool`, so nothing — not the compiler, not the runtime — tells the
2795
+ * developer that the model was handed a tool with nothing to fill in. It then
2796
+ * calls the tool with no arguments. `useComponent`, `useFrontendTool` and
2797
+ * `useHumanInTheLoop` all funnel into {@link addTool}; the provider's `tools`
2798
+ * prop funnels into {@link initialize} and {@link setTools}.
2799
+ *
2800
+ * A parameterless tool is legitimate (a HITL confirm dialog, say), so this
2801
+ * stays a warning rather than an error. An explicit empty schema
2802
+ * (`parameters: z.object({})`) is the way to say "takes none on purpose": it
2803
+ * satisfies the check below and `createToolSchema` reduces it to the same
2804
+ * advertised `{ type: "object", properties: {} }` that omitting `parameters`
2805
+ * produces, so silencing the warning costs nothing on the wire.
2806
+ */
2807
+ warnOnMissingToolParameters(tools) {
2808
+ if (process.env.NODE_ENV === "production") return;
2809
+ for (const tool of tools) {
2810
+ if (tool.parameters) continue;
2811
+ const key = this.capabilityKey(tool.name, tool.agentId);
2812
+ if (this._warnedMissingToolParameters.has(key)) continue;
2813
+ this._warnedMissingToolParameters.add(key);
2814
+ logger.warn(`Tool has no parameters schema: '${tool.name}' for agent '${tool.agentId || "global"}'. The model is told it takes no arguments and will call it with none. Add \`parameters\` (a Zod or Standard Schema object) if it should receive arguments, or \`parameters: z.object({})\` to declare that it takes none and silence this warning.`);
2815
+ }
2816
+ }
2817
+ /**
2755
2818
  * Remove a tool by name and optionally by agentId
2756
2819
  */
2757
2820
  removeTool(id, agentId) {
@@ -2784,6 +2847,7 @@ var RunHandler = class {
2784
2847
  setTools(tools) {
2785
2848
  this._propTools = [...tools];
2786
2849
  this._cachedMergedTools = null;
2850
+ this.warnOnMissingToolParameters(this._propTools);
2787
2851
  this.syncWebMCP();
2788
2852
  }
2789
2853
  /**