@copilotkit/core 1.69.3 → 1.70.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 +492 -102
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +90 -6
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +90 -6
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +491 -103
- package/dist/index.mjs.map +1 -1
- package/dist/index.umd.js +476 -103
- package/dist/index.umd.js.map +1 -1
- package/package.json +4 -3
package/dist/index.cjs
CHANGED
|
@@ -127,6 +127,7 @@ function ɵobservePhoenixSocketHealth$(socketSignals$, maxConsecutiveErrors) {
|
|
|
127
127
|
|
|
128
128
|
//#endregion
|
|
129
129
|
//#region src/intelligence-agent.ts
|
|
130
|
+
const globalFetch = (...args) => fetch(...args);
|
|
130
131
|
const CLIENT_AG_UI_EVENT = "ag_ui_event";
|
|
131
132
|
const REPLAY_COMPLETE_EVENT = "replay_complete";
|
|
132
133
|
const STREAM_IDLE_EVENT = "stream_idle";
|
|
@@ -353,7 +354,7 @@ var IntelligenceAgent = class IntelligenceAgent extends _ag_ui_client.AbstractAg
|
|
|
353
354
|
requestJoinCredentials$(mode, input, replayCursor) {
|
|
354
355
|
return (0, rxjs.defer)(async () => {
|
|
355
356
|
try {
|
|
356
|
-
const response = await fetch(this.buildRuntimeUrl(mode), {
|
|
357
|
+
const response = await (this.config.fetch ?? globalFetch)(this.buildRuntimeUrl(mode), {
|
|
357
358
|
method: "POST",
|
|
358
359
|
headers: {
|
|
359
360
|
"Content-Type": "application/json",
|
|
@@ -594,7 +595,12 @@ async function runtimeInfoError(response) {
|
|
|
594
595
|
const message = (await response.clone().json())?.message;
|
|
595
596
|
if (typeof message === "string" && message.trim().length > 0) detail = message.trim();
|
|
596
597
|
} catch {}
|
|
597
|
-
|
|
598
|
+
const error = new Error(detail ? `${base}: ${detail}` : base);
|
|
599
|
+
error.runtimeInfoStatus = response.status;
|
|
600
|
+
return error;
|
|
601
|
+
}
|
|
602
|
+
function isRuntimeInfoRequestError(error) {
|
|
603
|
+
return typeof error === "object" && error !== null && typeof error.runtimeInfoStatus === "number";
|
|
598
604
|
}
|
|
599
605
|
|
|
600
606
|
//#endregion
|
|
@@ -608,12 +614,12 @@ function hasCredentials(agent) {
|
|
|
608
614
|
function isZodError(error) {
|
|
609
615
|
return error !== null && typeof error === "object" && "name" in error && error.name === "ZodError";
|
|
610
616
|
}
|
|
611
|
-
function isAbortError$
|
|
617
|
+
function isAbortError$2(error) {
|
|
612
618
|
return (error instanceof DOMException || error instanceof Error) && error.name === "AbortError";
|
|
613
619
|
}
|
|
614
620
|
function withAbortErrorHandling(observable) {
|
|
615
621
|
return observable.pipe((0, rxjs_operators.catchError)((error) => {
|
|
616
|
-
if (isZodError(error) || isAbortError$
|
|
622
|
+
if (isZodError(error) || isAbortError$2(error)) return rxjs.EMPTY;
|
|
617
623
|
throw error;
|
|
618
624
|
}));
|
|
619
625
|
}
|
|
@@ -811,7 +817,8 @@ var ProxiedCopilotRuntimeAgent = class ProxiedCopilotRuntimeAgent extends _ag_ui
|
|
|
811
817
|
runtimeMode: this.runtimeMode,
|
|
812
818
|
intelligence: this.intelligence,
|
|
813
819
|
capabilities: this._capabilities,
|
|
814
|
-
debug: this.debug
|
|
820
|
+
debug: this.debug,
|
|
821
|
+
fetch: this.fetch
|
|
815
822
|
});
|
|
816
823
|
cloned.threadId = this.threadId;
|
|
817
824
|
cloned.setState(this.state);
|
|
@@ -881,7 +888,7 @@ var ProxiedCopilotRuntimeAgent = class ProxiedCopilotRuntimeAgent extends _ag_ui
|
|
|
881
888
|
url = `${this.runtimeUrl}/info`;
|
|
882
889
|
init = {};
|
|
883
890
|
}
|
|
884
|
-
const response = await fetch(url, {
|
|
891
|
+
const response = await this.fetch(url, {
|
|
885
892
|
...init,
|
|
886
893
|
headers,
|
|
887
894
|
...this.credentials ? { credentials: this.credentials } : {}
|
|
@@ -891,7 +898,7 @@ var ProxiedCopilotRuntimeAgent = class ProxiedCopilotRuntimeAgent extends _ag_ui
|
|
|
891
898
|
}
|
|
892
899
|
async fetchRuntimeInfoAutoDetect(headers) {
|
|
893
900
|
try {
|
|
894
|
-
const response = await fetch(`${this.runtimeUrl}/info`, {
|
|
901
|
+
const response = await this.fetch(`${this.runtimeUrl}/info`, {
|
|
895
902
|
headers: { ...headers },
|
|
896
903
|
...this.credentials ? { credentials: this.credentials } : {}
|
|
897
904
|
});
|
|
@@ -902,7 +909,7 @@ var ProxiedCopilotRuntimeAgent = class ProxiedCopilotRuntimeAgent extends _ag_ui
|
|
|
902
909
|
} catch {}
|
|
903
910
|
const singleHeaders = { ...headers };
|
|
904
911
|
if (!singleHeaders["Content-Type"]) singleHeaders["Content-Type"] = "application/json";
|
|
905
|
-
const response = await fetch(this.runtimeUrl, {
|
|
912
|
+
const response = await this.fetch(this.runtimeUrl, {
|
|
906
913
|
method: "POST",
|
|
907
914
|
headers: singleHeaders,
|
|
908
915
|
body: JSON.stringify({ method: "info" }),
|
|
@@ -943,7 +950,8 @@ var ProxiedCopilotRuntimeAgent = class ProxiedCopilotRuntimeAgent extends _ag_ui
|
|
|
943
950
|
runtimeUrl: this.runtimeUrl,
|
|
944
951
|
agentId: routedId,
|
|
945
952
|
headers: { ...this.headers },
|
|
946
|
-
credentials: this.credentials
|
|
953
|
+
credentials: this.credentials,
|
|
954
|
+
fetch: this.fetch
|
|
947
955
|
});
|
|
948
956
|
}
|
|
949
957
|
syncDelegate(delegate) {
|
|
@@ -957,16 +965,44 @@ var ProxiedCopilotRuntimeAgent = class ProxiedCopilotRuntimeAgent extends _ag_ui
|
|
|
957
965
|
}
|
|
958
966
|
};
|
|
959
967
|
|
|
968
|
+
//#endregion
|
|
969
|
+
//#region src/utils/abort-error.ts
|
|
970
|
+
const ABORT_MESSAGES = new Set([
|
|
971
|
+
"Fetch is aborted",
|
|
972
|
+
"signal is aborted without reason",
|
|
973
|
+
"component unmounted"
|
|
974
|
+
]);
|
|
975
|
+
function isAbortError$1(error) {
|
|
976
|
+
if (typeof error !== "object" || error === null) return false;
|
|
977
|
+
const { name, message } = error;
|
|
978
|
+
if (name === "AbortError") return true;
|
|
979
|
+
return typeof message === "string" && ABORT_MESSAGES.has(message);
|
|
980
|
+
}
|
|
981
|
+
|
|
982
|
+
//#endregion
|
|
983
|
+
//#region src/utils/runtime-request.ts
|
|
984
|
+
const RUNTIME_REQUEST_WATCHDOG_MS = 1e4;
|
|
985
|
+
function runtimeRequestMeta(init) {
|
|
986
|
+
return init?.ɵruntimeRequest;
|
|
987
|
+
}
|
|
988
|
+
|
|
960
989
|
//#endregion
|
|
961
990
|
//#region src/core/agent-registry.ts
|
|
962
991
|
/** Maximum wait for optional Inspector metadata before degrading to absence. */
|
|
963
992
|
const INSPECTOR_METADATA_REQUEST_TIMEOUT_MS = 5e3;
|
|
993
|
+
const ɵRUNTIME_PROBE_TIMEOUT_MS = 5e3;
|
|
994
|
+
function classifyRuntimeRequestFailure(error, meta) {
|
|
995
|
+
if (meta?.nonCritical) return "ignored";
|
|
996
|
+
if (isAbortError$1(error) && !meta?.timedOut) return "aborted";
|
|
997
|
+
return "failed";
|
|
998
|
+
}
|
|
964
999
|
/** Build case-insensitive JSON headers without mutating the Core snapshot. */
|
|
965
1000
|
function withJsonContentType(headers) {
|
|
966
1001
|
const requestHeaders = new Headers(headers);
|
|
967
1002
|
if (!requestHeaders.has("content-type")) requestHeaders.set("content-type", "application/json");
|
|
968
1003
|
return requestHeaders;
|
|
969
1004
|
}
|
|
1005
|
+
const RUNTIME_ENTITLEMENT_RETRY_DELAY_MS = 5e3;
|
|
970
1006
|
/**
|
|
971
1007
|
* Manages agent registration, lifecycle, and runtime connectivity for CopilotKitCore.
|
|
972
1008
|
* Handles both local development agents and remote runtime agents.
|
|
@@ -975,8 +1011,14 @@ var AgentRegistry = class {
|
|
|
975
1011
|
_agents = {};
|
|
976
1012
|
localAgents = {};
|
|
977
1013
|
remoteAgents = {};
|
|
1014
|
+
mintedThreadIds = /* @__PURE__ */ new WeakMap();
|
|
978
1015
|
_runtimeUrl;
|
|
979
1016
|
_connectionInFlight;
|
|
1017
|
+
_runtimeConnectionGeneration = 0;
|
|
1018
|
+
_activeRuntimeConnectionAttempt;
|
|
1019
|
+
_runtimeEntitlementRetryTimer;
|
|
1020
|
+
_runtimeEntitlementRetryAttemptedKey;
|
|
1021
|
+
_runtimeEntitlementRetryPendingKey;
|
|
980
1022
|
_runtimeVersion;
|
|
981
1023
|
_runtimeConnectionStatus = CopilotKitCoreRuntimeConnectionStatus.Disconnected;
|
|
982
1024
|
_runtimeTransport = "auto";
|
|
@@ -999,7 +1041,16 @@ var AgentRegistry = class {
|
|
|
999
1041
|
_a2uiAgents;
|
|
1000
1042
|
_openGenerativeUIEnabled = false;
|
|
1001
1043
|
_licenseStatus;
|
|
1044
|
+
_runtimeEntitlements;
|
|
1002
1045
|
_telemetryDisabled = false;
|
|
1046
|
+
remoteAgentConnections = /* @__PURE__ */ new WeakMap();
|
|
1047
|
+
runtimeFetch;
|
|
1048
|
+
runtimeProbeInFlight = false;
|
|
1049
|
+
runtimeProbeToken = 0;
|
|
1050
|
+
runtimeProbeAbortController;
|
|
1051
|
+
runtimeRecoveryRunning = false;
|
|
1052
|
+
runtimeRecoveryPending = false;
|
|
1053
|
+
runtimeHealthGeneration = 0;
|
|
1003
1054
|
/**
|
|
1004
1055
|
* The headers each HttpAgent was constructed with, captured on the first
|
|
1005
1056
|
* `applyHeadersToAgent` call for that agent (which, for agents the registry
|
|
@@ -1066,6 +1117,13 @@ var AgentRegistry = class {
|
|
|
1066
1117
|
get licenseStatus() {
|
|
1067
1118
|
return this._licenseStatus;
|
|
1068
1119
|
}
|
|
1120
|
+
/** Structured Runtime entitlement authority advertised by `/info`. */
|
|
1121
|
+
get runtimeEntitlements() {
|
|
1122
|
+
return this._runtimeEntitlements;
|
|
1123
|
+
}
|
|
1124
|
+
get runtimeEntitlementRetryPending() {
|
|
1125
|
+
return this._runtimeEntitlementRetryPendingKey === this.runtimeConnectionKey();
|
|
1126
|
+
}
|
|
1069
1127
|
get telemetryDisabled() {
|
|
1070
1128
|
return this._telemetryDisabled;
|
|
1071
1129
|
}
|
|
@@ -1076,6 +1134,7 @@ var AgentRegistry = class {
|
|
|
1076
1134
|
this.localAgents = this.assignAgentIds(agents);
|
|
1077
1135
|
this.applyHeadersToAgents(this.localAgents);
|
|
1078
1136
|
this.applyCredentialsToAgents(this.localAgents);
|
|
1137
|
+
this.applyRuntimeFetchToAgents(this.localAgents);
|
|
1079
1138
|
this._agents = this.localAgents;
|
|
1080
1139
|
}
|
|
1081
1140
|
/**
|
|
@@ -1085,9 +1144,13 @@ var AgentRegistry = class {
|
|
|
1085
1144
|
const normalizedRuntimeUrl = runtimeUrl ? runtimeUrl.replace(/\/$/, "") : void 0;
|
|
1086
1145
|
if (this._runtimeUrl === normalizedRuntimeUrl) return;
|
|
1087
1146
|
this.invalidateInspectorMetadataConnection();
|
|
1147
|
+
this.abandonRuntimeHealthProbe();
|
|
1148
|
+
this.resetRuntimeEntitlementRetry();
|
|
1149
|
+
this._licenseStatus = void 0;
|
|
1150
|
+
this._runtimeEntitlements = void 0;
|
|
1088
1151
|
this._runtimeUrl = normalizedRuntimeUrl;
|
|
1089
1152
|
if (options?.deferConnection) return;
|
|
1090
|
-
this.updateRuntimeConnection();
|
|
1153
|
+
this.updateRuntimeConnection({ preserveOnFailure: this.hasLiveRuntimeKnowledgeToProtect() });
|
|
1091
1154
|
}
|
|
1092
1155
|
/**
|
|
1093
1156
|
* Start the initial runtime connection if it has not been started yet.
|
|
@@ -1109,9 +1172,40 @@ var AgentRegistry = class {
|
|
|
1109
1172
|
setRuntimeTransport(runtimeTransport) {
|
|
1110
1173
|
if (this._requestedTransport === runtimeTransport) return;
|
|
1111
1174
|
this.invalidateInspectorMetadataConnection();
|
|
1175
|
+
this.abandonRuntimeHealthProbe();
|
|
1176
|
+
this.resetRuntimeEntitlementRetry();
|
|
1112
1177
|
this._requestedTransport = runtimeTransport;
|
|
1113
1178
|
this._runtimeTransport = runtimeTransport;
|
|
1114
|
-
this.updateRuntimeConnection();
|
|
1179
|
+
this.updateRuntimeConnection({ preserveOnFailure: this.hasLiveRuntimeKnowledgeToProtect() });
|
|
1180
|
+
}
|
|
1181
|
+
hasLiveRuntimeKnowledgeToProtect() {
|
|
1182
|
+
if (Object.keys(this.remoteAgents).length === 0) return false;
|
|
1183
|
+
return this._runtimeConnectionStatus !== CopilotKitCoreRuntimeConnectionStatus.Connected;
|
|
1184
|
+
}
|
|
1185
|
+
reconcileRecoveredAgents(reported) {
|
|
1186
|
+
const merged = {
|
|
1187
|
+
...this.remoteAgents,
|
|
1188
|
+
...reported
|
|
1189
|
+
};
|
|
1190
|
+
if (Object.keys(reported).length === 0) return merged;
|
|
1191
|
+
for (const [id, agent] of Object.entries(merged)) {
|
|
1192
|
+
if (Object.prototype.hasOwnProperty.call(reported, id)) continue;
|
|
1193
|
+
if (this.carriesConversationState(agent)) continue;
|
|
1194
|
+
delete merged[id];
|
|
1195
|
+
}
|
|
1196
|
+
return merged;
|
|
1197
|
+
}
|
|
1198
|
+
carriesConversationState(agent) {
|
|
1199
|
+
if (agent.messages.length > 0) return true;
|
|
1200
|
+
const mintedThreadId = this.mintedThreadIds.get(agent);
|
|
1201
|
+
return mintedThreadId === void 0 || agent.threadId !== mintedThreadId;
|
|
1202
|
+
}
|
|
1203
|
+
abandonRuntimeHealthProbe() {
|
|
1204
|
+
this.runtimeProbeToken += 1;
|
|
1205
|
+
this.runtimeProbeInFlight = false;
|
|
1206
|
+
this.runtimeHealthGeneration += 1;
|
|
1207
|
+
this.runtimeProbeAbortController?.abort();
|
|
1208
|
+
this.runtimeProbeAbortController = void 0;
|
|
1115
1209
|
}
|
|
1116
1210
|
/**
|
|
1117
1211
|
* Set all agents at once (for development use)
|
|
@@ -1127,6 +1221,7 @@ var AgentRegistry = class {
|
|
|
1127
1221
|
};
|
|
1128
1222
|
this.applyHeadersToAgents(this._agents);
|
|
1129
1223
|
this.applyCredentialsToAgents(this._agents);
|
|
1224
|
+
this.applyRuntimeFetchToAgents(this._agents);
|
|
1130
1225
|
this.notifyAgentsChanged();
|
|
1131
1226
|
}
|
|
1132
1227
|
/**
|
|
@@ -1137,6 +1232,7 @@ var AgentRegistry = class {
|
|
|
1137
1232
|
this.localAgents[id] = agent;
|
|
1138
1233
|
this.applyHeadersToAgent(agent);
|
|
1139
1234
|
this.applyCredentialsToAgent(agent);
|
|
1235
|
+
this.applyRuntimeFetchToAgent(agent);
|
|
1140
1236
|
this._agents = {
|
|
1141
1237
|
...this.localAgents,
|
|
1142
1238
|
...this.remoteAgents
|
|
@@ -1180,6 +1276,7 @@ var AgentRegistry = class {
|
|
|
1180
1276
|
debug: debug ? (0, _copilotkit_shared.resolveDebugConfig)(debug) : void 0
|
|
1181
1277
|
});
|
|
1182
1278
|
this.applyHeadersToAgent(agent);
|
|
1279
|
+
this.applyRuntimeFetchToAgent(agent);
|
|
1183
1280
|
this.localAgents[agentId] = agent;
|
|
1184
1281
|
this._agents = {
|
|
1185
1282
|
...this.localAgents,
|
|
@@ -1245,6 +1342,45 @@ var AgentRegistry = class {
|
|
|
1245
1342
|
this.applyCredentialsToAgent(agent);
|
|
1246
1343
|
});
|
|
1247
1344
|
}
|
|
1345
|
+
createRuntimeFetch() {
|
|
1346
|
+
if (!this.runtimeFetch) this.runtimeFetch = (async (input, init) => {
|
|
1347
|
+
const meta = () => runtimeRequestMeta(init);
|
|
1348
|
+
const watchdog = this.armRuntimeRequestWatchdog(meta());
|
|
1349
|
+
try {
|
|
1350
|
+
const response = await fetch(input, init);
|
|
1351
|
+
watchdog.clear();
|
|
1352
|
+
this.handleRuntimeRequestOutcome(response.ok ? "ok" : meta()?.nonCritical ? "ignored" : "failed", watchdog.checked);
|
|
1353
|
+
return response;
|
|
1354
|
+
} catch (error) {
|
|
1355
|
+
watchdog.clear();
|
|
1356
|
+
this.handleRuntimeRequestOutcome(classifyRuntimeRequestFailure(error, meta()), watchdog.checked);
|
|
1357
|
+
throw error;
|
|
1358
|
+
}
|
|
1359
|
+
});
|
|
1360
|
+
return this.runtimeFetch;
|
|
1361
|
+
}
|
|
1362
|
+
armRuntimeRequestWatchdog(meta) {
|
|
1363
|
+
if (typeof window === "undefined" || meta?.nonCritical || meta?.selfBounded) return {
|
|
1364
|
+
clear: () => {},
|
|
1365
|
+
checked: () => false
|
|
1366
|
+
};
|
|
1367
|
+
let checked = false;
|
|
1368
|
+
const timeoutId = setTimeout(() => {
|
|
1369
|
+
checked = this.handleRuntimeRequestOutcome("failed");
|
|
1370
|
+
}, RUNTIME_REQUEST_WATCHDOG_MS);
|
|
1371
|
+
return {
|
|
1372
|
+
clear: () => clearTimeout(timeoutId),
|
|
1373
|
+
checked: () => checked
|
|
1374
|
+
};
|
|
1375
|
+
}
|
|
1376
|
+
applyRuntimeFetchToAgent(agent) {
|
|
1377
|
+
if (agent instanceof ProxiedCopilotRuntimeAgent) agent.fetch = this.createRuntimeFetch();
|
|
1378
|
+
}
|
|
1379
|
+
applyRuntimeFetchToAgents(agents) {
|
|
1380
|
+
Object.values(agents).forEach((agent) => {
|
|
1381
|
+
this.applyRuntimeFetchToAgent(agent);
|
|
1382
|
+
});
|
|
1383
|
+
}
|
|
1248
1384
|
/** Refresh metadata after the Core header snapshot changes. */
|
|
1249
1385
|
handleHeadersChanged() {
|
|
1250
1386
|
this.inspectorMetadataHeadersGeneration += 1;
|
|
@@ -1380,17 +1516,114 @@ var AgentRegistry = class {
|
|
|
1380
1516
|
console.error("Subscriber onInspectorMetadataChanged queue error:", error);
|
|
1381
1517
|
});
|
|
1382
1518
|
}
|
|
1519
|
+
setRuntimeConnectionStatus(status) {
|
|
1520
|
+
this._runtimeConnectionStatus = status;
|
|
1521
|
+
this.runtimeHealthGeneration += 1;
|
|
1522
|
+
}
|
|
1523
|
+
handleRuntimeRequestOutcome(outcome, alreadyChecked = () => false) {
|
|
1524
|
+
if (outcome === "aborted" || outcome === "ignored") return false;
|
|
1525
|
+
if (outcome === "failed" && alreadyChecked()) return false;
|
|
1526
|
+
if (typeof window === "undefined") return false;
|
|
1527
|
+
if (!this._runtimeUrl) return false;
|
|
1528
|
+
if (outcome === "ok") {
|
|
1529
|
+
this.runtimeHealthGeneration += 1;
|
|
1530
|
+
if (this.runtimeRecoveryRunning) this.runtimeRecoveryPending = true;
|
|
1531
|
+
if (this._runtimeConnectionStatus === CopilotKitCoreRuntimeConnectionStatus.Error) this.recoverRuntimeConnection();
|
|
1532
|
+
return false;
|
|
1533
|
+
}
|
|
1534
|
+
if (this._runtimeConnectionStatus !== CopilotKitCoreRuntimeConnectionStatus.Connected) return false;
|
|
1535
|
+
if (this.runtimeProbeInFlight) return false;
|
|
1536
|
+
this.probeRuntimeReachability();
|
|
1537
|
+
return true;
|
|
1538
|
+
}
|
|
1539
|
+
async fetchRuntimeInfoWithTimeout(abortController, runtimeUrl = this.runtimeUrl, runtimeTransport = this._runtimeTransport) {
|
|
1540
|
+
if (!runtimeUrl) throw new Error("Runtime URL is not set");
|
|
1541
|
+
let timeoutId;
|
|
1542
|
+
const request = this.fetchRuntimeInfo(runtimeUrl, runtimeTransport, abortController.signal);
|
|
1543
|
+
request.catch(() => {});
|
|
1544
|
+
try {
|
|
1545
|
+
const timedOut = new Promise((_resolve, reject) => {
|
|
1546
|
+
timeoutId = setTimeout(() => {
|
|
1547
|
+
abortController.abort();
|
|
1548
|
+
reject(/* @__PURE__ */ new Error(`Runtime did not answer within ${ɵRUNTIME_PROBE_TIMEOUT_MS}ms`));
|
|
1549
|
+
}, ɵRUNTIME_PROBE_TIMEOUT_MS);
|
|
1550
|
+
});
|
|
1551
|
+
return await Promise.race([request, timedOut]);
|
|
1552
|
+
} finally {
|
|
1553
|
+
if (timeoutId !== void 0) clearTimeout(timeoutId);
|
|
1554
|
+
}
|
|
1555
|
+
}
|
|
1556
|
+
async probeRuntimeReachability() {
|
|
1557
|
+
const generation = this.runtimeHealthGeneration;
|
|
1558
|
+
const token = ++this.runtimeProbeToken;
|
|
1559
|
+
this.runtimeProbeInFlight = true;
|
|
1560
|
+
const abortController = new AbortController();
|
|
1561
|
+
this.runtimeProbeAbortController = abortController;
|
|
1562
|
+
try {
|
|
1563
|
+
await this.fetchRuntimeInfoWithTimeout(abortController);
|
|
1564
|
+
} catch (error) {
|
|
1565
|
+
if (generation !== this.runtimeHealthGeneration) return;
|
|
1566
|
+
await this.markRuntimeUnreachable(error instanceof Error ? error : new Error(String(error)));
|
|
1567
|
+
} finally {
|
|
1568
|
+
if (this.runtimeProbeAbortController === abortController) this.runtimeProbeAbortController = void 0;
|
|
1569
|
+
if (this.runtimeProbeToken === token) this.runtimeProbeInFlight = false;
|
|
1570
|
+
}
|
|
1571
|
+
}
|
|
1572
|
+
async markRuntimeUnreachable(error) {
|
|
1573
|
+
this.setRuntimeConnectionStatus(CopilotKitCoreRuntimeConnectionStatus.Error);
|
|
1574
|
+
await this.notifyRuntimeStatusChanged(CopilotKitCoreRuntimeConnectionStatus.Error);
|
|
1575
|
+
const runtimeStatus = isRuntimeInfoRequestError(error) ? error.runtimeInfoStatus : void 0;
|
|
1576
|
+
_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.`);
|
|
1577
|
+
await this.core.emitError({
|
|
1578
|
+
error,
|
|
1579
|
+
code: CopilotKitCoreErrorCode.RUNTIME_INFO_FETCH_FAILED,
|
|
1580
|
+
context: {
|
|
1581
|
+
runtimeUrl: this._runtimeUrl,
|
|
1582
|
+
reason: runtimeStatus === void 0 ? "no-answer" : "answered",
|
|
1583
|
+
...runtimeStatus === void 0 ? {} : { runtimeStatus }
|
|
1584
|
+
}
|
|
1585
|
+
});
|
|
1586
|
+
}
|
|
1587
|
+
async recoverRuntimeConnection() {
|
|
1588
|
+
if (this.runtimeRecoveryRunning) {
|
|
1589
|
+
this.runtimeRecoveryPending = true;
|
|
1590
|
+
return;
|
|
1591
|
+
}
|
|
1592
|
+
this.runtimeRecoveryRunning = true;
|
|
1593
|
+
try {
|
|
1594
|
+
do {
|
|
1595
|
+
this.runtimeRecoveryPending = false;
|
|
1596
|
+
await this.updateRuntimeConnection({
|
|
1597
|
+
preserveOnFailure: true,
|
|
1598
|
+
recovery: true
|
|
1599
|
+
});
|
|
1600
|
+
} while (this.runtimeRecoveryPending && this._runtimeConnectionStatus !== CopilotKitCoreRuntimeConnectionStatus.Connected);
|
|
1601
|
+
} finally {
|
|
1602
|
+
this.runtimeRecoveryRunning = false;
|
|
1603
|
+
this.runtimeRecoveryPending = false;
|
|
1604
|
+
}
|
|
1605
|
+
}
|
|
1383
1606
|
/**
|
|
1384
1607
|
* Update runtime connection and fetch remote agents
|
|
1385
1608
|
*/
|
|
1386
|
-
async updateRuntimeConnection() {
|
|
1609
|
+
async updateRuntimeConnection(options) {
|
|
1387
1610
|
if (typeof window === "undefined") return;
|
|
1388
|
-
const key =
|
|
1611
|
+
const key = this.runtimeConnectionKey();
|
|
1389
1612
|
const inFlight = this._connectionInFlight;
|
|
1390
|
-
if (inFlight && inFlight.key === key) return inFlight.promise;
|
|
1391
|
-
const
|
|
1392
|
-
this._connectionInFlight = {
|
|
1613
|
+
if (inFlight && inFlight.attempt.key === key && this.isCurrentRuntimeConnection(inFlight.attempt)) return inFlight.promise;
|
|
1614
|
+
const attempt = {
|
|
1393
1615
|
key,
|
|
1616
|
+
generation: ++this._runtimeConnectionGeneration
|
|
1617
|
+
};
|
|
1618
|
+
this._activeRuntimeConnectionAttempt = attempt;
|
|
1619
|
+
const promise = this.performRuntimeConnection({
|
|
1620
|
+
attempt,
|
|
1621
|
+
runtimeUrl: this._runtimeUrl,
|
|
1622
|
+
transport: this._runtimeTransport,
|
|
1623
|
+
options
|
|
1624
|
+
});
|
|
1625
|
+
this._connectionInFlight = {
|
|
1626
|
+
attempt,
|
|
1394
1627
|
promise
|
|
1395
1628
|
};
|
|
1396
1629
|
promise.finally(() => {
|
|
@@ -1398,10 +1631,64 @@ var AgentRegistry = class {
|
|
|
1398
1631
|
});
|
|
1399
1632
|
return promise;
|
|
1400
1633
|
}
|
|
1401
|
-
|
|
1402
|
-
|
|
1634
|
+
/** Return the stable key that scopes connection and entitlement retries. */
|
|
1635
|
+
runtimeConnectionKey() {
|
|
1636
|
+
return `${this._runtimeUrl ?? ""}::${this._requestedTransport}`;
|
|
1637
|
+
}
|
|
1638
|
+
/** Return whether a proxy still targets this Runtime connection. */
|
|
1639
|
+
canReuseRuntimeAgent(agent, runtimeUrl, transport) {
|
|
1640
|
+
if (!runtimeUrl) return false;
|
|
1641
|
+
const connection = this.remoteAgentConnections.get(agent);
|
|
1642
|
+
return connection?.runtimeUrl === runtimeUrl.replace(/\/$/, "") && connection.transport === transport;
|
|
1643
|
+
}
|
|
1644
|
+
/** Return whether an async attempt still owns the active Runtime state. */
|
|
1645
|
+
isCurrentRuntimeConnection(attempt) {
|
|
1646
|
+
return this._activeRuntimeConnectionAttempt?.generation === attempt.generation && this.runtimeConnectionKey() === attempt.key;
|
|
1647
|
+
}
|
|
1648
|
+
/** Cancel a pending entitlement retry and allow a new target to retry. */
|
|
1649
|
+
resetRuntimeEntitlementRetry() {
|
|
1650
|
+
if (this._runtimeEntitlementRetryTimer !== void 0) {
|
|
1651
|
+
clearTimeout(this._runtimeEntitlementRetryTimer);
|
|
1652
|
+
this._runtimeEntitlementRetryTimer = void 0;
|
|
1653
|
+
}
|
|
1654
|
+
this._runtimeEntitlementRetryAttemptedKey = void 0;
|
|
1655
|
+
this._runtimeEntitlementRetryPendingKey = void 0;
|
|
1656
|
+
}
|
|
1657
|
+
/** Schedule one retry after Runtime's short failed-entitlement cache. */
|
|
1658
|
+
updateRuntimeEntitlementRetry(runtimeEntitlements, attempt) {
|
|
1659
|
+
if (!this.isCurrentRuntimeConnection(attempt)) return;
|
|
1660
|
+
const { key } = attempt;
|
|
1661
|
+
if (runtimeEntitlements?.status === "ready" || runtimeEntitlements?.error.retryable !== true) {
|
|
1662
|
+
this.resetRuntimeEntitlementRetry();
|
|
1663
|
+
return;
|
|
1664
|
+
}
|
|
1665
|
+
if (this._runtimeEntitlementRetryTimer !== void 0) return;
|
|
1666
|
+
if (this._runtimeEntitlementRetryAttemptedKey === key) {
|
|
1667
|
+
this._runtimeEntitlementRetryPendingKey = void 0;
|
|
1668
|
+
return;
|
|
1669
|
+
}
|
|
1670
|
+
this._runtimeEntitlementRetryAttemptedKey = key;
|
|
1671
|
+
this._runtimeEntitlementRetryPendingKey = key;
|
|
1672
|
+
this._runtimeEntitlementRetryTimer = setTimeout(() => {
|
|
1673
|
+
this._runtimeEntitlementRetryTimer = void 0;
|
|
1674
|
+
this.executeRuntimeEntitlementRetry(attempt).catch((error) => {
|
|
1675
|
+
const message = error instanceof Error ? error.message : JSON.stringify(error);
|
|
1676
|
+
_copilotkit_shared.logger.warn(`Failed to retry runtime info (${this.runtimeUrl}/info): ${message}`);
|
|
1677
|
+
});
|
|
1678
|
+
}, RUNTIME_ENTITLEMENT_RETRY_DELAY_MS);
|
|
1679
|
+
}
|
|
1680
|
+
/** Start the bounded retry after the original connection has settled. */
|
|
1681
|
+
async executeRuntimeEntitlementRetry(attempt) {
|
|
1682
|
+
const inFlight = this._connectionInFlight;
|
|
1683
|
+
if (inFlight?.attempt.generation === attempt.generation) await inFlight.promise;
|
|
1684
|
+
if (!this._runtimeUrl || !this.isCurrentRuntimeConnection(attempt)) return;
|
|
1685
|
+
await this.updateRuntimeConnection();
|
|
1686
|
+
}
|
|
1687
|
+
async performRuntimeConnection({ attempt, runtimeUrl, transport, options }) {
|
|
1688
|
+
const { key } = attempt;
|
|
1689
|
+
if (!runtimeUrl) {
|
|
1403
1690
|
this.invalidateInspectorMetadataConnection();
|
|
1404
|
-
this.
|
|
1691
|
+
this.setRuntimeConnectionStatus(CopilotKitCoreRuntimeConnectionStatus.Disconnected);
|
|
1405
1692
|
this._runtimeVersion = void 0;
|
|
1406
1693
|
this._audioFileTranscriptionEnabled = false;
|
|
1407
1694
|
this._runtimeMode = _copilotkit_shared.RUNTIME_MODE_SSE;
|
|
@@ -1411,32 +1698,38 @@ var AgentRegistry = class {
|
|
|
1411
1698
|
this._a2uiEnabled = false;
|
|
1412
1699
|
this._a2uiAgents = void 0;
|
|
1413
1700
|
this._openGenerativeUIEnabled = false;
|
|
1701
|
+
this._licenseStatus = void 0;
|
|
1702
|
+
this._runtimeEntitlements = void 0;
|
|
1414
1703
|
this.remoteAgents = {};
|
|
1415
1704
|
this._agents = this.localAgents;
|
|
1416
1705
|
await this.notifyRuntimeStatusChanged(CopilotKitCoreRuntimeConnectionStatus.Disconnected);
|
|
1706
|
+
if (!this.isCurrentRuntimeConnection(attempt)) return;
|
|
1417
1707
|
await this.notifyAgentsChanged();
|
|
1418
1708
|
return;
|
|
1419
1709
|
}
|
|
1420
1710
|
const inspectorMetadataConnectionGeneration = this.inspectorMetadataConnectionGeneration;
|
|
1421
|
-
this.
|
|
1711
|
+
this.setRuntimeConnectionStatus(CopilotKitCoreRuntimeConnectionStatus.Connecting);
|
|
1712
|
+
const runtimeHealthGeneration = this.runtimeHealthGeneration;
|
|
1422
1713
|
await this.notifyRuntimeStatusChanged(CopilotKitCoreRuntimeConnectionStatus.Connecting);
|
|
1714
|
+
if (!this.isCurrentRuntimeConnection(attempt)) return;
|
|
1423
1715
|
try {
|
|
1424
1716
|
if (inspectorMetadataConnectionGeneration !== this.inspectorMetadataConnectionGeneration) return;
|
|
1425
|
-
const { runtimeInfo: runtimeInfoResponse, resolvedTransport } = await this.fetchRuntimeInfo();
|
|
1426
|
-
if (inspectorMetadataConnectionGeneration !== this.inspectorMetadataConnectionGeneration) return;
|
|
1717
|
+
const { runtimeInfo: runtimeInfoResponse, resolvedTransport } = options?.recovery ? await this.fetchRuntimeInfoWithTimeout(new AbortController(), runtimeUrl, transport) : await this.fetchRuntimeInfo(runtimeUrl, transport);
|
|
1718
|
+
if (!this.isCurrentRuntimeConnection(attempt) || inspectorMetadataConnectionGeneration !== this.inspectorMetadataConnectionGeneration) return;
|
|
1427
1719
|
this._runtimeTransport = resolvedTransport;
|
|
1428
1720
|
const { version, ...runtimeInfo } = runtimeInfoResponse;
|
|
1429
1721
|
const credentials = this.core.credentials;
|
|
1430
1722
|
const rawDebug = this.core.debug;
|
|
1431
|
-
|
|
1723
|
+
const agents = Object.fromEntries(Object.entries(runtimeInfo.agents).map(([id, { description, capabilities }]) => {
|
|
1432
1724
|
const existing = Object.prototype.hasOwnProperty.call(this.remoteAgents, id) ? this.remoteAgents[id] : void 0;
|
|
1433
|
-
if (existing instanceof ProxiedCopilotRuntimeAgent) {
|
|
1725
|
+
if (existing instanceof ProxiedCopilotRuntimeAgent && this.canReuseRuntimeAgent(existing, runtimeUrl, this._runtimeTransport)) {
|
|
1434
1726
|
this.applyHeadersToAgent(existing);
|
|
1435
1727
|
this.applyCredentialsToAgent(existing);
|
|
1728
|
+
this.applyRuntimeFetchToAgent(existing);
|
|
1436
1729
|
return [id, existing];
|
|
1437
1730
|
}
|
|
1438
1731
|
const agent = new ProxiedCopilotRuntimeAgent({
|
|
1439
|
-
runtimeUrl
|
|
1732
|
+
runtimeUrl,
|
|
1440
1733
|
agentId: id,
|
|
1441
1734
|
description,
|
|
1442
1735
|
transport: this._runtimeTransport,
|
|
@@ -1447,13 +1740,25 @@ var AgentRegistry = class {
|
|
|
1447
1740
|
debug: rawDebug ? (0, _copilotkit_shared.resolveDebugConfig)(rawDebug) : void 0
|
|
1448
1741
|
});
|
|
1449
1742
|
this.applyHeadersToAgent(agent);
|
|
1743
|
+
this.applyRuntimeFetchToAgent(agent);
|
|
1744
|
+
this.mintedThreadIds.set(agent, agent.threadId);
|
|
1745
|
+
if (options?.preserveOnFailure === true && existing) {
|
|
1746
|
+
agent.threadId = existing.threadId;
|
|
1747
|
+
agent.setState(existing.state);
|
|
1748
|
+
agent.setMessages([...existing.messages]);
|
|
1749
|
+
}
|
|
1750
|
+
this.remoteAgentConnections.set(agent, {
|
|
1751
|
+
runtimeUrl,
|
|
1752
|
+
transport: this._runtimeTransport
|
|
1753
|
+
});
|
|
1450
1754
|
return [id, agent];
|
|
1451
1755
|
}));
|
|
1756
|
+
this.remoteAgents = options?.recovery ? this.reconcileRecoveredAgents(agents) : agents;
|
|
1452
1757
|
this._agents = {
|
|
1453
1758
|
...this.localAgents,
|
|
1454
1759
|
...this.remoteAgents
|
|
1455
1760
|
};
|
|
1456
|
-
this.
|
|
1761
|
+
this.setRuntimeConnectionStatus(CopilotKitCoreRuntimeConnectionStatus.Connected);
|
|
1457
1762
|
this._runtimeVersion = version;
|
|
1458
1763
|
this._audioFileTranscriptionEnabled = runtimeInfoResponse.audioFileTranscriptionEnabled ?? false;
|
|
1459
1764
|
this._runtimeMode = runtimeInfoResponse.mode ?? _copilotkit_shared.RUNTIME_MODE_SSE;
|
|
@@ -1468,54 +1773,67 @@ var AgentRegistry = class {
|
|
|
1468
1773
|
this._a2uiAgents = a2uiInfo?.enabled ? a2uiInfo.agents : void 0;
|
|
1469
1774
|
this._openGenerativeUIEnabled = runtimeInfoResponse.openGenerativeUIEnabled ?? false;
|
|
1470
1775
|
this._licenseStatus = runtimeInfoResponse.licenseStatus;
|
|
1776
|
+
this._runtimeEntitlements = runtimeInfoResponse.runtimeEntitlements;
|
|
1777
|
+
this.updateRuntimeEntitlementRetry(runtimeInfoResponse.runtimeEntitlements, attempt);
|
|
1471
1778
|
this._telemetryDisabled = runtimeInfoResponse.telemetryDisabled ?? false;
|
|
1472
1779
|
await this.notifyRuntimeStatusChanged(CopilotKitCoreRuntimeConnectionStatus.Connected);
|
|
1780
|
+
if (!this.isCurrentRuntimeConnection(attempt)) return;
|
|
1473
1781
|
await this.notifyAgentsChanged();
|
|
1474
1782
|
if (inspectorMetadataConnectionGeneration !== this.inspectorMetadataConnectionGeneration || this._runtimeConnectionStatus !== CopilotKitCoreRuntimeConnectionStatus.Connected) return;
|
|
1475
1783
|
this.inspectorMetadataRefreshReady = true;
|
|
1476
1784
|
if (this._inspectorMetadataSupported) this.refreshInspectorMetadata();
|
|
1477
1785
|
} catch (error) {
|
|
1478
|
-
if (inspectorMetadataConnectionGeneration !== this.inspectorMetadataConnectionGeneration) return;
|
|
1479
|
-
this.
|
|
1480
|
-
this.
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1786
|
+
if (!this.isCurrentRuntimeConnection(attempt) || inspectorMetadataConnectionGeneration !== this.inspectorMetadataConnectionGeneration) return;
|
|
1787
|
+
const boundedEntitlementRetryFailed = this._runtimeEntitlementRetryTimer === void 0 && this._runtimeEntitlementRetryAttemptedKey === key && this._runtimeEntitlementRetryPendingKey === key;
|
|
1788
|
+
if (boundedEntitlementRetryFailed) this._runtimeEntitlementRetryPendingKey = void 0;
|
|
1789
|
+
if (options?.preserveOnFailure) {
|
|
1790
|
+
if (options?.recovery && runtimeHealthGeneration !== this.runtimeHealthGeneration) return;
|
|
1791
|
+
this.setRuntimeConnectionStatus(CopilotKitCoreRuntimeConnectionStatus.Error);
|
|
1792
|
+
await this.notifyRuntimeStatusChanged(CopilotKitCoreRuntimeConnectionStatus.Error);
|
|
1793
|
+
} else {
|
|
1794
|
+
this.invalidateInspectorMetadataConnection();
|
|
1795
|
+
this.setRuntimeConnectionStatus(CopilotKitCoreRuntimeConnectionStatus.Error);
|
|
1796
|
+
this._runtimeVersion = void 0;
|
|
1797
|
+
this._audioFileTranscriptionEnabled = false;
|
|
1798
|
+
this._runtimeMode = _copilotkit_shared.RUNTIME_MODE_SSE;
|
|
1799
|
+
this._intelligence = void 0;
|
|
1800
|
+
this._threadEndpoints = void 0;
|
|
1801
|
+
this._suggestions = void 0;
|
|
1802
|
+
this._a2uiEnabled = false;
|
|
1803
|
+
this._a2uiAgents = void 0;
|
|
1804
|
+
this._openGenerativeUIEnabled = false;
|
|
1805
|
+
if (!boundedEntitlementRetryFailed) {
|
|
1806
|
+
this._licenseStatus = void 0;
|
|
1807
|
+
this._runtimeEntitlements = void 0;
|
|
1808
|
+
}
|
|
1809
|
+
this.remoteAgents = {};
|
|
1810
|
+
this._agents = this.localAgents;
|
|
1811
|
+
await this.notifyRuntimeStatusChanged(CopilotKitCoreRuntimeConnectionStatus.Error);
|
|
1812
|
+
await this.notifyAgentsChanged();
|
|
1813
|
+
}
|
|
1494
1814
|
const message = error instanceof Error ? error.message : JSON.stringify(error);
|
|
1495
|
-
_copilotkit_shared.logger.warn(`Failed to load runtime info (${
|
|
1815
|
+
_copilotkit_shared.logger.warn(`Failed to load runtime info (${runtimeUrl}/info): ${message}`);
|
|
1496
1816
|
const runtimeError = error instanceof Error ? error : new Error(String(error));
|
|
1497
1817
|
await this.core.emitError({
|
|
1498
1818
|
error: runtimeError,
|
|
1499
1819
|
code: CopilotKitCoreErrorCode.RUNTIME_INFO_FETCH_FAILED,
|
|
1500
|
-
context: { runtimeUrl
|
|
1820
|
+
context: { runtimeUrl }
|
|
1501
1821
|
});
|
|
1502
1822
|
}
|
|
1503
1823
|
}
|
|
1504
|
-
async fetchRuntimeInfo() {
|
|
1505
|
-
const runtimeUrl = this.runtimeUrl;
|
|
1506
|
-
if (!runtimeUrl) throw new Error("Runtime URL is not set");
|
|
1824
|
+
async fetchRuntimeInfo(runtimeUrl, runtimeTransport, signal) {
|
|
1507
1825
|
const baseHeaders = this.core.headers;
|
|
1508
1826
|
const credentials = this.core.credentials;
|
|
1509
1827
|
const headers = { ...baseHeaders };
|
|
1510
|
-
const runtimeTransport = this._runtimeTransport;
|
|
1511
1828
|
if (runtimeTransport === "single") return {
|
|
1512
|
-
runtimeInfo: await this.fetchRuntimeInfoSingle(runtimeUrl, headers, credentials),
|
|
1829
|
+
runtimeInfo: await this.fetchRuntimeInfoSingle(runtimeUrl, headers, credentials, signal),
|
|
1513
1830
|
resolvedTransport: "single"
|
|
1514
1831
|
};
|
|
1515
|
-
if (runtimeTransport === "auto") return this.fetchRuntimeInfoAutoDetect(runtimeUrl, headers, credentials);
|
|
1832
|
+
if (runtimeTransport === "auto") return this.fetchRuntimeInfoAutoDetect(runtimeUrl, headers, credentials, signal);
|
|
1516
1833
|
const response = await fetch(`${runtimeUrl}/info`, {
|
|
1517
1834
|
headers,
|
|
1518
|
-
...credentials ? { credentials } : {}
|
|
1835
|
+
...credentials ? { credentials } : {},
|
|
1836
|
+
...signal ? { signal } : {}
|
|
1519
1837
|
});
|
|
1520
1838
|
if (!response.ok) throw await runtimeInfoError(response);
|
|
1521
1839
|
return {
|
|
@@ -1523,12 +1841,13 @@ var AgentRegistry = class {
|
|
|
1523
1841
|
resolvedTransport: "rest"
|
|
1524
1842
|
};
|
|
1525
1843
|
}
|
|
1526
|
-
async fetchRuntimeInfoSingle(runtimeUrl, headers, credentials) {
|
|
1844
|
+
async fetchRuntimeInfoSingle(runtimeUrl, headers, credentials, signal) {
|
|
1527
1845
|
const response = await fetch(runtimeUrl, {
|
|
1528
1846
|
method: "POST",
|
|
1529
1847
|
headers: withJsonContentType(headers),
|
|
1530
1848
|
body: JSON.stringify({ method: "info" }),
|
|
1531
|
-
...credentials ? { credentials } : {}
|
|
1849
|
+
...credentials ? { credentials } : {},
|
|
1850
|
+
...signal ? { signal } : {}
|
|
1532
1851
|
});
|
|
1533
1852
|
if (!response.ok) throw await runtimeInfoError(response);
|
|
1534
1853
|
return await response.json();
|
|
@@ -1538,11 +1857,12 @@ var AgentRegistry = class {
|
|
|
1538
1857
|
* The caller commits the detected transport only after confirming this
|
|
1539
1858
|
* connection attempt is still current.
|
|
1540
1859
|
*/
|
|
1541
|
-
async fetchRuntimeInfoAutoDetect(runtimeUrl, headers, credentials) {
|
|
1860
|
+
async fetchRuntimeInfoAutoDetect(runtimeUrl, headers, credentials, signal) {
|
|
1542
1861
|
try {
|
|
1543
1862
|
const response = await fetch(`${runtimeUrl}/info`, {
|
|
1544
1863
|
headers: { ...headers },
|
|
1545
|
-
...credentials ? { credentials } : {}
|
|
1864
|
+
...credentials ? { credentials } : {},
|
|
1865
|
+
...signal ? { signal } : {}
|
|
1546
1866
|
});
|
|
1547
1867
|
if (response.status >= 200 && response.status < 300) return {
|
|
1548
1868
|
runtimeInfo: await response.json(),
|
|
@@ -1550,7 +1870,7 @@ var AgentRegistry = class {
|
|
|
1550
1870
|
};
|
|
1551
1871
|
} catch {}
|
|
1552
1872
|
return {
|
|
1553
|
-
runtimeInfo: await this.fetchRuntimeInfoSingle(runtimeUrl, { ...headers }, credentials),
|
|
1873
|
+
runtimeInfo: await this.fetchRuntimeInfoSingle(runtimeUrl, { ...headers }, credentials, signal),
|
|
1554
1874
|
resolvedTransport: "single"
|
|
1555
1875
|
};
|
|
1556
1876
|
}
|
|
@@ -2039,11 +2359,40 @@ function isForwardedToClientPlaceholder(content) {
|
|
|
2039
2359
|
*/
|
|
2040
2360
|
const MAX_FOLLOW_UP_DEPTH = 100;
|
|
2041
2361
|
/**
|
|
2362
|
+
* Name of the catch-all frontend tool. A tool registered under this name
|
|
2363
|
+
* handles any tool call that has no exact match (see `executeWildcardTool`),
|
|
2364
|
+
* and is never advertised to the agent.
|
|
2365
|
+
*/
|
|
2366
|
+
const WILDCARD_TOOL_NAME = "*";
|
|
2367
|
+
/**
|
|
2042
2368
|
* Handles agent execution, tool calling, and agent connectivity for CopilotKitCore.
|
|
2043
2369
|
* Manages the complete lifecycle of agent runs including tool execution and follow-ups.
|
|
2044
2370
|
*/
|
|
2045
2371
|
var RunHandler = class {
|
|
2046
|
-
|
|
2372
|
+
/**
|
|
2373
|
+
* Tools owned by the framework provider, replaced wholesale by
|
|
2374
|
+
* {@link initialize} and {@link setTools} whenever the provider re-syncs its
|
|
2375
|
+
* props or runtime feature flags.
|
|
2376
|
+
*/
|
|
2377
|
+
_propTools = [];
|
|
2378
|
+
/**
|
|
2379
|
+
* Tools registered imperatively via {@link addTool} — `useFrontendTool`,
|
|
2380
|
+
* `useHumanInTheLoop`, and direct `core.addTool()` callers. Held separately
|
|
2381
|
+
* from {@link _propTools} so a provider re-sync cannot wipe them: they shared
|
|
2382
|
+
* one array before, so the `/info` response flipping `openGenerativeUI` (or
|
|
2383
|
+
* any other provider-prop change) silently dropped every hook-registered
|
|
2384
|
+
* tool (#4952). Key = `capabilityKey(name, agentId)`.
|
|
2385
|
+
*/
|
|
2386
|
+
_hookTools = /* @__PURE__ */ new Map();
|
|
2387
|
+
/**
|
|
2388
|
+
* Memoized merge of both buckets, invalidated on every registry write.
|
|
2389
|
+
*
|
|
2390
|
+
* This is about identity, not speed: `tools` is public and used to return the
|
|
2391
|
+
* same array instance until something mutated the registry, so consumers can
|
|
2392
|
+
* hold it or use it as an effect dependency. Rebuilding the merge on every
|
|
2393
|
+
* read would hand out a new array each time.
|
|
2394
|
+
*/
|
|
2395
|
+
_cachedMergedTools = null;
|
|
2047
2396
|
/**
|
|
2048
2397
|
* The full list of A2UI catalog components registered by the provider.
|
|
2049
2398
|
* Order is preserved for display in the inspector.
|
|
@@ -2127,35 +2476,49 @@ var RunHandler = class {
|
|
|
2127
2476
|
return anonymousId;
|
|
2128
2477
|
}
|
|
2129
2478
|
/**
|
|
2130
|
-
* Get all tools as a readonly array
|
|
2479
|
+
* Get all tools as a readonly array: provider-owned tools in registration
|
|
2480
|
+
* order, with imperatively-added tools appended and taking precedence over a
|
|
2481
|
+
* provider tool of the same name + agentId.
|
|
2131
2482
|
*/
|
|
2132
2483
|
get tools() {
|
|
2133
|
-
return this.
|
|
2484
|
+
if (this._hookTools.size === 0) return this._propTools;
|
|
2485
|
+
if (this._cachedMergedTools) return this._cachedMergedTools;
|
|
2486
|
+
const merged = /* @__PURE__ */ new Map();
|
|
2487
|
+
for (const tool of this._propTools) merged.set(this.capabilityKey(tool.name, tool.agentId), tool);
|
|
2488
|
+
for (const [key, tool] of this._hookTools) merged.set(key, tool);
|
|
2489
|
+
this._cachedMergedTools = Array.from(merged.values());
|
|
2490
|
+
return this._cachedMergedTools;
|
|
2134
2491
|
}
|
|
2135
2492
|
/**
|
|
2136
2493
|
* Initialize with tools
|
|
2137
2494
|
*/
|
|
2138
2495
|
initialize(tools) {
|
|
2139
|
-
this.
|
|
2496
|
+
this._propTools = [...tools];
|
|
2497
|
+
this._cachedMergedTools = null;
|
|
2140
2498
|
}
|
|
2141
2499
|
/**
|
|
2142
|
-
* Add a tool to the registry
|
|
2500
|
+
* Add a tool to the registry. Survives provider re-syncs ({@link setTools}),
|
|
2501
|
+
* and shadows a provider tool of the same name + agentId.
|
|
2143
2502
|
*/
|
|
2144
2503
|
addTool(tool) {
|
|
2145
|
-
|
|
2504
|
+
const key = this.capabilityKey(tool.name, tool.agentId);
|
|
2505
|
+
if (this._hookTools.has(key)) {
|
|
2146
2506
|
_copilotkit_shared.logger.warn(`Tool already exists: '${tool.name}' for agent '${tool.agentId || "global"}', skipping.`);
|
|
2147
2507
|
return;
|
|
2148
2508
|
}
|
|
2149
|
-
this.
|
|
2509
|
+
this._hookTools.set(key, tool);
|
|
2510
|
+
this._cachedMergedTools = null;
|
|
2150
2511
|
}
|
|
2151
2512
|
/**
|
|
2152
2513
|
* Remove a tool by name and optionally by agentId
|
|
2153
2514
|
*/
|
|
2154
2515
|
removeTool(id, agentId) {
|
|
2155
|
-
this.
|
|
2516
|
+
this._hookTools.delete(this.capabilityKey(id, agentId));
|
|
2517
|
+
this._propTools = this._propTools.filter((tool) => {
|
|
2156
2518
|
if (agentId !== void 0) return !(tool.name === id && tool.agentId === agentId);
|
|
2157
2519
|
return !(tool.name === id && !tool.agentId);
|
|
2158
2520
|
});
|
|
2521
|
+
this._cachedMergedTools = null;
|
|
2159
2522
|
}
|
|
2160
2523
|
/**
|
|
2161
2524
|
* Get a tool by name and optionally by agentId.
|
|
@@ -2164,17 +2527,20 @@ var RunHandler = class {
|
|
|
2164
2527
|
*/
|
|
2165
2528
|
getTool(params) {
|
|
2166
2529
|
const { toolName, agentId } = params;
|
|
2530
|
+
const tools = this.tools;
|
|
2167
2531
|
if (agentId) {
|
|
2168
|
-
const agentTool =
|
|
2532
|
+
const agentTool = tools.find((tool) => tool.name === toolName && tool.agentId === agentId);
|
|
2169
2533
|
if (agentTool) return agentTool;
|
|
2170
2534
|
}
|
|
2171
|
-
return
|
|
2535
|
+
return tools.find((tool) => tool.name === toolName && !tool.agentId);
|
|
2172
2536
|
}
|
|
2173
2537
|
/**
|
|
2174
|
-
* Set all tools at once. Replaces
|
|
2538
|
+
* Set all provider-owned tools at once. Replaces the previous provider set;
|
|
2539
|
+
* tools registered via {@link addTool} are unaffected.
|
|
2175
2540
|
*/
|
|
2176
2541
|
setTools(tools) {
|
|
2177
|
-
this.
|
|
2542
|
+
this._propTools = [...tools];
|
|
2543
|
+
this._cachedMergedTools = null;
|
|
2178
2544
|
}
|
|
2179
2545
|
/**
|
|
2180
2546
|
* Return the registered A2UI catalog components (readonly).
|
|
@@ -2238,7 +2604,7 @@ var RunHandler = class {
|
|
|
2238
2604
|
});
|
|
2239
2605
|
} catch (error) {
|
|
2240
2606
|
const connectError = error instanceof Error ? error : new Error(String(error));
|
|
2241
|
-
if (!(connectError
|
|
2607
|
+
if (!isAbortError$1(connectError)) {
|
|
2242
2608
|
const context = {};
|
|
2243
2609
|
if (agent.agentId) context.agentId = agent.agentId;
|
|
2244
2610
|
if (incomingThreadId) context.threadId = incomingThreadId;
|
|
@@ -2351,7 +2717,7 @@ var RunHandler = class {
|
|
|
2351
2717
|
const getWildcardTool = () => {
|
|
2352
2718
|
if (tool || wildcardTool) return wildcardTool;
|
|
2353
2719
|
wildcardTool = this.getTool({
|
|
2354
|
-
toolName:
|
|
2720
|
+
toolName: WILDCARD_TOOL_NAME,
|
|
2355
2721
|
agentId: agent.agentId
|
|
2356
2722
|
});
|
|
2357
2723
|
return wildcardTool;
|
|
@@ -2705,7 +3071,7 @@ var RunHandler = class {
|
|
|
2705
3071
|
* Build frontend tools for an agent
|
|
2706
3072
|
*/
|
|
2707
3073
|
buildFrontendTools(agentId) {
|
|
2708
|
-
return this.
|
|
3074
|
+
return this.tools.filter((tool) => tool.name !== WILDCARD_TOOL_NAME && tool.available !== false && tool.available !== "disabled" && (!tool.agentId || tool.agentId === agentId) && this.isToolEnabled(tool.name, tool.agentId)).map((tool) => ({
|
|
2709
3075
|
name: tool.name,
|
|
2710
3076
|
description: tool.description ?? "",
|
|
2711
3077
|
parameters: createToolSchema(tool)
|
|
@@ -2853,9 +3219,10 @@ var StateManager = class {
|
|
|
2853
3219
|
subscribeToAgent(agent) {
|
|
2854
3220
|
if (!agent.agentId) return;
|
|
2855
3221
|
const agentId = agent.agentId;
|
|
2856
|
-
const
|
|
2857
|
-
if (
|
|
2858
|
-
|
|
3222
|
+
const existing = this.agentSubscriptions.get(agentId);
|
|
3223
|
+
if (existing) {
|
|
3224
|
+
if (existing.agent === agent) return;
|
|
3225
|
+
existing.unsubscribe();
|
|
2859
3226
|
this.agentSubscriptions.delete(agentId);
|
|
2860
3227
|
}
|
|
2861
3228
|
let revoked = false;
|
|
@@ -2991,19 +3358,22 @@ var StateManager = class {
|
|
|
2991
3358
|
if (!input) this.pruneRawEvents(agent.agentId, agent.threadId, messages);
|
|
2992
3359
|
}
|
|
2993
3360
|
});
|
|
2994
|
-
this.agentSubscriptions.set(agentId,
|
|
2995
|
-
|
|
2996
|
-
|
|
2997
|
-
|
|
3361
|
+
this.agentSubscriptions.set(agentId, {
|
|
3362
|
+
agent,
|
|
3363
|
+
unsubscribe: () => {
|
|
3364
|
+
revoked = true;
|
|
3365
|
+
this.pendingContinuations.delete(agent);
|
|
3366
|
+
unsubscribe();
|
|
3367
|
+
}
|
|
2998
3368
|
});
|
|
2999
3369
|
}
|
|
3000
3370
|
/**
|
|
3001
3371
|
* Unsubscribe an agent's subscription.
|
|
3002
3372
|
*/
|
|
3003
3373
|
unsubscribeFromAgent(agentId) {
|
|
3004
|
-
const
|
|
3005
|
-
if (
|
|
3006
|
-
unsubscribe();
|
|
3374
|
+
const existing = this.agentSubscriptions.get(agentId);
|
|
3375
|
+
if (existing) {
|
|
3376
|
+
existing.unsubscribe();
|
|
3007
3377
|
this.agentSubscriptions.delete(agentId);
|
|
3008
3378
|
}
|
|
3009
3379
|
this.rawEventByMessage.delete(agentId);
|
|
@@ -4533,6 +4903,9 @@ var CopilotKitCore = class {
|
|
|
4533
4903
|
get runtimeConnectionStatus() {
|
|
4534
4904
|
return this.agentRegistry.runtimeConnectionStatus;
|
|
4535
4905
|
}
|
|
4906
|
+
get ɵruntimeFetch() {
|
|
4907
|
+
return this.agentRegistry.createRuntimeFetch();
|
|
4908
|
+
}
|
|
4536
4909
|
get audioFileTranscriptionEnabled() {
|
|
4537
4910
|
return this.agentRegistry.audioFileTranscriptionEnabled;
|
|
4538
4911
|
}
|
|
@@ -4572,6 +4945,14 @@ var CopilotKitCore = class {
|
|
|
4572
4945
|
get licenseStatus() {
|
|
4573
4946
|
return this.agentRegistry.licenseStatus;
|
|
4574
4947
|
}
|
|
4948
|
+
/** Structured Runtime entitlement authority advertised by `/info`. */
|
|
4949
|
+
get runtimeEntitlements() {
|
|
4950
|
+
return this.agentRegistry.runtimeEntitlements;
|
|
4951
|
+
}
|
|
4952
|
+
/** Whether Core still has a bounded Runtime entitlement retry to settle. */
|
|
4953
|
+
get runtimeEntitlementRetryPending() {
|
|
4954
|
+
return this.agentRegistry.runtimeEntitlementRetryPending;
|
|
4955
|
+
}
|
|
4575
4956
|
get telemetryDisabled() {
|
|
4576
4957
|
return this.agentRegistry.telemetryDisabled;
|
|
4577
4958
|
}
|
|
@@ -5544,22 +5925,34 @@ function createThreadRequestId() {
|
|
|
5544
5925
|
}
|
|
5545
5926
|
function threadFromFetch(input, init) {
|
|
5546
5927
|
return new rxjs.Observable((subscriber) => {
|
|
5547
|
-
const { fetch: fetchImpl, selector, signal, ...requestInit } = init;
|
|
5928
|
+
const { fetch: fetchImpl, selector, signal, timeoutMs, nonCritical, ...requestInit } = init;
|
|
5548
5929
|
const controller = new AbortController();
|
|
5930
|
+
const runtimeRequest = {
|
|
5931
|
+
...nonCritical ? { nonCritical: true } : {},
|
|
5932
|
+
...timeoutMs === void 0 ? {} : { selfBounded: true }
|
|
5933
|
+
};
|
|
5934
|
+
let timedOut = false;
|
|
5549
5935
|
const abortRequest = () => controller.abort();
|
|
5550
5936
|
if (signal?.aborted) abortRequest();
|
|
5551
5937
|
else signal?.addEventListener("abort", abortRequest, { once: true });
|
|
5938
|
+
const timeoutId = timeoutMs === void 0 ? void 0 : setTimeout(() => {
|
|
5939
|
+
timedOut = true;
|
|
5940
|
+
runtimeRequest.timedOut = true;
|
|
5941
|
+
abortRequest();
|
|
5942
|
+
}, timeoutMs);
|
|
5552
5943
|
fetchImpl(input, {
|
|
5553
5944
|
...requestInit,
|
|
5554
|
-
signal: controller.signal
|
|
5945
|
+
signal: controller.signal,
|
|
5946
|
+
ɵruntimeRequest: runtimeRequest
|
|
5555
5947
|
}).then((response) => selector(response)).then((value) => {
|
|
5556
5948
|
if (subscriber.closed) return;
|
|
5557
5949
|
subscriber.next(value);
|
|
5558
5950
|
subscriber.complete();
|
|
5559
5951
|
}).catch((error) => {
|
|
5560
|
-
if (!subscriber.closed) subscriber.error(error);
|
|
5952
|
+
if (!subscriber.closed) subscriber.error(timedOut ? /* @__PURE__ */ new Error("Request timed out") : error);
|
|
5561
5953
|
});
|
|
5562
5954
|
return () => {
|
|
5955
|
+
if (timeoutId !== void 0) clearTimeout(timeoutId);
|
|
5563
5956
|
signal?.removeEventListener("abort", abortRequest);
|
|
5564
5957
|
abortRequest();
|
|
5565
5958
|
};
|
|
@@ -5577,14 +5970,10 @@ function createThreadFetchObservable(environment, context, sessionId) {
|
|
|
5577
5970
|
return response.json();
|
|
5578
5971
|
},
|
|
5579
5972
|
fetch: environment.fetch,
|
|
5973
|
+
timeoutMs: REQUEST_TIMEOUT_MS,
|
|
5580
5974
|
method: "GET",
|
|
5581
5975
|
headers: { ...context.headers }
|
|
5582
|
-
}).pipe((0, rxjs_operators.
|
|
5583
|
-
first: REQUEST_TIMEOUT_MS,
|
|
5584
|
-
with: () => {
|
|
5585
|
-
throw new Error("Request timed out");
|
|
5586
|
-
}
|
|
5587
|
-
}), (0, rxjs_operators.map)((data) => threadRestEvents.listSucceeded({
|
|
5976
|
+
}).pipe((0, rxjs_operators.map)((data) => threadRestEvents.listSucceeded({
|
|
5588
5977
|
sessionId,
|
|
5589
5978
|
threads: data.threads,
|
|
5590
5979
|
joinCode: typeof data.joinCode === "string" && data.joinCode.length > 0 ? data.joinCode : null,
|
|
@@ -5605,18 +5994,15 @@ function createThreadMetadataCredentialsObservable(environment, context, session
|
|
|
5605
5994
|
return response.json();
|
|
5606
5995
|
},
|
|
5607
5996
|
fetch: environment.fetch,
|
|
5997
|
+
timeoutMs: REQUEST_TIMEOUT_MS,
|
|
5998
|
+
nonCritical: true,
|
|
5608
5999
|
method: "POST",
|
|
5609
6000
|
headers: {
|
|
5610
6001
|
...context.headers,
|
|
5611
6002
|
"Content-Type": "application/json"
|
|
5612
6003
|
},
|
|
5613
6004
|
body: JSON.stringify({})
|
|
5614
|
-
}).pipe((0, rxjs_operators.
|
|
5615
|
-
first: REQUEST_TIMEOUT_MS,
|
|
5616
|
-
with: () => {
|
|
5617
|
-
throw new Error("Request timed out");
|
|
5618
|
-
}
|
|
5619
|
-
}), (0, rxjs_operators.map)((data) => {
|
|
6005
|
+
}).pipe((0, rxjs_operators.map)((data) => {
|
|
5620
6006
|
if (typeof data.joinToken !== "string" || data.joinToken.length === 0) throw new Error("missing joinToken");
|
|
5621
6007
|
return threadRestEvents.metadataCredentialsSucceeded({
|
|
5622
6008
|
sessionId,
|
|
@@ -5747,14 +6133,10 @@ function createThreadStore(environment) {
|
|
|
5747
6133
|
return response.json();
|
|
5748
6134
|
},
|
|
5749
6135
|
fetch: environment.fetch,
|
|
6136
|
+
timeoutMs: REQUEST_TIMEOUT_MS,
|
|
5750
6137
|
method: "GET",
|
|
5751
6138
|
headers: { ...context.headers }
|
|
5752
|
-
}).pipe((0, rxjs_operators.
|
|
5753
|
-
first: REQUEST_TIMEOUT_MS,
|
|
5754
|
-
with: () => {
|
|
5755
|
-
throw new Error("Request timed out");
|
|
5756
|
-
}
|
|
5757
|
-
}), (0, rxjs_operators.map)((data) => threadRestEvents.nextPageSucceeded({
|
|
6139
|
+
}).pipe((0, rxjs_operators.map)((data) => threadRestEvents.nextPageSucceeded({
|
|
5758
6140
|
sessionId: state.sessionId,
|
|
5759
6141
|
threads: data.threads,
|
|
5760
6142
|
nextCursor: data.nextCursor ?? null
|
|
@@ -5918,6 +6300,12 @@ const ɵselectIsMutating = selectIsMutating;
|
|
|
5918
6300
|
* hardcoding the threshold separately from production.
|
|
5919
6301
|
*/
|
|
5920
6302
|
const ɵMAX_SOCKET_RETRIES = MAX_SOCKET_RETRIES;
|
|
6303
|
+
/**
|
|
6304
|
+
* How long a thread REST request is given before the store gives up on it.
|
|
6305
|
+
* Exposed for tests for the same reason as {@link ɵMAX_SOCKET_RETRIES}: a
|
|
6306
|
+
* separately hardcoded copy silently drifts away from this one.
|
|
6307
|
+
*/
|
|
6308
|
+
const ɵTHREAD_REQUEST_TIMEOUT_MS = REQUEST_TIMEOUT_MS;
|
|
5921
6309
|
|
|
5922
6310
|
//#endregion
|
|
5923
6311
|
//#region src/features.ts
|
|
@@ -6208,6 +6596,8 @@ exports.select = select;
|
|
|
6208
6596
|
exports.ɵCOPILOTKIT_FEATURES = ɵCOPILOTKIT_FEATURES;
|
|
6209
6597
|
exports.ɵInterruptState = ɵInterruptState;
|
|
6210
6598
|
exports.ɵMAX_SOCKET_RETRIES = ɵMAX_SOCKET_RETRIES;
|
|
6599
|
+
exports.ɵRUNTIME_PROBE_TIMEOUT_MS = ɵRUNTIME_PROBE_TIMEOUT_MS;
|
|
6600
|
+
exports.ɵTHREAD_REQUEST_TIMEOUT_MS = ɵTHREAD_REQUEST_TIMEOUT_MS;
|
|
6211
6601
|
exports.ɵcreateMemoryStore = createMemoryStore;
|
|
6212
6602
|
exports.ɵcreateThreadSelectors = ɵcreateThreadSelectors;
|
|
6213
6603
|
exports.ɵcreateThreadStore = createThreadStore;
|