@copilotkit/core 1.61.1 → 1.62.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 +342 -56
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +233 -26
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +233 -26
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +339 -57
- package/dist/index.mjs.map +1 -1
- package/dist/index.umd.js +348 -66
- package/dist/index.umd.js.map +1 -1
- package/package.json +5 -3
package/dist/index.mjs
CHANGED
|
@@ -151,12 +151,6 @@ var IntelligenceAgent = class IntelligenceAgent extends AbstractAgent {
|
|
|
151
151
|
activeChannel = null;
|
|
152
152
|
canonicalRunId = null;
|
|
153
153
|
sharedState;
|
|
154
|
-
/**
|
|
155
|
-
* Resolves when the active run's pipeline finalizes; `undefined` between runs.
|
|
156
|
-
* Set/cleared inside {@link connectAgent}'s observable lifecycle. Declared
|
|
157
|
-
* here so {@link RunCompletionAware} consumers can read it without a cast.
|
|
158
|
-
*/
|
|
159
|
-
activeRunCompletionPromise;
|
|
160
154
|
constructor(config, sharedState = { lastSeenEventIds: /* @__PURE__ */ new Map() }) {
|
|
161
155
|
super();
|
|
162
156
|
this.config = config;
|
|
@@ -202,7 +196,7 @@ var IntelligenceAgent = class IntelligenceAgent extends AbstractAgent {
|
|
|
202
196
|
const previousMessageIds = new Set(this.messages.map((m) => m.id));
|
|
203
197
|
const subscribers = [
|
|
204
198
|
{ onRunFinishedEvent: (event) => {
|
|
205
|
-
result = event.result;
|
|
199
|
+
if (event.outcome === "success") result = event.result;
|
|
206
200
|
} },
|
|
207
201
|
...this.subscribers,
|
|
208
202
|
subscriber ?? {}
|
|
@@ -210,10 +204,10 @@ var IntelligenceAgent = class IntelligenceAgent extends AbstractAgent {
|
|
|
210
204
|
await this.onInitialize(input, subscribers);
|
|
211
205
|
self.activeRunDetach$ = new Subject();
|
|
212
206
|
let resolveCompletion;
|
|
213
|
-
|
|
207
|
+
self.activeRunCompletionPromise = new Promise((resolve) => {
|
|
214
208
|
resolveCompletion = resolve;
|
|
215
209
|
});
|
|
216
|
-
const source$ = defer(() => this.connect(input)).pipe(transformChunks(this.
|
|
210
|
+
const source$ = defer(() => this.connect(input)).pipe(transformChunks(this.debugLogger), takeUntil(self.activeRunDetach$));
|
|
217
211
|
const applied$ = this.apply(input, source$, subscribers);
|
|
218
212
|
await lastValueFrom(this.processApplyEvents(input, applied$, subscribers).pipe(catchError((error) => {
|
|
219
213
|
this.isRunning = false;
|
|
@@ -223,7 +217,7 @@ var IntelligenceAgent = class IntelligenceAgent extends AbstractAgent {
|
|
|
223
217
|
this.onFinalize(input, subscribers);
|
|
224
218
|
resolveCompletion?.();
|
|
225
219
|
resolveCompletion = void 0;
|
|
226
|
-
|
|
220
|
+
self.activeRunCompletionPromise = void 0;
|
|
227
221
|
self.activeRunDetach$ = void 0;
|
|
228
222
|
})), { defaultValue: void 0 });
|
|
229
223
|
const newMessages = structuredClone_(this.messages).filter((m) => !previousMessageIds.has(m.id));
|
|
@@ -725,8 +719,9 @@ var ProxiedCopilotRuntimeAgent = class ProxiedCopilotRuntimeAgent extends HttpAg
|
|
|
725
719
|
cloned.setState(this.state);
|
|
726
720
|
cloned.setMessages(this.messages);
|
|
727
721
|
if (this.delegate) {
|
|
728
|
-
|
|
729
|
-
cloned.
|
|
722
|
+
const clonedDelegate = this.delegate.clone();
|
|
723
|
+
cloned.delegate = clonedDelegate;
|
|
724
|
+
cloned.syncDelegate(clonedDelegate);
|
|
730
725
|
}
|
|
731
726
|
return cloned;
|
|
732
727
|
}
|
|
@@ -881,6 +876,17 @@ var AgentRegistry = class {
|
|
|
881
876
|
_openGenerativeUIEnabled = false;
|
|
882
877
|
_licenseStatus;
|
|
883
878
|
_telemetryDisabled = false;
|
|
879
|
+
/**
|
|
880
|
+
* The headers each HttpAgent was constructed with, captured on the first
|
|
881
|
+
* `applyHeadersToAgent` call for that agent (which, for agents the registry
|
|
882
|
+
* owns, happens at registration before any core headers are applied). Core
|
|
883
|
+
* headers are merged ON TOP of this baseline so that headers configured
|
|
884
|
+
* directly on an agent (e.g. an `Authorization` for a self-hosted backend)
|
|
885
|
+
* survive registration instead of being silently replaced. The baseline is
|
|
886
|
+
* captured once and never re-captured, so a later direct mutation of
|
|
887
|
+
* `agent.headers` is not folded into it. See #5635.
|
|
888
|
+
*/
|
|
889
|
+
agentOwnHeaders = /* @__PURE__ */ new WeakMap();
|
|
884
890
|
constructor(core) {
|
|
885
891
|
this.core = core;
|
|
886
892
|
}
|
|
@@ -1053,10 +1059,19 @@ var AgentRegistry = class {
|
|
|
1053
1059
|
console.warn(`Agent ${id} not found`);
|
|
1054
1060
|
}
|
|
1055
1061
|
/**
|
|
1056
|
-
* Apply current headers to an agent
|
|
1062
|
+
* Apply current core headers to an agent, merged ON TOP of the agent's own
|
|
1063
|
+
* construction-time headers (the per-agent baseline in `agentOwnHeaders`).
|
|
1064
|
+
* Core wins on a key conflict. Non-`HttpAgent` agents are left untouched
|
|
1065
|
+
* because only `HttpAgent` carries a `headers` field. See #5635.
|
|
1057
1066
|
*/
|
|
1058
1067
|
applyHeadersToAgent(agent) {
|
|
1059
|
-
if (agent instanceof HttpAgent)
|
|
1068
|
+
if (agent instanceof HttpAgent) {
|
|
1069
|
+
if (!this.agentOwnHeaders.has(agent)) this.agentOwnHeaders.set(agent, { ...agent.headers });
|
|
1070
|
+
agent.headers = {
|
|
1071
|
+
...this.agentOwnHeaders.get(agent),
|
|
1072
|
+
...this.core.headers
|
|
1073
|
+
};
|
|
1074
|
+
}
|
|
1060
1075
|
}
|
|
1061
1076
|
/**
|
|
1062
1077
|
* Apply current headers to all agents
|
|
@@ -1728,7 +1743,11 @@ var RunHandler = class {
|
|
|
1728
1743
|
const proxied = agent;
|
|
1729
1744
|
if (incomingThreadId && typeof proxied.clearReplayCursor === "function") proxied.clearReplayCursor(incomingThreadId);
|
|
1730
1745
|
}
|
|
1731
|
-
|
|
1746
|
+
this._internal.applyHeadersToAgent(agent);
|
|
1747
|
+
await this._internal.notifySubscribers((subscriber) => subscriber.onAgentRunStarted?.({
|
|
1748
|
+
copilotkit: this.core,
|
|
1749
|
+
agent
|
|
1750
|
+
}), "Subscriber onAgentRunStarted error:");
|
|
1732
1751
|
const runAgentResult = await agent.connectAgent({
|
|
1733
1752
|
forwardedProps: this._internal.properties,
|
|
1734
1753
|
tools: this.buildFrontendTools(agent.agentId),
|
|
@@ -1749,15 +1768,18 @@ var RunHandler = class {
|
|
|
1749
1768
|
context
|
|
1750
1769
|
});
|
|
1751
1770
|
}
|
|
1752
|
-
return {
|
|
1771
|
+
return {
|
|
1772
|
+
result: void 0,
|
|
1773
|
+
newMessages: []
|
|
1774
|
+
};
|
|
1753
1775
|
}
|
|
1754
1776
|
}
|
|
1755
1777
|
/**
|
|
1756
1778
|
* Run an agent
|
|
1757
1779
|
*/
|
|
1758
|
-
async runAgent({ agent, forwardedProps }) {
|
|
1780
|
+
async runAgent({ agent, forwardedProps, resume }) {
|
|
1759
1781
|
if (agent.agentId) this._internal.suggestionEngine.clearSuggestions(agent.agentId);
|
|
1760
|
-
|
|
1782
|
+
this._internal.applyHeadersToAgent(agent);
|
|
1761
1783
|
if (agent.detachActiveRun) await agent.detachActiveRun();
|
|
1762
1784
|
const isTopLevel = this._runDepth === 0;
|
|
1763
1785
|
let originalAbortRun;
|
|
@@ -1769,6 +1791,10 @@ var RunHandler = class {
|
|
|
1769
1791
|
controller.abort();
|
|
1770
1792
|
originalAbortRun();
|
|
1771
1793
|
};
|
|
1794
|
+
await this._internal.notifySubscribers((subscriber) => subscriber.onAgentRunStarted?.({
|
|
1795
|
+
copilotkit: this.core,
|
|
1796
|
+
agent
|
|
1797
|
+
}), "Subscriber onAgentRunStarted error:");
|
|
1772
1798
|
}
|
|
1773
1799
|
this._runDepth++;
|
|
1774
1800
|
try {
|
|
@@ -1777,6 +1803,7 @@ var RunHandler = class {
|
|
|
1777
1803
|
...this._internal.properties,
|
|
1778
1804
|
...forwardedProps
|
|
1779
1805
|
},
|
|
1806
|
+
...resume !== void 0 ? { resume } : {},
|
|
1780
1807
|
tools: this.buildFrontendTools(agent.agentId),
|
|
1781
1808
|
context: this._internal.getContextForAgent(agent.agentId)
|
|
1782
1809
|
}, this.createAgentErrorSubscriber(agent));
|
|
@@ -1793,7 +1820,10 @@ var RunHandler = class {
|
|
|
1793
1820
|
code: CopilotKitCoreErrorCode.AGENT_RUN_FAILED,
|
|
1794
1821
|
context
|
|
1795
1822
|
});
|
|
1796
|
-
return {
|
|
1823
|
+
return {
|
|
1824
|
+
result: void 0,
|
|
1825
|
+
newMessages: []
|
|
1826
|
+
};
|
|
1797
1827
|
} finally {
|
|
1798
1828
|
this._runDepth--;
|
|
1799
1829
|
if (isTopLevel && originalAbortRun) agent.abortRun = originalAbortRun;
|
|
@@ -2065,18 +2095,19 @@ var RunHandler = class {
|
|
|
2065
2095
|
throw error;
|
|
2066
2096
|
}
|
|
2067
2097
|
const toolCallId = randomUUID$1();
|
|
2098
|
+
const assistantToolCall = {
|
|
2099
|
+
id: toolCallId,
|
|
2100
|
+
type: "function",
|
|
2101
|
+
function: {
|
|
2102
|
+
name,
|
|
2103
|
+
arguments: JSON.stringify(parameters)
|
|
2104
|
+
}
|
|
2105
|
+
};
|
|
2068
2106
|
const assistantMessage = {
|
|
2069
2107
|
id: randomUUID$1(),
|
|
2070
2108
|
role: "assistant",
|
|
2071
2109
|
content: "",
|
|
2072
|
-
toolCalls: [
|
|
2073
|
-
id: toolCallId,
|
|
2074
|
-
type: "function",
|
|
2075
|
-
function: {
|
|
2076
|
-
name,
|
|
2077
|
-
arguments: JSON.stringify(parameters)
|
|
2078
|
-
}
|
|
2079
|
-
}]
|
|
2110
|
+
toolCalls: [assistantToolCall]
|
|
2080
2111
|
};
|
|
2081
2112
|
agent.messages.push(assistantMessage);
|
|
2082
2113
|
let handlerResult = {
|
|
@@ -2086,7 +2117,7 @@ var RunHandler = class {
|
|
|
2086
2117
|
};
|
|
2087
2118
|
if (tool.handler) handlerResult = await this.executeToolHandler({
|
|
2088
2119
|
tool,
|
|
2089
|
-
toolCall:
|
|
2120
|
+
toolCall: assistantToolCall,
|
|
2090
2121
|
agent,
|
|
2091
2122
|
agentId: resolvedAgentId,
|
|
2092
2123
|
handlerArgs: parameters,
|
|
@@ -2172,9 +2203,9 @@ const EMPTY_TOOL_SCHEMA = {
|
|
|
2172
2203
|
*/
|
|
2173
2204
|
function createToolSchema(tool) {
|
|
2174
2205
|
if (!tool.parameters) return { ...EMPTY_TOOL_SCHEMA };
|
|
2175
|
-
const rawSchema = schemaToJsonSchema(tool.parameters, { zodToJsonSchema });
|
|
2206
|
+
const rawSchema = schemaToJsonSchema(tool.parameters, { zodToJsonSchema: (schema, options) => zodToJsonSchema(schema, options) });
|
|
2176
2207
|
if (!rawSchema || typeof rawSchema !== "object") return { ...EMPTY_TOOL_SCHEMA };
|
|
2177
|
-
const { $schema, ...schema } = rawSchema;
|
|
2208
|
+
const { $schema: _$schema, ...schema } = rawSchema;
|
|
2178
2209
|
if (typeof schema.type !== "string") schema.type = "object";
|
|
2179
2210
|
if (typeof schema.properties !== "object" || schema.properties === null) schema.properties = {};
|
|
2180
2211
|
stripAdditionalProperties(schema);
|
|
@@ -2761,9 +2792,19 @@ var CopilotKitCore = class {
|
|
|
2761
2792
|
* });
|
|
2762
2793
|
* ```
|
|
2763
2794
|
*
|
|
2764
|
-
* The resulting header set is also re-applied to every
|
|
2765
|
-
* `
|
|
2766
|
-
*
|
|
2795
|
+
* The resulting header set is also re-applied to every agent in the registry
|
|
2796
|
+
* and `onHeadersChanged` subscribers are notified. These headers are merged
|
|
2797
|
+
* ON TOP of the headers each `HttpAgent` was constructed with, so per-agent
|
|
2798
|
+
* headers (e.g. an `Authorization` for a self-hosted backend) are preserved;
|
|
2799
|
+
* on a key conflict the core-level value wins.
|
|
2800
|
+
*
|
|
2801
|
+
* Because the agent's construction-time headers form the merge baseline, this
|
|
2802
|
+
* method can override a per-agent header but cannot REMOVE one: clearing a
|
|
2803
|
+
* core key here only drops the core-level override, after which the agent's
|
|
2804
|
+
* own value (if any) re-surfaces. To change a header an agent was constructed
|
|
2805
|
+
* with, set it at the provider/core level instead of on the agent, or update
|
|
2806
|
+
* it on the agent directly. The clear-on-logout pattern above is for
|
|
2807
|
+
* core-level headers.
|
|
2767
2808
|
*/
|
|
2768
2809
|
setHeaders(headers) {
|
|
2769
2810
|
this._headers = normalizeHeaders(headers);
|
|
@@ -2822,6 +2863,23 @@ var CopilotKitCore = class {
|
|
|
2822
2863
|
return this.agentRegistry.getAgent(id);
|
|
2823
2864
|
}
|
|
2824
2865
|
/**
|
|
2866
|
+
* Re-apply the current headers to a single agent (delegated to
|
|
2867
|
+
* AgentRegistry). Core headers are merged on top of the agent's own
|
|
2868
|
+
* construction-time headers rather than replacing them, so headers
|
|
2869
|
+
* configured directly on an `HttpAgent` (e.g. an `Authorization` for a
|
|
2870
|
+
* self-hosted backend) survive header updates instead of being silently
|
|
2871
|
+
* dropped (see #5635). On a key conflict the core-level value wins.
|
|
2872
|
+
*
|
|
2873
|
+
* The merge baseline is the agent's headers as captured the first time the
|
|
2874
|
+
* agent is applied (at registration), so the way to change headers
|
|
2875
|
+
* afterwards is `setHeaders` (which re-applies to every agent), not mutating
|
|
2876
|
+
* `agent.headers` directly — a direct mutation is overwritten on the next
|
|
2877
|
+
* re-apply.
|
|
2878
|
+
*/
|
|
2879
|
+
applyHeadersToAgent(agent) {
|
|
2880
|
+
this.agentRegistry.applyHeadersToAgent(agent);
|
|
2881
|
+
}
|
|
2882
|
+
/**
|
|
2825
2883
|
* Context management (delegated to ContextStore).
|
|
2826
2884
|
* Pass `agentIds` to restrict the entry to runs of specific agents;
|
|
2827
2885
|
* omit it for context every agent should receive.
|
|
@@ -3538,7 +3596,9 @@ const initialThreadState = {
|
|
|
3538
3596
|
sessionId: 0,
|
|
3539
3597
|
metadataCredentialsRequested: false,
|
|
3540
3598
|
metadataJoinCode: null,
|
|
3541
|
-
nextCursor: null
|
|
3599
|
+
nextCursor: null,
|
|
3600
|
+
inFlightMutationCount: 0,
|
|
3601
|
+
pendingDeletes: {}
|
|
3542
3602
|
};
|
|
3543
3603
|
const threadAdapterEvents = createActionGroup("Thread Adapter", {
|
|
3544
3604
|
started: empty(),
|
|
@@ -3547,7 +3607,9 @@ const threadAdapterEvents = createActionGroup("Thread Adapter", {
|
|
|
3547
3607
|
fetchNextPageRequested: empty(),
|
|
3548
3608
|
renameRequested: props(),
|
|
3549
3609
|
archiveRequested: props(),
|
|
3550
|
-
|
|
3610
|
+
unarchiveRequested: props(),
|
|
3611
|
+
deleteRequested: props(),
|
|
3612
|
+
newThreadStarted: empty()
|
|
3551
3613
|
});
|
|
3552
3614
|
const threadRestEvents = createActionGroup("Thread REST", {
|
|
3553
3615
|
listRequested: props(),
|
|
@@ -3594,7 +3656,9 @@ const threadReducer = createReducer(initialThreadState, on(threadAdapterEvents.c
|
|
|
3594
3656
|
error: null,
|
|
3595
3657
|
metadataCredentialsRequested: false,
|
|
3596
3658
|
metadataJoinCode: null,
|
|
3597
|
-
nextCursor: null
|
|
3659
|
+
nextCursor: null,
|
|
3660
|
+
inFlightMutationCount: 0,
|
|
3661
|
+
pendingDeletes: {}
|
|
3598
3662
|
})), on(threadAdapterEvents.stopped, (state) => ({
|
|
3599
3663
|
...state,
|
|
3600
3664
|
threads: [],
|
|
@@ -3603,7 +3667,9 @@ const threadReducer = createReducer(initialThreadState, on(threadAdapterEvents.c
|
|
|
3603
3667
|
error: null,
|
|
3604
3668
|
metadataCredentialsRequested: false,
|
|
3605
3669
|
metadataJoinCode: null,
|
|
3606
|
-
nextCursor: null
|
|
3670
|
+
nextCursor: null,
|
|
3671
|
+
inFlightMutationCount: 0,
|
|
3672
|
+
pendingDeletes: {}
|
|
3607
3673
|
})), on(threadRestEvents.listRequested, (state, { sessionId }) => {
|
|
3608
3674
|
if (sessionId !== state.sessionId || !state.context) return state;
|
|
3609
3675
|
return {
|
|
@@ -3645,12 +3711,9 @@ const threadReducer = createReducer(initialThreadState, on(threadAdapterEvents.c
|
|
|
3645
3711
|
isFetchingNextPage: false,
|
|
3646
3712
|
error
|
|
3647
3713
|
};
|
|
3648
|
-
}), on(threadRestEvents.metadataCredentialsFailed, (state, { sessionId
|
|
3714
|
+
}), on(threadRestEvents.metadataCredentialsFailed, (state, { sessionId }) => {
|
|
3649
3715
|
if (sessionId !== state.sessionId) return state;
|
|
3650
|
-
return
|
|
3651
|
-
...state,
|
|
3652
|
-
error
|
|
3653
|
-
};
|
|
3716
|
+
return state;
|
|
3654
3717
|
}), on(threadRestEvents.metadataCredentialsRequested, (state, { sessionId }) => {
|
|
3655
3718
|
if (sessionId !== state.sessionId) return state;
|
|
3656
3719
|
return {
|
|
@@ -3663,10 +3726,105 @@ const threadReducer = createReducer(initialThreadState, on(threadAdapterEvents.c
|
|
|
3663
3726
|
...state,
|
|
3664
3727
|
isFetchingNextPage: true
|
|
3665
3728
|
};
|
|
3666
|
-
}), on(
|
|
3729
|
+
}), on(threadAdapterEvents.renameRequested, (state, { threadId, name }) => {
|
|
3730
|
+
const existing = state.threads.find((thread) => thread.id === threadId);
|
|
3731
|
+
const inFlightMutationCount = state.inFlightMutationCount + 1;
|
|
3732
|
+
if (!existing) return {
|
|
3733
|
+
...state,
|
|
3734
|
+
inFlightMutationCount
|
|
3735
|
+
};
|
|
3736
|
+
return {
|
|
3737
|
+
...state,
|
|
3738
|
+
threads: upsertThread(state.threads, {
|
|
3739
|
+
...existing,
|
|
3740
|
+
name
|
|
3741
|
+
}),
|
|
3742
|
+
inFlightMutationCount
|
|
3743
|
+
};
|
|
3744
|
+
}), on(threadAdapterEvents.archiveRequested, (state, { threadId }) => {
|
|
3745
|
+
const existing = state.threads.find((thread) => thread.id === threadId);
|
|
3746
|
+
const inFlightMutationCount = state.inFlightMutationCount + 1;
|
|
3747
|
+
if (!existing) return {
|
|
3748
|
+
...state,
|
|
3749
|
+
inFlightMutationCount
|
|
3750
|
+
};
|
|
3751
|
+
if (!state.context?.includeArchived) return {
|
|
3752
|
+
...state,
|
|
3753
|
+
threads: state.threads.filter((thread) => thread.id !== threadId),
|
|
3754
|
+
inFlightMutationCount
|
|
3755
|
+
};
|
|
3756
|
+
return {
|
|
3757
|
+
...state,
|
|
3758
|
+
threads: upsertThread(state.threads, {
|
|
3759
|
+
...existing,
|
|
3760
|
+
archived: true
|
|
3761
|
+
}),
|
|
3762
|
+
inFlightMutationCount
|
|
3763
|
+
};
|
|
3764
|
+
}), on(threadAdapterEvents.unarchiveRequested, (state, { threadId }) => {
|
|
3765
|
+
const existing = state.threads.find((thread) => thread.id === threadId);
|
|
3766
|
+
const inFlightMutationCount = state.inFlightMutationCount + 1;
|
|
3767
|
+
if (!existing) return {
|
|
3768
|
+
...state,
|
|
3769
|
+
inFlightMutationCount
|
|
3770
|
+
};
|
|
3771
|
+
return {
|
|
3772
|
+
...state,
|
|
3773
|
+
threads: upsertThread(state.threads, {
|
|
3774
|
+
...existing,
|
|
3775
|
+
archived: false
|
|
3776
|
+
}),
|
|
3777
|
+
inFlightMutationCount
|
|
3778
|
+
};
|
|
3779
|
+
}), on(threadAdapterEvents.deleteRequested, (state, { requestId, threadId }) => {
|
|
3780
|
+
const existing = state.threads.find((thread) => thread.id === threadId);
|
|
3781
|
+
const inFlightMutationCount = state.inFlightMutationCount + 1;
|
|
3782
|
+
if (!existing) return {
|
|
3783
|
+
...state,
|
|
3784
|
+
inFlightMutationCount
|
|
3785
|
+
};
|
|
3786
|
+
return {
|
|
3787
|
+
...state,
|
|
3788
|
+
threads: state.threads.filter((thread) => thread.id !== threadId),
|
|
3789
|
+
pendingDeletes: {
|
|
3790
|
+
...state.pendingDeletes,
|
|
3791
|
+
[requestId]: existing
|
|
3792
|
+
},
|
|
3793
|
+
inFlightMutationCount
|
|
3794
|
+
};
|
|
3795
|
+
}), on(threadAdapterEvents.newThreadStarted, (state) => ({
|
|
3667
3796
|
...state,
|
|
3668
|
-
error:
|
|
3669
|
-
})), on(
|
|
3797
|
+
error: null
|
|
3798
|
+
})), on(threadRestEvents.mutationFinished, (state, { outcome }) => {
|
|
3799
|
+
if (outcome.sessionId !== state.sessionId) return state;
|
|
3800
|
+
const inFlightMutationCount = Math.max(0, state.inFlightMutationCount - 1);
|
|
3801
|
+
if (outcome.ok) {
|
|
3802
|
+
if (state.pendingDeletes[outcome.requestId] === void 0) return {
|
|
3803
|
+
...state,
|
|
3804
|
+
inFlightMutationCount
|
|
3805
|
+
};
|
|
3806
|
+
const { [outcome.requestId]: _settled, ...rest } = state.pendingDeletes;
|
|
3807
|
+
return {
|
|
3808
|
+
...state,
|
|
3809
|
+
inFlightMutationCount,
|
|
3810
|
+
pendingDeletes: rest
|
|
3811
|
+
};
|
|
3812
|
+
}
|
|
3813
|
+
const rolledBack = state.pendingDeletes[outcome.requestId];
|
|
3814
|
+
if (rolledBack === void 0) return {
|
|
3815
|
+
...state,
|
|
3816
|
+
inFlightMutationCount,
|
|
3817
|
+
error: outcome.error
|
|
3818
|
+
};
|
|
3819
|
+
const { [outcome.requestId]: _restored, ...rest } = state.pendingDeletes;
|
|
3820
|
+
return {
|
|
3821
|
+
...state,
|
|
3822
|
+
threads: upsertThread(state.threads, rolledBack),
|
|
3823
|
+
pendingDeletes: rest,
|
|
3824
|
+
inFlightMutationCount,
|
|
3825
|
+
error: outcome.error
|
|
3826
|
+
};
|
|
3827
|
+
}), on(threadDomainEvents.threadUpserted, (state, { sessionId, thread }) => {
|
|
3670
3828
|
if (sessionId !== state.sessionId) return state;
|
|
3671
3829
|
return {
|
|
3672
3830
|
...state,
|
|
@@ -3679,23 +3837,49 @@ const threadReducer = createReducer(initialThreadState, on(threadAdapterEvents.c
|
|
|
3679
3837
|
threads: state.threads.filter((thread) => thread.id !== threadId)
|
|
3680
3838
|
};
|
|
3681
3839
|
}));
|
|
3682
|
-
|
|
3683
|
-
|
|
3684
|
-
|
|
3685
|
-
|
|
3686
|
-
|
|
3840
|
+
/**
|
|
3841
|
+
* Builds a fresh set of memoized thread selectors.
|
|
3842
|
+
*
|
|
3843
|
+
* Each `createSelector` closure owns a private one-entry cache. Sharing a
|
|
3844
|
+
* single module-level selector instance across multiple concurrent stores
|
|
3845
|
+
* (e.g. a `<CopilotThreadsDrawer>` plus an independent `useThreads`) makes every
|
|
3846
|
+
* cross-store emission a cache miss, defeating memoization and risking
|
|
3847
|
+
* emission instability for any future selector that allocates a new
|
|
3848
|
+
* object/array. Creating a per-store instance keeps each store's cache
|
|
3849
|
+
* isolated so concurrent stores never thrash one another.
|
|
3850
|
+
*/
|
|
3851
|
+
function createThreadSelectors() {
|
|
3852
|
+
return {
|
|
3853
|
+
threads: createSelector((state) => state.threads),
|
|
3854
|
+
isLoading: createSelector((state) => state.isLoading),
|
|
3855
|
+
error: createSelector((state) => state.error),
|
|
3856
|
+
hasNextPage: createSelector((state) => state.nextCursor != null),
|
|
3857
|
+
isFetchingNextPage: createSelector((state) => state.isFetchingNextPage),
|
|
3858
|
+
isMutating: createSelector((state) => state.inFlightMutationCount > 0)
|
|
3859
|
+
};
|
|
3860
|
+
}
|
|
3861
|
+
const standaloneSelectors = createThreadSelectors();
|
|
3862
|
+
const selectThreads = standaloneSelectors.threads;
|
|
3863
|
+
const selectThreadsIsLoading = standaloneSelectors.isLoading;
|
|
3864
|
+
const selectThreadsError = standaloneSelectors.error;
|
|
3865
|
+
const selectHasNextPage = standaloneSelectors.hasNextPage;
|
|
3866
|
+
const selectIsFetchingNextPage = standaloneSelectors.isFetchingNextPage;
|
|
3867
|
+
const selectIsMutating = standaloneSelectors.isMutating;
|
|
3687
3868
|
let threadRequestId = 0;
|
|
3688
3869
|
function createThreadRequestId() {
|
|
3689
3870
|
threadRequestId += 1;
|
|
3690
3871
|
return `thread-request-${threadRequestId}`;
|
|
3691
3872
|
}
|
|
3873
|
+
function threadFromFetch(input, init) {
|
|
3874
|
+
return fromFetch(input, init);
|
|
3875
|
+
}
|
|
3692
3876
|
function createThreadFetchObservable(environment, context, sessionId) {
|
|
3693
3877
|
return defer(() => {
|
|
3694
3878
|
const params = { agentId: context.agentId };
|
|
3695
3879
|
if (context.includeArchived) params.includeArchived = "true";
|
|
3696
3880
|
if (context.limit != null) params.limit = String(context.limit);
|
|
3697
3881
|
const qs = new URLSearchParams(params);
|
|
3698
|
-
return
|
|
3882
|
+
return threadFromFetch(`${context.runtimeUrl}/threads?${qs.toString()}`, {
|
|
3699
3883
|
selector: (response) => {
|
|
3700
3884
|
if (!response.ok) throw new Error(`Failed to fetch threads: ${response.status}`);
|
|
3701
3885
|
return response.json();
|
|
@@ -3723,7 +3907,7 @@ function createThreadFetchObservable(environment, context, sessionId) {
|
|
|
3723
3907
|
}
|
|
3724
3908
|
function createThreadMetadataCredentialsObservable(environment, context, sessionId) {
|
|
3725
3909
|
return defer(() => {
|
|
3726
|
-
return
|
|
3910
|
+
return threadFromFetch(`${context.runtimeUrl}${THREAD_SUBSCRIBE_PATH}`, {
|
|
3727
3911
|
selector: async (response) => {
|
|
3728
3912
|
if (!response.ok) throw new Error(`Failed to fetch thread metadata credentials: ${response.status}`);
|
|
3729
3913
|
return response.json();
|
|
@@ -3756,7 +3940,7 @@ function createThreadMetadataCredentialsObservable(environment, context, session
|
|
|
3756
3940
|
}
|
|
3757
3941
|
function createThreadMutationObservable(environment, context, request) {
|
|
3758
3942
|
return defer(() => {
|
|
3759
|
-
return
|
|
3943
|
+
return threadFromFetch(`${context.runtimeUrl}${request.path}`, {
|
|
3760
3944
|
selector: async (response) => {
|
|
3761
3945
|
if (!response.ok) throw new Error(`Request failed: ${response.status}`);
|
|
3762
3946
|
return null;
|
|
@@ -3770,10 +3954,12 @@ function createThreadMutationObservable(environment, context, request) {
|
|
|
3770
3954
|
body: JSON.stringify(request.body)
|
|
3771
3955
|
}).pipe(map(() => threadRestEvents.mutationFinished({ outcome: {
|
|
3772
3956
|
requestId: request.requestId,
|
|
3957
|
+
sessionId: request.sessionId,
|
|
3773
3958
|
ok: true
|
|
3774
3959
|
} })), catchError((error) => {
|
|
3775
3960
|
return of(threadRestEvents.mutationFinished({ outcome: {
|
|
3776
3961
|
requestId: request.requestId,
|
|
3962
|
+
sessionId: request.sessionId,
|
|
3777
3963
|
ok: false,
|
|
3778
3964
|
error: error instanceof Error ? error : new Error(String(error))
|
|
3779
3965
|
} }));
|
|
@@ -3781,6 +3967,7 @@ function createThreadMutationObservable(environment, context, request) {
|
|
|
3781
3967
|
});
|
|
3782
3968
|
}
|
|
3783
3969
|
function createThreadStore(environment) {
|
|
3970
|
+
const selectors = createThreadSelectors();
|
|
3784
3971
|
const store = createStore({
|
|
3785
3972
|
reducer: threadReducer,
|
|
3786
3973
|
effects: [
|
|
@@ -3847,6 +4034,10 @@ function createThreadStore(environment) {
|
|
|
3847
4034
|
thread: action.payload.thread
|
|
3848
4035
|
});
|
|
3849
4036
|
}))),
|
|
4037
|
+
createEffect((actions$, state$) => actions$.pipe(ofType(threadSocketEvents.joinFailed, threadSocketEvents.joinTimedOut, threadSocketEvents.errored, threadRestEvents.metadataCredentialsFailed), withLatestFrom(state$), filter(([action, state]) => action.sessionId === state.sessionId), tap(([action]) => {
|
|
4038
|
+
const reason = threadSocketEvents.joinTimedOut.match(action) ? "channel join timed out" : threadSocketEvents.joinFailed.match(action) ? "channel join was rejected" : threadRestEvents.metadataCredentialsFailed.match(action) ? "metadata credentials fetch failed" : "socket errored";
|
|
4039
|
+
console.warn(`[threads] realtime ${reason}; the thread list may be stale until reconnect`);
|
|
4040
|
+
})), { dispatch: false }),
|
|
3850
4041
|
createEffect((actions$, state$) => actions$.pipe(ofType(threadAdapterEvents.fetchNextPageRequested), withLatestFrom(state$), filter(([, state]) => Boolean(state.context) && Boolean(state.nextCursor)), switchMap$1(([, state]) => {
|
|
3851
4042
|
const context = state.context;
|
|
3852
4043
|
const params = {
|
|
@@ -3855,7 +4046,7 @@ function createThreadStore(environment) {
|
|
|
3855
4046
|
};
|
|
3856
4047
|
if (context.includeArchived) params.includeArchived = "true";
|
|
3857
4048
|
if (context.limit != null) params.limit = String(context.limit);
|
|
3858
|
-
return
|
|
4049
|
+
return threadFromFetch(`${context.runtimeUrl}/threads?${new URLSearchParams(params).toString()}`, {
|
|
3859
4050
|
selector: (response) => {
|
|
3860
4051
|
if (!response.ok) throw new Error(`Failed to fetch next page: ${response.status}`);
|
|
3861
4052
|
return response.json();
|
|
@@ -3877,12 +4068,14 @@ function createThreadStore(environment) {
|
|
|
3877
4068
|
error: error instanceof Error ? error : new Error(String(error))
|
|
3878
4069
|
}))), takeUntil(actions$.pipe(ofType(threadAdapterEvents.contextChanged, threadAdapterEvents.stopped))));
|
|
3879
4070
|
}))),
|
|
3880
|
-
createEffect((actions$, state$) => actions$.pipe(ofType(threadAdapterEvents.renameRequested, threadAdapterEvents.archiveRequested, threadAdapterEvents.deleteRequested), withLatestFrom(state$), mergeMap(([action, state]) => {
|
|
4071
|
+
createEffect((actions$, state$) => actions$.pipe(ofType(threadAdapterEvents.renameRequested, threadAdapterEvents.archiveRequested, threadAdapterEvents.unarchiveRequested, threadAdapterEvents.deleteRequested), withLatestFrom(state$), mergeMap(([action, state]) => {
|
|
4072
|
+
const sessionId = state.sessionId;
|
|
3881
4073
|
const context = state.context;
|
|
3882
4074
|
if (!context?.runtimeUrl) {
|
|
3883
4075
|
const requestId = action.requestId;
|
|
3884
4076
|
return of(threadRestEvents.mutationFinished({ outcome: {
|
|
3885
4077
|
requestId,
|
|
4078
|
+
sessionId,
|
|
3886
4079
|
ok: false,
|
|
3887
4080
|
error: /* @__PURE__ */ new Error("Runtime URL is not configured")
|
|
3888
4081
|
} }));
|
|
@@ -3890,6 +4083,7 @@ function createThreadStore(environment) {
|
|
|
3890
4083
|
const commonBody = { agentId: context.agentId };
|
|
3891
4084
|
if (threadAdapterEvents.renameRequested.match(action)) return createThreadMutationObservable(environment, context, {
|
|
3892
4085
|
requestId: action.requestId,
|
|
4086
|
+
sessionId,
|
|
3893
4087
|
method: "PATCH",
|
|
3894
4088
|
path: `/threads/${encodeURIComponent(action.threadId)}`,
|
|
3895
4089
|
body: {
|
|
@@ -3899,12 +4093,24 @@ function createThreadStore(environment) {
|
|
|
3899
4093
|
});
|
|
3900
4094
|
if (threadAdapterEvents.archiveRequested.match(action)) return createThreadMutationObservable(environment, context, {
|
|
3901
4095
|
requestId: action.requestId,
|
|
4096
|
+
sessionId,
|
|
3902
4097
|
method: "POST",
|
|
3903
4098
|
path: `/threads/${encodeURIComponent(action.threadId)}/archive`,
|
|
3904
4099
|
body: commonBody
|
|
3905
4100
|
});
|
|
4101
|
+
if (threadAdapterEvents.unarchiveRequested.match(action)) return createThreadMutationObservable(environment, context, {
|
|
4102
|
+
requestId: action.requestId,
|
|
4103
|
+
sessionId,
|
|
4104
|
+
method: "PATCH",
|
|
4105
|
+
path: `/threads/${encodeURIComponent(action.threadId)}`,
|
|
4106
|
+
body: {
|
|
4107
|
+
...commonBody,
|
|
4108
|
+
archived: false
|
|
4109
|
+
}
|
|
4110
|
+
});
|
|
3906
4111
|
return createThreadMutationObservable(environment, context, {
|
|
3907
4112
|
requestId: action.requestId,
|
|
4113
|
+
sessionId,
|
|
3908
4114
|
method: "DELETE",
|
|
3909
4115
|
path: `/threads/${encodeURIComponent(action.threadId)}`,
|
|
3910
4116
|
body: commonBody
|
|
@@ -3915,6 +4121,7 @@ function createThreadStore(environment) {
|
|
|
3915
4121
|
function trackMutation(dispatchAction) {
|
|
3916
4122
|
const resultPromise = firstValueFrom(merge(store.actions$.pipe(ofType(threadRestEvents.mutationFinished), filter((action) => action.outcome.requestId === dispatchAction.requestId), map((action) => action.outcome)), store.actions$.pipe(ofType(threadAdapterEvents.stopped), map(() => ({
|
|
3917
4123
|
requestId: dispatchAction.requestId,
|
|
4124
|
+
sessionId: store.getState().sessionId,
|
|
3918
4125
|
ok: false,
|
|
3919
4126
|
error: /* @__PURE__ */ new Error("Thread store stopped before mutation completed")
|
|
3920
4127
|
})))).pipe(take(1))).then((outcome) => {
|
|
@@ -3924,13 +4131,23 @@ function createThreadStore(environment) {
|
|
|
3924
4131
|
store.dispatch(dispatchAction);
|
|
3925
4132
|
return resultPromise;
|
|
3926
4133
|
}
|
|
4134
|
+
let errorSubscription = null;
|
|
4135
|
+
const subscribeErrors = () => {
|
|
4136
|
+
if (!environment.onError || errorSubscription) return;
|
|
4137
|
+
errorSubscription = store.actions$.pipe(ofType(threadRestEvents.mutationFinished), filter((action) => !action.outcome.ok && action.outcome.sessionId === store.getState().sessionId)).subscribe((action) => {
|
|
4138
|
+
if (!action.outcome.ok) environment.onError?.(action.outcome.error);
|
|
4139
|
+
});
|
|
4140
|
+
};
|
|
3927
4141
|
return {
|
|
3928
4142
|
start() {
|
|
3929
4143
|
store.init();
|
|
4144
|
+
subscribeErrors();
|
|
3930
4145
|
store.dispatch(threadAdapterEvents.started());
|
|
3931
4146
|
},
|
|
3932
4147
|
stop() {
|
|
3933
4148
|
store.dispatch(threadAdapterEvents.stopped());
|
|
4149
|
+
errorSubscription?.unsubscribe();
|
|
4150
|
+
errorSubscription = null;
|
|
3934
4151
|
store.stop();
|
|
3935
4152
|
},
|
|
3936
4153
|
setContext(context) {
|
|
@@ -3941,6 +4158,14 @@ function createThreadStore(environment) {
|
|
|
3941
4158
|
if (!context) return;
|
|
3942
4159
|
store.dispatch(threadRestEvents.listRequested({ sessionId }));
|
|
3943
4160
|
},
|
|
4161
|
+
refetchThreads() {
|
|
4162
|
+
const { sessionId, context } = store.getState();
|
|
4163
|
+
if (!context) return;
|
|
4164
|
+
store.dispatch(threadRestEvents.listRequested({ sessionId }));
|
|
4165
|
+
},
|
|
4166
|
+
startNewThread() {
|
|
4167
|
+
store.dispatch(threadAdapterEvents.newThreadStarted());
|
|
4168
|
+
},
|
|
3944
4169
|
fetchNextPage() {
|
|
3945
4170
|
store.dispatch(threadAdapterEvents.fetchNextPageRequested());
|
|
3946
4171
|
},
|
|
@@ -3957,6 +4182,12 @@ function createThreadStore(environment) {
|
|
|
3957
4182
|
threadId
|
|
3958
4183
|
}));
|
|
3959
4184
|
},
|
|
4185
|
+
unarchiveThread(threadId) {
|
|
4186
|
+
return trackMutation(threadAdapterEvents.unarchiveRequested({
|
|
4187
|
+
requestId: createThreadRequestId(),
|
|
4188
|
+
threadId
|
|
4189
|
+
}));
|
|
4190
|
+
},
|
|
3960
4191
|
deleteThread(threadId) {
|
|
3961
4192
|
return trackMutation(threadAdapterEvents.deleteRequested({
|
|
3962
4193
|
requestId: createThreadRequestId(),
|
|
@@ -3966,15 +4197,21 @@ function createThreadStore(environment) {
|
|
|
3966
4197
|
getState() {
|
|
3967
4198
|
return store.getState();
|
|
3968
4199
|
},
|
|
3969
|
-
|
|
4200
|
+
getServerState() {
|
|
4201
|
+
return initialThreadState;
|
|
4202
|
+
},
|
|
4203
|
+
select: store.select.bind(store),
|
|
4204
|
+
selectors
|
|
3970
4205
|
};
|
|
3971
4206
|
}
|
|
3972
4207
|
const ɵthreadAdapterEvents = threadAdapterEvents;
|
|
4208
|
+
const ɵcreateThreadSelectors = createThreadSelectors;
|
|
3973
4209
|
const ɵselectThreads = selectThreads;
|
|
3974
4210
|
const ɵselectThreadsIsLoading = selectThreadsIsLoading;
|
|
3975
4211
|
const ɵselectThreadsError = selectThreadsError;
|
|
3976
4212
|
const ɵselectHasNextPage = selectHasNextPage;
|
|
3977
4213
|
const ɵselectIsFetchingNextPage = selectIsFetchingNextPage;
|
|
4214
|
+
const ɵselectIsMutating = selectIsMutating;
|
|
3978
4215
|
/**
|
|
3979
4216
|
* Number of consecutive WebSocket connection failures after which the
|
|
3980
4217
|
* threads channel tears itself down rather than retrying indefinitely.
|
|
@@ -3984,5 +4221,50 @@ const ɵselectIsFetchingNextPage = selectIsFetchingNextPage;
|
|
|
3984
4221
|
const ɵMAX_SOCKET_RETRIES = MAX_SOCKET_RETRIES;
|
|
3985
4222
|
|
|
3986
4223
|
//#endregion
|
|
3987
|
-
|
|
4224
|
+
//#region src/features.ts
|
|
4225
|
+
/**
|
|
4226
|
+
* Central registry of CopilotKit feature names.
|
|
4227
|
+
*
|
|
4228
|
+
* Feature names are the strings passed to a license context's `checkFeature`
|
|
4229
|
+
* (see `@copilotkit/shared`'s `LicenseContextValue`). Historically the only
|
|
4230
|
+
* features referenced by literal were the chat surfaces (`chat`, `sidebar`,
|
|
4231
|
+
* `popup`); this module makes the set explicit and typed so new surfaces —
|
|
4232
|
+
* such as the threads drawer — register a real, discoverable feature name
|
|
4233
|
+
* rather than an ad-hoc string scattered across components.
|
|
4234
|
+
*
|
|
4235
|
+
* `checkFeature` itself still accepts any `string` for backward compatibility;
|
|
4236
|
+
* this registry simply documents and types the names CopilotKit recognises.
|
|
4237
|
+
*/
|
|
4238
|
+
/**
|
|
4239
|
+
* The set of feature names CopilotKit recognises.
|
|
4240
|
+
*
|
|
4241
|
+
* Frozen so the array cannot be mutated at runtime. Add new surfaces here when
|
|
4242
|
+
* they begin gating behaviour on `checkFeature`.
|
|
4243
|
+
*/
|
|
4244
|
+
const ɵCOPILOTKIT_FEATURES = Object.freeze([
|
|
4245
|
+
"chat",
|
|
4246
|
+
"sidebar",
|
|
4247
|
+
"popup",
|
|
4248
|
+
"threads"
|
|
4249
|
+
]);
|
|
4250
|
+
const FEATURE_SET = new Set(ɵCOPILOTKIT_FEATURES);
|
|
4251
|
+
/**
|
|
4252
|
+
* Type guard: returns `true` when `name` is a recognised CopilotKit feature.
|
|
4253
|
+
*
|
|
4254
|
+
* @param name - Candidate feature name.
|
|
4255
|
+
* @returns Whether `name` is a registered feature.
|
|
4256
|
+
*
|
|
4257
|
+
* @example
|
|
4258
|
+
* ```ts
|
|
4259
|
+
* if (ɵisCopilotKitFeature("threads")) {
|
|
4260
|
+
* // narrowed to ɵCopilotKitFeature
|
|
4261
|
+
* }
|
|
4262
|
+
* ```
|
|
4263
|
+
*/
|
|
4264
|
+
function ɵisCopilotKitFeature(name) {
|
|
4265
|
+
return FEATURE_SET.has(name);
|
|
4266
|
+
}
|
|
4267
|
+
|
|
4268
|
+
//#endregion
|
|
4269
|
+
export { AgentRegistry, AgentThreadLockedError, ContextStore, CopilotKitCore, CopilotKitCoreErrorCode, CopilotKitCoreRuntimeConnectionStatus, IntelligenceAgent, ProxiedCopilotRuntimeAgent, RunHandler, StateManager, SuggestionEngine, ToolCallStatus, completePartialMarkdown, createActionGroup, createEffect, createReducer, createSelector, createStore, empty, ensureObjectArgs, isRunCompletionAware, ofType, on, parseToolArguments, props, select, ɵCOPILOTKIT_FEATURES, ɵMAX_SOCKET_RETRIES, ɵcreateThreadSelectors, createThreadStore as ɵcreateThreadStore, ɵisCopilotKitFeature, ɵjoinPhoenixChannel$, ɵobservePhoenixEvent$, ɵobservePhoenixJoinOutcome$, ɵobservePhoenixSocketHealth$, ɵobservePhoenixSocketSignals$, ɵphoenixChannel$, ɵphoenixSocket$, ɵselectHasNextPage, ɵselectIsFetchingNextPage, ɵselectIsMutating, ɵselectThreads, ɵselectThreadsError, ɵselectThreadsIsLoading, ɵthreadAdapterEvents };
|
|
3988
4270
|
//# sourceMappingURL=index.mjs.map
|