@fencyai/js 0.1.191 → 0.1.193

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.
Files changed (91) hide show
  1. package/lib/AgentTaskEventData.d.ts +24 -0
  2. package/lib/AgentTaskEventData.d.ts.map +1 -1
  3. package/lib/api/createAgentTask.d.ts +2 -2
  4. package/lib/api/createAgentTask.d.ts.map +1 -1
  5. package/lib/api/createAgentTask.js +2 -1
  6. package/lib/api/createAgentTaskFileDownloadLink.d.ts +14 -0
  7. package/lib/api/createAgentTaskFileDownloadLink.d.ts.map +1 -0
  8. package/lib/api/createAgentTaskFileDownloadLink.js +36 -0
  9. package/lib/api/createStream.d.ts.map +1 -1
  10. package/lib/api/createStream.js +2 -1
  11. package/lib/api/extractApiErrorMessage.d.ts +2 -0
  12. package/lib/api/extractApiErrorMessage.d.ts.map +1 -0
  13. package/lib/api/extractApiErrorMessage.js +32 -0
  14. package/lib/constants/fencyFileLinkPrefix.d.ts +13 -0
  15. package/lib/constants/fencyFileLinkPrefix.d.ts.map +1 -0
  16. package/lib/constants/fencyFileLinkPrefix.js +12 -0
  17. package/lib/index.d.ts +17 -1
  18. package/lib/index.d.ts.map +1 -1
  19. package/lib/index.js +15 -1
  20. package/lib/openapi/ct/index.d.ts +2 -0
  21. package/lib/openapi/ct/index.d.ts.map +1 -1
  22. package/lib/openapi/ct/models/PubCreateAgentTaskFileDownloadLinkRequest.d.ts +4 -0
  23. package/lib/openapi/ct/models/PubCreateAgentTaskFileDownloadLinkRequest.d.ts.map +1 -0
  24. package/lib/openapi/ct/models/PubCreateAgentTaskFileDownloadLinkRequest.js +1 -0
  25. package/lib/openapi/ct/models/PubCreateAgentTaskFileDownloadLinkResponse.d.ts +4 -0
  26. package/lib/openapi/ct/models/PubCreateAgentTaskFileDownloadLinkResponse.d.ts.map +1 -0
  27. package/lib/openapi/ct/models/PubCreateAgentTaskFileDownloadLinkResponse.js +1 -0
  28. package/lib/openapi/ct/services/PubService.d.ts +9 -0
  29. package/lib/openapi/ct/services/PubService.d.ts.map +1 -1
  30. package/lib/openapi/ct/services/PubService.js +14 -0
  31. package/lib/parsing/AgentTaskEventDataSchemas.d.ts +315 -0
  32. package/lib/parsing/AgentTaskEventDataSchemas.d.ts.map +1 -0
  33. package/lib/parsing/AgentTaskEventDataSchemas.js +415 -0
  34. package/lib/stream/StreamCacheManager.d.ts +41 -0
  35. package/lib/stream/StreamCacheManager.d.ts.map +1 -0
  36. package/lib/stream/StreamCacheManager.js +101 -0
  37. package/lib/stream/StreamEventManager.d.ts +52 -0
  38. package/lib/stream/StreamEventManager.d.ts.map +1 -0
  39. package/lib/stream/StreamEventManager.js +271 -0
  40. package/lib/stream/createStreamWorkerCode.d.ts +8 -0
  41. package/lib/stream/createStreamWorkerCode.d.ts.map +1 -0
  42. package/lib/stream/createStreamWorkerCode.js +152 -0
  43. package/lib/stream/toStreamData.d.ts +4 -0
  44. package/lib/stream/toStreamData.d.ts.map +1 -0
  45. package/lib/stream/toStreamData.js +61 -0
  46. package/lib/task/mapCreateAgentTaskParams.d.ts +18 -0
  47. package/lib/task/mapCreateAgentTaskParams.d.ts.map +1 -0
  48. package/lib/task/mapCreateAgentTaskParams.js +84 -0
  49. package/lib/task/progressItems.d.ts +5 -0
  50. package/lib/task/progressItems.d.ts.map +1 -0
  51. package/lib/task/progressItems.js +19 -0
  52. package/lib/task/taskReducer.d.ts +7 -0
  53. package/lib/task/taskReducer.d.ts.map +1 -0
  54. package/lib/task/taskReducer.js +89 -0
  55. package/lib/task/types.d.ts +40 -0
  56. package/lib/task/types.d.ts.map +1 -0
  57. package/lib/task/types.js +1 -0
  58. package/lib/types/AgentTask.d.ts +17 -7
  59. package/lib/types/AgentTask.d.ts.map +1 -1
  60. package/lib/types/AgentTask.js +1 -9
  61. package/lib/types/AgentTaskDto.d.ts +11 -0
  62. package/lib/types/AgentTaskDto.d.ts.map +1 -0
  63. package/lib/types/AgentTaskDto.js +11 -0
  64. package/lib/types/CreateAgentTaskApiResponse.d.ts +11 -0
  65. package/lib/types/CreateAgentTaskApiResponse.d.ts.map +1 -0
  66. package/lib/types/CreateAgentTaskApiResponse.js +1 -0
  67. package/lib/types/CreateAgentTaskFileDownloadLinkResult.d.ts +14 -0
  68. package/lib/types/CreateAgentTaskFileDownloadLinkResult.d.ts.map +1 -0
  69. package/lib/types/CreateAgentTaskFileDownloadLinkResult.js +1 -0
  70. package/lib/types/CreateAgentTaskParams.d.ts +47 -0
  71. package/lib/types/CreateAgentTaskParams.d.ts.map +1 -0
  72. package/lib/types/CreateAgentTaskParams.js +1 -0
  73. package/lib/types/CreateAgentTaskResponse.d.ts +17 -3
  74. package/lib/types/CreateAgentTaskResponse.d.ts.map +1 -1
  75. package/lib/types/StreamCache.d.ts +7 -0
  76. package/lib/types/StreamCache.d.ts.map +1 -0
  77. package/lib/types/StreamCache.js +1 -0
  78. package/lib/types/StreamData.d.ts +26 -0
  79. package/lib/types/StreamData.d.ts.map +1 -0
  80. package/lib/types/StreamData.js +1 -0
  81. package/lib/types/index.d.ts +6 -0
  82. package/lib/types/index.d.ts.map +1 -1
  83. package/lib/types/index.js +6 -0
  84. package/lib/utils/base64Decode.d.ts +6 -0
  85. package/lib/utils/base64Decode.d.ts.map +1 -0
  86. package/lib/utils/base64Decode.js +12 -0
  87. package/lib/utils/parseAgentTaskFileIdFromFencyFileHref.d.ts +8 -0
  88. package/lib/utils/parseAgentTaskFileIdFromFencyFileHref.d.ts.map +1 -0
  89. package/lib/utils/parseAgentTaskFileIdFromFencyFileHref.js +43 -0
  90. package/lib/utils/version.js +1 -1
  91. package/package.json +15 -3
