@burdenoff/fe-libs 2026.1007.6 → 2026.1008.2
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/shared/assistant/attachmentCommit.d.ts +175 -0
- package/dist/shared/assistant/attachmentCommit.d.ts.map +1 -0
- package/dist/shared/assistant/attachmentCommit.js +638 -0
- package/dist/shared/assistant/attachments.d.ts +39 -19
- package/dist/shared/assistant/attachments.d.ts.map +1 -1
- package/dist/shared/assistant/history/historyEngine.js +280 -280
- package/dist/shared/assistant/i18nManifest.d.ts +14 -2
- package/dist/shared/assistant/i18nManifest.d.ts.map +1 -1
- package/dist/shared/assistant/i18nManifest.js +17 -3
- package/dist/shared/assistant/index.d.ts +3 -0
- package/dist/shared/assistant/index.d.ts.map +1 -1
- package/dist/shared/assistant/ui/AssistantChatArea.d.ts.map +1 -1
- package/dist/shared/assistant/ui/AssistantChatArea.js +1390 -1371
- package/dist/shared/assistant/ui/composer/AssistantAttachmentChips.d.ts +8 -5
- package/dist/shared/assistant/ui/composer/AssistantAttachmentChips.d.ts.map +1 -1
- package/dist/shared/assistant/ui/composer/AssistantAttachmentChips.js +26 -9
- package/dist/shared/assistant/ui/composer/AssistantComposer.d.ts +3 -2
- package/dist/shared/assistant/ui/composer/AssistantComposer.d.ts.map +1 -1
- package/dist/shared/assistant/ui/composer/AssistantComposer.js +214 -125
- package/dist/shared/assistant/ui/voice/AssistantVoiceSession.d.ts +10 -0
- package/dist/shared/assistant/ui/voice/AssistantVoiceSession.d.ts.map +1 -1
- package/dist/shared/assistant/ui/voice/AssistantVoiceSession.js +124 -116
- package/dist/shared/assistant/useAssistantAttachments.d.ts +20 -2
- package/dist/shared/assistant/useAssistantAttachments.d.ts.map +1 -1
- package/dist/shared/assistant/useAssistantAttachments.js +146 -202
- package/dist/shared/assistant/useAttachmentCommitter.d.ts +17 -0
- package/dist/shared/assistant/useAttachmentCommitter.d.ts.map +1 -0
- package/dist/shared/assistant/useAttachmentCommitter.js +41 -0
- package/dist/shared/assistant/voiceCommit.d.ts +36 -0
- package/dist/shared/assistant/voiceCommit.d.ts.map +1 -0
- package/dist/shared/assistant/voiceCommit.js +24 -0
- package/dist/shared-assistant.js +161 -158
- package/dist/storage/filesPort.d.ts +120 -0
- package/dist/storage/filesPort.d.ts.map +1 -0
- package/dist/storage/filesPort.js +269 -0
- package/dist/storage/index.d.ts +2 -0
- package/dist/storage/index.d.ts.map +1 -1
- package/dist/storage/index.js +9 -8
- package/package.json +1 -1
|
@@ -1,245 +1,189 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import "
|
|
3
|
-
import
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import { getWorkspaceId as f } from "./context.js";
|
|
8
|
-
import { useSaveToFiles as p } from "../../storage/useSaveToFiles.js";
|
|
9
|
-
import "../../storage/index.js";
|
|
10
|
-
import { extractDocumentText as m } from "./documentExtract.js";
|
|
11
|
-
import { useCallback as h, useEffect as g, useRef as _, useState as v } from "react";
|
|
1
|
+
import { downscaleImage as e } from "../utils/imageDownscale.js";
|
|
2
|
+
import { AttachmentRejectedError as t, INLINE_IMAGE_QUALITY as n, classifyAttachment as r, detectDocumentFormat as i, getAttachmentSendBlocker as a, resolveAssistantInlineLimits as o, truncateForInline as s, validateFile as c } from "./attachments.js";
|
|
3
|
+
import "./attachmentCommit.js";
|
|
4
|
+
import { useAttachmentCommitter as l } from "./useAttachmentCommitter.js";
|
|
5
|
+
import { extractDocumentText as u } from "./documentExtract.js";
|
|
6
|
+
import { useCallback as d, useEffect as f, useRef as p, useState as m } from "react";
|
|
12
7
|
//#region src/shared/assistant/useAssistantAttachments.ts
|
|
13
|
-
var
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
try {
|
|
17
|
-
return (await e({
|
|
18
|
-
gateway: "workspace",
|
|
19
|
-
query: y,
|
|
20
|
-
variables: { id: t },
|
|
21
|
-
workspaceToken: !0,
|
|
22
|
-
workspaceId: n,
|
|
23
|
-
suppressGlobalErrorEvent: !0
|
|
24
|
-
})).data?.getFileDownloadUrl ?? null;
|
|
25
|
-
} catch {
|
|
26
|
-
return null;
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
var x = 0;
|
|
30
|
-
function S() {
|
|
31
|
-
return x += 1, `att-${Date.now()}-${x}`;
|
|
8
|
+
var h = 0;
|
|
9
|
+
function g() {
|
|
10
|
+
return h += 1, `att-${Date.now()}-${h}`;
|
|
32
11
|
}
|
|
33
|
-
async function
|
|
34
|
-
let
|
|
35
|
-
id:
|
|
12
|
+
async function _(a, o) {
|
|
13
|
+
let c = r(a.type, a.name), l = {
|
|
14
|
+
id: g(),
|
|
36
15
|
status: "pending"
|
|
37
16
|
};
|
|
38
|
-
if (
|
|
39
|
-
let
|
|
17
|
+
if (c === "image") {
|
|
18
|
+
let r = await e(a, {
|
|
40
19
|
encodeFallback: !1,
|
|
41
20
|
inline: {
|
|
42
21
|
maxDim: 768,
|
|
43
|
-
quality:
|
|
22
|
+
quality: n
|
|
44
23
|
}
|
|
45
24
|
});
|
|
46
|
-
if (!
|
|
47
|
-
return {
|
|
25
|
+
if (!r.downscaled && r.blob.size > 10485760) throw new t("unsupported-image");
|
|
26
|
+
return v({
|
|
48
27
|
attachment: {
|
|
49
|
-
...
|
|
50
|
-
filename:
|
|
51
|
-
mimeType:
|
|
52
|
-
size:
|
|
53
|
-
kind:
|
|
54
|
-
previewUrl:
|
|
55
|
-
inlineDataUrl:
|
|
28
|
+
...l,
|
|
29
|
+
filename: r.filename,
|
|
30
|
+
mimeType: r.mimeType,
|
|
31
|
+
size: r.blob.size,
|
|
32
|
+
kind: c,
|
|
33
|
+
previewUrl: r.dataUrl || void 0,
|
|
34
|
+
inlineDataUrl: r.inlineDataUrl
|
|
56
35
|
},
|
|
57
|
-
blob:
|
|
58
|
-
};
|
|
36
|
+
blob: r.blob
|
|
37
|
+
});
|
|
59
38
|
}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
39
|
+
let d = new Blob([await a.arrayBuffer()], { type: a.type || "application/octet-stream" });
|
|
40
|
+
if (c === "text") {
|
|
41
|
+
let { text: e, truncated: t } = s(await d.text(), o);
|
|
42
|
+
return v({
|
|
63
43
|
attachment: {
|
|
64
|
-
...
|
|
65
|
-
filename:
|
|
66
|
-
mimeType:
|
|
67
|
-
size:
|
|
68
|
-
kind:
|
|
69
|
-
textContent:
|
|
70
|
-
textTruncated:
|
|
44
|
+
...l,
|
|
45
|
+
filename: a.name,
|
|
46
|
+
mimeType: a.type || "text/plain",
|
|
47
|
+
size: a.size,
|
|
48
|
+
kind: c,
|
|
49
|
+
textContent: e,
|
|
50
|
+
textTruncated: t
|
|
71
51
|
},
|
|
72
|
-
blob:
|
|
73
|
-
};
|
|
52
|
+
blob: d
|
|
53
|
+
});
|
|
74
54
|
}
|
|
75
|
-
let
|
|
76
|
-
if (
|
|
77
|
-
let
|
|
78
|
-
return {
|
|
55
|
+
let f = i(a.type, a.name);
|
|
56
|
+
if (f) {
|
|
57
|
+
let e = await u(new File([d], a.name, { type: d.type }), f, o);
|
|
58
|
+
return v({
|
|
79
59
|
attachment: {
|
|
80
|
-
...
|
|
81
|
-
filename:
|
|
82
|
-
mimeType:
|
|
83
|
-
size:
|
|
84
|
-
kind:
|
|
85
|
-
extraction:
|
|
86
|
-
textContent:
|
|
87
|
-
textTruncated:
|
|
88
|
-
documentPages:
|
|
60
|
+
...l,
|
|
61
|
+
filename: a.name,
|
|
62
|
+
mimeType: a.type || "application/octet-stream",
|
|
63
|
+
size: a.size,
|
|
64
|
+
kind: c,
|
|
65
|
+
extraction: e.extraction,
|
|
66
|
+
textContent: e.textContent,
|
|
67
|
+
textTruncated: e.textTruncated,
|
|
68
|
+
documentPages: e.documentPages
|
|
89
69
|
},
|
|
90
|
-
blob:
|
|
91
|
-
};
|
|
70
|
+
blob: d
|
|
71
|
+
});
|
|
92
72
|
}
|
|
93
|
-
return {
|
|
73
|
+
return v({
|
|
94
74
|
attachment: {
|
|
95
|
-
...
|
|
96
|
-
filename:
|
|
97
|
-
mimeType:
|
|
98
|
-
size:
|
|
99
|
-
kind:
|
|
75
|
+
...l,
|
|
76
|
+
filename: a.name,
|
|
77
|
+
mimeType: a.type || "application/octet-stream",
|
|
78
|
+
size: a.size,
|
|
79
|
+
kind: c
|
|
100
80
|
},
|
|
101
|
-
blob:
|
|
81
|
+
blob: d
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
function v(e) {
|
|
85
|
+
if (e.blob.size <= 5242880) return e;
|
|
86
|
+
let { attachment: n } = e;
|
|
87
|
+
if (n.kind === "image" || !n.textContent) throw new t("too-large-to-save");
|
|
88
|
+
return {
|
|
89
|
+
...e,
|
|
90
|
+
attachment: {
|
|
91
|
+
...n,
|
|
92
|
+
inlineOnly: !0
|
|
93
|
+
}
|
|
102
94
|
};
|
|
103
95
|
}
|
|
104
|
-
function
|
|
105
|
-
let
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
let j = _([]);
|
|
110
|
-
g(() => {
|
|
111
|
-
j.current = u;
|
|
112
|
-
}, [u]);
|
|
113
|
-
let M = h((e, t) => {
|
|
114
|
-
A.current && m((n) => n.map((n) => n.id === e ? {
|
|
96
|
+
function y(e = {}) {
|
|
97
|
+
let n = o({ maxInlineCharsPerFile: e.perFileChars }).perFileChars, [r, i] = m([]), [s, u] = m(null), [h, g] = m(!1), v = p(Promise.resolve()), [y, b] = m(0), x = p(0), S = p(/* @__PURE__ */ new Map()), C = p(0), w = p(!0), T = p(r);
|
|
98
|
+
T.current = r;
|
|
99
|
+
let E = d((e, t) => {
|
|
100
|
+
w.current && i((n) => n.map((n) => n.id === e ? {
|
|
115
101
|
...n,
|
|
116
102
|
...t
|
|
117
103
|
} : n));
|
|
118
|
-
}, []),
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
getBlob: async () => ({
|
|
131
|
-
blob: n,
|
|
132
|
-
filename: e.filename,
|
|
133
|
-
mimeType: e.mimeType
|
|
134
|
-
})
|
|
135
|
-
},
|
|
136
|
-
folderPath: o.attachments,
|
|
137
|
-
onRetry: (n) => {
|
|
138
|
-
O.current.has(e.id) || M(e.id, { progressNote: n.kind === "cold-start" ? t("attachments.waking", "File service is starting up — retry {{attempt}} of {{max}}", {
|
|
139
|
-
attempt: String(n.attempt),
|
|
140
|
-
max: String(n.maxAttempts)
|
|
141
|
-
}) : t("attachments.retrying", "Retrying {{attempt}} of {{max}}", {
|
|
142
|
-
attempt: String(n.attempt),
|
|
143
|
-
max: String(n.maxAttempts)
|
|
144
|
-
}) });
|
|
145
|
-
}
|
|
146
|
-
});
|
|
147
|
-
if (O.current.has(e.id)) return;
|
|
148
|
-
let i = r?.id ? await b(r.id, f()) : null;
|
|
149
|
-
if (O.current.has(e.id)) return;
|
|
150
|
-
M(e.id, {
|
|
151
|
-
status: "ready",
|
|
152
|
-
fileId: r?.id,
|
|
153
|
-
downloadUrl: i ?? void 0,
|
|
154
|
-
progressNote: void 0
|
|
155
|
-
});
|
|
156
|
-
} catch (t) {
|
|
157
|
-
if (O.current.has(e.id)) return;
|
|
158
|
-
if (e.kind === "text" || e.textContent) {
|
|
159
|
-
M(e.id, {
|
|
160
|
-
status: "ready",
|
|
161
|
-
progressNote: void 0
|
|
162
|
-
});
|
|
163
|
-
return;
|
|
164
|
-
}
|
|
165
|
-
M(e.id, {
|
|
166
|
-
status: "error",
|
|
167
|
-
error: t instanceof Error ? t.message : "Upload failed",
|
|
168
|
-
progressNote: void 0
|
|
169
|
-
});
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
}, [
|
|
173
|
-
M,
|
|
174
|
-
s,
|
|
175
|
-
t
|
|
176
|
-
]), P = h((e) => {
|
|
177
|
-
if (!e) return;
|
|
178
|
-
let t = Array.from(e);
|
|
179
|
-
if (t.length === 0) return;
|
|
180
|
-
x(null);
|
|
181
|
-
let n = [];
|
|
182
|
-
for (let e of t) {
|
|
183
|
-
let t = d(e, k.current);
|
|
104
|
+
}, []), D = l(E), O = p(D);
|
|
105
|
+
O.current = D, f(() => (w.current = !0, () => {
|
|
106
|
+
w.current = !1, O.current.cancel(), O.current.discardPending();
|
|
107
|
+
}), []);
|
|
108
|
+
let k = d((e) => {
|
|
109
|
+
if (!e || O.current.isCommitting) return;
|
|
110
|
+
let r = Array.from(e);
|
|
111
|
+
if (r.length === 0) return;
|
|
112
|
+
u(null);
|
|
113
|
+
let a = [];
|
|
114
|
+
for (let e of r) {
|
|
115
|
+
let t = c(e, C.current);
|
|
184
116
|
if (t) {
|
|
185
|
-
|
|
117
|
+
u(t);
|
|
186
118
|
continue;
|
|
187
119
|
}
|
|
188
|
-
|
|
120
|
+
a.push(e), C.current += 1;
|
|
189
121
|
}
|
|
190
|
-
if (
|
|
191
|
-
|
|
192
|
-
for (let e of
|
|
193
|
-
let
|
|
194
|
-
|
|
195
|
-
let
|
|
122
|
+
if (a.length !== 0) {
|
|
123
|
+
b((e) => e + a.length);
|
|
124
|
+
for (let e of a) {
|
|
125
|
+
let r = x.current;
|
|
126
|
+
v.current = v.current.then(async () => {
|
|
127
|
+
let a = null;
|
|
196
128
|
try {
|
|
197
|
-
|
|
129
|
+
a = await _(e, n);
|
|
198
130
|
} catch (e) {
|
|
199
|
-
|
|
131
|
+
C.current = Math.max(0, C.current - 1), w.current && u(e instanceof t ? e.reason : "unreadable");
|
|
200
132
|
}
|
|
201
|
-
if (!
|
|
202
|
-
if (
|
|
203
|
-
|
|
133
|
+
if (!w.current || (b((e) => Math.max(0, e - 1)), !a)) return;
|
|
134
|
+
if (r !== x.current) {
|
|
135
|
+
C.current = Math.max(0, C.current - 1);
|
|
204
136
|
return;
|
|
205
137
|
}
|
|
206
|
-
let
|
|
207
|
-
|
|
138
|
+
let o = a;
|
|
139
|
+
S.current.set(o.attachment.id, o.blob), i((e) => [...e, {
|
|
140
|
+
...o.attachment,
|
|
141
|
+
status: "ready"
|
|
142
|
+
}]);
|
|
208
143
|
});
|
|
209
144
|
}
|
|
210
145
|
}
|
|
211
|
-
}, [
|
|
212
|
-
|
|
213
|
-
}, []),
|
|
214
|
-
let t =
|
|
215
|
-
!t || t.status
|
|
216
|
-
status: "
|
|
146
|
+
}, [n]), A = d((e) => {
|
|
147
|
+
T.current.find((t) => t.id === e)?.status !== "uploading" && (S.current.delete(e), C.current = Math.max(0, C.current - 1), i((t) => t.filter((t) => t.id !== e)));
|
|
148
|
+
}, []), j = d((e) => {
|
|
149
|
+
let t = T.current.find((t) => t.id === e);
|
|
150
|
+
!t || !S.current.has(e) || t.status === "uploading" || t.status === "pending" || E(e, {
|
|
151
|
+
status: "ready",
|
|
217
152
|
error: void 0,
|
|
153
|
+
saveError: void 0,
|
|
154
|
+
progress: void 0,
|
|
218
155
|
progressNote: void 0
|
|
219
|
-
})
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
156
|
+
});
|
|
157
|
+
}, [E]), M = d(() => O.current.cancel(), []), N = d(async (e) => {
|
|
158
|
+
let t = T.current.filter((e) => e.status === "ready").map((e) => ({
|
|
159
|
+
attachment: e,
|
|
160
|
+
blob: S.current.get(e.id) ?? null
|
|
161
|
+
}));
|
|
162
|
+
g(!0);
|
|
163
|
+
try {
|
|
164
|
+
return await O.current.commit(t, e);
|
|
165
|
+
} finally {
|
|
166
|
+
w.current && g(!1);
|
|
167
|
+
}
|
|
168
|
+
}, []), P = d(() => {
|
|
169
|
+
O.current.cancel(), O.current.discardPending(), x.current += 1, C.current = 0, S.current.clear(), i([]);
|
|
170
|
+
}, []), F = d(() => u(null), []), I = a(y, r);
|
|
230
171
|
return {
|
|
231
|
-
attachments:
|
|
232
|
-
isBusy:
|
|
233
|
-
preparingCount:
|
|
234
|
-
sendBlocker:
|
|
235
|
-
rejection:
|
|
236
|
-
addFiles:
|
|
237
|
-
remove:
|
|
238
|
-
retry:
|
|
239
|
-
clear:
|
|
240
|
-
clearRejection:
|
|
241
|
-
canAddMore:
|
|
172
|
+
attachments: r,
|
|
173
|
+
isBusy: I === "in-flight",
|
|
174
|
+
preparingCount: y,
|
|
175
|
+
sendBlocker: I,
|
|
176
|
+
rejection: s,
|
|
177
|
+
addFiles: k,
|
|
178
|
+
remove: A,
|
|
179
|
+
retry: j,
|
|
180
|
+
clear: P,
|
|
181
|
+
clearRejection: F,
|
|
182
|
+
canAddMore: C.current < 5,
|
|
183
|
+
commit: N,
|
|
184
|
+
cancelCommit: M,
|
|
185
|
+
isCommitting: h
|
|
242
186
|
};
|
|
243
187
|
}
|
|
244
188
|
//#endregion
|
|
245
|
-
export {
|
|
189
|
+
export { y as useAssistantAttachments };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { FilesPort } from '../../storage/filesPort';
|
|
2
|
+
import { AttachmentCommitter, CommitOptions } from './attachmentCommit';
|
|
3
|
+
/**
|
|
4
|
+
* A test seam: a `FilesPort` that replaces the Apollo-backed one for everything below it. Never
|
|
5
|
+
* provided in production.
|
|
6
|
+
*/
|
|
7
|
+
export declare const AttachmentFilesPortContext: import('react').Context<FilesPort | null>;
|
|
8
|
+
/** The Files port for this tree: the override if one is provided, else the Apollo client's. */
|
|
9
|
+
export declare function useAttachmentFilesPort(): FilesPort | null;
|
|
10
|
+
/** Mint a download URL for a saved file (Retry replays an old turn's attachments). */
|
|
11
|
+
export declare function useAttachmentUrlResolver(): (fileId: string) => Promise<string | null>;
|
|
12
|
+
/**
|
|
13
|
+
* One committer per mounted draft. `onChange` and the product's folder are read at call time, so
|
|
14
|
+
* the committer (and the failed rollbacks it remembers) survives re-renders.
|
|
15
|
+
*/
|
|
16
|
+
export declare function useAttachmentCommitter(onChange: NonNullable<CommitOptions['onChange']>): AttachmentCommitter;
|
|
17
|
+
//# sourceMappingURL=useAttachmentCommitter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useAttachmentCommitter.d.ts","sourceRoot":"","sources":["../../../src/shared/assistant/useAttachmentCommitter.ts"],"names":[],"mappings":"AAQA,OAAO,EAGL,KAAK,SAAS,EAEf,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EAEL,KAAK,mBAAmB,EACxB,KAAK,aAAa,EACnB,MAAM,oBAAoB,CAAC;AAG5B;;;GAGG;AACH,eAAO,MAAM,0BAA0B,2CAAwC,CAAC;AAEhF,+FAA+F;AAC/F,wBAAgB,sBAAsB,IAAI,SAAS,GAAG,IAAI,CAOzD;AAED,sFAAsF;AACtF,wBAAgB,wBAAwB,IAAI,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAGrF;AAkBD;;;GAGG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,WAAW,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC,GAC/C,mBAAmB,CAqBrB"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { useAssistantStorageFolders as e } from "./product.js";
|
|
2
|
+
import { FilesPortError as t, createApolloFilesPort as n } from "../../storage/filesPort.js";
|
|
3
|
+
import { createAttachmentCommitter as r } from "./attachmentCommit.js";
|
|
4
|
+
import { getWorkspaceId as i } from "./context.js";
|
|
5
|
+
import { createContext as a, useCallback as o, useContext as s, useMemo as c, useRef as l } from "react";
|
|
6
|
+
import { getApolloContext as u } from "@apollo/client/react";
|
|
7
|
+
//#region src/shared/assistant/useAttachmentCommitter.ts
|
|
8
|
+
var d = a(null);
|
|
9
|
+
function f() {
|
|
10
|
+
let e = s(d), { client: t } = s(u());
|
|
11
|
+
return c(() => e ?? (t ? n(t, { getWorkspaceId: i }) : null), [e, t]);
|
|
12
|
+
}
|
|
13
|
+
function p() {
|
|
14
|
+
let e = f();
|
|
15
|
+
return o(async (t) => e ? e.getDownloadUrl(t) : null, [e]);
|
|
16
|
+
}
|
|
17
|
+
var m = (e) => () => Promise.reject(new t(e, "File storage is not available here.", void 0)), h = {
|
|
18
|
+
ensureFolder: m("ensureFolder"),
|
|
19
|
+
initiate: m("initiate"),
|
|
20
|
+
put: m("put"),
|
|
21
|
+
complete: m("complete"),
|
|
22
|
+
getSession: m("getSession"),
|
|
23
|
+
listSessions: m("listSessions"),
|
|
24
|
+
abort: m("abort"),
|
|
25
|
+
getDownloadUrl: m("getDownloadUrl"),
|
|
26
|
+
deleteFile: m("deleteFile")
|
|
27
|
+
};
|
|
28
|
+
function g(t) {
|
|
29
|
+
let n = f(), i = e(), a = l(t);
|
|
30
|
+
a.current = t;
|
|
31
|
+
let o = l(i.attachments);
|
|
32
|
+
return o.current = i.attachments, c(() => r({
|
|
33
|
+
port: n ?? h,
|
|
34
|
+
get folderPath() {
|
|
35
|
+
return o.current;
|
|
36
|
+
},
|
|
37
|
+
onChange: (e, t) => a.current(e, t)
|
|
38
|
+
}), [n]);
|
|
39
|
+
}
|
|
40
|
+
//#endregion
|
|
41
|
+
export { d as AttachmentFilesPortContext, g as useAttachmentCommitter, f as useAttachmentFilesPort, p as useAttachmentUrlResolver };
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { AssistantAttachment } from './attachments';
|
|
2
|
+
import { AttachmentCommitFailure, AttachmentCommitResult, CommitOptions } from './attachmentCommit';
|
|
3
|
+
/** How long a spoken turn waits for its files to be saved before it drops them. */
|
|
4
|
+
export declare const VOICE_COMMIT_BUDGET_MS = 20000;
|
|
5
|
+
/** The slice of the attachment draft this needs; `useAssistantAttachments` provides it. */
|
|
6
|
+
export interface SpokenTurnDraft {
|
|
7
|
+
readonly attachments: readonly AssistantAttachment[];
|
|
8
|
+
commit: (options?: {
|
|
9
|
+
mode?: CommitOptions['mode'];
|
|
10
|
+
budgetMs?: number;
|
|
11
|
+
signal?: AbortSignal;
|
|
12
|
+
}) => Promise<AttachmentCommitResult>;
|
|
13
|
+
clear: () => void;
|
|
14
|
+
}
|
|
15
|
+
export interface SettleSpokenTurnDeps {
|
|
16
|
+
draft: SpokenTurnDraft;
|
|
17
|
+
/** `maySendSpokenTurn` for this turn: false once the session ended or the conversation went. */
|
|
18
|
+
maySend: () => boolean;
|
|
19
|
+
/** Hand the turn over. Called after the commit, with only the attachments that may travel. */
|
|
20
|
+
sendTurn: (attachments: AssistantAttachment[]) => void;
|
|
21
|
+
/** Some files could not be saved and were not sent. Called once, before `sendTurn`. */
|
|
22
|
+
announceDropped: (count: number, failures: readonly AttachmentCommitFailure[]) => void;
|
|
23
|
+
budgetMs?: number;
|
|
24
|
+
}
|
|
25
|
+
export type SpokenTurnOutcome =
|
|
26
|
+
/** The turn was sent (possibly without some files). */
|
|
27
|
+
{
|
|
28
|
+
kind: 'sent';
|
|
29
|
+
dropped: number;
|
|
30
|
+
}
|
|
31
|
+
/** The turn no longer belongs anywhere; nothing was sent and the draft is cleared. */
|
|
32
|
+
| {
|
|
33
|
+
kind: 'abandoned';
|
|
34
|
+
};
|
|
35
|
+
export declare function settleAndCommitSpokenTurn(deps: SettleSpokenTurnDeps): Promise<SpokenTurnOutcome>;
|
|
36
|
+
//# sourceMappingURL=voiceCommit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"voiceCommit.d.ts","sourceRoot":"","sources":["../../../src/shared/assistant/voiceCommit.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,EAA0B,KAAK,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACjF,OAAO,KAAK,EACV,uBAAuB,EACvB,sBAAsB,EACtB,aAAa,EACd,MAAM,oBAAoB,CAAC;AAE5B,mFAAmF;AACnF,eAAO,MAAM,sBAAsB,QAAS,CAAC;AAE7C,2FAA2F;AAC3F,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,WAAW,EAAE,SAAS,mBAAmB,EAAE,CAAC;IACrD,MAAM,EAAE,CAAC,OAAO,CAAC,EAAE;QACjB,IAAI,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;QAC7B,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,MAAM,CAAC,EAAE,WAAW,CAAC;KACtB,KAAK,OAAO,CAAC,sBAAsB,CAAC,CAAC;IACtC,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB;AAED,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,eAAe,CAAC;IACvB,gGAAgG;IAChG,OAAO,EAAE,MAAM,OAAO,CAAC;IACvB,8FAA8F;IAC9F,QAAQ,EAAE,CAAC,WAAW,EAAE,mBAAmB,EAAE,KAAK,IAAI,CAAC;IACvD,uFAAuF;IACvF,eAAe,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,uBAAuB,EAAE,KAAK,IAAI,CAAC;IACvF,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,MAAM,iBAAiB;AAC3B,uDAAuD;AACrD;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE;AACnC,sFAAsF;GACpF;IAAE,IAAI,EAAE,WAAW,CAAA;CAAE,CAAC;AAQ1B,wBAAsB,yBAAyB,CAC7C,IAAI,EAAE,oBAAoB,GACzB,OAAO,CAAC,iBAAiB,CAAC,CAyC5B"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { getSendableAttachments as e } from "./attachments.js";
|
|
2
|
+
//#region src/shared/assistant/voiceCommit.ts
|
|
3
|
+
var t = 2e4;
|
|
4
|
+
function n(e) {
|
|
5
|
+
return e.some((e) => e.status === "ready" && !e.fileId && !e.inlineOnly);
|
|
6
|
+
}
|
|
7
|
+
async function r(t) {
|
|
8
|
+
let { draft: r } = t;
|
|
9
|
+
if (!t.maySend()) return r.clear(), { kind: "abandoned" };
|
|
10
|
+
if (!n(r.attachments)) return t.sendTurn(e([...r.attachments])), r.clear(), {
|
|
11
|
+
kind: "sent",
|
|
12
|
+
dropped: 0
|
|
13
|
+
};
|
|
14
|
+
let i = await r.commit({
|
|
15
|
+
mode: "best-effort",
|
|
16
|
+
budgetMs: t.budgetMs ?? 2e4
|
|
17
|
+
});
|
|
18
|
+
return i.ok ? t.maySend() ? (i.dropped.length > 0 && t.announceDropped(i.dropped.length, i.dropped), t.sendTurn(e(i.attachments)), i.handedOver(), r.clear(), {
|
|
19
|
+
kind: "sent",
|
|
20
|
+
dropped: i.dropped.length
|
|
21
|
+
}) : (await i.rollback(), r.clear(), { kind: "abandoned" }) : (r.clear(), { kind: "abandoned" });
|
|
22
|
+
}
|
|
23
|
+
//#endregion
|
|
24
|
+
export { t as VOICE_COMMIT_BUDGET_MS, r as settleAndCommitSpokenTurn };
|