@copilotkit/core 1.76.0 → 1.77.1
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 +981 -31
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +135 -3
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +135 -3
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +981 -31
- package/dist/index.mjs.map +1 -1
- package/dist/index.umd.js +1013 -35
- package/dist/index.umd.js.map +1 -1
- package/package.json +5 -4
package/dist/index.umd.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
(function(global, factory) {
|
|
2
|
-
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@tanstack/pacer'), require('@ag-ui/client'), require('@copilotkit/shared'), require('rxjs'), require('rxjs/operators'), require('phoenix'), require('zod-to-json-schema')) :
|
|
3
|
-
typeof define === 'function' && define.amd ? define(['exports', '@tanstack/pacer', '@ag-ui/client', '@copilotkit/shared', 'rxjs', 'rxjs/operators', 'phoenix', 'zod-to-json-schema'], factory) :
|
|
4
|
-
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory((global.CopilotKitCore = {}), global._tanstack_pacer,global.AgUIClient,global.CopilotKitShared,global.rxjs,global.rxjs.operators,global.phoenix,global.zodToJsonSchema));
|
|
5
|
-
})(this, function(exports, _tanstack_pacer, _ag_ui_client, _copilotkit_shared, rxjs, rxjs_operators, phoenix, zod_to_json_schema) {
|
|
2
|
+
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@tanstack/pacer'), require('@ag-ui/client'), require('@copilotkit/shared'), require('rxjs'), require('rxjs/operators'), require('phoenix'), require('zod-to-json-schema'), require('@copilotkit/learning')) :
|
|
3
|
+
typeof define === 'function' && define.amd ? define(['exports', '@tanstack/pacer', '@ag-ui/client', '@copilotkit/shared', 'rxjs', 'rxjs/operators', 'phoenix', 'zod-to-json-schema', '@copilotkit/learning'], factory) :
|
|
4
|
+
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory((global.CopilotKitCore = {}), global._tanstack_pacer,global.AgUIClient,global.CopilotKitShared,global.rxjs,global.rxjs.operators,global.phoenix,global.zodToJsonSchema,global._copilotkit_learning));
|
|
5
|
+
})(this, function(exports, _tanstack_pacer, _ag_ui_client, _copilotkit_shared, rxjs, rxjs_operators, phoenix, zod_to_json_schema, _copilotkit_learning) {
|
|
6
6
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
7
7
|
|
|
8
8
|
//#region src/utils/http-agent.ts
|
|
@@ -194,10 +194,17 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
194
194
|
*
|
|
195
195
|
* The socket is constructed and connected on subscription, and disconnected on
|
|
196
196
|
* teardown. Each subscription creates an isolated socket instance.
|
|
197
|
+
*
|
|
198
|
+
* Heartbeats default to every 15s: Phoenix's own 30s default matches common
|
|
199
|
+
* reverse-proxy WebSocket idle timeouts (e.g. Azure Application Gateway), which
|
|
200
|
+
* would drop the socket during a quiet run. Callers may override it.
|
|
197
201
|
*/
|
|
198
202
|
function ɵphoenixSocket$(options) {
|
|
199
203
|
return (0, rxjs.defer)(() => {
|
|
200
|
-
const socket = new phoenix.Socket(options.url,
|
|
204
|
+
const socket = new phoenix.Socket(options.url, {
|
|
205
|
+
heartbeatIntervalMs: 15e3,
|
|
206
|
+
...options.options
|
|
207
|
+
});
|
|
201
208
|
const signals$ = ɵcreatePhoenixSocketSignals$(socket).pipe((0, rxjs_operators.shareReplay)({
|
|
202
209
|
bufferSize: 1,
|
|
203
210
|
refCount: true
|
|
@@ -323,6 +330,11 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
323
330
|
const CONNECT_STREAM_IDLE_REPLAY_FALLBACK_MS = 100;
|
|
324
331
|
const CONNECT_IDLE_WARNING_MS = 3e4;
|
|
325
332
|
const MAX_UNOPENED_CREDENTIAL_REFRESHES = 2;
|
|
333
|
+
function isMcpResourceRead(input) {
|
|
334
|
+
const forwardedProps = input.forwardedProps;
|
|
335
|
+
const request = forwardedProps === null || forwardedProps === void 0 ? void 0 : forwardedProps.__proxiedMCPRequest;
|
|
336
|
+
return (forwardedProps === null || forwardedProps === void 0 ? void 0 : forwardedProps.__copilotkitMcpResourceReadOnly) === true && typeof request === "object" && request !== null && request.method === "resources/read";
|
|
337
|
+
}
|
|
326
338
|
var AgentThreadLockedError = class extends Error {
|
|
327
339
|
constructor(threadId) {
|
|
328
340
|
super(threadId ? `Thread ${threadId} is locked` : "Thread is locked");
|
|
@@ -430,10 +442,22 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
430
442
|
* server-pushed AG-UI events to the Observable subscriber.
|
|
431
443
|
*/
|
|
432
444
|
run(input) {
|
|
433
|
-
|
|
434
|
-
|
|
445
|
+
if (!isMcpResourceRead(input)) {
|
|
446
|
+
this.threadId = input.threadId;
|
|
447
|
+
this.canonicalRunId = input.runId;
|
|
448
|
+
}
|
|
435
449
|
return (0, rxjs.defer)(() => this.requestJoinCredentials$("run", input)).pipe((0, rxjs.switchMap)((credentials) => {
|
|
436
450
|
if (credentials === null) return (0, rxjs.throwError)(() => /* @__PURE__ */ new Error("REST run request returned no credentials"));
|
|
451
|
+
if ("kind" in credentials) return (0, rxjs.of)({
|
|
452
|
+
type: _ag_ui_client.EventType.RUN_STARTED,
|
|
453
|
+
threadId: credentials.threadId,
|
|
454
|
+
runId: credentials.runId
|
|
455
|
+
}, {
|
|
456
|
+
type: _ag_ui_client.EventType.RUN_FINISHED,
|
|
457
|
+
threadId: credentials.threadId,
|
|
458
|
+
runId: credentials.runId,
|
|
459
|
+
result: credentials.result
|
|
460
|
+
});
|
|
437
461
|
const canonicalInput = this.applyCanonicalRunIdentity(input, credentials, { fallbackToInputRunId: true });
|
|
438
462
|
return this.observeThread$(canonicalInput, credentials, {
|
|
439
463
|
completeOnRunError: false,
|
|
@@ -527,7 +551,18 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
527
551
|
const text = await response.text().catch(() => "");
|
|
528
552
|
throw new Error(text || response.statusText || String(response.status));
|
|
529
553
|
}
|
|
530
|
-
|
|
554
|
+
const payload = await response.json();
|
|
555
|
+
if (mode === "run" && isMcpResourceRead(input) && typeof payload === "object" && payload !== null && payload.kind === "mcp-resource-read") {
|
|
556
|
+
const resource = payload;
|
|
557
|
+
if (typeof resource.threadId !== "string" || !resource.threadId || typeof resource.runId !== "string" || !resource.runId) throw new Error("invalid MCP resource response identity");
|
|
558
|
+
return {
|
|
559
|
+
kind: "mcp-resource-read",
|
|
560
|
+
threadId: resource.threadId,
|
|
561
|
+
runId: resource.runId,
|
|
562
|
+
result: resource.result
|
|
563
|
+
};
|
|
564
|
+
}
|
|
565
|
+
return this.normalizeJoinCredentials(payload, input);
|
|
531
566
|
} catch (error) {
|
|
532
567
|
if (error instanceof AgentThreadLockedError) throw error;
|
|
533
568
|
throw new Error(`REST ${mode} request failed: ${error instanceof Error ? error.message : String(error)}`, { cause: error });
|
|
@@ -1268,6 +1303,22 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
1268
1303
|
}
|
|
1269
1304
|
return cloned;
|
|
1270
1305
|
}
|
|
1306
|
+
/** Run presentation-only MCP reads on a separate client agent so their
|
|
1307
|
+
* lifecycle cannot replace an in-flight approval's detach/completion state. */
|
|
1308
|
+
async ɵrunMcpResourceRead(parameters) {
|
|
1309
|
+
var _parameters$forwarded;
|
|
1310
|
+
const request = (_parameters$forwarded = parameters.forwardedProps) === null || _parameters$forwarded === void 0 ? void 0 : _parameters$forwarded.__proxiedMCPRequest;
|
|
1311
|
+
if (typeof request !== "object" || request === null || request.method !== "resources/read") throw new Error("Only MCP resources/read can use the read-only path");
|
|
1312
|
+
await this.ensureRuntimeConfiguration();
|
|
1313
|
+
const resourceParameters = {
|
|
1314
|
+
...parameters,
|
|
1315
|
+
forwardedProps: {
|
|
1316
|
+
...parameters.forwardedProps,
|
|
1317
|
+
__copilotkitMcpResourceReadOnly: true
|
|
1318
|
+
}
|
|
1319
|
+
};
|
|
1320
|
+
return this.runtimeMode === _copilotkit_shared.RUNTIME_MODE_INTELLIGENCE ? this.clone().runAgent(resourceParameters) : this.runAgent(resourceParameters);
|
|
1321
|
+
}
|
|
1271
1322
|
/**
|
|
1272
1323
|
* Drop the delegate's cached `lastSeenEventId` for this thread so
|
|
1273
1324
|
* the next connect requests a full historical replay from the
|
|
@@ -2015,6 +2066,10 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
2015
2066
|
this.applyMessageFilterToAgent(agent);
|
|
2016
2067
|
});
|
|
2017
2068
|
}
|
|
2069
|
+
/** Preserve the exact configured URL when posting to a single endpoint. */
|
|
2070
|
+
get runtimeEndpointUrl() {
|
|
2071
|
+
return this._runtimeEndpointUrl;
|
|
2072
|
+
}
|
|
2018
2073
|
createRuntimeFetch() {
|
|
2019
2074
|
if (!this.runtimeFetch) this.runtimeFetch = (async (input, init) => {
|
|
2020
2075
|
const meta = () => runtimeRequestMeta(init);
|
|
@@ -3080,6 +3135,68 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
3080
3135
|
function isForwardedToClientPlaceholder(content) {
|
|
3081
3136
|
return normalizeToolResultContent(content) === FORWARDED_TO_CLIENT;
|
|
3082
3137
|
}
|
|
3138
|
+
const MEDIA_PART_TYPES = new Set([
|
|
3139
|
+
"image",
|
|
3140
|
+
"audio",
|
|
3141
|
+
"video",
|
|
3142
|
+
"document"
|
|
3143
|
+
]);
|
|
3144
|
+
function isOptionalString(value) {
|
|
3145
|
+
return value === void 0 || typeof value === "string";
|
|
3146
|
+
}
|
|
3147
|
+
function isPartSource(value) {
|
|
3148
|
+
if (!value || typeof value !== "object") return false;
|
|
3149
|
+
const source = value;
|
|
3150
|
+
if (typeof source.value !== "string") return false;
|
|
3151
|
+
switch (source.type) {
|
|
3152
|
+
case "data": return typeof source.mimeType === "string";
|
|
3153
|
+
case "url": return isOptionalString(source.mimeType);
|
|
3154
|
+
case "file": return isOptionalString(source.provider) && isOptionalString(source.mimeType);
|
|
3155
|
+
default: return false;
|
|
3156
|
+
}
|
|
3157
|
+
}
|
|
3158
|
+
/**
|
|
3159
|
+
* Mirrors `ContentPartSchema` from `@ag-ui/core/schemas`. The runtime parses
|
|
3160
|
+
* the request with that schema, and one invalid part there fails the whole run.
|
|
3161
|
+
* Core does not import the schema because the UMD build has no global for it.
|
|
3162
|
+
* A test checks this function against the schema.
|
|
3163
|
+
*/
|
|
3164
|
+
function isContentPart(value) {
|
|
3165
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return false;
|
|
3166
|
+
const part = value;
|
|
3167
|
+
if (!isOptionalString(part.id) || part.metadata === null) return false;
|
|
3168
|
+
if (part.type === "text") return typeof part.text === "string";
|
|
3169
|
+
return typeof part.type === "string" && MEDIA_PART_TYPES.has(part.type) && isPartSource(part.source);
|
|
3170
|
+
}
|
|
3171
|
+
/**
|
|
3172
|
+
* Converts what a frontend tool handler returned into tool message content.
|
|
3173
|
+
* A non-empty array of AG-UI content parts passes through unchanged, so an
|
|
3174
|
+
* image reaches the model as media. Everything else becomes a string, as before.
|
|
3175
|
+
*
|
|
3176
|
+
* `text` is the string form, for surfaces typed as `result: string`
|
|
3177
|
+
* (`runTool`, `onToolExecutionEnd`). For content parts it is the JSON text they
|
|
3178
|
+
* received before. It is computed here, so a part that cannot be serialized
|
|
3179
|
+
* throws inside the caller's handler error boundary.
|
|
3180
|
+
*/
|
|
3181
|
+
function toToolResultContent(result) {
|
|
3182
|
+
if (result === void 0 || result === null) return {
|
|
3183
|
+
content: "",
|
|
3184
|
+
text: ""
|
|
3185
|
+
};
|
|
3186
|
+
if (typeof result === "string") return {
|
|
3187
|
+
content: result,
|
|
3188
|
+
text: result
|
|
3189
|
+
};
|
|
3190
|
+
const text = JSON.stringify(result);
|
|
3191
|
+
if (Array.isArray(result) && result.length > 0 && result.every(isContentPart)) return {
|
|
3192
|
+
content: result,
|
|
3193
|
+
text
|
|
3194
|
+
};
|
|
3195
|
+
return {
|
|
3196
|
+
content: text,
|
|
3197
|
+
text
|
|
3198
|
+
};
|
|
3199
|
+
}
|
|
3083
3200
|
|
|
3084
3201
|
//#endregion
|
|
3085
3202
|
//#region src/core/tool-schema.ts
|
|
@@ -3505,7 +3622,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
3505
3622
|
this.processAgentResult({
|
|
3506
3623
|
runAgentResult,
|
|
3507
3624
|
agent,
|
|
3508
|
-
toolExecutionMode: "
|
|
3625
|
+
toolExecutionMode: "restore",
|
|
3509
3626
|
signal: controller.signal
|
|
3510
3627
|
}).catch(async (error) => {
|
|
3511
3628
|
await this._internal.emitError({
|
|
@@ -3643,11 +3760,11 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
3643
3760
|
const threadId = agent.threadId;
|
|
3644
3761
|
const executing = (_this$_executingToolC = this._executingToolCalls.get(agent)) !== null && _this$_executingToolC !== void 0 ? _this$_executingToolC : /* @__PURE__ */ new Set();
|
|
3645
3762
|
this._executingToolCalls.set(agent, executing);
|
|
3646
|
-
if (toolExecutionMode === "
|
|
3763
|
+
if (toolExecutionMode === "restore" && agent.messages.some((message) => {
|
|
3647
3764
|
var _message$toolCalls;
|
|
3648
3765
|
return message.role === "assistant" && ((_message$toolCalls = message.toolCalls) === null || _message$toolCalls === void 0 ? void 0 : _message$toolCalls.some((call) => executing.has(JSON.stringify([threadId, call.id])) && !agent.messages.some((result) => result.role === "tool" && result.toolCallId === call.id && !this.isFrontendPlaceholderResult(result))));
|
|
3649
3766
|
})) return runAgentResult;
|
|
3650
|
-
const messagesToProcess = toolExecutionMode === "
|
|
3767
|
+
const messagesToProcess = toolExecutionMode === "restore" ? [...agent.messages] : newMessages;
|
|
3651
3768
|
for (const message of messagesToProcess) if (message.role === "assistant") for (const toolCall of message.toolCalls || []) {
|
|
3652
3769
|
var _agent$messages$find;
|
|
3653
3770
|
const tool = this.getTool({
|
|
@@ -3664,7 +3781,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
3664
3781
|
return wildcardTool;
|
|
3665
3782
|
};
|
|
3666
3783
|
const executableTool = tool !== null && tool !== void 0 ? tool : getWildcardTool();
|
|
3667
|
-
if (toolExecutionMode === "
|
|
3784
|
+
if (toolExecutionMode === "restore" && (!(executableTool === null || executableTool === void 0 ? void 0 : executableTool.handler) || executableTool.type !== "human-in-the-loop" && executableTool.reconnectBehavior !== "resume-pending")) continue;
|
|
3668
3785
|
const executionKey = JSON.stringify([threadId, toolCall.id]);
|
|
3669
3786
|
if ((signal === null || signal === void 0 ? void 0 : signal.aborted) || agent.threadId !== threadId || executing.has(executionKey)) continue;
|
|
3670
3787
|
const existingResultIndex = newMessages.findIndex((m) => m.role === "tool" && m.toolCallId === toolCall.id);
|
|
@@ -3696,14 +3813,14 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
3696
3813
|
if (signal === null || signal === void 0 ? void 0 : signal.aborted) abortInteraction();
|
|
3697
3814
|
}
|
|
3698
3815
|
const executionSignal = (_interactionControlle = interactionController === null || interactionController === void 0 ? void 0 : interactionController.signal) !== null && _interactionControlle !== void 0 ? _interactionControlle : signal;
|
|
3699
|
-
const discardOnAbort = toolExecutionMode === "
|
|
3816
|
+
const discardOnAbort = toolExecutionMode === "restore" || !!interactionController;
|
|
3700
3817
|
try {
|
|
3701
3818
|
if (tool) {
|
|
3702
|
-
if (await this.executeSpecificTool(tool, toolCall, message, agent, agentId, executionSignal, discardOnAbort)) needsFollowUp = true;
|
|
3819
|
+
if (await this.executeSpecificTool(tool, toolCall, message, agent, agentId, executionSignal, discardOnAbort, toolExecutionMode === "restore")) needsFollowUp = true;
|
|
3703
3820
|
} else {
|
|
3704
3821
|
const fallbackTool = getWildcardTool();
|
|
3705
3822
|
if (fallbackTool) {
|
|
3706
|
-
if (await this.executeWildcardTool(fallbackTool, toolCall, message, agent, agentId, executionSignal, discardOnAbort)) needsFollowUp = true;
|
|
3823
|
+
if (await this.executeWildcardTool(fallbackTool, toolCall, message, agent, agentId, executionSignal, discardOnAbort, toolExecutionMode === "restore")) needsFollowUp = true;
|
|
3707
3824
|
}
|
|
3708
3825
|
}
|
|
3709
3826
|
} finally {
|
|
@@ -3740,8 +3857,9 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
3740
3857
|
async executeToolHandler({ tool, toolCall, agent, agentId, handlerArgs, toolType, messageId, signal = (() => {
|
|
3741
3858
|
var _this$_runAbortContro3;
|
|
3742
3859
|
return (_this$_runAbortContro3 = this._runAbortController) === null || _this$_runAbortContro3 === void 0 ? void 0 : _this$_runAbortContro3.signal;
|
|
3743
|
-
})(), discardOnAbort = false }) {
|
|
3860
|
+
})(), discardOnAbort = false, isReplay = false }) {
|
|
3744
3861
|
let toolCallResult = "";
|
|
3862
|
+
let toolCallText = "";
|
|
3745
3863
|
let errorMessage;
|
|
3746
3864
|
let isArgumentError = false;
|
|
3747
3865
|
let parsedArgs;
|
|
@@ -3778,11 +3896,10 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
3778
3896
|
const result = await tool.handler(parsedArgs, {
|
|
3779
3897
|
toolCall,
|
|
3780
3898
|
agent,
|
|
3781
|
-
signal
|
|
3899
|
+
signal,
|
|
3900
|
+
...isReplay ? { isReplay } : {}
|
|
3782
3901
|
});
|
|
3783
|
-
|
|
3784
|
-
else if (typeof result === "string") toolCallResult = result;
|
|
3785
|
-
else toolCallResult = JSON.stringify(result);
|
|
3902
|
+
({content: toolCallResult, text: toolCallText} = toToolResultContent(result));
|
|
3786
3903
|
} catch (error) {
|
|
3787
3904
|
const handlerError = error instanceof Error ? error : new Error(String(error));
|
|
3788
3905
|
errorMessage = handlerError.message;
|
|
@@ -3799,7 +3916,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
3799
3916
|
}
|
|
3800
3917
|
});
|
|
3801
3918
|
}
|
|
3802
|
-
if (errorMessage) toolCallResult = `Error: ${errorMessage}`;
|
|
3919
|
+
if (errorMessage) toolCallResult = toolCallText = `Error: ${errorMessage}`;
|
|
3803
3920
|
await this._internal.notifySubscribers((subscriber) => {
|
|
3804
3921
|
var _subscriber$onToolExe2;
|
|
3805
3922
|
return (_subscriber$onToolExe2 = subscriber.onToolExecutionEnd) === null || _subscriber$onToolExe2 === void 0 ? void 0 : _subscriber$onToolExe2.call(subscriber, {
|
|
@@ -3807,12 +3924,13 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
3807
3924
|
toolCallId: toolCall.id,
|
|
3808
3925
|
agentId,
|
|
3809
3926
|
toolName: toolCall.function.name,
|
|
3810
|
-
result: errorMessage ? "" :
|
|
3927
|
+
result: errorMessage ? "" : toolCallText,
|
|
3811
3928
|
error: errorMessage
|
|
3812
3929
|
});
|
|
3813
3930
|
}, "Subscriber onToolExecutionEnd error:");
|
|
3814
3931
|
return {
|
|
3815
|
-
|
|
3932
|
+
content: toolCallResult,
|
|
3933
|
+
result: toolCallText,
|
|
3816
3934
|
error: errorMessage,
|
|
3817
3935
|
isArgumentError
|
|
3818
3936
|
};
|
|
@@ -3820,10 +3938,11 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
3820
3938
|
/**
|
|
3821
3939
|
* Execute a specific tool
|
|
3822
3940
|
*/
|
|
3823
|
-
async executeSpecificTool(tool, toolCall, message, agent, agentId, signal, discardOnAbort = false) {
|
|
3941
|
+
async executeSpecificTool(tool, toolCall, message, agent, agentId, signal, discardOnAbort = false, isReplay = false) {
|
|
3824
3942
|
const threadId = agent.threadId;
|
|
3825
3943
|
if ((tool === null || tool === void 0 ? void 0 : tool.agentId) && tool.agentId !== agent.agentId) return false;
|
|
3826
3944
|
let handlerResult = {
|
|
3945
|
+
content: "",
|
|
3827
3946
|
result: "",
|
|
3828
3947
|
error: void 0,
|
|
3829
3948
|
isArgumentError: false
|
|
@@ -3837,7 +3956,8 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
3837
3956
|
toolType: "specific",
|
|
3838
3957
|
messageId: message.id,
|
|
3839
3958
|
signal,
|
|
3840
|
-
discardOnAbort
|
|
3959
|
+
discardOnAbort,
|
|
3960
|
+
isReplay
|
|
3841
3961
|
});
|
|
3842
3962
|
{
|
|
3843
3963
|
var _agent$messages$inser;
|
|
@@ -3849,7 +3969,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
3849
3969
|
id: (0, _copilotkit_shared.randomUUID)(),
|
|
3850
3970
|
role: "tool",
|
|
3851
3971
|
toolCallId: toolCall.id,
|
|
3852
|
-
content: handlerResult.
|
|
3972
|
+
content: handlerResult.content
|
|
3853
3973
|
};
|
|
3854
3974
|
agent.messages.splice(insertAt, 0, toolMessage);
|
|
3855
3975
|
if (!handlerResult.error && (tool === null || tool === void 0 ? void 0 : tool.followUp) !== false) return true;
|
|
@@ -3862,10 +3982,11 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
3862
3982
|
* specific tools, so this method keeps its own arg-wrapping logic rather than
|
|
3863
3983
|
* delegating to `executeToolHandler`.
|
|
3864
3984
|
*/
|
|
3865
|
-
async executeWildcardTool(wildcardTool, toolCall, message, agent, agentId, signal, discardOnAbort = false) {
|
|
3985
|
+
async executeWildcardTool(wildcardTool, toolCall, message, agent, agentId, signal, discardOnAbort = false, isReplay = false) {
|
|
3866
3986
|
const threadId = agent.threadId;
|
|
3867
3987
|
if ((wildcardTool === null || wildcardTool === void 0 ? void 0 : wildcardTool.agentId) && wildcardTool.agentId !== agent.agentId) return false;
|
|
3868
3988
|
let toolCallResult = "";
|
|
3989
|
+
let toolCallText = "";
|
|
3869
3990
|
let errorMessage;
|
|
3870
3991
|
if (wildcardTool === null || wildcardTool === void 0 ? void 0 : wildcardTool.handler) {
|
|
3871
3992
|
let parsedArgs;
|
|
@@ -3905,11 +4026,10 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
3905
4026
|
const result = await wildcardTool.handler(wildcardArgs, {
|
|
3906
4027
|
toolCall,
|
|
3907
4028
|
agent,
|
|
3908
|
-
signal
|
|
4029
|
+
signal,
|
|
4030
|
+
...isReplay ? { isReplay } : {}
|
|
3909
4031
|
});
|
|
3910
|
-
|
|
3911
|
-
else if (typeof result === "string") toolCallResult = result;
|
|
3912
|
-
else toolCallResult = JSON.stringify(result);
|
|
4032
|
+
({content: toolCallResult, text: toolCallText} = toToolResultContent(result));
|
|
3913
4033
|
} catch (error) {
|
|
3914
4034
|
const handlerError = error instanceof Error ? error : new Error(String(error));
|
|
3915
4035
|
errorMessage = handlerError.message;
|
|
@@ -3926,7 +4046,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
3926
4046
|
}
|
|
3927
4047
|
});
|
|
3928
4048
|
}
|
|
3929
|
-
if (errorMessage) toolCallResult = `Error: ${errorMessage}`;
|
|
4049
|
+
if (errorMessage) toolCallResult = toolCallText = `Error: ${errorMessage}`;
|
|
3930
4050
|
await this._internal.notifySubscribers((subscriber) => {
|
|
3931
4051
|
var _subscriber$onToolExe4;
|
|
3932
4052
|
return (_subscriber$onToolExe4 = subscriber.onToolExecutionEnd) === null || _subscriber$onToolExe4 === void 0 ? void 0 : _subscriber$onToolExe4.call(subscriber, {
|
|
@@ -3934,7 +4054,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
3934
4054
|
toolCallId: toolCall.id,
|
|
3935
4055
|
agentId,
|
|
3936
4056
|
toolName: toolCall.function.name,
|
|
3937
|
-
result: errorMessage ? "" :
|
|
4057
|
+
result: errorMessage ? "" : toolCallText,
|
|
3938
4058
|
error: errorMessage
|
|
3939
4059
|
});
|
|
3940
4060
|
}, "Subscriber onToolExecutionEnd error:");
|
|
@@ -4007,6 +4127,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
4007
4127
|
};
|
|
4008
4128
|
agent.messages.push(assistantMessage);
|
|
4009
4129
|
let handlerResult = {
|
|
4130
|
+
content: "",
|
|
4010
4131
|
result: "",
|
|
4011
4132
|
error: void 0,
|
|
4012
4133
|
isArgumentError: false
|
|
@@ -4023,7 +4144,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
4023
4144
|
id: (0, _copilotkit_shared.randomUUID)(),
|
|
4024
4145
|
role: "tool",
|
|
4025
4146
|
toolCallId,
|
|
4026
|
-
content: handlerResult.
|
|
4147
|
+
content: handlerResult.content
|
|
4027
4148
|
};
|
|
4028
4149
|
const assistantIndex = agent.messages.findIndex((m) => m.id === assistantMessage.id);
|
|
4029
4150
|
if (assistantIndex !== -1) agent.messages.splice(assistantIndex + 1, 0, toolResultMessage);
|
|
@@ -4676,6 +4797,775 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
4676
4797
|
}
|
|
4677
4798
|
};
|
|
4678
4799
|
|
|
4800
|
+
//#endregion
|
|
4801
|
+
//#region src/core/trajectory-connection.ts
|
|
4802
|
+
const TIMEOUT_MS = 1e4;
|
|
4803
|
+
const BATCH_INTERVAL_MS = 2e3;
|
|
4804
|
+
const MAX_BATCH_EVENTS = 50;
|
|
4805
|
+
const MAX_BATCH_BYTES = 64 * 1024;
|
|
4806
|
+
const MAX_EVENT_BYTES = 16 * 1024;
|
|
4807
|
+
const byteLength = (value) => new TextEncoder().encode(JSON.stringify(value)).byteLength;
|
|
4808
|
+
const reconnectDelay = (0, _copilotkit_shared.phoenixExponentialBackoff)(1e3, 1e4);
|
|
4809
|
+
function isObject(value) {
|
|
4810
|
+
return typeof value === "object" && value !== null;
|
|
4811
|
+
}
|
|
4812
|
+
function isNonNegativeInteger(value) {
|
|
4813
|
+
return typeof value === "number" && Number.isSafeInteger(value) && value >= 0;
|
|
4814
|
+
}
|
|
4815
|
+
function isBatchAcknowledgement(value, eventCount) {
|
|
4816
|
+
return isObject(value) && isNonNegativeInteger(value.accepted) && isNonNegativeInteger(value.rejected) && value.accepted + value.rejected === eventCount && (value.highestSeq === null || isNonNegativeInteger(value.highestSeq)) && (value.accepted === 0 || value.highestSeq !== null);
|
|
4817
|
+
}
|
|
4818
|
+
function isGrant(value) {
|
|
4819
|
+
return isObject(value) && typeof value.joinToken === "string" && value.joinToken.length > 0 && isObject(value.realtime) && typeof value.realtime.clientUrl === "string" && value.realtime.clientUrl.length > 0 && typeof value.realtime.topic === "string" && value.realtime.topic.length > 0;
|
|
4820
|
+
}
|
|
4821
|
+
function errorCode(value, fallback) {
|
|
4822
|
+
return isObject(value) && typeof value.code === "string" && /^[A-Z][A-Z0-9_]{0,63}$/.test(value.code) ? value.code : fallback;
|
|
4823
|
+
}
|
|
4824
|
+
/** Owns bounded, connected-only capture batches. Failed batches are never resent. */
|
|
4825
|
+
var TrajectoryConnection = class {
|
|
4826
|
+
constructor(core, onChange) {
|
|
4827
|
+
this.core = core;
|
|
4828
|
+
this.onChange = onChange;
|
|
4829
|
+
_defineProperty(this, "session", void 0);
|
|
4830
|
+
_defineProperty(this, "nextSeq", Math.floor(Date.now()) * 1e3);
|
|
4831
|
+
}
|
|
4832
|
+
get trajectoryId() {
|
|
4833
|
+
var _this$session;
|
|
4834
|
+
return ((_this$session = this.session) === null || _this$session === void 0 ? void 0 : _this$session.ready) ? this.session.trajectoryId : null;
|
|
4835
|
+
}
|
|
4836
|
+
start(trajectoryId, config) {
|
|
4837
|
+
if (this.session && (trajectoryId === void 0 || trajectoryId === this.session.trajectoryId)) return this.session.promise;
|
|
4838
|
+
this.stop();
|
|
4839
|
+
const id = trajectoryId !== null && trajectoryId !== void 0 ? trajectoryId : crypto.randomUUID();
|
|
4840
|
+
let resolveStart;
|
|
4841
|
+
const promise = new Promise((resolve) => {
|
|
4842
|
+
resolveStart = resolve;
|
|
4843
|
+
});
|
|
4844
|
+
const session = {
|
|
4845
|
+
trajectoryId: id,
|
|
4846
|
+
config,
|
|
4847
|
+
promise,
|
|
4848
|
+
resolve: resolveStart,
|
|
4849
|
+
retries: 0,
|
|
4850
|
+
queue: [],
|
|
4851
|
+
dropped: 0,
|
|
4852
|
+
ready: false,
|
|
4853
|
+
started: false,
|
|
4854
|
+
offline: typeof navigator !== "undefined" && navigator.onLine === false,
|
|
4855
|
+
onOffline: () => {
|
|
4856
|
+
if (this.session !== session) return;
|
|
4857
|
+
session.offline = true;
|
|
4858
|
+
if (session.connection) this.fail(session, session.connection, "CONNECTION_LOST");
|
|
4859
|
+
clearTimeout(session.retry);
|
|
4860
|
+
session.retry = void 0;
|
|
4861
|
+
},
|
|
4862
|
+
onOnline: () => {
|
|
4863
|
+
if (this.session !== session) return;
|
|
4864
|
+
session.offline = false;
|
|
4865
|
+
if (!session.connection) {
|
|
4866
|
+
clearTimeout(session.retry);
|
|
4867
|
+
session.retry = void 0;
|
|
4868
|
+
this.connect(session);
|
|
4869
|
+
}
|
|
4870
|
+
},
|
|
4871
|
+
linkedThreads: /* @__PURE__ */ new Set(),
|
|
4872
|
+
agentWatches: /* @__PURE__ */ new Map()
|
|
4873
|
+
};
|
|
4874
|
+
this.session = session;
|
|
4875
|
+
session.runWatch = this.core.subscribe({ onAgentRunStarted: ({ agent }) => this.watchAgent(session, agent) });
|
|
4876
|
+
if (typeof window !== "undefined" && typeof window.addEventListener === "function") {
|
|
4877
|
+
window.addEventListener("offline", session.onOffline);
|
|
4878
|
+
window.addEventListener("online", session.onOnline);
|
|
4879
|
+
}
|
|
4880
|
+
if (session.offline) {
|
|
4881
|
+
this.report(session, "CONNECTION_LOST");
|
|
4882
|
+
this.end(session, {
|
|
4883
|
+
status: "error",
|
|
4884
|
+
code: "CONNECTION_LOST"
|
|
4885
|
+
});
|
|
4886
|
+
} else this.connect(session);
|
|
4887
|
+
return promise;
|
|
4888
|
+
}
|
|
4889
|
+
stop() {
|
|
4890
|
+
const session = this.session;
|
|
4891
|
+
if (!session) return;
|
|
4892
|
+
if (session.ready && session.connection) this.flush(session, session.connection);
|
|
4893
|
+
this.end(session, {
|
|
4894
|
+
status: "error",
|
|
4895
|
+
code: "CANCELLED"
|
|
4896
|
+
});
|
|
4897
|
+
}
|
|
4898
|
+
emit(name, value) {
|
|
4899
|
+
var _session$collector;
|
|
4900
|
+
const session = this.session;
|
|
4901
|
+
if (session === null || session === void 0 ? void 0 : session.ready) (_session$collector = session.collector) === null || _session$collector === void 0 || _session$collector.emit(name, value);
|
|
4902
|
+
else if (session === null || session === void 0 ? void 0 : session.started) this.addDropped(session, 1, false);
|
|
4903
|
+
}
|
|
4904
|
+
watchAgent(session, agent) {
|
|
4905
|
+
if (this.session !== session || session.agentWatches.has(agent)) return;
|
|
4906
|
+
session.agentWatches.set(agent, agent.subscribe({ onRunStartedEvent: ({ event }) => this.linkThread(session, event) }));
|
|
4907
|
+
}
|
|
4908
|
+
/** Sends one `thread.linked` per Thread. A link that cannot be sent waits for the next run. */
|
|
4909
|
+
linkThread(session, { threadId }) {
|
|
4910
|
+
const connection = session.connection;
|
|
4911
|
+
if (!session.ready || !connection || !threadId || session.linkedThreads.has(threadId)) return;
|
|
4912
|
+
session.linkedThreads.add(threadId);
|
|
4913
|
+
const event = {
|
|
4914
|
+
type: "CUSTOM",
|
|
4915
|
+
name: "thread.linked",
|
|
4916
|
+
timestamp: Date.now(),
|
|
4917
|
+
value: { threadId }
|
|
4918
|
+
};
|
|
4919
|
+
try {
|
|
4920
|
+
const { beforeSend } = session.config;
|
|
4921
|
+
const kept = beforeSend === void 0 ? event : beforeSend(event);
|
|
4922
|
+
if (kept !== null) this.send(session, connection, kept);
|
|
4923
|
+
} catch (_unused) {
|
|
4924
|
+
this.report(session, "INVALID_EVENT");
|
|
4925
|
+
}
|
|
4926
|
+
}
|
|
4927
|
+
report(session, code) {
|
|
4928
|
+
try {
|
|
4929
|
+
var _session$config$onErr, _session$config;
|
|
4930
|
+
(_session$config$onErr = (_session$config = session.config).onError) === null || _session$config$onErr === void 0 || _session$config$onErr.call(_session$config, {
|
|
4931
|
+
code,
|
|
4932
|
+
message: `Trajectory capture: ${code}.`
|
|
4933
|
+
});
|
|
4934
|
+
} catch (_unused2) {}
|
|
4935
|
+
}
|
|
4936
|
+
current(session, connection) {
|
|
4937
|
+
return this.session === session && session.connection === connection;
|
|
4938
|
+
}
|
|
4939
|
+
end(session, result) {
|
|
4940
|
+
var _session$runWatch, _session$collector2;
|
|
4941
|
+
if (this.session !== session) return;
|
|
4942
|
+
this.session = void 0;
|
|
4943
|
+
clearTimeout(session.retry);
|
|
4944
|
+
(_session$runWatch = session.runWatch) === null || _session$runWatch === void 0 || _session$runWatch.unsubscribe();
|
|
4945
|
+
for (const watch of session.agentWatches.values()) watch.unsubscribe();
|
|
4946
|
+
session.agentWatches.clear();
|
|
4947
|
+
(_session$collector2 = session.collector) === null || _session$collector2 === void 0 || _session$collector2.stop();
|
|
4948
|
+
session.ready = false;
|
|
4949
|
+
if (session.queue.length > 0) this.report(session, "EVENTS_DROPPED");
|
|
4950
|
+
this.discardQueue(session);
|
|
4951
|
+
if (session.connection) {
|
|
4952
|
+
for (const pending of session.connection.pending) {
|
|
4953
|
+
pending.finish("PERSISTENCE_UNKNOWN");
|
|
4954
|
+
this.report(session, "PERSISTENCE_UNKNOWN");
|
|
4955
|
+
}
|
|
4956
|
+
this.cleanup(session, session.connection);
|
|
4957
|
+
}
|
|
4958
|
+
if (typeof window !== "undefined" && typeof window.removeEventListener === "function") {
|
|
4959
|
+
window.removeEventListener("offline", session.onOffline);
|
|
4960
|
+
window.removeEventListener("online", session.onOnline);
|
|
4961
|
+
}
|
|
4962
|
+
session.resolve(result);
|
|
4963
|
+
this.onChange();
|
|
4964
|
+
}
|
|
4965
|
+
cleanup(session, connection) {
|
|
4966
|
+
session.connection = void 0;
|
|
4967
|
+
clearTimeout(connection.timer);
|
|
4968
|
+
connection.abort.abort();
|
|
4969
|
+
for (const pending of connection.pending) clearTimeout(pending.timer);
|
|
4970
|
+
connection.pending.clear();
|
|
4971
|
+
const { socket, channel } = connection;
|
|
4972
|
+
try {
|
|
4973
|
+
if (channel) {
|
|
4974
|
+
for (const [event, ref] of connection.channelRefs) channel.off(event, ref);
|
|
4975
|
+
channel.leave();
|
|
4976
|
+
}
|
|
4977
|
+
} finally {
|
|
4978
|
+
if (socket) {
|
|
4979
|
+
socket.off(connection.socketRefs);
|
|
4980
|
+
socket.disconnect();
|
|
4981
|
+
}
|
|
4982
|
+
}
|
|
4983
|
+
}
|
|
4984
|
+
fail(session, connection, code, retryable = true) {
|
|
4985
|
+
var _session$collector3;
|
|
4986
|
+
if (!this.current(session, connection)) return;
|
|
4987
|
+
(_session$collector3 = session.collector) === null || _session$collector3 === void 0 || _session$collector3.stop();
|
|
4988
|
+
session.collector = void 0;
|
|
4989
|
+
if (session.ready && session.started) session.promise = new Promise((resolve) => {
|
|
4990
|
+
session.resolve = resolve;
|
|
4991
|
+
});
|
|
4992
|
+
session.ready = false;
|
|
4993
|
+
this.discardQueue(session);
|
|
4994
|
+
session.linkedThreads.clear();
|
|
4995
|
+
for (const pending of connection.pending) pending.finish("PERSISTENCE_UNKNOWN");
|
|
4996
|
+
if (!this.current(session, connection)) return;
|
|
4997
|
+
this.cleanup(session, connection);
|
|
4998
|
+
this.onChange();
|
|
4999
|
+
this.report(session, code);
|
|
5000
|
+
if (this.session !== session) return;
|
|
5001
|
+
if (!session.started || !retryable) {
|
|
5002
|
+
this.end(session, {
|
|
5003
|
+
status: "error",
|
|
5004
|
+
code
|
|
5005
|
+
});
|
|
5006
|
+
return;
|
|
5007
|
+
}
|
|
5008
|
+
if (session.offline || this.session !== session) return;
|
|
5009
|
+
session.retry = setTimeout(() => {
|
|
5010
|
+
session.retry = void 0;
|
|
5011
|
+
if (this.session === session && !session.offline) this.connect(session);
|
|
5012
|
+
}, reconnectDelay(++session.retries));
|
|
5013
|
+
}
|
|
5014
|
+
async connect(session) {
|
|
5015
|
+
if (this.session !== session || session.offline || session.connection) return;
|
|
5016
|
+
const connection = {
|
|
5017
|
+
abort: new AbortController(),
|
|
5018
|
+
socketRefs: [],
|
|
5019
|
+
channelRefs: [],
|
|
5020
|
+
pending: /* @__PURE__ */ new Set()
|
|
5021
|
+
};
|
|
5022
|
+
session.connection = connection;
|
|
5023
|
+
connection.timer = setTimeout(() => this.fail(session, connection, "CONNECTION_TIMEOUT"), TIMEOUT_MS);
|
|
5024
|
+
try {
|
|
5025
|
+
var _this$core$ɵruntimeE;
|
|
5026
|
+
const runtimeUrl = this.core.runtimeUrl;
|
|
5027
|
+
if (!runtimeUrl) {
|
|
5028
|
+
this.fail(session, connection, "RUNTIME_REQUIRED", false);
|
|
5029
|
+
return;
|
|
5030
|
+
}
|
|
5031
|
+
let transport = this.core.runtimeTransport;
|
|
5032
|
+
if (transport === "auto") {
|
|
5033
|
+
transport = await this.detectedTransport(connection.abort.signal);
|
|
5034
|
+
if (!this.current(session, connection)) return;
|
|
5035
|
+
}
|
|
5036
|
+
const rest = transport === "rest";
|
|
5037
|
+
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, {
|
|
5038
|
+
method: "POST",
|
|
5039
|
+
redirect: "error",
|
|
5040
|
+
signal: connection.abort.signal,
|
|
5041
|
+
headers: {
|
|
5042
|
+
...this.core.headers,
|
|
5043
|
+
"Content-Type": "application/json"
|
|
5044
|
+
},
|
|
5045
|
+
credentials: this.core.credentials,
|
|
5046
|
+
body: JSON.stringify(rest ? {} : {
|
|
5047
|
+
method: "trajectory/connect",
|
|
5048
|
+
params: { trajectoryId: session.trajectoryId },
|
|
5049
|
+
body: {}
|
|
5050
|
+
})
|
|
5051
|
+
});
|
|
5052
|
+
if (!this.current(session, connection)) return;
|
|
5053
|
+
const payload = await response.json().catch(() => void 0);
|
|
5054
|
+
if (!this.current(session, connection)) return;
|
|
5055
|
+
if (!response.ok) {
|
|
5056
|
+
this.fail(session, connection, errorCode(payload, "CONNECTION_FAILED"), response.status >= 500 || response.status === 408 || response.status === 429);
|
|
5057
|
+
return;
|
|
5058
|
+
}
|
|
5059
|
+
if (!isGrant(payload)) {
|
|
5060
|
+
this.fail(session, connection, "INVALID_GRANT", false);
|
|
5061
|
+
return;
|
|
5062
|
+
}
|
|
5063
|
+
const socket = new phoenix.Socket(payload.realtime.clientUrl, {
|
|
5064
|
+
params: { join_token: payload.joinToken },
|
|
5065
|
+
timeout: TIMEOUT_MS
|
|
5066
|
+
});
|
|
5067
|
+
connection.socket = socket;
|
|
5068
|
+
const lost = () => this.fail(session, connection, "CONNECTION_LOST");
|
|
5069
|
+
connection.socketRefs.push(socket.onError(lost), socket.onClose(lost));
|
|
5070
|
+
const channel = socket.channel(payload.realtime.topic, {});
|
|
5071
|
+
connection.channel = channel;
|
|
5072
|
+
connection.channelRefs.push(["phx_error", channel.onError(lost)], ["phx_close", channel.onClose(lost)]);
|
|
5073
|
+
socket.connect();
|
|
5074
|
+
if (!this.current(session, connection)) return;
|
|
5075
|
+
channel.join(TIMEOUT_MS).receive("ok", () => {
|
|
5076
|
+
if (!this.current(session, connection)) return;
|
|
5077
|
+
try {
|
|
5078
|
+
var _session$config$ignor;
|
|
5079
|
+
clearTimeout(connection.timer);
|
|
5080
|
+
session.ready = true;
|
|
5081
|
+
session.retries = 0;
|
|
5082
|
+
session.collector = (0, _copilotkit_learning.createTrajectoryCollector)({
|
|
5083
|
+
...session.config,
|
|
5084
|
+
ignoreUrls: [
|
|
5085
|
+
...(_session$config$ignor = session.config.ignoreUrls) !== null && _session$config$ignor !== void 0 ? _session$config$ignor : [],
|
|
5086
|
+
...this.core.runtimeUrl ? [this.core.runtimeUrl] : [],
|
|
5087
|
+
...this.core.ɵruntimeEndpointUrl ? [this.core.ɵruntimeEndpointUrl] : [],
|
|
5088
|
+
"https://telemetry.copilotkit.ai/",
|
|
5089
|
+
"https://cdn.copilotkit.ai/"
|
|
5090
|
+
],
|
|
5091
|
+
onError: (error) => {
|
|
5092
|
+
if (error.code === "CAPTURE_FAILED") this.fail(session, connection, error.code, false);
|
|
5093
|
+
else {
|
|
5094
|
+
var _session$config$onErr2, _session$config2;
|
|
5095
|
+
if (error.code === "INVALID_EVENT" || error.code === "EVENT_TOO_LARGE") this.addDropped(session, 1);
|
|
5096
|
+
(_session$config$onErr2 = (_session$config2 = session.config).onError) === null || _session$config$onErr2 === void 0 || _session$config$onErr2.call(_session$config2, error);
|
|
5097
|
+
}
|
|
5098
|
+
},
|
|
5099
|
+
send: (event) => this.send(session, connection, event)
|
|
5100
|
+
});
|
|
5101
|
+
session.collector.start();
|
|
5102
|
+
if (!this.current(session, connection)) return;
|
|
5103
|
+
if (session.dropped > 0) this.scheduleFlush(session, connection);
|
|
5104
|
+
session.started = true;
|
|
5105
|
+
session.resolve({
|
|
5106
|
+
status: "started",
|
|
5107
|
+
trajectoryId: session.trajectoryId
|
|
5108
|
+
});
|
|
5109
|
+
this.onChange();
|
|
5110
|
+
} catch (_unused3) {
|
|
5111
|
+
this.fail(session, connection, "CAPTURE_FAILED", false);
|
|
5112
|
+
}
|
|
5113
|
+
}).receive("error", (joinError) => this.fail(session, connection, errorCode(joinError, "JOIN_FAILED"))).receive("timeout", () => this.fail(session, connection, "CONNECTION_TIMEOUT"));
|
|
5114
|
+
} catch (_unused4) {
|
|
5115
|
+
this.fail(session, connection, "CONNECTION_FAILED");
|
|
5116
|
+
}
|
|
5117
|
+
}
|
|
5118
|
+
/** Resolves once auto-detection picks a transport, or with "auto" when the attempt is aborted. */
|
|
5119
|
+
detectedTransport(signal) {
|
|
5120
|
+
return new Promise((resolve) => {
|
|
5121
|
+
const finish = () => {
|
|
5122
|
+
subscription.unsubscribe();
|
|
5123
|
+
signal.removeEventListener("abort", finish);
|
|
5124
|
+
resolve(this.core.runtimeTransport);
|
|
5125
|
+
};
|
|
5126
|
+
const subscription = this.core.subscribe({ onRuntimeConnectionStatusChanged: () => {
|
|
5127
|
+
if (this.core.runtimeTransport !== "auto") finish();
|
|
5128
|
+
} });
|
|
5129
|
+
signal.addEventListener("abort", finish, { once: true });
|
|
5130
|
+
});
|
|
5131
|
+
}
|
|
5132
|
+
addDropped(session, count, schedule = true) {
|
|
5133
|
+
session.dropped = Math.min(Number.MAX_SAFE_INTEGER, session.dropped + count);
|
|
5134
|
+
if (schedule && count > 0 && session.ready && session.connection) this.scheduleFlush(session, session.connection);
|
|
5135
|
+
}
|
|
5136
|
+
scheduleFlush(session, connection) {
|
|
5137
|
+
if (session.flushTimer !== void 0 || !this.current(session, connection)) return;
|
|
5138
|
+
session.flushTimer = setTimeout(() => {
|
|
5139
|
+
session.flushTimer = void 0;
|
|
5140
|
+
this.flush(session, connection);
|
|
5141
|
+
}, BATCH_INTERVAL_MS);
|
|
5142
|
+
}
|
|
5143
|
+
discardQueue(session) {
|
|
5144
|
+
clearTimeout(session.flushTimer);
|
|
5145
|
+
session.flushTimer = void 0;
|
|
5146
|
+
this.addDropped(session, session.queue.length, false);
|
|
5147
|
+
session.queue = [];
|
|
5148
|
+
}
|
|
5149
|
+
connected(connection) {
|
|
5150
|
+
var _connection$socket, _connection$channel;
|
|
5151
|
+
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";
|
|
5152
|
+
}
|
|
5153
|
+
send(session, connection, event) {
|
|
5154
|
+
if (!this.current(session, connection) || !session.ready) return;
|
|
5155
|
+
if (!this.connected(connection)) {
|
|
5156
|
+
this.addDropped(session, 1);
|
|
5157
|
+
this.fail(session, connection, "CONNECTION_LOST");
|
|
5158
|
+
return;
|
|
5159
|
+
}
|
|
5160
|
+
if (!Number.isSafeInteger(this.nextSeq)) {
|
|
5161
|
+
this.addDropped(session, 1);
|
|
5162
|
+
this.report(session, "SEQUENCE_EXHAUSTED");
|
|
5163
|
+
return;
|
|
5164
|
+
}
|
|
5165
|
+
const original = event.value;
|
|
5166
|
+
const fields = isObject(original) && !Array.isArray(original) && !Object.hasOwn(original, "seq") ? original : { data: original };
|
|
5167
|
+
const wire = {
|
|
5168
|
+
...event,
|
|
5169
|
+
value: {
|
|
5170
|
+
...fields,
|
|
5171
|
+
seq: this.nextSeq++
|
|
5172
|
+
}
|
|
5173
|
+
};
|
|
5174
|
+
if (byteLength(wire) > MAX_EVENT_BYTES) {
|
|
5175
|
+
this.addDropped(session, 1);
|
|
5176
|
+
this.report(session, "EVENT_TOO_LARGE");
|
|
5177
|
+
return;
|
|
5178
|
+
}
|
|
5179
|
+
const fits = () => session.queue.length < MAX_BATCH_EVENTS && byteLength({
|
|
5180
|
+
events: [...session.queue, wire],
|
|
5181
|
+
dropped: Number.MAX_SAFE_INTEGER
|
|
5182
|
+
}) <= MAX_BATCH_BYTES;
|
|
5183
|
+
if (!fits()) this.flush(session, connection);
|
|
5184
|
+
if (!this.current(session, connection) || !session.ready) return;
|
|
5185
|
+
if (!fits()) {
|
|
5186
|
+
this.addDropped(session, 1);
|
|
5187
|
+
this.report(session, "EVENTS_DROPPED");
|
|
5188
|
+
return;
|
|
5189
|
+
}
|
|
5190
|
+
session.queue.push(wire);
|
|
5191
|
+
if (session.queue.length === MAX_BATCH_EVENTS) this.flush(session, connection);
|
|
5192
|
+
else this.scheduleFlush(session, connection);
|
|
5193
|
+
}
|
|
5194
|
+
flush(session, connection) {
|
|
5195
|
+
if (!this.current(session, connection) || !session.ready || session.queue.length === 0 && session.dropped === 0) return;
|
|
5196
|
+
if (!this.connected(connection)) {
|
|
5197
|
+
this.fail(session, connection, "CONNECTION_LOST");
|
|
5198
|
+
return;
|
|
5199
|
+
}
|
|
5200
|
+
if (connection.pending.size > 0) return;
|
|
5201
|
+
clearTimeout(session.flushTimer);
|
|
5202
|
+
session.flushTimer = void 0;
|
|
5203
|
+
const batch = {
|
|
5204
|
+
events: session.queue,
|
|
5205
|
+
dropped: session.dropped
|
|
5206
|
+
};
|
|
5207
|
+
session.queue = [];
|
|
5208
|
+
session.dropped = 0;
|
|
5209
|
+
let finished = false;
|
|
5210
|
+
const pending = {
|
|
5211
|
+
timer: setTimeout(() => pending.finish("PERSISTENCE_UNKNOWN"), TIMEOUT_MS),
|
|
5212
|
+
finish: (code, knownRollback = false, flushNext = true) => {
|
|
5213
|
+
if (finished) return;
|
|
5214
|
+
finished = true;
|
|
5215
|
+
clearTimeout(pending.timer);
|
|
5216
|
+
connection.pending.delete(pending);
|
|
5217
|
+
if (knownRollback) this.addDropped(session, batch.events.length + batch.dropped, false);
|
|
5218
|
+
if (code && this.current(session, connection)) this.report(session, code);
|
|
5219
|
+
if (flushNext && this.current(session, connection) && session.ready && (session.queue.length > 0 || !knownRollback && session.dropped > 0)) this.flush(session, connection);
|
|
5220
|
+
}
|
|
5221
|
+
};
|
|
5222
|
+
connection.pending.add(pending);
|
|
5223
|
+
try {
|
|
5224
|
+
connection.channel.push("events", batch, TIMEOUT_MS).receive("ok", (payload) => {
|
|
5225
|
+
pending.finish(!isBatchAcknowledgement(payload, batch.events.length) ? "PERSISTENCE_UNKNOWN" : payload.rejected > 0 ? "EVENTS_REJECTED" : void 0);
|
|
5226
|
+
}).receive("error", (payload) => {
|
|
5227
|
+
if (!this.current(session, connection)) return;
|
|
5228
|
+
const reason = isObject(payload) ? payload.reason : void 0;
|
|
5229
|
+
if (reason === "unauthorized" || reason === "trajectory_mismatch") {
|
|
5230
|
+
pending.finish(void 0, true, false);
|
|
5231
|
+
this.fail(session, connection, reason.toUpperCase(), false);
|
|
5232
|
+
return;
|
|
5233
|
+
}
|
|
5234
|
+
const rollback = typeof reason === "string" && [
|
|
5235
|
+
"invalid_batch",
|
|
5236
|
+
"batch_too_large",
|
|
5237
|
+
"batch_too_many_events",
|
|
5238
|
+
"trajectory_over_share",
|
|
5239
|
+
"trajectory_outbox_full",
|
|
5240
|
+
"unsupported_event"
|
|
5241
|
+
].includes(reason);
|
|
5242
|
+
pending.finish(rollback ? reason.toUpperCase() : "PERSISTENCE_UNKNOWN", rollback);
|
|
5243
|
+
}).receive("timeout", () => pending.finish("PERSISTENCE_UNKNOWN"));
|
|
5244
|
+
} catch (_unused5) {
|
|
5245
|
+
pending.finish("PERSISTENCE_UNKNOWN");
|
|
5246
|
+
}
|
|
5247
|
+
}
|
|
5248
|
+
};
|
|
5249
|
+
|
|
5250
|
+
//#endregion
|
|
5251
|
+
//#region src/core/learning-bridge.ts
|
|
5252
|
+
const COPILOTKIT_OWN_URLS = ["https://telemetry.copilotkit.ai/", "https://cdn.copilotkit.ai/"];
|
|
5253
|
+
/**
|
|
5254
|
+
* Wires `@copilotkit/learning` into Core. Default capture uses Runtime and Phoenix;
|
|
5255
|
+
* explicit legacy sinks also use agent events and open-Thread attribution.
|
|
5256
|
+
*/
|
|
5257
|
+
var LearningBridge = class {
|
|
5258
|
+
constructor(core, config, onChange = () => {}) {
|
|
5259
|
+
this.core = core;
|
|
5260
|
+
this.config = config;
|
|
5261
|
+
_defineProperty(this, "collector", null);
|
|
5262
|
+
_defineProperty(this, "agents", /* @__PURE__ */ new Map());
|
|
5263
|
+
_defineProperty(this, "openThreads", /* @__PURE__ */ new Set());
|
|
5264
|
+
_defineProperty(this, "toolCalls", /* @__PURE__ */ new Map());
|
|
5265
|
+
_defineProperty(this, "executingTools", /* @__PURE__ */ new Map());
|
|
5266
|
+
_defineProperty(this, "lastRunIds", /* @__PURE__ */ new WeakMap());
|
|
5267
|
+
_defineProperty(this, "lastLinkedThreadId", null);
|
|
5268
|
+
_defineProperty(this, "coreSubscription", null);
|
|
5269
|
+
_defineProperty(this, "seq", 0);
|
|
5270
|
+
_defineProperty(this, "activeConfig", void 0);
|
|
5271
|
+
_defineProperty(this, "connection", void 0);
|
|
5272
|
+
this.connection = new TrajectoryConnection(core, onChange);
|
|
5273
|
+
this.setConfig(config);
|
|
5274
|
+
}
|
|
5275
|
+
setConfig(config) {
|
|
5276
|
+
this.config = config;
|
|
5277
|
+
if (config === void 0) this.stop();
|
|
5278
|
+
}
|
|
5279
|
+
get isConfigured() {
|
|
5280
|
+
return this.config !== void 0;
|
|
5281
|
+
}
|
|
5282
|
+
get isLegacyCaptureActive() {
|
|
5283
|
+
return this.collector !== null && this.collector.trajectoryId !== null;
|
|
5284
|
+
}
|
|
5285
|
+
startTracking() {
|
|
5286
|
+
if (this.coreSubscription !== null || !this.isLegacyCaptureActive) return;
|
|
5287
|
+
this.coreSubscription = this.core.subscribe({
|
|
5288
|
+
onAgentsChanged: ({ agents }) => {
|
|
5289
|
+
for (const agent of Object.values(agents)) this.track(agent);
|
|
5290
|
+
},
|
|
5291
|
+
onAgentRunStarted: ({ agent }) => this.track(agent),
|
|
5292
|
+
onToolExecutionStart: ({ toolCallId, agentId, toolName }) => {
|
|
5293
|
+
if (!this.isLegacyCaptureActive) return;
|
|
5294
|
+
this.executingTools.set(toolCallId, Date.now());
|
|
5295
|
+
this.emitToolCall("executing", toolCallId, agentId, toolName, {});
|
|
5296
|
+
},
|
|
5297
|
+
onToolExecutionEnd: ({ toolCallId, agentId, toolName, error }) => {
|
|
5298
|
+
if (!this.isLegacyCaptureActive) return;
|
|
5299
|
+
const startedAt = this.executingTools.get(toolCallId);
|
|
5300
|
+
this.executingTools.delete(toolCallId);
|
|
5301
|
+
this.emitToolCall("completed", toolCallId, agentId, toolName, {
|
|
5302
|
+
durationMs: startedAt === void 0 ? void 0 : Date.now() - startedAt,
|
|
5303
|
+
outcome: error === void 0 ? "ok" : "error"
|
|
5304
|
+
});
|
|
5305
|
+
this.toolCalls.delete(toolCallId);
|
|
5306
|
+
}
|
|
5307
|
+
});
|
|
5308
|
+
for (const agent of Object.values(this.core.agents)) this.track(agent);
|
|
5309
|
+
}
|
|
5310
|
+
get trajectoryId() {
|
|
5311
|
+
var _ref, _this$connection$traj, _this$collector;
|
|
5312
|
+
return (_ref = (_this$connection$traj = this.connection.trajectoryId) !== null && _this$connection$traj !== void 0 ? _this$connection$traj : (_this$collector = this.collector) === null || _this$collector === void 0 ? void 0 : _this$collector.trajectoryId) !== null && _ref !== void 0 ? _ref : null;
|
|
5313
|
+
}
|
|
5314
|
+
start(options = {}) {
|
|
5315
|
+
var _ref2, _options$trajectoryId, _this$collector2;
|
|
5316
|
+
const config = this.config;
|
|
5317
|
+
if (config === void 0) {
|
|
5318
|
+
console.warn("[CopilotKit] startTrajectory() needs the `learning` option on CopilotKitCore (or the CopilotKitProvider `learning` prop).");
|
|
5319
|
+
return Promise.resolve({
|
|
5320
|
+
status: "error",
|
|
5321
|
+
code: "LEARNING_DISABLED"
|
|
5322
|
+
});
|
|
5323
|
+
}
|
|
5324
|
+
if (config.sink === void 0) {
|
|
5325
|
+
if (options.learningContainerIds !== void 0) console.warn("[CopilotKit] learningContainerIds is supported only with a custom sink. Authenticated Trajectory capture does not assign Learning Containers; remove learningContainerIds from the capture options.");
|
|
5326
|
+
this.stopLegacy();
|
|
5327
|
+
return this.connection.start(options.trajectoryId, config);
|
|
5328
|
+
}
|
|
5329
|
+
this.connection.stop();
|
|
5330
|
+
const trajectoryId = (_ref2 = (_options$trajectoryId = options.trajectoryId) !== null && _options$trajectoryId !== void 0 ? _options$trajectoryId : (_this$collector2 = this.collector) === null || _this$collector2 === void 0 ? void 0 : _this$collector2.trajectoryId) !== null && _ref2 !== void 0 ? _ref2 : crypto.randomUUID();
|
|
5331
|
+
if (this.collector === null) {
|
|
5332
|
+
var _config$ignoreUrls;
|
|
5333
|
+
this.activeConfig = config;
|
|
5334
|
+
const runtimeUrl = this.core.runtimeUrl;
|
|
5335
|
+
this.collector = (0, _copilotkit_learning.createCollector)({
|
|
5336
|
+
...config,
|
|
5337
|
+
beforeSend: (event) => {
|
|
5338
|
+
const sequenced = {
|
|
5339
|
+
...event,
|
|
5340
|
+
value: {
|
|
5341
|
+
...event.value,
|
|
5342
|
+
seq: ++this.seq
|
|
5343
|
+
}
|
|
5344
|
+
};
|
|
5345
|
+
return config.beforeSend === void 0 ? sequenced : config.beforeSend(sequenced);
|
|
5346
|
+
},
|
|
5347
|
+
ignoreUrls: [
|
|
5348
|
+
...(_config$ignoreUrls = config.ignoreUrls) !== null && _config$ignoreUrls !== void 0 ? _config$ignoreUrls : [],
|
|
5349
|
+
...COPILOTKIT_OWN_URLS,
|
|
5350
|
+
...runtimeUrl === void 0 ? [] : [runtimeUrl]
|
|
5351
|
+
],
|
|
5352
|
+
enrich: (target) => this.enrich(target)
|
|
5353
|
+
});
|
|
5354
|
+
}
|
|
5355
|
+
const wasActive = this.collector.trajectoryId !== null;
|
|
5356
|
+
this.collector.start({
|
|
5357
|
+
...options,
|
|
5358
|
+
trajectoryId
|
|
5359
|
+
});
|
|
5360
|
+
if (wasActive) return Promise.resolve(this.collector.trajectoryId === trajectoryId ? {
|
|
5361
|
+
status: "started",
|
|
5362
|
+
trajectoryId
|
|
5363
|
+
} : {
|
|
5364
|
+
status: "error",
|
|
5365
|
+
code: "TRAJECTORY_ACTIVE"
|
|
5366
|
+
});
|
|
5367
|
+
this.startTracking();
|
|
5368
|
+
this.lastLinkedThreadId = null;
|
|
5369
|
+
for (const threadId of this.distinctOpenThreadIds()) this.emitThreadLinked(threadId, "start");
|
|
5370
|
+
return Promise.resolve({
|
|
5371
|
+
status: "started",
|
|
5372
|
+
trajectoryId
|
|
5373
|
+
});
|
|
5374
|
+
}
|
|
5375
|
+
stop() {
|
|
5376
|
+
this.connection.stop();
|
|
5377
|
+
this.stopLegacy();
|
|
5378
|
+
}
|
|
5379
|
+
stopLegacy() {
|
|
5380
|
+
var _this$collector3, _this$coreSubscriptio;
|
|
5381
|
+
(_this$collector3 = this.collector) === null || _this$collector3 === void 0 || _this$collector3.stop();
|
|
5382
|
+
this.collector = null;
|
|
5383
|
+
this.activeConfig = void 0;
|
|
5384
|
+
(_this$coreSubscriptio = this.coreSubscription) === null || _this$coreSubscriptio === void 0 || _this$coreSubscriptio.unsubscribe();
|
|
5385
|
+
this.coreSubscription = null;
|
|
5386
|
+
for (const subscription of this.agents.values()) subscription.unsubscribe();
|
|
5387
|
+
this.agents.clear();
|
|
5388
|
+
this.toolCalls.clear();
|
|
5389
|
+
this.executingTools.clear();
|
|
5390
|
+
}
|
|
5391
|
+
/** A developer event. Only an explicit legacy sink adds open-Thread context. */
|
|
5392
|
+
emit(name, value) {
|
|
5393
|
+
this.connection.emit(name, value);
|
|
5394
|
+
if (value !== null && typeof value === "object" && !Array.isArray(value)) {
|
|
5395
|
+
var _this$collector4;
|
|
5396
|
+
(_this$collector4 = this.collector) === null || _this$collector4 === void 0 || _this$collector4.emit(name, {
|
|
5397
|
+
...this.openThreadContext(),
|
|
5398
|
+
...value
|
|
5399
|
+
});
|
|
5400
|
+
}
|
|
5401
|
+
}
|
|
5402
|
+
registerOpenThread(params) {
|
|
5403
|
+
const entry = { ...params };
|
|
5404
|
+
const isNew = !this.distinctOpenThreadIds().includes(entry.threadId);
|
|
5405
|
+
this.openThreads.add(entry);
|
|
5406
|
+
if (isNew) this.emitThreadLinked(entry.threadId, "open");
|
|
5407
|
+
return {
|
|
5408
|
+
update: (threadId) => {
|
|
5409
|
+
if (threadId === entry.threadId) return;
|
|
5410
|
+
entry.threadId = threadId;
|
|
5411
|
+
if (![...this.openThreads].filter((other) => other !== entry).some((other) => other.threadId === threadId)) this.emitThreadLinked(threadId, "switch");
|
|
5412
|
+
},
|
|
5413
|
+
unregister: () => {
|
|
5414
|
+
this.openThreads.delete(entry);
|
|
5415
|
+
}
|
|
5416
|
+
};
|
|
5417
|
+
}
|
|
5418
|
+
distinctOpenThreadIds() {
|
|
5419
|
+
return [...new Set([...this.openThreads].map((open) => open.threadId))];
|
|
5420
|
+
}
|
|
5421
|
+
emitThreadLinked(threadId, reason) {
|
|
5422
|
+
var _this$collector5, _ref3, _owner$agentId, _agent$messages$lengt;
|
|
5423
|
+
if (!(this.collector !== null && this.collector.trajectoryId !== null) || threadId === this.lastLinkedThreadId) return;
|
|
5424
|
+
this.lastLinkedThreadId = threadId;
|
|
5425
|
+
const owner = [...this.openThreads].find((open) => open.threadId === threadId);
|
|
5426
|
+
const agent = this.findAgentForThread(threadId);
|
|
5427
|
+
(_this$collector5 = this.collector) === null || _this$collector5 === void 0 || _this$collector5.ɵemit("thread.linked", {
|
|
5428
|
+
threadId,
|
|
5429
|
+
agentId: (_ref3 = (_owner$agentId = owner === null || owner === void 0 ? void 0 : owner.agentId) !== null && _owner$agentId !== void 0 ? _owner$agentId : agent === null || agent === void 0 ? void 0 : agent.agentId) !== null && _ref3 !== void 0 ? _ref3 : null,
|
|
5430
|
+
hasMessages: ((_agent$messages$lengt = agent === null || agent === void 0 ? void 0 : agent.messages.length) !== null && _agent$messages$lengt !== void 0 ? _agent$messages$lengt : 0) > 0,
|
|
5431
|
+
reason
|
|
5432
|
+
});
|
|
5433
|
+
}
|
|
5434
|
+
findAgentForThread(threadId) {
|
|
5435
|
+
return [...this.agents.keys()].find((agent) => agent.threadId === threadId);
|
|
5436
|
+
}
|
|
5437
|
+
track(agent) {
|
|
5438
|
+
const agentId = agent.agentId;
|
|
5439
|
+
if (!this.isLegacyCaptureActive || this.agents.has(agent) || agentId === void 0) return;
|
|
5440
|
+
this.agents.set(agent, agent.subscribe(this.agentSubscriber(agent, agentId)));
|
|
5441
|
+
}
|
|
5442
|
+
agentSubscriber(agent, agentId) {
|
|
5443
|
+
const runIdFor = () => this.lastRunIds.get(agent);
|
|
5444
|
+
return {
|
|
5445
|
+
onRunStartedEvent: ({ event }) => {
|
|
5446
|
+
this.lastRunIds.set(agent, event.runId);
|
|
5447
|
+
this.emitRun("started", agent, event.threadId, event.runId);
|
|
5448
|
+
},
|
|
5449
|
+
onRunFinishedEvent: ({ event }) => {
|
|
5450
|
+
this.emitRun("finished", agent, event.threadId, event.runId);
|
|
5451
|
+
},
|
|
5452
|
+
onRunErrorEvent: () => {
|
|
5453
|
+
var _runIdFor;
|
|
5454
|
+
this.emitRun("error", agent, agent.threadId, (_runIdFor = runIdFor()) !== null && _runIdFor !== void 0 ? _runIdFor : null);
|
|
5455
|
+
},
|
|
5456
|
+
onToolCallStartEvent: ({ event }) => {
|
|
5457
|
+
if (!this.isLegacyCaptureActive) return;
|
|
5458
|
+
const origin = {
|
|
5459
|
+
agentId,
|
|
5460
|
+
threadId: agent.threadId,
|
|
5461
|
+
messageId: event.parentMessageId,
|
|
5462
|
+
runId: runIdFor()
|
|
5463
|
+
};
|
|
5464
|
+
this.toolCalls.set(event.toolCallId, origin);
|
|
5465
|
+
this.emitToolCall("started", event.toolCallId, origin.agentId, event.toolCallName, {});
|
|
5466
|
+
},
|
|
5467
|
+
onToolCallResultEvent: ({ event }) => {
|
|
5468
|
+
if (!this.executingTools.has(event.toolCallId)) this.toolCalls.delete(event.toolCallId);
|
|
5469
|
+
},
|
|
5470
|
+
onNewMessage: ({ message }) => this.emitMessage(agent, message)
|
|
5471
|
+
};
|
|
5472
|
+
}
|
|
5473
|
+
emitRun(phase, agent, threadId, runId) {
|
|
5474
|
+
var _this$collector6;
|
|
5475
|
+
(_this$collector6 = this.collector) === null || _this$collector6 === void 0 || _this$collector6.ɵemit("agent.run", {
|
|
5476
|
+
phase,
|
|
5477
|
+
runId,
|
|
5478
|
+
threadId,
|
|
5479
|
+
agentId: agent.agentId
|
|
5480
|
+
});
|
|
5481
|
+
}
|
|
5482
|
+
emitMessage(agent, message) {
|
|
5483
|
+
var _this$activeConfig, _this$collector7;
|
|
5484
|
+
const content = typeof message.content === "string" ? message.content : "";
|
|
5485
|
+
const includeText = ((_this$activeConfig = this.activeConfig) === null || _this$activeConfig === void 0 || (_this$activeConfig = _this$activeConfig.capture) === null || _this$activeConfig === void 0 ? void 0 : _this$activeConfig.agentText) !== false && typeof message.content === "string";
|
|
5486
|
+
(_this$collector7 = this.collector) === null || _this$collector7 === void 0 || _this$collector7.ɵemit("agent.message", {
|
|
5487
|
+
messageId: message.id,
|
|
5488
|
+
runId: this.runIdForMessage(agent, message.id),
|
|
5489
|
+
threadId: agent.threadId,
|
|
5490
|
+
agentId: agent.agentId,
|
|
5491
|
+
role: message.role,
|
|
5492
|
+
textLength: content.length,
|
|
5493
|
+
...includeText ? { text: content } : {}
|
|
5494
|
+
});
|
|
5495
|
+
}
|
|
5496
|
+
emitToolCall(phase, toolCallId, agentId, toolName, extra) {
|
|
5497
|
+
var _this$collector8, _origin$threadId;
|
|
5498
|
+
const origin = this.toolCalls.get(toolCallId);
|
|
5499
|
+
(_this$collector8 = this.collector) === null || _this$collector8 === void 0 || _this$collector8.ɵemit("tool.call", {
|
|
5500
|
+
phase,
|
|
5501
|
+
toolCallId,
|
|
5502
|
+
toolName,
|
|
5503
|
+
agentId,
|
|
5504
|
+
threadId: (_origin$threadId = origin === null || origin === void 0 ? void 0 : origin.threadId) !== null && _origin$threadId !== void 0 ? _origin$threadId : null,
|
|
5505
|
+
messageId: origin === null || origin === void 0 ? void 0 : origin.messageId,
|
|
5506
|
+
runId: origin === null || origin === void 0 ? void 0 : origin.runId,
|
|
5507
|
+
...extra
|
|
5508
|
+
});
|
|
5509
|
+
}
|
|
5510
|
+
runIdForMessage(agent, messageId) {
|
|
5511
|
+
var _ref4, _this$core$getRunIdFo;
|
|
5512
|
+
const agentId = agent.agentId;
|
|
5513
|
+
if (agentId === void 0) return null;
|
|
5514
|
+
return (_ref4 = (_this$core$getRunIdFo = this.core.getRunIdForMessage(agentId, agent.threadId, messageId)) !== null && _this$core$getRunIdFo !== void 0 ? _this$core$getRunIdFo : this.lastRunIds.get(agent)) !== null && _ref4 !== void 0 ? _ref4 : null;
|
|
5515
|
+
}
|
|
5516
|
+
findMessage(messageId) {
|
|
5517
|
+
for (const agent of this.agents.keys()) {
|
|
5518
|
+
const message = agent.messages.find((candidate) => candidate.id === messageId);
|
|
5519
|
+
if (message !== void 0) return {
|
|
5520
|
+
agent,
|
|
5521
|
+
message
|
|
5522
|
+
};
|
|
5523
|
+
}
|
|
5524
|
+
return null;
|
|
5525
|
+
}
|
|
5526
|
+
toolStatus(agent, toolCallId) {
|
|
5527
|
+
if (this.executingTools.has(toolCallId)) return "executing";
|
|
5528
|
+
return agent.messages.some((message) => message.role === "tool" && message.toolCallId === toolCallId) ? "complete" : "inProgress";
|
|
5529
|
+
}
|
|
5530
|
+
/** Adds agent context to a click: exact message first, then the single open Thread. */
|
|
5531
|
+
enrich(target) {
|
|
5532
|
+
var _target$closest$getAt, _target$closest, _target$closest$getAt2, _target$closest2;
|
|
5533
|
+
const messageId = (_target$closest$getAt = (_target$closest = target.closest("[data-message-id]")) === null || _target$closest === void 0 ? void 0 : _target$closest.getAttribute("data-message-id")) !== null && _target$closest$getAt !== void 0 ? _target$closest$getAt : null;
|
|
5534
|
+
const toolCallId = (_target$closest$getAt2 = (_target$closest2 = target.closest("[data-tool-call-id]")) === null || _target$closest2 === void 0 ? void 0 : _target$closest2.getAttribute("data-tool-call-id")) !== null && _target$closest$getAt2 !== void 0 ? _target$closest$getAt2 : null;
|
|
5535
|
+
const found = messageId === null ? null : this.findMessage(messageId);
|
|
5536
|
+
if (found !== null) {
|
|
5537
|
+
var _message$toolCalls;
|
|
5538
|
+
const { agent, message } = found;
|
|
5539
|
+
const toolCall = toolCallId !== null && message.role === "assistant" ? (_message$toolCalls = message.toolCalls) === null || _message$toolCalls === void 0 ? void 0 : _message$toolCalls.find((call) => call.id === toolCallId) : void 0;
|
|
5540
|
+
return {
|
|
5541
|
+
threadId: agent.threadId,
|
|
5542
|
+
agentId: agent.agentId,
|
|
5543
|
+
messageId: message.id,
|
|
5544
|
+
runId: this.runIdForMessage(agent, message.id),
|
|
5545
|
+
...toolCall === void 0 ? {} : {
|
|
5546
|
+
toolCallId: toolCall.id,
|
|
5547
|
+
toolName: toolCall.function.name,
|
|
5548
|
+
toolStatus: this.toolStatus(agent, toolCall.id)
|
|
5549
|
+
}
|
|
5550
|
+
};
|
|
5551
|
+
}
|
|
5552
|
+
return this.openThreadContext();
|
|
5553
|
+
}
|
|
5554
|
+
/** The single open Thread, or `null` with the candidates when several are open. */
|
|
5555
|
+
openThreadContext() {
|
|
5556
|
+
var _openIds$;
|
|
5557
|
+
const openIds = this.distinctOpenThreadIds();
|
|
5558
|
+
if (openIds.length > 1) return {
|
|
5559
|
+
threadId: null,
|
|
5560
|
+
threadAmbiguity: {
|
|
5561
|
+
reason: "multiple-open",
|
|
5562
|
+
candidates: openIds
|
|
5563
|
+
}
|
|
5564
|
+
};
|
|
5565
|
+
return { threadId: (_openIds$ = openIds[0]) !== null && _openIds$ !== void 0 ? _openIds$ : null };
|
|
5566
|
+
}
|
|
5567
|
+
};
|
|
5568
|
+
|
|
4679
5569
|
//#endregion
|
|
4680
5570
|
//#region src/utils/micro-redux.ts
|
|
4681
5571
|
const INTERNAL_ACTION_TYPES = {
|
|
@@ -5820,7 +6710,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
5820
6710
|
return Object.fromEntries(Object.entries(headers).filter((entry) => entry[1] != null));
|
|
5821
6711
|
}
|
|
5822
6712
|
var CopilotKitCore = class {
|
|
5823
|
-
constructor({ runtimeUrl, runtimeTransport = "auto", deferInitialConnection = false, headers = {}, credentials, messageFilter, properties = {}, agents__unsafe_dev_only = {}, tools = [], suggestionsConfig = [], debug }) {
|
|
6713
|
+
constructor({ runtimeUrl, runtimeTransport = "auto", deferInitialConnection = false, headers = {}, credentials, messageFilter, properties = {}, agents__unsafe_dev_only = {}, tools = [], suggestionsConfig = [], debug, learning }) {
|
|
5824
6714
|
_defineProperty(this, "_headers", void 0);
|
|
5825
6715
|
_defineProperty(this, "_credentials", void 0);
|
|
5826
6716
|
_defineProperty(this, "_messageFilter", void 0);
|
|
@@ -5834,6 +6724,9 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
5834
6724
|
_defineProperty(this, "runHandler", void 0);
|
|
5835
6725
|
_defineProperty(this, "stateManager", void 0);
|
|
5836
6726
|
_defineProperty(this, "threadStoreRegistry", void 0);
|
|
6727
|
+
_defineProperty(this, "learningBridge", void 0);
|
|
6728
|
+
_defineProperty(this, "notifiedTrajectoryId", null);
|
|
6729
|
+
_defineProperty(this, "learningConfiguredListeners", /* @__PURE__ */ new Set());
|
|
5837
6730
|
_defineProperty(this, "_memoryStore", void 0);
|
|
5838
6731
|
_defineProperty(this, "previousAgentIds", /* @__PURE__ */ new Set());
|
|
5839
6732
|
this._headers = normalizeHeaders(headers);
|
|
@@ -5851,6 +6744,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
5851
6744
|
this.runHandler.initialize(tools);
|
|
5852
6745
|
this.suggestionEngine.initialize(suggestionsConfig);
|
|
5853
6746
|
this.stateManager.initialize();
|
|
6747
|
+
this.learningBridge = new LearningBridge(this, learning, () => this.notifyTrajectoryChanged());
|
|
5854
6748
|
this.agentRegistry.setRuntimeTransport(runtimeTransport);
|
|
5855
6749
|
this.agentRegistry.setRuntimeUrl(runtimeUrl, { deferConnection: deferInitialConnection });
|
|
5856
6750
|
this.previousAgentIds = new Set(Object.keys(agents__unsafe_dev_only));
|
|
@@ -6005,6 +6899,10 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
6005
6899
|
get runtimeConnectionStatus() {
|
|
6006
6900
|
return this.agentRegistry.runtimeConnectionStatus;
|
|
6007
6901
|
}
|
|
6902
|
+
/** @internal The verbatim single-endpoint URL, including any trailing slash. */
|
|
6903
|
+
get ɵruntimeEndpointUrl() {
|
|
6904
|
+
return this.agentRegistry.runtimeEndpointUrl;
|
|
6905
|
+
}
|
|
6008
6906
|
get ɵruntimeFetch() {
|
|
6009
6907
|
return this.agentRegistry.createRuntimeFetch();
|
|
6010
6908
|
}
|
|
@@ -6170,6 +7068,86 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
6170
7068
|
getAgent(id) {
|
|
6171
7069
|
return this.agentRegistry.getAgent(id);
|
|
6172
7070
|
}
|
|
7071
|
+
/** Updates settings for the next capture. Removing the config stops capture. */
|
|
7072
|
+
setLearningConfig(config) {
|
|
7073
|
+
const wasConfigured = this.ɵlearningConfigured;
|
|
7074
|
+
this.learningBridge.setConfig(config);
|
|
7075
|
+
this.notifyTrajectoryChanged();
|
|
7076
|
+
if (this.ɵlearningConfigured === wasConfigured) return;
|
|
7077
|
+
for (const listener of this.learningConfiguredListeners) try {
|
|
7078
|
+
listener();
|
|
7079
|
+
} catch (error) {
|
|
7080
|
+
console.error("Learning configured listener error:", error);
|
|
7081
|
+
}
|
|
7082
|
+
}
|
|
7083
|
+
/**
|
|
7084
|
+
* @internal Whether a `learning` config is set. Unlike {@link trajectoryId},
|
|
7085
|
+
* it does not change with capture start, connection failures or reconnects.
|
|
7086
|
+
*/
|
|
7087
|
+
get ɵlearningConfigured() {
|
|
7088
|
+
return this.learningBridge.isConfigured;
|
|
7089
|
+
}
|
|
7090
|
+
/** @internal Calls `listener` when {@link ɵlearningConfigured} changes. */
|
|
7091
|
+
ɵsubscribeToLearningConfigured(listener) {
|
|
7092
|
+
this.learningConfiguredListeners.add(listener);
|
|
7093
|
+
return () => {
|
|
7094
|
+
this.learningConfiguredListeners.delete(listener);
|
|
7095
|
+
};
|
|
7096
|
+
}
|
|
7097
|
+
/** The active capture's Trajectory ID, or null while capture is stopped. */
|
|
7098
|
+
get trajectoryId() {
|
|
7099
|
+
return this.learningBridge.trajectoryId;
|
|
7100
|
+
}
|
|
7101
|
+
notifyTrajectoryChanged() {
|
|
7102
|
+
const trajectoryId = this.trajectoryId;
|
|
7103
|
+
if (trajectoryId === this.notifiedTrajectoryId) return;
|
|
7104
|
+
this.notifiedTrajectoryId = trajectoryId;
|
|
7105
|
+
this.notifySubscribers((subscriber) => {
|
|
7106
|
+
var _subscriber$onTraject;
|
|
7107
|
+
return (_subscriber$onTraject = subscriber.onTrajectoryChanged) === null || _subscriber$onTraject === void 0 ? void 0 : _subscriber$onTraject.call(subscriber, {
|
|
7108
|
+
copilotkit: this,
|
|
7109
|
+
trajectoryId
|
|
7110
|
+
});
|
|
7111
|
+
}, "Subscriber onTrajectoryChanged error:");
|
|
7112
|
+
}
|
|
7113
|
+
/**
|
|
7114
|
+
* Starts one Trajectory after Runtime authorization and the Gateway join.
|
|
7115
|
+
* Omit the ID to create one. Repeated starts await the active connection;
|
|
7116
|
+
* a different ID stops the previous capture. Explicit sinks retain the
|
|
7117
|
+
* prototype's synchronous capture and require a stop before changing IDs.
|
|
7118
|
+
*
|
|
7119
|
+
* @example copilotkit.startTrajectory({ trajectoryId: crypto.randomUUID() })
|
|
7120
|
+
*/
|
|
7121
|
+
startTrajectory(options = {}) {
|
|
7122
|
+
const result = this.learningBridge.start(options);
|
|
7123
|
+
this.notifyTrajectoryChanged();
|
|
7124
|
+
return result;
|
|
7125
|
+
}
|
|
7126
|
+
/** Cancels pending work and stops capture, attempting one final batch without waiting for its ACK. */
|
|
7127
|
+
stopTrajectory() {
|
|
7128
|
+
this.learningBridge.stop();
|
|
7129
|
+
this.notifyTrajectoryChanged();
|
|
7130
|
+
}
|
|
7131
|
+
/**
|
|
7132
|
+
* Records an outcome that clicks cannot show, such as a saved report or an
|
|
7133
|
+
* approved deal. The wire adds `value.seq`; arrays, primitives, and objects
|
|
7134
|
+
* already containing `seq` are preserved under `value.data`. Explicit legacy
|
|
7135
|
+
* sinks retain object-only events with open-Thread enrichment.
|
|
7136
|
+
* No-op while no Trajectory runs. Events emitted during connection recovery
|
|
7137
|
+
* count as dropped. Built-in names such as `click` are rejected.
|
|
7138
|
+
*
|
|
7139
|
+
* @example copilotkit.emitTrajectoryEvent("deal.approved", { dealId: "deal-1" })
|
|
7140
|
+
*/
|
|
7141
|
+
emitTrajectoryEvent(name, value = {}) {
|
|
7142
|
+
this.learningBridge.emit(name, value);
|
|
7143
|
+
}
|
|
7144
|
+
/**
|
|
7145
|
+
* Tells Core that a view shows this Thread, so captured interactions can link to it.
|
|
7146
|
+
* Framework bindings call this; call it yourself only without a CopilotKit provider.
|
|
7147
|
+
*/
|
|
7148
|
+
registerOpenThread(params) {
|
|
7149
|
+
return this.learningBridge.registerOpenThread(params);
|
|
7150
|
+
}
|
|
6173
7151
|
/**
|
|
6174
7152
|
* Re-apply the current headers to a single agent (delegated to
|
|
6175
7153
|
* AgentRegistry). Core headers are merged on top of the agent's own
|