@burdenoff/fe-libs 2026.904.17 → 2026.904.19
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/index.d.ts +4 -0
- package/dist/shared/assistant/index.d.ts.map +1 -1
- package/dist/shared/assistant/transportErrors.d.ts +39 -0
- package/dist/shared/assistant/transportErrors.d.ts.map +1 -0
- package/dist/shared/assistant/transportErrors.js +52 -0
- package/dist/shared/assistant/ui/voice/AssistantVoiceSession.d.ts +71 -0
- package/dist/shared/assistant/ui/voice/AssistantVoiceSession.d.ts.map +1 -0
- package/dist/shared/assistant/ui/voice/AssistantVoiceSession.js +190 -0
- package/dist/shared/assistant/useAssistantApiAccess.d.ts +23 -0
- package/dist/shared/assistant/useAssistantApiAccess.d.ts.map +1 -0
- package/dist/shared/assistant/useAssistantApiAccess.js +37 -0
- package/dist/shared/assistant/useConversationTurns.d.ts +36 -0
- package/dist/shared/assistant/useConversationTurns.d.ts.map +1 -0
- package/dist/shared/assistant/useConversationTurns.js +17 -0
- package/dist/shared-assistant.js +5 -1
- package/package.json +1 -1
|
@@ -106,4 +106,8 @@ export * from './ui/AssistantEmptyState';
|
|
|
106
106
|
export * from './exportConversation';
|
|
107
107
|
export * from './ui/AssistantMessageItem';
|
|
108
108
|
export * from './ui/AssistantMessageList';
|
|
109
|
+
export * from './ui/voice/AssistantVoiceSession';
|
|
110
|
+
export * from './useAssistantApiAccess';
|
|
111
|
+
export * from './useConversationTurns';
|
|
112
|
+
export * from './transportErrors';
|
|
109
113
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/shared/assistant/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAGH,cAAc,gCAAgC,CAAC;AAC/C,cAAc,mCAAmC,CAAC;AAClD,cAAc,WAAW,CAAC;AAC1B,cAAc,iBAAiB,CAAC;AAChC,cAAc,YAAY,CAAC;AAC3B,cAAc,OAAO,CAAC;AACtB,cAAc,SAAS,CAAC;AAGxB,cAAc,wBAAwB,CAAC;AAKvC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,6BAA6B,CAAC;AAC5C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,gCAAgC,CAAC;AAC/C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,+BAA+B,CAAC;AAG9C,cAAc,uBAAuB,CAAC;AACtC,cAAc,yBAAyB,CAAC;AACxC,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,yBAAyB,CAAC;AACxC,cAAc,uBAAuB,CAAC;AACtC,cAAc,sBAAsB,CAAC;AACrC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC;AAGlC,cAAc,gBAAgB,CAAC;AAK/B,cAAc,UAAU,CAAC;AACzB,cAAc,cAAc,CAAC;AAC7B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,4BAA4B,CAAC;AAG3C,cAAc,QAAQ,CAAC;AAEvB,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC;AACtC,cAAc,wBAAwB,CAAC;AAGvC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,SAAS,CAAC;AACxB,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAG/B,cAAc,4BAA4B,CAAC;AAC3C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,sBAAsB,CAAC;AAGrC,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,gCAAgC,CAAC;AAC/C,cAAc,kCAAkC,CAAC;AACjD,cAAc,gCAAgC,CAAC;AAC/C,cAAc,qCAAqC,CAAC;AACpD,cAAc,2BAA2B,CAAC;AAC1C,cAAc,iCAAiC,CAAC;AAChD,cAAc,yCAAyC,CAAC;AACxD,cAAc,wCAAwC,CAAC;AACvD,cAAc,yCAAyC,CAAC;AACxD,cAAc,qCAAqC,CAAC;AACpD,cAAc,oCAAoC,CAAC;AACnD,cAAc,sCAAsC,CAAC;AACrD,cAAc,8BAA8B,CAAC;AAC7C,cAAc,wCAAwC,CAAC;AACvD,cAAc,yBAAyB,CAAC;AACxC,cAAc,kCAAkC,CAAC;AACjD,cAAc,gCAAgC,CAAC;AAC/C,cAAc,uBAAuB,CAAC;AACtC,cAAc,kCAAkC,CAAC;AACjD,cAAc,0BAA0B,CAAC;AAGzC,cAAc,WAAW,CAAC;AAE1B,cAAc,wBAAwB,CAAC;AACvC,cAAc,sBAAsB,CAAC;AACrC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,0BAA0B,CAAC;AACzC,cAAc,sBAAsB,CAAC;AAErC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,2BAA2B,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/shared/assistant/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAGH,cAAc,gCAAgC,CAAC;AAC/C,cAAc,mCAAmC,CAAC;AAClD,cAAc,WAAW,CAAC;AAC1B,cAAc,iBAAiB,CAAC;AAChC,cAAc,YAAY,CAAC;AAC3B,cAAc,OAAO,CAAC;AACtB,cAAc,SAAS,CAAC;AAGxB,cAAc,wBAAwB,CAAC;AAKvC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,6BAA6B,CAAC;AAC5C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,gCAAgC,CAAC;AAC/C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,+BAA+B,CAAC;AAG9C,cAAc,uBAAuB,CAAC;AACtC,cAAc,yBAAyB,CAAC;AACxC,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,yBAAyB,CAAC;AACxC,cAAc,uBAAuB,CAAC;AACtC,cAAc,sBAAsB,CAAC;AACrC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC;AAGlC,cAAc,gBAAgB,CAAC;AAK/B,cAAc,UAAU,CAAC;AACzB,cAAc,cAAc,CAAC;AAC7B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,4BAA4B,CAAC;AAG3C,cAAc,QAAQ,CAAC;AAEvB,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC;AACtC,cAAc,wBAAwB,CAAC;AAGvC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,SAAS,CAAC;AACxB,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAG/B,cAAc,4BAA4B,CAAC;AAC3C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,sBAAsB,CAAC;AAGrC,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,gCAAgC,CAAC;AAC/C,cAAc,kCAAkC,CAAC;AACjD,cAAc,gCAAgC,CAAC;AAC/C,cAAc,qCAAqC,CAAC;AACpD,cAAc,2BAA2B,CAAC;AAC1C,cAAc,iCAAiC,CAAC;AAChD,cAAc,yCAAyC,CAAC;AACxD,cAAc,wCAAwC,CAAC;AACvD,cAAc,yCAAyC,CAAC;AACxD,cAAc,qCAAqC,CAAC;AACpD,cAAc,oCAAoC,CAAC;AACnD,cAAc,sCAAsC,CAAC;AACrD,cAAc,8BAA8B,CAAC;AAC7C,cAAc,wCAAwC,CAAC;AACvD,cAAc,yBAAyB,CAAC;AACxC,cAAc,kCAAkC,CAAC;AACjD,cAAc,gCAAgC,CAAC;AAC/C,cAAc,uBAAuB,CAAC;AACtC,cAAc,kCAAkC,CAAC;AACjD,cAAc,0BAA0B,CAAC;AAGzC,cAAc,WAAW,CAAC;AAE1B,cAAc,wBAAwB,CAAC;AACvC,cAAc,sBAAsB,CAAC;AACrC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,0BAA0B,CAAC;AACzC,cAAc,sBAAsB,CAAC;AAErC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,2BAA2B,CAAC;AAE1C,cAAc,kCAAkC,CAAC;AAEjD,cAAc,yBAAyB,CAAC;AACxC,cAAc,wBAAwB,CAAC;AACvC,cAAc,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deciding whether a failed turn is worth re-sending WITHOUT its images.
|
|
3
|
+
*
|
|
4
|
+
* The multimodal turn carries image bytes inside the `proxySandboxRequest` body.
|
|
5
|
+
* Two things can refuse that body before the model ever sees it:
|
|
6
|
+
*
|
|
7
|
+
* 1. `wspace-public-gateway` enforces `MAX_REQUEST_BODY_SIZE` (256kb in alpha
|
|
8
|
+
* and prod). It compares `Content-Length` and answers **413 before
|
|
9
|
+
* authenticating and before forwarding anything**.
|
|
10
|
+
* 2. The in-sandbox bridge can reject the body itself, which surfaces through
|
|
11
|
+
* fe-libs as `Proxy error: <status>`.
|
|
12
|
+
*
|
|
13
|
+
* In both cases the prompt provably did not reach the agent, so re-sending it
|
|
14
|
+
* text-only is safe and is strictly better than losing the turn.
|
|
15
|
+
*
|
|
16
|
+
* ## Why this is substring matching and not a status check
|
|
17
|
+
*
|
|
18
|
+
* fe-libs' `graphqlFetch` maps a non-2xx response to a human sentence and throws
|
|
19
|
+
* that — `throw Error(friendlyMessage(response))` — keeping no status code, no
|
|
20
|
+
* `extensions`, nothing structured. Every 4xx that is not 401/403/404/429
|
|
21
|
+
* collapses to one sentence. So the sentence IS the signal; there is nothing
|
|
22
|
+
* better to key on from here.
|
|
23
|
+
*
|
|
24
|
+
* ## Why the deny-list comes first
|
|
25
|
+
*
|
|
26
|
+
* Retrying something that may have LANDED would double-charge the user and give
|
|
27
|
+
* the agent the same question twice — the session is stateful and the prompt
|
|
28
|
+
* POST carries no idempotency key. Anything that could have failed on the
|
|
29
|
+
* RESPONSE leg (network drops, timeouts, 5xx) is therefore excluded outright,
|
|
30
|
+
* including the shapes fe-libs' own `executeSandboxGraphQL` has already retried
|
|
31
|
+
* three times before we ever see them.
|
|
32
|
+
*/
|
|
33
|
+
/**
|
|
34
|
+
* Is this error a rejection of the request BODY that we should retry without
|
|
35
|
+
* the multimodal parts?
|
|
36
|
+
*/
|
|
37
|
+
export declare function isMultimodalBodyRejection(error: unknown): boolean;
|
|
38
|
+
export declare function isRecoverableAssistantError(error: unknown): boolean;
|
|
39
|
+
//# sourceMappingURL=transportErrors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transportErrors.d.ts","sourceRoot":"","sources":["../../../src/shared/assistant/transportErrors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAmCH;;;GAGG;AACH,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CASjE;AA6CD,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CASnE"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
//#region src/shared/assistant/transportErrors.ts
|
|
2
|
+
var e = [
|
|
3
|
+
"failed to fetch",
|
|
4
|
+
"networkerror",
|
|
5
|
+
"network request failed",
|
|
6
|
+
"load failed",
|
|
7
|
+
"aborted",
|
|
8
|
+
"took too long",
|
|
9
|
+
"timed out",
|
|
10
|
+
"timeout",
|
|
11
|
+
"too many requests",
|
|
12
|
+
"the server is having trouble",
|
|
13
|
+
"unexpected error"
|
|
14
|
+
], t = [
|
|
15
|
+
"the request could not be processed",
|
|
16
|
+
"payload too large",
|
|
17
|
+
"request body exceeds maximum size",
|
|
18
|
+
"request entity too large",
|
|
19
|
+
"content too large",
|
|
20
|
+
"proxy error: 400",
|
|
21
|
+
"proxy error: 413",
|
|
22
|
+
"proxy error: 415",
|
|
23
|
+
"proxy error: 422"
|
|
24
|
+
];
|
|
25
|
+
function n(n) {
|
|
26
|
+
let r = (n instanceof Error ? n.message : String(n)).toLowerCase();
|
|
27
|
+
return e.some((e) => r.includes(e)) ? !1 : t.some((e) => r.includes(e));
|
|
28
|
+
}
|
|
29
|
+
var r = [
|
|
30
|
+
"rate limit exceeded",
|
|
31
|
+
"unauthorized",
|
|
32
|
+
"k8s api error 401"
|
|
33
|
+
], i = [
|
|
34
|
+
"sandbox not found",
|
|
35
|
+
"sandbox is not running",
|
|
36
|
+
"sandbox service not available yet",
|
|
37
|
+
"sandbox failed",
|
|
38
|
+
"sandbox startup timed out",
|
|
39
|
+
"assistant service did not become healthy",
|
|
40
|
+
"proxy error: 404",
|
|
41
|
+
"proxy error: 502",
|
|
42
|
+
"proxy error: 503",
|
|
43
|
+
"session mode mismatch",
|
|
44
|
+
"unable to connect",
|
|
45
|
+
"able to access the url"
|
|
46
|
+
];
|
|
47
|
+
function a(e) {
|
|
48
|
+
let t = (e instanceof Error ? e.message : String(e)).toLowerCase();
|
|
49
|
+
return r.some((e) => t.includes(e)) ? !1 : i.some((e) => t.includes(e));
|
|
50
|
+
}
|
|
51
|
+
//#endregion
|
|
52
|
+
export { n as isMultimodalBodyRejection, a as isRecoverableAssistantError };
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { FC } from 'react';
|
|
2
|
+
import { AssistantAttachment } from '../../attachments';
|
|
3
|
+
import { VoiceSessionSnapshot } from '../../voice/voiceSession';
|
|
4
|
+
import { VoiceSessionNotice } from '../useVoiceSession';
|
|
5
|
+
import { VoiceTranscriptTurn } from '../../voice/turnVisibility';
|
|
6
|
+
/** How much room the voice session takes: a strip, the panel, or the screen. */
|
|
7
|
+
export type VoiceView = "mini" | "panel" | "full";
|
|
8
|
+
interface Props {
|
|
9
|
+
session: VoiceSessionSnapshot;
|
|
10
|
+
/** Recent exchanges, oldest first — the running conversation. */
|
|
11
|
+
turns?: ReadonlyArray<VoiceTranscriptTurn>;
|
|
12
|
+
/** Download the spoken conversation. */
|
|
13
|
+
onSaveTranscript?: () => void;
|
|
14
|
+
/** Leave a note in the typed thread, end the session, and carry on there. */
|
|
15
|
+
onContinueInChat?: () => void;
|
|
16
|
+
/** Cut the assistant off mid-reply. */
|
|
17
|
+
onInterrupt?: () => void;
|
|
18
|
+
/** A recoverable problem to surface. Null when the microphone is healthy. */
|
|
19
|
+
notice?: VoiceSessionNotice | null;
|
|
20
|
+
/** The assistant's last reply, captioned while it is spoken. */
|
|
21
|
+
spoken: string | null;
|
|
22
|
+
onToggleMute: () => void;
|
|
23
|
+
/**
|
|
24
|
+
* Files attached to the NEXT spoken turn.
|
|
25
|
+
*
|
|
26
|
+
* ★ Deliberately a separate draft from the composer's. A photo taken during a
|
|
27
|
+
* voice session belongs to the question the user is about to ask aloud, not to
|
|
28
|
+
* whatever half-typed message is sitting in the text box behind the overlay.
|
|
29
|
+
*/
|
|
30
|
+
attachments?: AssistantAttachment[];
|
|
31
|
+
onAttachFiles?: (files: FileList | null) => void;
|
|
32
|
+
onRemoveAttachment?: (id: string) => void;
|
|
33
|
+
onRetryAttachment?: (id: string) => void;
|
|
34
|
+
canAttachMore?: boolean;
|
|
35
|
+
/** Files being read — placeholder chips, see AssistantAttachmentChips. */
|
|
36
|
+
preparingAttachments?: number;
|
|
37
|
+
/** Reveals the assistant caption in step with the audio. */
|
|
38
|
+
spokenChunks?: {
|
|
39
|
+
chunks: string[];
|
|
40
|
+
index: number;
|
|
41
|
+
} | null;
|
|
42
|
+
onEnd: () => void;
|
|
43
|
+
/** Is the recogniser actually running? Distinguishes CONNECTING from LISTENING. */
|
|
44
|
+
capturing?: boolean;
|
|
45
|
+
/** The user has cut the assistant off and capture has not resumed yet. */
|
|
46
|
+
interrupting?: boolean;
|
|
47
|
+
/** Quiet has fallen and the two-second correction window is running. */
|
|
48
|
+
awaitingEndpoint?: boolean;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Full-screen voice conversation (BOFF-7120).
|
|
52
|
+
*
|
|
53
|
+
* ★ **Voice only, by explicit product decision.** The reference (Gemini Live)
|
|
54
|
+
* also offers camera and screen sharing; those are deliberately absent here.
|
|
55
|
+
* Attaching images is a separate, existing capability of the assistant and
|
|
56
|
+
* stays in the composer, and screen sharing could not work on the primary
|
|
57
|
+
* device anyway — `getDisplayMedia` is unsupported by every iOS browser, so
|
|
58
|
+
* that control would be dead on an iPhone.
|
|
59
|
+
*
|
|
60
|
+
* The controls are therefore the two that a voice conversation actually needs:
|
|
61
|
+
* mute, and end. Anything else would be a button the user has to think about
|
|
62
|
+
* while talking.
|
|
63
|
+
*
|
|
64
|
+
* This component is presentational: every transition is owned by
|
|
65
|
+
* `voiceSessionReducer`, which is pure and tested. That split exists because
|
|
66
|
+
* this file cannot be tested at all in this repo — vitest runs in `node` with
|
|
67
|
+
* no DOM and no audio.
|
|
68
|
+
*/
|
|
69
|
+
export declare const AssistantVoiceSession: FC<Props>;
|
|
70
|
+
export {};
|
|
71
|
+
//# sourceMappingURL=AssistantVoiceSession.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AssistantVoiceSession.d.ts","sourceRoot":"","sources":["../../../../../src/shared/assistant/ui/voice/AssistantVoiceSession.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA4C,KAAK,EAAE,EAAE,MAAM,OAAO,CAAC;AAI1E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAO7D,OAAO,EAEL,KAAK,oBAAoB,EAC1B,MAAM,0BAA0B,CAAC;AAElC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAC7D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAEtE,gFAAgF;AAChF,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC;AAElD,UAAU,KAAK;IACb,OAAO,EAAE,oBAAoB,CAAC;IAC9B,iEAAiE;IACjE,KAAK,CAAC,EAAE,aAAa,CAAC,mBAAmB,CAAC,CAAC;IAC3C,wCAAwC;IACxC,gBAAgB,CAAC,EAAE,MAAM,IAAI,CAAC;IAC9B,6EAA6E;IAC7E,gBAAgB,CAAC,EAAE,MAAM,IAAI,CAAC;IAC9B,uCAAuC;IACvC,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;IACzB,6EAA6E;IAC7E,MAAM,CAAC,EAAE,kBAAkB,GAAG,IAAI,CAAC;IACnC,gEAAgE;IAChE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB;;;;;;OAMG;IACH,WAAW,CAAC,EAAE,mBAAmB,EAAE,CAAC;IACpC,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,GAAG,IAAI,KAAK,IAAI,CAAC;IACjD,kBAAkB,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1C,iBAAiB,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,0EAA0E;IAC1E,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,4DAA4D;IAC5D,YAAY,CAAC,EAAE;QAAE,MAAM,EAAE,MAAM,EAAE,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAC1D,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,mFAAmF;IACnF,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,0EAA0E;IAC1E,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,wEAAwE;IACxE,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,qBAAqB,EAAE,EAAE,CAAC,KAAK,CAoiB3C,CAAC"}
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
import { micIsInterrupt as e, voiceStageState as t } from "../../voice/voiceStageState.js";
|
|
2
|
+
import { spokenSoFar as n } from "../../voice/voiceSession.js";
|
|
3
|
+
import { useAssistantTr as r } from "../../i18n.js";
|
|
4
|
+
import { AssistantAttachmentButton as i } from "../composer/AssistantAttachmentButton.js";
|
|
5
|
+
import { AssistantAttachmentChips as ee } from "../composer/AssistantAttachmentChips.js";
|
|
6
|
+
import { AssistantVoiceOrb as a } from "./AssistantVoiceOrb.js";
|
|
7
|
+
import { VoiceMiniController as te } from "./VoiceMiniController.js";
|
|
8
|
+
import { VoiceStage as o } from "./VoiceStage.js";
|
|
9
|
+
import { VoiceTranscriptDrawer as s } from "./VoiceTranscriptDrawer.js";
|
|
10
|
+
import { useCallback as ne, useEffect as c, useRef as l, useState as u } from "react";
|
|
11
|
+
import { Maximize2 as d, Minimize2 as f, ScrollText as p, X as m } from "lucide-react";
|
|
12
|
+
import { jsx as h, jsxs as g } from "react/jsx-runtime";
|
|
13
|
+
//#region src/shared/assistant/ui/voice/AssistantVoiceSession.tsx
|
|
14
|
+
var _ = ({ session: _, turns: b = [], onSaveTranscript: x, onContinueInChat: S, notice: C = null, spoken: w, onInterrupt: T, onToggleMute: E, attachments: D = [], onAttachFiles: O, onRemoveAttachment: re, onRetryAttachment: k, canAttachMore: ie = !0, preparingAttachments: A = 0, spokenChunks: ae = null, onEnd: j, capturing: M = !0, interrupting: N = !1, awaitingEndpoint: P = !1 }) => {
|
|
15
|
+
let F = r(), { muted: I, error: L } = _, R = l(null), z = l(null), [B, V] = u("mini"), H = B === "full", U = B === "mini", W = B === "mini" ? "panel" : B === "panel" ? "full" : "mini", [G, K] = u(!1), q = l(!1), J = l(E);
|
|
16
|
+
J.current = E;
|
|
17
|
+
let oe = ne(() => {
|
|
18
|
+
I || q.current || n(_) || (q.current = !0, J.current());
|
|
19
|
+
}, [I, _]);
|
|
20
|
+
c(() => {
|
|
21
|
+
let e = () => {
|
|
22
|
+
q.current && (q.current = !1, J.current());
|
|
23
|
+
};
|
|
24
|
+
return window.addEventListener("focus", e), () => {
|
|
25
|
+
window.removeEventListener("focus", e), q.current = !1;
|
|
26
|
+
};
|
|
27
|
+
}, []), c(() => {
|
|
28
|
+
R.current?.focus();
|
|
29
|
+
}, []), c(() => {
|
|
30
|
+
let e = (e) => {
|
|
31
|
+
if (e.key === "Escape") {
|
|
32
|
+
if (G) {
|
|
33
|
+
K(!1);
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
j();
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
if (e.key !== "Tab" || !H) return;
|
|
40
|
+
let t = (G ? z.current?.querySelector("[data-testid=\"assistant-voice-transcript\"]") : z.current)?.querySelectorAll("button:not([disabled])");
|
|
41
|
+
if (!t || t.length === 0) return;
|
|
42
|
+
let n = t[0], r = t[t.length - 1];
|
|
43
|
+
!n || !r || (e.shiftKey && document.activeElement === n ? (e.preventDefault(), r.focus()) : !e.shiftKey && document.activeElement === r && (e.preventDefault(), n.focus()));
|
|
44
|
+
};
|
|
45
|
+
return window.addEventListener("keydown", e), () => window.removeEventListener("keydown", e);
|
|
46
|
+
}, [
|
|
47
|
+
j,
|
|
48
|
+
H,
|
|
49
|
+
G
|
|
50
|
+
]);
|
|
51
|
+
let Y = C !== null && L === null, X = n(_), Z = t({
|
|
52
|
+
snapshot: _,
|
|
53
|
+
capturing: M,
|
|
54
|
+
interrupting: N,
|
|
55
|
+
awaitingEndpoint: P
|
|
56
|
+
}), Q = (() => {
|
|
57
|
+
switch (Z) {
|
|
58
|
+
case "connecting": return F("voiceSession.connecting", "Starting the microphone…");
|
|
59
|
+
case "endpoint-grace": return F("voiceSession.endpointGrace", "Still listening — take your time");
|
|
60
|
+
case "interrupting": return F("voiceSession.interrupting", "Stopped — go ahead");
|
|
61
|
+
case "thinking": return F("voiceSession.thinking", "Thinking…");
|
|
62
|
+
case "speaking": return F("voiceSession.speaking", "Speaking — tap to stop");
|
|
63
|
+
case "mic-error":
|
|
64
|
+
case "ended": return "";
|
|
65
|
+
case "listening": return I ? F("voiceSession.muted", "Microphone off") : F("voiceSession.listening", "Listening…");
|
|
66
|
+
default: return Z;
|
|
67
|
+
}
|
|
68
|
+
})(), $ = I && Z !== "listening" && Q !== "" ? `${Q} · ${F("voiceSession.muted", "Microphone off")}` : Q;
|
|
69
|
+
return /* @__PURE__ */ g("div", {
|
|
70
|
+
ref: z,
|
|
71
|
+
className: `flex flex-col items-center justify-between bg-bg-sunken ${B === "full" ? "fixed inset-x-0 bottom-0 top-14 z-[60] px-6 py-8" : B === "panel" ? "absolute inset-0 z-20 px-4 py-6" : "absolute inset-x-0 bottom-0 z-20 h-[11.25rem] border-t border-border-subtle px-3 py-3 shadow-lg"}`,
|
|
72
|
+
role: "dialog",
|
|
73
|
+
"aria-modal": H || void 0,
|
|
74
|
+
"aria-label": F("voiceSession.title", "Voice conversation"),
|
|
75
|
+
"data-testid": "assistant-voice-session",
|
|
76
|
+
children: [
|
|
77
|
+
/* @__PURE__ */ g("button", {
|
|
78
|
+
ref: R,
|
|
79
|
+
type: "button",
|
|
80
|
+
onClick: j,
|
|
81
|
+
className: `absolute ${H ? "right-6 top-6 h-14 gap-2 px-5 text-base" : U ? "right-2 top-2 size-8" : "right-3 top-3 h-11 gap-2 px-4 text-sm"} flex items-center justify-center rounded-full border border-border-default bg-bg-elevated text-text-secondary hover:bg-bg-sunken transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-border-strong`,
|
|
82
|
+
"aria-label": U ? F("voiceSession.end", "End the voice conversation") : void 0,
|
|
83
|
+
"data-testid": "assistant-voice-end",
|
|
84
|
+
children: [/* @__PURE__ */ h(m, {
|
|
85
|
+
className: H ? "size-6" : U ? "size-4" : "size-5",
|
|
86
|
+
"aria-hidden": "true"
|
|
87
|
+
}), U ? null : /* @__PURE__ */ h("span", {
|
|
88
|
+
className: "max-w-[7rem] truncate whitespace-nowrap font-medium",
|
|
89
|
+
children: F("voiceSession.endShort", "End")
|
|
90
|
+
})]
|
|
91
|
+
}),
|
|
92
|
+
/* @__PURE__ */ h("div", {
|
|
93
|
+
className: `flex flex-col items-center ${U ? "px-3" : `min-h-[1.5rem] ${Y ? H ? "pt-14" : "pt-10" : ""}`}`,
|
|
94
|
+
children: Y ? /* @__PURE__ */ h("p", {
|
|
95
|
+
className: "max-w-xs text-center text-xs text-status-warning",
|
|
96
|
+
"data-testid": "assistant-voice-notice",
|
|
97
|
+
children: v(C, F)
|
|
98
|
+
}) : null
|
|
99
|
+
}),
|
|
100
|
+
(() => {
|
|
101
|
+
let t = /* @__PURE__ */ h(a, {
|
|
102
|
+
session: _,
|
|
103
|
+
compact: U,
|
|
104
|
+
connecting: Z === "connecting",
|
|
105
|
+
onPress: e(Z) ? T : E,
|
|
106
|
+
label: e(Z) ? F("voiceSession.interrupt", "Stop the assistant and speak") : I ? F("voiceSession.unmute", "Turn the microphone on") : F("voiceSession.mute", "Turn the microphone off")
|
|
107
|
+
}), n = e(Z) ? w : X || null, r = L === null ? null : y(L, F);
|
|
108
|
+
return U ? /* @__PURE__ */ h(te, {
|
|
109
|
+
state: Z,
|
|
110
|
+
caption: n,
|
|
111
|
+
statusText: $,
|
|
112
|
+
errorText: r,
|
|
113
|
+
control: t
|
|
114
|
+
}) : /* @__PURE__ */ h(o, {
|
|
115
|
+
state: Z,
|
|
116
|
+
userCaption: X || null,
|
|
117
|
+
spokenChunks: ae,
|
|
118
|
+
assistantCaption: w,
|
|
119
|
+
expanded: H,
|
|
120
|
+
statusText: $,
|
|
121
|
+
errorText: r,
|
|
122
|
+
control: t
|
|
123
|
+
});
|
|
124
|
+
})(),
|
|
125
|
+
G ? /* @__PURE__ */ h(s, {
|
|
126
|
+
turns: b,
|
|
127
|
+
onClose: () => K(!1),
|
|
128
|
+
onSave: x,
|
|
129
|
+
onContinueInChat: S
|
|
130
|
+
}) : null,
|
|
131
|
+
O ? /* @__PURE__ */ h("div", {
|
|
132
|
+
className: `absolute ${H ? "left-6 top-6" : U ? "left-11 top-2" : "left-3 top-3"}`,
|
|
133
|
+
children: /* @__PURE__ */ h(i, {
|
|
134
|
+
onFiles: (e) => {
|
|
135
|
+
O(e), V((e) => e === "mini" ? "panel" : e);
|
|
136
|
+
},
|
|
137
|
+
onPickerOpen: oe,
|
|
138
|
+
direction: "down",
|
|
139
|
+
canAddMore: ie
|
|
140
|
+
})
|
|
141
|
+
}) : null,
|
|
142
|
+
(D.length > 0 || A > 0) && !U ? /* @__PURE__ */ h("div", {
|
|
143
|
+
className: `absolute ${H ? "bottom-24 left-24 right-24" : "bottom-16 left-16 right-16"}`,
|
|
144
|
+
"data-testid": "assistant-voice-attachments",
|
|
145
|
+
children: /* @__PURE__ */ h(ee, {
|
|
146
|
+
attachments: D,
|
|
147
|
+
onRemove: re ?? (() => void 0),
|
|
148
|
+
onRetry: k ?? (() => void 0),
|
|
149
|
+
preparingCount: A
|
|
150
|
+
})
|
|
151
|
+
}) : null,
|
|
152
|
+
/* @__PURE__ */ h("button", {
|
|
153
|
+
type: "button",
|
|
154
|
+
onClick: () => K((e) => !e),
|
|
155
|
+
className: `absolute ${H ? "bottom-6 right-6 size-14" : U ? "right-11 top-2 size-8" : "bottom-3 right-3 size-11"} flex items-center justify-center rounded-full bg-bg-elevated text-text-secondary transition-colors hover:bg-bg-raised hover:text-text-primary focus:outline-none focus-visible:ring-2 focus-visible:ring-border-strong`,
|
|
156
|
+
"aria-pressed": G,
|
|
157
|
+
"aria-label": F("voiceSession.transcript", "Voice transcript"),
|
|
158
|
+
"data-testid": "assistant-voice-transcript-toggle",
|
|
159
|
+
children: /* @__PURE__ */ h(p, { className: H ? "size-6" : U ? "size-4" : "size-5" })
|
|
160
|
+
}),
|
|
161
|
+
/* @__PURE__ */ h("button", {
|
|
162
|
+
type: "button",
|
|
163
|
+
onClick: () => V(W),
|
|
164
|
+
className: `absolute ${H ? "bottom-6 left-6 size-14" : U ? "left-2 top-2 size-8" : "bottom-3 left-3 size-11"} flex items-center justify-center rounded-full bg-bg-elevated text-text-secondary transition-colors hover:bg-bg-raised hover:text-text-primary focus:outline-none focus-visible:ring-2 focus-visible:ring-border-strong`,
|
|
165
|
+
"aria-label": W === "panel" ? F("voiceSession.expandPanel", "Show the conversation in the panel") : W === "full" ? F("voiceSession.expand", "Expand the conversation to full screen") : F("voiceSession.collapse", "Shrink to the compact controller"),
|
|
166
|
+
"data-testid": "assistant-voice-expand",
|
|
167
|
+
children: H ? /* @__PURE__ */ h(f, { className: "size-5" }) : /* @__PURE__ */ h(d, { className: U ? "size-4" : "size-5" })
|
|
168
|
+
})
|
|
169
|
+
]
|
|
170
|
+
});
|
|
171
|
+
};
|
|
172
|
+
function v(e, t) {
|
|
173
|
+
switch (e) {
|
|
174
|
+
case "network": return t("voiceSession.noticeNetwork", "Speech recognition lost its connection. Check your network — it will retry.");
|
|
175
|
+
case "not-capturing": return t("voiceSession.noticeNotCapturing", "The microphone did not start. Check that this site is allowed to use it, then try again.");
|
|
176
|
+
case "recognition-failed": return t("voiceSession.noticeRecognitionFailed", "Speech recognition stopped unexpectedly. It will retry — if it keeps happening, reload the page.");
|
|
177
|
+
case "nothing-heard": return t("voiceSession.noticeNothingHeard", "Nothing heard yet. Check your microphone is not muted or in use by another app.");
|
|
178
|
+
default: return e;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
function y(e, t) {
|
|
182
|
+
switch (e) {
|
|
183
|
+
case "mic-denied": return t("voiceSession.micDenied", "Microphone access is blocked. Allow it in your browser settings to talk.");
|
|
184
|
+
case "no-speech-support": return t("voiceSession.noSpeechSupport", "This browser cannot listen. Try a different browser, or type instead.");
|
|
185
|
+
case "no-voice-support": return t("voiceSession.noVoiceSupport", "This device has no voice that can speak this language.");
|
|
186
|
+
default: return e;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
//#endregion
|
|
190
|
+
export { _ as AssistantVoiceSession };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolves whether the current user may use the write-capable `api-calls`
|
|
3
|
+
* assistant mode.
|
|
4
|
+
*
|
|
5
|
+
* That mode mints a per-sandbox OAuth app under the caller's identity
|
|
6
|
+
* (createApp/createApplication in wspace-sandbox-svc), which is RBAC-gated to a
|
|
7
|
+
* global Owner/Admin — a non-admin would only discover this as a FORBIDDEN at
|
|
8
|
+
* provision time. So we gate the UI on the same signal up front, via the global
|
|
9
|
+
* gateway's `myRoles(scopeId)` query (`@rbac(public: true)`, auth-only, returns
|
|
10
|
+
* `isAdmin`/`isOwner` directly — no extra provider wiring needed).
|
|
11
|
+
*
|
|
12
|
+
* Fails CLOSED: an error, an empty org scope, or the master flag being off all
|
|
13
|
+
* resolve to `canUseApiCalls = false`, so the mode stays hidden unless the user
|
|
14
|
+
* is provably an org admin.
|
|
15
|
+
*/
|
|
16
|
+
export interface AssistantApiAccess {
|
|
17
|
+
/** True only for a confirmed global Owner/Admin (and when the mode is enabled). */
|
|
18
|
+
canUseApiCalls: boolean;
|
|
19
|
+
/** True while the role check is in flight. */
|
|
20
|
+
loading: boolean;
|
|
21
|
+
}
|
|
22
|
+
export declare function useAssistantApiAccess(scopeId: string): AssistantApiAccess;
|
|
23
|
+
//# sourceMappingURL=useAssistantApiAccess.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useAssistantApiAccess.d.ts","sourceRoot":"","sources":["../../../src/shared/assistant/useAssistantApiAccess.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAiBH,MAAM,WAAW,kBAAkB;IACjC,mFAAmF;IACnF,cAAc,EAAE,OAAO,CAAC;IACxB,8CAA8C;IAC9C,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,kBAAkB,CAkDzE"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { graphqlFetch as e } from "../graphql/fetch.js";
|
|
2
|
+
import "../../shared-graphql.js";
|
|
3
|
+
import { useAssistantProduct as t } from "./product.js";
|
|
4
|
+
import { useEffect as n, useState as r } from "react";
|
|
5
|
+
//#region src/shared/assistant/useAssistantApiAccess.ts
|
|
6
|
+
var i = "query AssistantMyRoles($scopeId: String!) {\n myRoles(scopeId: $scopeId) {\n isAdmin\n isOwner\n }\n}";
|
|
7
|
+
function a(a) {
|
|
8
|
+
let { modes: o } = t(), s = o.some((e) => e.requiresAdmin) && !!a, [c, l] = r(!1), [u, d] = r(s);
|
|
9
|
+
return n(() => {
|
|
10
|
+
if (!s) {
|
|
11
|
+
l(!1), d(!1);
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
let t = !1;
|
|
15
|
+
return d(!0), e({
|
|
16
|
+
gateway: "global",
|
|
17
|
+
query: i,
|
|
18
|
+
variables: { scopeId: a },
|
|
19
|
+
suppressGlobalErrorEvent: !0
|
|
20
|
+
}).then((e) => {
|
|
21
|
+
if (t) return;
|
|
22
|
+
let n = e.data?.myRoles;
|
|
23
|
+
l(!!(n?.isOwner || n?.isAdmin));
|
|
24
|
+
}).catch(() => {
|
|
25
|
+
t || l(!1);
|
|
26
|
+
}).finally(() => {
|
|
27
|
+
t || d(!1);
|
|
28
|
+
}), () => {
|
|
29
|
+
t = !0;
|
|
30
|
+
};
|
|
31
|
+
}, [s, a]), {
|
|
32
|
+
canUseApiCalls: c,
|
|
33
|
+
loading: u
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
//#endregion
|
|
37
|
+
export { a as useAssistantApiAccess };
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { Conversation, Message } from './conversation';
|
|
2
|
+
export interface ConversationTurns {
|
|
3
|
+
/**
|
|
4
|
+
* Every turn, both surfaces. Readonly, so it cannot be handed to a component
|
|
5
|
+
* that renders a message list — that is the point of it being readonly.
|
|
6
|
+
*
|
|
7
|
+
* Use it for questions about the CONVERSATION ("is it used at all?"), never
|
|
8
|
+
* for questions about a SURFACE ("what should I draw?").
|
|
9
|
+
*/
|
|
10
|
+
all: readonly Message[];
|
|
11
|
+
/** Typed turns — what the chat thread draws. */
|
|
12
|
+
chat: Message[];
|
|
13
|
+
/** Spoken turns — what the voice panel and the transcript draw. */
|
|
14
|
+
voice: Message[];
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* One place that decides which turns belong to which surface.
|
|
18
|
+
*
|
|
19
|
+
* Voice and chat share a single message array; separation is a per-message
|
|
20
|
+
* marker plus a filter applied by every reader. That makes correctness scale
|
|
21
|
+
* with the NUMBER OF READERS, which is how the last round of leaks happened —
|
|
22
|
+
* the message list filtered correctly while four other readers did not, and
|
|
23
|
+
* nothing failed.
|
|
24
|
+
*
|
|
25
|
+
* ★ Deliberately a hook returning memoised arrays rather than a zustand
|
|
26
|
+
* selector. A selector like `useAssistantStore(s => chatTurns(...))` builds a
|
|
27
|
+
* fresh array on every call, so `Object.is` never matches and the component
|
|
28
|
+
* re-renders on every unrelated store change. Subscribing to the array and
|
|
29
|
+
* filtering in `useMemo` is the version that does not.
|
|
30
|
+
*
|
|
31
|
+
* The two filters are separate memos on purpose: a typed turn arriving must not
|
|
32
|
+
* hand the voice panel a new array identity, or the voice session re-renders
|
|
33
|
+
* mid-utterance.
|
|
34
|
+
*/
|
|
35
|
+
export declare function useConversationTurns(conversation: Conversation | undefined): ConversationTurns;
|
|
36
|
+
//# sourceMappingURL=useConversationTurns.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useConversationTurns.d.ts","sourceRoot":"","sources":["../../../src/shared/assistant/useConversationTurns.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAG5D,MAAM,WAAW,iBAAiB;IAChC;;;;;;OAMG;IACH,GAAG,EAAE,SAAS,OAAO,EAAE,CAAC;IACxB,gDAAgD;IAChD,IAAI,EAAE,OAAO,EAAE,CAAC;IAChB,mEAAmE;IACnE,KAAK,EAAE,OAAO,EAAE,CAAC;CAClB;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,oBAAoB,CAClC,YAAY,EAAE,YAAY,GAAG,SAAS,GACrC,iBAAiB,CAQnB"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { chatTurns as e, voiceTurnsOnly as t } from "./voice/turnVisibility.js";
|
|
2
|
+
import { useMemo as n } from "react";
|
|
3
|
+
//#region src/shared/assistant/useConversationTurns.ts
|
|
4
|
+
function r(r) {
|
|
5
|
+
let i = n(() => r?.messages ?? [], [r?.messages]), a = n(() => e(i), [i]), o = n(() => t(i), [i]);
|
|
6
|
+
return n(() => ({
|
|
7
|
+
all: i,
|
|
8
|
+
chat: a,
|
|
9
|
+
voice: o
|
|
10
|
+
}), [
|
|
11
|
+
i,
|
|
12
|
+
a,
|
|
13
|
+
o
|
|
14
|
+
]);
|
|
15
|
+
}
|
|
16
|
+
//#endregion
|
|
17
|
+
export { r as useConversationTurns };
|
package/dist/shared-assistant.js
CHANGED
|
@@ -72,4 +72,8 @@ import { AssistantConversationList as Xr } from "./shared/assistant/ui/Assistant
|
|
|
72
72
|
import { AssistantEmptyState as Zr } from "./shared/assistant/ui/AssistantEmptyState.js";
|
|
73
73
|
import { AssistantMessageItem as Qr } from "./shared/assistant/ui/AssistantMessageItem.js";
|
|
74
74
|
import { AssistantMessageList as $r } from "./shared/assistant/ui/AssistantMessageList.js";
|
|
75
|
-
|
|
75
|
+
import { AssistantVoiceSession as ei } from "./shared/assistant/ui/voice/AssistantVoiceSession.js";
|
|
76
|
+
import { useAssistantApiAccess as ti } from "./shared/assistant/useAssistantApiAccess.js";
|
|
77
|
+
import { useConversationTurns as ni } from "./shared/assistant/useConversationTurns.js";
|
|
78
|
+
import { isMultimodalBodyRejection as ri, isRecoverableAssistantError as ii } from "./shared/assistant/transportErrors.js";
|
|
79
|
+
export { p as ASSISTANT_API_AUTH_STRATEGY, At as ASSISTANT_LANGUAGES, Mr as ASSISTANT_MODE_META, Cn as ATTACHMENT_ACCEPT, dr as ATTACHMENT_SOURCES, Ir as AUTO_VOICE, Or as AssistantAttachmentButton, kr as AssistantAttachmentChips, _r as AssistantAutoSpeakToggle, Xr as AssistantConversationList, Zr as AssistantEmptyState, Yr as AssistantHeader, Ht as AssistantI18nProvider, Ar as AssistantLanguageSelector, vr as AssistantMarkdownImage, xr as AssistantMarkdownRenderer, Cr as AssistantMessageAttachments, Qr as AssistantMessageItem, $r as AssistantMessageList, Nr as AssistantModeSelector, Jr as AssistantMoreMenu, wr as AssistantPendingWriteCard, Rt as AssistantProductProvider, Tr as AssistantReplyLanguageSelector, U as AssistantRuntimeManager, Er as AssistantSpeakButton, ir as AssistantSpeechProvider, Dr as AssistantSpokenTurnsNotice, nr as AssistantToolActivity, Fr as AssistantVoiceButton, Rr as AssistantVoiceOrb, Lr as AssistantVoiceSelector, ei as AssistantVoiceSession, zr as AssistantVoiceSessionButton, wn as AttachmentRejectedError, nn as BOILERPLATE_PAGE_SHARE, i as CHECK_AI_CREDITS, a as CREATE_SANDBOX, dt as DEFAULT_SPEAKABLE_LABELS, jt as DEFAULT_SPEECH_RATE, Re as ENDPOINT_GRACE_MS, o as EXTEND_SANDBOX_TTL, jr as FOLLOW_APP_LOCALE, s as GET_ACTIVE_SANDBOXES, c as GET_SANDBOX, me as HOSTED_TTS_MAX_CHARS, ue as HOSTED_TTS_TIER, de as HOSTED_VOICES, Xt as IDLE_PLAYBACK, ze as INITIAL_SESSION, Tn as INLINE_IMAGE_MAX_DIM, En as INLINE_IMAGE_QUALITY, Be as INTERRUPT_MAX_MS, Ve as INTERRUPT_MIN_MS, Dn as MAX_ATTACHMENTS, rn as MAX_BOILERPLATE_LINE_CHARS, an as MAX_EXTRACTED_CHARS, On as MAX_FILE_BYTES, kn as MAX_INLINE_CHARS_PER_FILE, An as MAX_INLINE_CHARS_TOTAL, en as MAX_INLINE_IMAGE_BASE64_BYTES, jn as MAX_INLINE_IMAGE_BASE64_CHARS, Mn as MAX_INLINE_IMAGE_PARTS, Nn as MAX_INLINE_TURN_BODY_BYTES, on as MAX_PDF_PAGES_SCANNED, tn as MAX_REQUEST_BODY_BYTES, ft as MAX_SPEAKABLE_CHARS, pt as MAX_SPOKEN_TABLE_ROWS, Pn as MAX_TURN_BODY_BYTES, sn as MIN_PAGE_TEXT_CHARS, cn as MIN_TEXT_PAGE_SHARE, Ct as POLL_FAST_MS, wt as POLL_FAST_UNTIL_MS, Tt as POLL_SLOW_MS, Et as POLL_STEADY_MS, Dt as POLL_STEADY_UNTIL_MS, xt as PREVIEW_LANGUAGES, Fn as PROMPT_ENVELOPE_RESERVE_BYTES, l as PROXY_SANDBOX_REQUEST, u as REPORT_AI_TOKEN_USAGE, mr as SANDBOX_READY_TTL_MS, He as SILENCE_SUBMIT_MS, he as SPEAKING_RATE_MAX, ge as SPEAKING_RATE_MAX_STREAMING, _e as SPEAKING_RATE_MAX_SYNC, ve as SPEAKING_RATE_MIN, mt as SPEECH_CHUNK_CHARS, ht as SPEECH_CHUNK_CJK_CHARS, Xe as SPEECH_LANG, Kt as SPOKEN_LABEL_LANGUAGES, d as STOP_ASSISTANT_SANDBOX, In as TURN_BODY_HEADROOM_BYTES, Ze as VOICE_LIST_TIMEOUT_MS, Br as VoiceCaption, Vr as VoiceConversationView, Ur as VoiceMiniController, Wr as VoiceStage, Gr as VoiceTranscriptDrawer, Hr as VoiceWaveform, f as WAIT_FOR_SANDBOX_RUNNING, Ut as assistantTranslationKey, Sr as assistantUrlTransform, fr as availableAttachmentSources, ye as base64ToBytes, le as browserSpeechEngine, C as buildAssistantSandboxEnv, Ln as buildAttachmentPromptBlock, ct as buildContinuedFromVoiceNote, W as buildProgress, Rn as buildPromptParts, w as buildPromptRequestBody, zn as buildPromptWithAttachments, be as buildRequest, t as buildSandboxContextInput, lt as buildVoiceTranscriptMarkdown, ne as chatTurns, T as checkAssistantAiCredits, gt as chunkForSpeech, Bn as classifyAttachment, xe as classifyHttpFailure, ln as columnLetterToIndex, De as configureSpeechEngine, _t as containsCjk, sr as copyToClipboard, Vn as countInlineImageCandidates, Hn as countInlinedImageParts, E as createAssistantSandbox, D as createAssistantSession, Te as createHostedTtsEngine, hr as createReadinessTracker, Ee as createRoutingSpeechEngine, ee as createSandboxAssistantTransport, Oe as createSpeechEngines, Se as decodeAudioResponse, un as decodeXmlEntities, Un as detectDocumentFormat, Jt as detectScriptLocale, pr as deviceHasCamera, dn as docxXmlToText, O as downloadAssistantArtifact, Kr as downloadFile, Wn as estimateTurnBodyBytes, n as executeSandboxGraphQL, qr as exportConversation, k as extendAssistantSandboxTTL, Mt as findAssistantLanguage, A as findExistingSandbox, It as findPendingWrite, fn as fitPdfPages, Gn as formatBytes, pn as formatPageRanges, cr as getActorId, j as getAssistantArtifacts, G as getAssistantMedia, M as getAssistantMessages, N as getAssistantSession, P as getAssistantStreamAccess, K as getAssistantText, Kn as getAttachmentSendBlocker, y as getCapability, qn as getExtension, m as getImageForMode, h as getImageTagForMode, lr as getOrganizationId, q as getRawMessageCreatedAt, g as getResourcesForMode, _ as getSandboxImageRegistry, Jn as getSendableAttachments, ke as getSpeechEngine, J as getToolProgress, ur as getWorkspaceId, re as groupBySession, ie as groupConsecutiveBySession, Yn as hasAttachmentWorkInFlight, fe as hostedLocaleFor, pe as hostedSupportsLanguage, yr as imageHostLabel, Ue as isCapturing, We as isEcho, mn as isMostlyImagePages, ri as isMultimodalBodyRejection, r as isQuotaExhaustedError, Y as isReapedSandboxConnectionError, gr as isRecentlyVerified, X as isRecoverable, ii as isRecoverableAssistantError, br as isRemoteImageSrc, Zt as isSpeakingMessage, Qe as isSpeechBlocked, Ge as isSubmittable, tr as isTurnInFlight, b as isUnknownFieldError, ae as isVoiceTurn, hn as joinSheets, $e as languageDisplayName, Z as mapSessionToHistory, x as markSupported, S as markUnsupported, Q as mergeMessagesById, Me as micIsInterrupt, F as modeRequiresConfirmWrites, Pr as nextModeIndex, et as normalizeLangTag, Ke as orbMode, gn as pageMarker, Lt as parseConfirmationRefusal, Xn as parseDataUrl, _n as parseSharedStrings, rr as parseToolActivity, vn as parseWorkbookSheets, yn as pdfTextItemsToPage, qe as planReplyConsumption, Ot as pollDelayMs, tt as primaryLanguageSubtag, Ae as readSpeechEngineConfig, Pt as replyFollowsInput, I as reportAssistantAiTokenUsage, Qt as requiresCancel, je as resetSpeechEngine, Nt as resolveAssistantLanguage, Ft as resolveLanguagePair, zt as resolveModeConfig, v as resolveSandboxAssistantMode, Yt as resolveSpeechLocale, $ as sanitize, L as selectExistingAssistantSandbox, nt as selectVoiceForLocale, R as sendAssistantPromptAsync, z as sendHeartbeat, bn as sheetXmlToRows, Ce as shouldDisableEngine, Ne as showsAssistantCaption, Pe as showsUserCaption, vt as speakableEmail, rt as speechGate, qt as speechLabelsFor, it as speechLangForLocale, $t as speechPlaybackReducer, we as splitForVendor, yt as splitTableRow, Je as spokenSoFar, B as stopReapedAssistantSandbox, xn as summarisePageText, kt as toCaptionText, Zn as toMessageAttachment, bt as toSpeakableText, Qn as truncateForInline, Sn as truncatePagesForInline, ti as useAssistantApiAccess, Wt as useAssistantI18nNamespace, Bt as useAssistantProduct, Vt as useAssistantProductOrNull, ar as useAssistantSpeech, er as useAssistantStore, Gt as useAssistantTr, ni as useConversationTurns, te as useSandboxAssistantTransport, e as useVoiceInput, or as useVoiceSession, $n as validateFile, at as voiceAvailability, oe as voiceMarker, St as voicePreviewText, ot as voiceQualityRank, se as voiceSessionIdOf, Ye as voiceSessionReducer, Fe as voiceStageState, ut as voiceTranscriptFilename, ce as voiceTurnsOnly, st as voicesForLocale, V as waitForAssistantServiceReady, H as waitForSandboxRunning, Ie as waveformIsActive, Le as waveformIsSettled };
|