@copilotkitnext/core 1.54.0 → 1.54.1-next.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 +1287 -181
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +482 -15
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +482 -15
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +1280 -196
- package/dist/index.mjs.map +1 -1
- package/dist/index.umd.js +1378 -204
- package/dist/index.umd.js.map +1 -1
- package/package.json +4 -4
package/dist/index.umd.js
CHANGED
|
@@ -1,10 +1,128 @@
|
|
|
1
1
|
(function(global, factory) {
|
|
2
|
-
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@ag-ui/client'), require('@copilotkitnext/shared'), require('rxjs'), require('rxjs/operators'), require('zod-to-json-schema'), require('
|
|
3
|
-
typeof define === 'function' && define.amd ? define(['exports', '@ag-ui/client', '@copilotkitnext/shared', 'rxjs', 'rxjs/operators', 'zod-to-json-schema', '
|
|
4
|
-
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory((global.CopilotKitNextCore = {}), global.AgUIClient,global.CopilotKitNextShared,global.rxjs,global.rxjs.operators,global.zodToJsonSchema,global.
|
|
5
|
-
})(this, function(exports, _ag_ui_client, _copilotkitnext_shared, rxjs, rxjs_operators, zod_to_json_schema,
|
|
2
|
+
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@ag-ui/client'), require('@copilotkitnext/shared'), require('rxjs'), require('rxjs/operators'), require('phoenix'), require('zod-to-json-schema'), require('rxjs/fetch')) :
|
|
3
|
+
typeof define === 'function' && define.amd ? define(['exports', '@ag-ui/client', '@copilotkitnext/shared', 'rxjs', 'rxjs/operators', 'phoenix', 'zod-to-json-schema', 'rxjs/fetch'], factory) :
|
|
4
|
+
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory((global.CopilotKitNextCore = {}), global.AgUIClient,global.CopilotKitNextShared,global.rxjs,global.rxjs.operators,global.phoenix,global.zodToJsonSchema,global.rxjs_fetch));
|
|
5
|
+
})(this, function(exports, _ag_ui_client, _copilotkitnext_shared, rxjs, rxjs_operators, phoenix, zod_to_json_schema, rxjs_fetch) {
|
|
6
6
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
7
7
|
|
|
8
|
+
//#region src/utils/phoenix-observable.ts
|
|
9
|
+
/**
|
|
10
|
+
* Adapt Phoenix socket open/error callbacks into an observable signal stream.
|
|
11
|
+
*
|
|
12
|
+
* The returned observable is shared and replayable by the caller when needed,
|
|
13
|
+
* but this helper itself does not own socket connection teardown.
|
|
14
|
+
*/
|
|
15
|
+
function ɵcreatePhoenixSocketSignals$(socket) {
|
|
16
|
+
return new rxjs.Observable((observer) => {
|
|
17
|
+
socket.onOpen(() => observer.next({ type: "open" }));
|
|
18
|
+
socket.onError((error) => observer.next({
|
|
19
|
+
type: "error",
|
|
20
|
+
error
|
|
21
|
+
}));
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Adapt a Phoenix channel join attempt into a single-outcome observable.
|
|
26
|
+
*/
|
|
27
|
+
function ɵcreatePhoenixJoinOutcome$(channel) {
|
|
28
|
+
return new rxjs.Observable((observer) => {
|
|
29
|
+
channel.join().receive("ok", () => {
|
|
30
|
+
observer.next({ type: "joined" });
|
|
31
|
+
observer.complete();
|
|
32
|
+
}).receive("error", (response) => {
|
|
33
|
+
observer.next({
|
|
34
|
+
type: "error",
|
|
35
|
+
response
|
|
36
|
+
});
|
|
37
|
+
observer.complete();
|
|
38
|
+
}).receive("timeout", () => {
|
|
39
|
+
observer.next({ type: "timeout" });
|
|
40
|
+
observer.complete();
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Create a cold Phoenix socket session.
|
|
46
|
+
*
|
|
47
|
+
* The socket is constructed and connected on subscription, and disconnected on
|
|
48
|
+
* teardown. Each subscription creates an isolated socket instance.
|
|
49
|
+
*/
|
|
50
|
+
function ɵphoenixSocket$(options) {
|
|
51
|
+
return (0, rxjs.defer)(() => {
|
|
52
|
+
const socket = new phoenix.Socket(options.url, options.options);
|
|
53
|
+
const signals$ = ɵcreatePhoenixSocketSignals$(socket).pipe((0, rxjs_operators.shareReplay)({
|
|
54
|
+
bufferSize: 1,
|
|
55
|
+
refCount: true
|
|
56
|
+
}));
|
|
57
|
+
socket.connect();
|
|
58
|
+
return (0, rxjs.concat)((0, rxjs.of)({
|
|
59
|
+
socket,
|
|
60
|
+
signals$
|
|
61
|
+
}), rxjs.NEVER).pipe((0, rxjs_operators.finalize)(() => socket.disconnect()));
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Create a cold Phoenix channel session from a socket session stream.
|
|
66
|
+
*
|
|
67
|
+
* A channel is created and joined for each active socket session. If the
|
|
68
|
+
* upstream socket session changes, the previous channel is left before the
|
|
69
|
+
* next one becomes active.
|
|
70
|
+
*/
|
|
71
|
+
function ɵphoenixChannel$(options) {
|
|
72
|
+
return options.socket$.pipe((0, rxjs_operators.switchMap)(({ socket }) => (0, rxjs.defer)(() => {
|
|
73
|
+
const channel = socket.channel(options.topic, options.params);
|
|
74
|
+
return (0, rxjs.concat)((0, rxjs.of)({
|
|
75
|
+
channel,
|
|
76
|
+
joinOutcome$: ɵcreatePhoenixJoinOutcome$(channel).pipe((0, rxjs_operators.shareReplay)({
|
|
77
|
+
bufferSize: 1,
|
|
78
|
+
refCount: true
|
|
79
|
+
}))
|
|
80
|
+
}), rxjs.NEVER).pipe((0, rxjs_operators.finalize)(() => {
|
|
81
|
+
if (options.leaveOnUnsubscribe !== false) channel.leave();
|
|
82
|
+
}));
|
|
83
|
+
})));
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Observe a named Phoenix channel event as an observable payload stream.
|
|
87
|
+
*/
|
|
88
|
+
function ɵobservePhoenixEvent$(channel, eventName) {
|
|
89
|
+
return new rxjs.Observable((observer) => {
|
|
90
|
+
const ref = channel.on(eventName, (payload) => observer.next(payload));
|
|
91
|
+
return () => {
|
|
92
|
+
channel.off(eventName, ref);
|
|
93
|
+
};
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Flatten channel sessions into their join-outcome stream.
|
|
98
|
+
*/
|
|
99
|
+
function ɵobservePhoenixJoinOutcome$(channel$) {
|
|
100
|
+
return channel$.pipe((0, rxjs_operators.switchMap)((session) => session.joinOutcome$));
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Complete when a channel joins successfully, or error if the join fails.
|
|
104
|
+
*/
|
|
105
|
+
function ɵjoinPhoenixChannel$(channel$) {
|
|
106
|
+
return ɵobservePhoenixJoinOutcome$(channel$).pipe((0, rxjs_operators.take)(1), (0, rxjs_operators.mergeMap)((outcome) => {
|
|
107
|
+
if (outcome.type === "joined") return rxjs.EMPTY;
|
|
108
|
+
throw outcome.type === "timeout" ? /* @__PURE__ */ new Error("Timed out joining channel") : /* @__PURE__ */ new Error(`Failed to join channel: ${JSON.stringify(outcome.response)}`);
|
|
109
|
+
}));
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Flatten socket sessions into their lifecycle signal stream.
|
|
113
|
+
*/
|
|
114
|
+
function ɵobservePhoenixSocketSignals$(socket$) {
|
|
115
|
+
return socket$.pipe((0, rxjs_operators.switchMap)((session) => session.signals$));
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Error after a socket emits the configured number of consecutive error
|
|
119
|
+
* signals, resetting the counter after each successful open signal.
|
|
120
|
+
*/
|
|
121
|
+
function ɵobservePhoenixSocketHealth$(socketSignals$, maxConsecutiveErrors) {
|
|
122
|
+
return socketSignals$.pipe((0, rxjs_operators.scan)((consecutiveErrors, signal) => signal.type === "open" ? 0 : consecutiveErrors + 1, 0), (0, rxjs_operators.filter)((consecutiveErrors) => consecutiveErrors >= maxConsecutiveErrors), (0, rxjs_operators.take)(1), (0, rxjs_operators.mergeMap)((consecutiveErrors) => (0, rxjs.throwError)(() => /* @__PURE__ */ new Error(`WebSocket connection failed after ${consecutiveErrors} consecutive errors`))));
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
//#endregion
|
|
8
126
|
//#region \0@oxc-project+runtime@0.112.0/helpers/typeof.js
|
|
9
127
|
function _typeof(o) {
|
|
10
128
|
"@babel/helpers - typeof";
|
|
@@ -46,28 +164,445 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
46
164
|
}) : e[r] = t, e;
|
|
47
165
|
}
|
|
48
166
|
|
|
167
|
+
//#endregion
|
|
168
|
+
//#region src/intelligence-agent.ts
|
|
169
|
+
const CLIENT_AG_UI_EVENT = "ag_ui_event";
|
|
170
|
+
const STOP_RUN_EVENT = "stop_run";
|
|
171
|
+
var IntelligenceAgent = class IntelligenceAgent extends _ag_ui_client.AbstractAgent {
|
|
172
|
+
constructor(config, sharedState = { lastSeenEventIds: /* @__PURE__ */ new Map() }) {
|
|
173
|
+
super();
|
|
174
|
+
_defineProperty(this, "config", void 0);
|
|
175
|
+
_defineProperty(this, "socket", null);
|
|
176
|
+
_defineProperty(this, "activeChannel", null);
|
|
177
|
+
_defineProperty(this, "runId", null);
|
|
178
|
+
_defineProperty(this, "sharedState", void 0);
|
|
179
|
+
this.config = config;
|
|
180
|
+
this.sharedState = sharedState;
|
|
181
|
+
}
|
|
182
|
+
clone() {
|
|
183
|
+
return new IntelligenceAgent(this.config, this.sharedState);
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Override of AbstractAgent.connectAgent that removes the `verifyEvents` step.
|
|
187
|
+
*
|
|
188
|
+
* Background: AbstractAgent's connectAgent pipeline runs events through
|
|
189
|
+
* `verifyEvents`, which validates that the stream follows the AG-UI protocol
|
|
190
|
+
* lifecycle — specifically, it expects a RUN_STARTED event before any content
|
|
191
|
+
* events and a RUN_FINISHED/RUN_ERROR event to complete the stream.
|
|
192
|
+
*
|
|
193
|
+
* IntelligenceAgent uses long-lived WebSocket connections rather than
|
|
194
|
+
* request-scoped SSE streams. When connecting to replay historical messages
|
|
195
|
+
* for an existing thread, the connection semantics don't map to a single
|
|
196
|
+
* agent run start/stop cycle. The replayed events may not include
|
|
197
|
+
* RUN_STARTED/RUN_FINISHED bookends (or may contain events from multiple
|
|
198
|
+
* past runs), which causes verifyEvents to either never complete or to
|
|
199
|
+
* error out.
|
|
200
|
+
*
|
|
201
|
+
* This override replicates the base connectAgent implementation exactly,
|
|
202
|
+
* substituting only `transformChunks` (which is still needed for message
|
|
203
|
+
* reassembly) and omitting `verifyEvents`.
|
|
204
|
+
*
|
|
205
|
+
* TODO: Remove this override once AG-UI's AbstractAgent supports opting out
|
|
206
|
+
* of verifyEvents for transports with different connection life-cycles.
|
|
207
|
+
*/
|
|
208
|
+
async connectAgent(parameters, subscriber) {
|
|
209
|
+
const self = this;
|
|
210
|
+
try {
|
|
211
|
+
var _this$agentId;
|
|
212
|
+
this.isRunning = true;
|
|
213
|
+
this.agentId = (_this$agentId = this.agentId) !== null && _this$agentId !== void 0 ? _this$agentId : (0, _ag_ui_client.randomUUID)();
|
|
214
|
+
const input = this.prepareRunAgentInput(parameters);
|
|
215
|
+
let result;
|
|
216
|
+
const previousMessageIds = new Set(this.messages.map((m) => m.id));
|
|
217
|
+
const subscribers = [
|
|
218
|
+
{ onRunFinishedEvent: (event) => {
|
|
219
|
+
result = event.result;
|
|
220
|
+
} },
|
|
221
|
+
...this.subscribers,
|
|
222
|
+
subscriber !== null && subscriber !== void 0 ? subscriber : {}
|
|
223
|
+
];
|
|
224
|
+
await this.onInitialize(input, subscribers);
|
|
225
|
+
self.activeRunDetach$ = new rxjs.Subject();
|
|
226
|
+
let resolveCompletion;
|
|
227
|
+
self.activeRunCompletionPromise = new Promise((resolve) => {
|
|
228
|
+
resolveCompletion = resolve;
|
|
229
|
+
});
|
|
230
|
+
const source$ = (0, rxjs.defer)(() => this.connect(input)).pipe((0, _ag_ui_client.transformChunks)(this.debug), (0, rxjs_operators.takeUntil)(self.activeRunDetach$));
|
|
231
|
+
const applied$ = this.apply(input, source$, subscribers);
|
|
232
|
+
await (0, rxjs.lastValueFrom)(this.processApplyEvents(input, applied$, subscribers).pipe((0, rxjs_operators.catchError)((error) => {
|
|
233
|
+
this.isRunning = false;
|
|
234
|
+
return this.onError(input, error, subscribers);
|
|
235
|
+
}), (0, rxjs_operators.finalize)(() => {
|
|
236
|
+
this.isRunning = false;
|
|
237
|
+
this.onFinalize(input, subscribers);
|
|
238
|
+
resolveCompletion === null || resolveCompletion === void 0 || resolveCompletion();
|
|
239
|
+
resolveCompletion = void 0;
|
|
240
|
+
self.activeRunCompletionPromise = void 0;
|
|
241
|
+
self.activeRunDetach$ = void 0;
|
|
242
|
+
})), { defaultValue: void 0 });
|
|
243
|
+
const newMessages = (0, _ag_ui_client.structuredClone_)(this.messages).filter((m) => !previousMessageIds.has(m.id));
|
|
244
|
+
return {
|
|
245
|
+
result,
|
|
246
|
+
newMessages
|
|
247
|
+
};
|
|
248
|
+
} finally {
|
|
249
|
+
this.isRunning = false;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
abortRun() {
|
|
253
|
+
if (this.activeChannel && this.runId) {
|
|
254
|
+
const fallback = setTimeout(() => clear(), 5e3);
|
|
255
|
+
const clear = () => {
|
|
256
|
+
clearTimeout(fallback);
|
|
257
|
+
this.detachActiveRun();
|
|
258
|
+
this.cleanup();
|
|
259
|
+
};
|
|
260
|
+
this.activeChannel.push(STOP_RUN_EVENT, { run_id: this.runId }).receive("ok", clear).receive("error", clear).receive("timeout", clear);
|
|
261
|
+
} else {
|
|
262
|
+
this.detachActiveRun();
|
|
263
|
+
this.cleanup();
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* Trigger the run via REST, then join the realtime thread channel and relay
|
|
268
|
+
* server-pushed AG-UI events to the Observable subscriber.
|
|
269
|
+
*/
|
|
270
|
+
run(input) {
|
|
271
|
+
this.threadId = input.threadId;
|
|
272
|
+
this.runId = input.runId;
|
|
273
|
+
return (0, rxjs.defer)(() => this.requestJoinCredentials$("run", input)).pipe((0, rxjs.switchMap)((credentials) => this.observeThread$(input, credentials, {
|
|
274
|
+
completeOnRunError: false,
|
|
275
|
+
streamMode: "run"
|
|
276
|
+
})));
|
|
277
|
+
}
|
|
278
|
+
/**
|
|
279
|
+
* Reconnect to an existing thread by fetching websocket credentials and
|
|
280
|
+
* joining the realtime thread channel.
|
|
281
|
+
*/
|
|
282
|
+
connect(input) {
|
|
283
|
+
this.threadId = input.threadId;
|
|
284
|
+
this.runId = input.runId;
|
|
285
|
+
return (0, rxjs.defer)(() => this.requestConnectPlan$(input)).pipe((0, rxjs.switchMap)((plan) => {
|
|
286
|
+
if (plan === null) return rxjs.EMPTY;
|
|
287
|
+
if (plan.mode === "bootstrap") {
|
|
288
|
+
this.setLastSeenEventId(input.threadId, plan.latestEventId);
|
|
289
|
+
for (const event of plan.events) this.updateRunIdFromEvent(event);
|
|
290
|
+
return (0, rxjs.from)(plan.events);
|
|
291
|
+
}
|
|
292
|
+
this.setLastSeenEventId(input.threadId, plan.joinFromEventId);
|
|
293
|
+
for (const event of plan.events) this.updateRunIdFromEvent(event);
|
|
294
|
+
return (0, rxjs.concat)((0, rxjs.from)(plan.events), this.observeThread$(input, { joinToken: plan.joinToken }, {
|
|
295
|
+
completeOnRunError: true,
|
|
296
|
+
streamMode: "connect",
|
|
297
|
+
replayCursor: plan.joinFromEventId
|
|
298
|
+
}));
|
|
299
|
+
}));
|
|
300
|
+
}
|
|
301
|
+
/**
|
|
302
|
+
* Tear down a specific channel + socket pair that belongs to one pipeline.
|
|
303
|
+
* Only nulls instance references when they still point to the owned resource,
|
|
304
|
+
* so a concurrent pipeline's resources are never clobbered.
|
|
305
|
+
*/
|
|
306
|
+
cleanupOwned(ownChannel, ownSocket) {
|
|
307
|
+
if (ownChannel) {
|
|
308
|
+
ownChannel.leave();
|
|
309
|
+
if (this.activeChannel === ownChannel) this.activeChannel = null;
|
|
310
|
+
}
|
|
311
|
+
if (ownSocket) {
|
|
312
|
+
ownSocket.disconnect();
|
|
313
|
+
if (this.socket === ownSocket) this.socket = null;
|
|
314
|
+
}
|
|
315
|
+
if (this.threadId) this.sharedState.lastSeenEventIds.delete(this.threadId);
|
|
316
|
+
this.runId = null;
|
|
317
|
+
}
|
|
318
|
+
cleanup() {
|
|
319
|
+
this.cleanupOwned(this.activeChannel, this.socket);
|
|
320
|
+
}
|
|
321
|
+
requestJoinCredentials$(mode, input) {
|
|
322
|
+
return (0, rxjs.defer)(async () => {
|
|
323
|
+
try {
|
|
324
|
+
const response = await fetch(this.buildRuntimeUrl(mode), {
|
|
325
|
+
method: "POST",
|
|
326
|
+
headers: {
|
|
327
|
+
"Content-Type": "application/json",
|
|
328
|
+
...this.config.headers
|
|
329
|
+
},
|
|
330
|
+
body: JSON.stringify({
|
|
331
|
+
threadId: input.threadId,
|
|
332
|
+
runId: input.runId,
|
|
333
|
+
messages: input.messages,
|
|
334
|
+
tools: input.tools,
|
|
335
|
+
context: input.context,
|
|
336
|
+
state: input.state,
|
|
337
|
+
forwardedProps: input.forwardedProps
|
|
338
|
+
}),
|
|
339
|
+
...this.config.credentials ? { credentials: this.config.credentials } : {}
|
|
340
|
+
});
|
|
341
|
+
if (!response.ok) {
|
|
342
|
+
const text = await response.text().catch(() => "");
|
|
343
|
+
throw new Error(text || response.statusText || String(response.status));
|
|
344
|
+
}
|
|
345
|
+
const payload = await response.json();
|
|
346
|
+
if (!payload.joinToken) throw new Error("missing joinToken");
|
|
347
|
+
return { joinToken: payload.joinToken };
|
|
348
|
+
} catch (error) {
|
|
349
|
+
throw new Error(`REST ${mode} request failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
350
|
+
}
|
|
351
|
+
});
|
|
352
|
+
}
|
|
353
|
+
requestConnectPlan$(input) {
|
|
354
|
+
return (0, rxjs.defer)(async () => {
|
|
355
|
+
try {
|
|
356
|
+
const response = await fetch(this.buildRuntimeUrl("connect"), {
|
|
357
|
+
method: "POST",
|
|
358
|
+
headers: {
|
|
359
|
+
"Content-Type": "application/json",
|
|
360
|
+
...this.config.headers
|
|
361
|
+
},
|
|
362
|
+
body: JSON.stringify({
|
|
363
|
+
threadId: input.threadId,
|
|
364
|
+
runId: input.runId,
|
|
365
|
+
messages: input.messages,
|
|
366
|
+
tools: input.tools,
|
|
367
|
+
context: input.context,
|
|
368
|
+
state: input.state,
|
|
369
|
+
forwardedProps: input.forwardedProps,
|
|
370
|
+
lastSeenEventId: this.getReconnectCursor(input)
|
|
371
|
+
}),
|
|
372
|
+
...this.config.credentials ? { credentials: this.config.credentials } : {}
|
|
373
|
+
});
|
|
374
|
+
if (response.status === 204) return null;
|
|
375
|
+
if (!response.ok) {
|
|
376
|
+
const text = await response.text().catch(() => "");
|
|
377
|
+
throw new Error(text || response.statusText || String(response.status));
|
|
378
|
+
}
|
|
379
|
+
return this.normalizeConnectPlan(await response.json());
|
|
380
|
+
} catch (error) {
|
|
381
|
+
throw new Error(`REST connect request failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
382
|
+
}
|
|
383
|
+
});
|
|
384
|
+
}
|
|
385
|
+
normalizeConnectPlan(payload) {
|
|
386
|
+
const envelope = payload && typeof payload === "object" ? payload : null;
|
|
387
|
+
if ((envelope === null || envelope === void 0 ? void 0 : envelope.mode) === "bootstrap") return {
|
|
388
|
+
mode: "bootstrap",
|
|
389
|
+
latestEventId: typeof envelope.latestEventId === "string" ? envelope.latestEventId : null,
|
|
390
|
+
events: Array.isArray(envelope.events) ? envelope.events : []
|
|
391
|
+
};
|
|
392
|
+
if ((envelope === null || envelope === void 0 ? void 0 : envelope.mode) === "live") {
|
|
393
|
+
if (typeof envelope.joinToken !== "string" || envelope.joinToken.length === 0) throw new Error("missing joinToken");
|
|
394
|
+
return {
|
|
395
|
+
mode: "live",
|
|
396
|
+
joinToken: envelope.joinToken,
|
|
397
|
+
joinFromEventId: typeof envelope.joinFromEventId === "string" ? envelope.joinFromEventId : null,
|
|
398
|
+
events: Array.isArray(envelope.events) ? envelope.events : []
|
|
399
|
+
};
|
|
400
|
+
}
|
|
401
|
+
throw new Error("invalid connect plan");
|
|
402
|
+
}
|
|
403
|
+
observeThread$(input, credentials, options) {
|
|
404
|
+
return (0, rxjs.defer)(() => {
|
|
405
|
+
var _this$config$socketPa;
|
|
406
|
+
let ownSocket = null;
|
|
407
|
+
let ownChannel = null;
|
|
408
|
+
const socket$ = ɵphoenixSocket$({
|
|
409
|
+
url: this.config.url,
|
|
410
|
+
options: {
|
|
411
|
+
params: {
|
|
412
|
+
...(_this$config$socketPa = this.config.socketParams) !== null && _this$config$socketPa !== void 0 ? _this$config$socketPa : {},
|
|
413
|
+
join_token: credentials.joinToken
|
|
414
|
+
},
|
|
415
|
+
reconnectAfterMs: (0, _copilotkitnext_shared.phoenixExponentialBackoff)(100, 1e4),
|
|
416
|
+
rejoinAfterMs: (0, _copilotkitnext_shared.phoenixExponentialBackoff)(1e3, 3e4)
|
|
417
|
+
}
|
|
418
|
+
}).pipe((0, rxjs_operators.tap)(({ socket }) => {
|
|
419
|
+
ownSocket = socket;
|
|
420
|
+
this.socket = ownSocket;
|
|
421
|
+
}), (0, rxjs_operators.shareReplay)({
|
|
422
|
+
bufferSize: 1,
|
|
423
|
+
refCount: true
|
|
424
|
+
}));
|
|
425
|
+
const { topic, params } = this.createThreadChannelDescriptor(input, options.streamMode, options.replayCursor);
|
|
426
|
+
const channel$ = ɵphoenixChannel$({
|
|
427
|
+
socket$,
|
|
428
|
+
topic,
|
|
429
|
+
params
|
|
430
|
+
}).pipe((0, rxjs_operators.tap)(({ channel }) => {
|
|
431
|
+
ownChannel = channel;
|
|
432
|
+
this.activeChannel = ownChannel;
|
|
433
|
+
}), (0, rxjs_operators.shareReplay)({
|
|
434
|
+
bufferSize: 1,
|
|
435
|
+
refCount: true
|
|
436
|
+
}));
|
|
437
|
+
const threadEvents$ = this.observeThreadEvents$(input.threadId, channel$, options).pipe((0, rxjs_operators.share)());
|
|
438
|
+
const threadCompleted$ = threadEvents$.pipe((0, rxjs_operators.ignoreElements)(), (0, rxjs_operators.endWith)(null), (0, rxjs_operators.take)(1));
|
|
439
|
+
return (0, rxjs.merge)(this.joinThreadChannel$(channel$), this.observeSocketHealth$(socket$).pipe((0, rxjs_operators.takeUntil)(threadCompleted$)), threadEvents$).pipe((0, rxjs_operators.finalize)(() => this.cleanupOwned(ownChannel, ownSocket)));
|
|
440
|
+
});
|
|
441
|
+
}
|
|
442
|
+
joinThreadChannel$(channel$) {
|
|
443
|
+
return ɵjoinPhoenixChannel$(channel$);
|
|
444
|
+
}
|
|
445
|
+
observeSocketHealth$(socket$) {
|
|
446
|
+
return ɵobservePhoenixSocketHealth$(ɵobservePhoenixSocketSignals$(socket$), 5);
|
|
447
|
+
}
|
|
448
|
+
observeThreadEvents$(threadId, channel$, options) {
|
|
449
|
+
return channel$.pipe((0, rxjs_operators.switchMap)(({ channel }) => this.observeChannelEvent$(channel, CLIENT_AG_UI_EVENT)), (0, rxjs_operators.tap)((payload) => {
|
|
450
|
+
this.updateLastSeenEventId(threadId, payload);
|
|
451
|
+
this.updateRunIdFromEvent(payload);
|
|
452
|
+
}), (0, rxjs_operators.mergeMap)((payload) => (0, rxjs.from)(this.createThreadNotifications(payload, options.completeOnRunError))), (0, rxjs.dematerialize)());
|
|
453
|
+
}
|
|
454
|
+
observeChannelEvent$(channel, eventName) {
|
|
455
|
+
return ɵobservePhoenixEvent$(channel, eventName);
|
|
456
|
+
}
|
|
457
|
+
createThreadNotifications(payload, completeOnRunError) {
|
|
458
|
+
if (payload.type === _ag_ui_client.EventType.RUN_FINISHED) return [rxjs.Notification.createNext(payload), rxjs.Notification.createComplete()];
|
|
459
|
+
if (payload.type === _ag_ui_client.EventType.RUN_ERROR) {
|
|
460
|
+
var _message;
|
|
461
|
+
const errorMessage = (_message = payload.message) !== null && _message !== void 0 ? _message : "Run error";
|
|
462
|
+
return completeOnRunError ? [rxjs.Notification.createNext(payload), rxjs.Notification.createComplete()] : [rxjs.Notification.createNext(payload), rxjs.Notification.createError(new Error(errorMessage))];
|
|
463
|
+
}
|
|
464
|
+
return [rxjs.Notification.createNext(payload)];
|
|
465
|
+
}
|
|
466
|
+
buildRuntimeUrl(mode) {
|
|
467
|
+
const path = `${this.config.runtimeUrl}/agent/${encodeURIComponent(this.config.agentId)}/${mode}`;
|
|
468
|
+
const origin = typeof window !== "undefined" && window.location ? window.location.origin : "http://localhost";
|
|
469
|
+
return new URL(path, new URL(this.config.runtimeUrl, origin)).toString();
|
|
470
|
+
}
|
|
471
|
+
createThreadChannelDescriptor(input, streamMode, replayCursor) {
|
|
472
|
+
const params = streamMode === "run" ? {
|
|
473
|
+
stream_mode: "run",
|
|
474
|
+
run_id: input.runId
|
|
475
|
+
} : {
|
|
476
|
+
stream_mode: "connect",
|
|
477
|
+
last_seen_event_id: replayCursor === void 0 ? this.getReconnectCursor(input) : replayCursor
|
|
478
|
+
};
|
|
479
|
+
return {
|
|
480
|
+
topic: `thread:${input.threadId}`,
|
|
481
|
+
params
|
|
482
|
+
};
|
|
483
|
+
}
|
|
484
|
+
getLastSeenEventId(threadId) {
|
|
485
|
+
var _this$sharedState$las;
|
|
486
|
+
return (_this$sharedState$las = this.sharedState.lastSeenEventIds.get(threadId)) !== null && _this$sharedState$las !== void 0 ? _this$sharedState$las : null;
|
|
487
|
+
}
|
|
488
|
+
getReconnectCursor(input) {
|
|
489
|
+
return this.hasLocalThreadMessages(input) ? this.getLastSeenEventId(input.threadId) : null;
|
|
490
|
+
}
|
|
491
|
+
hasLocalThreadMessages(input) {
|
|
492
|
+
return Array.isArray(input.messages) && input.messages.length > 0;
|
|
493
|
+
}
|
|
494
|
+
updateLastSeenEventId(threadId, payload) {
|
|
495
|
+
const eventId = this.readEventId(payload);
|
|
496
|
+
if (!eventId) return;
|
|
497
|
+
this.sharedState.lastSeenEventIds.set(threadId, eventId);
|
|
498
|
+
}
|
|
499
|
+
setLastSeenEventId(threadId, eventId) {
|
|
500
|
+
if (!eventId) return;
|
|
501
|
+
this.sharedState.lastSeenEventIds.set(threadId, eventId);
|
|
502
|
+
}
|
|
503
|
+
/**
|
|
504
|
+
* Keep `this.runId` in sync with the backend's actual run ID.
|
|
505
|
+
*
|
|
506
|
+
* During a `connect` (resume) flow the client generates a fresh `runId`
|
|
507
|
+
* via `prepareRunAgentInput`, but the backend is running under its own
|
|
508
|
+
* run ID. If the client later sends `STOP_RUN_EVENT` with the wrong
|
|
509
|
+
* `runId`, the gateway's runner channel will not match it and the agent
|
|
510
|
+
* keeps running. Extracting the run ID from live events fixes this.
|
|
511
|
+
*
|
|
512
|
+
* The runner normalises events to `run_id` (snake_case) before pushing
|
|
513
|
+
* to the gateway, so we check both `runId` and `run_id`.
|
|
514
|
+
*/
|
|
515
|
+
updateRunIdFromEvent(payload) {
|
|
516
|
+
var _record$runId;
|
|
517
|
+
const record = payload;
|
|
518
|
+
const eventRunId = (_record$runId = record.runId) !== null && _record$runId !== void 0 ? _record$runId : record.run_id;
|
|
519
|
+
if (typeof eventRunId === "string" && eventRunId.length > 0) this.runId = eventRunId;
|
|
520
|
+
}
|
|
521
|
+
readEventId(payload) {
|
|
522
|
+
const metadata = payload.metadata;
|
|
523
|
+
if (!metadata || typeof metadata !== "object") return null;
|
|
524
|
+
const runnerEventId = metadata.cpki_event_id;
|
|
525
|
+
return typeof runnerEventId === "string" ? runnerEventId : null;
|
|
526
|
+
}
|
|
527
|
+
};
|
|
528
|
+
|
|
529
|
+
//#endregion
|
|
530
|
+
//#region \0@oxc-project+runtime@0.112.0/helpers/checkPrivateRedeclaration.js
|
|
531
|
+
function _checkPrivateRedeclaration(e, t) {
|
|
532
|
+
if (t.has(e)) throw new TypeError("Cannot initialize the same private elements twice on an object");
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
//#endregion
|
|
536
|
+
//#region \0@oxc-project+runtime@0.112.0/helpers/classPrivateMethodInitSpec.js
|
|
537
|
+
function _classPrivateMethodInitSpec(e, a) {
|
|
538
|
+
_checkPrivateRedeclaration(e, a), a.add(e);
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
//#endregion
|
|
542
|
+
//#region \0@oxc-project+runtime@0.112.0/helpers/assertClassBrand.js
|
|
543
|
+
function _assertClassBrand(e, t, n) {
|
|
544
|
+
if ("function" == typeof e ? e === t : e.has(t)) return arguments.length < 3 ? t : n;
|
|
545
|
+
throw new TypeError("Private element is not present on this object");
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
//#endregion
|
|
549
|
+
//#region \0@oxc-project+runtime@0.112.0/helpers/getPrototypeOf.js
|
|
550
|
+
function _getPrototypeOf(t) {
|
|
551
|
+
return _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function(t) {
|
|
552
|
+
return t.__proto__ || Object.getPrototypeOf(t);
|
|
553
|
+
}, _getPrototypeOf(t);
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
//#endregion
|
|
557
|
+
//#region \0@oxc-project+runtime@0.112.0/helpers/superPropBase.js
|
|
558
|
+
function _superPropBase(t, o) {
|
|
559
|
+
for (; !{}.hasOwnProperty.call(t, o) && null !== (t = _getPrototypeOf(t)););
|
|
560
|
+
return t;
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
//#endregion
|
|
564
|
+
//#region \0@oxc-project+runtime@0.112.0/helpers/get.js
|
|
565
|
+
function _get() {
|
|
566
|
+
return _get = "undefined" != typeof Reflect && Reflect.get ? Reflect.get.bind() : function(e, t, r) {
|
|
567
|
+
var p = _superPropBase(e, t);
|
|
568
|
+
if (p) {
|
|
569
|
+
var n = Object.getOwnPropertyDescriptor(p, t);
|
|
570
|
+
return n.get ? n.get.call(arguments.length < 3 ? e : r) : n.value;
|
|
571
|
+
}
|
|
572
|
+
}, _get.apply(null, arguments);
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
//#endregion
|
|
576
|
+
//#region \0@oxc-project+runtime@0.112.0/helpers/superPropGet.js
|
|
577
|
+
function _superPropGet(t, o, e, r) {
|
|
578
|
+
var p = _get(_getPrototypeOf(1 & r ? t.prototype : t), o, e);
|
|
579
|
+
return 2 & r && "function" == typeof p ? function(t) {
|
|
580
|
+
return p.apply(e, t);
|
|
581
|
+
} : p;
|
|
582
|
+
}
|
|
583
|
+
|
|
49
584
|
//#endregion
|
|
50
585
|
//#region src/agent.ts
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
586
|
+
var _ProxiedCopilotRuntimeAgent;
|
|
587
|
+
function hasHeaders(agent) {
|
|
588
|
+
return "headers" in agent;
|
|
589
|
+
}
|
|
590
|
+
function hasCredentials(agent) {
|
|
591
|
+
return "credentials" in agent;
|
|
592
|
+
}
|
|
55
593
|
function isZodError(error) {
|
|
56
594
|
return error !== null && typeof error === "object" && "name" in error && error.name === "ZodError";
|
|
57
595
|
}
|
|
58
|
-
/**
|
|
59
|
-
* Wrap an Observable to catch and suppress ZodErrors that occur during stream abort.
|
|
60
|
-
* These errors are expected when the connection is cancelled mid-stream.
|
|
61
|
-
*/
|
|
62
596
|
function withAbortErrorHandling(observable) {
|
|
63
597
|
return observable.pipe((0, rxjs_operators.catchError)((error) => {
|
|
64
598
|
if (isZodError(error)) return rxjs.EMPTY;
|
|
65
599
|
throw error;
|
|
66
600
|
}));
|
|
67
601
|
}
|
|
68
|
-
var
|
|
602
|
+
var _ProxiedCopilotRuntimeAgent_brand = /* @__PURE__ */ new WeakSet();
|
|
603
|
+
var ProxiedCopilotRuntimeAgent = class ProxiedCopilotRuntimeAgent extends _ag_ui_client.HttpAgent {
|
|
69
604
|
constructor(config) {
|
|
70
|
-
var _config$transport, _ref, _config$agentId;
|
|
605
|
+
var _config$transport, _ref, _config$agentId, _config$runtimeMode;
|
|
71
606
|
const normalizedRuntimeUrl = config.runtimeUrl ? config.runtimeUrl.replace(/\/$/, "") : void 0;
|
|
72
607
|
const transport = (_config$transport = config.transport) !== null && _config$transport !== void 0 ? _config$transport : "rest";
|
|
73
608
|
const runUrl = transport === "single" ? (_ref = normalizedRuntimeUrl !== null && normalizedRuntimeUrl !== void 0 ? normalizedRuntimeUrl : config.runtimeUrl) !== null && _ref !== void 0 ? _ref : "" : `${normalizedRuntimeUrl !== null && normalizedRuntimeUrl !== void 0 ? normalizedRuntimeUrl : config.runtimeUrl}/agent/${encodeURIComponent((_config$agentId = config.agentId) !== null && _config$agentId !== void 0 ? _config$agentId : "")}/run`;
|
|
@@ -76,16 +611,33 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
76
611
|
...config,
|
|
77
612
|
url: runUrl
|
|
78
613
|
});
|
|
614
|
+
_classPrivateMethodInitSpec(this, _ProxiedCopilotRuntimeAgent_brand);
|
|
79
615
|
_defineProperty(this, "runtimeUrl", void 0);
|
|
80
616
|
_defineProperty(this, "credentials", void 0);
|
|
81
617
|
_defineProperty(this, "transport", void 0);
|
|
82
618
|
_defineProperty(this, "singleEndpointUrl", void 0);
|
|
619
|
+
_defineProperty(this, "runtimeMode", void 0);
|
|
620
|
+
_defineProperty(this, "intelligence", void 0);
|
|
621
|
+
_defineProperty(this, "delegate", void 0);
|
|
622
|
+
_defineProperty(this, "runtimeInfoPromise", void 0);
|
|
83
623
|
this.runtimeUrl = normalizedRuntimeUrl !== null && normalizedRuntimeUrl !== void 0 ? normalizedRuntimeUrl : config.runtimeUrl;
|
|
84
624
|
this.credentials = config.credentials;
|
|
85
625
|
this.transport = transport;
|
|
626
|
+
this.runtimeMode = (_config$runtimeMode = config.runtimeMode) !== null && _config$runtimeMode !== void 0 ? _config$runtimeMode : _copilotkitnext_shared.RUNTIME_MODE_SSE;
|
|
627
|
+
this.intelligence = config.intelligence;
|
|
86
628
|
if (this.transport === "single") this.singleEndpointUrl = this.runtimeUrl;
|
|
87
629
|
}
|
|
630
|
+
async detachActiveRun() {
|
|
631
|
+
if (this.delegate) await this.delegate.detachActiveRun();
|
|
632
|
+
await super.detachActiveRun();
|
|
633
|
+
}
|
|
88
634
|
abortRun() {
|
|
635
|
+
if (this.delegate) {
|
|
636
|
+
this.syncDelegate(this.delegate);
|
|
637
|
+
this.delegate.abortRun();
|
|
638
|
+
this.detachActiveRun();
|
|
639
|
+
return;
|
|
640
|
+
}
|
|
89
641
|
if (!this.agentId || !this.threadId) return;
|
|
90
642
|
if (typeof fetch === "undefined") return;
|
|
91
643
|
if (this.transport === "single") {
|
|
@@ -126,30 +678,112 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
126
678
|
console.error("ProxiedCopilotRuntimeAgent: stop request failed", error);
|
|
127
679
|
});
|
|
128
680
|
}
|
|
129
|
-
|
|
130
|
-
if (this.
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
681
|
+
async connectAgent(parameters, subscriber) {
|
|
682
|
+
if (this.runtimeMode !== _copilotkitnext_shared.RUNTIME_MODE_INTELLIGENCE) return super.connectAgent(parameters, subscriber);
|
|
683
|
+
if (this.delegate) await this.delegate.detachActiveRun();
|
|
684
|
+
await this.resolveDelegate();
|
|
685
|
+
const delegate = this.delegate;
|
|
686
|
+
const bridgeSub = delegate.subscribe({
|
|
687
|
+
onMessagesChanged: () => {
|
|
688
|
+
this.setMessages([...delegate.messages]);
|
|
689
|
+
},
|
|
690
|
+
onStateChanged: () => {
|
|
691
|
+
this.setState({ ...delegate.state });
|
|
692
|
+
},
|
|
693
|
+
onRunInitialized: () => {
|
|
694
|
+
this.isRunning = true;
|
|
695
|
+
},
|
|
696
|
+
onRunFinalized: () => {
|
|
697
|
+
this.isRunning = false;
|
|
698
|
+
},
|
|
699
|
+
onRunFailed: () => {
|
|
700
|
+
this.isRunning = false;
|
|
701
|
+
}
|
|
702
|
+
});
|
|
703
|
+
const forwardedSubs = this.subscribers.map((s) => delegate.subscribe(s));
|
|
704
|
+
try {
|
|
705
|
+
const result = await delegate.connectAgent(parameters, subscriber);
|
|
706
|
+
this.setMessages([...delegate.messages]);
|
|
707
|
+
this.setState({ ...delegate.state });
|
|
708
|
+
return result;
|
|
709
|
+
} finally {
|
|
710
|
+
this.isRunning = false;
|
|
711
|
+
bridgeSub.unsubscribe();
|
|
712
|
+
for (const sub of forwardedSubs) sub.unsubscribe();
|
|
134
713
|
}
|
|
135
|
-
|
|
714
|
+
}
|
|
715
|
+
connect(input) {
|
|
716
|
+
if (this.runtimeMode === _copilotkitnext_shared.RUNTIME_MODE_INTELLIGENCE) return _assertClassBrand(_ProxiedCopilotRuntimeAgent_brand, this, _connectViaDelegate).call(this, input);
|
|
717
|
+
return _assertClassBrand(_ProxiedCopilotRuntimeAgent_brand, this, _connectViaHttp).call(this, input);
|
|
136
718
|
}
|
|
137
719
|
run(input) {
|
|
138
|
-
if (this.
|
|
139
|
-
|
|
140
|
-
const requestInit = this.createSingleRouteRequestInit(input, "agent/run", { agentId: this.agentId });
|
|
141
|
-
return withAbortErrorHandling((0, _ag_ui_client.transformHttpEventStream)((0, _ag_ui_client.runHttpRequest)(this.singleEndpointUrl, requestInit)));
|
|
142
|
-
}
|
|
143
|
-
return withAbortErrorHandling(super.run(input));
|
|
720
|
+
if (this.runtimeMode === _copilotkitnext_shared.RUNTIME_MODE_INTELLIGENCE) return _assertClassBrand(_ProxiedCopilotRuntimeAgent_brand, this, _runViaDelegate).call(this, input);
|
|
721
|
+
return _assertClassBrand(_ProxiedCopilotRuntimeAgent_brand, this, _runViaHttp).call(this, input);
|
|
144
722
|
}
|
|
145
723
|
clone() {
|
|
146
|
-
const cloned =
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
724
|
+
const cloned = new ProxiedCopilotRuntimeAgent({
|
|
725
|
+
runtimeUrl: this.runtimeUrl,
|
|
726
|
+
agentId: this.agentId,
|
|
727
|
+
description: this.description,
|
|
728
|
+
headers: { ...this.headers },
|
|
729
|
+
credentials: this.credentials,
|
|
730
|
+
transport: this.transport,
|
|
731
|
+
runtimeMode: this.runtimeMode,
|
|
732
|
+
intelligence: this.intelligence
|
|
733
|
+
});
|
|
734
|
+
cloned.threadId = this.threadId;
|
|
735
|
+
cloned.setState(this.state);
|
|
736
|
+
cloned.setMessages(this.messages);
|
|
737
|
+
if (this.delegate) {
|
|
738
|
+
cloned.delegate = this.delegate.clone();
|
|
739
|
+
cloned.syncDelegate(cloned.delegate);
|
|
740
|
+
}
|
|
151
741
|
return cloned;
|
|
152
742
|
}
|
|
743
|
+
async resolveDelegate() {
|
|
744
|
+
await this.ensureRuntimeMode();
|
|
745
|
+
if (!this.delegate) {
|
|
746
|
+
if (this.runtimeMode !== _copilotkitnext_shared.RUNTIME_MODE_INTELLIGENCE) throw new Error("A delegate is only created for Intelligence mode");
|
|
747
|
+
this.delegate = this.createIntelligenceDelegate();
|
|
748
|
+
}
|
|
749
|
+
this.syncDelegate(this.delegate);
|
|
750
|
+
return this.delegate;
|
|
751
|
+
}
|
|
752
|
+
async ensureRuntimeMode() {
|
|
753
|
+
var _this$runtimeInfoProm;
|
|
754
|
+
if (this.runtimeMode !== "pending") return;
|
|
755
|
+
if (!this.runtimeUrl) throw new Error("Runtime URL is not set");
|
|
756
|
+
(_this$runtimeInfoProm = this.runtimeInfoPromise) !== null && _this$runtimeInfoProm !== void 0 || (this.runtimeInfoPromise = this.fetchRuntimeInfo().then((runtimeInfo) => {
|
|
757
|
+
var _runtimeInfo$mode;
|
|
758
|
+
this.runtimeMode = (_runtimeInfo$mode = runtimeInfo.mode) !== null && _runtimeInfo$mode !== void 0 ? _runtimeInfo$mode : _copilotkitnext_shared.RUNTIME_MODE_SSE;
|
|
759
|
+
this.intelligence = runtimeInfo.intelligence;
|
|
760
|
+
}));
|
|
761
|
+
await this.runtimeInfoPromise;
|
|
762
|
+
}
|
|
763
|
+
async fetchRuntimeInfo() {
|
|
764
|
+
const headers = { ...this.headers };
|
|
765
|
+
let init;
|
|
766
|
+
let url;
|
|
767
|
+
if (this.transport === "single") {
|
|
768
|
+
if (!this.singleEndpointUrl) throw new Error("Single endpoint transport requires a runtimeUrl");
|
|
769
|
+
if (!headers["Content-Type"]) headers["Content-Type"] = "application/json";
|
|
770
|
+
url = this.runtimeUrl;
|
|
771
|
+
init = {
|
|
772
|
+
method: "POST",
|
|
773
|
+
body: JSON.stringify({ method: "info" })
|
|
774
|
+
};
|
|
775
|
+
} else {
|
|
776
|
+
url = `${this.runtimeUrl}/info`;
|
|
777
|
+
init = {};
|
|
778
|
+
}
|
|
779
|
+
const response = await fetch(url, {
|
|
780
|
+
...init,
|
|
781
|
+
headers,
|
|
782
|
+
...this.credentials ? { credentials: this.credentials } : {}
|
|
783
|
+
});
|
|
784
|
+
if (!response.ok) throw new Error(`Runtime info request failed with status ${response.status}`);
|
|
785
|
+
return await response.json();
|
|
786
|
+
}
|
|
153
787
|
createSingleRouteRequestInit(input, method, params) {
|
|
154
788
|
var _baseInit$headers, _headers$get;
|
|
155
789
|
if (!this.agentId) throw new Error("ProxiedCopilotRuntimeAgent requires agentId to make runtime requests");
|
|
@@ -162,7 +796,6 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
162
796
|
originalBody = JSON.parse(baseInit.body);
|
|
163
797
|
} catch (error) {
|
|
164
798
|
console.warn("ProxiedCopilotRuntimeAgent: failed to parse request body for single route transport", error);
|
|
165
|
-
originalBody = void 0;
|
|
166
799
|
}
|
|
167
800
|
const envelope = { method };
|
|
168
801
|
if (params && Object.keys(params).length > 0) envelope.params = params;
|
|
@@ -174,7 +807,50 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
174
807
|
...this.credentials ? { credentials: this.credentials } : {}
|
|
175
808
|
};
|
|
176
809
|
}
|
|
810
|
+
createIntelligenceDelegate() {
|
|
811
|
+
var _this$intelligence;
|
|
812
|
+
if (!this.runtimeUrl || !this.agentId || !((_this$intelligence = this.intelligence) === null || _this$intelligence === void 0 ? void 0 : _this$intelligence.wsUrl)) throw new Error("Intelligence mode requires runtimeUrl, agentId, and intelligence websocket metadata");
|
|
813
|
+
return new IntelligenceAgent({
|
|
814
|
+
url: this.intelligence.wsUrl,
|
|
815
|
+
runtimeUrl: this.runtimeUrl,
|
|
816
|
+
agentId: this.agentId,
|
|
817
|
+
headers: { ...this.headers },
|
|
818
|
+
credentials: this.credentials
|
|
819
|
+
});
|
|
820
|
+
}
|
|
821
|
+
syncDelegate(delegate) {
|
|
822
|
+
delegate.agentId = this.agentId;
|
|
823
|
+
delegate.description = this.description;
|
|
824
|
+
delegate.threadId = this.threadId;
|
|
825
|
+
delegate.setMessages(this.messages);
|
|
826
|
+
delegate.setState(this.state);
|
|
827
|
+
if (hasHeaders(delegate)) delegate.headers = { ...this.headers };
|
|
828
|
+
if (hasCredentials(delegate)) delegate.credentials = this.credentials;
|
|
829
|
+
}
|
|
177
830
|
};
|
|
831
|
+
_ProxiedCopilotRuntimeAgent = ProxiedCopilotRuntimeAgent;
|
|
832
|
+
function _connectViaDelegate(input) {
|
|
833
|
+
return (0, rxjs.defer)(() => (0, rxjs.from)(this.resolveDelegate())).pipe((0, rxjs_operators.switchMap)((delegate) => withAbortErrorHandling(delegate.connect(input))));
|
|
834
|
+
}
|
|
835
|
+
function _connectViaHttp(input) {
|
|
836
|
+
if (this.transport === "single") {
|
|
837
|
+
if (!this.singleEndpointUrl) throw new Error("Single endpoint transport requires a runtimeUrl");
|
|
838
|
+
const requestInit = this.createSingleRouteRequestInit(input, "agent/connect", { agentId: this.agentId });
|
|
839
|
+
return withAbortErrorHandling((0, _ag_ui_client.transformHttpEventStream)((0, _ag_ui_client.runHttpRequest)(this.singleEndpointUrl, requestInit)));
|
|
840
|
+
}
|
|
841
|
+
return withAbortErrorHandling((0, _ag_ui_client.transformHttpEventStream)((0, _ag_ui_client.runHttpRequest)(`${this.runtimeUrl}/agent/${this.agentId}/connect`, this.requestInit(input))));
|
|
842
|
+
}
|
|
843
|
+
function _runViaDelegate(input) {
|
|
844
|
+
return (0, rxjs.defer)(() => (0, rxjs.from)(this.resolveDelegate())).pipe((0, rxjs_operators.switchMap)((delegate) => withAbortErrorHandling(delegate.run(input))));
|
|
845
|
+
}
|
|
846
|
+
function _runViaHttp(input) {
|
|
847
|
+
if (this.transport === "single") {
|
|
848
|
+
if (!this.singleEndpointUrl) throw new Error("Single endpoint transport requires a runtimeUrl");
|
|
849
|
+
const requestInit = this.createSingleRouteRequestInit(input, "agent/run", { agentId: this.agentId });
|
|
850
|
+
return withAbortErrorHandling((0, _ag_ui_client.transformHttpEventStream)((0, _ag_ui_client.runHttpRequest)(this.singleEndpointUrl, requestInit)));
|
|
851
|
+
}
|
|
852
|
+
return withAbortErrorHandling(_superPropGet(_ProxiedCopilotRuntimeAgent.prototype, "run", this, 2)([input]));
|
|
853
|
+
}
|
|
178
854
|
|
|
179
855
|
//#endregion
|
|
180
856
|
//#region src/core/agent-registry.ts
|
|
@@ -193,6 +869,8 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
193
869
|
_defineProperty(this, "_runtimeConnectionStatus", CopilotKitCoreRuntimeConnectionStatus.Disconnected);
|
|
194
870
|
_defineProperty(this, "_runtimeTransport", "rest");
|
|
195
871
|
_defineProperty(this, "_audioFileTranscriptionEnabled", false);
|
|
872
|
+
_defineProperty(this, "_runtimeMode", _copilotkitnext_shared.RUNTIME_MODE_SSE);
|
|
873
|
+
_defineProperty(this, "_intelligence", void 0);
|
|
196
874
|
_defineProperty(this, "_a2uiEnabled", false);
|
|
197
875
|
}
|
|
198
876
|
/**
|
|
@@ -216,6 +894,12 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
216
894
|
get audioFileTranscriptionEnabled() {
|
|
217
895
|
return this._audioFileTranscriptionEnabled;
|
|
218
896
|
}
|
|
897
|
+
get runtimeMode() {
|
|
898
|
+
return this._runtimeMode;
|
|
899
|
+
}
|
|
900
|
+
get intelligence() {
|
|
901
|
+
return this._intelligence;
|
|
902
|
+
}
|
|
219
903
|
get a2uiEnabled() {
|
|
220
904
|
return this._a2uiEnabled;
|
|
221
905
|
}
|
|
@@ -325,6 +1009,8 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
325
1009
|
this._runtimeConnectionStatus = CopilotKitCoreRuntimeConnectionStatus.Disconnected;
|
|
326
1010
|
this._runtimeVersion = void 0;
|
|
327
1011
|
this._audioFileTranscriptionEnabled = false;
|
|
1012
|
+
this._runtimeMode = _copilotkitnext_shared.RUNTIME_MODE_SSE;
|
|
1013
|
+
this._intelligence = void 0;
|
|
328
1014
|
this._a2uiEnabled = false;
|
|
329
1015
|
this.remoteAgents = {};
|
|
330
1016
|
this._agents = this.localAgents;
|
|
@@ -335,17 +1021,20 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
335
1021
|
this._runtimeConnectionStatus = CopilotKitCoreRuntimeConnectionStatus.Connecting;
|
|
336
1022
|
await this.notifyRuntimeStatusChanged(CopilotKitCoreRuntimeConnectionStatus.Connecting);
|
|
337
1023
|
try {
|
|
338
|
-
var _runtimeInfoResponse
|
|
1024
|
+
var _runtimeInfoResponse$2, _runtimeInfoResponse$3, _runtimeInfoResponse$4;
|
|
339
1025
|
const runtimeInfoResponse = await this.fetchRuntimeInfo();
|
|
340
1026
|
const { version, ...runtimeInfo } = runtimeInfoResponse;
|
|
341
1027
|
const credentials = this.core.credentials;
|
|
342
1028
|
this.remoteAgents = Object.fromEntries(Object.entries(runtimeInfo.agents).map(([id, { description }]) => {
|
|
1029
|
+
var _runtimeInfoResponse$;
|
|
343
1030
|
const agent = new ProxiedCopilotRuntimeAgent({
|
|
344
1031
|
runtimeUrl: this.runtimeUrl,
|
|
345
1032
|
agentId: id,
|
|
346
1033
|
description,
|
|
347
1034
|
transport: this._runtimeTransport,
|
|
348
|
-
credentials
|
|
1035
|
+
credentials,
|
|
1036
|
+
runtimeMode: (_runtimeInfoResponse$ = runtimeInfoResponse.mode) !== null && _runtimeInfoResponse$ !== void 0 ? _runtimeInfoResponse$ : _copilotkitnext_shared.RUNTIME_MODE_SSE,
|
|
1037
|
+
intelligence: runtimeInfoResponse.intelligence
|
|
349
1038
|
});
|
|
350
1039
|
this.applyHeadersToAgent(agent);
|
|
351
1040
|
return [id, agent];
|
|
@@ -356,14 +1045,18 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
356
1045
|
};
|
|
357
1046
|
this._runtimeConnectionStatus = CopilotKitCoreRuntimeConnectionStatus.Connected;
|
|
358
1047
|
this._runtimeVersion = version;
|
|
359
|
-
this._audioFileTranscriptionEnabled = (_runtimeInfoResponse$ = runtimeInfoResponse.audioFileTranscriptionEnabled) !== null && _runtimeInfoResponse$ !== void 0 ? _runtimeInfoResponse$ : false;
|
|
360
|
-
this.
|
|
1048
|
+
this._audioFileTranscriptionEnabled = (_runtimeInfoResponse$2 = runtimeInfoResponse.audioFileTranscriptionEnabled) !== null && _runtimeInfoResponse$2 !== void 0 ? _runtimeInfoResponse$2 : false;
|
|
1049
|
+
this._runtimeMode = (_runtimeInfoResponse$3 = runtimeInfoResponse.mode) !== null && _runtimeInfoResponse$3 !== void 0 ? _runtimeInfoResponse$3 : _copilotkitnext_shared.RUNTIME_MODE_SSE;
|
|
1050
|
+
this._intelligence = runtimeInfoResponse.intelligence;
|
|
1051
|
+
this._a2uiEnabled = (_runtimeInfoResponse$4 = runtimeInfoResponse.a2uiEnabled) !== null && _runtimeInfoResponse$4 !== void 0 ? _runtimeInfoResponse$4 : false;
|
|
361
1052
|
await this.notifyRuntimeStatusChanged(CopilotKitCoreRuntimeConnectionStatus.Connected);
|
|
362
1053
|
await this.notifyAgentsChanged();
|
|
363
1054
|
} catch (error) {
|
|
364
1055
|
this._runtimeConnectionStatus = CopilotKitCoreRuntimeConnectionStatus.Error;
|
|
365
1056
|
this._runtimeVersion = void 0;
|
|
366
1057
|
this._audioFileTranscriptionEnabled = false;
|
|
1058
|
+
this._runtimeMode = _copilotkitnext_shared.RUNTIME_MODE_SSE;
|
|
1059
|
+
this._intelligence = void 0;
|
|
367
1060
|
this._a2uiEnabled = false;
|
|
368
1061
|
this.remoteAgents = {};
|
|
369
1062
|
this._agents = this.localAgents;
|
|
@@ -915,6 +1608,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
915
1608
|
async runAgent({ agent, forwardedProps }) {
|
|
916
1609
|
if (agent.agentId) this._internal.suggestionEngine.clearSuggestions(agent.agentId);
|
|
917
1610
|
if (agent instanceof _ag_ui_client.HttpAgent) agent.headers = { ...this._internal.headers };
|
|
1611
|
+
if (agent.detachActiveRun) agent.detachActiveRun();
|
|
918
1612
|
try {
|
|
919
1613
|
const runAgentResult = await agent.runAgent({
|
|
920
1614
|
forwardedProps: {
|
|
@@ -1659,6 +2353,12 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
1659
2353
|
get audioFileTranscriptionEnabled() {
|
|
1660
2354
|
return this.agentRegistry.audioFileTranscriptionEnabled;
|
|
1661
2355
|
}
|
|
2356
|
+
get runtimeMode() {
|
|
2357
|
+
return this.agentRegistry.runtimeMode;
|
|
2358
|
+
}
|
|
2359
|
+
get intelligence() {
|
|
2360
|
+
return this.agentRegistry.intelligence;
|
|
2361
|
+
}
|
|
1662
2362
|
get a2uiEnabled() {
|
|
1663
2363
|
return this.agentRegistry.a2uiEnabled;
|
|
1664
2364
|
}
|
|
@@ -1995,183 +2695,635 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
1995
2695
|
}
|
|
1996
2696
|
|
|
1997
2697
|
//#endregion
|
|
1998
|
-
//#region src/
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2698
|
+
//#region src/utils/micro-redux.ts
|
|
2699
|
+
const INTERNAL_ACTION_TYPES = {
|
|
2700
|
+
boot: "@@micro-redux/boot",
|
|
2701
|
+
init: "@@micro-redux/init",
|
|
2702
|
+
stop: "@@micro-redux/stop"
|
|
2703
|
+
};
|
|
2704
|
+
const INTERNAL_BOOT_ACTION = { type: INTERNAL_ACTION_TYPES.boot };
|
|
2705
|
+
/**
|
|
2706
|
+
* Builds a typed action creator from a type string and payload factory.
|
|
2707
|
+
*/
|
|
2708
|
+
function createTypedActionCreator(type, factory) {
|
|
2709
|
+
const creator = ((...args) => ({
|
|
2710
|
+
...factory(...args),
|
|
2711
|
+
type
|
|
2712
|
+
}));
|
|
2713
|
+
creator.type = type;
|
|
2714
|
+
creator.match = (action) => action.type === type;
|
|
2715
|
+
return creator;
|
|
2716
|
+
}
|
|
2717
|
+
/**
|
|
2718
|
+
* Declares a payload-based action config for `createActionGroup`.
|
|
2719
|
+
*
|
|
2720
|
+
* @example
|
|
2721
|
+
* ```ts
|
|
2722
|
+
* const actions = createActionGroup("User", {
|
|
2723
|
+
* loaded: props<{ id: string }>(),
|
|
2724
|
+
* });
|
|
2725
|
+
* ```
|
|
2726
|
+
*/
|
|
2727
|
+
function props() {
|
|
2728
|
+
return { kind: "props" };
|
|
2729
|
+
}
|
|
2730
|
+
/**
|
|
2731
|
+
* Declares a no-payload action config for `createActionGroup`.
|
|
2732
|
+
*
|
|
2733
|
+
* @example
|
|
2734
|
+
* ```ts
|
|
2735
|
+
* const actions = createActionGroup("User", {
|
|
2736
|
+
* reset: empty(),
|
|
2737
|
+
* });
|
|
2738
|
+
* ```
|
|
2739
|
+
*/
|
|
2740
|
+
function empty() {
|
|
2741
|
+
return { kind: "empty" };
|
|
2742
|
+
}
|
|
2743
|
+
/**
|
|
2744
|
+
* Creates a namespaced group of typed action creators.
|
|
2745
|
+
*
|
|
2746
|
+
* Action types are formatted as: `[Source] actionName`.
|
|
2747
|
+
*/
|
|
2748
|
+
function createActionGroup(source, config) {
|
|
2749
|
+
const group = {};
|
|
2750
|
+
for (const eventName of Object.keys(config)) {
|
|
2751
|
+
const eventConfig = config[eventName];
|
|
2752
|
+
if (!eventConfig) continue;
|
|
2753
|
+
const actionType = `[${source}] ${eventName}`;
|
|
2754
|
+
if (eventConfig.kind === "props") {
|
|
2755
|
+
group[eventName] = createTypedActionCreator(actionType, (payload) => ({ ...payload }));
|
|
2756
|
+
continue;
|
|
2757
|
+
}
|
|
2758
|
+
group[eventName] = createTypedActionCreator(actionType, () => ({}));
|
|
2010
2759
|
}
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2760
|
+
return group;
|
|
2761
|
+
}
|
|
2762
|
+
/**
|
|
2763
|
+
* Registers one reducer handler for one or more action creators.
|
|
2764
|
+
*
|
|
2765
|
+
* @throws Error when called without at least one action creator and reducer.
|
|
2766
|
+
*/
|
|
2767
|
+
function on(...args) {
|
|
2768
|
+
if (args.length < 2) throw new Error("on requires at least one action creator and one reducer");
|
|
2769
|
+
const reducer = args[args.length - 1];
|
|
2770
|
+
return {
|
|
2771
|
+
creators: args.slice(0, -1),
|
|
2772
|
+
reducer
|
|
2773
|
+
};
|
|
2774
|
+
}
|
|
2775
|
+
/**
|
|
2776
|
+
* Creates a reducer from an initial state and `on(...)` handler entries.
|
|
2777
|
+
*
|
|
2778
|
+
* Unknown action types return the current state unchanged.
|
|
2779
|
+
*/
|
|
2780
|
+
function createReducer(initialState, ...entries) {
|
|
2781
|
+
const reducerMap = /* @__PURE__ */ new Map();
|
|
2782
|
+
for (const entry of entries) for (const creator of entry.creators) {
|
|
2783
|
+
var _reducerMap$get;
|
|
2784
|
+
const handlers = (_reducerMap$get = reducerMap.get(creator.type)) !== null && _reducerMap$get !== void 0 ? _reducerMap$get : [];
|
|
2785
|
+
handlers.push(entry.reducer);
|
|
2786
|
+
reducerMap.set(creator.type, handlers);
|
|
2787
|
+
}
|
|
2788
|
+
return (state, action) => {
|
|
2789
|
+
const currentState = state !== null && state !== void 0 ? state : initialState;
|
|
2790
|
+
const handlers = reducerMap.get(action.type);
|
|
2791
|
+
if (!handlers || handlers.length === 0) return currentState;
|
|
2792
|
+
let nextState = currentState;
|
|
2793
|
+
for (const handler of handlers) nextState = handler(nextState, action);
|
|
2794
|
+
return nextState;
|
|
2795
|
+
};
|
|
2796
|
+
}
|
|
2797
|
+
/**
|
|
2798
|
+
* Creates a selector that caches and reuses the last computed result
|
|
2799
|
+
* when all input references are unchanged.
|
|
2800
|
+
*/
|
|
2801
|
+
function createSelector(...args) {
|
|
2802
|
+
if (args.length === 1) {
|
|
2803
|
+
const projector = args[0];
|
|
2804
|
+
let hasCached = false;
|
|
2805
|
+
let lastState;
|
|
2806
|
+
let lastResult;
|
|
2807
|
+
return (state) => {
|
|
2808
|
+
if (hasCached && state === lastState) return lastResult;
|
|
2809
|
+
lastState = state;
|
|
2810
|
+
lastResult = projector(state);
|
|
2811
|
+
hasCached = true;
|
|
2812
|
+
return lastResult;
|
|
2813
|
+
};
|
|
2024
2814
|
}
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
|
|
2815
|
+
const projector = args[args.length - 1];
|
|
2816
|
+
const selectors = args.slice(0, -1);
|
|
2817
|
+
let hasCached = false;
|
|
2818
|
+
let lastInputs = [];
|
|
2819
|
+
let lastResult;
|
|
2820
|
+
return (state) => {
|
|
2821
|
+
const inputs = selectors.map((selector) => selector(state));
|
|
2822
|
+
if (hasCached && inputs.length === lastInputs.length && inputs.every((value, index) => value === lastInputs[index])) return lastResult;
|
|
2823
|
+
lastInputs = inputs;
|
|
2824
|
+
lastResult = projector(...inputs);
|
|
2825
|
+
hasCached = true;
|
|
2826
|
+
return lastResult;
|
|
2827
|
+
};
|
|
2828
|
+
}
|
|
2829
|
+
/**
|
|
2830
|
+
* RxJS operator that maps state emissions through a selector and suppresses
|
|
2831
|
+
* unchanged projected values via reference equality.
|
|
2832
|
+
*/
|
|
2833
|
+
function select(selector) {
|
|
2834
|
+
return (source$) => source$.pipe((0, rxjs_operators.map)(selector), (0, rxjs_operators.distinctUntilChanged)());
|
|
2835
|
+
}
|
|
2836
|
+
/**
|
|
2837
|
+
* RxJS operator that filters an action stream by action creators and narrows
|
|
2838
|
+
* the output action type to the matched creator union.
|
|
2839
|
+
*
|
|
2840
|
+
* @throws Error when called without at least one action creator.
|
|
2841
|
+
*/
|
|
2842
|
+
function ofType(...creators) {
|
|
2843
|
+
if (creators.length === 0) throw new Error("ofType requires at least one action creator");
|
|
2844
|
+
const actionTypes = new Set(creators.map((creator) => creator.type));
|
|
2845
|
+
return (source$) => {
|
|
2846
|
+
return source$.pipe((0, rxjs_operators.filter)((action) => {
|
|
2847
|
+
return actionTypes.has(action.type);
|
|
2848
|
+
}));
|
|
2849
|
+
};
|
|
2850
|
+
}
|
|
2851
|
+
/**
|
|
2852
|
+
* Creates an effect descriptor consumed by `createStore`.
|
|
2853
|
+
*/
|
|
2854
|
+
function createEffect(factory, options = {}) {
|
|
2855
|
+
if (options.dispatch === false) return {
|
|
2856
|
+
run: factory,
|
|
2857
|
+
dispatch: false
|
|
2858
|
+
};
|
|
2859
|
+
return {
|
|
2860
|
+
run: factory,
|
|
2861
|
+
dispatch: true
|
|
2862
|
+
};
|
|
2863
|
+
}
|
|
2864
|
+
/**
|
|
2865
|
+
* Creates a small observable store with reducer + effects.
|
|
2866
|
+
*
|
|
2867
|
+
* Behavior:
|
|
2868
|
+
* - `init()` starts effects and dispatches `@@micro-redux/init`.
|
|
2869
|
+
* - `stop()` dispatches `@@micro-redux/stop` and unsubscribes all effects.
|
|
2870
|
+
* - Effect action observation is scheduled on `asapScheduler` to avoid
|
|
2871
|
+
* synchronous re-entrancy in the effect loop.
|
|
2872
|
+
* - Any effect error triggers fail-fast teardown and errors both `actions$`
|
|
2873
|
+
* and `state$`.
|
|
2874
|
+
*/
|
|
2875
|
+
function createStore(options) {
|
|
2876
|
+
var _options$effects;
|
|
2877
|
+
const reducer = options.reducer;
|
|
2878
|
+
const effects = (_options$effects = options.effects) !== null && _options$effects !== void 0 ? _options$effects : [];
|
|
2879
|
+
let hasFatalError = false;
|
|
2880
|
+
let isRunning = false;
|
|
2881
|
+
let effectSubscriptions = new rxjs.Subscription();
|
|
2882
|
+
let currentState = reducer(void 0, INTERNAL_BOOT_ACTION);
|
|
2883
|
+
const stateSubject = new rxjs.BehaviorSubject(currentState);
|
|
2884
|
+
const actionsSubject = new rxjs.Subject();
|
|
2885
|
+
const dispatchInternal = (action) => {
|
|
2886
|
+
if (hasFatalError) throw new Error("Store is in a failed state due to an effect error");
|
|
2887
|
+
currentState = reducer(currentState, action);
|
|
2888
|
+
stateSubject.next(currentState);
|
|
2889
|
+
actionsSubject.next(action);
|
|
2890
|
+
};
|
|
2891
|
+
const failFast = (error) => {
|
|
2892
|
+
if (hasFatalError) return;
|
|
2893
|
+
hasFatalError = true;
|
|
2894
|
+
isRunning = false;
|
|
2895
|
+
effectSubscriptions.unsubscribe();
|
|
2896
|
+
effectSubscriptions = new rxjs.Subscription();
|
|
2897
|
+
actionsSubject.error(error);
|
|
2898
|
+
stateSubject.error(error);
|
|
2899
|
+
};
|
|
2900
|
+
const startEffects = () => {
|
|
2901
|
+
for (const effect of effects) {
|
|
2902
|
+
const scheduledActions$ = actionsSubject.asObservable().pipe((0, rxjs_operators.observeOn)(rxjs.asapScheduler));
|
|
2903
|
+
const state$ = stateSubject.asObservable();
|
|
2904
|
+
if (effect.dispatch) {
|
|
2905
|
+
const subscription = effect.run(scheduledActions$, state$).subscribe({
|
|
2906
|
+
next: (effectAction) => {
|
|
2907
|
+
if (hasFatalError) return;
|
|
2908
|
+
dispatchInternal(effectAction);
|
|
2081
2909
|
},
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
messages: input.messages,
|
|
2086
|
-
tools: input.tools,
|
|
2087
|
-
context: input.context,
|
|
2088
|
-
state: input.state,
|
|
2089
|
-
forwardedProps: input.forwardedProps
|
|
2090
|
-
}),
|
|
2091
|
-
...credentials ? { credentials } : {}
|
|
2092
|
-
}).catch((error) => {
|
|
2093
|
-
var _error$message;
|
|
2094
|
-
observer.error(/* @__PURE__ */ new Error(`REST run request failed: ${(_error$message = error.message) !== null && _error$message !== void 0 ? _error$message : error}`));
|
|
2095
|
-
this.cleanup();
|
|
2910
|
+
error: (error) => {
|
|
2911
|
+
failFast(error);
|
|
2912
|
+
}
|
|
2096
2913
|
});
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
2914
|
+
effectSubscriptions.add(subscription);
|
|
2915
|
+
continue;
|
|
2916
|
+
}
|
|
2917
|
+
const subscription = effect.run(scheduledActions$, state$).subscribe({ error: (error) => {
|
|
2918
|
+
failFast(error);
|
|
2919
|
+
} });
|
|
2920
|
+
effectSubscriptions.add(subscription);
|
|
2921
|
+
}
|
|
2922
|
+
};
|
|
2923
|
+
return {
|
|
2924
|
+
dispatch(action) {
|
|
2925
|
+
dispatchInternal(action);
|
|
2926
|
+
},
|
|
2927
|
+
getState() {
|
|
2928
|
+
return currentState;
|
|
2929
|
+
},
|
|
2930
|
+
get state$() {
|
|
2931
|
+
return stateSubject.asObservable();
|
|
2932
|
+
},
|
|
2933
|
+
get actions$() {
|
|
2934
|
+
return actionsSubject.asObservable();
|
|
2935
|
+
},
|
|
2936
|
+
select(selector) {
|
|
2937
|
+
return stateSubject.asObservable().pipe(select(selector));
|
|
2938
|
+
},
|
|
2939
|
+
init() {
|
|
2940
|
+
if (hasFatalError || isRunning) return;
|
|
2941
|
+
isRunning = true;
|
|
2942
|
+
startEffects();
|
|
2943
|
+
if (hasFatalError) return;
|
|
2944
|
+
dispatchInternal({ type: INTERNAL_ACTION_TYPES.init });
|
|
2945
|
+
},
|
|
2946
|
+
stop() {
|
|
2947
|
+
if (hasFatalError || !isRunning) return;
|
|
2948
|
+
dispatchInternal({ type: INTERNAL_ACTION_TYPES.stop });
|
|
2949
|
+
effectSubscriptions.unsubscribe();
|
|
2950
|
+
effectSubscriptions = new rxjs.Subscription();
|
|
2951
|
+
isRunning = false;
|
|
2952
|
+
}
|
|
2953
|
+
};
|
|
2954
|
+
}
|
|
2955
|
+
|
|
2956
|
+
//#endregion
|
|
2957
|
+
//#region src/threads.ts
|
|
2958
|
+
const THREADS_CHANNEL_EVENT = "thread_metadata";
|
|
2959
|
+
const THREAD_SUBSCRIBE_PATH = "/threads/subscribe";
|
|
2960
|
+
const MAX_SOCKET_RETRIES = 5;
|
|
2961
|
+
const REQUEST_TIMEOUT_MS = 15e3;
|
|
2962
|
+
const initialThreadState = {
|
|
2963
|
+
threads: [],
|
|
2964
|
+
isLoading: false,
|
|
2965
|
+
error: null,
|
|
2966
|
+
context: null,
|
|
2967
|
+
sessionId: 0,
|
|
2968
|
+
metadataCredentialsRequested: false
|
|
2969
|
+
};
|
|
2970
|
+
const threadAdapterEvents = createActionGroup("Thread Adapter", {
|
|
2971
|
+
started: empty(),
|
|
2972
|
+
stopped: empty(),
|
|
2973
|
+
contextChanged: props(),
|
|
2974
|
+
renameRequested: props(),
|
|
2975
|
+
archiveRequested: props(),
|
|
2976
|
+
deleteRequested: props()
|
|
2977
|
+
});
|
|
2978
|
+
const threadRestEvents = createActionGroup("Thread REST", {
|
|
2979
|
+
listRequested: props(),
|
|
2980
|
+
listSucceeded: props(),
|
|
2981
|
+
listFailed: props(),
|
|
2982
|
+
metadataCredentialsRequested: props(),
|
|
2983
|
+
metadataCredentialsSucceeded: props(),
|
|
2984
|
+
metadataCredentialsFailed: props(),
|
|
2985
|
+
mutationFinished: props()
|
|
2986
|
+
});
|
|
2987
|
+
const threadSocketEvents = createActionGroup("Thread Socket", {
|
|
2988
|
+
opened: props(),
|
|
2989
|
+
errored: props(),
|
|
2990
|
+
joinFailed: props(),
|
|
2991
|
+
joinTimedOut: props(),
|
|
2992
|
+
metadataReceived: props()
|
|
2993
|
+
});
|
|
2994
|
+
const threadDomainEvents = createActionGroup("Thread Domain", {
|
|
2995
|
+
threadUpserted: props(),
|
|
2996
|
+
threadDeleted: props()
|
|
2997
|
+
});
|
|
2998
|
+
function sortThreadsByUpdatedAt(threads) {
|
|
2999
|
+
return [...threads].sort((left, right) => right.updatedAt.localeCompare(left.updatedAt));
|
|
3000
|
+
}
|
|
3001
|
+
function upsertThread(threads, thread) {
|
|
3002
|
+
const existingIndex = threads.findIndex((item) => item.id === thread.id);
|
|
3003
|
+
if (existingIndex === -1) return sortThreadsByUpdatedAt([...threads, thread]);
|
|
3004
|
+
const next = [...threads];
|
|
3005
|
+
next[existingIndex] = thread;
|
|
3006
|
+
return sortThreadsByUpdatedAt(next);
|
|
3007
|
+
}
|
|
3008
|
+
const threadReducer = createReducer(initialThreadState, on(threadAdapterEvents.contextChanged, (state, { context }) => ({
|
|
3009
|
+
...state,
|
|
3010
|
+
context,
|
|
3011
|
+
sessionId: state.sessionId + 1,
|
|
3012
|
+
threads: [],
|
|
3013
|
+
isLoading: Boolean(context),
|
|
3014
|
+
error: null,
|
|
3015
|
+
metadataCredentialsRequested: false
|
|
3016
|
+
})), on(threadAdapterEvents.stopped, (state) => ({
|
|
3017
|
+
...state,
|
|
3018
|
+
threads: [],
|
|
3019
|
+
isLoading: false,
|
|
3020
|
+
error: null,
|
|
3021
|
+
metadataCredentialsRequested: false
|
|
3022
|
+
})), on(threadRestEvents.listRequested, (state, { sessionId }) => {
|
|
3023
|
+
if (sessionId !== state.sessionId || !state.context) return state;
|
|
3024
|
+
return {
|
|
3025
|
+
...state,
|
|
3026
|
+
isLoading: true,
|
|
3027
|
+
error: null
|
|
3028
|
+
};
|
|
3029
|
+
}), on(threadRestEvents.listSucceeded, (state, { sessionId, threads }) => {
|
|
3030
|
+
if (sessionId !== state.sessionId) return state;
|
|
3031
|
+
return {
|
|
3032
|
+
...state,
|
|
3033
|
+
threads: sortThreadsByUpdatedAt(threads),
|
|
3034
|
+
isLoading: false,
|
|
3035
|
+
error: null
|
|
3036
|
+
};
|
|
3037
|
+
}), on(threadRestEvents.listFailed, (state, { sessionId, error }) => {
|
|
3038
|
+
if (sessionId !== state.sessionId) return state;
|
|
3039
|
+
return {
|
|
3040
|
+
...state,
|
|
3041
|
+
isLoading: false,
|
|
3042
|
+
error
|
|
3043
|
+
};
|
|
3044
|
+
}), on(threadRestEvents.metadataCredentialsFailed, (state, { sessionId, error }) => {
|
|
3045
|
+
if (sessionId !== state.sessionId) return state;
|
|
3046
|
+
return {
|
|
3047
|
+
...state,
|
|
3048
|
+
error
|
|
3049
|
+
};
|
|
3050
|
+
}), on(threadRestEvents.metadataCredentialsRequested, (state, { sessionId }) => {
|
|
3051
|
+
if (sessionId !== state.sessionId) return state;
|
|
3052
|
+
return {
|
|
3053
|
+
...state,
|
|
3054
|
+
metadataCredentialsRequested: true
|
|
3055
|
+
};
|
|
3056
|
+
}), on(threadRestEvents.mutationFinished, (state, { outcome }) => ({
|
|
3057
|
+
...state,
|
|
3058
|
+
error: outcome.ok ? state.error : outcome.error
|
|
3059
|
+
})), on(threadDomainEvents.threadUpserted, (state, { sessionId, thread }) => {
|
|
3060
|
+
if (sessionId !== state.sessionId) return state;
|
|
3061
|
+
return {
|
|
3062
|
+
...state,
|
|
3063
|
+
threads: upsertThread(state.threads, thread)
|
|
3064
|
+
};
|
|
3065
|
+
}), on(threadDomainEvents.threadDeleted, (state, { sessionId, threadId }) => {
|
|
3066
|
+
if (sessionId !== state.sessionId) return state;
|
|
3067
|
+
return {
|
|
3068
|
+
...state,
|
|
3069
|
+
threads: state.threads.filter((thread) => thread.id !== threadId)
|
|
3070
|
+
};
|
|
3071
|
+
}));
|
|
3072
|
+
const selectThreads = createSelector((state) => state.threads);
|
|
3073
|
+
const selectThreadsIsLoading = createSelector((state) => state.isLoading);
|
|
3074
|
+
const selectThreadsError = createSelector((state) => state.error);
|
|
3075
|
+
let threadRequestId = 0;
|
|
3076
|
+
function createThreadRequestId() {
|
|
3077
|
+
threadRequestId += 1;
|
|
3078
|
+
return `thread-request-${threadRequestId}`;
|
|
3079
|
+
}
|
|
3080
|
+
function createThreadFetchObservable(environment, context, sessionId) {
|
|
3081
|
+
return (0, rxjs.defer)(() => {
|
|
3082
|
+
const params = new URLSearchParams({
|
|
3083
|
+
userId: context.userId,
|
|
3084
|
+
agentId: context.agentId
|
|
2107
3085
|
});
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
|
|
3086
|
+
return (0, rxjs_fetch.fromFetch)(`${context.runtimeUrl}/threads?${params.toString()}`, {
|
|
3087
|
+
selector: (response) => {
|
|
3088
|
+
if (!response.ok) throw new Error(`Failed to fetch threads: ${response.status}`);
|
|
3089
|
+
return response.json();
|
|
3090
|
+
},
|
|
3091
|
+
fetch: environment.fetch,
|
|
3092
|
+
method: "GET",
|
|
3093
|
+
headers: { ...context.headers }
|
|
3094
|
+
}).pipe((0, rxjs_operators.timeout)({
|
|
3095
|
+
first: REQUEST_TIMEOUT_MS,
|
|
3096
|
+
with: () => {
|
|
3097
|
+
throw new Error("Request timed out");
|
|
3098
|
+
}
|
|
3099
|
+
}), (0, rxjs_operators.map)((data) => threadRestEvents.listSucceeded({
|
|
3100
|
+
sessionId,
|
|
3101
|
+
threads: data.threads
|
|
3102
|
+
})), (0, rxjs_operators.catchError)((error) => {
|
|
3103
|
+
return (0, rxjs.of)(threadRestEvents.listFailed({
|
|
3104
|
+
sessionId,
|
|
3105
|
+
error: error instanceof Error ? error : new Error(String(error))
|
|
3106
|
+
}));
|
|
3107
|
+
}));
|
|
3108
|
+
});
|
|
3109
|
+
}
|
|
3110
|
+
function createThreadMetadataCredentialsObservable(environment, context, sessionId) {
|
|
3111
|
+
return (0, rxjs.defer)(() => {
|
|
3112
|
+
return (0, rxjs_fetch.fromFetch)(`${context.runtimeUrl}${THREAD_SUBSCRIBE_PATH}`, {
|
|
3113
|
+
selector: async (response) => {
|
|
3114
|
+
if (!response.ok) throw new Error(`Failed to fetch thread metadata credentials: ${response.status}`);
|
|
3115
|
+
return response.json();
|
|
3116
|
+
},
|
|
3117
|
+
fetch: environment.fetch,
|
|
3118
|
+
method: "POST",
|
|
3119
|
+
headers: {
|
|
3120
|
+
...context.headers,
|
|
3121
|
+
"Content-Type": "application/json"
|
|
3122
|
+
},
|
|
3123
|
+
body: JSON.stringify({ userId: context.userId })
|
|
3124
|
+
}).pipe((0, rxjs_operators.timeout)({
|
|
3125
|
+
first: REQUEST_TIMEOUT_MS,
|
|
3126
|
+
with: () => {
|
|
3127
|
+
throw new Error("Request timed out");
|
|
3128
|
+
}
|
|
3129
|
+
}), (0, rxjs_operators.map)((data) => {
|
|
3130
|
+
if (typeof data.joinToken !== "string" || data.joinToken.length === 0) throw new Error("missing joinToken");
|
|
3131
|
+
return threadRestEvents.metadataCredentialsSucceeded({
|
|
3132
|
+
sessionId,
|
|
3133
|
+
joinToken: data.joinToken
|
|
2132
3134
|
});
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
3135
|
+
}), (0, rxjs_operators.catchError)((error) => {
|
|
3136
|
+
return (0, rxjs.of)(threadRestEvents.metadataCredentialsFailed({
|
|
3137
|
+
sessionId,
|
|
3138
|
+
error: error instanceof Error ? error : new Error(String(error))
|
|
3139
|
+
}));
|
|
3140
|
+
}));
|
|
3141
|
+
});
|
|
3142
|
+
}
|
|
3143
|
+
function createThreadMutationObservable(environment, context, request) {
|
|
3144
|
+
return (0, rxjs.defer)(() => {
|
|
3145
|
+
return (0, rxjs_fetch.fromFetch)(`${context.runtimeUrl}${request.path}`, {
|
|
3146
|
+
selector: async (response) => {
|
|
3147
|
+
if (!response.ok) throw new Error(`Request failed: ${response.status}`);
|
|
3148
|
+
return null;
|
|
3149
|
+
},
|
|
3150
|
+
fetch: environment.fetch,
|
|
3151
|
+
method: request.method,
|
|
3152
|
+
headers: {
|
|
3153
|
+
...context.headers,
|
|
3154
|
+
"Content-Type": "application/json"
|
|
3155
|
+
},
|
|
3156
|
+
body: JSON.stringify(request.body)
|
|
3157
|
+
}).pipe((0, rxjs_operators.map)(() => threadRestEvents.mutationFinished({ outcome: {
|
|
3158
|
+
requestId: request.requestId,
|
|
3159
|
+
ok: true
|
|
3160
|
+
} })), (0, rxjs_operators.catchError)((error) => {
|
|
3161
|
+
return (0, rxjs.of)(threadRestEvents.mutationFinished({ outcome: {
|
|
3162
|
+
requestId: request.requestId,
|
|
3163
|
+
ok: false,
|
|
3164
|
+
error: error instanceof Error ? error : new Error(String(error))
|
|
3165
|
+
} }));
|
|
3166
|
+
}));
|
|
3167
|
+
});
|
|
3168
|
+
}
|
|
3169
|
+
function createThreadStore(environment) {
|
|
3170
|
+
const store = createStore({
|
|
3171
|
+
reducer: threadReducer,
|
|
3172
|
+
effects: [
|
|
3173
|
+
createEffect((actions$, state$) => actions$.pipe(ofType(threadAdapterEvents.contextChanged), (0, rxjs_operators.withLatestFrom)(state$), (0, rxjs_operators.filter)(([, state]) => Boolean(state.context)), (0, rxjs_operators.map)(([, state]) => threadRestEvents.listRequested({ sessionId: state.sessionId })))),
|
|
3174
|
+
createEffect((actions$, state$) => actions$.pipe(ofType(threadRestEvents.listRequested), (0, rxjs_operators.switchMap)((action) => state$.pipe((0, rxjs_operators.map)((state) => state.context), (0, rxjs_operators.filter)((context) => Boolean(context)), (0, rxjs_operators.take)(1), (0, rxjs_operators.map)((context) => ({
|
|
3175
|
+
action,
|
|
3176
|
+
context
|
|
3177
|
+
})), (0, rxjs_operators.takeUntil)(actions$.pipe(ofType(threadAdapterEvents.contextChanged, threadAdapterEvents.stopped))), (0, rxjs_operators.switchMap)(({ action: currentAction, context }) => createThreadFetchObservable(environment, context, currentAction.sessionId)))))),
|
|
3178
|
+
createEffect((actions$, state$) => actions$.pipe(ofType(threadRestEvents.listSucceeded), (0, rxjs_operators.withLatestFrom)(state$), (0, rxjs_operators.filter)(([action, state]) => {
|
|
3179
|
+
var _state$context;
|
|
3180
|
+
return action.sessionId === state.sessionId && !state.metadataCredentialsRequested && Boolean((_state$context = state.context) === null || _state$context === void 0 ? void 0 : _state$context.wsUrl);
|
|
3181
|
+
}), (0, rxjs_operators.map)(([action]) => threadRestEvents.metadataCredentialsRequested({ sessionId: action.sessionId })))),
|
|
3182
|
+
createEffect((actions$, state$) => actions$.pipe(ofType(threadRestEvents.metadataCredentialsRequested), (0, rxjs_operators.switchMap)((action) => state$.pipe((0, rxjs_operators.map)((state) => state.context), (0, rxjs_operators.filter)((context) => Boolean(context)), (0, rxjs_operators.take)(1), (0, rxjs_operators.map)((context) => ({
|
|
3183
|
+
action,
|
|
3184
|
+
context
|
|
3185
|
+
})), (0, rxjs_operators.takeUntil)(actions$.pipe(ofType(threadAdapterEvents.contextChanged, threadAdapterEvents.stopped))), (0, rxjs_operators.switchMap)(({ action: currentAction, context }) => createThreadMetadataCredentialsObservable(environment, context, currentAction.sessionId)))))),
|
|
3186
|
+
createEffect((actions$, state$) => actions$.pipe(ofType(threadRestEvents.metadataCredentialsSucceeded), (0, rxjs_operators.withLatestFrom)(state$), (0, rxjs_operators.filter)(([action, state]) => {
|
|
3187
|
+
var _state$context2;
|
|
3188
|
+
return action.sessionId === state.sessionId && Boolean((_state$context2 = state.context) === null || _state$context2 === void 0 ? void 0 : _state$context2.wsUrl);
|
|
3189
|
+
}), (0, rxjs_operators.switchMap)(([action, state]) => {
|
|
3190
|
+
const context = state.context;
|
|
3191
|
+
const joinToken = action.joinToken;
|
|
3192
|
+
const shutdown$ = actions$.pipe(ofType(threadAdapterEvents.contextChanged, threadAdapterEvents.stopped));
|
|
3193
|
+
return (0, rxjs.defer)(() => {
|
|
3194
|
+
const socket$ = ɵphoenixSocket$({
|
|
3195
|
+
url: context.wsUrl,
|
|
3196
|
+
options: {
|
|
3197
|
+
params: { join_token: joinToken },
|
|
3198
|
+
reconnectAfterMs: (0, _copilotkitnext_shared.phoenixExponentialBackoff)(100, 1e4),
|
|
3199
|
+
rejoinAfterMs: (0, _copilotkitnext_shared.phoenixExponentialBackoff)(1e3, 3e4)
|
|
3200
|
+
}
|
|
3201
|
+
}).pipe((0, rxjs_operators.shareReplay)({
|
|
3202
|
+
bufferSize: 1,
|
|
3203
|
+
refCount: true
|
|
3204
|
+
}));
|
|
3205
|
+
const channel$ = ɵphoenixChannel$({
|
|
3206
|
+
socket$,
|
|
3207
|
+
topic: `user_meta:${context.userId}`
|
|
3208
|
+
}).pipe((0, rxjs_operators.shareReplay)({
|
|
3209
|
+
bufferSize: 1,
|
|
3210
|
+
refCount: true
|
|
3211
|
+
}));
|
|
3212
|
+
const socketSignals$ = ɵobservePhoenixSocketSignals$(socket$).pipe((0, rxjs_operators.share)());
|
|
3213
|
+
const fatalSocketShutdown$ = ɵobservePhoenixSocketHealth$(socketSignals$, MAX_SOCKET_RETRIES).pipe((0, rxjs_operators.catchError)(() => {
|
|
3214
|
+
console.warn(`[threads] WebSocket failed after ${MAX_SOCKET_RETRIES} attempts, giving up`);
|
|
3215
|
+
return (0, rxjs.of)(void 0);
|
|
3216
|
+
}), (0, rxjs_operators.share)());
|
|
3217
|
+
return (0, rxjs.merge)(socketSignals$.pipe((0, rxjs_operators.map)((signal) => signal.type === "open" ? threadSocketEvents.opened({ sessionId: action.sessionId }) : threadSocketEvents.errored({ sessionId: action.sessionId }))), channel$.pipe((0, rxjs_operators.switchMap)(({ channel }) => ɵobservePhoenixEvent$(channel, THREADS_CHANNEL_EVENT)), (0, rxjs_operators.map)((payload) => threadSocketEvents.metadataReceived({
|
|
3218
|
+
sessionId: action.sessionId,
|
|
3219
|
+
payload
|
|
3220
|
+
}))), ɵobservePhoenixJoinOutcome$(channel$).pipe((0, rxjs_operators.filter)((outcome) => outcome.type !== "joined"), (0, rxjs_operators.map)((outcome) => outcome.type === "timeout" ? threadSocketEvents.joinTimedOut({ sessionId: action.sessionId }) : threadSocketEvents.joinFailed({ sessionId: action.sessionId })))).pipe((0, rxjs_operators.takeUntil)((0, rxjs.merge)(shutdown$, fatalSocketShutdown$)));
|
|
3221
|
+
});
|
|
3222
|
+
}))),
|
|
3223
|
+
createEffect((actions$, state$) => actions$.pipe(ofType(threadSocketEvents.metadataReceived), (0, rxjs_operators.withLatestFrom)(state$), (0, rxjs_operators.filter)(([action, state]) => {
|
|
3224
|
+
var _state$context3;
|
|
3225
|
+
return action.sessionId === state.sessionId && action.payload.userId === ((_state$context3 = state.context) === null || _state$context3 === void 0 ? void 0 : _state$context3.userId);
|
|
3226
|
+
}), (0, rxjs_operators.map)(([action]) => {
|
|
3227
|
+
if (action.payload.operation === "deleted") return threadDomainEvents.threadDeleted({
|
|
3228
|
+
sessionId: action.sessionId,
|
|
3229
|
+
threadId: action.payload.deleted.id
|
|
3230
|
+
});
|
|
3231
|
+
return threadDomainEvents.threadUpserted({
|
|
3232
|
+
sessionId: action.sessionId,
|
|
3233
|
+
thread: action.payload.thread
|
|
3234
|
+
});
|
|
3235
|
+
}))),
|
|
3236
|
+
createEffect((actions$, state$) => actions$.pipe(ofType(threadAdapterEvents.renameRequested, threadAdapterEvents.archiveRequested, threadAdapterEvents.deleteRequested), (0, rxjs_operators.withLatestFrom)(state$), (0, rxjs_operators.mergeMap)(([action, state]) => {
|
|
3237
|
+
const context = state.context;
|
|
3238
|
+
if (!(context === null || context === void 0 ? void 0 : context.runtimeUrl)) {
|
|
3239
|
+
const requestId = action.requestId;
|
|
3240
|
+
return (0, rxjs.of)(threadRestEvents.mutationFinished({ outcome: {
|
|
3241
|
+
requestId,
|
|
3242
|
+
ok: false,
|
|
3243
|
+
error: /* @__PURE__ */ new Error("Runtime URL is not configured")
|
|
3244
|
+
} }));
|
|
2140
3245
|
}
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
|
|
2144
|
-
|
|
2145
|
-
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
3246
|
+
const commonBody = {
|
|
3247
|
+
userId: context.userId,
|
|
3248
|
+
agentId: context.agentId
|
|
3249
|
+
};
|
|
3250
|
+
if (threadAdapterEvents.renameRequested.match(action)) return createThreadMutationObservable(environment, context, {
|
|
3251
|
+
requestId: action.requestId,
|
|
3252
|
+
method: "PATCH",
|
|
3253
|
+
path: `/threads/${encodeURIComponent(action.threadId)}`,
|
|
3254
|
+
body: {
|
|
3255
|
+
...commonBody,
|
|
3256
|
+
name: action.name
|
|
3257
|
+
}
|
|
2151
3258
|
});
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
3259
|
+
if (threadAdapterEvents.archiveRequested.match(action)) return createThreadMutationObservable(environment, context, {
|
|
3260
|
+
requestId: action.requestId,
|
|
3261
|
+
method: "POST",
|
|
3262
|
+
path: `/threads/${encodeURIComponent(action.threadId)}/archive`,
|
|
3263
|
+
body: commonBody
|
|
3264
|
+
});
|
|
3265
|
+
return createThreadMutationObservable(environment, context, {
|
|
3266
|
+
requestId: action.requestId,
|
|
3267
|
+
method: "DELETE",
|
|
3268
|
+
path: `/threads/${encodeURIComponent(action.threadId)}`,
|
|
3269
|
+
body: commonBody
|
|
3270
|
+
});
|
|
3271
|
+
})))
|
|
3272
|
+
]
|
|
3273
|
+
});
|
|
3274
|
+
function trackMutation(dispatchAction) {
|
|
3275
|
+
const resultPromise = (0, rxjs.firstValueFrom)((0, rxjs.merge)(store.actions$.pipe(ofType(threadRestEvents.mutationFinished), (0, rxjs_operators.filter)((action) => action.outcome.requestId === dispatchAction.requestId), (0, rxjs_operators.map)((action) => action.outcome)), store.actions$.pipe(ofType(threadAdapterEvents.stopped), (0, rxjs_operators.map)(() => ({
|
|
3276
|
+
requestId: dispatchAction.requestId,
|
|
3277
|
+
ok: false,
|
|
3278
|
+
error: /* @__PURE__ */ new Error("Thread store stopped before mutation completed")
|
|
3279
|
+
})))).pipe((0, rxjs_operators.take)(1))).then((outcome) => {
|
|
3280
|
+
if (outcome.ok) return;
|
|
3281
|
+
throw outcome.error;
|
|
2162
3282
|
});
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
3283
|
+
store.dispatch(dispatchAction);
|
|
3284
|
+
return resultPromise;
|
|
3285
|
+
}
|
|
3286
|
+
return {
|
|
3287
|
+
start() {
|
|
3288
|
+
store.init();
|
|
3289
|
+
store.dispatch(threadAdapterEvents.started());
|
|
3290
|
+
},
|
|
3291
|
+
stop() {
|
|
3292
|
+
store.dispatch(threadAdapterEvents.stopped());
|
|
3293
|
+
store.stop();
|
|
3294
|
+
},
|
|
3295
|
+
setContext(context) {
|
|
3296
|
+
store.dispatch(threadAdapterEvents.contextChanged({ context }));
|
|
3297
|
+
},
|
|
3298
|
+
renameThread(threadId, name) {
|
|
3299
|
+
return trackMutation(threadAdapterEvents.renameRequested({
|
|
3300
|
+
requestId: createThreadRequestId(),
|
|
3301
|
+
threadId,
|
|
3302
|
+
name
|
|
3303
|
+
}));
|
|
3304
|
+
},
|
|
3305
|
+
archiveThread(threadId) {
|
|
3306
|
+
return trackMutation(threadAdapterEvents.archiveRequested({
|
|
3307
|
+
requestId: createThreadRequestId(),
|
|
3308
|
+
threadId
|
|
3309
|
+
}));
|
|
3310
|
+
},
|
|
3311
|
+
deleteThread(threadId) {
|
|
3312
|
+
return trackMutation(threadAdapterEvents.deleteRequested({
|
|
3313
|
+
requestId: createThreadRequestId(),
|
|
3314
|
+
threadId
|
|
3315
|
+
}));
|
|
3316
|
+
},
|
|
3317
|
+
getState() {
|
|
3318
|
+
return store.getState();
|
|
3319
|
+
},
|
|
3320
|
+
select: store.select.bind(store)
|
|
3321
|
+
};
|
|
3322
|
+
}
|
|
3323
|
+
const ɵthreadAdapterEvents = threadAdapterEvents;
|
|
3324
|
+
const ɵselectThreads = selectThreads;
|
|
3325
|
+
const ɵselectThreadsIsLoading = selectThreadsIsLoading;
|
|
3326
|
+
const ɵselectThreadsError = selectThreadsError;
|
|
2175
3327
|
|
|
2176
3328
|
//#endregion
|
|
2177
3329
|
exports.AgentRegistry = AgentRegistry;
|
|
@@ -2186,6 +3338,28 @@ exports.StateManager = StateManager;
|
|
|
2186
3338
|
exports.SuggestionEngine = SuggestionEngine;
|
|
2187
3339
|
exports.ToolCallStatus = ToolCallStatus;
|
|
2188
3340
|
exports.completePartialMarkdown = completePartialMarkdown;
|
|
3341
|
+
exports.createActionGroup = createActionGroup;
|
|
3342
|
+
exports.createEffect = createEffect;
|
|
3343
|
+
exports.createReducer = createReducer;
|
|
3344
|
+
exports.createSelector = createSelector;
|
|
3345
|
+
exports.createStore = createStore;
|
|
3346
|
+
exports.empty = empty;
|
|
2189
3347
|
exports.ensureObjectArgs = ensureObjectArgs;
|
|
3348
|
+
exports.ofType = ofType;
|
|
3349
|
+
exports.on = on;
|
|
3350
|
+
exports.props = props;
|
|
3351
|
+
exports.select = select;
|
|
3352
|
+
exports.ɵcreateThreadStore = createThreadStore;
|
|
3353
|
+
exports.ɵjoinPhoenixChannel$ = ɵjoinPhoenixChannel$;
|
|
3354
|
+
exports.ɵobservePhoenixEvent$ = ɵobservePhoenixEvent$;
|
|
3355
|
+
exports.ɵobservePhoenixJoinOutcome$ = ɵobservePhoenixJoinOutcome$;
|
|
3356
|
+
exports.ɵobservePhoenixSocketHealth$ = ɵobservePhoenixSocketHealth$;
|
|
3357
|
+
exports.ɵobservePhoenixSocketSignals$ = ɵobservePhoenixSocketSignals$;
|
|
3358
|
+
exports.ɵphoenixChannel$ = ɵphoenixChannel$;
|
|
3359
|
+
exports.ɵphoenixSocket$ = ɵphoenixSocket$;
|
|
3360
|
+
exports.ɵselectThreads = ɵselectThreads;
|
|
3361
|
+
exports.ɵselectThreadsError = ɵselectThreadsError;
|
|
3362
|
+
exports.ɵselectThreadsIsLoading = ɵselectThreadsIsLoading;
|
|
3363
|
+
exports.ɵthreadAdapterEvents = ɵthreadAdapterEvents;
|
|
2190
3364
|
});
|
|
2191
3365
|
//# sourceMappingURL=index.umd.js.map
|