@@ -0,0 +1,271 @@
1
+ import { base64Decode } from '../utils/base64Decode';
2
+ import { EventStreamContentType, fetchEventSource, } from '@microsoft/fetch-event-source';
3
+ import { createStreamWorkerCode } from './createStreamWorkerCode';
4
+ function streamFailureMessage(error) {
5
+ if (error instanceof Error)
6
+ return error.message;
7
+ if (typeof error === 'string')
8
+ return error;
9
+ return 'Unknown stream error';
10
+ }
11
+ /**
12
+ * Centralized manager for EventSource connections to streams.
13
+ * Ensures only one connection per stream regardless of how many hooks subscribe.
14
+ *
15
+ * When a Web Worker is available, the main thread performs fetch (correct CORS origin)
16
+ * and transfers the response body to the worker for parsing, so the read loop is not
17
+ * stalled by background tab throttling. Otherwise falls back to fetchEventSource on
18
+ * the main thread with openWhenHidden so the connection is not aborted on tab switch.
19
+ * @public
20
+ */
21
+ export class StreamEventManager {
22
+ constructor(fency) {
23
+ this.activeConnections = new Map();
24
+ this.subscribers = new Map();
25
+ this.worker = null;
26
+ this.workerBlobUrl = null;
27
+ this.workerSupported = false;
28
+ this.fency = fency;
29
+ this.tryInitWorker();
30
+ }
31
+ tryInitWorker() {
32
+ try {
33
+ if (typeof Worker === 'undefined' ||
34
+ typeof Blob === 'undefined' ||
35
+ typeof URL === 'undefined' ||
36
+ typeof URL.createObjectURL !== 'function' ||
37
+ typeof ReadableStream === 'undefined') {
38
+ return;
39
+ }
40
+ const code = createStreamWorkerCode();
41
+ const blob = new Blob([code], { type: 'application/javascript' });
42
+ const blobUrl = URL.createObjectURL(blob);
43
+ const worker = new Worker(blobUrl);
44
+ worker.onmessage = (e) => {
45
+ this.handleWorkerMessage(e.data);
46
+ };
47
+ worker.onerror = (event) => {
48
+ console.error('Fency stream worker error:', event.message);
49
+ };
50
+ this.worker = worker;
51
+ this.workerBlobUrl = blobUrl;
52
+ this.workerSupported = true;
53
+ }
54
+ catch {
55
+ this.workerSupported = false;
56
+ this.worker = null;
57
+ if (this.workerBlobUrl) {
58
+ URL.revokeObjectURL(this.workerBlobUrl);
59
+ this.workerBlobUrl = null;
60
+ }
61
+ }
62
+ }
63
+ handleWorkerMessage(data) {
64
+ if (!data || typeof data !== 'object')
65
+ return;
66
+ const msg = data;
67
+ switch (msg.type) {
68
+ case 'message':
69
+ if (msg.data && msg.streamId) {
70
+ const decodedData = base64Decode(msg.data);
71
+ this.broadcast(decodedData, msg.streamId);
72
+ }
73
+ break;
74
+ case 'error':
75
+ if (msg.streamId) {
76
+ this.activeConnections.delete(msg.streamId);
77
+ this.broadcastError(msg.streamId, msg.error);
78
+ }
79
+ break;
80
+ case 'open':
81
+ break;
82
+ default:
83
+ break;
84
+ }
85
+ }
86
+ /**
87
+ * Called by FencyProvider when activeStreams changes.
88
+ * Creates new connections and removes old ones.
89
+ */
90
+ updateStreams(streams) {
91
+ streams.forEach((streamCache) => {
92
+ const streamId = streamCache.stream.id;
93
+ if (!this.activeConnections.has(streamId)) {
94
+ this.connectStream(streamCache);
95
+ }
96
+ });
97
+ const activeStreamIds = new Set(streams.map((s) => s.stream.id));
98
+ this.activeConnections.forEach((connection, streamId) => {
99
+ if (!activeStreamIds.has(streamId)) {
100
+ connection.abort();
101
+ this.activeConnections.delete(streamId);
102
+ }
103
+ });
104
+ }
105
+ connectStream(streamCache) {
106
+ if (this.workerSupported && this.worker) {
107
+ this.connectStreamInWorker(streamCache);
108
+ }
109
+ else {
110
+ this.connectStreamOnMainThread(streamCache);
111
+ }
112
+ }
113
+ connectStreamInWorker(streamCache) {
114
+ const streamId = streamCache.stream.id;
115
+ const url = `${this.fency.baseUrl}/sse/streams/${streamId}`;
116
+ const fetchAbort = new AbortController();
117
+ const headers = {
118
+ accept: EventStreamContentType,
119
+ 'X-Fency-Publishable-Key': this.fency.publishableKey,
120
+ 'X-Fency-Stream-Token': streamCache.stream.token,
121
+ };
122
+ this.activeConnections.set(streamId, {
123
+ abort: () => {
124
+ fetchAbort.abort();
125
+ this.worker?.postMessage({ command: 'disconnect', streamId });
126
+ },
127
+ });
128
+ void this.startWorkerStream(streamId, url, headers, fetchAbort, streamCache);
129
+ }
130
+ async startWorkerStream(streamId, url, headers, fetchAbort, streamCache) {
131
+ const worker = this.worker;
132
+ if (!worker)
133
+ return;
134
+ const fail = (message) => {
135
+ if (fetchAbort.signal.aborted)
136
+ return;
137
+ this.activeConnections.delete(streamId);
138
+ this.broadcastError(streamId, message);
139
+ };
140
+ try {
141
+ const response = await fetch(url, {
142
+ method: 'GET',
143
+ headers,
144
+ signal: fetchAbort.signal,
145
+ });
146
+ if (!response.ok) {
147
+ if (response.status >= 400 &&
148
+ response.status < 500 &&
149
+ response.status !== 429) {
150
+ fail(`Client error ${response.status}`);
151
+ }
152
+ else {
153
+ fail(`HTTP ${response.status}`);
154
+ }
155
+ return;
156
+ }
157
+ const body = response.body;
158
+ if (!body) {
159
+ fail('No response body');
160
+ return;
161
+ }
162
+ if (!this.activeConnections.has(streamId)) {
163
+ await body.cancel().catch(() => {
164
+ // ignore
165
+ });
166
+ return;
167
+ }
168
+ try {
169
+ worker.postMessage({ command: 'start', streamId, readableStream: body }, [body]);
170
+ }
171
+ catch {
172
+ // ReadableStream transfer not supported (e.g. Safari).
173
+ // Disable worker for this session and fall back to main-thread SSE.
174
+ this.workerSupported = false;
175
+ body.cancel().catch(() => { });
176
+ this.activeConnections.delete(streamId);
177
+ this.connectStreamOnMainThread(streamCache);
178
+ }
179
+ }
180
+ catch (err) {
181
+ if (fetchAbort.signal.aborted)
182
+ return;
183
+ fail(streamFailureMessage(err));
184
+ }
185
+ }
186
+ connectStreamOnMainThread(streamCache) {
187
+ const streamId = streamCache.stream.id;
188
+ const abortController = new AbortController();
189
+ this.activeConnections.set(streamId, {
190
+ abort: () => abortController.abort(),
191
+ });
192
+ const url = `${this.fency.baseUrl}/sse/streams/${streamId}`;
193
+ const headers = {
194
+ 'X-Fency-Publishable-Key': this.fency.publishableKey,
195
+ 'X-Fency-Stream-Token': streamCache.stream.token,
196
+ };
197
+ fetchEventSource(url, {
198
+ headers,
199
+ signal: abortController.signal,
200
+ openWhenHidden: true,
201
+ onopen: async (response) => {
202
+ if (response.ok) {
203
+ return;
204
+ }
205
+ if (response.status >= 400 &&
206
+ response.status < 500 &&
207
+ response.status !== 429) {
208
+ this.activeConnections.delete(streamId);
209
+ throw new Error(`Client error ${response.status}`);
210
+ }
211
+ },
212
+ onmessage: (message) => {
213
+ if (message.data) {
214
+ const decodedData = base64Decode(message.data);
215
+ this.broadcast(decodedData, streamId);
216
+ }
217
+ },
218
+ onerror: (error) => {
219
+ console.error('EventSource error for stream', streamId, ':', error);
220
+ this.activeConnections.delete(streamId);
221
+ this.broadcastError(streamId, streamFailureMessage(error));
222
+ throw error;
223
+ },
224
+ onclose() {
225
+ // Connection closed by server
226
+ },
227
+ });
228
+ }
229
+ /**
230
+ * Subscribe to events from all active streams.
231
+ * Returns an unsubscribe function.
232
+ */
233
+ subscribe(subscriberId, callbacks) {
234
+ this.subscribers.set(subscriberId, callbacks);
235
+ return () => {
236
+ this.subscribers.delete(subscriberId);
237
+ };
238
+ }
239
+ broadcast(data, streamId) {
240
+ this.subscribers.forEach((subscription) => {
241
+ subscription.onMessage(data, streamId);
242
+ });
243
+ }
244
+ broadcastError(streamId, errorMessage) {
245
+ this.subscribers.forEach((subscription) => {
246
+ subscription.onError(streamId, errorMessage);
247
+ });
248
+ }
249
+ /**
250
+ * Cleanup all connections and subscriptions
251
+ */
252
+ cleanup() {
253
+ this.activeConnections.forEach((connection) => connection.abort());
254
+ this.activeConnections.clear();
255
+ if (this.worker) {
256
+ try {
257
+ this.worker.postMessage({ command: 'cleanup' });
258
+ }
259
+ catch {
260
+ // ignore
261
+ }
262
+ this.worker = null;
263
+ }
264
+ if (this.workerBlobUrl) {
265
+ URL.revokeObjectURL(this.workerBlobUrl);
266
+ this.workerBlobUrl = null;
267
+ }
268
+ this.workerSupported = false;
269
+ this.subscribers.clear();
270
+ }
271
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Returns the source code for the inline SSE stream Web Worker.
3
+ * Consumes a ReadableStream transferred from the main thread (same-origin fetch + CORS)
4
+ * so the read loop runs off the main thread and is not stalled by tab throttling.
5
+ * @public
6
+ */
7
+ export declare function createStreamWorkerCode(): string;
8
+ //# sourceMappingURL=createStreamWorkerCode.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createStreamWorkerCode.d.ts","sourceRoot":"","sources":["../../src/stream/createStreamWorkerCode.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,wBAAgB,sBAAsB,IAAI,MAAM,CAiJ/C"}
@@ -0,0 +1,152 @@
1
+ /**
2
+ * Returns the source code for the inline SSE stream Web Worker.
3
+ * Consumes a ReadableStream transferred from the main thread (same-origin fetch + CORS)
4
+ * so the read loop runs off the main thread and is not stalled by tab throttling.
5
+ * @public
6
+ */
7
+ export function createStreamWorkerCode() {
8
+ return `
9
+ var connections = new Map();
10
+
11
+ function disconnectStream(streamId) {
12
+ var entry = connections.get(streamId);
13
+ if (entry) {
14
+ try {
15
+ entry.cancel();
16
+ } catch (e) {}
17
+ connections.delete(streamId);
18
+ }
19
+ }
20
+
21
+ function findEventBoundary(buf) {
22
+ var iCRLF = buf.indexOf("\\r\\n\\r\\n");
23
+ var iLF = buf.indexOf("\\n\\n");
24
+ if (iCRLF !== -1 && (iLF === -1 || iCRLF < iLF)) {
25
+ return { index: iCRLF, len: 4 };
26
+ }
27
+ if (iLF !== -1) {
28
+ return { index: iLF, len: 2 };
29
+ }
30
+ return null;
31
+ }
32
+
33
+ function parseSseBuffer(buffer) {
34
+ var events = [];
35
+ var rest = buffer;
36
+ while (true) {
37
+ var boundary = findEventBoundary(rest);
38
+ if (!boundary) break;
39
+ var rawEvent = rest.slice(0, boundary.index);
40
+ rest = rest.slice(boundary.index + boundary.len);
41
+ if (!rawEvent.trim()) continue;
42
+
43
+ var eventType = "";
44
+ var eventId = "";
45
+ var dataLines = [];
46
+ var lines = rawEvent.split(/\\r\\n|\\r|\\n/);
47
+ for (var i = 0; i < lines.length; i++) {
48
+ var line = lines[i];
49
+ if (line.charAt(0) === ":") continue;
50
+ var colon = line.indexOf(":");
51
+ if (colon === -1) continue;
52
+ var field = line.slice(0, colon);
53
+ var value = line.slice(colon + 1);
54
+ if (value.charAt(0) === " ") value = value.slice(1);
55
+ if (field === "data") dataLines.push(value);
56
+ else if (field === "event") eventType = value;
57
+ else if (field === "id") eventId = value;
58
+ }
59
+ var data = dataLines.join("\\n");
60
+ if (data.length > 0) {
61
+ events.push({ data: data, event: eventType, id: eventId });
62
+ }
63
+ }
64
+ return { events: events, rest: rest };
65
+ }
66
+
67
+ async function readStream(streamId, readableStream) {
68
+ disconnectStream(streamId);
69
+ if (!readableStream || typeof readableStream.getReader !== "function") {
70
+ self.postMessage({
71
+ type: "error",
72
+ streamId: streamId,
73
+ error: "No readable stream",
74
+ });
75
+ return;
76
+ }
77
+ var reader = readableStream.getReader();
78
+ connections.set(streamId, {
79
+ cancel: function () {
80
+ reader.cancel().catch(function () {});
81
+ },
82
+ });
83
+ try {
84
+ var decoder = new TextDecoder();
85
+ var buf = "";
86
+ while (true) {
87
+ var readResult = await reader.read();
88
+ var done = readResult.done;
89
+ var value = readResult.value;
90
+ if (done) break;
91
+ buf += decoder.decode(value, { stream: true });
92
+ var parsed = parseSseBuffer(buf);
93
+ buf = parsed.rest;
94
+ for (var j = 0; j < parsed.events.length; j++) {
95
+ var ev = parsed.events[j];
96
+ self.postMessage({
97
+ type: "message",
98
+ streamId: streamId,
99
+ data: ev.data,
100
+ event: ev.event || undefined,
101
+ id: ev.id || undefined,
102
+ });
103
+ }
104
+ }
105
+ buf += decoder.decode();
106
+ var finalParsed = parseSseBuffer(buf);
107
+ for (var k = 0; k < finalParsed.events.length; k++) {
108
+ var fev = finalParsed.events[k];
109
+ self.postMessage({
110
+ type: "message",
111
+ streamId: streamId,
112
+ data: fev.data,
113
+ event: fev.event || undefined,
114
+ id: fev.id || undefined,
115
+ });
116
+ }
117
+ } catch (err) {
118
+ if (err && err.name === "AbortError") {
119
+ return;
120
+ }
121
+ var msg = err && err.message ? String(err.message) : String(err);
122
+ self.postMessage({ type: "error", streamId: streamId, error: msg });
123
+ } finally {
124
+ connections.delete(streamId);
125
+ }
126
+ }
127
+
128
+ self.onmessage = function (e) {
129
+ var d = e.data;
130
+ if (!d || !d.command) return;
131
+ switch (d.command) {
132
+ case "start":
133
+ readStream(d.streamId, d.readableStream);
134
+ break;
135
+ case "disconnect":
136
+ disconnectStream(d.streamId);
137
+ break;
138
+ case "cleanup":
139
+ connections.forEach(function (entry) {
140
+ try {
141
+ entry.cancel();
142
+ } catch (e2) {}
143
+ });
144
+ connections.clear();
145
+ self.close();
146
+ break;
147
+ default:
148
+ break;
149
+ }
150
+ };
151
+ `.trim();
152
+ }
@@ -0,0 +1,4 @@
1
+ import { StreamData } from '../types/StreamData';
2
+ /** @public */
3
+ export declare const toStreamData: (data: string) => StreamData | null;
4
+ //# sourceMappingURL=toStreamData.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"toStreamData.d.ts","sourceRoot":"","sources":["../../src/stream/toStreamData.ts"],"names":[],"mappings":"AAWA,OAAO,EAEH,UAAU,EAGb,MAAM,qBAAqB,CAAA;AAE5B,cAAc;AACd,eAAO,MAAM,YAAY,GAAI,MAAM,MAAM,KAAG,UAAU,GAAG,IAQxD,CAAA"}
@@ -0,0 +1,61 @@
1
+ import { isAgentTaskProgressItemUpdatedEvent, isStreamNotFoundEvent, isStreamTimeoutEvent, } from '../utils/streamEventTypes';
2
+ import { parseAgentTaskEventData } from '../parsing/AgentTaskEventDataSchemas';
3
+ /** @public */
4
+ export const toStreamData = (data) => {
5
+ try {
6
+ const json = JSON.parse(data);
7
+ return toStreamDataRaw(json);
8
+ }
9
+ catch (error) {
10
+ console.error('Error parsing message:', error);
11
+ return null;
12
+ }
13
+ };
14
+ const toStreamDataRaw = (data) => {
15
+ if (isStreamTimeoutEvent(data)) {
16
+ return toStreamTimeout(data);
17
+ }
18
+ if (isStreamNotFoundEvent(data)) {
19
+ return toStreamNotFound(data);
20
+ }
21
+ if (isAgentTaskProgressItemUpdatedEvent(data)) {
22
+ return toAgentTaskProgressItemUpdated(data);
23
+ }
24
+ return null;
25
+ };
26
+ const toStreamTimeout = (data) => {
27
+ return {
28
+ type: 'STREAM_TIMEOUT',
29
+ streamId: data.streamId,
30
+ timestamp: data.timestamp,
31
+ };
32
+ };
33
+ const toStreamNotFound = (data) => {
34
+ return {
35
+ type: 'STREAM_NOT_FOUND',
36
+ streamId: data.streamId,
37
+ timestamp: data.timestamp,
38
+ };
39
+ };
40
+ const toAgentTaskProgressItemUpdated = (data) => {
41
+ let raw;
42
+ try {
43
+ raw = JSON.parse(data.data);
44
+ }
45
+ catch (error) {
46
+ console.warn('[fency] Invalid JSON in AGENT_TASK_PROGRESS_ITEM_UPDATED data payload:', error);
47
+ return null;
48
+ }
49
+ const parsed = parseAgentTaskEventData(raw);
50
+ if (parsed === null)
51
+ return null;
52
+ return {
53
+ type: 'AGENT_TASK_PROGRESS_ITEM_UPDATED',
54
+ streamId: data.streamId,
55
+ agentTaskId: data.agentTaskId,
56
+ progressItemId: data.progressItemId,
57
+ timestamp: data.timestamp,
58
+ createdAt: data.createdAt,
59
+ data: parsed,
60
+ };
61
+ };
@@ -0,0 +1,18 @@
1
+ import type { AgentTaskEventData } from '../AgentTaskEventData';
2
+ import type { ApiError } from '../types/ApiError';
3
+ import type { CreateAgentTaskRequest } from '../types/CreateAgentTaskRequest';
4
+ import type { CreateAgentTaskParams } from '../types/CreateAgentTaskParams';
5
+ import type { CreateAgentTaskResponse } from '../types/CreateAgentTaskResponse';
6
+ /** @public */
7
+ export declare function mapCreateAgentTaskParams(params: CreateAgentTaskParams): CreateAgentTaskRequest;
8
+ /** @public */
9
+ export declare function isTerminalAgentTaskEventData(data: AgentTaskEventData): data is Extract<AgentTaskEventData, {
10
+ eventType: 'Completed' | 'Error';
11
+ }>;
12
+ /** @public */
13
+ export declare function shouldAppendCompletedToProgress(data: AgentTaskEventData): boolean;
14
+ /** @public */
15
+ export declare function agentTaskErrorFromEventData(data: AgentTaskEventData): ApiError | null;
16
+ /** @public */
17
+ export declare function getTerminalCreateAgentTaskResponse(streamId: string, agentTaskId: string, data: AgentTaskEventData): CreateAgentTaskResponse | null;
18
+ //# sourceMappingURL=mapCreateAgentTaskParams.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mapCreateAgentTaskParams.d.ts","sourceRoot":"","sources":["../../src/task/mapCreateAgentTaskParams.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAA;AAC/D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AACjD,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,iCAAiC,CAAA;AAC7E,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAA;AAC3E,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,kCAAkC,CAAA;AAE/E,cAAc;AACd,wBAAgB,wBAAwB,CACpC,MAAM,EAAE,qBAAqB,GAC9B,sBAAsB,CAiDxB;AAED,cAAc;AACd,wBAAgB,4BAA4B,CACxC,IAAI,EAAE,kBAAkB,GACzB,IAAI,IAAI,OAAO,CAAC,kBAAkB,EAAE;IAAE,SAAS,EAAE,WAAW,GAAG,OAAO,CAAA;CAAE,CAAC,CAE3E;AAED,cAAc;AACd,wBAAgB,+BAA+B,CAC3C,IAAI,EAAE,kBAAkB,GACzB,OAAO,CAMT;AAED,cAAc;AACd,wBAAgB,2BAA2B,CACvC,IAAI,EAAE,kBAAkB,GACzB,QAAQ,GAAG,IAAI,CASjB;AAED,cAAc;AACd,wBAAgB,kCAAkC,CAC9C,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,kBAAkB,GACzB,uBAAuB,GAAG,IAAI,CAoBhC"}
@@ -0,0 +1,84 @@
1
+ /** @public */
2
+ export function mapCreateAgentTaskParams(params) {
3
+ return {
4
+ streamingChatCompletionTask: params.type === 'StreamingChatCompletion'
5
+ ? {
6
+ messages: params.messages,
7
+ model: params.model,
8
+ ...(params.temperature !== undefined
9
+ ? { temperature: params.temperature }
10
+ : {}),
11
+ ...(params.topP !== undefined ? { topP: params.topP } : {}),
12
+ }
13
+ : undefined,
14
+ structuredChatCompletionTask: params.type === 'StructuredChatCompletion'
15
+ ? {
16
+ messages: params.messages,
17
+ jsonSchema: params.jsonSchema,
18
+ model: params.model,
19
+ ...(params.temperature !== undefined
20
+ ? { temperature: params.temperature }
21
+ : {}),
22
+ ...(params.topP !== undefined ? { topP: params.topP } : {}),
23
+ }
24
+ : undefined,
25
+ memoryChatTask: params.type === 'MemoryChat'
26
+ ? {
27
+ messages: params.messages,
28
+ model: params.model,
29
+ language: params.language ?? 'en',
30
+ chunkLimit: params.chunkLimit ?? 10,
31
+ memoryScanLimit: params.memoryScanLimit ?? 3,
32
+ }
33
+ : undefined,
34
+ memorySearchTask: params.type === 'MemorySearch'
35
+ ? {
36
+ query: params.query,
37
+ model: params.model,
38
+ language: params.language ?? 'en',
39
+ chunkLimit: params.chunkLimit ?? 10,
40
+ contextExpansion: params.contextExpansion,
41
+ ...(params.queryExpansion != null
42
+ ? { queryExpansion: params.queryExpansion }
43
+ : {}),
44
+ }
45
+ : undefined,
46
+ };
47
+ }
48
+ /** @public */
49
+ export function isTerminalAgentTaskEventData(data) {
50
+ return data.eventType === 'Completed' || data.eventType === 'Error';
51
+ }
52
+ /** @public */
53
+ export function shouldAppendCompletedToProgress(data) {
54
+ return ((data.taskType === 'MemorySearch' && data.eventType === 'Completed') ||
55
+ (data.taskType === 'StructuredChatCompletion' &&
56
+ data.eventType === 'Completed'));
57
+ }
58
+ /** @public */
59
+ export function agentTaskErrorFromEventData(data) {
60
+ if (data.eventType !== 'Error')
61
+ return null;
62
+ return {
63
+ code: 'AgentTaskError',
64
+ message: 'message' in data && typeof data.message === 'string'
65
+ ? data.message
66
+ : 'Agent task failed',
67
+ };
68
+ }
69
+ /** @public */
70
+ export function getTerminalCreateAgentTaskResponse(streamId, agentTaskId, data) {
71
+ if (data.eventType === 'Error') {
72
+ const error = agentTaskErrorFromEventData(data);
73
+ return error ? { type: 'error', error } : null;
74
+ }
75
+ if (data.eventType === 'Completed') {
76
+ return {
77
+ type: 'success',
78
+ streamId,
79
+ agentTaskId,
80
+ response: data,
81
+ };
82
+ }
83
+ return null;
84
+ }
@@ -0,0 +1,5 @@
1
+ import type { AgentTaskEventData } from '../AgentTaskEventData';
2
+ import type { AgentTaskProgressItemUpdated } from '../types/StreamData';
3
+ export declare function upsertProgressItem(progressItems: AgentTaskProgressItemUpdated[], item: AgentTaskProgressItemUpdated): AgentTaskProgressItemUpdated[];
4
+ export declare function createSyntheticCompletedProgressItem(agentTaskId: string, streamId: string, data: AgentTaskEventData): AgentTaskProgressItemUpdated;
5
+ //# sourceMappingURL=progressItems.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"progressItems.d.ts","sourceRoot":"","sources":["../../src/task/progressItems.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAA;AAC/D,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,qBAAqB,CAAA;AAEvE,wBAAgB,kBAAkB,CAC9B,aAAa,EAAE,4BAA4B,EAAE,EAC7C,IAAI,EAAE,4BAA4B,GACnC,4BAA4B,EAAE,CAUhC;AAED,wBAAgB,oCAAoC,CAChD,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,kBAAkB,GACzB,4BAA4B,CAW9B"}
@@ -0,0 +1,19 @@
1
+ export function upsertProgressItem(progressItems, item) {
2
+ const alreadyExists = progressItems.some((p) => p.progressItemId === item.progressItemId);
3
+ if (alreadyExists) {
4
+ return progressItems.map((p) => p.progressItemId === item.progressItemId ? item : p);
5
+ }
6
+ return [...progressItems, item];
7
+ }
8
+ export function createSyntheticCompletedProgressItem(agentTaskId, streamId, data) {
9
+ const timestamp = new Date().toISOString();
10
+ return {
11
+ type: 'AGENT_TASK_PROGRESS_ITEM_UPDATED',
12
+ streamId,
13
+ agentTaskId,
14
+ progressItemId: `completed-${agentTaskId}`,
15
+ timestamp,
16
+ createdAt: timestamp,
17
+ data,
18
+ };
19
+ }
@@ -0,0 +1,7 @@
1
+ import type { TaskEvent, TaskStoreState } from './types';
2
+ /** @public */
3
+ export declare const initialTaskStoreState: TaskStoreState;
4
+ /** @public */
5
+ export declare function taskReducer(state: TaskStoreState, event: TaskEvent): TaskStoreState;
6
+ export { agentTaskErrorFromEventData, getTerminalCreateAgentTaskResponse, isTerminalAgentTaskEventData, mapCreateAgentTaskParams, shouldAppendCompletedToProgress, } from './mapCreateAgentTaskParams';
7
+ //# sourceMappingURL=taskReducer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"taskReducer.d.ts","sourceRoot":"","sources":["../../src/task/taskReducer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AAOxD,cAAc;AACd,eAAO,MAAM,qBAAqB,EAAE,cAA8B,CAAA;AAElE,cAAc;AACd,wBAAgB,WAAW,CACvB,KAAK,EAAE,cAAc,EACrB,KAAK,EAAE,SAAS,GACjB,cAAc,CA+GhB;AAED,OAAO,EACH,2BAA2B,EAC3B,kCAAkC,EAClC,4BAA4B,EAC5B,wBAAwB,EACxB,+BAA+B,GAClC,MAAM,4BAA4B,CAAA"}